X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=src%2Fajax.js;h=cbe55727072168c245644dd429a2c24b6fe9a8de;hb=44f3a1b405e158615d9f2fca3238ccb12f9fa895;hp=3eb36c3a8e886e1ba07aac668774d3f184432aea;hpb=21143c3b213843bc202c16b5532b6e9de951eb2c;p=jquery.git diff --git a/src/ajax.js b/src/ajax.js index 3eb36c3..cbe5572 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -182,9 +182,6 @@ jQuery.extend({ headers: {}, crossDomain: null, */ - xhr: function() { - return new window.XMLHttpRequest(); - }, accepts: { xml: "application/xml, text/xml", @@ -232,12 +229,57 @@ jQuery.extend({ // Parse text as xml "text xml": jQuery.parseXML + }, + + // Utility function that handles dataType when response is received + // (for those transports that can give text or xml responses) + determineDataType: function( ct , text , xml ) { + + var s = this, + 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; } + }, // Main method - // (s is used internally) - ajax: function( url , options , s ) { + ajax: function( url , options ) { // Handle varargs if ( arguments.length === 1 ) { @@ -251,19 +293,14 @@ jQuery.extend({ // 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, + callbackContext = options.context || s.context || s, + globalEventContext = callbackContext === s ? jQuery.event : jQuery( callbackContext ), // Deferreds deferred = jQuery.Deferred(), completeDeferred = jQuery._Deferred(), @@ -280,6 +317,7 @@ jQuery.extend({ timeoutTimer, // Cross-domain detection vars loc = document.location, + protocol = loc.protocol || "http:", parts, // The jXHR state state = 0, @@ -304,30 +342,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 @@ -340,6 +373,10 @@ jQuery.extend({ } }; + // We force the original context + // (plain objects used as context get extended) + s.context = options.context; + // 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) @@ -355,7 +392,7 @@ jQuery.extend({ // Dereference transport for early garbage collection // (no matter how long the jXHR transport will be used - transport = 0; + transport = undefined; // Set readyState jXHR.readyState = status ? 4 : 0; @@ -378,7 +415,12 @@ jQuery.extend({ // Stored success success, // Stored error - error; + error, + + // Keep track of statusCode callbacks + oldStatusCode = statusCode; + + statusCode = undefined; // If successful, handle type chaining if ( status >= 200 && status < 300 || status === 304 ) { @@ -420,6 +462,8 @@ jQuery.extend({ current, // Previous dataType prev, + // Conversion expression + conversion, // Conversion function conv, // Conversion functions (when text is used in-between) @@ -458,8 +502,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; @@ -534,7 +578,7 @@ jQuery.extend({ } // Status-dependent callbacks - jXHR.statusCode( statusCode ); + jXHR.statusCode( oldStatusCode ); if ( s.global ) { globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ) , @@ -562,20 +606,14 @@ 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; @@ -584,12 +622,6 @@ jQuery.extend({ // Remove hash character (#7531: and string promotion) s.url = ( "" + s.url ).replace( rhash , "" ); - // Uppercase the type - s.type = s.type.toUpperCase(); - - // Determine if request has content - s.hasContent = ! rnoContent.test( s.type ); - // Extract dataTypes list s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( /\s+/ ); @@ -598,20 +630,27 @@ 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 ) ) ) ); } // Convert data if not already a string - if ( s.data && s.processData && typeof s.data != "string" ) { + if ( s.data && s.processData && typeof s.data !== "string" ) { s.data = jQuery.param( s.data , s.traditional ); } // Apply prefilters jQuery.ajaxPrefilter( s , options ); + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = ! rnoContent.test( s.type ); + // Watch for a new set of requests if ( s.global && jQuery.active++ === 0 ) { jQuery.event.trigger( "ajaxStart" ); @@ -679,7 +718,7 @@ jQuery.extend({ } // Get transport - transport = jQuery.ajaxTransport( s ); + transport = jQuery.ajaxTransport( s , options ); // If no transport, we auto-abort if ( ! transport ) { @@ -812,7 +851,7 @@ jQuery.extend({ }); //Execute or select from functions in a given structure of options -function ajax_selectOrExecute( structure , s ) { +function ajax_selectOrExecute( structure , s , options ) { var dataTypes = s.dataTypes, transportDataType, @@ -850,7 +889,7 @@ function ajax_selectOrExecute( structure , s ) { } else { - selected = list[ i ]( s , determineDataType ); + selected = list[ i ]( s , options ); // If we got redirected to another dataType // Search there (if not in progress or already tried) @@ -885,7 +924,7 @@ function ajax_addElement( structure , args ) { first = jQuery.type( args[ 0 ] ); if ( first === "object" ) { - return ajax_selectOrExecute( structure , args[ 0 ] ); + return ajax_selectOrExecute( structure , args[ 0 ] , args[ 1 ] ); } structure = jQuery.ajaxSettings[ structure ]; @@ -933,77 +972,4 @@ jQuery.each( [ "Prefilter" , "Transport" ] , function( _ , name ) { }; } ); -// 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 );