Merge branch 'master' of git://github.com/jquery/jquery into bug_7931

This commit is contained in:
Xavi 2011-01-18 12:06:05 -05:00
commit 0942b3b3f5
43 changed files with 4653 additions and 1146 deletions

View file

@ -61,26 +61,34 @@ jQuery.fn.extend({
type: type,
dataType: "html",
data: params,
complete: function( res, status ) {
// Complete callback (responseText is used internally)
complete: function( jXHR, status, responseText ) {
// Store the response as specified by the jXHR object
responseText = jXHR.responseText;
// If successful, inject the HTML into all the matched elements
if ( status === "success" || status === "notmodified" ) {
if ( jXHR.isResolved() ) {
// #4825: Get the actual response in case
// a dataFilter is present in ajaxSettings
jXHR.done(function( r ) {
responseText = r;
});
// See if a selector was specified
self.html( selector ?
// Create a dummy div to hold the results
jQuery("<div>")
// inject the contents of the document in, removing the scripts
// to avoid any 'Permission Denied' errors in IE
.append(res.responseText.replace(rscript, ""))
.append(responseText.replace(rscript, ""))
// Locate the specified elements
.find(selector) :
// If not, just inject the full result
res.responseText );
responseText );
}
if ( callback ) {
self.each( callback, [res.responseText, status, res] );
self.each( callback, [responseText, status, jXHR] );
}
}
});
@ -152,7 +160,8 @@ jQuery.extend({
},
ajaxSetup: function( settings ) {
jQuery.extend( jQuery.ajaxSettings, settings );
jQuery.extend( true, jQuery.ajaxSettings, settings );
return this;
},
ajaxSettings: {
@ -166,11 +175,12 @@ jQuery.extend({
timeout: 0,
data: null,
dataType: null,
dataTypes: null,
username: null,
password: null,
cache: null,
traditional: false,
headers: {},
crossDomain: null,
*/
xhr: function() {
return new window.XMLHttpRequest();
@ -257,6 +267,8 @@ jQuery.extend({
// Deferreds
deferred = jQuery.Deferred(),
completeDeferred = jQuery._Deferred(),
// Status-dependent callbacks
statusCode = s.statusCode || {},
// Headers (they are sent all at once)
requestHeaders = {},
// Response headers
@ -266,6 +278,9 @@ jQuery.extend({
transport,
// timeout handle
timeoutTimer,
// Cross-domain detection vars
loc = document.location,
parts,
// The jXHR state
state = 0,
// Loop variable
@ -292,30 +307,35 @@ jQuery.extend({
// (match is used internally)
getResponseHeader: function( key , match ) {
if ( state !== 2 ) {
return null;
}
if ( state === 2 ) {
if ( responseHeaders === undefined ) {
if ( responseHeaders === undefined ) {
responseHeaders = {};
responseHeaders = {};
if ( typeof responseHeadersString === "string" ) {
if ( typeof responseHeadersString === "string" ) {
while( ( match = rheaders.exec( responseHeadersString ) ) ) {
responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
while( ( match = rheaders.exec( responseHeadersString ) ) ) {
responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
}
}
}
match = responseHeaders[ key.toLowerCase() ];
} else {
match = null;
}
return responseHeaders[ key.toLowerCase() ];
return match;
},
// Cancel the request
abort: function( statusText ) {
if ( transport && state !== 2 ) {
if ( transport ) {
transport.abort( statusText || "abort" );
done( 0 , statusText );
}
done( 0 , statusText );
return this;
}
};
@ -333,6 +353,10 @@ jQuery.extend({
// State is "done" now
state = 2;
// Dereference transport for early garbage collection
// (no matter how long the jXHR transport will be used
transport = 0;
// Set readyState
jXHR.readyState = status ? 4 : 0;
@ -354,17 +378,10 @@ jQuery.extend({
// Stored success
success,
// Stored error
error = statusText;
// If not timeout, force a jQuery-compliant status text
if ( statusText != "timeout" ) {
statusText = ( status >= 200 && status < 300 ) ?
"success" :
( status === 304 ? "notmodified" : "error" );
}
error;
// If successful, handle type chaining
if ( statusText === "success" || statusText === "notmodified" ) {
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 ) {
@ -380,91 +397,124 @@ jQuery.extend({
}
}
if ( s.ifModified && statusText === "notmodified" ) {
// If not modified
if ( status === 304 ) {
success = null;
// Set the statusText accordingly
statusText = "notmodified";
// Mark as a success
isSuccess = 1;
// If we have data
} else {
// Set the statusText accordingly
statusText = "success";
// Chain data conversions and determine the final value
// (if an exception is thrown in the process, it'll be notified as an error)
try {
var i,
// Current dataType
current,
// Previous dataType
prev,
checker,
// Conversion function
conv,
// Conversion functions (when text is used in-between)
conv1,
conv2,
convertion,
// Local references to dataTypes & converters
dataTypes = s.dataTypes,
converters = s.converters,
// DataType to responseXXX field mapping
responses = {
"xml": "XML",
"text": "Text"
};
// For each dataType in the chain
for( i = 0 ; i < dataTypes.length ; i++ ) {
current = dataTypes[ i ];
// If a responseXXX field for this dataType exists
// and if it hasn't been set yet
if ( responses[ current ] ) {
// Set it
jXHR[ "response" + responses[ current ] ] = response;
// Mark it as set
responses[ current ] = 0;
}
// If this is not the first element
if ( i ) {
// Get the dataType to convert from
prev = dataTypes[ i - 1 ];
// If no catch-all and dataTypes are actually different
if ( prev !== "*" && current !== "*" && prev !== current ) {
conv = converters[ ( conversion = prev + " " + current ) ] ||
// Get the converter
conv = converters[ prev + " " + current ] ||
converters[ "* " + current ];
conv1 = conv2 = 0;
// If there is no direct converter and none of the dataTypes is text
if ( ! conv && prev !== "text" && current !== "text" ) {
// Try with text in-between
conv1 = converters[ prev + " text" ] || converters[ "* text" ];
conv2 = converters[ "text " + current ];
// Revert back to a single converter
// if one of the converter is an equivalence
if ( conv1 === true ) {
conv = conv2;
} else if ( conv2 === true ) {
conv = conv1;
}
}
// If we found no converter, dispatch an error
if ( ! ( conv || conv1 && conv2 ) ) {
throw conversion;
}
// If found converter is not an equivalence
if ( conv !== true ) {
// Convert with 1 or 2 converters accordingly
response = conv ? conv( response ) : conv2( conv1( response ) );
}
}
// If it is the first element of the chain
// and we have a dataFilter
} else if ( s.dataFilter ) {
response = s.dataFilter( response );
// Apply the dataFilter
response = s.dataFilter( response , current );
// Get dataTypes again in case the filter changed them
dataTypes = s.dataTypes;
}
}
// End of loop
// We have a real success
success = response;
isSuccess = 1;
// If an exception was thrown
} catch(e) {
// We have a parsererror
statusText = "parsererror";
error = "" + e;
}
}
} else { // if not success, mark it as an error
// if not success, mark it as an error
} else {
error = error || statusText;
error = statusText = statusText || "error";
// Set responseText if needed
if ( response ) {
@ -483,6 +533,9 @@ jQuery.extend({
deferred.fireReject( callbackContext , [ jXHR , statusText , error ] );
}
// Status-dependent callbacks
jXHR.statusCode( statusCode );
if ( s.global ) {
globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ) ,
[ jXHR , s , isSuccess ? success : error ] );
@ -506,23 +559,37 @@ jQuery.extend({
jXHR.error = jXHR.fail;
jXHR.complete = completeDeferred.done;
// Status-dependent callbacks
jXHR.statusCode = function( map ) {
if ( map ) {
var resolved = jXHR.isResolved(),
tmp;
if ( resolved || jXHR.isRejected() ) {
tmp = map[ jXHR.status ];
if ( tmp ) {
if ( map === statusCode ) {
delete statusCode[ jXHR.status ];
}
jXHR[ resolved ? "done" : "fail" ]( tmp );
}
} else {
for( tmp in map ) {
statusCode[ tmp ] = [ statusCode[ tmp ] , map[ tmp ] ];
}
}
}
return this;
};
// Remove hash character (#7531: and string promotion)
s.url = ( "" + s.url ).replace( rhash , "" );
// Uppercase the type
s.type = s.type.toUpperCase();
// Determine if request has content
s.hasContent = ! rnoContent.test( s.type );
// Extract dataTypes list
s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( /\s+/ );
// Determine if a cross-domain request is in order
var parts = rurl.exec( s.url.toLowerCase() ),
loc = location;
if ( ! s.crossDomain ) {
parts = rurl.exec( s.url.toLowerCase() );
s.crossDomain = !!(
parts &&
( parts[ 1 ] && parts[ 1 ] != loc.protocol ||
@ -532,88 +599,97 @@ jQuery.extend({
}
// Convert data if not already a string
if ( s.data && s.processData && typeof s.data != "string" ) {
if ( s.data && s.processData && typeof s.data !== "string" ) {
s.data = jQuery.param( s.data , s.traditional );
}
// Get transport
transport = jQuery.ajax.prefilter( s , options ).transport( s );
// Apply prefilters
jQuery.ajaxPrefilter( s , options );
// 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 ( s.global && jQuery.active++ === 0 ) {
jQuery.event.trigger( "ajaxStart" );
}
// If no transport, we auto-abort
if ( ! transport ) {
// More options handling for requests with no content
if ( ! s.hasContent ) {
done( 0 , "transport not found" );
jXHR = false;
// If data is available, append data to url
if ( s.data ) {
s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
}
// Add anti-cache in url if needed
if ( s.cache === false ) {
var ts = jQuery.now(),
// try replacing _= if it is there
ret = s.url.replace( rts , "$1_=" + ts );
// if nothing was replaced, add timestamp to the end
s.url = ret + ( (ret == s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "");
}
}
// Set the correct header, if data is being sent
if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
requestHeaders[ "content-type" ] = s.contentType;
}
// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
if ( s.ifModified ) {
if ( jQuery_lastModified[ s.url ] ) {
requestHeaders[ "if-modified-since" ] = jQuery_lastModified[ s.url ];
}
if ( jQuery_etag[ s.url ] ) {
requestHeaders[ "if-none-match" ] = jQuery_etag[ s.url ];
}
}
// Set the Accepts header for the server, depending on the dataType
requestHeaders.accept = s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
s.accepts[ s.dataTypes[ 0 ] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) :
s.accepts[ "*" ];
// Check for headers option
for ( i in s.headers ) {
requestHeaders[ i.toLowerCase() ] = s.headers[ i ];
}
// Allow custom headers/mimetypes and early abort
if ( s.beforeSend && ( s.beforeSend.call( callbackContext , jXHR , s ) === false || state === 2 ) ) {
// Abort if not done already
done( 0 , "abort" );
// Return false
jXHR = false;
} else {
// 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;
}
// Add anti-cache in url if needed
if ( s.cache === false ) {
var ts = jQuery.now(),
// try replacing _= if it is there
ret = s.url.replace( rts , "$1_=" + ts );
// if nothing was replaced, add timestamp to the end
s.url = ret + ( (ret == s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "");
}
// Install callbacks on deferreds
for ( i in { success:1, error:1, complete:1 } ) {
jXHR[ i ]( s[ i ] );
}
// Set the correct header, if data is being sent
if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
requestHeaders[ "content-type" ] = s.contentType;
}
// Get transport
transport = jQuery.ajaxTransport( s );
// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
if ( s.ifModified ) {
if ( jQuery_lastModified[ s.url ] ) {
requestHeaders[ "if-modified-since" ] = jQuery_lastModified[ s.url ];
}
if ( jQuery_etag[ s.url ] ) {
requestHeaders[ "if-none-match" ] = jQuery_etag[ s.url ];
}
}
// If no transport, we auto-abort
if ( ! transport ) {
// Set the Accepts header for the server, depending on the dataType
requestHeaders.accept = s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
s.accepts[ s.dataTypes[ 0 ] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) :
s.accepts[ "*" ];
// Check for headers option
for ( i in s.headers ) {
requestHeaders[ i.toLowerCase() ] = s.headers[ i ];
}
// Allow custom headers/mimetypes and early abort
if ( s.beforeSend && ( s.beforeSend.call( callbackContext , jXHR , s ) === false || state === 2 ) ) {
// Abort if not done already
done( 0 , "abort" );
jXHR = false;
done( 0 , "notransport" );
} else {
// Set state as sending
state = 1;
jXHR.readyState = 1;
// Install callbacks on deferreds
for ( i in { success:1, error:1, complete:1 } ) {
jXHR[ i ]( s[ i ] );
}
state = jXHR.readyState = 1;
// Send global event
if ( s.global ) {
@ -787,7 +863,7 @@ function ajax_selectOrExecute( structure , s ) {
}
}
return noSelect ? jQuery.ajax : selected;
return noSelect ? jQuery : selected;
}
// Add an element to one of the structures in ajaxSettings
@ -846,13 +922,13 @@ function ajax_addElement( structure , args ) {
}
}
return jQuery.ajax;
return jQuery;
}
// Install prefilter & transport methods
jQuery.each( [ "prefilter" , "transport" ] , function( _ , name ) {
_ = name + "s";
jQuery.ajax[ name ] = function() {
jQuery.each( [ "Prefilter" , "Transport" ] , function( _ , name ) {
_ = name.toLowerCase() + "s";
jQuery[ "ajax" + name ] = function() {
return ajax_addElement( _ , arguments );
};
} );

View file

@ -1,8 +1,7 @@
(function( jQuery ) {
var jsc = jQuery.now(),
jsre = /\=(?:\?|%3F)(&|$)/i,
rquery_jsonp = /\?/;
jsre = /(\=)(?:\?|%3F)(&|$)|()(?:\?\?|%3F%3F)()/i;
// Default jsonp settings
jQuery.ajaxSetup({
@ -10,75 +9,78 @@ jQuery.ajaxSetup({
jsonpCallback: function() {
return "jsonp" + jsc++;
}
});
// Normalize jsonp queries
// 1) put callback parameter in url or data
// 2) sneakily ensure transportDataType is always jsonp for jsonp requests
jQuery.ajax.prefilter("json jsonp", function(s, originalSettings) {
// Detect, normalize options and install callbacks for jsonp requests
// (dataIsString is used internally)
}).ajaxPrefilter("json jsonp", function(s, originalSettings, dataIsString) {
dataIsString = ( typeof(s.data) === "string" );
if ( s.dataTypes[ 0 ] === "jsonp" ||
originalSettings.jsonp ||
originalSettings.jsonpCallback ||
jsre.test(s.url) ||
typeof(s.data) === "string" && jsre.test(s.data) ) {
originalSettings.jsonp != null ||
s.jsonp !== false && ( jsre.test( s.url ) ||
dataIsString && jsre.test( s.data ) ) ) {
var jsonpCallback = s.jsonpCallback =
var responseContainer,
jsonpCallback = s.jsonpCallback =
jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
url = s.url.replace(jsre, "=" + jsonpCallback + "$1"),
data = s.url === url && typeof(s.data) === "string" ? s.data.replace(jsre, "=" + jsonpCallback + "$1") : s.data;
previous = window[ jsonpCallback ],
url = s.url,
data = s.data,
replace = "$1" + jsonpCallback + "$2";
if ( url === s.url && data === s.data ) {
url += (rquery_jsonp.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
if ( s.jsonp !== false ) {
url = url.replace( jsre, replace );
if ( s.url === url ) {
if ( dataIsString ) {
data = data.replace( jsre, replace );
}
if ( s.data === data ) {
// Add callback manually
url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
}
}
}
s.url = url;
s.data = data;
s.dataTypes[ 0 ] = "jsonp";
}
// Bind transport to jsonp dataType
}).transport("jsonp", function(s) {
window [ jsonpCallback ] = function( response ) {
responseContainer = [response];
};
// Put callback in place
var responseContainer,
jsonpCallback = s.jsonpCallback,
previous = window[ jsonpCallback ];
s.complete = [function() {
window [ jsonpCallback ] = function( response ) {
responseContainer = [response];
};
// Set callback back to previous value
window[ jsonpCallback ] = previous;
s.complete = [function() {
// Set callback back to previous value
window[ jsonpCallback ] = previous;
// Call if it was a function and we have a response
if ( previous) {
if ( responseContainer && jQuery.isFunction ( previous ) ) {
window[ jsonpCallback ] ( responseContainer[0] );
// Call if it was a function and we have a response
if ( previous) {
if ( responseContainer && jQuery.isFunction ( previous ) ) {
window[ jsonpCallback ] ( responseContainer[0] );
}
} else {
// else, more memory leak avoidance
try{ delete window[ jsonpCallback ]; } catch(e){}
}
} else {
// else, more memory leak avoidance
try{ delete window[ jsonpCallback ]; } catch(e){}
}
}, s.complete ];
}, s.complete ];
// Sneakily ensure this will be handled as json
s.dataTypes[ 0 ] = "json";
// Use data converter to retrieve json after script execution
s.converters["script json"] = function() {
if ( ! responseContainer ) {
jQuery.error( jsonpCallback + " was not called" );
}
return responseContainer[ 0 ];
};
// Use data converter to retrieve json after script execution
s.converters["script json"] = function() {
if ( ! responseContainer ) {
jQuery.error( jsonpCallback + " was not called" );
}
return responseContainer[ 0 ];
};
// force json dataType
s.dataTypes[ 0 ] = "json";
// Delegate to script transport
return "script";
// Delegate to script
return "script";
}
});
})( jQuery );

View file

@ -1,7 +1,7 @@
(function( jQuery ) {
// Install text to script executor
jQuery.extend( true, jQuery.ajaxSettings , {
// Install script dataType
jQuery.ajaxSetup({
accepts: {
script: "text/javascript, application/javascript"
@ -14,20 +14,24 @@ jQuery.extend( true, jQuery.ajaxSettings , {
converters: {
"text script": jQuery.globalEval
}
} );
// Bind script tag hack transport
jQuery.ajax.transport("script", function(s) {
// Handle cache's special case and global
}).ajaxPrefilter("script", function(s) {
// Handle cache special case
if ( s.cache === undefined ) {
s.cache = false;
}
// This transport only deals with cross domain get requests
if ( s.crossDomain && s.async && ( s.type === "GET" || ! s.data ) ) {
if ( s.crossDomain ) {
s.type = "GET";
s.global = false;
}
// Bind script tag hack transport
}).ajaxTransport("script", function(s) {
// This transport only deals with cross domain requests
if ( s.crossDomain ) {
var script,
head = document.getElementsByTagName("head")[0] || document.documentElement;
@ -47,7 +51,7 @@ jQuery.ajax.transport("script", function(s) {
script.src = s.url;
// Attach handlers for all browsers
script.onload = script.onreadystatechange = function( _ , statusText) {
script.onload = script.onreadystatechange = function( _ , isAbort ) {
if ( ! script.readyState || /loaded|complete/.test( script.readyState ) ) {
@ -59,10 +63,13 @@ jQuery.ajax.transport("script", function(s) {
head.removeChild( script );
}
// Dereference the script
script = 0;
// Callback
callback( statusText ? 0 : 200, statusText || "success" );
// Callback if not abort
if ( ! isAbort ) {
callback( 200, "success" );
}
}
};
// Use insertBefore instead of appendChild to circumvent an IE6 bug.
@ -70,9 +77,9 @@ jQuery.ajax.transport("script", function(s) {
head.insertBefore( script, head.firstChild );
},
abort: function(statusText) {
abort: function() {
if ( script ) {
script.onload( 0 , statusText );
script.onload(0,1);
}
}
};

View file

@ -1,19 +1,16 @@
(function( jQuery ) {
var // Next fake timer id
xhrPollingId = jQuery.now(),
var // Next active xhr id
xhrId = jQuery.now(),
// Callbacks hashtable
// active xhrs
xhrs = {},
// XHR pool
xhrPool = [],
// #5280: see end of file
xhrUnloadAbortMarker;
// #5280: see below
xhrUnloadAbortInstalled;
jQuery.ajax.transport( function( s , determineDataType ) {
jQuery.ajaxTransport( function( s , determineDataType ) {
// Cross domain only allowed if supported through XMLHttpRequest
if ( ! s.crossDomain || jQuery.support.cors ) {
@ -25,26 +22,24 @@ jQuery.ajax.transport( function( s , determineDataType ) {
send: function(headers, complete) {
// #5280: we need to abort on unload or IE will keep connections alive
if ( ! xhrUnloadAbortMarker ) {
if ( ! xhrUnloadAbortInstalled ) {
xhrUnloadAbortMarker = [];
xhrUnloadAbortInstalled = 1;
jQuery(window).bind( "unload" , function() {
// Abort all pending requests
jQuery.each(xhrs, function(_, xhr) {
if ( xhr.onreadystatechange ) {
xhr.onreadystatechange( xhrUnloadAbortMarker );
xhr.onreadystatechange( 1 );
}
});
// Reset polling structure to be safe
xhrs = {};
});
}
var xhr = xhrPool.pop() || s.xhr(),
// Get a new xhr
var xhr = s.xhr(),
handle;
// Open the socket
@ -58,7 +53,7 @@ jQuery.ajax.transport( function( s , determineDataType ) {
// Requested-With header
// Not set for crossDomain requests with no content
// (see why at http://trac.dojotoolkit.org/ticket/9486)
// Won't change header if already provided in beforeSend
// Won't change header if already provided
if ( ! ( s.crossDomain && ! s.hasContent ) && ! headers["x-requested-with"] ) {
headers["x-requested-with"] = "XMLHttpRequest";
}
@ -76,49 +71,40 @@ jQuery.ajax.transport( function( s , determineDataType ) {
try {
xhr.send( ( s.hasContent && s.data ) || null );
} catch(e) {
// Store back in pool
xhrPool.push( xhr );
complete(0, "error", "" + e);
return;
}
// Listener
callback = function ( abortStatusText ) {
callback = function( _ , isAbort ) {
// Was never called and is aborted or complete
if ( callback && ( abortStatusText || xhr.readyState === 4 ) ) {
if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
// Do not listen anymore
// and Store back in pool
// Only called once
callback = 0;
// Do not keep as active anymore
// and store back into pool
if (handle) {
xhr.onreadystatechange = jQuery.noop;
delete xhrs[ handle ];
handle = undefined;
xhrPool.push( xhr );
}
callback = 0;
// Get info
var status, statusText, response, responseHeaders;
if ( abortStatusText ) {
// If it's an abort
if ( isAbort ) {
// Abort it manually if needed
if ( xhr.readyState !== 4 ) {
xhr.abort();
}
// Stop here if unloadAbort
if ( abortStatusText === xhrUnloadAbortMarker ) {
return;
}
status = 0;
statusText = abortStatusText;
} else {
status = xhr.status;
// Get info
var status = xhr.status,
statusText,
response,
responseHeaders = xhr.getAllResponseHeaders();
try { // Firefox throws an exception when accessing statusText for faulty cross-domain requests
@ -130,8 +116,6 @@ jQuery.ajax.transport( function( s , determineDataType ) {
}
responseHeaders = xhr.getAllResponseHeaders();
// Filter status for non standard behaviours
// (so many they seem to be the actual "standard")
status =
@ -164,10 +148,10 @@ jQuery.ajax.transport( function( s , determineDataType ) {
xhr.getResponseHeader("content-type"),
xhr.responseText,
xhr.responseXML );
}
// Call complete
complete(status,statusText,response,responseHeaders);
// Call complete
complete(status,statusText,response,responseHeaders);
}
}
};
@ -180,18 +164,16 @@ jQuery.ajax.transport( function( s , determineDataType ) {
} else {
// Listener is externalized to handle abort on unload
handle = xhrPollingId++;
// Add to list of active xhrs
handle = xhrId++;
xhrs[ handle ] = xhr;
xhr.onreadystatechange = function() {
callback();
};
xhr.onreadystatechange = callback;
}
},
abort: function(statusText) {
abort: function() {
if ( callback ) {
callback(statusText);
callback(0,1);
}
}
};

View file

@ -133,11 +133,11 @@ jQuery.fn.extend({
} else if ( type === "undefined" || type === "boolean" ) {
if ( this.className ) {
// store className if set
jQuery.data( this, "__className__", this.className );
jQuery._data( this, "__className__", this.className );
}
// toggle whole className
this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";
this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
}
});
},

View file

@ -3,7 +3,7 @@ var jQuery = (function() {
// Define a local copy of jQuery
var jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
return new jQuery.fn.init( selector, context );
return new jQuery.fn.init( selector, context, rootjQuery );
},
// Map over jQuery in case of overwrite
@ -63,6 +63,9 @@ var jQuery = function( selector, context ) {
// The deferred used on DOM ready
readyList,
// Promise methods
promiseMethods = "then done fail isResolved isRejected promise".split( " " ),
// The ready event handler
DOMContentLoaded,
@ -78,7 +81,8 @@ var jQuery = function( selector, context ) {
class2type = {};
jQuery.fn = jQuery.prototype = {
init: function( selector, context ) {
constructor: jQuery,
init: function( selector, context, rootjQuery ) {
var match, elem, ret, doc;
// Handle $(""), $(null), or $(undefined)
@ -112,6 +116,7 @@ jQuery.fn = jQuery.prototype = {
// HANDLE: $(html) -> $(array)
if ( match[1] ) {
context = context instanceof jQuery ? context[0] : context;
doc = (context ? context.ownerDocument || context : document);
// If a single string is passed in and it's a single tag
@ -129,7 +134,7 @@ jQuery.fn = jQuery.prototype = {
} else {
ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
selector = (ret.cacheable ? jQuery(ret.fragment).clone()[0] : ret.fragment).childNodes;
}
return jQuery.merge( this, selector );
@ -171,7 +176,7 @@ jQuery.fn = jQuery.prototype = {
// HANDLE: $(expr, context)
// (which is just equivalent to: $(context).find(expr)
} else {
return jQuery( context ).find( selector );
return this.constructor( context ).find( selector );
}
// HANDLE: $(function)
@ -222,7 +227,7 @@ jQuery.fn = jQuery.prototype = {
// (returning the new matched element set)
pushStack: function( elems, name, selector ) {
// Build a new jQuery matched element set
var ret = jQuery();
var ret = this.constructor();
if ( jQuery.isArray( elems ) ) {
push.apply( ret, elems );
@ -287,7 +292,7 @@ jQuery.fn = jQuery.prototype = {
},
end: function() {
return this.prevObject || jQuery(null);
return this.prevObject || this.constructor(null);
},
// For internal use only.
@ -578,7 +583,7 @@ jQuery.extend({
script.type = "text/javascript";
if ( jQuery.support.scriptEval ) {
if ( jQuery.support.scriptEval() ) {
script.appendChild( document.createTextNode( data ) );
} else {
script.text = data;
@ -896,9 +901,10 @@ jQuery.extend({
Deferred: function( func ) {
var deferred = jQuery._Deferred(),
failDeferred = jQuery._Deferred();
failDeferred = jQuery._Deferred(),
promise;
// Add errorDeferred methods and redefine cancel
// Add errorDeferred methods, then and promise
jQuery.extend( deferred , {
then: function( doneCallbacks , failCallbacks ) {
@ -911,14 +917,18 @@ jQuery.extend({
isRejected: failDeferred.isResolved,
// Get a promise for this deferred
// If obj is provided, the promise aspect is added to the object
promise: function( obj ) {
obj = obj || {};
jQuery.each( "then done fail isResolved isRejected".split( " " ) , function( _ , method ) {
obj[ method ] = deferred[ method ];
});
obj.promise = function() {
return obj;
};
// (i is used internally)
promise: function( obj , i ) {
if ( obj == null ) {
if ( promise ) {
return promise;
}
promise = obj = {};
}
i = promiseMethods.length;
while( i-- ) {
obj[ promiseMethods[ i ] ] = deferred[ promiseMethods[ i ] ];
}
return obj;
}
@ -940,10 +950,32 @@ jQuery.extend({
// Deferred helper
when: function( object ) {
object = object && jQuery.isFunction( object.promise ) ?
object :
jQuery.Deferred().resolve( object );
return object.promise();
var args = arguments,
length = args.length,
deferred = length <= 1 && object && jQuery.isFunction( object.promise ) ?
object :
jQuery.Deferred(),
promise = deferred.promise(),
resolveArray;
if ( length > 1 ) {
resolveArray = new Array( length );
jQuery.each( args, function( index, element, args ) {
jQuery.when( element ).done( function( value ) {
args = arguments;
resolveArray[ index ] = args.length > 1 ? slice.call( args , 0 ) : value;
if( ! --length ) {
deferred.fire( promise, resolveArray );
}
}).fail( function() {
deferred.fireReject( promise, arguments );
});
return !deferred.isRejected();
});
} else if ( deferred !== object ) {
deferred.resolve( object );
}
return promise;
},
// Use of jQuery.browser is frowned upon.
@ -960,6 +992,25 @@ jQuery.extend({
return { browser: match[1] || "", version: match[2] || "0" };
},
subclass: function(){
function jQuerySubclass( selector, context ) {
return new jQuerySubclass.fn.init( selector, context );
}
jQuerySubclass.superclass = this;
jQuerySubclass.fn = jQuerySubclass.prototype = this();
jQuerySubclass.fn.constructor = jQuerySubclass;
jQuerySubclass.subclass = this.subclass;
jQuerySubclass.fn.init = function init( selector, context ) {
if (context && context instanceof jQuery && !(context instanceof jQuerySubclass)){
context = jQuerySubclass(context);
}
return jQuery.fn.init.call( this, selector, context, rootjQuerySubclass );
};
jQuerySubclass.fn.init.prototype = jQuerySubclass.fn;
var rootjQuerySubclass = jQuerySubclass(document);
return jQuerySubclass;
},
browser: {}
});

View file

@ -263,8 +263,9 @@ if ( document.defaultView && document.defaultView.getComputedStyle ) {
if ( document.documentElement.currentStyle ) {
currentStyle = function( elem, name ) {
var left, rsLeft,
var left,
ret = elem.currentStyle && elem.currentStyle[ name ],
rsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ],
style = elem.style;
// From the awesome hack by Dean Edwards
@ -275,16 +276,19 @@ if ( document.documentElement.currentStyle ) {
if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
// Remember the original values
left = style.left;
rsLeft = elem.runtimeStyle.left;
// Put in the new values to get a computed value out
elem.runtimeStyle.left = elem.currentStyle.left;
if ( rsLeft ) {
elem.runtimeStyle.left = elem.currentStyle.left;
}
style.left = name === "fontSize" ? "1em" : (ret || 0);
ret = style.pixelLeft + "px";
// Revert the changed values
style.left = left;
elem.runtimeStyle.left = rsLeft;
if ( rsLeft ) {
elem.runtimeStyle.left = rsLeft;
}
}
return ret === "" ? "auto" : ret;

View file

@ -1,7 +1,6 @@
(function( jQuery ) {
var windowData = {},
rbrace = /^(?:\{.*\}|\[.*\])$/;
var rbrace = /^(?:\{.*\}|\[.*\])$/;
jQuery.extend({
cache: {},
@ -23,108 +22,168 @@ jQuery.extend({
},
hasData: function( elem ) {
if ( elem.nodeType ) {
elem = jQuery.cache[ elem[jQuery.expando] ];
}
elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
return !!elem && !jQuery.isEmptyObject(elem);
},
data: function( elem, name, data ) {
data: function( elem, name, data, pvt /* Internal Use Only */ ) {
if ( !jQuery.acceptData( elem ) ) {
return;
}
elem = elem == window ?
windowData :
elem;
var internalKey = jQuery.expando, getByName = typeof name === "string", thisCache,
var isNode = elem.nodeType,
id = isNode ? elem[ jQuery.expando ] : null,
cache = jQuery.cache, thisCache;
// We have to handle DOM nodes and JS objects differently because IE6-7
// can't GC object references properly across the DOM-JS boundary
isNode = elem.nodeType,
if ( isNode && !id && typeof name === "string" && data === undefined ) {
// Only DOM nodes need the global jQuery cache; JS object data is
// attached directly to the object so GC can occur automatically
cache = isNode ? jQuery.cache : elem,
// Only defining an ID for JS objects if its cache already exists allows
// the code to shortcut on the same path as a DOM node with no cache
id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando;
// Avoid doing any more work than we need to when trying to get data on an
// object that has no data at all
if ( (!id || (pvt && id && !cache[ id ][ internalKey ])) && getByName && data === undefined ) {
return;
}
// Get the data from the object directly
if ( !isNode ) {
cache = elem;
// Compute a unique ID for the element
} else if ( !id ) {
elem[ jQuery.expando ] = id = ++jQuery.uuid;
if ( !id ) {
// Only DOM nodes need a new unique ID for each element since their data
// ends up in the global cache
if ( isNode ) {
elem[ jQuery.expando ] = id = ++jQuery.uuid;
} else {
id = jQuery.expando;
}
}
// Avoid generating a new cache unless none exists and we
// want to manipulate it.
if ( typeof name === "object" ) {
if ( isNode ) {
cache[ id ] = jQuery.extend(cache[ id ], name);
} else {
jQuery.extend( cache, name );
}
} else if ( isNode && !cache[ id ] ) {
if ( !cache[ id ] ) {
cache[ id ] = {};
}
thisCache = isNode ? cache[ id ] : cache;
// An object can be passed to jQuery.data instead of a key/value pair; this gets
// shallow copied over onto the existing cache
if ( typeof name === "object" ) {
if ( pvt ) {
cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name);
} else {
cache[ id ] = jQuery.extend(cache[ id ], name);
}
}
thisCache = cache[ id ];
// Internal jQuery data is stored in a separate object inside the object's data
// cache in order to avoid key collisions between internal data and user-defined
// data
if ( pvt ) {
if ( !thisCache[ internalKey ] ) {
thisCache[ internalKey ] = {};
}
thisCache = thisCache[ internalKey ];
}
// Prevent overriding the named cache with undefined values
if ( data !== undefined ) {
thisCache[ name ] = data;
}
return typeof name === "string" ? thisCache[ name ] : thisCache;
// TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should
// not attempt to inspect the internal events object using jQuery.data, as this
// internal data object is undocumented and subject to change.
if ( name === "events" && !thisCache[name] ) {
return thisCache[ internalKey ] && thisCache[ internalKey ].events;
}
return getByName ? thisCache[ name ] : thisCache;
},
removeData: function( elem, name ) {
removeData: function( elem, name, pvt /* Internal Use Only */ ) {
if ( !jQuery.acceptData( elem ) ) {
return;
}
elem = elem == window ?
windowData :
elem;
var internalKey = jQuery.expando, isNode = elem.nodeType,
var isNode = elem.nodeType,
id = isNode ? elem[ jQuery.expando ] : elem,
cache = jQuery.cache,
thisCache = isNode ? cache[ id ] : id;
// See jQuery.data for more information
cache = isNode ? jQuery.cache : elem,
// See jQuery.data for more information
id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
// If there is already no cache entry for this object, there is no
// purpose in continuing
if ( !cache[ id ] ) {
return;
}
// If we want to remove a specific section of the element's data
if ( name ) {
var thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ];
if ( thisCache ) {
// Remove the section of cache data
delete thisCache[ name ];
// If we've removed all the data, remove the element's cache
if ( isNode && jQuery.isEmptyObject(thisCache) ) {
jQuery.removeData( elem );
}
}
// Otherwise, we want to remove all of the element's data
} else {
if ( isNode && jQuery.support.deleteExpando ) {
delete elem[ jQuery.expando ];
} else if ( elem.removeAttribute ) {
elem.removeAttribute( jQuery.expando );
// Completely remove the data cache
} else if ( isNode ) {
delete cache[ id ];
// Remove all fields from the object
} else {
for ( var n in elem ) {
delete elem[ n ];
// If there is no data left in the cache, we want to continue
// and let the cache object itself get destroyed
if ( !jQuery.isEmptyObject(thisCache) ) {
return;
}
}
}
// See jQuery.data for more information
if ( pvt ) {
delete cache[ id ][ internalKey ];
// Don't destroy the parent cache unless the internal data object
// had been the only thing left in it
if ( !jQuery.isEmptyObject(cache[ id ]) ) {
return;
}
}
var internalCache = cache[ id ][ internalKey ];
// Browsers that fail expando deletion also refuse to delete expandos on
// the window, but it will allow it on all other JS objects; other browsers
// don't care
if ( jQuery.support.deleteExpando || cache != window ) {
delete cache[ id ];
} else {
cache[ id ] = null;
}
// We destroyed the entire user cache at once because it's faster than
// iterating through each key, but we need to continue to persist internal
// data if it existed
if ( internalCache ) {
cache[ id ] = {};
cache[ id ][ internalKey ] = internalCache;
// Otherwise, we need to eliminate the expando on the node to avoid
// false lookups in the cache for entries that no longer exist
} else if ( isNode ) {
// IE does not allow us to delete expando properties from nodes,
// nor does it have a removeAttribute function on Document nodes;
// we must handle all of these cases
if ( jQuery.support.deleteExpando ) {
delete elem[ jQuery.expando ];
} else if ( elem.removeAttribute ) {
elem.removeAttribute( jQuery.expando );
} else {
elem[ jQuery.expando ] = null;
}
}
},
// For internal use only.
_data: function( elem, name, data ) {
return jQuery.data( elem, name, data, true );
},
// A method for determining if a DOM node can handle the data expando

10
src/effects.js vendored
View file

@ -27,7 +27,7 @@ jQuery.fn.extend({
// Reset the inline display of this element to learn if it is
// being hidden by cascaded rules or not
if ( !jQuery.data(elem, "olddisplay") && display === "none" ) {
if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {
display = elem.style.display = "";
}
@ -35,7 +35,7 @@ jQuery.fn.extend({
// in a stylesheet to whatever the default browser style is
// for such an element
if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
jQuery.data(elem, "olddisplay", defaultDisplay(elem.nodeName));
jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName));
}
}
@ -46,7 +46,7 @@ jQuery.fn.extend({
display = elem.style.display;
if ( display === "" || display === "none" ) {
elem.style.display = jQuery.data(elem, "olddisplay") || "";
elem.style.display = jQuery._data(elem, "olddisplay") || "";
}
}
@ -62,8 +62,8 @@ jQuery.fn.extend({
for ( var i = 0, j = this.length; i < j; i++ ) {
var display = jQuery.css( this[i], "display" );
if ( display !== "none" && !jQuery.data( this[i], "olddisplay" ) ) {
jQuery.data( this[i], "olddisplay", display );
if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) {
jQuery._data( this[i], "olddisplay", display );
}
}

View file

@ -8,7 +8,8 @@ var rnamespaces = /\.(.*)$/,
fcleanup = function( nm ) {
return nm.replace(rescape, "\\$&");
},
focusCounts = { focusin: 0, focusout: 0 };
focusCounts = { focusin: 0, focusout: 0 },
eventKey = "events";
/*
* A number of helper functions used for managing events.
@ -50,7 +51,7 @@ jQuery.event = {
}
// Init the element's event structure
var elemData = jQuery.data( elem );
var elemData = jQuery._data( elem );
// If no elemData is found then we must be trying to bind to one of the
// banned noData elements
@ -58,10 +59,7 @@ jQuery.event = {
return;
}
// Use a key less likely to result in collisions for plain JS objects.
// Fixes bug #7150.
var eventKey = elem.nodeType ? "events" : "__events__",
events = elemData[ eventKey ],
var events = elemData[ eventKey ],
eventHandle = elemData.handle;
if ( typeof events === "function" ) {
@ -177,8 +175,7 @@ jQuery.event = {
}
var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
eventKey = elem.nodeType ? "events" : "__events__",
elemData = jQuery.data( elem ),
elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
events = elemData && elemData[ eventKey ];
if ( !elemData || !events ) {
@ -290,10 +287,10 @@ jQuery.event = {
delete elemData.handle;
if ( typeof elemData === "function" ) {
jQuery.removeData( elem, eventKey );
jQuery.removeData( elem, eventKey, true );
} else if ( jQuery.isEmptyObject( elemData ) ) {
jQuery.removeData( elem );
jQuery.removeData( elem, undefined, true );
}
}
},
@ -325,9 +322,16 @@ jQuery.event = {
// Only trigger if we've ever bound an event for it
if ( jQuery.event.global[ type ] ) {
// XXX This code smells terrible. event.js should not be directly
// inspecting the data cache
jQuery.each( jQuery.cache, function() {
if ( this.events && this.events[type] ) {
jQuery.event.trigger( event, data, this.handle.elem );
// internalKey variable is just used to make it easier to find
// and potentially change this stuff later; currently it just
// points to jQuery.expando
var internalKey = jQuery.expando,
internalCache = this[ internalKey ];
if ( internalCache && internalCache.events && internalCache.events[type] ) {
jQuery.event.trigger( event, data, internalCache.handle.elem );
}
});
}
@ -353,8 +357,8 @@ jQuery.event = {
// Trigger the event, it is assumed that "handle" is a function
var handle = elem.nodeType ?
jQuery.data( elem, "handle" ) :
(jQuery.data( elem, "__events__" ) || {}).handle;
jQuery._data( elem, "handle" ) :
(jQuery._data( elem, eventKey ) || {}).handle;
if ( handle ) {
handle.apply( elem, data );
@ -432,7 +436,7 @@ jQuery.event = {
event.namespace = event.namespace || namespace_sort.join(".");
events = jQuery.data(this, this.nodeType ? "events" : "__events__");
events = jQuery._data(this, eventKey);
if ( typeof events === "function" ) {
events = events.events;
@ -603,7 +607,7 @@ jQuery.Event = function( src ) {
// Events bubbling up the document may have been marked as prevented
// by a handler lower down the tree; reflect the correct value.
this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false ||
this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false ||
src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;
// Event type
@ -787,12 +791,12 @@ if ( !jQuery.support.changeBubbles ) {
return;
}
data = jQuery.data( elem, "_change_data" );
data = jQuery._data( elem, "_change_data" );
val = getVal(elem);
// the current data will be also retrieved by beforeactivate
if ( e.type !== "focusout" || elem.type !== "radio" ) {
jQuery.data( elem, "_change_data", val );
jQuery._data( elem, "_change_data", val );
}
if ( data === undefined || val === data ) {
@ -837,7 +841,7 @@ if ( !jQuery.support.changeBubbles ) {
// information
beforeactivate: function( e ) {
var elem = e.target;
jQuery.data( elem, "_change_data", getVal(elem) );
jQuery._data( elem, "_change_data", getVal(elem) );
}
},
@ -986,8 +990,8 @@ jQuery.fn.extend({
return this.click( jQuery.proxy( fn, function( event ) {
// Figure out which function to execute
var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i;
jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 );
// Make sure that clicks stop
event.preventDefault();
@ -1075,7 +1079,7 @@ function liveHandler( event ) {
var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
elems = [],
selectors = [],
events = jQuery.data( this, this.nodeType ? "events" : "__events__" );
events = jQuery._data( this, eventKey );
if ( typeof events === "function" ) {
events = events.events;

View file

@ -346,7 +346,7 @@ jQuery.fn.extend({
table ?
root(this[i], first) :
this[i],
i > 0 || results.cacheable || this.length > 1 ?
i > 0 || results.cacheable || (this.length > 1 && i > 0) ?
jQuery(fragment).clone(true)[0] :
fragment
);
@ -381,17 +381,24 @@ function cloneCopyEvent(orig, ret) {
throw "Cloned data mismatch";
}
var oldData = jQuery.data( orig[nodeIndex] ),
curData = jQuery.data( this, oldData ),
events = oldData && oldData.events;
var internalKey = jQuery.expando,
oldData = jQuery.data( orig[nodeIndex] ),
curData = jQuery.data( this, oldData );
if ( events ) {
delete curData.handle;
curData.events = {};
// Switch to use the internal data object, if it exists, for the next
// stage of data copying
if ( (oldData = oldData[ internalKey ]) ) {
var events = oldData.events;
curData = curData[ internalKey ] = jQuery.extend({}, oldData);
for ( var type in events ) {
for ( var i = 0, l = events[ type ].length; i < l; i++ ) {
jQuery.event.add( this, type, events[ type ][ i ], events[ type ][ i ].data );
if ( events ) {
delete curData.handle;
curData.events = {};
for ( var type in events ) {
for ( var i = 0, l = events[ type ].length; i < l; i++ ) {
jQuery.event.add( this, type, events[ type ][ i ], events[ type ][ i ].data );
}
}
}
}
@ -420,15 +427,29 @@ function cloneFixAttributes(src, dest) {
if ( nodeName === "object" ) {
dest.outerHTML = src.outerHTML;
// IE6-8 fails to persist the checked state of a cloned checkbox
// or radio button
} else if ( nodeName === "input" && src.checked ) {
dest.defaultChecked = dest.checked = src.checked;
} else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {
// IE6-8 fails to persist the checked state of a cloned checkbox
// or radio button. Worse, IE6-7 fail to give the cloned element
// a checked appearance if the defaultChecked value isn't also set
if ( src.checked ) {
dest.defaultChecked = dest.checked = src.checked;
}
// IE6-7 get confused and end up setting the value of a cloned
// checkbox/radio button to an empty string instead of "on"
if ( dest.value !== src.value ) {
dest.value = src.value;
}
// IE6-8 fails to return the selected option to the default selected
// state when cloning options
} else if ( nodeName === "option" ) {
dest.selected = src.defaultSelected;
// IE6-8 fails to set the defaultValue to the correct value when
// cloning other types of input fields
} else if ( nodeName === "input" || nodeName === "textarea" ) {
dest.defaultValue = src.defaultValue;
}
// Event data gets referenced instead of copied if the expando
@ -594,8 +615,7 @@ jQuery.extend({
},
cleanData: function( elems ) {
var data, id, cache = jQuery.cache,
special = jQuery.event.special,
var data, id, cache = jQuery.cache, internalKey = jQuery.expando, special = jQuery.event.special,
deleteExpando = jQuery.support.deleteExpando;
for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
@ -606,13 +626,14 @@ jQuery.extend({
id = elem[ jQuery.expando ];
if ( id ) {
data = cache[ id ];
data = cache[ id ] && cache[ id ][ internalKey ];
if ( data && data.events ) {
for ( var type in data.events ) {
if ( special[ type ] ) {
jQuery.event.remove( elem, type );
// This is a shortcut to avoid jQuery.event.remove's overhead
} else {
jQuery.removeEvent( elem, type, data.handle );
}

View file

@ -7,7 +7,7 @@ jQuery.extend({
}
type = (type || "fx") + "queue";
var q = jQuery.data( elem, type );
var q = jQuery._data( elem, type );
// Speed up dequeue by getting out quickly if this is just a lookup
if ( !data ) {
@ -15,7 +15,7 @@ jQuery.extend({
}
if ( !q || jQuery.isArray(data) ) {
q = jQuery.data( elem, type, jQuery.makeArray(data) );
q = jQuery._data( elem, type, jQuery.makeArray(data) );
} else {
q.push( data );
@ -46,6 +46,10 @@ jQuery.extend({
jQuery.dequeue(elem, type);
});
}
if ( !queue.length ) {
jQuery.removeData( elem, type + "queue", true );
}
}
});

View file

@ -4,10 +4,7 @@
jQuery.support = {};
var root = document.documentElement,
script = document.createElement("script"),
div = document.createElement("div"),
id = "script" + jQuery.now();
var div = document.createElement("div");
div.style.display = "none";
div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
@ -64,7 +61,7 @@
deleteExpando: true,
optDisabled: false,
checkClone: false,
scriptEval: false,
_scriptEval: null,
noCloneEvent: true,
boxModel: null,
inlineBlockNeedsLayout: false,
@ -77,32 +74,45 @@
select.disabled = true;
jQuery.support.optDisabled = !opt.disabled;
script.type = "text/javascript";
try {
script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
} catch(e) {}
jQuery.support.scriptEval = function() {
if ( jQuery.support._scriptEval === null) {
var root = document.documentElement,
script = document.createElement("script"),
id = "script" + jQuery.now();
root.insertBefore( script, root.firstChild );
script.type = "text/javascript";
try {
script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
} catch(e) {}
// Make sure that the execution of code works by injecting a script
// tag with appendChild/createTextNode
// (IE doesn't support this, fails, and uses .text instead)
if ( window[ id ] ) {
jQuery.support.scriptEval = true;
delete window[ id ];
}
root.insertBefore( script, root.firstChild );
// Make sure that the execution of code works by injecting a script
// tag with appendChild/createTextNode
// (IE doesn't support this, fails, and uses .text instead)
if ( window[ id ] ) {
jQuery.support._scriptEval = true;
delete window[ id ];
} else {
jQuery.support._scriptEval = false;
}
root.removeChild( script );
// release memory in IE
root = script = id = null;
}
return jQuery.support._scriptEval;
};
// Test to see if it's possible to delete an expando from an element
// Fails in Internet Explorer
try {
delete script.test;
delete div.test;
} catch(e) {
jQuery.support.deleteExpando = false;
}
root.removeChild( script );
if ( div.attachEvent && div.fireEvent ) {
div.attachEvent("onclick", function click() {
// Cloning a node shouldn't copy over any
@ -191,6 +201,6 @@
jQuery.support.changeBubbles = eventSupported("change");
// release memory in IE
root = script = div = all = a = null;
div = all = a = null;
})();
})( jQuery );

View file

@ -6,7 +6,14 @@ var runtil = /Until$/,
rmultiselector = /,/,
isSimple = /^.[^:#\[\.,]*$/,
slice = Array.prototype.slice,
POS = jQuery.expr.match.POS;
POS = jQuery.expr.match.POS,
// methods guaranteed to produce a unique set when starting from a unique set
guaranteedUnique = {
children: true,
contents: true,
next: true,
prev: true
};
jQuery.fn.extend({
find: function( selector ) {
@ -196,7 +203,8 @@ jQuery.each({
}
}, function( name, fn ) {
jQuery.fn[ name ] = function( until, selector ) {
var ret = jQuery.map( this, fn, until );
var ret = jQuery.map( this, fn, until ),
args = slice.call(arguments);
if ( !runtil.test( name ) ) {
selector = until;
@ -206,13 +214,13 @@ jQuery.each({
ret = jQuery.filter( selector, ret );
}
ret = this.length > 1 ? jQuery.unique( ret ) : ret;
ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
ret = ret.reverse();
}
return this.pushStack( ret, name, slice.call(arguments).join(",") );
return this.pushStack( ret, name, args.join(",") );
};
});