Merge branch 'make_fix' of https://github.com/danheberden/jquery into danheberden...
authorJohn Resig <jeresig@gmail.com>
Thu, 20 Jan 2011 19:39:28 +0000 (14:39 -0500)
committerJohn Resig <jeresig@gmail.com>
Thu, 20 Jan 2011 19:39:28 +0000 (14:39 -0500)
src/ajax.js
src/ajax/jsonp.js
src/ajax/script.js
src/ajax/xhr.js
src/core.js
test/unit/ajax.js
test/unit/core.js

index 871481d..bf0259c 100644 (file)
@@ -161,7 +161,9 @@ jQuery.extend({
 
        ajaxSetup: function( settings ) {
                jQuery.extend( true, jQuery.ajaxSettings, settings );
-               return this;
+               if ( settings.context ) {
+                       jQuery.ajaxSettings.context = settings.context;
+               }
        },
 
        ajaxSettings: {
@@ -182,9 +184,6 @@ jQuery.extend({
                headers: {},
                crossDomain: null,
                */
-               xhr: function() {
-                       return new window.XMLHttpRequest();
-               },
 
                accepts: {
                        xml: "application/xml, text/xml",
@@ -200,6 +199,11 @@ jQuery.extend({
                        json: /json/
                },
 
+               responseFields: {
+                       xml: "responseXML",
+                       text: "responseText"
+               },
+
                // Prefilters
                // 1) They are useful to introduce custom dataTypes (see transport/jsonp for an example)
                // 2) These are called:
@@ -235,35 +239,39 @@ jQuery.extend({
                }
        },
 
+       ajaxPrefilter: function( a , b ) {
+               ajaxPrefilterOrTransport( "prefilters" , a , b );
+       },
+
+       ajaxTransport: function( a , b ) {
+               return ajaxPrefilterOrTransport( "transports" , a , b );
+       },
+
        // Main method
-       // (s is used internally)
-       ajax: function( url , options , s ) {
+       ajax: function( url , options ) {
 
-               // Handle varargs
-               if ( arguments.length === 1 ) {
+               // If options is not an object,
+               // we simulate pre-1.5 signature
+               if ( typeof( options ) !== "object" ) {
                        options = url;
-                       url = options ? options.url : undefined;
+                       url = undefined;
                }
 
                // Force options to be an object
                options = options || {};
 
-               // Get the url if provided separately
-               options.url = url || options.url;
-
-               // Create the final options object
-               s = jQuery.extend( true , {} , jQuery.ajaxSettings , options );
-
-               // We force the original context
-               // (plain objects used as context get extended)
-               s.context = options.context;
-
-               var // jQuery lists
+               var // Create the final options object
+                       s = jQuery.extend( true , {} , jQuery.ajaxSettings , options ),
+                       // jQuery lists
                        jQuery_lastModified = jQuery.lastModified,
                        jQuery_etag = jQuery.etag,
                        // Callbacks contexts
-                       callbackContext = s.context || s,
-                       globalEventContext = s.context ? jQuery( s.context ) : jQuery.event,
+                       // We force the original context if it exists
+                       // or take it from jQuery.ajaxSettings otherwise
+                       // (plain objects used as context get extended)
+                       callbackContext =
+                               ( s.context = ( "context" in options ? options : jQuery.ajaxSettings ).context ) || s,
+                       globalEventContext = callbackContext === s ? jQuery.event : jQuery( callbackContext ),
                        // Deferreds
                        deferred = jQuery.Deferred(),
                        completeDeferred = jQuery._Deferred(),
@@ -280,6 +288,7 @@ jQuery.extend({
                        timeoutTimer,
                        // Cross-domain detection vars
                        loc = document.location,
+                       protocol = loc.protocol || "http:",
                        parts,
                        // The jXHR state
                        state = 0,
@@ -304,30 +313,25 @@ jQuery.extend({
                                },
 
                                // Builds headers hashtable if needed
-                               // (match is used internally)
-                               getResponseHeader: function( key , match ) {
+                               getResponseHeader: function( key ) {
+
+                                       var match;
 
                                        if ( state === 2 ) {
 
-                                               if ( responseHeaders === undefined ) {
+                                               if ( !responseHeaders ) {
 
                                                        responseHeaders = {};
 
-                                                       if ( typeof responseHeadersString === "string" ) {
-
-                                                               while( ( match = rheaders.exec( responseHeadersString ) ) ) {
-                                                                       responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
-                                                               }
+                                                       while( ( match = rheaders.exec( responseHeadersString ) ) ) {
+                                                               responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
                                                        }
                                                }
                                                match = responseHeaders[ key.toLowerCase() ];
 
-                                       } else {
-
-                                               match = null;
                                        }
 
-                                       return match;
+                                       return match || null;
                                },
 
                                // Cancel the request
@@ -343,7 +347,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 , response , headers) {
+               function done( status , statusText , responses , headers) {
 
                        // Called once
                        if ( state === 2 ) {
@@ -354,8 +358,8 @@ jQuery.extend({
                        state = 2;
 
                        // Dereference transport for early garbage collection
-                       // (no matter how long the jXHR transport will be used
-                       transport = 0;
+                       // (no matter how long the jXHR object will be used)
+                       transport = undefined;
 
                        // Set readyState
                        jXHR.readyState = status ? 4 : 0;
@@ -368,17 +372,73 @@ jQuery.extend({
                                clearTimeout(timeoutTimer);
                        }
 
-                       var // Reference url
-                               url = s.url,
-                               // and ifModified status
-                               ifModified = s.ifModified,
+                       var // Reference dataTypes and responseFields
+                               dataTypes = s.dataTypes,
+                               responseFields = s.responseFields,
+                               responseField,
 
-                               // Is it a success?
-                               isSuccess = 0,
+                               // Flag to mark as success
+                               isSuccess,
                                // Stored success
                                success,
                                // Stored error
-                               error;
+                               error,
+
+                               // To keep track of statusCode based callbacks
+                               oldStatusCode,
+
+                               // Actual response
+                               response;
+
+                       // If we got responses:
+                       // - find the right one
+                       // - update dataTypes accordingly
+                       // - set responseXXX accordingly too
+                       if ( responses ) {
+
+                               var contents = s.contents,
+                                       transportDataType = dataTypes[0],
+                                       ct,
+                                       type,
+                                       finalDataType;
+
+                               // Auto (xml, json, script or text determined given headers)
+                               if ( transportDataType === "*" && ( ct = jXHR.getResponseHeader( "content-type" ) ) ) {
+
+                                       for ( type in contents ) {
+                                               if ( contents[ type ] && contents[ type ].test( ct ) ) {
+                                                       transportDataType = dataTypes[0] = type;
+                                                       break;
+                                               }
+                                       }
+
+                                       type = undefined;
+                               }
+
+                               // Get final dataType
+                               for( type in responses ) {
+                                       if ( ! finalDataType && type === transportDataType ) {
+                                               finalDataType = type;
+                                       }
+                                       responseField = responseFields[ type ];
+                                       if ( responseField && ! ( responseField in jXHR ) ) {
+                                               jXHR[ responseField ] = responses[ type ];
+                                       }
+                               }
+
+                               // If no response with the expected dataType was provided
+                               // Take the last response as a default if it exists
+                               if ( ! finalDataType && type ) {
+                                       finalDataType = type;
+                                       if ( transportDataType === "*" ) {
+                                               dataTypes.shift();
+                                       }
+                                       dataTypes.unshift( finalDataType );
+                               }
+
+                               // Get final response
+                               response = responses[ finalDataType ];
+                       }
 
                        // If successful, handle type chaining
                        if ( status >= 200 && status < 300 || status === 304 ) {
@@ -400,15 +460,12 @@ jQuery.extend({
                                // If not modified
                                if ( status === 304 ) {
 
-                                       // Set the statusText accordingly
                                        statusText = "notmodified";
-                                       // Mark as a success
                                        isSuccess = 1;
 
                                // If we have data
                                } else {
 
-                                       // Set the statusText accordingly
                                        statusText = "success";
 
                                        // Chain data conversions and determine the final value
@@ -420,19 +477,15 @@ jQuery.extend({
                                                        current,
                                                        // Previous dataType
                                                        prev,
+                                                       // Conversion expression
+                                                       conversion,
                                                        // Conversion function
                                                        conv,
                                                        // Conversion functions (when text is used in-between)
                                                        conv1,
                                                        conv2,
-                                                       // Local references to dataTypes & converters
-                                                       dataTypes = s.dataTypes,
-                                                       converters = s.converters,
-                                                       // DataType to responseXXX field mapping
-                                                       responses = {
-                                                               "xml": "XML",
-                                                               "text": "Text"
-                                                       };
+                                                       // Local references to converters
+                                                       converters = s.converters;
 
                                                // For each dataType in the chain
                                                for( i = 0 ; i < dataTypes.length ; i++ ) {
@@ -441,11 +494,9 @@ jQuery.extend({
 
                                                        // 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;
+                                                       responseField = responseFields[ current ];
+                                                       if ( responseField && ! ( responseField in jXHR ) ) {
+                                                               jXHR[ responseField ] = response;
                                                        }
 
                                                        // If this is not the first element
@@ -458,8 +509,8 @@ jQuery.extend({
                                                                if ( prev !== "*" && current !== "*" && prev !== current ) {
 
                                                                        // Get the converter
-                                                                       conv = converters[ prev + " " + current ] ||
-                                                                               converters[ "* " + current ];
+                                                                       conversion = prev + " " + current;
+                                                                       conv = converters[ conversion ] || converters[ "* " + current ];
 
                                                                        conv1 = conv2 = 0;
 
@@ -513,13 +564,7 @@ jQuery.extend({
 
                        // if not success, mark it as an error
                        } else {
-
                                        error = statusText = statusText || "error";
-
-                                       // Set responseText if needed
-                                       if ( response ) {
-                                               jXHR.responseText = response;
-                                       }
                        }
 
                        // Set data for the fake xhr object
@@ -528,13 +573,15 @@ jQuery.extend({
 
                        // Success/Error
                        if ( isSuccess ) {
-                               deferred.fire( callbackContext , [ success , statusText , jXHR ] );
+                               deferred.resolveWith( callbackContext , [ success , statusText , jXHR ] );
                        } else {
-                               deferred.fireReject( callbackContext , [ jXHR , statusText , error ] );
+                               deferred.rejectWith( callbackContext , [ jXHR , statusText , error ] );
                        }
 
                        // Status-dependent callbacks
-                       jXHR.statusCode( statusCode );
+                       oldStatusCode = statusCode;
+                       statusCode = undefined;
+                       jXHR.statusCode( oldStatusCode );
 
                        if ( s.global ) {
                                globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ) ,
@@ -542,7 +589,7 @@ jQuery.extend({
                        }
 
                        // Complete
-                       completeDeferred.fire( callbackContext, [ jXHR , statusText ] );
+                       completeDeferred.resolveWith( callbackContext, [ jXHR , statusText ] );
 
                        if ( s.global ) {
                                globalEventContext.trigger( "ajaxComplete" , [ jXHR , s] );
@@ -562,27 +609,22 @@ jQuery.extend({
                // Status-dependent callbacks
                jXHR.statusCode = function( map ) {
                        if ( map ) {
-                               var resolved = jXHR.isResolved(),
-                                       tmp;
-                               if ( resolved || jXHR.isRejected() ) {
-                                       tmp = map[ jXHR.status ];
-                                       if ( tmp ) {
-                                               if ( map === statusCode ) {
-                                                       delete statusCode[ jXHR.status ];
-                                               }
-                                               jXHR[ resolved ? "done" : "fail" ]( tmp );
-                                       }
-                               } else {
+                               var tmp;
+                               if ( statusCode ) {
                                        for( tmp in map ) {
                                                statusCode[ tmp ] = [ statusCode[ tmp ] , map[ tmp ] ];
                                        }
+                               } else {
+                                       tmp = map[ jXHR.status ];
+                                       jXHR.done( tmp ).fail( tmp );
                                }
                        }
                        return this;
                };
 
                // Remove hash character (#7531: and string promotion)
-               s.url = ( "" + s.url ).replace( rhash , "" );
+               // We also use the url parameter if available
+               s.url = ( "" + ( url || s.url ) ).replace( rhash , "" );
 
                // Extract dataTypes list
                s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( /\s+/ );
@@ -592,9 +634,10 @@ jQuery.extend({
                        parts = rurl.exec( s.url.toLowerCase() );
                        s.crossDomain = !!(
                                        parts &&
-                                       ( parts[ 1 ] && parts[ 1 ] != loc.protocol ||
+                                       ( parts[ 1 ] && parts[ 1 ] != protocol ||
                                                parts[ 2 ] != loc.hostname ||
-                                               ( parts[ 3 ] || 80 ) != ( loc.port || 80 ) )
+                                               ( parts[ 3 ] || ( ( parts[ 1 ] || protocol ) === "http:" ? 80 : 443 ) ) !=
+                                                       ( loc.port || ( protocol === "http:" ? 80 : 443 ) ) )
                        );
                }
 
@@ -679,7 +722,7 @@ jQuery.extend({
                        }
 
                        // Get transport
-                       transport = jQuery.ajaxTransport( s );
+                       transport = jQuery.ajaxTransport( s , options );
 
                        // If no transport, we auto-abort
                        if ( ! transport ) {
@@ -811,199 +854,97 @@ jQuery.extend({
 
 });
 
-//Execute or select from functions in a given structure of options
-function ajax_selectOrExecute( structure , s ) {
+// Base function for both ajaxPrefilter and ajaxTransport
+function ajaxPrefilterOrTransport( arg0 , arg1 , arg2 ) {
 
-       var dataTypes = s.dataTypes,
-               transportDataType,
-               list,
-               selected,
+       var type = jQuery.type( arg1 ),
+               structure = jQuery.ajaxSettings[ arg0 ],
                i,
-               length,
-               checked = {},
-               flag,
-               noSelect = structure !== "transports";
-
-       function initSearch( dataType ) {
-
-               flag = transportDataType !== dataType && ! checked[ dataType ];
-
-               if ( flag ) {
-
-                       checked[ dataType ] = 1;
-                       transportDataType = dataType;
-                       list = s[ structure ][ dataType ];
-                       i = -1;
-                       length = list ? list.length : 0 ;
-               }
-
-               return flag;
-       }
-
-       initSearch( dataTypes[ 0 ] );
-
-       for ( i = 0 ; ( noSelect || ! selected ) && i <= length ; i++ ) {
-
-               if ( i === length ) {
-
-                       initSearch( "*" );
-
-               } else {
-
-                       selected = list[ i ]( s , determineDataType );
-
-                       // If we got redirected to another dataType
-                       // Search there (if not in progress or already tried)
-                       if ( typeof( selected ) === "string" &&
-                               initSearch( selected ) ) {
-
-                               dataTypes.unshift( selected );
-                               selected = 0;
-                       }
-               }
-       }
-
-       return noSelect ? jQuery : selected;
-}
-
-// Add an element to one of the structures in ajaxSettings
-function ajax_addElement( structure , args ) {
-
-       var i,
-               start = 0,
-               length = args.length,
-               dataTypes = [ "*" ],
-               dLength = 1,
-               dataType,
-               functors = [],
-               first,
-               append,
-               list;
-
-       if ( length ) {
-
-               first = jQuery.type( args[ 0 ] );
+               length;
+
+       // We have an options map so we have to inspect the structure
+       if ( type === "object" ) {
+
+               var options = arg1,
+                       originalOptions = arg2,
+                       // When dealing with prefilters, we execute only
+                       // (no selection so we never stop when a function
+                       // returns a non-falsy, non-string value)
+                       executeOnly = ( arg0 === "prefilters" ),
+                       inspect = function( dataType, tested ) {
+
+                               if ( ! tested[ dataType ] ) {
+
+                                       tested[ dataType ] = true;
+
+                                       var list = structure[ dataType ],
+                                               selected;
+
+                                       for( i = 0, length = list ? list.length : 0 ; ( executeOnly || ! selected ) && i < length ; i++ ) {
+                                               selected = list[ i ]( options , originalOptions );
+                                               // If we got redirected to a different dataType,
+                                               // we add it and switch to the corresponding list
+                                               if ( typeof( selected ) === "string" && selected !== dataType ) {
+                                                       options.dataTypes.unshift( selected );
+                                                       selected = inspect( selected , tested );
+                                                       // We always break in order not to continue
+                                                       // to iterate in previous list
+                                                       break;
+                                               }
+                                       }
+                                       // If we're only executing or nothing was selected
+                                       // we try the catchall dataType
+                                       if ( executeOnly || ! selected ) {
+                                               selected = inspect( "*" , tested );
+                                       }
+                                       // This will be ignored by ajaxPrefilter
+                                       // so it's safe to return no matter what
+                                       return selected;
+                               }
 
-               if ( first === "object" ) {
-                       return ajax_selectOrExecute( structure , args[ 0 ] );
-               }
+                       };
 
-               structure = jQuery.ajaxSettings[ structure ];
+               // Start inspection with current transport dataType
+               return inspect( options.dataTypes[ 0 ] , {} );
 
-               if ( first !== "function" ) {
+       } else {
 
-                       dataTypes = args[ 0 ].toLowerCase().split(/\s+/);
-                       dLength = dataTypes.length;
-                       start = 1;
+               // We're requested to add to the structure
+               // Signature is ( dataTypeExpression , function )
+               // with dataTypeExpression being optional and
+               // defaulting to catchAll (*)
+               type = type === "function";
 
+               if ( type ) {
+                       arg2 = arg1;
+                       arg1 = undefined;
                }
+               arg1 = arg1 || "*";
 
-               if ( dLength && start < length ) {
-
-                       functors = sliceFunc.call( args , start );
+               // We control that the second argument is really a function
+               if ( type || jQuery.isFunction( arg2 ) ) {
 
-                       for( i = 0 ; i < dLength ; i++ ) {
+                       var dataTypes = arg1.split( /\s+/ ),
+                               functor = arg2,
+                               dataType,
+                               list,
+                               placeBefore;
 
+                       // For each dataType in the dataTypeExpression
+                       for( i = 0 , length = dataTypes.length ; i < length ; i++ ) {
                                dataType = dataTypes[ i ];
-
-                               first = /^\+/.test( dataType );
-
-                               if (first) {
-                                       dataType = dataType.substr(1);
-                               }
-
-                               if ( dataType !== "" ) {
-
-                                       append = Array.prototype[ first ? "unshift" : "push" ];
-                                       list = structure[ dataType ] = structure[ dataType ] || [];
-                                       append.apply( list , functors );
+                               // We control if we're asked to add before
+                               // any existing element
+                               placeBefore = /^\+/.test( dataType );
+                               if ( placeBefore ) {
+                                       dataType = dataType.substr( 1 );
                                }
+                               list = structure[ dataType ] = structure[ dataType ] || [];
+                               // then we add to the structure accordingly
+                               list[ placeBefore ? "unshift" : "push" ]( functor );
                        }
                }
        }
-
-       return jQuery;
 }
 
-// Install prefilter & transport methods
-jQuery.each( [ "Prefilter" , "Transport" ] , function( _ , name ) {
-       _ = name.toLowerCase() + "s";
-       jQuery[ "ajax" + name ] = function() {
-               return ajax_addElement( _ , arguments );
-       };
-} );
-
-// Utility function that handles dataType when response is received
-// (for those transports that can give text or xml responses)
-function determineDataType( s , ct , text , xml ) {
-
-       var contents = s.contents,
-               type,
-               regexp,
-               dataTypes = s.dataTypes,
-               transportDataType = dataTypes[0],
-               response;
-
-       // Auto (xml, json, script or text determined given headers)
-       if ( transportDataType === "*" ) {
-
-               for ( type in contents ) {
-                       if ( ( regexp = contents[ type ] ) && regexp.test( ct ) ) {
-                               transportDataType = dataTypes[0] = type;
-                               break;
-                       }
-               }
-       }
-
-       // xml and parsed as such
-       if ( transportDataType === "xml" &&
-               xml &&
-               xml.documentElement /* #4958 */ ) {
-
-               response = xml;
-
-       // Text response was provided
-       } else {
-
-               response = text;
-
-               // If it's not really text, defer to converters
-               if ( transportDataType !== "text" ) {
-                       dataTypes.unshift( "text" );
-               }
-
-       }
-
-       return response;
-}
-
-/*
- * Create the request object; Microsoft failed to properly
- * implement the XMLHttpRequest in IE7 (can't request local files),
- * so we use the ActiveXObject when it is available
- * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
- * we need a fallback.
- */
-if ( window.ActiveXObject ) {
-       jQuery.ajaxSettings.xhr = function() {
-       if ( window.location.protocol !== "file:" ) {
-               try {
-                       return new window.XMLHttpRequest();
-               } catch( xhrError ) {}
-       }
-
-       try {
-               return new window.ActiveXObject("Microsoft.XMLHTTP");
-       } catch( activeError ) {}
-       };
-}
-
-var testXHR = jQuery.ajaxSettings.xhr();
-
-// Does this browser support XHR requests?
-jQuery.support.ajax = !!testXHR;
-
-// Does this browser support crossDomain XHR requests
-jQuery.support.cors = testXHR && "withCredentials" in testXHR;
-
 })( jQuery );
index 883876f..ff8d1f1 100644 (file)
@@ -9,10 +9,11 @@ jQuery.ajaxSetup({
        jsonpCallback: function() {
                return "jsonp" + jsc++;
        }
+});
 
 // Detect, normalize options and install callbacks for jsonp requests
 // (dataIsString is used internally)
-}).ajaxPrefilter("json jsonp", function(s, originalSettings, dataIsString) {
+jQuery.ajaxPrefilter("json jsonp", function(s, originalSettings, dataIsString) {
 
        dataIsString = ( typeof(s.data) === "string" );
 
index b0e576f..bdf69dd 100644 (file)
@@ -14,9 +14,10 @@ jQuery.ajaxSetup({
        converters: {
                "text script": jQuery.globalEval
        }
+});
 
 // Handle cache's special case and global
-}).ajaxPrefilter("script", function(s) {
+jQuery.ajaxPrefilter("script", function(s) {
 
        if ( s.cache === undefined ) {
                s.cache = false;
@@ -26,9 +27,10 @@ jQuery.ajaxSetup({
                s.type = "GET";
                s.global = false;
        }
+});
 
 // Bind script tag hack transport
-}).ajaxTransport("script", function(s) {
+jQuery.ajaxTransport("script", function(s) {
 
        // This transport only deals with cross domain requests
        if ( s.crossDomain ) {
index 34aa832..7a4da2d 100644 (file)
@@ -7,177 +7,219 @@ var // Next active xhr id
        xhrs = {},
 
        // #5280: see below
-       xhrUnloadAbortInstalled;
+       xhrUnloadAbortInstalled,
 
+       // XHR used to determine supports properties
+       testXHR;
 
-jQuery.ajaxTransport( function( s , determineDataType ) {
+// Create the request object
+// (This is still attached to ajaxSettings for backward compatibility)
+jQuery.ajaxSettings.xhr = window.ActiveXObject ?
+       /* Microsoft failed to properly
+        * implement the XMLHttpRequest in IE7 (can't request local files),
+        * so we use the ActiveXObject when it is available
+        * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
+        * we need a fallback.
+        */
+       function() {
+               if ( window.location.protocol !== "file:" ) {
+                       try {
+                               return new window.XMLHttpRequest();
+                       } catch( xhrError ) {}
+               }
 
-       // Cross domain only allowed if supported through XMLHttpRequest
-       if ( ! s.crossDomain || jQuery.support.cors ) {
+               try {
+                       return new window.ActiveXObject("Microsoft.XMLHTTP");
+               } catch( activeError ) {}
+       } :
+       // For all other browsers, use the standard XMLHttpRequest object
+       function() {
+               return new window.XMLHttpRequest();
+       };
 
-               var callback;
+// Test if we can create an xhr object
+try {
+       testXHR = jQuery.ajaxSettings.xhr();
+} catch( xhrCreationException ) {}
 
-               return {
+//Does this browser support XHR requests?
+jQuery.support.ajax = !!testXHR;
 
-                       send: function(headers, complete) {
+// Does this browser support crossDomain XHR requests
+jQuery.support.cors = testXHR && "withCredentials" in testXHR;
 
-                               // #5280: we need to abort on unload or IE will keep connections alive
-                               if ( ! xhrUnloadAbortInstalled ) {
+// No need for the temporary xhr anymore
+testXHR = undefined;
 
-                                       xhrUnloadAbortInstalled = 1;
+// Create transport if the browser can provide an xhr
+if ( jQuery.support.ajax ) {
+       jQuery.ajaxTransport( function( s ) {
 
-                                       jQuery(window).bind( "unload" , function() {
+               // Cross domain only allowed if supported through XMLHttpRequest
+               if ( ! s.crossDomain || jQuery.support.cors ) {
 
-                                               // Abort all pending requests
-                                               jQuery.each(xhrs, function(_, xhr) {
-                                                       if ( xhr.onreadystatechange ) {
-                                                               xhr.onreadystatechange( 1 );
-                                                       }
-                                               });
+                       var callback;
 
-                                       });
-                               }
+                       return {
 
-                               // Get a new xhr
-                               var xhr = s.xhr(),
-                                       handle;
+                               send: function(headers, complete) {
 
-                               // Open the socket
-                               // Passing null username, generates a login popup on Opera (#2865)
-                               if ( s.username ) {
-                                       xhr.open(s.type, s.url, s.async, s.username, s.password);
-                               } else {
-                                       xhr.open(s.type, s.url, s.async);
-                               }
+                                       // #5280: we need to abort on unload or IE will keep connections alive
+                                       if ( ! xhrUnloadAbortInstalled ) {
 
-                               // Requested-With header
-                               // Not set for crossDomain requests with no content
-                               // (see why at http://trac.dojotoolkit.org/ticket/9486)
-                               // Won't change header if already provided
-                               if ( ! ( s.crossDomain && ! s.hasContent ) && ! headers["x-requested-with"] ) {
-                                       headers["x-requested-with"] = "XMLHttpRequest";
-                               }
+                                               xhrUnloadAbortInstalled = 1;
+
+                                               jQuery(window).bind( "unload" , function() {
+
+                                                       // Abort all pending requests
+                                                       jQuery.each(xhrs, function(_, xhr) {
+                                                               if ( xhr.onreadystatechange ) {
+                                                                       xhr.onreadystatechange( 1 );
+                                                               }
+                                                       });
 
-                               // Need an extra try/catch for cross domain requests in Firefox 3
-                               try {
+                                               });
+                                       }
 
-                                       jQuery.each(headers, function(key,value) {
-                                               xhr.setRequestHeader(key,value);
-                                       });
+                                       // Get a new xhr
+                                       var xhr = s.xhr(),
+                                               handle;
 
-                               } catch(_) {}
+                                       // Open the socket
+                                       // Passing null username, generates a login popup on Opera (#2865)
+                                       if ( s.username ) {
+                                               xhr.open(s.type, s.url, s.async, s.username, s.password);
+                                       } else {
+                                               xhr.open(s.type, s.url, s.async);
+                                       }
 
-                               // Do send the request
-                               try {
-                                       xhr.send( ( s.hasContent && s.data ) || null );
-                               } catch(e) {
-                                       complete(0, "error", "" + e);
-                                       return;
-                               }
+                                       // Requested-With header
+                                       // Not set for crossDomain requests with no content
+                                       // (see why at http://trac.dojotoolkit.org/ticket/9486)
+                                       // Won't change header if already provided
+                                       if ( ! ( s.crossDomain && ! s.hasContent ) && ! headers["x-requested-with"] ) {
+                                               headers["x-requested-with"] = "XMLHttpRequest";
+                                       }
 
-                               // Listener
-                               callback = function( _ , isAbort ) {
+                                       // Need an extra try/catch for cross domain requests in Firefox 3
+                                       try {
 
-                                       // Was never called and is aborted or complete
-                                       if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
+                                               jQuery.each(headers, function(key,value) {
+                                                       xhr.setRequestHeader(key,value);
+                                               });
 
-                                               // Only called once
-                                               callback = 0;
+                                       } catch(_) {}
 
-                                               // Do not keep as active anymore
-                                               // and store back into pool
-                                               if (handle) {
-                                                       xhr.onreadystatechange = jQuery.noop;
-                                                       delete xhrs[ handle ];
-                                               }
+                                       // Do send the request
+                                       try {
+                                               xhr.send( ( s.hasContent && s.data ) || null );
+                                       } catch(e) {
+                                               complete(0, "error", "" + e);
+                                               return;
+                                       }
+
+                                       // Listener
+                                       callback = function( _ , isAbort ) {
 
-                                               // If it's an abort
-                                               if ( isAbort ) {
+                                               // Was never called and is aborted or complete
+                                               if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
 
-                                                       // Abort it manually if needed
-                                                       if ( xhr.readyState !== 4 ) {
-                                                               xhr.abort();
+                                                       // Only called once
+                                                       callback = 0;
+
+                                                       // Do not keep as active anymore
+                                                       if (handle) {
+                                                               xhr.onreadystatechange = jQuery.noop;
+                                                               delete xhrs[ handle ];
                                                        }
-                                               } else {
 
-                                                       // Get info
-                                                       var status = xhr.status,
-                                                               statusText,
-                                                               response,
-                                                               responseHeaders = xhr.getAllResponseHeaders();
+                                                       // If it's an abort
+                                                       if ( isAbort ) {
 
-                                                       try { // Firefox throws an exception when accessing statusText for faulty cross-domain requests
+                                                               // Abort it manually if needed
+                                                               if ( xhr.readyState !== 4 ) {
+                                                                       xhr.abort();
+                                                               }
+                                                       } else {
 
-                                                               statusText = xhr.statusText;
+                                                               // Get info
+                                                               var status = xhr.status,
+                                                                       statusText,
+                                                                       responseHeaders = xhr.getAllResponseHeaders(),
+                                                                       responses = {},
+                                                                       xml = xhr.responseXML;
 
-                                                       } catch( e ) {
+                                                               // Construct response list
+                                                               if ( xml && xml.documentElement /* #4958 */ ) {
+                                                                       responses.xml = xml;
+                                                               }
+                                                               responses.text = xhr.responseText;
 
-                                                               statusText = ""; // We normalize with Webkit giving an empty statusText
+                                                               try { // Firefox throws an exception when accessing statusText for faulty cross-domain requests
 
-                                                       }
+                                                                       statusText = xhr.statusText;
+
+                                                               } catch( e ) {
+
+                                                                       statusText = ""; // We normalize with Webkit giving an empty statusText
+
+                                                               }
 
-                                                       // Filter status for non standard behaviours
-                                                       // (so many they seem to be the actual "standard")
-                                                       status =
-                                                               // Opera returns 0 when it should be 304
-                                                               // Webkit returns 0 for failing cross-domain no matter the real status
-                                                               status === 0 ?
-                                                                       (
-                                                                               ! s.crossDomain || statusText ? // Webkit, Firefox: filter out faulty cross-domain requests
+                                                               // Filter status for non standard behaviours
+                                                               // (so many they seem to be the actual "standard")
+                                                               status =
+                                                                       // Opera returns 0 when it should be 304
+                                                                       // Webkit returns 0 for failing cross-domain no matter the real status
+                                                                       status === 0 ?
                                                                                (
-                                                                                       responseHeaders ? // Opera: filter out real aborts #6060
-                                                                                       304
+                                                                                       ! s.crossDomain || statusText ? // Webkit, Firefox: filter out faulty cross-domain requests
+                                                                                       (
+                                                                                               responseHeaders ? // Opera: filter out real aborts #6060
+                                                                                               304
+                                                                                               :
+                                                                                               0
+                                                                                       )
                                                                                        :
-                                                                                       0
+                                                                                       302 // We assume 302 but could be anything cross-domain related
                                                                                )
                                                                                :
-                                                                               302 // We assume 302 but could be anything cross-domain related
-                                                                       )
-                                                                       :
-                                                                       (
-                                                                               status == 1223 ?        // IE sometimes returns 1223 when it should be 204 (see #1450)
-                                                                                       204
-                                                                                       :
-                                                                                       status
-                                                                       );
-
-                                                       // Guess response & update dataType accordingly
-                                                       response =
-                                                               determineDataType(
-                                                                       s,
-                                                                       xhr.getResponseHeader("content-type"),
-                                                                       xhr.responseText,
-                                                                       xhr.responseXML );
-
-                                                       // Call complete
-                                                       complete(status,statusText,response,responseHeaders);
+                                                                               (
+                                                                                       status == 1223 ?        // IE sometimes returns 1223 when it should be 204 (see #1450)
+                                                                                               204
+                                                                                               :
+                                                                                               status
+                                                                               );
+
+                                                               // Call complete
+                                                               complete(status,statusText,responses,responseHeaders);
+                                                       }
                                                }
-                                       }
-                               };
+                                       };
 
-                               // if we're in sync mode
-                               // or it's in cache and has been retrieved directly (IE6 & IE7)
-                               // we need to manually fire the callback
-                               if ( ! s.async || xhr.readyState === 4 ) {
+                                       // if we're in sync mode
+                                       // or it's in cache and has been retrieved directly (IE6 & IE7)
+                                       // we need to manually fire the callback
+                                       if ( ! s.async || xhr.readyState === 4 ) {
 
-                                       callback();
+                                               callback();
 
-                               } else {
+                                       } else {
 
-                                       // Add to list of active xhrs
-                                       handle = xhrId++;
-                                       xhrs[ handle ] = xhr;
-                                       xhr.onreadystatechange = callback;
-                               }
-                       },
+                                               // Add to list of active xhrs
+                                               handle = xhrId++;
+                                               xhrs[ handle ] = xhr;
+                                               xhr.onreadystatechange = callback;
+                                       }
+                               },
 
-                       abort: function() {
-                               if ( callback ) {
-                                       callback(0,1);
+                               abort: function() {
+                                       if ( callback ) {
+                                               callback(0,1);
+                                       }
                                }
-                       }
-               };
-       }
-});
+                       };
+               }
+       });
+}
 
 })( jQuery );
index f116ef4..236f84d 100644 (file)
@@ -134,7 +134,7 @@ jQuery.fn = jQuery.prototype = {
                                        }
 
                                        return jQuery.merge( this, selector );
-
+                                       
                                // HANDLE: $("#id")
                                } else {
                                        elem = document.getElementById( match[2] );
@@ -158,13 +158,6 @@ jQuery.fn = jQuery.prototype = {
                                        return this;
                                }
 
-                       // HANDLE: $("TAG")
-                       } else if ( !context && !rnonword.test( selector ) ) {
-                               this.selector = selector;
-                               this.context = document;
-                               selector = document.getElementsByTagName( selector );
-                               return jQuery.merge( this, selector );
-
                        // HANDLE: $(expr, $(...))
                        } else if ( !context || context.jquery ) {
                                return (context || rootjQuery).find( selector );
@@ -406,7 +399,7 @@ jQuery.extend({
                        }
 
                        // If there are functions bound, to execute
-                       readyList.fire( document , [ jQuery ] );
+                       readyList.resolveWith( document , [ jQuery ] );
 
                        // Trigger any bound ready events
                        if ( jQuery.fn.trigger ) {
@@ -844,7 +837,7 @@ jQuery.extend({
                                                }
 
                                                if ( _fired ) {
-                                                       deferred.fire( _fired[ 0 ] , _fired[ 1 ] );
+                                                       deferred.resolveWith( _fired[ 0 ] , _fired[ 1 ] );
                                                }
                                        }
 
@@ -852,7 +845,7 @@ jQuery.extend({
                                },
 
                                // resolve with given context and args
-                               fire: function( context , args ) {
+                               resolveWith: function( context , args ) {
                                        if ( ! cancelled && ! fired && ! firing ) {
 
                                                firing = 1;
@@ -872,7 +865,7 @@ jQuery.extend({
 
                                // resolve with this as context and given arguments
                                resolve: function() {
-                                       deferred.fire( jQuery.isFunction( this.promise ) ? this.promise() : this , arguments );
+                                       deferred.resolveWith( jQuery.isFunction( this.promise ) ? this.promise() : this , arguments );
                                        return this;
                                },
 
@@ -908,7 +901,7 @@ jQuery.extend({
                                return this;
                        },
                        fail: failDeferred.done,
-                       fireReject: failDeferred.fire,
+                       rejectWith: failDeferred.resolveWith,
                        reject: failDeferred.resolve,
                        isRejected: failDeferred.isResolved,
                        // Get a promise for this deferred
@@ -961,10 +954,10 @@ jQuery.extend({
                                        args = arguments;
                                        resolveArray[ index ] = args.length > 1 ? slice.call( args , 0 ) : value;
                                        if( ! --length ) {
-                                               deferred.fire( promise, resolveArray );
+                                               deferred.resolveWith( promise, resolveArray );
                                        }
                                }).fail( function() {
-                                       deferred.fireReject( promise, arguments );
+                                       deferred.rejectWith( promise, arguments );
                                });
                                return !deferred.isRejected();
                        });
index 3f672ae..1ed15b5 100644 (file)
@@ -599,6 +599,47 @@ test("jQuery.ajax context modification", function() {
        equals( obj.test, "foo", "Make sure the original object is maintained." );
 });
 
+test("jQuery.ajax context modification through ajaxSetup", function() {
+       expect(4);
+
+       stop();
+
+       var obj = {};
+
+       jQuery.ajaxSetup({
+               context: obj
+       });
+
+       strictEqual( jQuery.ajaxSettings.context, obj, "Make sure the context is properly set in ajaxSettings." );
+
+       jQuery.ajax({
+               url: url("data/name.html"),
+               complete: function() {
+                       strictEqual( this, obj, "Make sure the original object is maintained." );
+                       jQuery.ajax({
+                               url: url("data/name.html"),
+                               context: {},
+                               complete: function() {
+                                       ok( this !== obj, "Make sure overidding context is possible." );
+                                       jQuery.ajaxSetup({
+                                               context: false
+                                       });
+                                       jQuery.ajax({
+                                               url: url("data/name.html"),
+                                               beforeSend: function(){
+                                                       this.test = "foo2";
+                                               },
+                                               complete: function() {
+                                                       ok( this !== obj, "Make sure unsetting context is possible." );
+                                                       start();
+                                               }
+                                       });
+                               }
+                       });
+               }
+       });
+});
+
 test("jQuery.ajax() - disabled globals", function() {
        expect( 3 );
        stop();
@@ -1857,10 +1898,6 @@ test("jQuery ajax - atom+xml", function() {
 
 });
 
-test("jQuery.ajax - active counter", function() {
-    ok( jQuery.active == 0, "ajax active counter should be zero: " + jQuery.active );
-});
-
 test( "jQuery.ajax - Location object as url (#7531)", 1, function () {
        var success = false;
        try {
@@ -1874,9 +1911,9 @@ test( "jQuery.ajax - Location object as url (#7531)", 1, function () {
 
 test( "jQuery.ajax - statusCode" , function() {
 
-       var count = 10;
+       var count = 12;
 
-       expect( 16 );
+       expect( 20 );
        stop();
 
        function countComplete() {
@@ -1938,8 +1975,39 @@ test( "jQuery.ajax - statusCode" , function() {
                        }
                }).statusCode( createStatusCodes( "all (immediately with method)" , isSuccess ) );
 
+               var testString = "";
+
+               jQuery.ajax( url( uri ), {
+                       success: function( a , b , jXHR ) {
+                               ok( isSuccess , "success" );
+                               var statusCode = {};
+                               statusCode[ jXHR.status ] = function() {
+                                       testString += "B";
+                               };
+                               jXHR.statusCode( statusCode );
+                               testString += "A";
+                       },
+                       error: function( jXHR ) {
+                               ok( ! isSuccess , "error" );
+                               var statusCode = {};
+                               statusCode[ jXHR.status ] = function() {
+                                       testString += "B";
+                               };
+                               jXHR.statusCode( statusCode );
+                               testString += "A";
+                       },
+                       complete: function() {
+                               strictEqual( testString , "AB" , "Test statusCode callbacks are ordered like " +
+                                               ( isSuccess ? "success" :  "error" ) + " callbacks" );
+                               countComplete();
+                       }
+               } );
+
        });
+});
 
+test("jQuery.ajax - active counter", function() {
+    ok( jQuery.active == 0, "ajax active counter should be zero: " + jQuery.active );
 });
 
 }
index 8e57edf..30039bf 100644 (file)
@@ -1002,7 +1002,7 @@ test("jQuery._Deferred()", function() {
 
        deferred = jQuery._Deferred();
 
-       deferred.fire( jQuery , [ document ] ).done( function( doc ) {
+       deferred.resolveWith( jQuery , [ document ] ).done( function( doc ) {
                ok( this === jQuery && arguments.length === 1 && doc === document , "Test fire context & args" );
        });
 });