1/* 2 * jQuery JSONP Core Plugin 2.4.0 (2012-08-21) 3 * 4 * https://github.com/jaubourg/jquery-jsonp 5 * 6 * Copyright (c) 2012 Julian Aubourg 7 * 8 * This document is licensed as free software under the terms of the 9 * MIT License: http://www.opensource.org/licenses/mit-license.php 10 */ 11( function( $ ) { 12 13 // ###################### UTILITIES ## 14 15 // Noop 16 function noop() { 17 } 18 19 // Generic callback 20 function genericCallback( data ) { 21 lastValue = [ data ]; 22 } 23 24 // Call if defined 25 function callIfDefined( method , object , parameters ) { 26 return method && method.apply( object.context || object , parameters ); 27 } 28 29 // Give joining character given url 30 function qMarkOrAmp( url ) { 31 return /\?/ .test( url ) ? "&" : "?"; 32 } 33 34 var // String constants (for better minification) 35 STR_ASYNC = "async", 36 STR_CHARSET = "charset", 37 STR_EMPTY = "", 38 STR_ERROR = "error", 39 STR_INSERT_BEFORE = "insertBefore", 40 STR_JQUERY_JSONP = "_jqjsp", 41 STR_ON = "on", 42 STR_ON_CLICK = STR_ON + "click", 43 STR_ON_ERROR = STR_ON + STR_ERROR, 44 STR_ON_LOAD = STR_ON + "load", 45 STR_ON_READY_STATE_CHANGE = STR_ON + "readystatechange", 46 STR_READY_STATE = "readyState", 47 STR_REMOVE_CHILD = "removeChild", 48 STR_SCRIPT_TAG = "<script>", 49 STR_SUCCESS = "success", 50 STR_TIMEOUT = "timeout", 51 52 // Window 53 win = window, 54 // Deferred 55 Deferred = $.Deferred, 56 // Head element 57 head = $( "head" )[ 0 ] || document.documentElement, 58 // Page cache 59 pageCache = {}, 60 // Counter 61 count = 0, 62 // Last returned value 63 lastValue, 64 65 // ###################### DEFAULT OPTIONS ## 66 xOptionsDefaults = { 67 //beforeSend: undefined, 68 //cache: false, 69 callback: STR_JQUERY_JSONP, 70 //callbackParameter: undefined, 71 //charset: undefined, 72 //complete: undefined, 73 //context: undefined, 74 //data: "", 75 //dataFilter: undefined, 76 //error: undefined, 77 //pageCache: false, 78 //success: undefined, 79 //timeout: 0, 80 //traditional: false, 81 url: location.href 82 }, 83 84 // opera demands sniffing :/ 85 opera = win.opera, 86 87 // IE < 10 88 oldIE = !!$( "<div>" ).html( "<!--[if IE]><i><![endif]-->" ).find("i").length; 89 90 // ###################### MAIN FUNCTION ## 91 function jsonp( xOptions ) { 92 93 // Build data with default 94 xOptions = $.extend( {} , xOptionsDefaults , xOptions ); 95 96 // References to xOptions members (for better minification) 97 var successCallback = xOptions.success, 98 errorCallback = xOptions.error, 99 completeCallback = xOptions.complete, 100 dataFilter = xOptions.dataFilter, 101 callbackParameter = xOptions.callbackParameter, 102 successCallbackName = xOptions.callback, 103 cacheFlag = xOptions.cache, 104 pageCacheFlag = xOptions.pageCache, 105 charset = xOptions.charset, 106 url = xOptions.url, 107 data = xOptions.data, 108 timeout = xOptions.timeout, 109 pageCached, 110 111 // Abort/done flag 112 done = 0, 113 114 // Life-cycle functions 115 cleanUp = noop, 116 117 // Support vars 118 supportOnload, 119 supportOnreadystatechange, 120 121 // Request execution vars 122 firstChild, 123 script, 124 scriptAfter, 125 timeoutTimer; 126 127 // If we have Deferreds: 128 // - substitute callbacks 129 // - promote xOptions to a promise 130 Deferred && Deferred(function( defer ) { 131 defer.done( successCallback ).fail( errorCallback ); 132 successCallback = defer.resolve; 133 errorCallback = defer.reject; 134 }).promise( xOptions ); 135 136 // Create the abort method 137 xOptions.abort = function() { 138 !( done++ ) && cleanUp(); 139 }; 140 141 // Call beforeSend if provided (early abort if false returned) 142 if ( callIfDefined( xOptions.beforeSend , xOptions , [ xOptions ] ) === !1 || done ) { 143 return xOptions; 144 } 145 146 // Control entries 147 url = url || STR_EMPTY; 148 data = data ? ( (typeof data) == "string" ? data : $.param( data , xOptions.traditional ) ) : STR_EMPTY; 149 150 // Build final url 151 url += data ? ( qMarkOrAmp( url ) + data ) : STR_EMPTY; 152 153 // Add callback parameter if provided as option 154 callbackParameter && ( url += qMarkOrAmp( url ) + encodeURIComponent( callbackParameter ) + "=?" ); 155 156 // Add anticache parameter if needed 157 !cacheFlag && !pageCacheFlag && ( url += qMarkOrAmp( url ) + "_" + ( new Date() ).getTime() + "=" ); 158 159 // Replace last ? by callback parameter 160 url = url.replace( /=\?(&|$)/ , "=" + successCallbackName + "$1" ); 161 162 // Success notifier 163 function notifySuccess( json ) { 164 165 if ( !( done++ ) ) { 166 167 cleanUp();
168 // Pagecache if needed 169 pageCacheFlag && ( pageCache [ url ] = { s: [ json ] } ); 170 // Apply the data filter if provided 171 dataFilter && ( json = dataFilter.apply( xOptions , [ json ] ) ); 172 // Call success then complete 173 callIfDefined( successCallback , xOptions , [ json , STR_SUCCESS, xOptions ] ); 174 callIfDefined( completeCallback , xOptions , [ xOptions , STR_SUCCESS ] ); 175 176 } 177 } 178 179 // Error notifier 180 function notifyError( type ) { 181 182 if ( !( done++ ) ) { 183 184 // Clean up 185 cleanUp(); 186 // If pure error (not timeout), cache if needed 187 pageCacheFlag && type != STR_TIMEOUT && ( pageCache[ url ] = type ); 188 // Call error then complete 189 callIfDefined( errorCallback , xOptions , [ xOptions , type ] ); 190 callIfDefined( completeCallback , xOptions , [ xOptions , type ] ); 191 192 } 193 } 194 195 // Check page cache 196 if ( pageCacheFlag && ( pageCached = pageCache[ url ] ) ) { 197 198 pageCached.s ? notifySuccess( pageCached.s[ 0 ] ) : notifyError( pageCached ); 199 200 } else { 201 202 // Install the generic callback 203 // (BEWARE: global namespace pollution ahoy) 204 win[ successCallbackName ] = genericCallback; 205 206 // Create the script tag 207 script = $( STR_SCRIPT_TAG )[ 0 ]; 208 script.id = STR_JQUERY_JSONP + count++; 209 210 // Set charset if provided 211 if ( charset ) { 212 script[ STR_CHARSET ] = charset; 213 } 214 215 opera && opera.version() < 11.60 ? 216 // onerror is not supported: do not set as async and assume in-order execution. 217 // Add a trailing script to emulate the event 218 ( ( scriptAfter = $( STR_SCRIPT_TAG )[ 0 ] ).text = "document.getElementById('" + script.id + "')." + STR_ON_ERROR + "()" ) 219 : 220 // onerror is supported: set the script as async to avoid requests blocking each others 221 ( script[ STR_ASYNC ] = STR_ASYNC ) 222 223 ; 224 225 // Internet Explorer: event/htmlFor trick 226 if ( oldIE ) { 227 script.htmlFor = script.id; 228 script.event = STR_ON_CLICK; 229 } 230 231 // Attached event handlers 232 script[ STR_ON_LOAD ] = script[ STR_ON_ERROR ] = script[ STR_ON_READY_STATE_CHANGE ] = function ( result ) { 233 234 // Test readyState if it exists 235 if ( !script[ STR_READY_STATE ] || !/i/.test( script[ STR_READY_STATE ] ) ) { 236 237 try { 238 239 script[ STR_ON_CLICK ] && script[ STR_ON_CLICK ](); 240 241 } catch( _ ) {} 242 243 result = lastValue; 244 lastValue = 0; 245 result ? notifySuccess( result[ 0 ] ) : notifyError( STR_ERROR ); 246 247 } 248 }; 249 250 // Set source 251 script.src = url; 252 253 // Re-declare cleanUp function 254 cleanUp = function( i ) { 255 timeoutTimer && clearTimeout( timeoutTimer ); 256 script[ STR_ON_READY_STATE_CHANGE ] = script[ STR_ON_LOAD ] = script[ STR_ON_ERROR ] = null; 257 head[ STR_REMOVE_CHILD ]( script ); 258 scriptAfter && head[ STR_REMOVE_CHILD ]( scriptAfter ); 259 }; 260 261 // Append main script 262 head[ STR_INSERT_BEFORE ]( script , ( firstChild = head.firstChild ) ); 263 264 // Append trailing script if needed 265 scriptAfter && head[ STR_INSERT_BEFORE ]( scriptAfter , firstChild ); 266 267 // If a timeout is needed, install it 268 timeoutTimer = timeout > 0 && setTimeout( function() { 269 notifyError( STR_TIMEOUT ); 270 } , timeout ); 271 272 } 273 274 return xOptions; 275 } 276 277 // ###################### SETUP FUNCTION ## 278 jsonp.setup = function( xOptions ) { 279 $.extend( xOptionsDefaults , xOptions ); 280 }; 281 282 // ###################### INSTALL in jQuery ## 283 $.jsonp = jsonp; 284 285} )( jQuery );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.