X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=src%2Fxhr.js;h=8e9a2b08a38e09a8a0b7de0748148ddc4a29bc88;hb=56628c7adffb4b5436257255f55e31b85b58aa8f;hp=fae1110c49ae7e73dd173fb19c3c28674562caaf;hpb=ab3ba4a81252c4357a7aab5f24d765d41d47986e;p=jquery.git diff --git a/src/xhr.js b/src/xhr.js index fae1110..8e9a2b0 100644 --- a/src/xhr.js +++ b/src/xhr.js @@ -1,13 +1,13 @@ -(function( jQuery , undefined ) { +(function( jQuery ) { -var rquery = /\?/, +var rquery_xhr = /\?/, rhash = /#.*$/, rheaders = /^(.*?):\s*(.*?)\r?$/mg, // IE leaves an \r character at EOL rnoContent = /^(?:GET|HEAD)$/, rts = /([?&])_=[^&]*/, rurl = /^(\w+:)?\/\/([^\/?#]+)/, - slice = Array.prototype.slice, + sliceFunc = Array.prototype.slice, isFunction = jQuery.isFunction; @@ -18,18 +18,19 @@ jQuery.xhr = function( _native ) { return jQuery.ajaxSettings.xhr(); } - function reset(force) { + function reset( force ) { // We only need to reset if we went through the init phase // (with the exception of object creation) if ( force || internal ) { - + // Reset callbacks lists - callbacksLists = { - success: createCBList(), - error: createCBList(), - complete: createCBList() - }; + deferred = jQuery.deferred(); + completeDeferred = jQuery._deferred(); + + xhr.success = xhr.then = deferred.then; + xhr.error = xhr.fail = deferred.fail; + xhr.complete = completeDeferred.then; // Reset private variables requestHeaders = {}; @@ -80,14 +81,14 @@ jQuery.xhr = function( _native ) { // Other Variables transportDataType, i; - + // Convert data if not already a string if ( data && s.processData && typeof data != "string" ) { data = s.data = jQuery.param( data , s.traditional ); } // Apply option prefilters - for (i in prefilters) { + for ( i = 0; i < prefilters.length; i++ ) { prefilters[i](s); } @@ -109,7 +110,7 @@ jQuery.xhr = function( _native ) { // If data is available, append data to url if ( data ) { - url += (rquery.test(url) ? "&" : "?") + data; + url += (rquery_xhr.test(url) ? "&" : "?") + data; } // Add anti-cache in url if needed @@ -120,7 +121,7 @@ jQuery.xhr = function( _native ) { ret = url.replace(rts, "$1_=" + ts ); // if nothing was replaced, add timestamp to the end - url = ret + ((ret == url) ? (rquery.test(url) ? "&" : "?") + "_=" + ts : ""); + url = ret + ((ret == url) ? (rquery_xhr.test(url) ? "&" : "?") + "_=" + ts : ""); } s.url = url; @@ -147,16 +148,16 @@ jQuery.xhr = function( _native ) { accepts[ "*" ]; // Check for headers option - if ( headers ) { - xhr.setRequestHeaders( headers ); + for ( i in headers ) { + requestHeaders[ i.toLowerCase() ] = headers[ i ]; } } callbackContext = s.context || s; globalEventContext = s.context ? jQuery(s.context) : jQuery.event; - for ( i in callbacksLists ) { - callbacksLists[i].bind(s[i]); + for ( i in { success:1, error:1, complete:1 } ) { + xhr[ i ]( s[ i ] ); } // Watch for a new set of requests @@ -355,10 +356,12 @@ jQuery.xhr = function( _native ) { // Keep local copies of vars in case callbacks re-use the xhr var _s = s, - _callbacksLists = callbacksLists, + _deferred = deferred, + _completeDeferred = completeDeferred, _callbackContext = callbackContext, _globalEventContext = globalEventContext; + // Set state if the xhr hasn't been re-used function _setState( value ) { if ( xhr.readyState && s === _s ) { @@ -375,18 +378,20 @@ jQuery.xhr = function( _native ) { // We're done _setState( 4 ); - // Success - _callbacksLists.success.fire( isSuccess , _callbackContext , success, statusText, xhr); - if ( isSuccess && _s.global ) { - _globalEventContext.trigger( "ajaxSuccess", [xhr, _s, success] ); + // Success/Error + if ( isSuccess ) { + _deferred.fire( _callbackContext , [ success , statusText , xhr ] ); + } else { + _deferred.fireReject( _callbackContext , [ xhr , statusText , error ] ); } - // Error - _callbacksLists.error.fire( ! isSuccess , _callbackContext , xhr, statusText, error); - if ( !isSuccess && _s.global ) { - _globalEventContext.trigger( "ajaxError", [xhr, _s, error] ); + + if ( _s.global ) { + _globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ) , [ xhr , _s , isSuccess ? success : error ] ); } + // Complete - _callbacksLists.complete.fire( 1 , _callbackContext, xhr, statusText); + _completeDeferred.fire( _callbackContext, [ xhr , statusText ] ); + if ( _s.global ) { _globalEventContext.trigger( "ajaxComplete", [xhr, _s] ); // Handle the global AJAX counter @@ -419,7 +424,8 @@ jQuery.xhr = function( _native ) { // Callback stuff callbackContext, globalEventContext, - callbacksLists, + deferred, + completeDeferred, // Headers (they are sent all at once) requestHeaders, // Response headers @@ -554,21 +560,6 @@ jQuery.xhr = function( _native ) { return xhr; }, - // Ditto with an s - setRequestHeaders: function(map) { - checkState(1, !sendFlag); - for ( var name in map ) { - requestHeaders[ name.toLowerCase() ] = map[name]; - } - return xhr; - }, - - // Utility method to get headers set - getRequestHeader: function(name) { - checkState(1, !sendFlag); - return requestHeaders[ name.toLowerCase() ]; - }, - // Raw string getAllResponseHeaders: function() { return xhr.readyState <= 1 ? "" : responseHeadersString; @@ -611,152 +602,10 @@ jQuery.xhr = function( _native ) { // Init data (so that we can bind callbacks early reset(1); - // Install callbacks related methods - jQuery.each(["bind","unbind"], function(_, name) { - xhr[name] = function(type) { - - var functors = slice.call(arguments,1), - list; - - jQuery.each(type.split(/\s+/g), function() { - list = callbacksLists[this]; - if ( list ) { - list[name].apply(list, functors ); - } - }); - - return this; - }; - }); - - jQuery.each(callbacksLists, function(name) { - var list; - xhr[name] = function() { - list = callbacksLists[name]; - if ( list ) { - list.bind.apply(list, arguments ); - } - return this; - }; - }); - // Return the xhr emulation return xhr; }; -// Create a callback list -function createCBList() { - - var functors = [], - autoFire = 0, - fireArgs, - list = { - - fire: function( flag , context ) { - - // Save info for later bindings - fireArgs = arguments; - - // Remove autoFire to keep bindings in order - autoFire = 0; - - var args = slice.call( fireArgs , 2 ); - - // Execute callbacks - while ( flag && functors.length ) { - flag = functors.shift().apply( context , args ) !== false; - } - - // Clean if asked to stop - if ( ! flag ) { - clean(); - } - - // Set autoFire - autoFire = 1; - }, - - bind: function() { - - var args = arguments, - i = 0, - length = args.length, - func; - - for ( ; i < length ; i++ ) { - - func = args[ i ]; - - if ( jQuery.isArray(func) ) { - - list.bind.apply( list , func ); - - } else if ( isFunction(func) ) { - - // Add if not already in - if ( ! pos( func ) ) { - functors.push( func ); - } - } - } - - if ( autoFire ) { - list.fire.apply( list , fireArgs ); - } - }, - - unbind: function() { - - var i = 0, - args = arguments, - length = args.length, - func, - position; - - if ( length ) { - - for( ; i < length ; i++ ) { - func = args[i]; - if ( jQuery.isArray(func) ) { - list.unbind.apply(list,func); - } else if ( isFunction(func) ) { - position = pos(func); - if ( position ) { - functors.splice(position-1,1); - } - } - } - - } else { - - functors = []; - - } - - } - - }; - - // Get the index of the functor in the list (1-based) - function pos( func ) { - for (var i = 0, length = functors.length; i < length && functors[i] !== func; i++) { - } - return i < length ? ( i + 1 ) : 0; - } - - // Clean the object - function clean() { - // Empty callbacks list - functors = []; - // Inhibit methods - for (var i in list) { - list[i] = jQuery.noop; - } - } - - return list; -} - jQuery.extend(jQuery.xhr, { // Add new prefilter @@ -938,4 +787,4 @@ function determineDataType( s , ct , text , xml ) { return response; } -})(jQuery); +})( jQuery );