Minor changes to enforce JQuery Core Style Guidelines.
[jquery.git] / src / ajax.js
index 2c61cf2..790585d 100644 (file)
@@ -7,7 +7,7 @@ var r20 = /%20/g,
        rheaders = /^(.*?):\s*(.*?)\r?$/mg, // IE leaves an \r character at EOL
        rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
        // #7653, #8125, #8152: local protocol detection
-       rlocalProtocol = /(?:^file|\-extension):$/,
+       rlocalProtocol = /(?:^file|^widget|\-extension):$/,
        rnoContent = /^(?:GET|HEAD)$/,
        rprotocol = /^\/\//,
        rquery = /\?/,
@@ -15,7 +15,8 @@ var r20 = /%20/g,
        rselectTextarea = /^(?:select|textarea)/i,
        rspacesAjax = /\s+/,
        rts = /([?&])_=[^&]*/,
-       rurl = /^(\w+:)\/\/([^\/?#:]*)(?::(\d+))?/,
+       rucWord = /(^|\-)([a-z])/g,
+       rurl = /^([\w\+\.\-]+:)\/\/([^\/?#:]*)(?::(\d+))?/,
 
        // Keep a copy of the old load method
        _load = jQuery.fn.load,
@@ -113,9 +114,9 @@ function inspectPrefiltersOrTransports( structure, options, originalOptions, jqX
        for(; i < length && ( executeOnly || !selection ); i++ ) {
                selection = list[ i ]( options, originalOptions, jqXHR );
                // If we got redirected to another dataType
-               // we try there if not done already
+               // we try there if executing only and not done already
                if ( typeof selection === "string" ) {
-                       if ( inspected[ selection ] ) {
+                       if ( !executeOnly || inspected[ selection ] ) {
                                selection = undefined;
                        } else {
                                options.dataTypes.unshift( selection );
@@ -365,9 +366,10 @@ jQuery.extend({
                                ( s.context = ( "context" in options ? options : jQuery.ajaxSettings ).context ) || s,
                        // Context for global events
                        // It's the callbackContext if one was provided in the options
-                       // and if it's a DOM node
-                       globalEventContext = callbackContext !== s && callbackContext.nodeType ?
-                               jQuery( callbackContext ) : jQuery.event,
+                       // and if it's a DOM node or a jQuery collection
+                       globalEventContext = callbackContext !== s &&
+                               ( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
+                                               jQuery( callbackContext ) : jQuery.event,
                        // Deferreds
                        deferred = jQuery.Deferred(),
                        completeDeferred = jQuery._Deferred(),
@@ -388,6 +390,8 @@ jQuery.extend({
                        parts,
                        // The jqXHR state
                        state = 0,
+                       // To know if global events are to be dispatched
+                       fireGlobals,
                        // Loop variable
                        i,
                        // Fake xhr
@@ -397,8 +401,10 @@ jQuery.extend({
 
                                // Caches the header
                                setRequestHeader: function( name, value ) {
-                                       if ( state === 0 ) {
-                                               requestHeaders[ name.toLowerCase() ] = value;
+                                       if ( !state ) {
+                                               requestHeaders[ name.toLowerCase().replace( rucWord, function( _, $1, $2 ) {
+                                                       return $1 + $2.toUpperCase();
+                                               } ) ] = value;
                                        }
                                        return this;
                                },
@@ -423,6 +429,14 @@ jQuery.extend({
                                        return match || null;
                                },
 
+                               // Overrides response content-type header
+                               overrideMimeType: function( type ) {
+                                       if ( !state ) {
+                                               s.mimeType = type;
+                                       }
+                                       return this;
+                               },
+
                                // Cancel the request
                                abort: function( statusText ) {
                                        statusText = statusText || "abort";
@@ -437,7 +451,7 @@ jQuery.extend({
                // Callback for when everything is done
                // It is defined here because jslint complains if it is declared
                // at the end of the function (which would be more logical and readable)
-               function done( status, statusText, responses, headers) {
+               function done( status, statusText, responses, headers ) {
 
                        // Called once
                        if ( state === 2 ) {
@@ -506,7 +520,7 @@ jQuery.extend({
                                // We extract error from statusText
                                // then normalize statusText and status for non-aborts
                                error = statusText;
-                               if( status ) {
+                               if( !statusText || status ) {
                                        statusText = "error";
                                        if ( status < 0 ) {
                                                status = 0;
@@ -529,7 +543,7 @@ jQuery.extend({
                        jqXHR.statusCode( statusCode );
                        statusCode = undefined;
 
-                       if ( s.global ) {
+                       if ( fireGlobals ) {
                                globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
                                                [ jqXHR, s, isSuccess ? success : error ] );
                        }
@@ -537,7 +551,7 @@ jQuery.extend({
                        // Complete
                        completeDeferred.resolveWith( callbackContext, [ jqXHR, statusText ] );
 
-                       if ( s.global ) {
+                       if ( fireGlobals ) {
                                globalEventContext.trigger( "ajaxComplete", [ jqXHR, s] );
                                // Handle the global AJAX counter
                                if ( !( --jQuery.active ) ) {
@@ -594,6 +608,14 @@ jQuery.extend({
                // Apply prefilters
                inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
 
+               // If request was aborted inside a prefiler, stop there
+               if ( state === 2 ) {
+                       return false;
+               }
+
+               // We can fire global events as of now if asked to
+               fireGlobals = s.global;
+
                // Uppercase the type
                s.type = s.type.toUpperCase();
 
@@ -601,7 +623,7 @@ jQuery.extend({
                s.hasContent = !rnoContent.test( s.type );
 
                // Watch for a new set of requests
-               if ( s.global && jQuery.active++ === 0 ) {
+               if ( fireGlobals && jQuery.active++ === 0 ) {
                        jQuery.event.trigger( "ajaxStart" );
                }
 
@@ -630,77 +652,76 @@ jQuery.extend({
 
                // Set the correct header, if data is being sent
                if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
-                       requestHeaders[ "content-type" ] = s.contentType;
+                       requestHeaders[ "Content-Type" ] = s.contentType;
                }
 
                // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
                if ( s.ifModified ) {
                        ifModifiedKey = ifModifiedKey || s.url;
                        if ( jQuery.lastModified[ ifModifiedKey ] ) {
-                               requestHeaders[ "if-modified-since" ] = jQuery.lastModified[ ifModifiedKey ];
+                               requestHeaders[ "If-Modified-Since" ] = jQuery.lastModified[ ifModifiedKey ];
                        }
                        if ( jQuery.etag[ ifModifiedKey ] ) {
-                               requestHeaders[ "if-none-match" ] = jQuery.etag[ ifModifiedKey ];
+                               requestHeaders[ "If-None-Match" ] = jQuery.etag[ ifModifiedKey ];
                        }
                }
 
                // Set the Accepts header for the server, depending on the dataType
-               requestHeaders.accept = s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
+               requestHeaders.Accept = s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
                        s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) :
                        s.accepts[ "*" ];
 
                // Check for headers option
                for ( i in s.headers ) {
-                       requestHeaders[ i.toLowerCase() ] = s.headers[ i ];
+                       jqXHR.setRequestHeader( i, s.headers[ i ] );
                }
 
                // Allow custom headers/mimetypes and early abort
                if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
                                // Abort if not done already
-                               done( 0, "abort" );
-                               // Return false
-                               jqXHR = false;
+                               jqXHR.abort();
+                               return false;
 
-               } else {
+               }
 
-                       // Install callbacks on deferreds
-                       for ( i in { success: 1, error: 1, complete: 1 } ) {
-                               jqXHR[ i ]( s[ i ] );
-                       }
+               // Install callbacks on deferreds
+               for ( i in { success: 1, error: 1, complete: 1 } ) {
+                       jqXHR[ i ]( s[ i ] );
+               }
 
-                       // Get transport
-                       transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
+               // Get transport
+               transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
 
-                       // If no transport, we auto-abort
-                       if ( !transport ) {
-                               done( -1, "No Transport" );
-                       } else {
-                               // Set state as sending
-                               state = jqXHR.readyState = 1;
-                               // Send global event
-                               if ( s.global ) {
-                                       globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
-                               }
-                               // Timeout
-                               if ( s.async && s.timeout > 0 ) {
-                                       timeoutTimer = setTimeout( function(){
-                                               jqXHR.abort( "timeout" );
-                                       }, s.timeout );
-                               }
+               // If no transport, we auto-abort
+               if ( !transport ) {
+                       done( -1, "No Transport" );
+               } else {
+                       jqXHR.readyState = 1;
+                       // Send global event
+                       if ( fireGlobals ) {
+                               globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
+                       }
+                       // Timeout
+                       if ( s.async && s.timeout > 0 ) {
+                               timeoutTimer = setTimeout( function(){
+                                       jqXHR.abort( "timeout" );
+                               }, s.timeout );
+                       }
 
-                               try {
-                                       transport.send( requestHeaders, done );
-                               } catch (e) {
-                                       // Propagate exception as error if not done
-                                       if ( status < 2 ) {
-                                               done( -1, e );
-                                       // Simply rethrow otherwise
-                                       } else {
-                                               jQuery.error( e );
-                                       }
+                       try {
+                               state = 1;
+                               transport.send( requestHeaders, done );
+                       } catch (e) {
+                               // Propagate exception as error if not done
+                               if ( status < 2 ) {
+                                       done( -1, e );
+                               // Simply rethrow otherwise
+                               } else {
+                                       jQuery.error( e );
                                }
                        }
                }
+
                return jqXHR;
        },
 
@@ -817,7 +838,7 @@ function ajaxHandleResponses( s, jqXHR, responses ) {
        while( dataTypes[ 0 ] === "*" ) {
                dataTypes.shift();
                if ( ct === undefined ) {
-                       ct = jqXHR.getResponseHeader( "content-type" );
+                       ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
                }
        }