Manipulation: Support $el.html(selfRemovingScript) (#5378)
[jquery.git] / src / ajax / jsonp.js
blobadd5a5c9ce4ec1fc227f01b30a22b5e8d58257e0
1 import { jQuery } from "../core.js";
2 import { nonce } from "./var/nonce.js";
3 import { rquery } from "./var/rquery.js";
5 import "../ajax.js";
7 var oldCallbacks = [],
8         rjsonp = /(=)\?(?=&|$)|\?\?/;
10 // Default jsonp settings
11 jQuery.ajaxSetup( {
12         jsonp: "callback",
13         jsonpCallback: function() {
14                 var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce.guid++ ) );
15                 this[ callback ] = true;
16                 return callback;
17         }
18 } );
20 // Detect, normalize options and install callbacks for jsonp requests
21 jQuery.ajaxPrefilter( "jsonp", function( s, originalSettings, jqXHR ) {
23         var callbackName, overwritten, responseContainer,
24                 jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
25                         "url" :
26                         typeof s.data === "string" &&
27                                 ( s.contentType || "" )
28                                         .indexOf( "application/x-www-form-urlencoded" ) === 0 &&
29                                 rjsonp.test( s.data ) && "data"
30                 );
32         // Get callback name, remembering preexisting value associated with it
33         callbackName = s.jsonpCallback = typeof s.jsonpCallback === "function" ?
34                 s.jsonpCallback() :
35                 s.jsonpCallback;
37         // Insert callback into url or form data
38         if ( jsonProp ) {
39                 s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
40         } else if ( s.jsonp !== false ) {
41                 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
42         }
44         // Use data converter to retrieve json after script execution
45         s.converters[ "script json" ] = function() {
46                 if ( !responseContainer ) {
47                         jQuery.error( callbackName + " was not called" );
48                 }
49                 return responseContainer[ 0 ];
50         };
52         // Force json dataType
53         s.dataTypes[ 0 ] = "json";
55         // Install callback
56         overwritten = window[ callbackName ];
57         window[ callbackName ] = function() {
58                 responseContainer = arguments;
59         };
61         // Clean-up function (fires after converters)
62         jqXHR.always( function() {
64                 // If previous value didn't exist - remove it
65                 if ( overwritten === undefined ) {
66                         jQuery( window ).removeProp( callbackName );
68                 // Otherwise restore preexisting value
69                 } else {
70                         window[ callbackName ] = overwritten;
71                 }
73                 // Save back as free
74                 if ( s[ callbackName ] ) {
76                         // Make sure that re-using the options doesn't screw things around
77                         s.jsonpCallback = originalSettings.jsonpCallback;
79                         // Save the callback name for future use
80                         oldCallbacks.push( callbackName );
81                 }
83                 // Call if it was a function and we have a response
84                 if ( responseContainer && typeof overwritten === "function" ) {
85                         overwritten( responseContainer[ 0 ] );
86                 }
88                 responseContainer = overwritten = undefined;
89         } );
91         // Delegate to script
92         return "script";
93 } );