Merge branch 'master' into proxy-native-bind
* master: (194 commits) Revert "Make sure that focusin/focusout bubbles in non-IE browsers." This was causing problems with the focusin event, see: #7340. Replaces "text in-between" technique with a full-fledged one-level transitive search for converters (unit tests added). Also cleans up auto dataType determination and adds converter checks in order to guess the best dataType possible. Moves determineResponse logic into main ajax callback. Puts responseXXX fields definitions into ajaxSettings. Removes misleading comment. Bring jQuery('#id') and jQuery('body') logic back into core (while leaving it in Sizzle at the same time). Was causing too much of a performance hit to leave it all to Sizzle. Renames Deferred's fire and fireReject methods as resolveWith and rejectWith respectively. Fix typo in regex tweak from previous commit. Renames determineDataType as determineResponse. Makes it more generic as a first step into integrating the logic into the main ajax done callback. Also fixes some comments in ajax/xhr.js. Move jQuery(...) selector speed-up logic into Sizzle(...) qSA handling. Additionally add in a new catch for Sizzle('.class') (avoid using qSA and use getElementsByClassName instead, where applicable). Revises the way arguments are handled in ajax. Makes sure statusCode callbacks are ordered in the same way success and error callbacks are. Unit tests added. Cleans up and simplifies code shared by ajaxPrefilter and ajaxTransport. Removes chainability of ajaxSetup, ajaxPrefilter and ajaxTransport. Also makes sure context is handled properly by ajaxSetup (unit test added). Rework unit tests to check actual result elements. Moves active counter test after all other ajax tests where it should be. Revised the Nokia support fallback. It turns out that Nokia supports the documentElement property but does not define document.compatMode. Adding this third fallback allows Nokia to run jQuery error-free and return proper values for window width and height. Moves things around to make jsLint happier. Fixes crossDomain test so that it assumes port to be 80 for http and 443 for https when it is not provided. Moves determineDataType into ajaxSettings so that it is accessible to transports without the need for a second argument and so that we can now pass the original options to the transport instead. Also ensures the original options are actually propagated to prefilters (they were not). Re-adds hastily removed variable and simplifies statusCode based callbacks handling. Use undefined instead of 0 to deference transport for clarity. ... Conflicts: src/event.js
This commit is contained in:
commit
a03f040dbf
56 changed files with 6696 additions and 3009 deletions
865
src/ajax.js
865
src/ajax.js
File diff suppressed because it is too large
Load diff
87
src/ajax/jsonp.js
Normal file
87
src/ajax/jsonp.js
Normal file
|
@ -0,0 +1,87 @@
|
|||
(function( jQuery ) {
|
||||
|
||||
var jsc = jQuery.now(),
|
||||
jsre = /(\=)(?:\?|%3F)(&|$)|()(?:\?\?|%3F%3F)()/i;
|
||||
|
||||
// Default jsonp settings
|
||||
jQuery.ajaxSetup({
|
||||
jsonp: "callback",
|
||||
jsonpCallback: function() {
|
||||
return "jsonp" + jsc++;
|
||||
}
|
||||
});
|
||||
|
||||
// Detect, normalize options and install callbacks for jsonp requests
|
||||
// (dataIsString is used internally)
|
||||
jQuery.ajaxPrefilter("json jsonp", function(s, originalSettings, dataIsString) {
|
||||
|
||||
dataIsString = ( typeof(s.data) === "string" );
|
||||
|
||||
if ( s.dataTypes[ 0 ] === "jsonp" ||
|
||||
originalSettings.jsonpCallback ||
|
||||
originalSettings.jsonp != null ||
|
||||
s.jsonp !== false && ( jsre.test( s.url ) ||
|
||||
dataIsString && jsre.test( s.data ) ) ) {
|
||||
|
||||
var responseContainer,
|
||||
jsonpCallback = s.jsonpCallback =
|
||||
jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
|
||||
previous = window[ jsonpCallback ],
|
||||
url = s.url,
|
||||
data = s.data,
|
||||
replace = "$1" + jsonpCallback + "$2";
|
||||
|
||||
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;
|
||||
|
||||
window [ jsonpCallback ] = function( response ) {
|
||||
responseContainer = [response];
|
||||
};
|
||||
|
||||
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] );
|
||||
}
|
||||
} else {
|
||||
// else, more memory leak avoidance
|
||||
try{ delete window[ jsonpCallback ]; } catch(e){}
|
||||
}
|
||||
|
||||
}, s.complete ];
|
||||
|
||||
// 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
|
||||
return "script";
|
||||
}
|
||||
});
|
||||
|
||||
})( jQuery );
|
|
@ -1,39 +1,45 @@
|
|||
(function( jQuery ) {
|
||||
|
||||
// Install text to script executor
|
||||
jQuery.extend( true, jQuery.ajaxSettings , {
|
||||
// Install script dataType
|
||||
jQuery.ajaxSetup({
|
||||
|
||||
accepts: {
|
||||
script: "text/javascript, application/javascript"
|
||||
},
|
||||
|
||||
autoDataType: {
|
||||
|
||||
contents: {
|
||||
script: /javascript/
|
||||
},
|
||||
|
||||
dataConverters: {
|
||||
"text => script": jQuery.globalEval
|
||||
}
|
||||
} );
|
||||
|
||||
// Bind script tag hack transport
|
||||
jQuery.xhr.bindTransport("script", function(s) {
|
||||
|
||||
// Handle cache special case
|
||||
converters: {
|
||||
"text script": jQuery.globalEval
|
||||
}
|
||||
});
|
||||
|
||||
// Handle cache's special case and global
|
||||
jQuery.ajaxPrefilter("script", function(s) {
|
||||
|
||||
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
|
||||
jQuery.ajaxTransport("script", function(s) {
|
||||
|
||||
// This transport only deals with cross domain requests
|
||||
if ( s.crossDomain ) {
|
||||
|
||||
var script,
|
||||
head = document.getElementsByTagName("head")[0] || document.documentElement;
|
||||
|
||||
|
||||
return {
|
||||
|
||||
|
||||
send: function(_, callback) {
|
||||
|
||||
script = document.createElement("script");
|
||||
|
@ -43,37 +49,39 @@ jQuery.xhr.bindTransport("script", function(s) {
|
|||
if ( s.scriptCharset ) {
|
||||
script.charset = s.scriptCharset;
|
||||
}
|
||||
|
||||
|
||||
script.src = s.url;
|
||||
|
||||
|
||||
// Attach handlers for all browsers
|
||||
script.onload = script.onreadystatechange = function(statusText) {
|
||||
|
||||
if ( (!script.readyState ||
|
||||
script.readyState === "loaded" || script.readyState === "complete") ) {
|
||||
|
||||
script.onload = script.onreadystatechange = function( _ , isAbort ) {
|
||||
|
||||
if ( ! script.readyState || /loaded|complete/.test( script.readyState ) ) {
|
||||
|
||||
// Handle memory leak in IE
|
||||
script.onload = script.onreadystatechange = null;
|
||||
|
||||
|
||||
// Remove the script
|
||||
if ( head && script.parentNode ) {
|
||||
head.removeChild( script );
|
||||
}
|
||||
|
||||
script = undefined;
|
||||
|
||||
// Callback & dereference
|
||||
callback(statusText ? 0 : 200, statusText || "success");
|
||||
|
||||
// Dereference the script
|
||||
script = 0;
|
||||
|
||||
// Callback if not abort
|
||||
if ( ! isAbort ) {
|
||||
callback( 200, "success" );
|
||||
}
|
||||
}
|
||||
};
|
||||
// Use insertBefore instead of appendChild to circumvent an IE6 bug.
|
||||
// This arises when a base node is used (#2709 and #4378).
|
||||
head.insertBefore( script, head.firstChild );
|
||||
},
|
||||
|
||||
abort: function(statusText) {
|
||||
|
||||
abort: function() {
|
||||
if ( script ) {
|
||||
script.onload(statusText);
|
||||
script.onload(0,1);
|
||||
}
|
||||
}
|
||||
};
|
225
src/ajax/xhr.js
Normal file
225
src/ajax/xhr.js
Normal file
|
@ -0,0 +1,225 @@
|
|||
(function( jQuery ) {
|
||||
|
||||
var // Next active xhr id
|
||||
xhrId = jQuery.now(),
|
||||
|
||||
// active xhrs
|
||||
xhrs = {},
|
||||
|
||||
// #5280: see below
|
||||
xhrUnloadAbortInstalled,
|
||||
|
||||
// XHR used to determine supports properties
|
||||
testXHR;
|
||||
|
||||
// Create the request object
|
||||
// (This is still attached to ajaxSettings for backward compatibility)
|
||||
jQuery.ajaxSettings.xhr = window.ActiveXObject ?
|
||||
/* Microsoft failed to properly
|
||||
* implement the XMLHttpRequest in IE7 (can't request local files),
|
||||
* so we use the ActiveXObject when it is available
|
||||
* Additionally XMLHttpRequest can be disabled in IE7/IE8 so
|
||||
* we need a fallback.
|
||||
*/
|
||||
function() {
|
||||
if ( window.location.protocol !== "file:" ) {
|
||||
try {
|
||||
return new window.XMLHttpRequest();
|
||||
} catch( xhrError ) {}
|
||||
}
|
||||
|
||||
try {
|
||||
return new window.ActiveXObject("Microsoft.XMLHTTP");
|
||||
} catch( activeError ) {}
|
||||
} :
|
||||
// For all other browsers, use the standard XMLHttpRequest object
|
||||
function() {
|
||||
return new window.XMLHttpRequest();
|
||||
};
|
||||
|
||||
// Test if we can create an xhr object
|
||||
try {
|
||||
testXHR = jQuery.ajaxSettings.xhr();
|
||||
} catch( xhrCreationException ) {}
|
||||
|
||||
//Does this browser support XHR requests?
|
||||
jQuery.support.ajax = !!testXHR;
|
||||
|
||||
// Does this browser support crossDomain XHR requests
|
||||
jQuery.support.cors = testXHR && "withCredentials" in testXHR;
|
||||
|
||||
// No need for the temporary xhr anymore
|
||||
testXHR = undefined;
|
||||
|
||||
// Create transport if the browser can provide an xhr
|
||||
if ( jQuery.support.ajax ) {
|
||||
jQuery.ajaxTransport( function( s ) {
|
||||
|
||||
// Cross domain only allowed if supported through XMLHttpRequest
|
||||
if ( ! s.crossDomain || jQuery.support.cors ) {
|
||||
|
||||
var callback;
|
||||
|
||||
return {
|
||||
|
||||
send: function(headers, complete) {
|
||||
|
||||
// #5280: we need to abort on unload or IE will keep connections alive
|
||||
if ( ! xhrUnloadAbortInstalled ) {
|
||||
|
||||
xhrUnloadAbortInstalled = 1;
|
||||
|
||||
jQuery(window).bind( "unload" , function() {
|
||||
|
||||
// Abort all pending requests
|
||||
jQuery.each(xhrs, function(_, xhr) {
|
||||
if ( xhr.onreadystatechange ) {
|
||||
xhr.onreadystatechange( 1 );
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
// Get a new xhr
|
||||
var xhr = s.xhr(),
|
||||
handle;
|
||||
|
||||
// Open the socket
|
||||
// Passing null username, generates a login popup on Opera (#2865)
|
||||
if ( s.username ) {
|
||||
xhr.open(s.type, s.url, s.async, s.username, s.password);
|
||||
} else {
|
||||
xhr.open(s.type, s.url, s.async);
|
||||
}
|
||||
|
||||
// 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
|
||||
if ( ! ( s.crossDomain && ! s.hasContent ) && ! headers["x-requested-with"] ) {
|
||||
headers["x-requested-with"] = "XMLHttpRequest";
|
||||
}
|
||||
|
||||
// Need an extra try/catch for cross domain requests in Firefox 3
|
||||
try {
|
||||
|
||||
jQuery.each(headers, function(key,value) {
|
||||
xhr.setRequestHeader(key,value);
|
||||
});
|
||||
|
||||
} catch(_) {}
|
||||
|
||||
// Do send the request
|
||||
try {
|
||||
xhr.send( ( s.hasContent && s.data ) || null );
|
||||
} catch(e) {
|
||||
complete(0, "error", "" + e);
|
||||
return;
|
||||
}
|
||||
|
||||
// Listener
|
||||
callback = function( _ , isAbort ) {
|
||||
|
||||
// Was never called and is aborted or complete
|
||||
if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
|
||||
|
||||
// Only called once
|
||||
callback = 0;
|
||||
|
||||
// Do not keep as active anymore
|
||||
if (handle) {
|
||||
xhr.onreadystatechange = jQuery.noop;
|
||||
delete xhrs[ handle ];
|
||||
}
|
||||
|
||||
// If it's an abort
|
||||
if ( isAbort ) {
|
||||
|
||||
// Abort it manually if needed
|
||||
if ( xhr.readyState !== 4 ) {
|
||||
xhr.abort();
|
||||
}
|
||||
} else {
|
||||
|
||||
// Get info
|
||||
var status = xhr.status,
|
||||
statusText,
|
||||
responseHeaders = xhr.getAllResponseHeaders(),
|
||||
responses = {},
|
||||
xml = xhr.responseXML;
|
||||
|
||||
// Construct response list
|
||||
if ( xml && xml.documentElement /* #4958 */ ) {
|
||||
responses.xml = xml;
|
||||
}
|
||||
responses.text = xhr.responseText;
|
||||
|
||||
try { // Firefox throws an exception when accessing statusText for faulty cross-domain requests
|
||||
|
||||
statusText = xhr.statusText;
|
||||
|
||||
} catch( e ) {
|
||||
|
||||
statusText = ""; // We normalize with Webkit giving an empty statusText
|
||||
|
||||
}
|
||||
|
||||
// Filter status for non standard behaviours
|
||||
// (so many they seem to be the actual "standard")
|
||||
status =
|
||||
// Opera returns 0 when it should be 304
|
||||
// Webkit returns 0 for failing cross-domain no matter the real status
|
||||
status === 0 ?
|
||||
(
|
||||
! s.crossDomain || statusText ? // Webkit, Firefox: filter out faulty cross-domain requests
|
||||
(
|
||||
responseHeaders ? // Opera: filter out real aborts #6060
|
||||
304
|
||||
:
|
||||
0
|
||||
)
|
||||
:
|
||||
302 // We assume 302 but could be anything cross-domain related
|
||||
)
|
||||
:
|
||||
(
|
||||
status == 1223 ? // IE sometimes returns 1223 when it should be 204 (see #1450)
|
||||
204
|
||||
:
|
||||
status
|
||||
);
|
||||
|
||||
// Call complete
|
||||
complete(status,statusText,responses,responseHeaders);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// if we're in sync mode
|
||||
// or it's in cache and has been retrieved directly (IE6 & IE7)
|
||||
// we need to manually fire the callback
|
||||
if ( ! s.async || xhr.readyState === 4 ) {
|
||||
|
||||
callback();
|
||||
|
||||
} else {
|
||||
|
||||
// Add to list of active xhrs
|
||||
handle = xhrId++;
|
||||
xhrs[ handle ] = xhr;
|
||||
xhr.onreadystatechange = callback;
|
||||
}
|
||||
},
|
||||
|
||||
abort: function() {
|
||||
if ( callback ) {
|
||||
callback(0,1);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
})( jQuery );
|
|
@ -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__" ) || "";
|
||||
}
|
||||
});
|
||||
},
|
||||
|
@ -182,7 +182,7 @@ jQuery.fn.extend({
|
|||
var option = options[ i ];
|
||||
|
||||
// Don't return options that are disabled or in a disabled optgroup
|
||||
if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
|
||||
if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
|
||||
(!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
|
||||
|
||||
// Get the specific value for the option
|
||||
|
|
345
src/core.js
345
src/core.js
|
@ -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
|
||||
|
@ -19,12 +19,8 @@ var jQuery = function( selector, context ) {
|
|||
// (both of which we optimize for)
|
||||
quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/,
|
||||
|
||||
// Is it a simple selector
|
||||
isSimple = /^.[^:#\[\.,]*$/,
|
||||
|
||||
// Check if a string has a non-whitespace character in it
|
||||
rnotwhite = /\S/,
|
||||
rwhite = /\s/,
|
||||
|
||||
// Used for trimming whitespace
|
||||
trimLeft = /^\s+/,
|
||||
|
@ -56,12 +52,15 @@ var jQuery = function( selector, context ) {
|
|||
|
||||
// For matching the engine and version of the browser
|
||||
browserMatch,
|
||||
|
||||
|
||||
// Has the ready events already been bound?
|
||||
readyBound = false,
|
||||
|
||||
// The functions to execute on DOM ready
|
||||
readyList = [],
|
||||
|
||||
// The deferred used on DOM ready
|
||||
readyList,
|
||||
|
||||
// Promise methods
|
||||
promiseMethods = "then done fail isResolved isRejected promise".split( " " ),
|
||||
|
||||
// The ready event handler
|
||||
DOMContentLoaded,
|
||||
|
@ -73,12 +72,13 @@ var jQuery = function( selector, context ) {
|
|||
slice = Array.prototype.slice,
|
||||
trim = String.prototype.trim,
|
||||
indexOf = Array.prototype.indexOf,
|
||||
|
||||
|
||||
// [[Class]] -> type pairs
|
||||
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)
|
||||
|
@ -92,7 +92,7 @@ jQuery.fn = jQuery.prototype = {
|
|||
this.length = 1;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
// The body element only exists once, optimize finding it
|
||||
if ( selector === "body" && !context && document.body ) {
|
||||
this.context = document;
|
||||
|
@ -112,6 +112,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,9 +130,9 @@ 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 );
|
||||
|
||||
// HANDLE: $("#id")
|
||||
|
@ -157,13 +158,6 @@ jQuery.fn = jQuery.prototype = {
|
|||
return this;
|
||||
}
|
||||
|
||||
// HANDLE: $("TAG")
|
||||
} else if ( !context && !rnonword.test( selector ) ) {
|
||||
this.selector = selector;
|
||||
this.context = document;
|
||||
selector = document.getElementsByTagName( selector );
|
||||
return jQuery.merge( this, selector );
|
||||
|
||||
// HANDLE: $(expr, $(...))
|
||||
} else if ( !context || context.jquery ) {
|
||||
return (context || rootjQuery).find( selector );
|
||||
|
@ -171,7 +165,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,11 +216,11 @@ 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 );
|
||||
|
||||
|
||||
} else {
|
||||
jQuery.merge( ret, elems );
|
||||
}
|
||||
|
@ -252,25 +246,15 @@ jQuery.fn = jQuery.prototype = {
|
|||
each: function( callback, args ) {
|
||||
return jQuery.each( this, callback, args );
|
||||
},
|
||||
|
||||
ready: function( fn ) {
|
||||
|
||||
ready: function() {
|
||||
// Attach the listeners
|
||||
jQuery.bindReady();
|
||||
|
||||
// If the DOM is already ready
|
||||
if ( jQuery.isReady ) {
|
||||
// Execute the function immediately
|
||||
fn.call( document, jQuery );
|
||||
|
||||
// Otherwise, remember the function for later
|
||||
} else if ( readyList ) {
|
||||
// Add the function to the wait list
|
||||
readyList.push( fn );
|
||||
}
|
||||
|
||||
return this;
|
||||
// Change ready & apply
|
||||
return ( jQuery.fn.ready = readyList.done ).apply( this , arguments );
|
||||
},
|
||||
|
||||
|
||||
eq: function( i ) {
|
||||
return i === -1 ?
|
||||
this.slice( i ) :
|
||||
|
@ -295,9 +279,9 @@ jQuery.fn = jQuery.prototype = {
|
|||
return callback.call( elem, i, elem );
|
||||
}));
|
||||
},
|
||||
|
||||
|
||||
end: function() {
|
||||
return this.prevObject || jQuery(null);
|
||||
return this.prevObject || this.constructor(null);
|
||||
},
|
||||
|
||||
// For internal use only.
|
||||
|
@ -384,14 +368,14 @@ jQuery.extend({
|
|||
|
||||
return jQuery;
|
||||
},
|
||||
|
||||
|
||||
// Is the DOM ready to be used? Set to true once it occurs.
|
||||
isReady: false,
|
||||
|
||||
// A counter to track how many items to wait for before
|
||||
// the ready event fires. See #6781
|
||||
readyWait: 1,
|
||||
|
||||
|
||||
// Handle when the DOM is ready
|
||||
ready: function( wait ) {
|
||||
// A third-party is pushing the ready event forwards
|
||||
|
@ -415,27 +399,15 @@ jQuery.extend({
|
|||
}
|
||||
|
||||
// If there are functions bound, to execute
|
||||
if ( readyList ) {
|
||||
// Execute all of them
|
||||
var fn,
|
||||
i = 0,
|
||||
ready = readyList;
|
||||
readyList.resolveWith( document , [ jQuery ] );
|
||||
|
||||
// Reset the list of functions
|
||||
readyList = null;
|
||||
|
||||
while ( (fn = ready[ i++ ]) ) {
|
||||
fn.call( document, jQuery );
|
||||
}
|
||||
|
||||
// Trigger any bound ready events
|
||||
if ( jQuery.fn.trigger ) {
|
||||
jQuery( document ).trigger( "ready" ).unbind( "ready" );
|
||||
}
|
||||
// Trigger any bound ready events
|
||||
if ( jQuery.fn.trigger ) {
|
||||
jQuery( document ).trigger( "ready" ).unbind( "ready" );
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
bindReady: function() {
|
||||
if ( readyBound ) {
|
||||
return;
|
||||
|
@ -454,7 +426,7 @@ jQuery.extend({
|
|||
if ( document.addEventListener ) {
|
||||
// Use the handy event callback
|
||||
document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
|
||||
|
||||
|
||||
// A fallback to window.onload, that will always work
|
||||
window.addEventListener( "load", jQuery.ready, false );
|
||||
|
||||
|
@ -463,7 +435,7 @@ jQuery.extend({
|
|||
// ensure firing before onload,
|
||||
// maybe late but safe also for iframes
|
||||
document.attachEvent("onreadystatechange", DOMContentLoaded);
|
||||
|
||||
|
||||
// A fallback to window.onload, that will always work
|
||||
window.attachEvent( "onload", jQuery.ready );
|
||||
|
||||
|
@ -514,20 +486,20 @@ jQuery.extend({
|
|||
if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Not own constructor property must be Object
|
||||
if ( obj.constructor &&
|
||||
!hasOwn.call(obj, "constructor") &&
|
||||
!hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Own properties are enumerated firstly, so to speed up,
|
||||
// if last one is own, then all properties are own.
|
||||
|
||||
|
||||
var key;
|
||||
for ( key in obj ) {}
|
||||
|
||||
|
||||
return key === undefined || hasOwn.call( obj, key );
|
||||
},
|
||||
|
||||
|
@ -537,11 +509,11 @@ jQuery.extend({
|
|||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
|
||||
error: function( msg ) {
|
||||
throw msg;
|
||||
},
|
||||
|
||||
|
||||
parseJSON: function( data ) {
|
||||
if ( typeof data !== "string" || !data ) {
|
||||
return null;
|
||||
|
@ -549,7 +521,7 @@ jQuery.extend({
|
|||
|
||||
// Make sure leading/trailing whitespace is removed (IE can't handle it)
|
||||
data = jQuery.trim( data );
|
||||
|
||||
|
||||
// Make sure the incoming data is actual JSON
|
||||
// Logic borrowed from http://json.org/json2.js
|
||||
if ( rvalidchars.test(data.replace(rvalidescape, "@")
|
||||
|
@ -566,6 +538,28 @@ jQuery.extend({
|
|||
}
|
||||
},
|
||||
|
||||
// Cross-browser xml parsing
|
||||
// (xml & tmp used internally)
|
||||
parseXML: function( data , xml , tmp ) {
|
||||
|
||||
if ( window.DOMParser ) { // Standard
|
||||
tmp = new DOMParser();
|
||||
xml = tmp.parseFromString( data , "text/xml" );
|
||||
} else { // IE
|
||||
xml = new ActiveXObject( "Microsoft.XMLDOM" );
|
||||
xml.async = "false";
|
||||
xml.loadXML( data );
|
||||
}
|
||||
|
||||
tmp = xml.documentElement;
|
||||
|
||||
if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) {
|
||||
jQuery.error( "Invalid XML: " + data );
|
||||
}
|
||||
|
||||
return xml;
|
||||
},
|
||||
|
||||
noop: function() {},
|
||||
|
||||
// Evalulates a script in a global context
|
||||
|
@ -578,7 +572,7 @@ jQuery.extend({
|
|||
|
||||
script.type = "text/javascript";
|
||||
|
||||
if ( jQuery.support.scriptEval ) {
|
||||
if ( jQuery.support.scriptEval() ) {
|
||||
script.appendChild( document.createTextNode( data ) );
|
||||
} else {
|
||||
script.text = data;
|
||||
|
@ -691,7 +685,7 @@ jQuery.extend({
|
|||
for ( var l = second.length; j < l; j++ ) {
|
||||
first[ i++ ] = second[ j ];
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
while ( second[j] !== undefined ) {
|
||||
first[ i++ ] = second[ j++ ];
|
||||
|
@ -787,7 +781,7 @@ jQuery.extend({
|
|||
// The value/s can be optionally by executed if its a function
|
||||
access: function( elems, key, value, exec, fn, pass ) {
|
||||
var length = elems.length;
|
||||
|
||||
|
||||
// Setting many attributes
|
||||
if ( typeof key === "object" ) {
|
||||
for ( var k in key ) {
|
||||
|
@ -795,19 +789,19 @@ jQuery.extend({
|
|||
}
|
||||
return elems;
|
||||
}
|
||||
|
||||
|
||||
// Setting one attribute
|
||||
if ( value !== undefined ) {
|
||||
// Optionally, function values get executed if exec is true
|
||||
exec = !pass && exec && jQuery.isFunction(value);
|
||||
|
||||
|
||||
for ( var i = 0; i < length; i++ ) {
|
||||
fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
|
||||
}
|
||||
|
||||
|
||||
return elems;
|
||||
}
|
||||
|
||||
|
||||
// Getting an attribute
|
||||
return length ? fn( elems[0], key ) : undefined;
|
||||
},
|
||||
|
@ -816,6 +810,178 @@ jQuery.extend({
|
|||
return (new Date()).getTime();
|
||||
},
|
||||
|
||||
// Create a simple deferred (one callbacks list)
|
||||
_Deferred: function() {
|
||||
|
||||
var // callbacks list
|
||||
callbacks = [],
|
||||
// stored [ context , args ]
|
||||
fired,
|
||||
// to avoid firing when already doing so
|
||||
firing,
|
||||
// flag to know if the deferred has been cancelled
|
||||
cancelled,
|
||||
// the deferred itself
|
||||
deferred = {
|
||||
|
||||
// done( f1, f2, ...)
|
||||
done: function () {
|
||||
|
||||
if ( ! cancelled ) {
|
||||
|
||||
var args = arguments,
|
||||
i,
|
||||
length,
|
||||
elem,
|
||||
type,
|
||||
_fired;
|
||||
|
||||
if ( fired ) {
|
||||
_fired = fired;
|
||||
fired = 0;
|
||||
}
|
||||
|
||||
for ( i = 0, length = args.length ; i < length ; i++ ) {
|
||||
elem = args[ i ];
|
||||
type = jQuery.type( elem );
|
||||
if ( type === "array" ) {
|
||||
deferred.done.apply( deferred , elem );
|
||||
} else if ( type === "function" ) {
|
||||
callbacks.push( elem );
|
||||
}
|
||||
}
|
||||
|
||||
if ( _fired ) {
|
||||
deferred.resolveWith( _fired[ 0 ] , _fired[ 1 ] );
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
// resolve with given context and args
|
||||
resolveWith: function( context , args ) {
|
||||
if ( ! cancelled && ! fired && ! firing ) {
|
||||
|
||||
firing = 1;
|
||||
|
||||
try {
|
||||
while( callbacks[ 0 ] ) {
|
||||
callbacks.shift().apply( context , args );
|
||||
}
|
||||
}
|
||||
finally {
|
||||
fired = [ context , args ];
|
||||
firing = 0;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
// resolve with this as context and given arguments
|
||||
resolve: function() {
|
||||
deferred.resolveWith( jQuery.isFunction( this.promise ) ? this.promise() : this , arguments );
|
||||
return this;
|
||||
},
|
||||
|
||||
// Has this deferred been resolved?
|
||||
isResolved: function() {
|
||||
return !!( firing || fired );
|
||||
},
|
||||
|
||||
// Cancel
|
||||
cancel: function() {
|
||||
cancelled = 1;
|
||||
callbacks = [];
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
return deferred;
|
||||
},
|
||||
|
||||
// Full fledged deferred (two callbacks list)
|
||||
// Typical success/error system
|
||||
Deferred: function( func ) {
|
||||
|
||||
var deferred = jQuery._Deferred(),
|
||||
failDeferred = jQuery._Deferred(),
|
||||
promise;
|
||||
|
||||
// Add errorDeferred methods, then and promise
|
||||
jQuery.extend( deferred , {
|
||||
|
||||
then: function( doneCallbacks , failCallbacks ) {
|
||||
deferred.done( doneCallbacks ).fail( failCallbacks );
|
||||
return this;
|
||||
},
|
||||
fail: failDeferred.done,
|
||||
rejectWith: failDeferred.resolveWith,
|
||||
reject: failDeferred.resolve,
|
||||
isRejected: failDeferred.isResolved,
|
||||
// Get a promise for this deferred
|
||||
// If obj is provided, the promise aspect is added to the object
|
||||
// (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;
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
// Make sure only one callback list will be used
|
||||
deferred.then( failDeferred.cancel , deferred.cancel );
|
||||
|
||||
// Unexpose cancel
|
||||
delete deferred.cancel;
|
||||
|
||||
// Call given func if any
|
||||
if ( func ) {
|
||||
func.call( deferred , deferred );
|
||||
}
|
||||
|
||||
return deferred;
|
||||
},
|
||||
|
||||
// Deferred helper
|
||||
when: function( object ) {
|
||||
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.resolveWith( promise, resolveArray );
|
||||
}
|
||||
}).fail( function() {
|
||||
deferred.rejectWith( promise, arguments );
|
||||
});
|
||||
return !deferred.isRejected();
|
||||
});
|
||||
} else if ( deferred !== object ) {
|
||||
deferred.resolve( object );
|
||||
}
|
||||
return promise;
|
||||
},
|
||||
|
||||
// Use of jQuery.browser is frowned upon.
|
||||
// More details: http://docs.jquery.com/Utilities/jQuery.browser
|
||||
uaMatch: function( ua ) {
|
||||
|
@ -830,9 +996,31 @@ 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: {}
|
||||
});
|
||||
|
||||
// Create readyList deferred
|
||||
readyList = jQuery._Deferred();
|
||||
|
||||
// Populate the class2type map
|
||||
jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
|
||||
class2type[ "[object " + name + "]" ] = name.toLowerCase();
|
||||
|
@ -855,9 +1043,8 @@ if ( indexOf ) {
|
|||
};
|
||||
}
|
||||
|
||||
// Verify that \s matches non-breaking spaces
|
||||
// (IE fails on this test)
|
||||
if ( !rwhite.test( "\xA0" ) ) {
|
||||
// IE doesn't match non-breaking spaces with \s
|
||||
if ( rnotwhite.test( "\xA0" ) ) {
|
||||
trimLeft = /^[\s\xA0]+/;
|
||||
trimRight = /[\s\xA0]+$/;
|
||||
}
|
||||
|
|
12
src/css.js
12
src/css.js
|
@ -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;
|
||||
|
|
200
src/data.js
200
src/data.js
|
@ -1,7 +1,6 @@
|
|||
(function( jQuery ) {
|
||||
|
||||
var windowData = {},
|
||||
rbrace = /^(?:\{.*\}|\[.*\])$/;
|
||||
var rbrace = /^(?:\{.*\}|\[.*\])$/;
|
||||
|
||||
jQuery.extend({
|
||||
cache: {},
|
||||
|
@ -9,8 +8,9 @@ jQuery.extend({
|
|||
// Please use with caution
|
||||
uuid: 0,
|
||||
|
||||
// Unique for each copy of jQuery on the page
|
||||
expando: "jQuery" + jQuery.now(),
|
||||
// Unique for each copy of jQuery on the page
|
||||
// Non-digits removed to match rinlinejQuery
|
||||
expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
|
||||
|
||||
// The following elements throw uncatchable exceptions if you
|
||||
// attempt to add expando properties to them.
|
||||
|
@ -21,101 +21,169 @@ jQuery.extend({
|
|||
"applet": true
|
||||
},
|
||||
|
||||
data: function( elem, name, data ) {
|
||||
hasData: function( elem ) {
|
||||
elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
|
||||
|
||||
return !!elem && !jQuery.isEmptyObject(elem);
|
||||
},
|
||||
|
||||
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
|
||||
|
@ -144,7 +212,7 @@ jQuery.fn.extend({
|
|||
var attr = this[0].attributes, name;
|
||||
for ( var i = 0, l = attr.length; i < l; i++ ) {
|
||||
name = attr[i].name;
|
||||
|
||||
|
||||
if ( name.indexOf( "data-" ) === 0 ) {
|
||||
name = name.substr( 5 );
|
||||
dataAttr( this[0], name, data[ name ] );
|
||||
|
|
|
@ -25,7 +25,7 @@ jQuery.each([ "Height", "Width" ], function( i, name ) {
|
|||
if ( !elem ) {
|
||||
return size == null ? null : this;
|
||||
}
|
||||
|
||||
|
||||
if ( jQuery.isFunction( size ) ) {
|
||||
return this.each(function( i ) {
|
||||
var self = jQuery( this );
|
||||
|
@ -35,8 +35,10 @@ jQuery.each([ "Height", "Width" ], function( i, name ) {
|
|||
|
||||
if ( jQuery.isWindow( elem ) ) {
|
||||
// Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
|
||||
return elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
|
||||
elem.document.body[ "client" + name ];
|
||||
// 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat
|
||||
var docElemProp = elem.document.documentElement[ "client" + name ];
|
||||
return elem.document.compatMode === "CSS1Compat" && docElemProp ||
|
||||
elem.document.body[ "client" + name ] || docElemProp;
|
||||
|
||||
// Get document width or height
|
||||
} else if ( elem.nodeType === 9 ) {
|
||||
|
|
12
src/effects.js
vendored
12
src/effects.js
vendored
|
@ -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", display );
|
||||
if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) {
|
||||
jQuery._data( this[i], "olddisplay", display );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -337,7 +337,7 @@ jQuery.fx.prototype = {
|
|||
}
|
||||
|
||||
var r = parseFloat( jQuery.css( this.elem, this.prop ) );
|
||||
return r && r > -10000 ? r : 0;
|
||||
return r || 0;
|
||||
},
|
||||
|
||||
// Start an animation from one number to another
|
||||
|
|
122
src/event.js
122
src/event.js
|
@ -8,7 +8,7 @@ var rnamespaces = /\.(.*)$/,
|
|||
fcleanup = function( nm ) {
|
||||
return nm.replace(rescape, "\\$&");
|
||||
},
|
||||
focusCounts = { focusin: 0, focusout: 0 };
|
||||
eventKey = "events";
|
||||
|
||||
/*
|
||||
* A number of helper functions used for managing events.
|
||||
|
@ -50,7 +50,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,12 +58,9 @@ 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" ) {
|
||||
// On plain objects events is a fn that holds the the data
|
||||
// which prevents this data from being JSON serialized
|
||||
|
@ -143,9 +140,9 @@ jQuery.event = {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( special.add ) {
|
||||
special.add.call( elem, handleObj );
|
||||
|
||||
if ( special.add ) {
|
||||
special.add.call( elem, handleObj );
|
||||
|
||||
if ( !handleObj.handler.guid ) {
|
||||
handleObj.handler.guid = handler.guid;
|
||||
|
@ -177,14 +174,13 @@ 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 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if ( typeof events === "function" ) {
|
||||
elemData = events;
|
||||
events = events.events;
|
||||
|
@ -222,7 +218,7 @@ jQuery.event = {
|
|||
namespaces = type.split(".");
|
||||
type = namespaces.shift();
|
||||
|
||||
namespace = new RegExp("(^|\\.)" +
|
||||
namespace = new RegExp("(^|\\.)" +
|
||||
jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
|
||||
}
|
||||
|
||||
|
@ -290,10 +286,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 +321,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 +356,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 );
|
||||
|
@ -384,7 +387,7 @@ jQuery.event = {
|
|||
isClick = jQuery.nodeName( target, "a" ) && targetType === "click",
|
||||
special = jQuery.event.special[ targetType ] || {};
|
||||
|
||||
if ( (!special._default || special._default.call( elem, event ) === false) &&
|
||||
if ( (!special._default || special._default.call( elem, event ) === false) &&
|
||||
!isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
|
||||
|
||||
try {
|
||||
|
@ -432,7 +435,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;
|
||||
|
@ -454,7 +457,7 @@ jQuery.event = {
|
|||
event.handler = handleObj.handler;
|
||||
event.data = handleObj.data;
|
||||
event.handleObj = handleObj;
|
||||
|
||||
|
||||
var ret = handleObj.handler.apply( this, args );
|
||||
|
||||
if ( ret !== undefined ) {
|
||||
|
@ -553,7 +556,7 @@ jQuery.event = {
|
|||
add: function( handleObj ) {
|
||||
jQuery.event.add( this,
|
||||
liveConvert( handleObj.origType, handleObj.selector ),
|
||||
jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
|
||||
jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
|
||||
},
|
||||
|
||||
remove: function( handleObj ) {
|
||||
|
@ -583,7 +586,7 @@ jQuery.removeEvent = document.removeEventListener ?
|
|||
if ( elem.removeEventListener ) {
|
||||
elem.removeEventListener( type, handle, false );
|
||||
}
|
||||
} :
|
||||
} :
|
||||
function( elem, type, handle ) {
|
||||
if ( elem.detachEvent ) {
|
||||
elem.detachEvent( "on" + type, handle );
|
||||
|
@ -600,6 +603,12 @@ jQuery.Event = function( src ) {
|
|||
if ( src && src.type ) {
|
||||
this.originalEvent = src;
|
||||
this.type = src.type;
|
||||
|
||||
// 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 ||
|
||||
src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;
|
||||
|
||||
// Event type
|
||||
} else {
|
||||
this.type = src;
|
||||
|
@ -630,7 +639,7 @@ jQuery.Event.prototype = {
|
|||
if ( !e ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// if preventDefault exists run it on the original event
|
||||
if ( e.preventDefault ) {
|
||||
e.preventDefault();
|
||||
|
@ -726,7 +735,7 @@ if ( !jQuery.support.submitBubbles ) {
|
|||
return trigger( "submit", this, arguments );
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
|
||||
var elem = e.target,
|
||||
type = elem.type;
|
||||
|
@ -781,14 +790,14 @@ 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 ) {
|
||||
return;
|
||||
}
|
||||
|
@ -802,7 +811,7 @@ if ( !jQuery.support.changeBubbles ) {
|
|||
|
||||
jQuery.event.special.change = {
|
||||
filters: {
|
||||
focusout: testChange,
|
||||
focusout: testChange,
|
||||
|
||||
beforedeactivate: testChange,
|
||||
|
||||
|
@ -831,7 +840,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) );
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -870,21 +879,17 @@ if ( document.addEventListener ) {
|
|||
jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
|
||||
jQuery.event.special[ fix ] = {
|
||||
setup: function() {
|
||||
if ( focusCounts[fix]++ === 0 ) {
|
||||
document.addEventListener( orig, handler, true );
|
||||
}
|
||||
this.addEventListener( orig, handler, true );
|
||||
},
|
||||
teardown: function() {
|
||||
if ( --focusCounts[fix] === 0 ) {
|
||||
document.removeEventListener( orig, handler, true );
|
||||
}
|
||||
this.removeEventListener( orig, handler, true );
|
||||
}
|
||||
};
|
||||
|
||||
function handler( e ) {
|
||||
function handler( e ) {
|
||||
e = jQuery.event.fix( e );
|
||||
e.type = fix;
|
||||
return jQuery.event.trigger( e, null, e.target );
|
||||
return jQuery.event.handle.call( this, e );
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -900,7 +905,7 @@ jQuery.each(["bind", "one"], function( i, name ) {
|
|||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
if ( jQuery.isFunction( data ) || data === false ) {
|
||||
fn = data;
|
||||
data = undefined;
|
||||
|
@ -945,20 +950,20 @@ jQuery.fn.extend({
|
|||
|
||||
return this;
|
||||
},
|
||||
|
||||
|
||||
delegate: function( selector, types, data, fn ) {
|
||||
return this.live( types, data, fn, selector );
|
||||
},
|
||||
|
||||
|
||||
undelegate: function( selector, types, fn ) {
|
||||
if ( arguments.length === 0 ) {
|
||||
return this.unbind( "live" );
|
||||
|
||||
|
||||
} else {
|
||||
return this.die( types, null, fn, selector );
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
trigger: function( type, data ) {
|
||||
return this.each(function() {
|
||||
jQuery.event.trigger( type, data, this );
|
||||
|
@ -1018,12 +1023,12 @@ jQuery.each(["live", "die"], function( i, name ) {
|
|||
var type, i = 0, match, namespaces, preType,
|
||||
selector = origSelector || this.selector,
|
||||
context = origSelector ? this : jQuery( this.context );
|
||||
|
||||
|
||||
if ( typeof types === "object" && !types.preventDefault ) {
|
||||
for ( var key in types ) {
|
||||
context[ name ]( key, data, types[key], selector );
|
||||
}
|
||||
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -1070,7 +1075,7 @@ jQuery.each(["live", "die"], function( i, name ) {
|
|||
context.unbind( "live." + liveConvert( type, selector ), fn );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return this;
|
||||
};
|
||||
});
|
||||
|
@ -1079,7 +1084,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;
|
||||
|
@ -1089,7 +1094,7 @@ function liveHandler( event ) {
|
|||
if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if ( event.namespace ) {
|
||||
namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
|
||||
}
|
||||
|
@ -1187,21 +1192,4 @@ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblcl
|
|||
}
|
||||
});
|
||||
|
||||
// Prevent memory leaks in IE
|
||||
// Window isn't included so as not to unbind existing unload events
|
||||
// More info:
|
||||
// - http://isaacschlueter.com/2006/10/msie-memory-leaks/
|
||||
if ( window.attachEvent && !window.addEventListener ) {
|
||||
jQuery(window).bind("unload", function() {
|
||||
for ( var id in jQuery.cache ) {
|
||||
if ( jQuery.cache[ id ].handle ) {
|
||||
// Try/Catch is to handle iframes being unloaded, see #4280
|
||||
try {
|
||||
jQuery.event.remove( jQuery.cache[ id ].handle.elem );
|
||||
} catch(e) {}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
})( jQuery );
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
* Copyright 2010, The Dojo Foundation
|
||||
* Released under the MIT, BSD, and GPL Licenses.
|
||||
*
|
||||
* Date:
|
||||
* Date: @DATE
|
||||
*/
|
||||
(function( window, undefined ) {
|
||||
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
@ -370,24 +370,35 @@ function root( elem, cur ) {
|
|||
}
|
||||
|
||||
function cloneCopyEvent(orig, ret) {
|
||||
var i = 0;
|
||||
|
||||
ret.each(function() {
|
||||
if ( this.nodeType !== 1 || this.nodeName !== (orig[i] && orig[i].nodeName) ) {
|
||||
ret.each(function (nodeIndex) {
|
||||
if ( this.nodeType !== 1 || !jQuery.hasData(orig[nodeIndex]) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var oldData = jQuery.data( orig[i++] ),
|
||||
curData = jQuery.data( this, oldData ),
|
||||
events = oldData && oldData.events;
|
||||
// XXX remove for 1.5 RC or merge back in if there is actually a reason for this check that has been
|
||||
// unexposed by unit tests
|
||||
if ( this.nodeName !== (orig[nodeIndex] && orig[nodeIndex].nodeName) ) {
|
||||
throw "Cloned data mismatch";
|
||||
}
|
||||
|
||||
if ( events ) {
|
||||
delete curData.handle;
|
||||
curData.events = {};
|
||||
var internalKey = jQuery.expando,
|
||||
oldData = jQuery.data( orig[nodeIndex] ),
|
||||
curData = jQuery.data( this, oldData );
|
||||
|
||||
for ( var type in events ) {
|
||||
for ( var handler in events[ type ] ) {
|
||||
jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
|
||||
// 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);
|
||||
|
||||
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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -415,18 +426,30 @@ function cloneFixAttributes(src, dest) {
|
|||
// attribute) to identify the type of content to display
|
||||
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" ) {
|
||||
} 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
|
||||
|
@ -438,12 +461,12 @@ jQuery.buildFragment = function( args, nodes, scripts ) {
|
|||
var fragment, cacheable, cacheresults,
|
||||
doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
|
||||
|
||||
// Only cache "small" (1/2 KB) strings that are associated with the main document
|
||||
// Only cache "small" (1/2 KB) HTML strings that are associated with the main document
|
||||
// Cloning options loses the selected state, so don't cache them
|
||||
// IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
|
||||
// Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
|
||||
if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
|
||||
!rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
|
||||
args[0].charAt(0) === "<" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
|
||||
|
||||
cacheable = true;
|
||||
cacheresults = jQuery.fragments[ args[0] ];
|
||||
|
@ -592,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++ ) {
|
||||
|
@ -604,17 +626,23 @@ 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 );
|
||||
}
|
||||
}
|
||||
|
||||
// Null the DOM reference to avoid IE6/7/8 leak (#7054)
|
||||
if ( data.handle ) {
|
||||
data.handle.elem = null;
|
||||
}
|
||||
}
|
||||
|
||||
if ( deleteExpando ) {
|
||||
|
|
|
@ -7,7 +7,7 @@ if ( "getBoundingClientRect" in document.documentElement ) {
|
|||
jQuery.fn.offset = function( options ) {
|
||||
var elem = this[0], box;
|
||||
|
||||
if ( options ) {
|
||||
if ( options ) {
|
||||
return this.each(function( i ) {
|
||||
jQuery.offset.setOffset( this, options, i );
|
||||
});
|
||||
|
@ -30,7 +30,7 @@ if ( "getBoundingClientRect" in document.documentElement ) {
|
|||
|
||||
// Make sure we're not dealing with a disconnected DOM node
|
||||
if ( !box || !jQuery.contains( docElem, elem ) ) {
|
||||
return box || { top: 0, left: 0 };
|
||||
return box ? { top: box.top, left: box.left } : { top: 0, left: 0 };
|
||||
}
|
||||
|
||||
var body = doc.body,
|
||||
|
@ -49,7 +49,7 @@ if ( "getBoundingClientRect" in document.documentElement ) {
|
|||
jQuery.fn.offset = function( options ) {
|
||||
var elem = this[0];
|
||||
|
||||
if ( options ) {
|
||||
if ( options ) {
|
||||
return this.each(function( i ) {
|
||||
jQuery.offset.setOffset( this, options, i );
|
||||
});
|
||||
|
@ -168,7 +168,7 @@ jQuery.offset = {
|
|||
|
||||
return { top: top, left: left };
|
||||
},
|
||||
|
||||
|
||||
setOffset: function( elem, options, i ) {
|
||||
var position = jQuery.css( elem, "position" );
|
||||
|
||||
|
@ -202,7 +202,7 @@ jQuery.offset = {
|
|||
if (options.left != null) {
|
||||
props.left = (options.left - curOffset.left) + curLeft;
|
||||
}
|
||||
|
||||
|
||||
if ( "using" in options ) {
|
||||
options.using.call( elem, props );
|
||||
} else {
|
||||
|
@ -262,7 +262,7 @@ jQuery.each( ["Left", "Top"], function( i, name ) {
|
|||
|
||||
jQuery.fn[ method ] = function(val) {
|
||||
var elem = this[0], win;
|
||||
|
||||
|
||||
if ( !elem ) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -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'/>";
|
||||
|
@ -68,7 +65,7 @@
|
|||
deleteExpando: true,
|
||||
optDisabled: false,
|
||||
checkClone: false,
|
||||
scriptEval: false,
|
||||
_scriptEval: null,
|
||||
noCloneEvent: true,
|
||||
boxModel: null,
|
||||
inlineBlockNeedsLayout: false,
|
||||
|
@ -81,32 +78,46 @@
|
|||
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
|
||||
|
@ -151,7 +162,7 @@
|
|||
jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2;
|
||||
}
|
||||
|
||||
div.innerHTML = "<table><tr><td style='padding:0;display:none'></td><td>t</td></tr></table>";
|
||||
div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
|
||||
var tds = div.getElementsByTagName("td");
|
||||
|
||||
// Check if table cells still have offsetWidth/Height when they are set
|
||||
|
@ -181,6 +192,14 @@
|
|||
var el = document.createElement("div");
|
||||
eventName = "on" + eventName;
|
||||
|
||||
// We only care about the case where non-standard event systems
|
||||
// are used, namely in IE. Short-circuiting here helps us to
|
||||
// avoid an eval call (in setAttribute) which can cause CSP
|
||||
// to go haywire. See: https://developer.mozilla.org/en/Security/CSP
|
||||
if ( !el.attachEvent ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var isSupported = (eventName in el);
|
||||
if ( !isSupported ) {
|
||||
el.setAttribute(eventName, "return;");
|
||||
|
@ -195,6 +214,6 @@
|
|||
jQuery.support.changeBubbles = eventSupported("change");
|
||||
|
||||
// release memory in IE
|
||||
root = script = div = all = a = null;
|
||||
div = all = a = null;
|
||||
})();
|
||||
})( jQuery );
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
(function( jQuery ) {
|
||||
|
||||
var jsc = jQuery.now(),
|
||||
jsre = /\=\?(&|$)/,
|
||||
rquery_jsonp = /\?/;
|
||||
|
||||
// Default jsonp callback name
|
||||
jQuery.ajaxSettings.jsonpCallback = function() {
|
||||
return "jsonp" + jsc++;
|
||||
};
|
||||
|
||||
// Normalize jsonp queries
|
||||
// 1) put callback parameter in url or data
|
||||
// 2) ensure transportDataType is json
|
||||
// 3) ensure options jsonp is always provided so that jsonp requests are always
|
||||
// json request with the jsonp option set
|
||||
jQuery.xhr.prefilter( function(s) {
|
||||
|
||||
var transportDataType = s.dataTypes[0];
|
||||
|
||||
if ( s.jsonp ||
|
||||
transportDataType === "jsonp" ||
|
||||
transportDataType === "json" && ( jsre.test(s.url) || typeof(s.data) === "string" && jsre.test(s.data) ) ) {
|
||||
|
||||
var jsonp = s.jsonp = s.jsonp || "callback",
|
||||
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;
|
||||
|
||||
if ( url == s.url && data == s.data ) {
|
||||
url = url += (rquery_jsonp.test( url ) ? "&" : "?") + jsonp + "=" + jsonpCallback;
|
||||
}
|
||||
|
||||
s.url = url;
|
||||
s.data = data;
|
||||
|
||||
s.dataTypes[0] = "json";
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Bind transport to json dataType
|
||||
jQuery.xhr.bindTransport("json", function(s) {
|
||||
|
||||
if ( s.jsonp ) {
|
||||
|
||||
// Put callback in place
|
||||
var responseContainer,
|
||||
jsonpCallback = s.jsonpCallback,
|
||||
previous = window[ jsonpCallback ];
|
||||
|
||||
window [ jsonpCallback ] = function( response ) {
|
||||
responseContainer = [response];
|
||||
};
|
||||
|
||||
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] );
|
||||
}
|
||||
} else {
|
||||
// else, more memory leak avoidance
|
||||
try{ delete window[ jsonpCallback ]; } catch(e){}
|
||||
}
|
||||
|
||||
}, s.complete ];
|
||||
|
||||
// Use data converter to retrieve json after script execution
|
||||
s.dataConverters["script => json"] = function() {
|
||||
if ( ! responseContainer ) {
|
||||
jQuery.error("Callback '" + jsonpCallback + "' was not called");
|
||||
}
|
||||
return responseContainer[ 0 ];
|
||||
};
|
||||
|
||||
// Delegate to script transport
|
||||
return "script";
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
})( jQuery );
|
|
@ -1,191 +0,0 @@
|
|||
(function( jQuery ) {
|
||||
|
||||
var // Next fake timer id
|
||||
xhrPollingId = jQuery.now(),
|
||||
|
||||
// Callbacks hashtable
|
||||
xhrs = {},
|
||||
|
||||
// #5280: see end of file
|
||||
xhrUnloadAbortMarker = [];
|
||||
|
||||
|
||||
jQuery.xhr.bindTransport( function( s , determineDataType ) {
|
||||
|
||||
// Cross domain only allowed if supported through XMLHttpRequest
|
||||
if ( ! s.crossDomain || jQuery.support.cors ) {
|
||||
|
||||
var callback;
|
||||
|
||||
return {
|
||||
|
||||
send: function(headers, complete) {
|
||||
|
||||
var xhr = s.xhr(),
|
||||
handle;
|
||||
|
||||
// Open the socket
|
||||
// Passing null username, generates a login popup on Opera (#2865)
|
||||
if ( s.username ) {
|
||||
xhr.open(s.type, s.url, s.async, s.username, s.password);
|
||||
} else {
|
||||
xhr.open(s.type, s.url, s.async);
|
||||
}
|
||||
|
||||
// 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
|
||||
if ( ! ( s.crossDomain && ! s.hasContent ) && ! headers["x-requested-with"] ) {
|
||||
headers["x-requested-with"] = "XMLHttpRequest";
|
||||
}
|
||||
|
||||
// Need an extra try/catch for cross domain requests in Firefox 3
|
||||
try {
|
||||
|
||||
jQuery.each(headers, function(key,value) {
|
||||
xhr.setRequestHeader(key,value);
|
||||
});
|
||||
|
||||
} catch(_) {}
|
||||
|
||||
// Do send the request
|
||||
try {
|
||||
xhr.send( ( s.hasContent && s.data ) || null );
|
||||
} catch(e) {
|
||||
complete(0, "error", "" + e);
|
||||
return;
|
||||
}
|
||||
|
||||
// Listener
|
||||
callback = function ( abortStatusText ) {
|
||||
|
||||
// Was never called and is aborted or complete
|
||||
if ( callback && ( abortStatusText || xhr.readyState === 4 ) ) {
|
||||
|
||||
// Do not listen anymore
|
||||
if (handle) {
|
||||
xhr.onreadystatechange = jQuery.noop;
|
||||
delete xhrs[ handle ];
|
||||
handle = undefined;
|
||||
}
|
||||
|
||||
callback = 0;
|
||||
|
||||
// Get info
|
||||
var status, statusText, response, responseHeaders;
|
||||
|
||||
if ( abortStatusText ) {
|
||||
|
||||
if ( xhr.readyState !== 4 ) {
|
||||
xhr.abort();
|
||||
}
|
||||
|
||||
// Stop here if unloadAbort
|
||||
if ( abortStatusText === xhrUnloadAbortMarker ) {
|
||||
return;
|
||||
}
|
||||
|
||||
status = 0;
|
||||
statusText = abortStatusText;
|
||||
|
||||
} else {
|
||||
|
||||
status = xhr.status;
|
||||
|
||||
try { // Firefox throws an exception when accessing statusText for faulty cross-domain requests
|
||||
|
||||
statusText = xhr.statusText;
|
||||
|
||||
} catch( e ) {
|
||||
|
||||
statusText = ""; // We normalize with Webkit giving an empty statusText
|
||||
|
||||
}
|
||||
|
||||
responseHeaders = xhr.getAllResponseHeaders();
|
||||
|
||||
// Filter status for non standard behaviours
|
||||
// (so many they seem to be the actual "standard")
|
||||
status =
|
||||
// Opera returns 0 when it should be 304
|
||||
// Webkit returns 0 for failing cross-domain no matter the real status
|
||||
status === 0 ?
|
||||
(
|
||||
! s.crossDomain || statusText ? // Webkit, Firefox: filter out faulty cross-domain requests
|
||||
(
|
||||
responseHeaders ? // Opera: filter out real aborts #6060
|
||||
304
|
||||
:
|
||||
0
|
||||
)
|
||||
:
|
||||
302 // We assume 302 but could be anything cross-domain related
|
||||
)
|
||||
:
|
||||
(
|
||||
status == 1223 ? // IE sometimes returns 1223 when it should be 204 (see #1450)
|
||||
204
|
||||
:
|
||||
status
|
||||
);
|
||||
|
||||
// Guess response if needed & update datatype accordingly
|
||||
if ( status >= 200 && status < 300 ) {
|
||||
response =
|
||||
determineDataType(
|
||||
s,
|
||||
xhr.getResponseHeader("content-type"),
|
||||
xhr.responseText,
|
||||
xhr.responseXML );
|
||||
}
|
||||
}
|
||||
|
||||
// Call complete
|
||||
complete(status,statusText,response,responseHeaders);
|
||||
}
|
||||
};
|
||||
|
||||
// if we're in sync mode
|
||||
// or it's in cache and has been retrieved directly (IE6 & IE7)
|
||||
// we need to manually fire the callback
|
||||
if ( ! s.async || xhr.readyState === 4 ) {
|
||||
|
||||
callback();
|
||||
|
||||
} else {
|
||||
|
||||
// Listener is externalized to handle abort on unload
|
||||
handle = xhrPollingId++;
|
||||
xhrs[ handle ] = xhr;
|
||||
xhr.onreadystatechange = function() {
|
||||
callback();
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
abort: function(statusText) {
|
||||
if ( callback ) {
|
||||
callback(statusText);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// #5280: we need to abort on unload or IE will keep connections alive
|
||||
jQuery(window).bind( "unload" , function() {
|
||||
|
||||
// Abort all pending requests
|
||||
jQuery.each(xhrs, function(_, xhr) {
|
||||
if ( xhr.onreadystatechange ) {
|
||||
xhr.onreadystatechange( xhrUnloadAbortMarker );
|
||||
}
|
||||
});
|
||||
|
||||
// Resest polling structure to be safe
|
||||
xhrs = {};
|
||||
|
||||
});
|
||||
|
||||
})( jQuery );
|
|
@ -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 ) {
|
||||
|
@ -51,7 +58,7 @@ jQuery.fn.extend({
|
|||
filter: function( selector ) {
|
||||
return this.pushStack( winnow(this, selector, true), "filter", selector );
|
||||
},
|
||||
|
||||
|
||||
is: function( selector ) {
|
||||
return !!selector && jQuery.filter( selector, this ).length > 0;
|
||||
},
|
||||
|
@ -69,7 +76,7 @@ jQuery.fn.extend({
|
|||
selector = selectors[i];
|
||||
|
||||
if ( !matches[selector] ) {
|
||||
matches[selector] = jQuery.expr.match.POS.test( selector ) ?
|
||||
matches[selector] = jQuery.expr.match.POS.test( selector ) ?
|
||||
jQuery( selector, context || this.context ) :
|
||||
selector;
|
||||
}
|
||||
|
@ -92,7 +99,7 @@ jQuery.fn.extend({
|
|||
return ret;
|
||||
}
|
||||
|
||||
var pos = POS.test( selectors ) ?
|
||||
var pos = POS.test( selectors ) ?
|
||||
jQuery( selectors, context || this.context ) : null;
|
||||
|
||||
for ( i = 0, l = this.length; i < l; i++ ) {
|
||||
|
@ -113,10 +120,10 @@ jQuery.fn.extend({
|
|||
}
|
||||
|
||||
ret = ret.length > 1 ? jQuery.unique(ret) : ret;
|
||||
|
||||
|
||||
return this.pushStack( ret, "closest", selectors );
|
||||
},
|
||||
|
||||
|
||||
// Determine the position of an element within
|
||||
// the matched set of elements
|
||||
index: function( elem ) {
|
||||
|
@ -134,7 +141,7 @@ jQuery.fn.extend({
|
|||
|
||||
add: function( selector, context ) {
|
||||
var set = typeof selector === "string" ?
|
||||
jQuery( selector, context || this.context ) :
|
||||
jQuery( selector, context ) :
|
||||
jQuery.makeArray( selector ),
|
||||
all = jQuery.merge( this.get(), set );
|
||||
|
||||
|
@ -196,8 +203,13 @@ 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 ),
|
||||
// The variable 'args' was introduced in
|
||||
// https://github.com/jquery/jquery/commit/52a0238
|
||||
// to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed.
|
||||
// http://code.google.com/p/v8/issues/detail?id=1050
|
||||
args = slice.call(arguments);
|
||||
|
||||
if ( !runtil.test( name ) ) {
|
||||
selector = until;
|
||||
}
|
||||
|
@ -206,13 +218,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(",") );
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -226,7 +238,7 @@ jQuery.extend({
|
|||
jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
|
||||
jQuery.find.matches(expr, elems);
|
||||
},
|
||||
|
||||
|
||||
dir: function( elem, dir, until ) {
|
||||
var matched = [],
|
||||
cur = elem[ dir ];
|
||||
|
|
909
src/xhr.js
909
src/xhr.js
|
@ -1,909 +0,0 @@
|
|||
(function( jQuery ) {
|
||||
|
||||
var rquery_xhr = /\?/,
|
||||
rhash = /#.*$/,
|
||||
rheaders = /^(.*?):\s*(.*?)\r?$/mg, // IE leaves an \r character at EOL
|
||||
rnoContent = /^(?:GET|HEAD)$/,
|
||||
rts = /([?&])_=[^&]*/,
|
||||
rurl = /^(\w+:)?\/\/([^\/?#]+)/,
|
||||
|
||||
sliceFunc = Array.prototype.slice,
|
||||
|
||||
isFunction = jQuery.isFunction;
|
||||
|
||||
// Creates a jQuery xhr object
|
||||
jQuery.xhr = function( _native ) {
|
||||
|
||||
if ( _native ) {
|
||||
return jQuery.ajaxSettings.xhr();
|
||||
}
|
||||
|
||||
function reset(force) {
|
||||
|
||||
// We only need to reset if we went through the init phase
|
||||
// (with the exception of object creation)
|
||||
if ( force || internal ) {
|
||||
|
||||
// Reset callbacks lists
|
||||
callbacksLists = {
|
||||
success: createCBList(),
|
||||
error: createCBList(),
|
||||
complete: createCBList()
|
||||
};
|
||||
|
||||
// Reset private variables
|
||||
requestHeaders = {};
|
||||
responseHeadersString = responseHeaders = internal = done = timeoutTimer = s = undefined;
|
||||
|
||||
// Reset state
|
||||
xhr.readyState = 0;
|
||||
sendFlag = 0;
|
||||
|
||||
// Remove responseX fields
|
||||
for ( var name in xhr ) {
|
||||
if ( /^response/.test(name) ) {
|
||||
delete xhr[name];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
var // Options extraction
|
||||
|
||||
// Remove hash character (#7531: first for string promotion)
|
||||
url = s.url = ( "" + s.url ).replace( rhash , "" ),
|
||||
|
||||
// Uppercase the type
|
||||
type = s.type = s.type.toUpperCase(),
|
||||
|
||||
// Determine if request has content
|
||||
hasContent = s.hasContent = ! rnoContent.test( type ),
|
||||
|
||||
// Extract dataTypes list
|
||||
dataType = s.dataType,
|
||||
dataTypes = s.dataTypes = dataType ? jQuery.trim(dataType).toLowerCase().split(/\s+/) : ["*"],
|
||||
|
||||
// Determine if a cross-domain request is in order
|
||||
parts = rurl.exec( url.toLowerCase() ),
|
||||
loc = location,
|
||||
crossDomain = s.crossDomain = !!( parts && ( parts[1] && parts[1] != loc.protocol || parts[2] != loc.host ) ),
|
||||
|
||||
// Get other options locally
|
||||
data = s.data,
|
||||
originalContentType = s.contentType,
|
||||
prefilters = s.prefilters,
|
||||
accepts = s.accepts,
|
||||
headers = s.headers,
|
||||
|
||||
// Other Variables
|
||||
transportDataType,
|
||||
i;
|
||||
|
||||
// Convert data if not already a string
|
||||
if ( data && s.processData && typeof data != "string" ) {
|
||||
data = s.data = jQuery.param( data , s.traditional );
|
||||
}
|
||||
|
||||
// Apply option prefilters
|
||||
for (i in prefilters) {
|
||||
prefilters[i](s);
|
||||
}
|
||||
|
||||
// Get internal
|
||||
internal = selectTransport( s );
|
||||
|
||||
// Re-actualize url & data
|
||||
url = s.url;
|
||||
data = s.data;
|
||||
|
||||
// If internal was found
|
||||
if ( internal ) {
|
||||
|
||||
// Get transportDataType
|
||||
transportDataType = dataTypes[0];
|
||||
|
||||
// More options handling for requests with no content
|
||||
if ( ! hasContent ) {
|
||||
|
||||
// If data is available, append data to url
|
||||
if ( data ) {
|
||||
url += (rquery_xhr.test(url) ? "&" : "?") + data;
|
||||
}
|
||||
|
||||
// Add anti-cache in url if needed
|
||||
if ( s.cache === false ) {
|
||||
|
||||
var ts = jQuery.now(),
|
||||
// try replacing _= if it is there
|
||||
ret = url.replace(rts, "$1_=" + ts );
|
||||
|
||||
// if nothing was replaced, add timestamp to the end
|
||||
url = ret + ((ret == url) ? (rquery_xhr.test(url) ? "&" : "?") + "_=" + ts : "");
|
||||
}
|
||||
|
||||
s.url = url;
|
||||
}
|
||||
|
||||
// Set the correct header, if data is being sent
|
||||
if ( ( data && hasContent ) || originalContentType ) {
|
||||
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[url] ) {
|
||||
requestHeaders["if-modified-since"] = jQuery_lastModified[url];
|
||||
}
|
||||
if ( jQuery_etag[url] ) {
|
||||
requestHeaders["if-none-match"] = jQuery_etag[url];
|
||||
}
|
||||
}
|
||||
|
||||
// Set the Accepts header for the server, depending on the dataType
|
||||
requestHeaders.accept = transportDataType && accepts[ transportDataType ] ?
|
||||
accepts[ transportDataType ] + ( transportDataType !== "*" ? ", */*; q=0.01" : "" ) :
|
||||
accepts[ "*" ];
|
||||
|
||||
// Check for headers option
|
||||
for ( i in headers ) {
|
||||
requestHeaders[ i.toLowerCase() ] = headers[ i ];
|
||||
}
|
||||
}
|
||||
|
||||
callbackContext = s.context || s;
|
||||
globalEventContext = s.context ? jQuery(s.context) : jQuery.event;
|
||||
|
||||
for ( i in callbacksLists ) {
|
||||
callbacksLists[i].bind(s[i]);
|
||||
}
|
||||
|
||||
// Watch for a new set of requests
|
||||
if ( s.global && jQuery.active++ === 0 ) {
|
||||
jQuery.event.trigger( "ajaxStart" );
|
||||
}
|
||||
|
||||
done = whenDone;
|
||||
}
|
||||
|
||||
function whenDone(status, statusText, response, headers) {
|
||||
|
||||
// Called once
|
||||
done = undefined;
|
||||
|
||||
// Reset sendFlag
|
||||
sendFlag = 0;
|
||||
|
||||
// Cache response headers
|
||||
responseHeadersString = headers || "";
|
||||
|
||||
// Clear timeout if it exists
|
||||
if ( timeoutTimer ) {
|
||||
clearTimeout(timeoutTimer);
|
||||
}
|
||||
|
||||
var // Reference url
|
||||
url = s.url,
|
||||
// and ifModified status
|
||||
ifModified = s.ifModified,
|
||||
|
||||
// Is it a success?
|
||||
isSuccess = 0,
|
||||
// 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" );
|
||||
}
|
||||
|
||||
// If successful, handle type chaining
|
||||
if ( statusText === "success" || statusText === "notmodified" ) {
|
||||
|
||||
// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
|
||||
if ( ifModified ) {
|
||||
var lastModified = xhr.getResponseHeader("Last-Modified"),
|
||||
etag = xhr.getResponseHeader("Etag");
|
||||
|
||||
if (lastModified) {
|
||||
jQuery_lastModified[url] = lastModified;
|
||||
}
|
||||
if (etag) {
|
||||
jQuery_etag[url] = etag;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ifModified && statusText === "notmodified" ) {
|
||||
|
||||
success = null;
|
||||
isSuccess = 1;
|
||||
|
||||
} else {
|
||||
// Chain data conversions and determine the final value
|
||||
// (if an exception is thrown in the process, it'll be notified as an error)
|
||||
try {
|
||||
|
||||
function checkData(data) {
|
||||
if ( data !== undefined ) {
|
||||
var testFunction = s.dataCheckers[srcDataType];
|
||||
if ( isFunction( testFunction ) ) {
|
||||
testFunction(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function convertData (data) {
|
||||
var conversionFunction = dataConverters[srcDataType+" => "+destDataType] ||
|
||||
dataConverters["* => "+destDataType],
|
||||
noFunction = ! isFunction( conversionFunction );
|
||||
if ( noFunction ) {
|
||||
if ( srcDataType != "text" && destDataType != "text" ) {
|
||||
// We try to put text inbetween
|
||||
var first = dataConverters[srcDataType+" => text"] ||
|
||||
dataConverters["* => text"],
|
||||
second = dataConverters["text => "+destDataType] ||
|
||||
dataConverters["* => "+destDataType],
|
||||
areFunctions = isFunction( first ) && isFunction( second );
|
||||
if ( areFunctions ) {
|
||||
conversionFunction = function (data) {
|
||||
return second( first ( data ) );
|
||||
};
|
||||
}
|
||||
noFunction = ! areFunctions;
|
||||
}
|
||||
if ( noFunction ) {
|
||||
jQuery.error( "no data converter between " + srcDataType + " and " + destDataType );
|
||||
}
|
||||
|
||||
}
|
||||
return conversionFunction(data);
|
||||
}
|
||||
|
||||
var dataTypes = s.dataTypes,
|
||||
i,
|
||||
length,
|
||||
data = response,
|
||||
dataConverters = s.dataConverters,
|
||||
srcDataType,
|
||||
destDataType,
|
||||
responseTypes = s.xhrResponseFields;
|
||||
|
||||
for ( i = 0, length = dataTypes.length ; i < length ; i++ ) {
|
||||
|
||||
destDataType = dataTypes[i];
|
||||
|
||||
if ( !srcDataType ) { // First time
|
||||
|
||||
// Copy type
|
||||
srcDataType = destDataType;
|
||||
// Check
|
||||
checkData(data);
|
||||
// Apply dataFilter
|
||||
if ( isFunction( s.dataFilter ) ) {
|
||||
data = s.dataFilter(data, s.dataType);
|
||||
// Recheck data
|
||||
checkData(data);
|
||||
}
|
||||
|
||||
} else { // Subsequent times
|
||||
|
||||
// handle auto
|
||||
// JULIAN: for reasons unknown to me === doesn't work here
|
||||
if (destDataType == "*") {
|
||||
|
||||
destDataType = srcDataType;
|
||||
|
||||
} else if ( srcDataType != destDataType ) {
|
||||
|
||||
// Convert
|
||||
data = convertData(data);
|
||||
// Copy type & check
|
||||
srcDataType = destDataType;
|
||||
checkData(data);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Copy response into the xhr if it hasn't been already
|
||||
var responseDataType,
|
||||
responseType = responseTypes[srcDataType];
|
||||
|
||||
if ( responseType ) {
|
||||
|
||||
responseDataType = srcDataType;
|
||||
|
||||
} else {
|
||||
|
||||
responseType = responseTypes[ responseDataType = "text" ];
|
||||
|
||||
}
|
||||
|
||||
if ( responseType !== 1 ) {
|
||||
xhr[ "response" + responseType ] = data;
|
||||
responseTypes[ responseType ] = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// We have a real success
|
||||
success = data;
|
||||
isSuccess = 1;
|
||||
|
||||
} catch(e) {
|
||||
|
||||
statusText = "parsererror";
|
||||
error = "" + e;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} else { // if not success, mark it as an error
|
||||
|
||||
error = error || statusText;
|
||||
|
||||
}
|
||||
|
||||
// Set data for the fake xhr object
|
||||
xhr.status = status;
|
||||
xhr.statusText = statusText;
|
||||
|
||||
// Keep local copies of vars in case callbacks re-use the xhr
|
||||
var _s = s,
|
||||
_callbacksLists = callbacksLists,
|
||||
_callbackContext = callbackContext,
|
||||
_globalEventContext = globalEventContext;
|
||||
|
||||
// Set state if the xhr hasn't been re-used
|
||||
function _setState( value ) {
|
||||
if ( xhr.readyState && s === _s ) {
|
||||
setState( value );
|
||||
}
|
||||
}
|
||||
|
||||
// Really completed?
|
||||
if ( status && s.async ) {
|
||||
setState( 2 );
|
||||
_setState( 3 );
|
||||
}
|
||||
|
||||
// We're done
|
||||
_setState( 4 );
|
||||
|
||||
// Success
|
||||
_callbacksLists.success.fire( isSuccess , _callbackContext , success, statusText, xhr);
|
||||
if ( isSuccess && _s.global ) {
|
||||
_globalEventContext.trigger( "ajaxSuccess", [xhr, _s, success] );
|
||||
}
|
||||
// Error
|
||||
_callbacksLists.error.fire( ! isSuccess , _callbackContext , xhr, statusText, error);
|
||||
if ( !isSuccess && _s.global ) {
|
||||
_globalEventContext.trigger( "ajaxError", [xhr, _s, error] );
|
||||
}
|
||||
// Complete
|
||||
_callbacksLists.complete.fire( 1 , _callbackContext, xhr, statusText);
|
||||
if ( _s.global ) {
|
||||
_globalEventContext.trigger( "ajaxComplete", [xhr, _s] );
|
||||
// Handle the global AJAX counter
|
||||
if ( ! --jQuery.active ) {
|
||||
jQuery.event.trigger( "ajaxStop" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ready state control
|
||||
function checkState( expected , test ) {
|
||||
if ( expected !== true && ( expected === false || test === false || xhr.readyState !== expected ) ) {
|
||||
jQuery.error("INVALID_STATE_ERR");
|
||||
}
|
||||
}
|
||||
|
||||
// Ready state change
|
||||
function setState( value ) {
|
||||
xhr.readyState = value;
|
||||
if ( isFunction( xhr.onreadystatechange ) ) {
|
||||
xhr.onreadystatechange();
|
||||
}
|
||||
}
|
||||
|
||||
var // jQuery lists
|
||||
jQuery_lastModified = jQuery.lastModified,
|
||||
jQuery_etag = jQuery.etag,
|
||||
// Options object
|
||||
s,
|
||||
// Callback stuff
|
||||
callbackContext,
|
||||
globalEventContext,
|
||||
callbacksLists,
|
||||
// Headers (they are sent all at once)
|
||||
requestHeaders,
|
||||
// Response headers
|
||||
responseHeadersString,
|
||||
responseHeaders,
|
||||
// Done callback
|
||||
done,
|
||||
// transport
|
||||
internal,
|
||||
// timeout handle
|
||||
timeoutTimer,
|
||||
// The send flag
|
||||
sendFlag,
|
||||
// Fake xhr
|
||||
xhr = {
|
||||
// state
|
||||
readyState: 0,
|
||||
|
||||
// Callback
|
||||
onreadystatechange: null,
|
||||
|
||||
// Open
|
||||
open: function(type, url, async, username, password) {
|
||||
|
||||
xhr.abort();
|
||||
reset();
|
||||
|
||||
s = {
|
||||
type: type,
|
||||
url: url,
|
||||
async: async,
|
||||
username: username,
|
||||
password: password
|
||||
};
|
||||
|
||||
setState(1);
|
||||
|
||||
return xhr;
|
||||
},
|
||||
|
||||
// Send
|
||||
send: function(data, moreOptions) {
|
||||
|
||||
checkState(1 , !sendFlag);
|
||||
|
||||
s.data = data;
|
||||
|
||||
s = jQuery.extend( true,
|
||||
{},
|
||||
jQuery.ajaxSettings,
|
||||
s,
|
||||
moreOptions || ( moreOptions === false ? { global: false } : {} ) );
|
||||
|
||||
if ( moreOptions ) {
|
||||
// We force the original context
|
||||
// (plain objects used as context get extended)
|
||||
s.context = moreOptions.context;
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
// If not internal, abort
|
||||
if ( ! internal ) {
|
||||
done( 0 , "transport not found" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Allow custom headers/mimetypes and early abort
|
||||
if ( s.beforeSend ) {
|
||||
|
||||
var _s = s;
|
||||
|
||||
if ( s.beforeSend.call(callbackContext, xhr, s) === false || ! xhr.readyState || _s !== s ) {
|
||||
|
||||
// Abort if not done
|
||||
if ( xhr.readyState && _s === s ) {
|
||||
xhr.abort();
|
||||
}
|
||||
|
||||
// Handle the global AJAX counter
|
||||
if ( _s.global && ! --jQuery.active ) {
|
||||
jQuery.event.trigger( "ajaxStop" );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
sendFlag = 1;
|
||||
|
||||
// Send global event
|
||||
if ( s.global ) {
|
||||
globalEventContext.trigger("ajaxSend", [xhr, s]);
|
||||
}
|
||||
|
||||
// Timeout
|
||||
if ( s.async && s.timeout > 0 ) {
|
||||
timeoutTimer = setTimeout(function(){
|
||||
xhr.abort("timeout");
|
||||
}, s.timeout);
|
||||
}
|
||||
|
||||
if ( s.async ) {
|
||||
setState(1);
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
internal.send(requestHeaders, done);
|
||||
return xhr;
|
||||
|
||||
} catch (e) {
|
||||
|
||||
if ( done ) {
|
||||
|
||||
done(0, "error", "" + e);
|
||||
|
||||
} else {
|
||||
|
||||
jQuery.error(e);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
// Caches the header
|
||||
setRequestHeader: function(name,value) {
|
||||
checkState(1, !sendFlag);
|
||||
requestHeaders[ name.toLowerCase() ] = value;
|
||||
return xhr;
|
||||
},
|
||||
|
||||
// Raw string
|
||||
getAllResponseHeaders: function() {
|
||||
return xhr.readyState <= 1 ? "" : responseHeadersString;
|
||||
},
|
||||
|
||||
// Builds headers hashtable if needed
|
||||
getResponseHeader: function( key ) {
|
||||
|
||||
if ( xhr.readyState <= 1 ) {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
if ( responseHeaders === undefined ) {
|
||||
|
||||
responseHeaders = {};
|
||||
|
||||
if ( typeof responseHeadersString === "string" ) {
|
||||
|
||||
var match;
|
||||
|
||||
while( ( match = rheaders.exec( responseHeadersString ) ) ) {
|
||||
responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
|
||||
}
|
||||
}
|
||||
}
|
||||
return responseHeaders[ key.toLowerCase() ];
|
||||
},
|
||||
|
||||
// Cancel the request
|
||||
abort: function(statusText) {
|
||||
if (internal) {
|
||||
internal.abort( statusText || "abort" );
|
||||
}
|
||||
xhr.readyState = 0;
|
||||
}
|
||||
};
|
||||
|
||||
// Init data (so that we can bind callbacks early
|
||||
reset(1);
|
||||
|
||||
// Install callbacks related methods
|
||||
jQuery.each(callbacksLists, function(name) {
|
||||
var list;
|
||||
xhr[name] = function() {
|
||||
list = callbacksLists[name];
|
||||
if ( list ) {
|
||||
list.bind.apply(list, arguments );
|
||||
}
|
||||
return this;
|
||||
};
|
||||
});
|
||||
|
||||
// Return the xhr emulation
|
||||
return xhr;
|
||||
};
|
||||
|
||||
// Create a callback list
|
||||
function createCBList() {
|
||||
|
||||
var functors = [],
|
||||
autoFire = 0,
|
||||
fireArgs,
|
||||
list = {
|
||||
|
||||
fire: function( flag , context ) {
|
||||
|
||||
// Save info for later bindings
|
||||
fireArgs = arguments;
|
||||
|
||||
// Remove autoFire to keep bindings in order
|
||||
autoFire = 0;
|
||||
|
||||
var args = sliceFunc.call( fireArgs , 2 );
|
||||
|
||||
// Execute callbacks
|
||||
while ( flag && functors.length ) {
|
||||
flag = functors.shift().apply( context , args ) !== false;
|
||||
}
|
||||
|
||||
// Clean if asked to stop
|
||||
if ( ! flag ) {
|
||||
clean();
|
||||
}
|
||||
|
||||
// Set autoFire
|
||||
autoFire = 1;
|
||||
},
|
||||
|
||||
bind: function() {
|
||||
|
||||
var args = arguments,
|
||||
i = 0,
|
||||
length = args.length,
|
||||
func;
|
||||
|
||||
for ( ; i < length ; i++ ) {
|
||||
|
||||
func = args[ i ];
|
||||
|
||||
if ( jQuery.isArray(func) ) {
|
||||
|
||||
list.bind.apply( list , func );
|
||||
|
||||
} else if ( isFunction(func) ) {
|
||||
|
||||
// Add if not already in
|
||||
if ( ! pos( func ) ) {
|
||||
functors.push( func );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( autoFire ) {
|
||||
list.fire.apply( list , fireArgs );
|
||||
}
|
||||
},
|
||||
|
||||
unbind: function() {
|
||||
|
||||
var i = 0,
|
||||
args = arguments,
|
||||
length = args.length,
|
||||
func,
|
||||
position;
|
||||
|
||||
if ( length ) {
|
||||
|
||||
for( ; i < length ; i++ ) {
|
||||
func = args[i];
|
||||
if ( jQuery.isArray(func) ) {
|
||||
list.unbind.apply(list,func);
|
||||
} else if ( isFunction(func) ) {
|
||||
position = pos(func);
|
||||
if ( position ) {
|
||||
functors.splice(position-1,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
functors = [];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Get the index of the functor in the list (1-based)
|
||||
function pos( func ) {
|
||||
for (var i = 0, length = functors.length; i < length && functors[i] !== func; i++) {
|
||||
}
|
||||
return i < length ? ( i + 1 ) : 0;
|
||||
}
|
||||
|
||||
// Clean the object
|
||||
function clean() {
|
||||
// Empty callbacks list
|
||||
functors = [];
|
||||
// Inhibit methods
|
||||
for (var i in list) {
|
||||
list[i] = jQuery.noop;
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
jQuery.extend(jQuery.xhr, {
|
||||
|
||||
// Add new prefilter
|
||||
prefilter: function (functor) {
|
||||
if ( isFunction(functor) ) {
|
||||
jQuery.ajaxSettings.prefilters.push( functor );
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
// Bind a transport to one or more dataTypes
|
||||
bindTransport: function () {
|
||||
|
||||
var args = arguments,
|
||||
i,
|
||||
start = 0,
|
||||
length = args.length,
|
||||
dataTypes = [ "*" ],
|
||||
functors = [],
|
||||
functor,
|
||||
first,
|
||||
append,
|
||||
list,
|
||||
transports = jQuery.ajaxSettings.transports;
|
||||
|
||||
if ( length ) {
|
||||
|
||||
if ( ! isFunction( args[ 0 ] ) ) {
|
||||
|
||||
dataTypes = args[ 0 ].toLowerCase().split(/\s+/);
|
||||
start = 1;
|
||||
|
||||
}
|
||||
|
||||
if ( dataTypes.length && start < length ) {
|
||||
|
||||
for ( i = start; i < length; i++ ) {
|
||||
functor = args[i];
|
||||
if ( isFunction(functor) ) {
|
||||
functors.push( functor );
|
||||
}
|
||||
}
|
||||
|
||||
if ( functors.length ) {
|
||||
|
||||
jQuery.each ( dataTypes, function( _ , dataType ) {
|
||||
|
||||
first = /^\+/.test( dataType );
|
||||
|
||||
if (first) {
|
||||
dataType = dataType.substr(1);
|
||||
}
|
||||
|
||||
if ( dataType !== "" ) {
|
||||
|
||||
append = Array.prototype[ first ? "unshift" : "push" ];
|
||||
|
||||
list = transports[ dataType ];
|
||||
|
||||
jQuery.each ( functors, function( _ , functor ) {
|
||||
|
||||
if ( ! list ) {
|
||||
|
||||
list = transports[ dataType ] = [ functor ];
|
||||
|
||||
} else {
|
||||
|
||||
append.call( list , functor );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
// Select a transport given options
|
||||
function selectTransport( s ) {
|
||||
|
||||
var dataTypes = s.dataTypes,
|
||||
transportDataType,
|
||||
transportsList,
|
||||
transport,
|
||||
i,
|
||||
length,
|
||||
checked = {},
|
||||
flag;
|
||||
|
||||
function initSearch( dataType ) {
|
||||
|
||||
flag = transportDataType !== dataType && ! checked[ dataType ];
|
||||
|
||||
if ( flag ) {
|
||||
|
||||
checked[ dataType ] = 1;
|
||||
transportDataType = dataType;
|
||||
transportsList = s.transports[ dataType ];
|
||||
i = -1;
|
||||
length = transportsList ? transportsList.length : 0 ;
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
initSearch( dataTypes[ 0 ] );
|
||||
|
||||
for ( i = 0 ; ! transport && i <= length ; i++ ) {
|
||||
|
||||
if ( i === length ) {
|
||||
|
||||
initSearch( "*" );
|
||||
|
||||
} else {
|
||||
|
||||
transport = transportsList[ i ]( s , determineDataType );
|
||||
|
||||
// If we got redirected to another dataType
|
||||
// Search there (if not in progress or already tried)
|
||||
if ( typeof( transport ) === "string" &&
|
||||
initSearch( transport ) ) {
|
||||
|
||||
dataTypes.unshift( transport );
|
||||
transport = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return transport;
|
||||
}
|
||||
|
||||
// Utility function that handles dataType when response is received
|
||||
// (for those transports that can give text or xml responses)
|
||||
function determineDataType( s , ct , text , xml ) {
|
||||
|
||||
var autoDataType = s.autoDataType,
|
||||
type,
|
||||
regexp,
|
||||
dataTypes = s.dataTypes,
|
||||
transportDataType = dataTypes[0],
|
||||
response;
|
||||
|
||||
// Auto (xml, json, script or text determined given headers)
|
||||
if ( transportDataType === "*" ) {
|
||||
|
||||
for ( type in autoDataType ) {
|
||||
if ( ( regexp = autoDataType[ type ] ) && regexp.test( ct ) ) {
|
||||
transportDataType = dataTypes[0] = type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// xml and parsed as such
|
||||
if ( transportDataType === "xml" &&
|
||||
xml &&
|
||||
xml.documentElement /* #4958 */ ) {
|
||||
|
||||
response = xml;
|
||||
|
||||
// Text response was provided
|
||||
} else {
|
||||
|
||||
response = text;
|
||||
|
||||
// If it's not really text, defer to dataConverters
|
||||
if ( transportDataType !== "text" ) {
|
||||
dataTypes.unshift( "text" );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
})( jQuery );
|
Loading…
Add table
Add a link
Reference in a new issue