X-Git-Url: http://git.asbjorn.it/?a=blobdiff_plain;f=src%2Fajax%2Fajax.js;h=0b965e4a1628bbde8f67f3b18e686d2af359e47e;hb=a5dbcaf67579b2266b64ffbdd2a328d180f7f64b;hp=ccf4f14a95f89048b842a048b5b5984a8433e95b;hpb=456f0fe5985eaad42eba456b9ff710771669607c;p=jquery.git diff --git a/src/ajax/ajax.js b/src/ajax/ajax.js index ccf4f14..0b965e4 100644 --- a/src/ajax/ajax.js +++ b/src/ajax/ajax.js @@ -244,6 +244,8 @@ jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".sp }; }); +var jsc = (new Date).getTime(); + jQuery.extend({ /** @@ -599,30 +601,95 @@ jQuery.extend({ * @see ajaxSetup(Map) */ ajax: function( s ) { + var jsonp, jsre = /=(\?|%3F)/g, status, data; + // Extend the settings, but re-extend 's' so that it can be // checked again later (in the test suite, specifically) s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s)); - // if data available - if ( s.data ) { - // convert data if not already a string - if ( s.processData && typeof s.data != "string" ) - s.data = jQuery.param(s.data); + // convert data if not already a string + if ( s.data && s.processData && typeof s.data != "string" ) + s.data = jQuery.param(s.data); - // append data to url for get requests - if ( s.type.toLowerCase() == "get" ) { - // "?" + data or "&" + data (in case there are already params) - s.url += (s.url.indexOf("?") > -1 ? "&" : "?") + s.data; + // Break the data into one single string + var q = s.url.indexOf("?"); + if ( q > -1 ) { + s.data = (s.data ? s.data + "&" : "") + s.url.slice(q + 1); + s.url = s.url.slice(0, q); + } - // IE likes to send both get and post data, prevent this - s.data = null; - } + // Handle JSONP Parameter Callbacks + if ( s.dataType == "jsonp" ) { + if ( !s.data || !s.data.match(jsre) ) + s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?"; + s.dataType = "json"; + } + + // Build temporary JSONP function + if ( s.dataType == "json" && s.data && s.data.match(jsre) ) { + jsonp = "jsonp" + jsc++; + s.data = s.data.replace(jsre, "=" + jsonp); + + // We need to make sure + // that a JSONP style response is executed properly + s.dataType = "script"; + + // Handle JSONP-style loading + window[ jsonp ] = function(tmp){ + data = tmp; + success(); + // Garbage collect + window[ jsonp ] = undefined; + try{ delete window[ jsonp ]; } catch(e){} + }; + } + + if ( s.dataType == "script" && s.cache == null ) + s.cache = false; + + if ( s.cache === false && s.type.toLowerCase() == "get" ) + s.data = (s.data ? s.data + "&" : "") + "_=" + (new Date()).getTime(); + + // If data is available, append data to url for get requests + if ( s.data && s.type.toLowerCase() == "get" ) { + s.url += "?" + s.data; + + // IE likes to send both get and post data, prevent this + s.data = null; } // Watch for a new set of requests if ( s.global && ! jQuery.active++ ) jQuery.event.trigger( "ajaxStart" ); + // If we're requesting a remote document + // and trying to load JSON or Script + if ( !s.url.indexOf("http") && s.dataType == "script" ) { + var script = document.createElement("script"); + script.src = s.url; + + // Handle Script loading + if ( !jsonp && (s.success || s.complete) ) { + var done = false; + + // Attach handlers for all browsers + script.onload = script.onreadystatechange = function(){ + if ( !done && (!this.readyState || + this.readyState == "loaded" || this.readyState == "complete") ) { + done = true; + success(); + complete(); + document.body.removeChild( script ); + } + }; + } + + document.body.appendChild(script); + + // We handle everything using the script element injection + return; + } + var requestDone = false; // Create the request object; Microsoft failed to properly @@ -645,7 +712,7 @@ jQuery.extend({ xml.setRequestHeader("X-Requested-With", "XMLHttpRequest"); // Allow custom headers/mimetypes - if( s.beforeSend ) + if ( s.beforeSend ) s.beforeSend(xml); if ( s.global ) @@ -663,7 +730,7 @@ jQuery.extend({ ival = null; } - var status = isTimeout == "timeout" && "timeout" || + status = isTimeout == "timeout" && "timeout" || !jQuery.httpSuccess( xml ) && "error" || s.ifModified && jQuery.httpNotModified( xml, s.url ) && "notmodified" || "success"; @@ -672,7 +739,7 @@ jQuery.extend({ // Watch for, and catch, XML document parse errors try { // process the data (runs the xml through httpData regardless of callback) - var data = jQuery.httpData( xml, s.dataType ); + data = jQuery.httpData( xml, s.dataType ); } catch(e) { status = "parsererror"; } @@ -688,31 +755,18 @@ jQuery.extend({ if ( s.ifModified && modRes ) jQuery.lastModified[s.url] = modRes; - - // If a local callback was specified, fire it and pass it the data - if ( s.success ) - s.success( data, status ); - - // Fire the global callback - if ( s.global ) - jQuery.event.trigger( "ajaxSuccess", [xml, s] ); + + // JSONP handles its own success callback + if ( !jsonp ) + success(); } else jQuery.handleError(s, xml, status); - // The request was completed - if( s.global ) - jQuery.event.trigger( "ajaxComplete", [xml, s] ); - - // Handle the global AJAX counter - if ( s.global && ! --jQuery.active ) - jQuery.event.trigger( "ajaxStop" ); - - // Process result - if ( s.complete ) - s.complete(xml, status); + // Fire the complete handlers + complete(); // Stop memory leaks - if(s.async) + if ( s.async ) xml = null; } }; @@ -748,6 +802,30 @@ jQuery.extend({ // return XMLHttpRequest to allow aborting the request etc. return xml; + + function success(){ + // If a local callback was specified, fire it and pass it the data + if ( s.success ) + s.success( data, status ); + + // Fire the global callback + if ( s.global ) + jQuery.event.trigger( "ajaxSuccess", [xml, s] ); + } + + function complete(){ + // Process result + if ( s.complete ) + s.complete(xml, status); + + // The request was completed + if ( s.global ) + jQuery.event.trigger( "ajaxComplete", [xml, s] ); + + // Handle the global AJAX counter + if ( s.global && ! --jQuery.active ) + jQuery.event.trigger( "ajaxStop" ); + } }, handleError: function( s, xml, status, e ) { @@ -793,7 +871,7 @@ jQuery.extend({ httpData: function( r, type ) { var ct = r.getResponseHeader("content-type"); var xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0; - data = xml ? r.responseXML : r.responseText; + var data = xml ? r.responseXML : r.responseText; if ( xml && data.documentElement.tagName == "parsererror" ) throw "parsererror";