Skip to content

Commit 8e7aaa7

Browse files
committed
Merge branch '1.8-jsonp-optimize' of git://github.com/gibson042/jquery into pr749
2 parents 78583d0 + 180a997 commit 8e7aaa7

File tree

1 file changed

+54
-51
lines changed

1 file changed

+54
-51
lines changed

src/ajax/jsonp.js

Lines changed: 54 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
(function( jQuery ) {
22

3-
var jsc = jQuery.now(),
4-
jsre = /(\=)\?(&|$)|\?\?/i,
5-
jscallbacks = [];
3+
var oldCallbacks = [],
4+
rquestion = /\?/,
5+
rjsonp = /(=)\?(?=&|$)|\?\?/,
6+
nonce = jQuery.now();
67

78
// Default jsonp settings
89
jQuery.ajaxSetup({
910
jsonp: "callback",
1011
jsonpCallback: function() {
11-
var callback = jscallbacks.pop() || ( jQuery.expando + "_" + ( jsc++ ) );
12+
var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
1213
this[ callback ] = true;
1314
return callback;
1415
}
@@ -17,68 +18,70 @@ jQuery.ajaxSetup({
1718
// Detect, normalize options and install callbacks for jsonp requests
1819
jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
1920

20-
var inspectData = ( typeof s.data === "string" ) && /^application\/x\-www\-form\-urlencoded/.test( s.contentType );
21-
22-
if ( s.dataTypes[ 0 ] === "jsonp" ||
23-
s.jsonp !== false && ( jsre.test( s.url ) ||
24-
inspectData && jsre.test( s.data ) ) ) {
25-
26-
var responseContainer,
27-
jsonpCallback = s.jsonpCallback =
28-
jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
29-
previous = window[ jsonpCallback ],
30-
url = s.url,
31-
data = s.data,
32-
replace = "$1" + jsonpCallback + "$2";
33-
34-
if ( s.jsonp !== false ) {
35-
url = url.replace( jsre, replace );
36-
if ( s.url === url ) {
37-
if ( inspectData ) {
38-
data = data.replace( jsre, replace );
39-
}
40-
if ( s.data === data ) {
41-
// Add callback manually
42-
url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
43-
}
44-
}
21+
var callbackName, overwritten, responseContainer,
22+
data = s.data,
23+
url = s.url,
24+
hasCallback = s.jsonp !== false,
25+
replaceInUrl = hasCallback && rjsonp.test( url ),
26+
replaceInData = hasCallback && typeof data === "string" &&
27+
!( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") &&
28+
rjsonp.test( data );
29+
30+
// Handle iff the expected data type is "jsonp" or we have a parameter to set
31+
if ( s.dataTypes[ 0 ] === "jsonp" || replaceInUrl || replaceInData ) {
32+
33+
// Get callback name, remembering preexisting value associated with it
34+
callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
35+
s.jsonpCallback() :
36+
s.jsonpCallback;
37+
overwritten = window[ callbackName ];
38+
39+
// Insert callback into url or form data
40+
if ( replaceInUrl ) {
41+
s.url = url.replace( rjsonp, "$1" + callbackName );
42+
} else if ( replaceInData ) {
43+
s.data = data.replace( rjsonp, "$1" + callbackName );
44+
} else if ( hasCallback ) {
45+
s.url += ( rquestion.test( url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
4546
}
4647

47-
s.url = url;
48-
s.data = data;
48+
// Use data converter to retrieve json after script execution
49+
s.converters["script json"] = function() {
50+
if ( !responseContainer ) {
51+
jQuery.error( callbackName + " was not called" );
52+
}
53+
return responseContainer[ 0 ];
54+
};
55+
56+
// force json dataType
57+
s.dataTypes[ 0 ] = "json";
4958

5059
// Install callback
51-
window[ jsonpCallback ] = function( response ) {
52-
responseContainer = [ response ];
60+
window[ callbackName ] = function() {
61+
responseContainer = arguments;
5362
};
5463

55-
// Clean-up function
64+
// Clean-up function (fires after converters)
5665
jqXHR.always(function() {
57-
// Set callback back to previous value
58-
window[ jsonpCallback ] = previous;
66+
// Restore preexisting value
67+
window[ callbackName ] = overwritten;
68+
5969
// Save back as free
60-
if ( s[ jsonpCallback ] ) {
70+
if ( s[ callbackName ] ) {
6171
// make sure that re-using the options doesn't screw things around
6272
s.jsonpCallback = originalSettings.jsonpCallback;
73+
6374
// save the callback name for future use
64-
jscallbacks.push( jsonpCallback );
65-
}
66-
// Call if it was a function and we have a response
67-
if ( responseContainer && jQuery.isFunction( previous ) ) {
68-
window[ jsonpCallback ]( responseContainer[ 0 ] );
75+
oldCallbacks.push( callbackName );
6976
}
70-
});
7177

72-
// Use data converter to retrieve json after script execution
73-
s.converters["script json"] = function() {
74-
if ( !responseContainer ) {
75-
jQuery.error( jsonpCallback + " was not called" );
78+
// Call if it was a function and we have a response
79+
if ( responseContainer && jQuery.isFunction( overwritten ) ) {
80+
overwritten( responseContainer[ 0 ] );
7681
}
77-
return responseContainer[ 0 ];
78-
};
7982

80-
// force json dataType
81-
s.dataTypes[ 0 ] = "json";
83+
responseContainer = overwritten = undefined;
84+
});
8285

8386
// Delegate to script
8487
return "script";

0 commit comments

Comments
 (0)