Removes unnecessary variables and adds much needed comments into the data conversion...
[jquery.git] / src / ajax.js
index d78542d..c307ba5 100644 (file)
@@ -10,7 +10,8 @@ var r20 = /%20/g,
        rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
        rselectTextarea = /^(?:select|textarea)/i,
        rts = /([?&])_=[^&]*/,
-       rurl = /^(\w+:)?\/\/([^\/?#]+)/,
+       rurl = /^(\w+:)?\/\/([^\/?#:]+)(?::(\d+))?/,
+       rCRLF = /\r?\n/g,
 
        // Slice function
        sliceFunc = Array.prototype.slice,
@@ -60,26 +61,34 @@ jQuery.fn.extend({
                        type: type,
                        dataType: "html",
                        data: params,
-                       complete: function( res, status ) {
+                       // Complete callback (responseText is used internally)
+                       complete: function( jXHR, status, responseText ) {
+                               // Store the response as specified by the jXHR object
+                               responseText = jXHR.responseText;
                                // If successful, inject the HTML into all the matched elements
-                               if ( status === "success" || status === "notmodified" ) {
+                               if ( jXHR.isResolved() ) {
+                                       // #4825: Get the actual response in case
+                                       // a dataFilter is present in ajaxSettings
+                                       jXHR.done(function( r ) {
+                                               responseText = r;
+                                       });
                                        // See if a selector was specified
                                        self.html( selector ?
                                                // Create a dummy div to hold the results
                                                jQuery("<div>")
                                                        // inject the contents of the document in, removing the scripts
                                                        // to avoid any 'Permission Denied' errors in IE
-                                                       .append(res.responseText.replace(rscript, ""))
+                                                       .append(responseText.replace(rscript, ""))
 
                                                        // Locate the specified elements
                                                        .find(selector) :
 
                                                // If not, just inject the full result
-                                               res.responseText );
+                                               responseText );
                                }
 
                                if ( callback ) {
-                                       self.each( callback, [res.responseText, status, res] );
+                                       self.each( callback, [responseText, status, jXHR] );
                                }
                        }
                });
@@ -107,9 +116,9 @@ jQuery.fn.extend({
                                null :
                                jQuery.isArray(val) ?
                                        jQuery.map( val, function(val, i){
-                                               return {name: elem.name, value: val.replace(/\r?\n/g, "\r\n")};
+                                               return { name: elem.name, value: val.replace(rCRLF, "\r\n") };
                                        }) :
-                                       {name: elem.name, value: val.replace(/\r?\n/g, "\r\n")};
+                                       { name: elem.name, value: val.replace(rCRLF, "\r\n") };
                }).get();
        }
 });
@@ -151,7 +160,7 @@ jQuery.extend({
        },
 
        ajaxSetup: function( settings ) {
-               jQuery.extend( jQuery.ajaxSettings, settings );
+               jQuery.extend( true, jQuery.ajaxSettings, settings );
        },
 
        ajaxSettings: {
@@ -265,6 +274,9 @@ jQuery.extend({
                        transport,
                        // timeout handle
                        timeoutTimer,
+                       // Cross-domain detection vars
+                       loc = document.location,
+                       parts,
                        // The jXHR state
                        state = 0,
                        // Loop variable
@@ -390,64 +402,86 @@ jQuery.extend({
                                        try {
 
                                                var i,
+                                                       // Current dataType
                                                        current,
+                                                       // Previous dataType
                                                        prev,
-                                                       checker,
+                                                       // Conversion function
                                                        conv,
+                                                       // Conversion functions (when text is used in-between)
                                                        conv1,
                                                        conv2,
-                                                       convertion,
+                                                       // Local references to dataTypes & converters
                                                        dataTypes = s.dataTypes,
                                                        converters = s.converters,
+                                                       // DataType to responseXXX field mapping
                                                        responses = {
                                                                "xml": "XML",
                                                                "text": "Text"
                                                        };
 
+                                               // For each dataType in the chain
                                                for( i = 0 ; i < dataTypes.length ; i++ ) {
 
                                                        current = dataTypes[ i ];
 
+                                                       // If a responseXXX field for this dataType exists
+                                                       // and if it hasn't been set yet
                                                        if ( responses[ current ] ) {
+                                                               // Set it
                                                                jXHR[ "response" + responses[ current ] ] = response;
+                                                               // Mark it as set
                                                                responses[ current ] = 0;
                                                        }
 
+                                                       // If this is not the first element
                                                        if ( i ) {
 
+                                                               // Get the dataType to convert from
                                                                prev = dataTypes[ i - 1 ];
 
+                                                               // If no catch-all and dataTypes are actually different
                                                                if ( prev !== "*" && current !== "*" && prev !== current ) {
 
-                                                                       conv = converters[ ( conversion = prev + " " + current ) ] ||
+                                                                       // Get the converter
+                                                                       conv = converters[ prev + " " + current ] ||
                                                                                converters[ "* " + current ];
 
                                                                        conv1 = conv2 = 0;
 
+                                                                       // If there is no direct converter and none of the dataTypes is text
                                                                        if ( ! conv && prev !== "text" && current !== "text" ) {
+                                                                               // Try with text in-between
                                                                                conv1 = converters[ prev + " text" ] || converters[ "* text" ];
                                                                                conv2 = converters[ "text " + current ];
+                                                                               // Revert back to a single converter
+                                                                               // if one of the converter is an equivalence
                                                                                if ( conv1 === true ) {
                                                                                        conv = conv2;
                                                                                } else if ( conv2 === true ) {
                                                                                        conv = conv1;
                                                                                }
                                                                        }
-
+                                                                       // If we found no converter, dispatch an error
                                                                        if ( ! ( conv || conv1 && conv2 ) ) {
                                                                                throw conversion;
                                                                        }
-
+                                                                       // If found converter is not an equivalence
                                                                        if ( conv !== true ) {
+                                                                               // Convert with 1 or 2 converters accordingly
                                                                                response = conv ? conv( response ) : conv2( conv1( response ) );
                                                                        }
                                                                }
+                                                       // If it is the first element of the chain
+                                                       // and we have a dataFilter
                                                        } else if ( s.dataFilter ) {
-
-                                                               response = s.dataFilter( response );
+                                                               // Apply the dataFilter
+                                                               response = s.dataFilter( response , current );
+                                                               // Get dataTypes again in case the filter changed them
                                                                dataTypes = s.dataTypes;
                                                        }
                                                }
+                                               // End of loop
 
                                                // We have a real success
                                                success = response;
@@ -464,6 +498,11 @@ jQuery.extend({
                        } else { // if not success, mark it as an error
 
                                        error = error || statusText;
+
+                                       // Set responseText if needed
+                                       if ( response ) {
+                                               jXHR.responseText = response;
+                                       }
                        }
 
                        // Set data for the fake xhr object
@@ -496,9 +535,9 @@ jQuery.extend({
 
                // Attach deferreds
                deferred.promise( jXHR );
-               jXHR.success = jXHR.complete;
+               jXHR.success = jXHR.done;
                jXHR.error = jXHR.fail;
-               jXHR.complete = completeDeferred.complete;
+               jXHR.complete = completeDeferred.done;
 
                // Remove hash character (#7531: and string promotion)
                s.url = ( "" + s.url ).replace( rhash , "" );
@@ -513,23 +552,29 @@ jQuery.extend({
                s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( /\s+/ );
 
                // Determine if a cross-domain request is in order
-               var parts = rurl.exec( s.url.toLowerCase() ),
-                       loc = location;
-               s.crossDomain = !!( parts && ( parts[ 1 ] && parts[ 1 ] != loc.protocol || parts[ 2 ] != loc.host ) );
+               if ( ! s.crossDomain ) {
+                       parts = rurl.exec( s.url.toLowerCase() );
+                       s.crossDomain = !!(
+                                       parts &&
+                                       ( parts[ 1 ] && parts[ 1 ] != loc.protocol ||
+                                               parts[ 2 ] != loc.hostname ||
+                                               ( parts[ 3 ] || 80 ) != ( loc.port || 80 ) )
+                       );
+               }
 
                // Convert data if not already a string
                if ( s.data && s.processData && typeof s.data != "string" ) {
                        s.data = jQuery.param( s.data , s.traditional );
                }
 
+               // Get transport
+               transport = jQuery.ajax.prefilter( s , options ).transport( s );
+
                // Watch for a new set of requests
                if ( s.global && jQuery.active++ === 0 ) {
                        jQuery.event.trigger( "ajaxStart" );
                }
 
-               // Get transport
-               transport = jQuery.ajax.prefilter( s ).transport( s );
-
                // If no transport, we auto-abort
                if ( ! transport ) {
 
@@ -559,7 +604,7 @@ jQuery.extend({
                        }
 
                        // Set the correct header, if data is being sent
-                       if ( ( s.data && s.hasContent ) || options.contentType ) {
+                       if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
                                requestHeaders[ "content-type" ] = s.contentType;
                        }