No ticket: compress ajax. Close gh-1041.

This commit is contained in:
Richard Gibson 2012-11-23 10:29:08 -05:00
parent c27dc018e2
commit a938d7b128
4 changed files with 293 additions and 328 deletions

View File

@ -3,17 +3,16 @@ var
ajaxLocParts,
ajaxLocation,
antiCacheValue = jQuery.now(),
ajax_nonce = jQuery.now(),
ajax_rquery = /\?/,
rhash = /#.*$/,
rts = /([?&])_=[^&]*/,
rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
// #7653, #8125, #8152: local protocol detection
rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,
rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
rnoContent = /^(?:GET|HEAD)$/,
rprotocol = /^\/\//,
rquery = /\?/,
rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
rts = /([?&])_=[^&]*/,
rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,
// Keep a copy of the old load method
@ -38,7 +37,7 @@ var
transports = {},
// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
allTypes = ["*/"] + ["*"];
allTypes = "*/".concat("*");
// #8138, IE may throw an exception when accessing
// a field from window.location if document.domain has been set
@ -66,24 +65,22 @@ function addToPrefiltersOrTransports( structure ) {
dataTypeExpression = "*";
}
var dataType, list, placeBefore,
dataTypes = dataTypeExpression.toLowerCase().split( core_rspace ),
var dataType,
i = 0,
length = dataTypes.length;
dataTypes = dataTypeExpression.toLowerCase().split( core_rspace );
if ( jQuery.isFunction( func ) ) {
// For each dataType in the dataTypeExpression
for ( ; i < length; i++ ) {
dataType = dataTypes[ i ];
// We control if we're asked to add before
// any existing element
placeBefore = /^\+/.test( dataType );
if ( placeBefore ) {
dataType = dataType.substr( 1 ) || "*";
while ( (dataType = dataTypes[i++]) ) {
// Prepend if requested
if ( dataType[0] === "+" ) {
dataType = dataType.slice( 1 ) || "*";
(structure[ dataType ] = structure[ dataType ] || []).unshift( func );
// Otherwise append
} else {
(structure[ dataType ] = structure[ dataType ] || []).push( func );
}
list = structure[ dataType ] = structure[ dataType ] || [];
// then we add to the structure accordingly
list[ placeBefore ? "unshift" : "push" ]( func );
}
}
};
@ -120,14 +117,17 @@ function inspectPrefiltersOrTransports( structure, options, originalOptions, jqX
function ajaxExtend( target, src ) {
var key, deep,
flatOptions = jQuery.ajaxSettings.flatOptions || {};
for ( key in src ) {
if ( src[ key ] !== undefined ) {
( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
}
}
if ( deep ) {
jQuery.extend( true, target, deep );
}
return target;
}
jQuery.fn.load = function( url, params, callback ) {
@ -135,11 +135,6 @@ jQuery.fn.load = function( url, params, callback ) {
return _load.apply( this, arguments );
}
// Don't do a request if no elements are being requested
if ( !this.length ) {
return this;
}
var selector, type, response,
self = this,
off = url.indexOf(" ");
@ -161,49 +156,41 @@ jQuery.fn.load = function( url, params, callback ) {
type = "POST";
}
// Request the remote document
jQuery.ajax({
url: url,
// If we have elements to modify, make the request
if ( self.length > 0 ) {
jQuery.ajax({
url: url,
// if "type" variable is undefined, then "GET" method will be used
type: type,
dataType: "html",
data: params,
complete: function( jqXHR, status ) {
if ( callback ) {
self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
}
}
}).done(function( responseText ) {
// if "type" variable is undefined, then "GET" method will be used
type: type,
dataType: "html",
data: params
}).done(function( responseText ) {
// Save response for use in complete callback
response = arguments;
// Save response for use in complete callback
response = arguments;
// See if a selector was specified
self.html( selector ?
self.html( selector ?
// Create a dummy div to hold the results
jQuery("<div>")
// If a selector was specified, locate the right elements in a dummy div
// Exclude scripts to avoid IE 'Permission Denied' errors
jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) :
// inject the contents of the document in, removing the scripts
// to avoid any 'Permission Denied' errors in IE
.append( responseText.replace( rscript, "" ) )
// Otherwise use the full result
responseText );
// Locate the specified elements
.find( selector ) :
// If not, just inject the full result
responseText );
});
}).complete( callback && function( jqXHR, status ) {
self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
});
}
return this;
};
// Attach a bunch of functions for handling common AJAX events
jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
jQuery.fn[ o ] = function( f ){
return this.on( o, f );
jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ){
jQuery.fn[ type ] = function( fn ){
return this.on( type, fn );
};
});
@ -217,50 +204,32 @@ jQuery.each( [ "get", "post" ], function( i, method ) {
}
return jQuery.ajax({
type: method,
url: url,
type: method,
dataType: type,
data: data,
success: callback,
dataType: type
success: callback
});
};
});
jQuery.extend({
getScript: function( url, callback ) {
return jQuery.get( url, undefined, callback, "script" );
},
// Counter for holding the number of active queries
active: 0,
getJSON: function( url, data, callback ) {
return jQuery.get( url, data, callback, "json" );
},
// Creates a full fledged settings object into target
// with both ajaxSettings and settings fields.
// If target is omitted, writes into ajaxSettings.
ajaxSetup: function( target, settings ) {
if ( settings ) {
// Building a settings object
ajaxExtend( target, jQuery.ajaxSettings );
} else {
// Extending ajaxSettings
settings = target;
target = jQuery.ajaxSettings;
}
ajaxExtend( target, settings );
return target;
},
// Last-Modified header cache for next request
lastModified: {},
etag: {},
ajaxSettings: {
url: ajaxLocation,
type: "GET",
isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
global: true,
type: "GET",
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
processData: true,
async: true,
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
/*
timeout: 0,
data: null,
@ -274,11 +243,11 @@ jQuery.extend({
*/
accepts: {
xml: "application/xml, text/xml",
html: "text/html",
"*": allTypes,
text: "text/plain",
json: "application/json, text/javascript",
"*": allTypes
html: "text/html",
xml: "application/xml, text/xml",
json: "application/json, text/javascript"
},
contents: {
@ -292,9 +261,8 @@ jQuery.extend({
text: "responseText"
},
// List of data converters
// 1) key format is "source_type destination_type" (a single space in-between)
// 2) the catchall symbol "*" can be used for source_type
// Data converters
// Keys separate source (or catchall "*") and destination types with a single space
converters: {
// Convert anything to text
@ -315,11 +283,24 @@ jQuery.extend({
// and when you create one that shouldn't be
// deep extended (see ajaxExtend)
flatOptions: {
context: true,
url: true
url: true,
context: true
}
},
// Creates a full fledged settings object into target
// with both ajaxSettings and settings fields.
// If target is omitted, writes into ajaxSettings.
ajaxSetup: function( target, settings ) {
return settings ?
// Building a settings object
ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
// Extending ajaxSettings
ajaxExtend( jQuery.ajaxSettings, target );
},
ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
ajaxTransport: addToPrefiltersOrTransports( transports ),
@ -335,13 +316,12 @@ jQuery.extend({
// Force options to be an object
options = options || {};
var // ifModified key
var transport,
// ifModified key
ifModifiedKey,
// Response headers
responseHeadersString,
responseHeaders,
// transport
transport,
// timeout handle
timeoutTimer,
// Cross-domain detection vars
@ -354,15 +334,13 @@ jQuery.extend({
s = jQuery.ajaxSetup( {}, options ),
// Callbacks context
callbackContext = s.context || s,
// Context for global events
// It's the callbackContext if one was provided in the options
// and if it's a DOM node or a jQuery collection
globalEventContext = callbackContext !== s &&
( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
jQuery( callbackContext ) : jQuery.event,
// Context for global events is callbackContext if it is a DOM node or jQuery collection
globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?
jQuery( callbackContext ) :
jQuery.event,
// Deferreds
deferred = jQuery.Deferred(),
completeDeferred = jQuery.Callbacks( "once memory" ),
completeDeferred = jQuery.Callbacks("once memory"),
// Status-dependent callbacks
statusCode = s.statusCode || {},
// Headers (they are sent all at once)
@ -374,37 +352,36 @@ jQuery.extend({
strAbort = "canceled",
// Fake xhr
jqXHR = {
readyState: 0,
// Caches the header
setRequestHeader: function( name, value ) {
if ( !state ) {
var lname = name.toLowerCase();
name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
requestHeaders[ name ] = value;
}
return this;
},
// Raw string
getAllResponseHeaders: function() {
return state === 2 ? responseHeadersString : null;
},
// Builds headers hashtable if needed
getResponseHeader: function( key ) {
var match;
if ( state === 2 ) {
if ( !responseHeaders ) {
responseHeaders = {};
while( ( match = rheaders.exec( responseHeadersString ) ) ) {
while ( (match = rheaders.exec( responseHeadersString )) ) {
responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
}
}
match = responseHeaders[ key.toLowerCase() ];
}
return match === undefined ? null : match;
return match == null ? null : match;
},
// Raw string
getAllResponseHeaders: function() {
return state === 2 ? responseHeadersString : null;
},
// Caches the header
setRequestHeader: function( name, value ) {
var lname = name.toLowerCase();
if ( !state ) {
name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
requestHeaders[ name ] = value;
}
return this;
},
// Overrides response content-type header
@ -415,148 +392,38 @@ jQuery.extend({
return this;
},
// Status-dependent callbacks
statusCode: function( map ) {
var code;
if ( map ) {
if ( state < 2 ) {
for ( code in map ) {
// Lazy-add the new callback in a way that preserves old ones
statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
}
} else {
// Execute the appropriate callbacks
jqXHR.always( map[ jqXHR.status ] );
}
}
return this;
},
// Cancel the request
abort: function( statusText ) {
statusText = statusText || strAbort;
var finalText = statusText || strAbort;
if ( transport ) {
transport.abort( statusText );
transport.abort( finalText );
}
done( 0, statusText );
done( 0, finalText );
return this;
}
};
// Callback for when everything is done
// It is defined here because jslint complains if it is declared
// at the end of the function (which would be more logical and readable)
function done( status, nativeStatusText, responses, headers ) {
var isSuccess, success, error, response, modified,
statusText = nativeStatusText;
// Called once
if ( state === 2 ) {
return;
}
// State is "done" now
state = 2;
// Clear timeout if it exists
if ( timeoutTimer ) {
clearTimeout( timeoutTimer );
}
// Dereference transport for early garbage collection
// (no matter how long the jqXHR object will be used)
transport = undefined;
// Cache response headers
responseHeadersString = headers || "";
// Set readyState
jqXHR.readyState = status > 0 ? 4 : 0;
// Get response data
if ( responses ) {
response = ajaxHandleResponses( s, jqXHR, responses );
}
// If successful, handle type chaining
if ( status >= 200 && status < 300 || status === 304 ) {
// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
if ( s.ifModified ) {
modified = jqXHR.getResponseHeader("Last-Modified");
if ( modified ) {
jQuery.lastModified[ ifModifiedKey ] = modified;
}
modified = jqXHR.getResponseHeader("Etag");
if ( modified ) {
jQuery.etag[ ifModifiedKey ] = modified;
}
}
// If not modified
if ( status === 304 ) {
statusText = "notmodified";
isSuccess = true;
// If we have data
} else {
isSuccess = ajaxConvert( s, response );
statusText = isSuccess.state;
success = isSuccess.data;
error = isSuccess.error;
isSuccess = !error;
}
} else {
// We extract error from statusText
// then normalize statusText and status for non-aborts
error = statusText;
if ( !statusText || status ) {
statusText = "error";
if ( status < 0 ) {
status = 0;
}
}
}
// Set data for the fake xhr object
jqXHR.status = status;
jqXHR.statusText = ( nativeStatusText || statusText ) + "";
// Success/Error
if ( isSuccess ) {
deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
} else {
deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
}
// Status-dependent callbacks
jqXHR.statusCode( statusCode );
statusCode = undefined;
if ( fireGlobals ) {
globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
[ jqXHR, s, isSuccess ? success : error ] );
}
// Complete
completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
if ( fireGlobals ) {
globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
// Handle the global AJAX counter
if ( !( --jQuery.active ) ) {
jQuery.event.trigger( "ajaxStop" );
}
}
}
// Attach deferreds
deferred.promise( jqXHR );
deferred.promise( jqXHR ).complete = completeDeferred.add;
jqXHR.success = jqXHR.done;
jqXHR.error = jqXHR.fail;
jqXHR.complete = completeDeferred.add;
// Status-dependent callbacks
jqXHR.statusCode = function( map ) {
if ( map ) {
var tmp;
if ( state < 2 ) {
for ( tmp in map ) {
statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
}
} else {
tmp = map[ jqXHR.status ];
jqXHR.always( tmp );
}
}
return this;
};
// Remove hash character (#7531: and string promotion)
// Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
@ -593,23 +460,23 @@ jQuery.extend({
// We can fire global events as of now if asked to
fireGlobals = s.global;
// Watch for a new set of requests
if ( fireGlobals && jQuery.active++ === 0 ) {
jQuery.event.trigger("ajaxStart");
}
// Uppercase the type
s.type = s.type.toUpperCase();
// Determine if request has content
s.hasContent = !rnoContent.test( s.type );
// Watch for a new set of requests
if ( fireGlobals && jQuery.active++ === 0 ) {
jQuery.event.trigger( "ajaxStart" );
}
// More options handling for requests with no content
if ( !s.hasContent ) {
// If data is available, append data to url
if ( s.data ) {
s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
s.url += ( ajax_rquery.test( s.url ) ? "&" : "?" ) + s.data;
// #9682: remove data so that it's not used in an eventual retry
delete s.data;
}
@ -619,21 +486,16 @@ jQuery.extend({
// Add anti-cache in url if needed
if ( s.cache === false ) {
s.url = rts.test( ifModifiedKey ) ?
var ts = antiCacheValue++,
// try replacing _= if it is there
ret = s.url.replace( rts, "$1_=" + ts );
// If there is already a '_' parameter, set its value
ifModifiedKey.replace( rts, "$1_=" + ajax_nonce++ ) :
// if nothing was replaced, add timestamp to the end
s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
// Otherwise add one to the end
ifModifiedKey + ( ajax_rquery.test( ifModifiedKey ) ? "&" : "?" ) + "_=" + ajax_nonce++;
}
}
// Set the correct header, if data is being sent
if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
jqXHR.setRequestHeader( "Content-Type", s.contentType );
}
// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
if ( s.ifModified ) {
ifModifiedKey = ifModifiedKey || s.url;
@ -645,6 +507,11 @@ jQuery.extend({
}
}
// Set the correct header, if data is being sent
if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
jqXHR.setRequestHeader( "Content-Type", s.contentType );
}
// Set the Accepts header for the server, depending on the dataType
jqXHR.setRequestHeader(
"Accept",
@ -681,21 +548,22 @@ jQuery.extend({
done( -1, "No Transport" );
} else {
jqXHR.readyState = 1;
// Send global event
if ( fireGlobals ) {
globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
}
// Timeout
if ( s.async && s.timeout > 0 ) {
timeoutTimer = setTimeout( function(){
jqXHR.abort( "timeout" );
timeoutTimer = setTimeout(function() {
jqXHR.abort("timeout");
}, s.timeout );
}
try {
state = 1;
transport.send( requestHeaders, done );
} catch (e) {
} catch ( e ) {
// Propagate exception as error if not done
if ( state < 2 ) {
done( -1, e );
@ -706,16 +574,121 @@ jQuery.extend({
}
}
// Callback for when everything is done
function done( status, nativeStatusText, responses, headers ) {
var isSuccess, success, error, response, modified,
statusText = nativeStatusText;
// Called once
if ( state === 2 ) {
return;
}
// State is "done" now
state = 2;
// Clear timeout if it exists
if ( timeoutTimer ) {
clearTimeout( timeoutTimer );
}
// Dereference transport for early garbage collection
// (no matter how long the jqXHR object will be used)
transport = undefined;
// Cache response headers
responseHeadersString = headers || "";
// Set readyState
jqXHR.readyState = status > 0 ? 4 : 0;
// Get response data
if ( responses ) {
response = ajaxHandleResponses( s, jqXHR, responses );
}
// If successful, handle type chaining
if ( status >= 200 && status < 300 || status === 304 ) {
// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
if ( s.ifModified ) {
modified = jqXHR.getResponseHeader("Last-Modified");
if ( modified ) {
jQuery.lastModified[ ifModifiedKey ] = modified;
}
modified = jqXHR.getResponseHeader("etag");
if ( modified ) {
jQuery.etag[ ifModifiedKey ] = modified;
}
}
// If not modified
if ( status === 304 ) {
isSuccess = true;
statusText = "notmodified";
// If we have data
} else {
isSuccess = ajaxConvert( s, response );
statusText = isSuccess.state;
success = isSuccess.data;
error = isSuccess.error;
isSuccess = !error;
}
} else {
// We extract error from statusText
// then normalize statusText and status for non-aborts
error = statusText;
if ( status || !statusText ) {
statusText = "error";
if ( status < 0 ) {
status = 0;
}
}
}
// Set data for the fake xhr object
jqXHR.status = status;
jqXHR.statusText = ( nativeStatusText || statusText ) + "";
// Success/Error
if ( isSuccess ) {
deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
} else {
deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
}
// Status-dependent callbacks
jqXHR.statusCode( statusCode );
statusCode = undefined;
if ( fireGlobals ) {
globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
[ jqXHR, s, isSuccess ? success : error ] );
}
// Complete
completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
if ( fireGlobals ) {
globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
// Handle the global AJAX counter
if ( !( --jQuery.active ) ) {
jQuery.event.trigger("ajaxStop");
}
}
}
return jqXHR;
},
// Counter for holding the number of active queries
active: 0,
// Last-Modified header cache for next request
lastModified: {},
etag: {}
getScript: function( url, callback ) {
return jQuery.get( url, undefined, callback, "script" );
},
getJSON: function( url, data, callback ) {
return jQuery.get( url, data, callback, "json" );
}
});
/* Handles responses to an ajax request:
@ -741,7 +714,7 @@ function ajaxHandleResponses( s, jqXHR, responses ) {
while( dataTypes[ 0 ] === "*" ) {
dataTypes.shift();
if ( ct === undefined ) {
ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
}
}
@ -788,11 +761,11 @@ function ajaxHandleResponses( s, jqXHR, responses ) {
function ajaxConvert( s, response ) {
var conv, conv2, current, tmp,
converters = {},
i = 0,
// Work with a copy of dataTypes in case we need to modify it for conversion
dataTypes = s.dataTypes.slice(),
prev = dataTypes[ 0 ],
converters = {},
i = 0;
prev = dataTypes[ 0 ];
// Apply the dataFilter if provided
if ( s.dataFilter ) {

View File

@ -1,13 +1,11 @@
var oldCallbacks = [],
rquestion = /\?/,
rjsonp = /(=)\?(?=&|$)|\?\?/,
nonce = jQuery.now();
rjsonp = /(=)\?(?=&|$)|\?\?/;
// Default jsonp settings
jQuery.ajaxSetup({
jsonp: "callback",
jsonpCallback: function() {
var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( ajax_nonce++ ) );
this[ callback ] = true;
return callback;
}
@ -17,30 +15,24 @@ jQuery.ajaxSetup({
jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
var callbackName, overwritten, responseContainer,
data = s.data,
url = s.url,
hasCallback = s.jsonp !== false,
replaceInUrl = hasCallback && rjsonp.test( url ),
replaceInData = hasCallback && !replaceInUrl && typeof data === "string" &&
!( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") &&
rjsonp.test( data );
jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
"url" :
typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
);
// Handle iff the expected data type is "jsonp" or we have a parameter to set
if ( s.dataTypes[ 0 ] === "jsonp" || replaceInUrl || replaceInData ) {
if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
// Get callback name, remembering preexisting value associated with it
callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
s.jsonpCallback() :
s.jsonpCallback;
overwritten = window[ callbackName ];
// Insert callback into url or form data
if ( replaceInUrl ) {
s.url = url.replace( rjsonp, "$1" + callbackName );
} else if ( replaceInData ) {
s.data = data.replace( rjsonp, "$1" + callbackName );
} else if ( hasCallback ) {
s.url += ( rquestion.test( url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
if ( jsonProp ) {
s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
} else if ( s.jsonp !== false ) {
s.url += ( ajax_rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
}
// Use data converter to retrieve json after script execution
@ -55,6 +47,7 @@ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
s.dataTypes[ 0 ] = "json";
// Install callback
overwritten = window[ callbackName ];
window[ callbackName ] = function() {
responseContainer = arguments;
};

View File

@ -4,7 +4,7 @@ jQuery.ajaxSetup({
script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
},
contents: {
script: /javascript|ecmascript/
script: /(?:java|ecma)script/
},
converters: {
"text script": function( text ) {
@ -32,13 +32,13 @@ jQuery.ajaxTransport( "script", function(s) {
if ( s.crossDomain ) {
var script,
head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
head = document.head || jQuery("head")[0] || document.documentElement;
return {
send: function( _, callback ) {
script = document.createElement( "script" );
script = document.createElement("script");
script.async = true;
@ -57,12 +57,12 @@ jQuery.ajaxTransport( "script", function(s) {
script.onload = script.onreadystatechange = null;
// Remove the script
if ( head && script.parentNode ) {
head.removeChild( script );
if ( script.parentNode ) {
script.parentNode.removeChild( script );
}
// Dereference the script
script = undefined;
script = null;
// Callback if not abort
if ( !isAbort ) {
@ -70,14 +70,15 @@ jQuery.ajaxTransport( "script", function(s) {
}
}
};
// Use insertBefore instead of appendChild to circumvent an IE6 bug.
// This arises when a base node is used (#2709 and #4378).
// Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
// Use native DOM manipulation to avoid our domManip AJAX trickery
head.insertBefore( script, head.firstChild );
},
abort: function() {
if ( script ) {
script.onload( 0, 1 );
script.onload( undefined, true );
}
}
};

View File

@ -1,12 +1,13 @@
var xhrCallbacks,
var xhrCallbacks, xhrSupported,
xhrId = 0,
// #5280: Internet Explorer will keep connections alive if we don't abort on unload
xhrOnUnloadAbort = window.ActiveXObject ? function() {
xhrOnUnloadAbort = window.ActiveXObject && function() {
// Abort all pending requests
for ( var key in xhrCallbacks ) {
xhrCallbacks[ key ]( 0, 1 );
var key;
for ( key in xhrCallbacks ) {
xhrCallbacks[ key ]( undefined, true );
}
} : false,
xhrId = 0;
};
// Functions to create xhrs
function createStandardXHR() {
@ -17,7 +18,7 @@ function createStandardXHR() {
function createActiveXHR() {
try {
return new window.ActiveXObject( "Microsoft.XMLHTTP" );
return new window.ActiveXObject("Microsoft.XMLHTTP");
} catch( e ) {}
}
@ -37,15 +38,12 @@ jQuery.ajaxSettings.xhr = window.ActiveXObject ?
createStandardXHR;
// Determine support properties
(function( xhr ) {
jQuery.extend( jQuery.support, {
ajax: !!xhr,
cors: !!xhr && ( "withCredentials" in xhr )
});
})( jQuery.ajaxSettings.xhr() );
xhrSupported = jQuery.ajaxSettings.xhr();
jQuery.support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
xhrSupported = jQuery.support.ajax = !!xhrSupported;
// Create transport if the browser can provide an xhr
if ( jQuery.support.ajax ) {
if ( xhrSupported ) {
jQuery.ajaxTransport(function( s ) {
// Cross domain only allowed if supported through XMLHttpRequest
@ -86,7 +84,7 @@ if ( jQuery.support.ajax ) {
// (it can always be set on a per-request basis or even using ajaxSetup)
// For same-domain requests, won't change header if already provided.
if ( !s.crossDomain && !headers["X-Requested-With"] ) {
headers[ "X-Requested-With" ] = "XMLHttpRequest";
headers["X-Requested-With"] = "XMLHttpRequest";
}
// Need an extra try/catch for cross domain requests in Firefox 3
@ -136,10 +134,10 @@ if ( jQuery.support.ajax ) {
xhr.abort();
}
} else {
status = xhr.status;
responseHeaders = xhr.getAllResponseHeaders();
responses = {};
status = xhr.status;
xml = xhr.responseXML;
responseHeaders = xhr.getAllResponseHeaders();
// Construct response list
if ( xml && xml.documentElement /* #4958 */ ) {
@ -211,7 +209,7 @@ if ( jQuery.support.ajax ) {
abort: function() {
if ( callback ) {
callback(0,1);
callback( undefined, true );
}
}
};