From 667a3b31e6a27cfe3f209765d583bff584ecc2f6 Mon Sep 17 00:00:00 2001 From: jaubourg Date: Thu, 13 Jan 2011 02:05:39 +0100 Subject: [PATCH] Reworked script and xhr abort logic to take advantage of the fact jXHR.abort will complete the request itself if not done already. --- src/ajax/script.js | 13 +++++++---- src/ajax/xhr.js | 65 ++++++++++++++++++++++------------------------------ 2 files changed, 36 insertions(+), 42 deletions(-) diff --git a/src/ajax/script.js b/src/ajax/script.js index 75f34fc..645ddf3 100644 --- a/src/ajax/script.js +++ b/src/ajax/script.js @@ -47,7 +47,7 @@ jQuery.ajax.transport("script", function(s) { script.src = s.url; // Attach handlers for all browsers - script.onload = script.onreadystatechange = function( _ , statusText) { + script.onload = script.onreadystatechange = function( _ , isAbort ) { if ( ! script.readyState || /loaded|complete/.test( script.readyState ) ) { @@ -59,10 +59,13 @@ jQuery.ajax.transport("script", function(s) { head.removeChild( script ); } + // Dereference the script script = 0; - // Callback - callback( statusText ? 0 : 200, statusText || "success" ); + // Callback if not abort + if ( ! isAbort ) { + callback( 200, "success" ); + } } }; // Use insertBefore instead of appendChild to circumvent an IE6 bug. @@ -70,9 +73,9 @@ jQuery.ajax.transport("script", function(s) { head.insertBefore( script, head.firstChild ); }, - abort: function(statusText) { + abort: function() { if ( script ) { - script.onload( 0 , statusText ); + script.onload(0,1); } } }; diff --git a/src/ajax/xhr.js b/src/ajax/xhr.js index 26e91ce..3c3d124 100644 --- a/src/ajax/xhr.js +++ b/src/ajax/xhr.js @@ -9,8 +9,8 @@ var // Next fake timer id // XHR pool xhrPool = [], - // #5280: see end of file - xhrUnloadAbortMarker; + // #5280: see below + xhrUnloadAbortInstalled; jQuery.ajax.transport( function( s , determineDataType ) { @@ -25,25 +25,23 @@ jQuery.ajax.transport( function( s , determineDataType ) { send: function(headers, complete) { // #5280: we need to abort on unload or IE will keep connections alive - if ( ! xhrUnloadAbortMarker ) { + if ( ! xhrUnloadAbortInstalled ) { - xhrUnloadAbortMarker = []; + xhrUnloadAbortInstalled = 1; jQuery(window).bind( "unload" , function() { // Abort all pending requests jQuery.each(xhrs, function(_, xhr) { if ( xhr.onreadystatechange ) { - xhr.onreadystatechange( xhrUnloadAbortMarker ); + xhr.onreadystatechange( 1 ); } }); - // Reset polling structure to be safe - xhrs = {}; - }); } + // Get a new xhr var xhr = xhrPool.pop() || s.xhr(), handle; @@ -58,7 +56,7 @@ jQuery.ajax.transport( function( s , determineDataType ) { // 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 in beforeSend + // Won't change header if already provided if ( ! ( s.crossDomain && ! s.hasContent ) && ! headers["x-requested-with"] ) { headers["x-requested-with"] = "XMLHttpRequest"; } @@ -76,20 +74,23 @@ jQuery.ajax.transport( function( s , determineDataType ) { try { xhr.send( ( s.hasContent && s.data ) || null ); } catch(e) { - // Store back in pool + // Store back into pool xhrPool.push( xhr ); complete(0, "error", "" + e); return; } // Listener - callback = function ( abortStatusText ) { + callback = function( isAbort ) { // Was never called and is aborted or complete - if ( callback && ( abortStatusText || xhr.readyState === 4 ) ) { + if ( callback && ( isAbort || xhr.readyState === 4 ) ) { + + // Only called once + callback = 0; - // Do not listen anymore - // and Store back in pool + // Do not keep as active anymore + // and store back into pool if (handle) { xhr.onreadystatechange = jQuery.noop; delete xhrs[ handle ]; @@ -97,28 +98,20 @@ jQuery.ajax.transport( function( s , determineDataType ) { xhrPool.push( xhr ); } - callback = 0; - - // Get info - var status, statusText, response, responseHeaders; - - if ( abortStatusText ) { + // If it's an abort + if ( isAbort ) { + // Abort it manually if needed if ( xhr.readyState !== 4 ) { xhr.abort(); } - - // Stop here if unloadAbort - if ( abortStatusText === xhrUnloadAbortMarker ) { - return; - } - - status = 0; - statusText = abortStatusText; - } else { - status = xhr.status; + // Get info + var status = xhr.status, + statusText, + response, + responseHeaders = xhr.getAllResponseHeaders(); try { // Firefox throws an exception when accessing statusText for faulty cross-domain requests @@ -130,8 +123,6 @@ jQuery.ajax.transport( function( s , determineDataType ) { } - responseHeaders = xhr.getAllResponseHeaders(); - // Filter status for non standard behaviours // (so many they seem to be the actual "standard") status = @@ -164,10 +155,10 @@ jQuery.ajax.transport( function( s , determineDataType ) { xhr.getResponseHeader("content-type"), xhr.responseText, xhr.responseXML ); - } - // Call complete - complete(status,statusText,response,responseHeaders); + // Call complete + complete(status,statusText,response,responseHeaders); + } } }; @@ -189,9 +180,9 @@ jQuery.ajax.transport( function( s , determineDataType ) { } }, - abort: function(statusText) { + abort: function() { if ( callback ) { - callback(statusText); + callback(1); } } }; -- 1.7.10.4