ff8d1f145471b2fdea24054edd365c2bcb232c28
[jquery.git] / src / ajax / jsonp.js
1 (function( jQuery ) {
2
3 var jsc = jQuery.now(),
4         jsre = /(\=)(?:\?|%3F)(&|$)|()(?:\?\?|%3F%3F)()/i;
5
6 // Default jsonp settings
7 jQuery.ajaxSetup({
8         jsonp: "callback",
9         jsonpCallback: function() {
10                 return "jsonp" + jsc++;
11         }
12 });
13
14 // Detect, normalize options and install callbacks for jsonp requests
15 // (dataIsString is used internally)
16 jQuery.ajaxPrefilter("json jsonp", function(s, originalSettings, dataIsString) {
17
18         dataIsString = ( typeof(s.data) === "string" );
19
20         if ( s.dataTypes[ 0 ] === "jsonp" ||
21                 originalSettings.jsonpCallback ||
22                 originalSettings.jsonp != null ||
23                 s.jsonp !== false && ( jsre.test( s.url ) ||
24                                 dataIsString && 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 ( dataIsString ) {
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                         }
45                 }
46
47                 s.url = url;
48                 s.data = data;
49
50                 window [ jsonpCallback ] = function( response ) {
51                         responseContainer = [response];
52                 };
53
54                 s.complete = [function() {
55
56                         // Set callback back to previous value
57                         window[ jsonpCallback ] = previous;
58
59                         // Call if it was a function and we have a response
60                         if ( previous) {
61                                 if ( responseContainer && jQuery.isFunction ( previous ) ) {
62                                         window[ jsonpCallback ] ( responseContainer[0] );
63                                 }
64                         } else {
65                                 // else, more memory leak avoidance
66                                 try{ delete window[ jsonpCallback ]; } catch(e){}
67                         }
68
69                 }, s.complete ];
70
71                 // Use data converter to retrieve json after script execution
72                 s.converters["script json"] = function() {
73                         if ( ! responseContainer ) {
74                                 jQuery.error( jsonpCallback + " was not called" );
75                         }
76                         return responseContainer[ 0 ];
77                 };
78
79                 // force json dataType
80                 s.dataTypes[ 0 ] = "json";
81
82                 // Delegate to script
83                 return "script";
84         }
85 });
86
87 })( jQuery );