X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=src%2Fajax.js;h=871481d01ab832b319a2ea4ce8e54f84f6b86213;hb=158fa822dea3198de5a4bcff3955b869ebb758c8;hp=c307ba50d6bcf7387bace1b99fd3c081acc362f5;hpb=97b244312e5dba9b28129006c9407ca80bb6c99b;p=jquery.git diff --git a/src/ajax.js b/src/ajax.js index c307ba5..871481d 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -161,6 +161,7 @@ jQuery.extend({ ajaxSetup: function( settings ) { jQuery.extend( true, jQuery.ajaxSettings, settings ); + return this; }, ajaxSettings: { @@ -174,11 +175,12 @@ jQuery.extend({ timeout: 0, data: null, dataType: null, - dataTypes: null, username: null, password: null, cache: null, traditional: false, + headers: {}, + crossDomain: null, */ xhr: function() { return new window.XMLHttpRequest(); @@ -265,6 +267,8 @@ jQuery.extend({ // Deferreds deferred = jQuery.Deferred(), completeDeferred = jQuery._Deferred(), + // Status-dependent callbacks + statusCode = s.statusCode || {}, // Headers (they are sent all at once) requestHeaders = {}, // Response headers @@ -303,30 +307,35 @@ jQuery.extend({ // (match is used internally) getResponseHeader: function( key , match ) { - if ( state !== 2 ) { - return null; - } + if ( state === 2 ) { - if ( responseHeaders === undefined ) { + if ( responseHeaders === undefined ) { - responseHeaders = {}; + responseHeaders = {}; - if ( typeof responseHeadersString === "string" ) { + 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 responseHeaders[ key.toLowerCase() ]; + + return match; }, // Cancel the request abort: function( statusText ) { - if ( transport && state !== 2 ) { + if ( transport ) { transport.abort( statusText || "abort" ); - done( 0 , statusText ); } + done( 0 , statusText ); return this; } }; @@ -344,6 +353,10 @@ jQuery.extend({ // State is "done" now state = 2; + // Dereference transport for early garbage collection + // (no matter how long the jXHR transport will be used + transport = 0; + // Set readyState jXHR.readyState = status ? 4 : 0; @@ -365,17 +378,10 @@ jQuery.extend({ // Stored success success, // Stored error - error = statusText; - - // If not timeout, force a jQuery-compliant status text - if ( statusText != "timeout" ) { - statusText = ( status >= 200 && status < 300 ) ? - "success" : - ( status === 304 ? "notmodified" : "error" ); - } + error; // If successful, handle type chaining - if ( statusText === "success" || statusText === "notmodified" ) { + if ( status >= 200 && status < 300 || status === 304 ) { // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. if ( s.ifModified ) { @@ -391,12 +397,20 @@ jQuery.extend({ } } - if ( s.ifModified && statusText === "notmodified" ) { + // If not modified + if ( status === 304 ) { - success = null; + // 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 // (if an exception is thrown in the process, it'll be notified as an error) try { @@ -487,17 +501,20 @@ jQuery.extend({ success = response; isSuccess = 1; + // If an exception was thrown } catch(e) { + // We have a parsererror statusText = "parsererror"; error = "" + e; } } - } else { // if not success, mark it as an error + // if not success, mark it as an error + } else { - error = error || statusText; + error = statusText = statusText || "error"; // Set responseText if needed if ( response ) { @@ -516,6 +533,9 @@ jQuery.extend({ deferred.fireReject( callbackContext , [ jXHR , statusText , error ] ); } + // Status-dependent callbacks + jXHR.statusCode( statusCode ); + if ( s.global ) { globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ) , [ jXHR , s , isSuccess ? success : error ] ); @@ -539,15 +559,31 @@ jQuery.extend({ jXHR.error = jXHR.fail; jXHR.complete = completeDeferred.done; + // 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 { + for( tmp in map ) { + statusCode[ tmp ] = [ statusCode[ tmp ] , map[ tmp ] ]; + } + } + } + return this; + }; + // 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+/ ); @@ -563,88 +599,97 @@ jQuery.extend({ } // 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 ); } - // Get transport - transport = jQuery.ajax.prefilter( s , options ).transport( s ); + // 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" ); } - // If no transport, we auto-abort - if ( ! transport ) { - - done( 0 , "transport not found" ); - jXHR = false; + // More options handling for requests with no content + if ( ! s.hasContent ) { - } else { + // If data is available, append data to url + if ( s.data ) { + s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data; + } - // More options handling for requests with no content - if ( ! s.hasContent ) { + // Add anti-cache in url if needed + if ( s.cache === false ) { - // If data is available, append data to url - if ( s.data ) { - s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data; - } + var ts = jQuery.now(), + // try replacing _= if it is there + ret = s.url.replace( rts , "$1_=" + ts ); - // Add anti-cache in url if needed - if ( s.cache === false ) { + // if nothing was replaced, add timestamp to the end + s.url = ret + ( (ret == s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : ""); + } + } - var ts = jQuery.now(), - // try replacing _= if it is there - ret = s.url.replace( rts , "$1_=" + ts ); + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + requestHeaders[ "content-type" ] = s.contentType; + } - // if nothing was replaced, add timestamp to the end - s.url = ret + ( (ret == s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : ""); - } + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery_lastModified[ s.url ] ) { + requestHeaders[ "if-modified-since" ] = jQuery_lastModified[ s.url ]; } - - // Set the correct header, if data is being sent - if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { - requestHeaders[ "content-type" ] = s.contentType; + if ( jQuery_etag[ s.url ] ) { + requestHeaders[ "if-none-match" ] = jQuery_etag[ s.url ]; } + } - // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. - if ( s.ifModified ) { - if ( jQuery_lastModified[ s.url ] ) { - requestHeaders[ "if-modified-since" ] = jQuery_lastModified[ s.url ]; - } - if ( jQuery_etag[ s.url ] ) { - requestHeaders[ "if-none-match" ] = jQuery_etag[ s.url ]; - } - } + // Set the Accepts header for the server, depending on the dataType + 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 ]; + } - // Set the Accepts header for the server, depending on the dataType - requestHeaders.accept = s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? - s.accepts[ s.dataTypes[ 0 ] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) : - s.accepts[ "*" ]; + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && ( s.beforeSend.call( callbackContext , jXHR , s ) === false || state === 2 ) ) { - // Check for headers option - for ( i in s.headers ) { - requestHeaders[ i.toLowerCase() ] = s.headers[ i ]; + // Abort if not done already + done( 0 , "abort" ); + + // Return false + jXHR = false; + + } else { + + // Install callbacks on deferreds + for ( i in { success:1, error:1, complete:1 } ) { + jXHR[ i ]( s[ i ] ); } - // Allow custom headers/mimetypes and early abort - if ( s.beforeSend && ( s.beforeSend.call( callbackContext , jXHR , s ) === false || state === 2 ) ) { + // Get transport + transport = jQuery.ajaxTransport( s ); - // Abort if not done already - done( 0 , "abort" ); - jXHR = false; + // If no transport, we auto-abort + if ( ! transport ) { + + done( 0 , "notransport" ); } else { // Set state as sending - state = 1; - jXHR.readyState = 1; - - // Install callbacks on deferreds - for ( i in { success:1, error:1, complete:1 } ) { - jXHR[ i ]( s[ i ] ); - } + state = jXHR.readyState = 1; // Send global event if ( s.global ) { @@ -818,7 +863,7 @@ function ajax_selectOrExecute( structure , s ) { } } - return noSelect ? jQuery.ajax : selected; + return noSelect ? jQuery : selected; } // Add an element to one of the structures in ajaxSettings @@ -877,13 +922,13 @@ function ajax_addElement( structure , args ) { } } - return jQuery.ajax; + return jQuery; } // Install prefilter & transport methods -jQuery.each( [ "prefilter" , "transport" ] , function( _ , name ) { - _ = name + "s"; - jQuery.ajax[ name ] = function() { +jQuery.each( [ "Prefilter" , "Transport" ] , function( _ , name ) { + _ = name.toLowerCase() + "s"; + jQuery[ "ajax" + name ] = function() { return ajax_addElement( _ , arguments ); }; } );