Copybara bot | be50d49 | 2023-11-30 00:16:42 +0100 | [diff] [blame] | 1 | define( [ |
| 2 | "../core", |
| 3 | "../var/isFunction", |
| 4 | "./var/nonce", |
| 5 | "./var/rquery", |
| 6 | "../ajax" |
| 7 | ], function( jQuery, isFunction, nonce, rquery ) { |
| 8 | |
| 9 | "use strict"; |
| 10 | |
| 11 | var oldCallbacks = [], |
| 12 | rjsonp = /(=)\?(?=&|$)|\?\?/; |
| 13 | |
| 14 | // Default jsonp settings |
| 15 | jQuery.ajaxSetup( { |
| 16 | jsonp: "callback", |
| 17 | jsonpCallback: function() { |
| 18 | var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); |
| 19 | this[ callback ] = true; |
| 20 | return callback; |
| 21 | } |
| 22 | } ); |
| 23 | |
| 24 | // Detect, normalize options and install callbacks for jsonp requests |
| 25 | jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { |
| 26 | |
| 27 | var callbackName, overwritten, responseContainer, |
| 28 | jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? |
| 29 | "url" : |
| 30 | typeof s.data === "string" && |
| 31 | ( s.contentType || "" ) |
| 32 | .indexOf( "application/x-www-form-urlencoded" ) === 0 && |
| 33 | rjsonp.test( s.data ) && "data" |
| 34 | ); |
| 35 | |
| 36 | // Handle iff the expected data type is "jsonp" or we have a parameter to set |
| 37 | if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { |
| 38 | |
| 39 | // Get callback name, remembering preexisting value associated with it |
| 40 | callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ? |
| 41 | s.jsonpCallback() : |
| 42 | s.jsonpCallback; |
| 43 | |
| 44 | // Insert callback into url or form data |
| 45 | if ( jsonProp ) { |
| 46 | s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); |
| 47 | } else if ( s.jsonp !== false ) { |
| 48 | s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; |
| 49 | } |
| 50 | |
| 51 | // Use data converter to retrieve json after script execution |
| 52 | s.converters[ "script json" ] = function() { |
| 53 | if ( !responseContainer ) { |
| 54 | jQuery.error( callbackName + " was not called" ); |
| 55 | } |
| 56 | return responseContainer[ 0 ]; |
| 57 | }; |
| 58 | |
| 59 | // Force json dataType |
| 60 | s.dataTypes[ 0 ] = "json"; |
| 61 | |
| 62 | // Install callback |
| 63 | overwritten = window[ callbackName ]; |
| 64 | window[ callbackName ] = function() { |
| 65 | responseContainer = arguments; |
| 66 | }; |
| 67 | |
| 68 | // Clean-up function (fires after converters) |
| 69 | jqXHR.always( function() { |
| 70 | |
| 71 | // If previous value didn't exist - remove it |
| 72 | if ( overwritten === undefined ) { |
| 73 | jQuery( window ).removeProp( callbackName ); |
| 74 | |
| 75 | // Otherwise restore preexisting value |
| 76 | } else { |
| 77 | window[ callbackName ] = overwritten; |
| 78 | } |
| 79 | |
| 80 | // Save back as free |
| 81 | if ( s[ callbackName ] ) { |
| 82 | |
| 83 | // Make sure that re-using the options doesn't screw things around |
| 84 | s.jsonpCallback = originalSettings.jsonpCallback; |
| 85 | |
| 86 | // Save the callback name for future use |
| 87 | oldCallbacks.push( callbackName ); |
| 88 | } |
| 89 | |
| 90 | // Call if it was a function and we have a response |
| 91 | if ( responseContainer && isFunction( overwritten ) ) { |
| 92 | overwritten( responseContainer[ 0 ] ); |
| 93 | } |
| 94 | |
| 95 | responseContainer = overwritten = undefined; |
| 96 | } ); |
| 97 | |
| 98 | // Delegate to script |
| 99 | return "script"; |
| 100 | } |
| 101 | } ); |
| 102 | |
| 103 | } ); |