Commit 8ebb2f47 authored by jaubourg's avatar jaubourg

Fixes #8205. Mitigates memory usage by recycling jsonp callback names the...

Fixes #8205. Mitigates memory usage by recycling jsonp callback names the safest possible way (no kittens were harmed in the making of this). Doesn't even try to delete window properties (would necessitate a try/catch for IE which makes the cost in size prohibitive). Unit tests added.
parent 3e6f94c3
(function( jQuery ) { (function( jQuery ) {
var jsc = jQuery.now(), var jsc = jQuery.now(),
jsre = /(\=)\?(&|$)|\?\?/i; jsre = /(\=)\?(&|$)|\?\?/i,
jscallbacks = [];
// Default jsonp settings // Default jsonp settings
jQuery.ajaxSetup({ jQuery.ajaxSetup({
jsonp: "callback", jsonp: "callback",
jsonpCallback: function() { jsonpCallback: function() {
return jQuery.expando + "_" + ( jsc++ ); var callback = jscallbacks.pop() || ( jQuery.expando + "_" + ( jsc++ ) );
this[ callback ] = true;
return callback;
} }
}); });
...@@ -53,6 +56,13 @@ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { ...@@ -53,6 +56,13 @@ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
jqXHR.always(function() { jqXHR.always(function() {
// Set callback back to previous value // Set callback back to previous value
window[ jsonpCallback ] = previous; window[ jsonpCallback ] = previous;
// Save back as free
if ( s[ jsonpCallback ] ) {
// make sure that re-using the options doesn't screw things around
s.jsonpCallback = originalSettings.jsonpCallback;
// save the callback name for future use
jscallbacks.push( jsonpCallback );
}
// Call if it was a function and we have a response // Call if it was a function and we have a response
if ( responseContainer && jQuery.isFunction( previous ) ) { if ( responseContainer && jQuery.isFunction( previous ) ) {
window[ jsonpCallback ]( responseContainer[ 0 ] ); window[ jsonpCallback ]( responseContainer[ 0 ] );
......
...@@ -1309,10 +1309,10 @@ test("jQuery.getScript(String, Function) - no callback", function() { ...@@ -1309,10 +1309,10 @@ test("jQuery.getScript(String, Function) - no callback", function() {
jQuery.each( [ "Same Domain", "Cross Domain" ] , function( crossDomain , label ) { jQuery.each( [ "Same Domain", "Cross Domain" ] , function( crossDomain , label ) {
test("jQuery.ajax() - JSONP, " + label, function() { test("jQuery.ajax() - JSONP, " + label, function() {
expect(20); expect(24);
var count = 0; var count = 0;
function plus(){ if ( ++count == 18 ) start(); } function plus(){ if ( ++count == 20 ) start(); }
stop(); stop();
...@@ -1330,6 +1330,25 @@ jQuery.each( [ "Same Domain", "Cross Domain" ] , function( crossDomain , label ) ...@@ -1330,6 +1330,25 @@ jQuery.each( [ "Same Domain", "Cross Domain" ] , function( crossDomain , label )
} }
}); });
jQuery.ajax({
url: "data/jsonp.php",
dataType: "jsonp",
crossDomain: crossDomain,
success: function(data){
ok( data.data, ( this.alreadyDone ? "this re-used" : "first request" ) + ": JSON results returned (GET, no callback)" );
if ( !this.alreadyDone ) {
this.alreadyDone = true;
jQuery.ajax( this );
} else {
plus();
}
},
error: function(data){
ok( false, "Ajax error JSON (GET, no callback)" );
plus();
}
});
jQuery.ajax({ jQuery.ajax({
url: "data/jsonp.php?callback=?", url: "data/jsonp.php?callback=?",
dataType: "jsonp", dataType: "jsonp",
...@@ -1564,6 +1583,28 @@ jQuery.each( [ "Same Domain", "Cross Domain" ] , function( crossDomain , label ) ...@@ -1564,6 +1583,28 @@ jQuery.each( [ "Same Domain", "Cross Domain" ] , function( crossDomain , label )
} }
}); });
//#8205
jQuery.ajax({
url: "data/jsonp.php",
dataType: "jsonp",
crossDomain: crossDomain,
beforeSend: function() {
this.callback = this.jsonpCallback;
}
}).pipe(function() {
var previous = this;
strictEqual( previous.jsonpCallback, undefined, "jsonpCallback option is set back to default in callbacks" );
jQuery.ajax({
url: "data/jsonp.php",
dataType: "jsonp",
crossDomain: crossDomain,
beforeSend: function() {
strictEqual( this.jsonpCallback, previous.callback, "JSONP callback name is re-used" );
return false;
}
});
}).always( plus );
}); });
}); });
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment