aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--frontend/js/lib/jquery.js3079
1 files changed, 1993 insertions, 1086 deletions
diff --git a/frontend/js/lib/jquery.js b/frontend/js/lib/jquery.js
index af8b3b8..e2c203f 100644
--- a/frontend/js/lib/jquery.js
+++ b/frontend/js/lib/jquery.js
@@ -1,15 +1,15 @@
/*!
- * jQuery JavaScript Library v2.0.0b2
+ * jQuery JavaScript Library v1.9.1
* http://jquery.com/
*
* Includes Sizzle.js
* http://sizzlejs.com/
*
- * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors
+ * Copyright 2005, 2012 jQuery Foundation, Inc. and other contributors
* Released under the MIT license
* http://jquery.org/license
*
- * Date: 2013-3-1
+ * Date: 2013-2-4
*/
(function( window, undefined ) {
@@ -19,20 +19,19 @@
// Support: Firefox 18+
//"use strict";
var
- // A central reference to the root jQuery(document)
- rootjQuery,
-
// The deferred used on DOM ready
readyList,
- // Support: IE9
- // For `typeof xmlNode.method` instead of `xmlNode.method !== undefined`
+ // A central reference to the root jQuery(document)
+ rootjQuery,
+
+ // Support: IE<9
+ // For `typeof node.method` instead of `node.method !== undefined`
core_strundefined = typeof undefined,
// Use the correct document accordingly with window argument (sandbox)
- location = window.location,
document = window.document,
- docElem = document.documentElement,
+ location = window.location,
// Map over jQuery in case of overwrite
_jQuery = window.jQuery,
@@ -46,7 +45,7 @@ var
// List of deleted data cache ids, so we can reuse them
core_deletedIds = [],
- core_version = "2.0.0b2",
+ core_version = "1.9.1",
// Save a reference to some core methods
core_concat = core_deletedIds.concat,
@@ -69,6 +68,9 @@ var
// Used for splitting on whitespace
core_rnotwhite = /\S+/g,
+ // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE)
+ rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
+
// A simple way to check for HTML strings
// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
// Strict HTML recognition (#11290: must start with <)
@@ -77,6 +79,12 @@ var
// Match a standalone tag
rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,
+ // JSON RegExp
+ rvalidchars = /^[\],:{}\s]*$/,
+ rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
+ rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,
+ rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,
+
// Matches dashed string for camelizing
rmsPrefix = /^-ms-/,
rdashAlpha = /-([\da-z])/gi,
@@ -86,11 +94,25 @@ var
return letter.toUpperCase();
},
- // The ready event handler and self cleanup method
- completed = function() {
- document.removeEventListener( "DOMContentLoaded", completed, false );
- window.removeEventListener( "load", completed, false );
- jQuery.ready();
+ // The ready event handler
+ completed = function( event ) {
+
+ // readyState === "complete" is good enough for us to call the dom ready in oldIE
+ if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) {
+ detach();
+ jQuery.ready();
+ }
+ },
+ // Clean-up method for dom ready events
+ detach = function() {
+ if ( document.addEventListener ) {
+ document.removeEventListener( "DOMContentLoaded", completed, false );
+ window.removeEventListener( "load", completed, false );
+
+ } else {
+ document.detachEvent( "onreadystatechange", completed );
+ window.detachEvent( "onload", completed );
+ }
};
jQuery.fn = jQuery.prototype = {
@@ -294,7 +316,7 @@ jQuery.fn = jQuery.prototype = {
jQuery.fn.init.prototype = jQuery.fn;
jQuery.extend = jQuery.fn.extend = function() {
- var options, name, src, copy, copyIsArray, clone,
+ var src, copyIsArray, copy, name, options, clone,
target = arguments[0] || {},
i = 1,
length = arguments.length,
@@ -358,9 +380,6 @@ jQuery.extend = jQuery.fn.extend = function() {
};
jQuery.extend({
- // Unique for each copy of jQuery on the page
- expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ),
-
noConflict: function( deep ) {
if ( window.$ === jQuery ) {
window.$ = _$;
@@ -397,6 +416,11 @@ jQuery.extend({
return;
}
+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+ if ( !document.body ) {
+ return setTimeout( jQuery.ready );
+ }
+
// Remember that the DOM is ready
jQuery.isReady = true;
@@ -421,7 +445,9 @@ jQuery.extend({
return jQuery.type(obj) === "function";
},
- isArray: Array.isArray,
+ isArray: Array.isArray || function( obj ) {
+ return jQuery.type(obj) === "array";
+ },
isWindow: function( obj ) {
return obj != null && obj == obj.window;
@@ -435,36 +461,38 @@ jQuery.extend({
if ( obj == null ) {
return String( obj );
}
- // Support: Safari <=5.1 (functionish RegExp)
return typeof obj === "object" || typeof obj === "function" ?
class2type[ core_toString.call(obj) ] || "object" :
typeof obj;
},
isPlainObject: function( obj ) {
- // Not plain objects:
- // - Any object or value whose internal [[Class]] property is not "[object Object]"
- // - DOM nodes
- // - window
- if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
+ // Must be an Object.
+ // Because of IE, we also have to check the presence of the constructor property.
+ // Make sure that DOM nodes and window objects don't pass through, as well
+ if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
return false;
}
- // Support: Firefox >16
- // The try/catch suppresses exceptions thrown when attempting to access
- // the "constructor" property of certain host objects, ie. |window.location|
try {
+ // Not own constructor property must be Object
if ( obj.constructor &&
- !core_hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
+ !core_hasOwn.call(obj, "constructor") &&
+ !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
return false;
}
} catch ( e ) {
+ // IE8,9 Will throw exceptions on certain host objects #9897
return false;
}
- // If the function hasn't returned already, we're confident that
- // |obj| is a plain object, created by {} or constructed with new Object
- return true;
+ // 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 || core_hasOwn.call( obj, key );
},
isEmptyObject: function( obj ) {
@@ -501,15 +529,41 @@ jQuery.extend({
}
parsed = jQuery.buildFragment( [ data ], context, scripts );
-
if ( scripts ) {
jQuery( scripts ).remove();
}
-
return jQuery.merge( [], parsed.childNodes );
},
- parseJSON: JSON.parse,
+ parseJSON: function( data ) {
+ // Attempt to parse using the native JSON parser first
+ if ( window.JSON && window.JSON.parse ) {
+ return window.JSON.parse( data );
+ }
+
+ if ( data === null ) {
+ return data;
+ }
+
+ if ( typeof data === "string" ) {
+
+ // Make sure leading/trailing whitespace is removed (IE can't handle it)
+ data = jQuery.trim( data );
+
+ if ( data ) {
+ // Make sure the incoming data is actual JSON
+ // Logic borrowed from http://json.org/json2.js
+ if ( rvalidchars.test( data.replace( rvalidescape, "@" )
+ .replace( rvalidtokens, "]" )
+ .replace( rvalidbraces, "")) ) {
+
+ return ( new Function( "return " + data ) )();
+ }
+ }
+ }
+
+ jQuery.error( "Invalid JSON: " + data );
+ },
// Cross-browser xml parsing
parseXML: function( data ) {
@@ -517,16 +571,19 @@ jQuery.extend({
if ( !data || typeof data !== "string" ) {
return null;
}
-
- // Support: IE9
try {
- tmp = new DOMParser();
- xml = tmp.parseFromString( data , "text/xml" );
- } catch ( e ) {
+ 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 );
+ }
+ } catch( e ) {
xml = undefined;
}
-
- if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
+ if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
jQuery.error( "Invalid XML: " + data );
}
return xml;
@@ -535,10 +592,16 @@ jQuery.extend({
noop: function() {},
// Evaluates a script in a global context
+ // Workarounds based on findings by Jim Driscoll
+ // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
globalEval: function( data ) {
- var indirect = eval;
- if ( jQuery.trim( data ) ) {
- indirect( data + ";" );
+ if ( data && jQuery.trim( data ) ) {
+ // We use execScript on Internet Explorer
+ // We use an anonymous function so that context is window
+ // rather than jQuery in Firefox
+ ( window.execScript || function( data ) {
+ window[ "eval" ].call( window, data );
+ } )( data );
}
},
@@ -602,9 +665,20 @@ jQuery.extend({
return obj;
},
- trim: function( text ) {
- return text == null ? "" : core_trim.call( text );
- },
+ // Use native String.trim function wherever possible
+ trim: core_trim && !core_trim.call("\uFEFF\xA0") ?
+ function( text ) {
+ return text == null ?
+ "" :
+ core_trim.call( text );
+ } :
+
+ // Otherwise use our own trimming functionality
+ function( text ) {
+ return text == null ?
+ "" :
+ ( text + "" ).replace( rtrim, "" );
+ },
// results is for internal usage only
makeArray: function( arr, results ) {
@@ -625,7 +699,25 @@ jQuery.extend({
},
inArray: function( elem, arr, i ) {
- return arr == null ? -1 : core_indexOf.call( arr, elem, i );
+ var len;
+
+ if ( arr ) {
+ if ( core_indexOf ) {
+ return core_indexOf.call( arr, elem, i );
+ }
+
+ len = arr.length;
+ i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
+
+ for ( ; i < len; i++ ) {
+ // Skip accessing in sparse arrays
+ if ( i in arr && arr[ i ] === elem ) {
+ return i;
+ }
+ }
+ }
+
+ return -1;
},
merge: function( first, second ) {
@@ -706,7 +798,7 @@ jQuery.extend({
// Bind a function to a context, optionally partially applying any
// arguments.
proxy: function( fn, context ) {
- var tmp, args, proxy;
+ var args, proxy, tmp;
if ( typeof context === "string" ) {
tmp = fn[ context ];
@@ -785,7 +877,9 @@ jQuery.extend({
length ? fn( elems[0], key ) : emptyGet;
},
- now: Date.now
+ now: function() {
+ return ( new Date() ).getTime();
+ }
});
jQuery.ready.promise = function( obj ) {
@@ -800,13 +894,50 @@ jQuery.ready.promise = function( obj ) {
// Handle it asynchronously to allow scripts the opportunity to delay ready
setTimeout( jQuery.ready );
- } else {
-
+ // Standards-based browsers support DOMContentLoaded
+ } else if ( document.addEventListener ) {
// Use the handy event callback
document.addEventListener( "DOMContentLoaded", completed, false );
// A fallback to window.onload, that will always work
window.addEventListener( "load", completed, false );
+
+ // If IE event model is used
+ } else {
+ // Ensure firing before onload, maybe late but safe also for iframes
+ document.attachEvent( "onreadystatechange", completed );
+
+ // A fallback to window.onload, that will always work
+ window.attachEvent( "onload", completed );
+
+ // If IE and not a frame
+ // continually check to see if the document is ready
+ var top = false;
+
+ try {
+ top = window.frameElement == null && document.documentElement;
+ } catch(e) {}
+
+ if ( top && top.doScroll ) {
+ (function doScrollCheck() {
+ if ( !jQuery.isReady ) {
+
+ try {
+ // Use the trick by Diego Perini
+ // http://javascript.nwbox.com/IEContentLoaded/
+ top.doScroll("left");
+ } catch(e) {
+ return setTimeout( doScrollCheck, 50 );
+ }
+
+ // detach all dom ready events
+ detach();
+
+ // and execute any waiting functions
+ jQuery.ready();
+ }
+ })();
+ }
}
}
return readyList.promise( obj );
@@ -878,18 +1009,18 @@ jQuery.Callbacks = function( options ) {
( optionsCache[ options ] || createOptions( options ) ) :
jQuery.extend( {}, options );
- var // Last fire value (for non-forgettable lists)
+ var // Flag to know if list is currently firing
+ firing,
+ // Last fire value (for non-forgettable lists)
memory,
// Flag to know if list was already fired
fired,
- // Flag to know if list is currently firing
- firing,
- // First callback to fire (used internally by add and fireWith)
- firingStart,
// End of the loop when firing
firingLength,
// Index of currently firing callback (modified by remove if needed)
firingIndex,
+ // First callback to fire (used internally by add and fireWith)
+ firingStart,
// Actual callback list
list = [],
// Stack of fire calls for repeatable lists
@@ -983,7 +1114,6 @@ jQuery.Callbacks = function( options ) {
// Remove all callbacks from the list
empty: function() {
list = [];
- firingLength = 0;
return this;
},
// Have the list do nothing anymore
@@ -1174,37 +1304,90 @@ jQuery.extend({
return deferred.promise();
}
});
-jQuery.support = (function( support ) {
- var input = document.createElement("input"),
- fragment = document.createDocumentFragment(),
- div = document.createElement("div"),
- select = document.createElement("select"),
- opt = select.appendChild( document.createElement("option") );
-
- // Finish early in limited environments
- if ( !input.type ) {
- return support;
- }
-
- input.type = "checkbox";
-
- // Check the default checkbox/radio value ("" on old WebKit; "on" elsewhere)
- support.checkOn = input.value === "";
-
- // Must access the parent to make an option select properly
- // Support: IE9, IE10
- support.optSelected = opt.selected;
-
- // jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode
- support.boxModel = document.compatMode === "CSS1Compat";
-
- // Will be defined later
- support.reliableMarginRight = true;
- support.boxSizingReliable = true;
- support.pixelPosition = false;
+jQuery.support = (function() {
+
+ var support, all, a,
+ input, select, fragment,
+ opt, eventName, isSupported, i,
+ div = document.createElement("div");
+
+ // Setup
+ div.setAttribute( "className", "t" );
+ div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
+
+ // Support tests won't run in some limited or non-browser environments
+ all = div.getElementsByTagName("*");
+ a = div.getElementsByTagName("a")[ 0 ];
+ if ( !all || !a || !all.length ) {
+ return {};
+ }
+
+ // First batch of tests
+ select = document.createElement("select");
+ opt = select.appendChild( document.createElement("option") );
+ input = div.getElementsByTagName("input")[ 0 ];
+
+ a.style.cssText = "top:1px;float:left;opacity:.5";
+ support = {
+ // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
+ getSetAttribute: div.className !== "t",
+
+ // IE strips leading whitespace when .innerHTML is used
+ leadingWhitespace: div.firstChild.nodeType === 3,
+
+ // Make sure that tbody elements aren't automatically inserted
+ // IE will insert them into empty tables
+ tbody: !div.getElementsByTagName("tbody").length,
+
+ // Make sure that link elements get serialized correctly by innerHTML
+ // This requires a wrapper element in IE
+ htmlSerialize: !!div.getElementsByTagName("link").length,
+
+ // Get the style information from getAttribute
+ // (IE uses .cssText instead)
+ style: /top/.test( a.getAttribute("style") ),
+
+ // Make sure that URLs aren't manipulated
+ // (IE normalizes it by default)
+ hrefNormalized: a.getAttribute("href") === "/a",
+
+ // Make sure that element opacity exists
+ // (IE uses filter instead)
+ // Use a regex to work around a WebKit issue. See #5145
+ opacity: /^0.5/.test( a.style.opacity ),
+
+ // Verify style float existence
+ // (IE uses styleFloat instead of cssFloat)
+ cssFloat: !!a.style.cssFloat,
+
+ // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere)
+ checkOn: !!input.value,
+
+ // Make sure that a selected-by-default option has a working selected property.
+ // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
+ optSelected: opt.selected,
+
+ // Tests for enctype support on a form (#6743)
+ enctype: !!document.createElement("form").enctype,
+
+ // Makes sure cloning an html5 element does not cause problems
+ // Where outerHTML is undefined, this still works
+ html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav></:nav>",
+
+ // jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode
+ boxModel: document.compatMode === "CSS1Compat",
+
+ // Will be defined later
+ deleteExpando: true,
+ noCloneEvent: true,
+ inlineBlockNeedsLayout: false,
+ shrinkWrapBlocks: false,
+ reliableMarginRight: true,
+ boxSizingReliable: true,
+ pixelPosition: false
+ };
// Make sure checked status is properly cloned
- // Support: IE9, IE10
input.checked = true;
support.noCloneChecked = input.cloneNode( true ).checked;
@@ -1213,25 +1396,55 @@ jQuery.support = (function( support ) {
select.disabled = true;
support.optDisabled = !opt.disabled;
- // Check if an input maintains its value after becoming a radio
- // Support: IE9, IE10, Opera
+ // Support: IE<9
+ try {
+ delete div.test;
+ } catch( e ) {
+ support.deleteExpando = false;
+ }
+
+ // Check if we can trust getAttribute("value")
input = document.createElement("input");
+ input.setAttribute( "value", "" );
+ support.input = input.getAttribute( "value" ) === "";
+
+ // Check if an input maintains its value after becoming a radio
input.value = "t";
- input.type = "radio";
+ input.setAttribute( "type", "radio" );
support.radioValue = input.value === "t";
// #11217 - WebKit loses check when the name is after the checked attribute
input.setAttribute( "checked", "t" );
input.setAttribute( "name", "t" );
+ fragment = document.createDocumentFragment();
fragment.appendChild( input );
- // old WebKit doesn't clone checked state correctly in fragments
+ // Check if a disconnected checkbox will retain its checked
+ // value of true after appended to the DOM (IE6/7)
+ support.appendChecked = input.checked;
+
+ // WebKit doesn't clone checked state correctly in fragments
support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
- // Support: Firefox 17+
- // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)
- support.focusinBubbles = "onfocusin" in window;
+ // Support: IE<9
+ // Opera does not clone events (and typeof div.attachEvent === undefined).
+ // IE9-10 clones events bound via attachEvent, but they don't trigger with .click()
+ if ( div.attachEvent ) {
+ div.attachEvent( "onclick", function() {
+ support.noCloneEvent = false;
+ });
+
+ div.cloneNode( true ).click();
+ }
+
+ // Support: IE<9 (lack submit/change bubble), Firefox 17+ (lack focusin event)
+ // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP), test/csp.php
+ for ( i in { submit: true, change: true, focusin: true }) {
+ div.setAttribute( eventName = "on" + i, "t" );
+
+ support[ i + "Bubbles" ] = eventName in window || div.attributes[ eventName ].expando === false;
+ }
div.style.backgroundClip = "content-box";
div.cloneNode( true ).style.backgroundClip = "";
@@ -1239,9 +1452,9 @@ jQuery.support = (function( support ) {
// Run tests that need a body at doc ready
jQuery(function() {
- var container, marginDiv,
+ var container, marginDiv, tds,
divReset = "padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",
- body = document.getElementsByTagName("body")[ 0 ];
+ body = document.getElementsByTagName("body")[0];
if ( !body ) {
// Return for frameset docs that don't have a body
@@ -1251,13 +1464,32 @@ jQuery.support = (function( support ) {
container = document.createElement("div");
container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px";
- // Check box-sizing and margin behavior
body.appendChild( container ).appendChild( div );
+
+ // Support: IE8
+ // Check if table cells still have offsetWidth/Height when they are set
+ // to display:none and there are still other visible table cells in a
+ // table row; if so, offsetWidth/Height are not reliable for use when
+ // determining if an element has been hidden directly using
+ // display:none (it is still safe to use offsets if a parent element is
+ // hidden; don safety goggles and see bug #4512 for more information).
+ div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
+ tds = div.getElementsByTagName("td");
+ tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none";
+ isSupported = ( tds[ 0 ].offsetHeight === 0 );
+
+ tds[ 0 ].style.display = "";
+ tds[ 1 ].style.display = "none";
+
+ // Support: IE8
+ // Check if empty table cells still have offsetWidth/Height
+ support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
+
+ // Check box-sizing and margin behavior
div.innerHTML = "";
div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;";
-
- support.boxSizing = div.offsetWidth === 4;
- support.doesNotIncludeMarginInBodyOffset = body.offsetTop !== 1;
+ support.boxSizing = ( div.offsetWidth === 4 );
+ support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 );
// Use window.getComputedStyle because jsdom on node.js will break without it.
if ( window.getComputedStyle ) {
@@ -1277,226 +1509,275 @@ jQuery.support = (function( support ) {
!parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );
}
+ if ( typeof div.style.zoom !== core_strundefined ) {
+ // Support: IE<8
+ // Check if natively block-level elements act like inline-block
+ // elements when setting their display to 'inline' and giving
+ // them layout
+ div.innerHTML = "";
+ div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1";
+ support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 );
+
+ // Support: IE6
+ // Check if elements with layout shrink-wrap their children
+ div.style.display = "block";
+ div.innerHTML = "<div></div>";
+ div.firstChild.style.width = "5px";
+ support.shrinkWrapBlocks = ( div.offsetWidth !== 3 );
+
+ if ( support.inlineBlockNeedsLayout ) {
+ // Prevent IE 6 from affecting layout for positioned elements #11048
+ // Prevent IE from shrinking the body in IE 7 mode #12869
+ // Support: IE<8
+ body.style.zoom = 1;
+ }
+ }
+
body.removeChild( container );
+
+ // Null elements to avoid leaks in IE
+ container = div = tds = marginDiv = null;
});
+ // Null elements to avoid leaks in IE
+ all = select = fragment = opt = a = input = null;
+
return support;
-})( {} );
+})();
-/*
- Implementation Summary
-
- 1. Enforce API surface and semantic compatibility with 1.9.x branch
- 2. Improve the module's maintainability by reducing the storage
- paths to a single mechanism.
- 3. Use the same single mechanism to support "private" and "user" data.
- 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
- 5. Avoid exposing implementation details on user objects (eg. expando properties)
- 6. Provide a clear path for implementation upgrade to WeakMap in 2014
-*/
-var data_user, data_priv,
- rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/,
+var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/,
rmultiDash = /([A-Z])/g;
-function Data() {
- this.cache = {};
- this.expando = jQuery.expando + Math.random();
-}
+function internalData( elem, name, data, pvt /* Internal Use Only */ ){
+ if ( !jQuery.acceptData( elem ) ) {
+ return;
+ }
-Data.uid = 1;
+ var thisCache, ret,
+ internalKey = jQuery.expando,
+ getByName = typeof name === "string",
-Data.prototype = {
- key: function( owner ) {
- var descriptor = {},
- // Check if the owner object already has a cache key
- unlock = owner[ this.expando ];
+ // 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 not, create one
- if ( !unlock ) {
- unlock = Data.uid++;
- descriptor[ this.expando ] = { value: unlock };
-
- // Secure it in a non-enumerable, non-writable property
- try {
- Object.defineProperties( owner, descriptor );
+ // 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,
- // Support: Android<4
- // Fallback to a less secure definition
- } catch ( e ) {
- descriptor[ this.expando ] = unlock;
- jQuery.extend( owner, descriptor );
- }
- }
+ // 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[ internalKey ] : elem[ internalKey ] && internalKey;
+
+ // 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 || !cache[id] || (!pvt && !cache[id].data)) && getByName && data === undefined ) {
+ return;
+ }
- // Ensure the cache object
- if ( !this.cache[ unlock ] ) {
- this.cache[ unlock ] = {};
+ 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[ internalKey ] = id = core_deletedIds.pop() || jQuery.guid++;
+ } else {
+ id = internalKey;
}
+ }
- return unlock;
- },
- set: function( owner, data, value ) {
- var prop,
- // There may be an unlock assigned to this node,
- // if there is no entry for this "owner", create one inline
- // and set the unlock as though an owner entry had always existed
- unlock = this.key( owner ),
- cache = this.cache[ unlock ];
+ if ( !cache[ id ] ) {
+ cache[ id ] = {};
- // Handle: [ owner, key, value ] args
- if ( typeof data === "string" ) {
- cache[ data ] = value;
+ // Avoids exposing jQuery metadata on plain JS objects when the object
+ // is serialized using JSON.stringify
+ if ( !isNode ) {
+ cache[ id ].toJSON = jQuery.noop;
+ }
+ }
- // Handle: [ owner, { properties } ] args
+ // 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" || typeof name === "function" ) {
+ if ( pvt ) {
+ cache[ id ] = jQuery.extend( cache[ id ], name );
} else {
- // Support an expectation from the old data system where plain
- // objects used to initialize would be set to the cache by
- // reference, instead of having properties and values copied.
- // Note, this will kill the connection between
- // "this.cache[ unlock ]" and "cache"
- if ( jQuery.isEmptyObject( cache ) ) {
- this.cache[ unlock ] = data;
- // Otherwise, copy the properties one-by-one to the cache object
- } else {
- for ( prop in data ) {
- cache[ prop ] = data[ prop ];
- }
- }
+ cache[ id ].data = jQuery.extend( cache[ id ].data, name );
}
+ }
- return this;
- },
- get: function( owner, key ) {
- // Either a valid cache is found, or will be created.
- // New caches will be created and the unlock returned,
- // allowing direct access to the newly created
- // empty data object.
- var cache = this.cache[ this.key( owner ) ];
-
- return key === undefined ?
- cache : cache[ key ];
- },
- access: function( owner, key, value ) {
- // In cases where either:
- //
- // 1. No key was specified
- // 2. A string key was specified, but no value provided
- //
- // Take the "read" path and allow the get method to determine
- // which value to return, respectively either:
- //
- // 1. The entire cache object
- // 2. The data stored at the key
- //
- if ( key === undefined ||
- ((key && typeof key === "string") && value === undefined) ) {
- return this.get( owner, key );
- }
-
- // [*]When the key is not a string, or both a key and value
- // are specified, set or extend (existing objects) with either:
- //
- // 1. An object of properties
- // 2. A key and value
- //
- this.set( owner, key, value );
-
- // Since the "set" path can have two possible entry points
- // return the expected data based on which path was taken[*]
- return value !== undefined ? value : key;
- },
- remove: function( owner, key ) {
- var i, name,
- unlock = this.key( owner ),
- cache = this.cache[ unlock ];
+ thisCache = cache[ id ];
- if ( key === undefined ) {
- this.cache[ unlock ] = {};
- } else {
- // Support array or space separated string of keys
- if ( jQuery.isArray( key ) ) {
+ // jQuery data() is stored in a separate object inside the object's internal data
+ // cache in order to avoid key collisions between internal data and user-defined
+ // data.
+ if ( !pvt ) {
+ if ( !thisCache.data ) {
+ thisCache.data = {};
+ }
+
+ thisCache = thisCache.data;
+ }
+
+ if ( data !== undefined ) {
+ thisCache[ jQuery.camelCase( name ) ] = data;
+ }
+
+ // Check for both converted-to-camel and non-converted data property names
+ // If a data property was specified
+ if ( getByName ) {
+
+ // First Try to find as-is property data
+ ret = thisCache[ name ];
+
+ // Test for null|undefined property data
+ if ( ret == null ) {
+
+ // Try to find the camelCased property
+ ret = thisCache[ jQuery.camelCase( name ) ];
+ }
+ } else {
+ ret = thisCache;
+ }
+
+ return ret;
+}
+
+function internalRemoveData( elem, name, pvt ) {
+ if ( !jQuery.acceptData( elem ) ) {
+ return;
+ }
+
+ var i, l, thisCache,
+ isNode = elem.nodeType,
+
+ // See jQuery.data for more information
+ cache = isNode ? jQuery.cache : elem,
+ 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 ( name ) {
+
+ thisCache = pvt ? cache[ id ] : cache[ id ].data;
+
+ if ( thisCache ) {
+
+ // Support array or space separated string names for data keys
+ if ( !jQuery.isArray( name ) ) {
+
+ // try the string as a key before any manipulation
+ if ( name in thisCache ) {
+ name = [ name ];
+ } else {
+
+ // split the camel cased version by spaces unless a key with the spaces exists
+ name = jQuery.camelCase( name );
+ if ( name in thisCache ) {
+ name = [ name ];
+ } else {
+ name = name.split(" ");
+ }
+ }
+ } else {
// If "name" is an array of keys...
// When data is initially created, via ("key", "val") signature,
// keys will be converted to camelCase.
// Since there is no way to tell _how_ a key was added, remove
// both plain key and camelCase key. #12786
// This will only penalize the array argument path.
- name = key.concat( key.map( jQuery.camelCase ) );
- } else {
- // Try the string as a key before any manipulation
- if ( key in cache ) {
- name = [ key ];
- } else {
- // If a key with the spaces exists, use it.
- // Otherwise, create an array by matching non-whitespace
- name = jQuery.camelCase( key );
- name = name in cache ?
- [ name ] : ( name.match( core_rnotwhite ) || [] );
- }
+ name = name.concat( jQuery.map( name, jQuery.camelCase ) );
}
- i = name.length;
- while ( i-- ) {
- delete cache[ name[i] ];
+ for ( i = 0, l = name.length; i < l; i++ ) {
+ delete thisCache[ name[i] ];
+ }
+
+ // If there is no data left in the cache, we want to continue
+ // and let the cache object itself get destroyed
+ if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) {
+ return;
}
}
- },
- hasData: function( owner ) {
- return !jQuery.isEmptyObject(
- this.cache[ this.key( owner ) ]
- );
- },
- discard: function( owner ) {
- delete this.cache[ this.key( owner ) ];
}
-};
-// This will be used by remove()/cleanData() in manipulation to sever
-// remaining references to node objects. One day we'll replace the dual
-// arrays with a WeakMap and this won't be an issue.
-// (Splices the data objects out of the internal cache arrays)
-function data_discard( owner ) {
- data_user.discard( owner );
- data_priv.discard( owner );
-}
+ // See jQuery.data for more information
+ if ( !pvt ) {
+ delete cache[ id ].data;
-// These may be used throughout the jQuery core codebase
-data_user = new Data();
-data_priv = new Data();
+ // Don't destroy the parent cache unless the internal data object
+ // had been the only thing left in it
+ if ( !isEmptyDataObject( cache[ id ] ) ) {
+ return;
+ }
+ }
+
+ // Destroy the cache
+ if ( isNode ) {
+ jQuery.cleanData( [ elem ], true );
+ // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
+ } else if ( jQuery.support.deleteExpando || cache != cache.window ) {
+ delete cache[ id ];
+
+ // When all else fails, null
+ } else {
+ cache[ id ] = null;
+ }
+}
jQuery.extend({
- // This is no longer relevant to jQuery core, but must remain
- // supported for the sake of jQuery 1.9.x API surface compatibility.
- acceptData: function() {
- return true;
+ cache: {},
+
+ // Unique for each copy of jQuery on the page
+ // Non-digits removed to match rinlinejQuery
+ expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ),
+
+ // The following elements throw uncatchable exceptions if you
+ // attempt to add expando properties to them.
+ noData: {
+ "embed": true,
+ // Ban all objects except for Flash (which handle expandos)
+ "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
+ "applet": true
},
hasData: function( elem ) {
- return data_user.hasData( elem ) || data_priv.hasData( elem );
+ elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
+ return !!elem && !isEmptyDataObject( elem );
},
data: function( elem, name, data ) {
- return data_user.access( elem, name, data );
+ return internalData( elem, name, data );
},
removeData: function( elem, name ) {
- return data_user.remove( elem, name );
+ return internalRemoveData( elem, name );
},
- // TODO: Replace all calls to _data and _removeData with direct
- // calls to
- //
- // data_priv.access( elem, name, data );
- //
- // data_priv.remove( elem, name );
- //
+ // For internal use only.
_data: function( elem, name, data ) {
- return data_priv.access( elem, name, data );
+ return internalData( elem, name, data, true );
},
_removeData: function( elem, name ) {
- return data_priv.remove( elem, name );
+ return internalRemoveData( elem, name, true );
+ },
+
+ // A method for determining if a DOM node can handle the data expando
+ acceptData: function( elem ) {
+ // Do not set data on non-element because it will not be cleared (#8335).
+ if ( elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9 ) {
+ return false;
+ }
+
+ var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ];
+
+ // nodes accept data unless otherwise specified; rejection can be conditional
+ return !noData || noData !== true && elem.getAttribute("classid") === noData;
}
});
@@ -1510,19 +1791,20 @@ jQuery.fn.extend({
// Gets all values
if ( key === undefined ) {
if ( this.length ) {
- data = data_user.get( elem );
+ data = jQuery.data( elem );
- if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) {
+ if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
attrs = elem.attributes;
for ( ; i < attrs.length; i++ ) {
name = attrs[i].name;
- if ( name.indexOf( "data-" ) === 0 ) {
- name = jQuery.camelCase( name.substring(5) );
+ if ( !name.indexOf( "data-" ) ) {
+ name = jQuery.camelCase( name.slice(5) );
+
dataAttr( elem, name, data[ name ] );
}
}
- data_priv.set( elem, "hasDataAttrs", true );
+ jQuery._data( elem, "parsedAttrs", true );
}
}
@@ -1532,99 +1814,77 @@ jQuery.fn.extend({
// Sets multiple values
if ( typeof key === "object" ) {
return this.each(function() {
- data_user.set( this, key );
+ jQuery.data( this, key );
});
}
return jQuery.access( this, function( value ) {
- var data,
- camelKey = jQuery.camelCase( key );
- // Get the Data...
if ( value === undefined ) {
-
- // Attempt to get data from the cache
- // with the key as-is
- data = data_user.get( elem, key );
- if ( data !== undefined ) {
- return data;
- }
- // Attempt to "discover" the data in
- // HTML5 custom data-* attrs
- data = dataAttr( elem, key, undefined );
- if ( data !== undefined ) {
- return data;
- }
-
- // As a last resort, attempt to find
- // the data by checking AGAIN, but with
- // a camelCased key.
- data = data_user.get( elem, camelKey );
- if ( data !== undefined ) {
- return data;
- }
-
- // We tried really hard, but the data doesn't exist.
- return undefined;
+ // Try to fetch any internally stored data first
+ return elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : null;
}
- // Set the data...
this.each(function() {
- // First, attempt to store a copy or reference of any
- // data that might've been store with a camelCased key.
- var data = data_user.get( this, camelKey );
-
- // For HTML5 data-* attribute interop, we have to
- // store property names with dashes in a camelCase form.
- // This might not apply to all properties...*
- data_user.set( this, camelKey, value );
-
- // *... In the case of properties that might ACTUALLY
- // have dashes, we need to also store a copy of that
- // unchanged property.
- if ( /-/.test( key ) && data !== undefined ) {
- data_user.set( this, key, value );
- }
+ jQuery.data( this, key, value );
});
}, null, value, arguments.length > 1, null, true );
},
removeData: function( key ) {
return this.each(function() {
- data_user.remove( this, key );
+ jQuery.removeData( this, key );
});
}
});
function dataAttr( elem, key, data ) {
- var name;
-
// If nothing was found internally, try to fetch any
// data from the HTML5 data-* attribute
if ( data === undefined && elem.nodeType === 1 ) {
- name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
+ var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
+
data = elem.getAttribute( name );
if ( typeof data === "string" ) {
try {
data = data === "true" ? true :
- data === "false" ? false :
- data === "null" ? null :
- // Only convert to a number if it doesn't change the string
- +data + "" === data ? +data :
- rbrace.test( data ) ?
- JSON.parse( data ) : data;
+ data === "false" ? false :
+ data === "null" ? null :
+ // Only convert to a number if it doesn't change the string
+ +data + "" === data ? +data :
+ rbrace.test( data ) ? jQuery.parseJSON( data ) :
+ data;
} catch( e ) {}
// Make sure we set the data so it isn't changed later
- data_user.set( elem, key, data );
+ jQuery.data( elem, key, data );
+
} else {
data = undefined;
}
}
+
return data;
}
+
+// checks a cache object for emptiness
+function isEmptyDataObject( obj ) {
+ var name;
+ for ( name in obj ) {
+
+ // if the public data object is empty, the private is still empty
+ if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
+ continue;
+ }
+ if ( name !== "toJSON" ) {
+ return false;
+ }
+ }
+
+ return true;
+}
jQuery.extend({
queue: function( elem, type, data ) {
var queue;
@@ -1777,7 +2037,10 @@ var nodeHook, boolHook,
rreturn = /\r/g,
rfocusable = /^(?:input|select|textarea|button|object)$/i,
rclickable = /^(?:a|area)$/i,
- rboolean = /^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i;
+ rboolean = /^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i,
+ ruseDefault = /^(?:checked|selected)$/i,
+ getSetAttribute = jQuery.support.getSetAttribute,
+ getSetInput = jQuery.support.input;
jQuery.fn.extend({
attr: function( name, value ) {
@@ -1937,7 +2200,7 @@ jQuery.fn.extend({
},
val: function( value ) {
- var hooks, ret, isFunction,
+ var ret, hooks, isFunction,
elem = this[0];
if ( !arguments.length ) {
@@ -2061,7 +2324,7 @@ jQuery.extend({
},
attr: function( elem, name, value ) {
- var ret, hooks, notxml,
+ var hooks, notxml, ret,
nType = elem.nodeType;
// don't get/set attributes on text, comment and attribute nodes
@@ -2124,12 +2387,22 @@ jQuery.extend({
propName = jQuery.propFix[ name ] || name;
// Boolean attributes get special treatment (#10870)
- // Set corresponding property to false for boolean attributes
if ( rboolean.test( name ) ) {
- elem[ propName ] = false;
+ // Set corresponding property to false for boolean attributes
+ // Also clear defaultChecked/defaultSelected (if appropriate) for IE<8
+ if ( !getSetAttribute && ruseDefault.test( name ) ) {
+ elem[ jQuery.camelCase( "default-" + name ) ] =
+ elem[ propName ] = false;
+ } else {
+ elem[ propName ] = false;
+ }
+
+ // See #9699 for explanation of this approach (setting first, then removal)
+ } else {
+ jQuery.attr( elem, name, "" );
}
- elem.removeAttribute( name );
+ elem.removeAttribute( getSetAttribute ? name : propName );
}
}
},
@@ -2221,7 +2494,26 @@ jQuery.extend({
// Hook for boolean attributes
boolHook = {
get: function( elem, name ) {
- return elem.getAttribute( name ) !== null ?
+ var
+ // Use .prop to determine if this attribute is understood as boolean
+ prop = jQuery.prop( elem, name ),
+
+ // Fetch it accordingly
+ attr = typeof prop === "boolean" && elem.getAttribute( name ),
+ detail = typeof prop === "boolean" ?
+
+ getSetInput && getSetAttribute ?
+ attr != null :
+ // oldIE fabricates an empty string for missing boolean attributes
+ // and conflates checked/selected into attroperties
+ ruseDefault.test( name ) ?
+ elem[ jQuery.camelCase( "default-" + name ) ] :
+ !!attr :
+
+ // fetch an attribute node for properties not recognized as boolean
+ elem.getAttributeNode( name );
+
+ return detail && detail.value !== false ?
name.toLowerCase() :
undefined;
},
@@ -2229,13 +2521,158 @@ boolHook = {
if ( value === false ) {
// Remove boolean attributes when set to false
jQuery.removeAttr( elem, name );
+ } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
+ // IE<8 needs the *property* name
+ elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );
+
+ // Use defaultChecked and defaultSelected for oldIE
} else {
- elem.setAttribute( name, name );
+ elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
}
+
return name;
}
};
+// fix oldIE value attroperty
+if ( !getSetInput || !getSetAttribute ) {
+ jQuery.attrHooks.value = {
+ get: function( elem, name ) {
+ var ret = elem.getAttributeNode( name );
+ return jQuery.nodeName( elem, "input" ) ?
+
+ // Ignore the value *property* by using defaultValue
+ elem.defaultValue :
+
+ ret && ret.specified ? ret.value : undefined;
+ },
+ set: function( elem, value, name ) {
+ if ( jQuery.nodeName( elem, "input" ) ) {
+ // Does not return so that setAttribute is also used
+ elem.defaultValue = value;
+ } else {
+ // Use nodeHook if defined (#1954); otherwise setAttribute is fine
+ return nodeHook && nodeHook.set( elem, value, name );
+ }
+ }
+ };
+}
+
+// IE6/7 do not support getting/setting some attributes with get/setAttribute
+if ( !getSetAttribute ) {
+
+ // Use this for any attribute in IE6/7
+ // This fixes almost every IE6/7 issue
+ nodeHook = jQuery.valHooks.button = {
+ get: function( elem, name ) {
+ var ret = elem.getAttributeNode( name );
+ return ret && ( name === "id" || name === "name" || name === "coords" ? ret.value !== "" : ret.specified ) ?
+ ret.value :
+ undefined;
+ },
+ set: function( elem, value, name ) {
+ // Set the existing or create a new attribute node
+ var ret = elem.getAttributeNode( name );
+ if ( !ret ) {
+ elem.setAttributeNode(
+ (ret = elem.ownerDocument.createAttribute( name ))
+ );
+ }
+
+ ret.value = value += "";
+
+ // Break association with cloned elements by also using setAttribute (#9646)
+ return name === "value" || value === elem.getAttribute( name ) ?
+ value :
+ undefined;
+ }
+ };
+
+ // Set contenteditable to false on removals(#10429)
+ // Setting to empty string throws an error as an invalid value
+ jQuery.attrHooks.contenteditable = {
+ get: nodeHook.get,
+ set: function( elem, value, name ) {
+ nodeHook.set( elem, value === "" ? false : value, name );
+ }
+ };
+
+ // Set width and height to auto instead of 0 on empty string( Bug #8150 )
+ // This is for removals
+ jQuery.each([ "width", "height" ], function( i, name ) {
+ jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
+ set: function( elem, value ) {
+ if ( value === "" ) {
+ elem.setAttribute( name, "auto" );
+ return value;
+ }
+ }
+ });
+ });
+}
+
+
+// Some attributes require a special call on IE
+// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
+if ( !jQuery.support.hrefNormalized ) {
+ jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
+ jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
+ get: function( elem ) {
+ var ret = elem.getAttribute( name, 2 );
+ return ret == null ? undefined : ret;
+ }
+ });
+ });
+
+ // href/src property should get the full normalized URL (#10299/#12915)
+ jQuery.each([ "href", "src" ], function( i, name ) {
+ jQuery.propHooks[ name ] = {
+ get: function( elem ) {
+ return elem.getAttribute( name, 4 );
+ }
+ };
+ });
+}
+
+if ( !jQuery.support.style ) {
+ jQuery.attrHooks.style = {
+ get: function( elem ) {
+ // Return undefined in the case of empty string
+ // Note: IE uppercases css property names, but if we were to .toLowerCase()
+ // .cssText, that would destroy case senstitivity in URL's, like in "background"
+ return elem.style.cssText || undefined;
+ },
+ set: function( elem, value ) {
+ return ( elem.style.cssText = value + "" );
+ }
+ };
+}
+
+// Safari mis-reports the default selected property of an option
+// Accessing the parent's selectedIndex property fixes it
+if ( !jQuery.support.optSelected ) {
+ jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
+ get: function( elem ) {
+ var parent = elem.parentNode;
+
+ if ( parent ) {
+ parent.selectedIndex;
+
+ // Make sure that it also works with optgroups, see #5701
+ if ( parent.parentNode ) {
+ parent.parentNode.selectedIndex;
+ }
+ }
+ return null;
+ }
+ });
+}
+
+// IE6/7 call enctype encoding
+if ( !jQuery.support.enctype ) {
+ jQuery.propFix.enctype = "encoding";
+}
+
// Radios and checkboxes getter/setter
if ( !jQuery.support.checkOn ) {
jQuery.each([ "radio", "checkbox" ], function() {
@@ -2256,21 +2693,8 @@ jQuery.each([ "radio", "checkbox" ], function() {
}
});
});
-
-// IE9/10 do not see a selected option inside an optgroup unless you access it
-// Support: IE9, IE10
-if ( !jQuery.support.optSelected ) {
- jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
- get: function( elem ) {
- var parent = elem.parentNode;
- if ( parent && parent.parentNode ) {
- parent.parentNode.selectedIndex;
- }
- return null;
- }
- });
-}
-var rkeyEvent = /^key/,
+var rformElems = /^(?:input|select|textarea)$/i,
+ rkeyEvent = /^key/,
rmouseEvent = /^(?:mouse|contextmenu)|click/,
rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
@@ -2292,11 +2716,10 @@ jQuery.event = {
global: {},
add: function( elem, types, handler, data, selector ) {
-
- var handleObjIn, eventHandle, tmp,
- events, t, handleObj,
- special, handlers, type, namespaces, origType,
- elemData = data_priv.get( elem );
+ var tmp, events, t, handleObjIn,
+ special, eventHandle, handleObj,
+ handlers, type, namespaces, origType,
+ elemData = jQuery._data( elem );
// Don't attach events to noData or text/comment nodes (but allow plain objects)
if ( !elemData ) {
@@ -2332,17 +2755,13 @@ jQuery.event = {
}
// Handle multiple events separated by a space
+ // jQuery(...).bind("mouseover mouseout", fn);
types = ( types || "" ).match( core_rnotwhite ) || [""];
t = types.length;
while ( t-- ) {
tmp = rtypenamespace.exec( types[t] ) || [];
type = origType = tmp[1];
namespaces = ( tmp[2] || "" ).split( "." ).sort();
-
- // There *must* be a type, no attaching namespace-only handlers
- if ( !type ) {
- continue;
- }
// If event changes its type, use the special event handlers for the changed type
special = jQuery.event.special[ type ] || {};
@@ -2370,10 +2789,14 @@ jQuery.event = {
handlers = events[ type ] = [];
handlers.delegateCount = 0;
- // Only use addEventListener if the special events handler returns false
+ // Only use addEventListener/attachEvent if the special events handler returns false
if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+ // Bind the global event handler to the element
if ( elem.addEventListener ) {
elem.addEventListener( type, eventHandle, false );
+
+ } else if ( elem.attachEvent ) {
+ elem.attachEvent( "on" + type, eventHandle );
}
}
}
@@ -2403,11 +2826,11 @@ jQuery.event = {
// Detach an event or set of events from an element
remove: function( elem, types, handler, selector, mappedTypes ) {
-
- var j, origCount, tmp,
- events, t, handleObj,
- special, handlers, type, namespaces, origType,
- elemData = data_priv.hasData( elem ) && data_priv.get( elem );
+ var j, handleObj, tmp,
+ origCount, t, events,
+ special, handlers, type,
+ namespaces, origType,
+ elemData = jQuery.hasData( elem ) && jQuery._data( elem );
if ( !elemData || !(events = elemData.events) ) {
return;
@@ -2476,8 +2899,8 @@ jQuery.event = {
},
trigger: function( event, data, elem, onlyHandlers ) {
-
- var i, cur, tmp, bubbleType, ontype, handle, special,
+ var handle, ontype, cur,
+ bubbleType, special, tmp, i,
eventPath = [ elem || document ],
type = core_hasOwn.call( event, "type" ) ? event.type : event,
namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
@@ -2507,8 +2930,7 @@ jQuery.event = {
event :
new jQuery.Event( type, typeof event === "object" && event );
- // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
- event.isTrigger = onlyHandlers ? 2 : 3;
+ event.isTrigger = true;
event.namespace = namespaces.join(".");
event.namespace_re = event.namespace ?
new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
@@ -2579,8 +3001,9 @@ jQuery.event = {
!(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
// Call a native DOM method on the target with the same name name as the event.
+ // Can't use an .isFunction() check here because IE6/7 fails that test.
// Don't do default actions on window, that's where global variables be (#6170)
- if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
+ if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {
// Don't re-trigger an onFOO event when we call its FOO() method
tmp = elem[ ontype ];
@@ -2591,7 +3014,12 @@ jQuery.event = {
// Prevent re-triggering of the same event, since we already bubbled it above
jQuery.event.triggered = type;
- elem[ type ]();
+ try {
+ elem[ type ]();
+ } catch ( e ) {
+ // IE<9 dies on focus/blur to hidden element (#1486,#12518)
+ // only reproducible on winXP IE8 native, not IE9 in IE8 mode
+ }
jQuery.event.triggered = undefined;
if ( tmp ) {
@@ -2609,7 +3037,7 @@ jQuery.event = {
// Make a writable jQuery.Event from the native event object
event = jQuery.event.fix( event );
- var i, j, ret, matched, handleObj,
+ var i, ret, handleObj, matched, j,
handlerQueue = [],
args = core_slice.call( arguments ),
handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [],
@@ -2664,7 +3092,7 @@ jQuery.event = {
},
handlers: function( event, handlers ) {
- var i, matches, sel, handleObj,
+ var sel, handleObj, matches, i,
handlerQueue = [],
delegateCount = handlers.delegateCount,
cur = event.target;
@@ -2676,8 +3104,9 @@ jQuery.event = {
for ( ; cur != this; cur = cur.parentNode || this ) {
+ // Don't check non-elements (#13208)
// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
- if ( cur.disabled !== true || event.type !== "click" ) {
+ if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) {
matches = [];
for ( i = 0; i < delegateCount; i++ ) {
handleObj = handlers[ i ];
@@ -2709,6 +3138,52 @@ jQuery.event = {
return handlerQueue;
},
+ fix: function( event ) {
+ if ( event[ jQuery.expando ] ) {
+ return event;
+ }
+
+ // Create a writable copy of the event object and normalize some properties
+ var i, prop, copy,
+ type = event.type,
+ originalEvent = event,
+ fixHook = this.fixHooks[ type ];
+
+ if ( !fixHook ) {
+ this.fixHooks[ type ] = fixHook =
+ rmouseEvent.test( type ) ? this.mouseHooks :
+ rkeyEvent.test( type ) ? this.keyHooks :
+ {};
+ }
+ copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
+
+ event = new jQuery.Event( originalEvent );
+
+ i = copy.length;
+ while ( i-- ) {
+ prop = copy[ i ];
+ event[ prop ] = originalEvent[ prop ];
+ }
+
+ // Support: IE<9
+ // Fix target property (#1925)
+ if ( !event.target ) {
+ event.target = originalEvent.srcElement || document;
+ }
+
+ // Support: Chrome 23+, Safari?
+ // Target should not be a text node (#504, #13143)
+ if ( event.target.nodeType === 3 ) {
+ event.target = event.target.parentNode;
+ }
+
+ // Support: IE<9
+ // For mouse/key events, metaKey==false if it's undefined (#3368, #11328)
+ event.metaKey = !!event.metaKey;
+
+ return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
+ },
+
// Includes some event props shared by KeyEvent and MouseEvent
props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
@@ -2728,10 +3203,11 @@ jQuery.event = {
},
mouseHooks: {
- props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
+ props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
filter: function( event, original ) {
- var eventDoc, doc, body,
- button = original.button;
+ var body, eventDoc, doc,
+ button = original.button,
+ fromElement = original.fromElement;
// Calculate pageX/Y if missing and clientX/Y available
if ( event.pageX == null && original.clientX != null ) {
@@ -2743,6 +3219,11 @@ jQuery.event = {
event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );
}
+ // Add relatedTarget, if necessary
+ if ( !event.relatedTarget && fromElement ) {
+ event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
+ }
+
// Add which for click: 1 === left; 2 === middle; 3 === right
// Note: button is not normalized, so don't use it
if ( !event.which && button !== undefined ) {
@@ -2753,42 +3234,6 @@ jQuery.event = {
}
},
- fix: function( event ) {
- if ( event[ jQuery.expando ] ) {
- return event;
- }
-
- // Create a writable copy of the event object and normalize some properties
- var i, prop, copy,
- type = event.type,
- originalEvent = event,
- fixHook = this.fixHooks[ type ];
-
- if ( !fixHook ) {
- this.fixHooks[ type ] = fixHook =
- rmouseEvent.test( type ) ? this.mouseHooks :
- rkeyEvent.test( type ) ? this.keyHooks :
- {};
- }
- copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
-
- event = new jQuery.Event( originalEvent );
-
- i = copy.length;
- while ( i-- ) {
- prop = copy[ i ];
- event[ prop ] = originalEvent[ prop ];
- }
-
- // Support: Chrome 23+, Safari?
- // Target should not be a text node (#504, #13143)
- if ( event.target.nodeType === 3 ) {
- event.target = event.target.parentNode;
- }
-
- return fixHook.filter? fixHook.filter( event, originalEvent ) : event;
- },
-
special: {
load: {
// Prevent triggered image.load events from bubbling to window.load
@@ -2797,7 +3242,7 @@ jQuery.event = {
click: {
// For checkbox, fire native event so checked state will be right
trigger: function() {
- if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) {
+ if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) {
this.click();
return false;
}
@@ -2807,8 +3252,14 @@ jQuery.event = {
// Fire native event if possible so blur/focus sequence is correct
trigger: function() {
if ( this !== document.activeElement && this.focus ) {
- this.focus();
- return false;
+ try {
+ this.focus();
+ return false;
+ } catch ( e ) {
+ // Support: IE<9
+ // If we error on focus to hidden element (#1486, #12518),
+ // let .trigger() run the handlers
+ }
}
},
delegateType: "focusin"
@@ -2826,7 +3277,7 @@ jQuery.event = {
beforeunload: {
postDispatch: function( event ) {
- // Support: Firefox 10+
+ // Even when returnValue equals to undefined Firefox will still show alert
if ( event.result !== undefined ) {
event.originalEvent.returnValue = event.result;
}
@@ -2841,8 +3292,7 @@ jQuery.event = {
var e = jQuery.extend(
new jQuery.Event(),
event,
- {
- type: type,
+ { type: type,
isSimulated: true,
originalEvent: {}
}
@@ -2858,11 +3308,26 @@ jQuery.event = {
}
};
-jQuery.removeEvent = function( elem, type, handle ) {
- if ( elem.removeEventListener ) {
- elem.removeEventListener( type, handle, false );
- }
-};
+jQuery.removeEvent = document.removeEventListener ?
+ function( elem, type, handle ) {
+ if ( elem.removeEventListener ) {
+ elem.removeEventListener( type, handle, false );
+ }
+ } :
+ function( elem, type, handle ) {
+ var name = "on" + type;
+
+ if ( elem.detachEvent ) {
+
+ // #8545, #7054, preventing memory leaks for custom events in IE6-8
+ // detachEvent needed property on element, by name of that event, to properly expose it to GC
+ if ( typeof elem[ name ] === core_strundefined ) {
+ elem[ name ] = null;
+ }
+
+ elem.detachEvent( name, handle );
+ }
+ };
jQuery.Event = function( src, props ) {
// Allow instantiation without the 'new' keyword
@@ -2877,7 +3342,7 @@ jQuery.Event = function( src, props ) {
// 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 ||
+ this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||
src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;
// Event type
@@ -2908,19 +3373,35 @@ jQuery.Event.prototype = {
var e = this.originalEvent;
this.isDefaultPrevented = returnTrue;
+ if ( !e ) {
+ return;
+ }
- if ( e && e.preventDefault ) {
+ // If preventDefault exists, run it on the original event
+ if ( e.preventDefault ) {
e.preventDefault();
+
+ // Support: IE
+ // Otherwise set the returnValue property of the original event to false
+ } else {
+ e.returnValue = false;
}
},
stopPropagation: function() {
var e = this.originalEvent;
this.isPropagationStopped = returnTrue;
-
- if ( e && e.stopPropagation ) {
+ if ( !e ) {
+ return;
+ }
+ // If stopPropagation exists, run it on the original event
+ if ( e.stopPropagation ) {
e.stopPropagation();
}
+
+ // Support: IE
+ // Set the cancelBubble property of the original event to true
+ e.cancelBubble = true;
},
stopImmediatePropagation: function() {
this.isImmediatePropagationStopped = returnTrue;
@@ -2929,7 +3410,6 @@ jQuery.Event.prototype = {
};
// Create mouseenter/leave events using mouseover/out and event-time checks
-// Support: Chrome 15+
jQuery.each({
mouseenter: "mouseover",
mouseleave: "mouseout"
@@ -2956,8 +3436,113 @@ jQuery.each({
};
});
+// IE submit delegation
+if ( !jQuery.support.submitBubbles ) {
+
+ jQuery.event.special.submit = {
+ setup: function() {
+ // Only need this for delegated form submit events
+ if ( jQuery.nodeName( this, "form" ) ) {
+ return false;
+ }
+
+ // Lazy-add a submit handler when a descendant form may potentially be submitted
+ jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
+ // Node name check avoids a VML-related crash in IE (#9807)
+ var elem = e.target,
+ form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;
+ if ( form && !jQuery._data( form, "submitBubbles" ) ) {
+ jQuery.event.add( form, "submit._submit", function( event ) {
+ event._submit_bubble = true;
+ });
+ jQuery._data( form, "submitBubbles", true );
+ }
+ });
+ // return undefined since we don't need an event listener
+ },
+
+ postDispatch: function( event ) {
+ // If form was submitted by the user, bubble the event up the tree
+ if ( event._submit_bubble ) {
+ delete event._submit_bubble;
+ if ( this.parentNode && !event.isTrigger ) {
+ jQuery.event.simulate( "submit", this.parentNode, event, true );
+ }
+ }
+ },
+
+ teardown: function() {
+ // Only need this for delegated form submit events
+ if ( jQuery.nodeName( this, "form" ) ) {
+ return false;
+ }
+
+ // Remove delegated handlers; cleanData eventually reaps submit handlers attached above
+ jQuery.event.remove( this, "._submit" );
+ }
+ };
+}
+
+// IE change delegation and checkbox/radio fix
+if ( !jQuery.support.changeBubbles ) {
+
+ jQuery.event.special.change = {
+
+ setup: function() {
+
+ if ( rformElems.test( this.nodeName ) ) {
+ // IE doesn't fire change on a check/radio until blur; trigger it on click
+ // after a propertychange. Eat the blur-change in special.change.handle.
+ // This still fires onchange a second time for check/radio after blur.
+ if ( this.type === "checkbox" || this.type === "radio" ) {
+ jQuery.event.add( this, "propertychange._change", function( event ) {
+ if ( event.originalEvent.propertyName === "checked" ) {
+ this._just_changed = true;
+ }
+ });
+ jQuery.event.add( this, "click._change", function( event ) {
+ if ( this._just_changed && !event.isTrigger ) {
+ this._just_changed = false;
+ }
+ // Allow triggered, simulated change events (#11500)
+ jQuery.event.simulate( "change", this, event, true );
+ });
+ }
+ return false;
+ }
+ // Delegated event; lazy-add a change handler on descendant inputs
+ jQuery.event.add( this, "beforeactivate._change", function( e ) {
+ var elem = e.target;
+
+ if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) {
+ jQuery.event.add( elem, "change._change", function( event ) {
+ if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
+ jQuery.event.simulate( "change", this.parentNode, event, true );
+ }
+ });
+ jQuery._data( elem, "changeBubbles", true );
+ }
+ });
+ },
+
+ handle: function( event ) {
+ var elem = event.target;
+
+ // Swallow native change events from checkbox/radio, we already triggered them above
+ if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
+ return event.handleObj.handler.apply( this, arguments );
+ }
+ },
+
+ teardown: function() {
+ jQuery.event.remove( this, "._change" );
+
+ return !rformElems.test( this.nodeName );
+ }
+ };
+}
+
// Create "bubbling" focus and blur events
-// Support: Firefox 10+
if ( !jQuery.support.focusinBubbles ) {
jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
@@ -2985,7 +3570,7 @@ if ( !jQuery.support.focusinBubbles ) {
jQuery.fn.extend({
on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
- var origFn, type;
+ var type, origFn;
// Types can be a map of types/handlers
if ( typeof types === "object" ) {
@@ -3101,7 +3686,7 @@ jQuery.fn.extend({
});
/*!
* Sizzle CSS Selector Engine
- * Copyright 2013 jQuery Foundation and other contributors
+ * Copyright 2012 jQuery Foundation and other contributors
* Released under the MIT license
* http://sizzlejs.com/
*/
@@ -3113,9 +3698,8 @@ var i,
getText,
isXML,
compile,
+ hasDuplicate,
outermostContext,
- recompare,
- sortInput,
// Local document vars
setDocument,
@@ -3126,6 +3710,7 @@ var i,
rbuggyMatches,
matches,
contains,
+ sortOrder,
// Instance-specific data
expando = "sizzle" + -(new Date()),
@@ -3136,8 +3721,6 @@ var i,
classCache = createCache(),
tokenCache = createCache(),
compilerCache = createCache(),
- hasDuplicate = false,
- sortOrder = function() { return 0; },
// General-purpose constants
strundefined = typeof undefined,
@@ -3146,7 +3729,6 @@ var i,
// Array methods
arr = [],
pop = arr.pop,
- push_native = arr.push,
push = arr.push,
slice = arr.slice,
// Use a stripped-down indexOf if we can't use a native one
@@ -3238,32 +3820,17 @@ var i,
String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
};
-// Optimize for push.apply( _, NodeList )
+// Use a stripped-down slice if we can't use a native one
try {
- push.apply(
- (arr = slice.call( preferredDoc.childNodes )),
- preferredDoc.childNodes
- );
- // Support: Android<4.0
- // Detect silently failing push.apply
- arr[ preferredDoc.childNodes.length ].nodeType;
+ slice.call( preferredDoc.documentElement.childNodes, 0 )[0].nodeType;
} catch ( e ) {
- push = { apply: arr.length ?
-
- // Leverage slice if possible
- function( target, els ) {
- push_native.apply( target, slice.call(els) );
- } :
-
- // Support: IE<9
- // Otherwise append directly
- function( target, els ) {
- var j = target.length,
- i = 0;
- // Can't trust NodeList.length
- while ( (target[j++] = els[i++]) ) {}
- target.length = j - 1;
+ slice = function( i ) {
+ var elem,
+ results = [];
+ while ( (elem = this[i++]) ) {
+ results.push( elem );
}
+ return results;
};
}
@@ -3312,7 +3879,7 @@ function assert( fn ) {
var div = document.createElement("div");
try {
- return !!fn( div );
+ return fn( div );
} catch (e) {
return false;
} finally {
@@ -3372,12 +3939,12 @@ function Sizzle( selector, context, results, seed ) {
// Speed-up: Sizzle("TAG")
} else if ( match[2] ) {
- push.apply( results, context.getElementsByTagName( selector ) );
+ push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) );
return results;
// Speed-up: Sizzle(".CLASS")
} else if ( (m = match[3]) && support.getByClassName && context.getElementsByClassName ) {
- push.apply( results, context.getElementsByClassName( m ) );
+ push.apply( results, slice.call(context.getElementsByClassName( m ), 0) );
return results;
}
}
@@ -3413,9 +3980,9 @@ function Sizzle( selector, context, results, seed ) {
if ( newSelector ) {
try {
- push.apply( results,
- newContext.querySelectorAll( newSelector )
- );
+ push.apply( results, slice.call( newContext.querySelectorAll(
+ newSelector
+ ), 0 ) );
return results;
} catch(qsaError) {
} finally {
@@ -3489,17 +4056,13 @@ setDocument = Sizzle.setDocument = function( node ) {
return div.getElementsByClassName("e").length === 2;
});
+ // Check if getElementById returns elements by name
// Check if getElementsByName privileges form controls or returns elements by ID
- // If so, assume (for broader support) that getElementById returns elements by name
support.getByName = assert(function( div ) {
// Inject content
div.id = expando + 0;
- // Support: Windows 8 Native Apps
- // Assigning innerHTML with "name" attributes throws uncatchable exceptions
- // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx
- div.appendChild( document.createElement("a") ).setAttribute( "name", expando );
- div.appendChild( document.createElement("i") ).setAttribute( "name", expando );
- docElem.appendChild( div );
+ div.innerHTML = "<a name='" + expando + "'></a><div name='" + expando + "'></div>";
+ docElem.insertBefore( div, docElem.firstChild );
// Test
var pass = doc.getElementsByName &&
@@ -3507,6 +4070,7 @@ setDocument = Sizzle.setDocument = function( node ) {
doc.getElementsByName( expando ).length === 2 +
// buggy browsers will return more than the correct 0
doc.getElementsByName( expando + 0 ).length;
+ support.getIdNotName = !doc.getElementById( expando );
// Cleanup
docElem.removeChild( div );
@@ -3514,14 +4078,6 @@ setDocument = Sizzle.setDocument = function( node ) {
return pass;
});
- // Support: Webkit<537.32
- // Detached nodes confoundingly follow *each other*
- support.sortDetached = assert(function( div1 ) {
- return div1.compareDocumentPosition &&
- // Should return 1, but Webkit returns 4 (following)
- (div1.compareDocumentPosition( document.createElement("div") ) & 1);
- });
-
// IE6/7 return modified attributes
Expr.attrHandle = assert(function( div ) {
div.innerHTML = "<a href='#'></a>";
@@ -3539,7 +4095,7 @@ setDocument = Sizzle.setDocument = function( node ) {
};
// ID find and filter
- if ( support.getByName ) {
+ if ( support.getIdNotName ) {
Expr.find["ID"] = function( id, context ) {
if ( typeof context.getElementById !== strundefined && !documentIsXML ) {
var m = context.getElementById( id );
@@ -3689,7 +4245,7 @@ setDocument = Sizzle.setDocument = function( node ) {
}
rbuggyQSA = new RegExp( rbuggyQSA.join("|") );
- rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
+ rbuggyMatches = new RegExp( rbuggyMatches.join("|") );
// Element contains another
// Purposefully does not implement inclusive descendent
@@ -3718,38 +4274,26 @@ setDocument = Sizzle.setDocument = function( node ) {
// Document order sorting
sortOrder = docElem.compareDocumentPosition ?
function( a, b ) {
+ var compare;
- // Flag for duplicate removal
if ( a === b ) {
hasDuplicate = true;
return 0;
}
- var compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b );
-
- if ( compare ) {
- // Disconnected nodes
- if ( compare & 1 ||
- (recompare && b.compareDocumentPosition( a ) === compare) ) {
-
- // Choose the first element that is related to our preferred document
- if ( a === doc || contains(preferredDoc, a) ) {
+ if ( (compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b )) ) {
+ if ( compare & 1 || a.parentNode && a.parentNode.nodeType === 11 ) {
+ if ( a === doc || contains( preferredDoc, a ) ) {
return -1;
}
- if ( b === doc || contains(preferredDoc, b) ) {
+ if ( b === doc || contains( preferredDoc, b ) ) {
return 1;
}
-
- // Maintain original order
- return sortInput ?
- ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
- 0;
+ return 0;
}
-
return compare & 4 ? -1 : 1;
}
- // Not directly comparable, sort on existence of method
return a.compareDocumentPosition ? -1 : 1;
} :
function( a, b ) {
@@ -3803,6 +4347,12 @@ setDocument = Sizzle.setDocument = function( node ) {
0;
};
+ // Always assume the presence of duplicates if sort doesn't
+ // pass them to our comparison function (as in Google Chrome).
+ hasDuplicate = false;
+ [0, 0].sort( sortOrder );
+ support.detectDuplicates = hasDuplicate;
+
return document;
};
@@ -3875,19 +4425,16 @@ Sizzle.error = function( msg ) {
Sizzle.uniqueSort = function( results ) {
var elem,
duplicates = [],
- j = 0,
- i = 0;
+ i = 1,
+ j = 0;
// Unless we *know* we can detect duplicates, assume their presence
hasDuplicate = !support.detectDuplicates;
- // Compensate for sort limitations
- recompare = !support.sortDetached;
- sortInput = !support.sortStable && results.slice( 0 );
results.sort( sortOrder );
if ( hasDuplicate ) {
- while ( (elem = results[i++]) ) {
- if ( elem === results[ i ] ) {
+ for ( ; (elem = results[i]); i++ ) {
+ if ( elem === results[ i - 1 ] ) {
j = duplicates.push( i );
}
}
@@ -3899,12 +4446,6 @@ Sizzle.uniqueSort = function( results ) {
return results;
};
-/**
- * Checks document order of two siblings
- * @param {Element} a
- * @param {Element} b
- * @returns Returns -1 if a precedes b, 1 if a follows b
- */
function siblingCheck( a, b ) {
var cur = b && a,
diff = cur && ( ~b.sourceIndex || MAX_NEGATIVE ) - ( ~a.sourceIndex || MAX_NEGATIVE );
@@ -4928,7 +5469,7 @@ function select( selector, context, results, seed ) {
context.nodeType === 9 && !documentIsXML &&
Expr.relative[ tokens[1].type ] ) {
- context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
+ context = Expr.find["ID"]( token.matches[0].replace( runescape, funescape ), context )[0];
if ( !context ) {
return results;
}
@@ -4956,7 +5497,7 @@ function select( selector, context, results, seed ) {
tokens.splice( i, 1 );
selector = seed.length && toSelector( tokens );
if ( !selector ) {
- push.apply( results, seed );
+ push.apply( results, slice.call( seed, 0 ) );
return results;
}
@@ -4984,20 +5525,12 @@ Expr.pseudos["nth"] = Expr.pseudos["eq"];
// Easy API for creating new setFilters
function setFilters() {}
-setFilters.prototype = Expr.filters = Expr.pseudos;
+Expr.filters = setFilters.prototype = Expr.pseudos;
Expr.setFilters = new setFilters();
-// Check sort stability
-support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
-
// Initialize with the default document
setDocument();
-// Always assume the presence of duplicates if sort doesn't
-// pass them to our comparison function (as in Google Chrome).
-[0, 0].sort( sortOrder );
-support.detectDuplicates = hasDuplicate;
-
// Override sizzle attribute retrieval
Sizzle.attr = jQuery.attr;
jQuery.find = Sizzle;
@@ -5024,13 +5557,13 @@ var runtil = /Until$/,
jQuery.fn.extend({
find: function( selector ) {
- var self, matched, i,
- l = this.length;
+ var i, ret, self,
+ len = this.length;
if ( typeof selector !== "string" ) {
self = this;
return this.pushStack( jQuery( selector ).filter(function() {
- for ( i = 0; i < l; i++ ) {
+ for ( i = 0; i < len; i++ ) {
if ( jQuery.contains( self[ i ], this ) ) {
return true;
}
@@ -5038,24 +5571,24 @@ jQuery.fn.extend({
}) );
}
- matched = [];
- for ( i = 0; i < l; i++ ) {
- jQuery.find( selector, this[ i ], matched );
+ ret = [];
+ for ( i = 0; i < len; i++ ) {
+ jQuery.find( selector, this[ i ], ret );
}
// Needed because $( selector, context ) becomes $( context ).find( selector )
- matched = this.pushStack( l > 1 ? jQuery.unique( matched ) : matched );
- matched.selector = ( this.selector ? this.selector + " " : "" ) + selector;
- return matched;
+ ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
+ ret.selector = ( this.selector ? this.selector + " " : "" ) + selector;
+ return ret;
},
has: function( target ) {
- var targets = jQuery( target, this ),
- l = targets.length;
+ var i,
+ targets = jQuery( target, this ),
+ len = targets.length;
return this.filter(function() {
- var i = 0;
- for ( ; i < l; i++ ) {
+ for ( i = 0; i < len; i++ ) {
if ( jQuery.contains( this, targets[i] ) ) {
return true;
}
@@ -5077,7 +5610,7 @@ jQuery.fn.extend({
// If this is a positional/relative selector, check membership in the returned set
// so $("p:first").is("p:last") won't return true for a doc with two "p".
rneedsContext.test( selector ) ?
- jQuery( selector, this.context ).index( this[ 0 ] ) >= 0 :
+ jQuery( selector, this.context ).index( this[0] ) >= 0 :
jQuery.filter( selector, this ).length > 0 :
this.filter( selector ).length > 0 );
},
@@ -5086,28 +5619,24 @@ jQuery.fn.extend({
var cur,
i = 0,
l = this.length,
- matched = [],
- pos = ( rneedsContext.test( selectors ) || typeof selectors !== "string" ) ?
+ ret = [],
+ pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
jQuery( selectors, context || this.context ) :
0;
for ( ; i < l; i++ ) {
- for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
- // Always skip document fragments
- if ( cur.nodeType < 11 && (pos ?
- pos.index(cur) > -1 :
-
- // Don't pass non-elements to Sizzle
- cur.nodeType === 1 &&
- jQuery.find.matchesSelector(cur, selectors)) ) {
+ cur = this[i];
- cur = matched.push( cur );
+ while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) {
+ if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
+ ret.push( cur );
break;
}
+ cur = cur.parentNode;
}
}
- return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
+ return this.pushStack( ret.length > 1 ? jQuery.unique( ret ) : ret );
},
// Determine the position of an element within
@@ -5116,20 +5645,18 @@ jQuery.fn.extend({
// No argument, return index in parent
if ( !elem ) {
- return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
+ return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;
}
// index in selector
if ( typeof elem === "string" ) {
- return core_indexOf.call( jQuery( elem ), this[ 0 ] );
+ return jQuery.inArray( this[0], jQuery( elem ) );
}
// Locate the position of the desired element
- return core_indexOf.call( this,
-
+ return jQuery.inArray(
// If it receives a jQuery object, the first element is used
- elem.jquery ? elem[ 0 ] : elem
- );
+ elem.jquery ? elem[0] : elem, this );
},
add: function( selector, context ) {
@@ -5148,8 +5675,12 @@ jQuery.fn.extend({
}
});
+jQuery.fn.andSelf = jQuery.fn.addBack;
+
function sibling( cur, dir ) {
- while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {}
+ do {
+ cur = cur[ dir ];
+ } while ( cur && cur.nodeType !== 1 );
return cur;
}
@@ -5196,27 +5727,23 @@ jQuery.each({
}
}, function( name, fn ) {
jQuery.fn[ name ] = function( until, selector ) {
- var matched = jQuery.map( this, fn, until );
+ var ret = jQuery.map( this, fn, until );
if ( !runtil.test( name ) ) {
selector = until;
}
if ( selector && typeof selector === "string" ) {
- matched = jQuery.filter( selector, matched );
+ ret = jQuery.filter( selector, ret );
}
- if ( this.length > 1 ) {
- if ( !guaranteedUnique[ name ] ) {
- jQuery.unique( matched );
- }
+ ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
- if ( rparentsprev.test( name ) ) {
- matched.reverse();
- }
+ if ( this.length > 1 && rparentsprev.test( name ) ) {
+ ret = ret.reverse();
}
- return this.pushStack( matched );
+ return this.pushStack( ret );
};
});
@@ -5227,35 +5754,33 @@ jQuery.extend({
}
return elems.length === 1 ?
- jQuery.find.matchesSelector( elems[ 0 ], expr ) ? [ elems[ 0 ] ] : [] :
- jQuery.find.matches( expr, elems );
+ jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
+ jQuery.find.matches(expr, elems);
},
dir: function( elem, dir, until ) {
var matched = [],
- truncate = until !== undefined;
+ cur = elem[ dir ];
- while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) {
- if ( elem.nodeType === 1 ) {
- if ( truncate && jQuery( elem ).is( until ) ) {
- break;
- }
- matched.push( elem );
+ while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
+ if ( cur.nodeType === 1 ) {
+ matched.push( cur );
}
+ cur = cur[dir];
}
return matched;
},
sibling: function( n, elem ) {
- var matched = [];
+ var r = [];
for ( ; n; n = n.nextSibling ) {
if ( n.nodeType === 1 && n !== elem ) {
- matched.push( n );
+ r.push( n );
}
}
- return matched;
+ return r;
}
});
@@ -5266,39 +5791,55 @@ function winnow( elements, qualifier, keep ) {
// Set to 0 to skip string check
qualifier = qualifier || 0;
- var filtered;
-
if ( jQuery.isFunction( qualifier ) ) {
return jQuery.grep(elements, function( elem, i ) {
var retVal = !!qualifier.call( elem, i, elem );
return retVal === keep;
});
- }
- if ( qualifier.nodeType ) {
+ } else if ( qualifier.nodeType ) {
return jQuery.grep(elements, function( elem ) {
return ( elem === qualifier ) === keep;
});
- }
- if ( typeof qualifier === "string" ) {
- filtered = jQuery.grep(elements, function( elem ) {
+ } else if ( typeof qualifier === "string" ) {
+ var filtered = jQuery.grep(elements, function( elem ) {
return elem.nodeType === 1;
});
if ( isSimple.test( qualifier ) ) {
- return jQuery.filter( qualifier, filtered, !keep );
+ return jQuery.filter(qualifier, filtered, !keep);
+ } else {
+ qualifier = jQuery.filter( qualifier, filtered );
}
-
- qualifier = jQuery.filter( qualifier, filtered );
}
return jQuery.grep(elements, function( elem ) {
- return ( core_indexOf.call( qualifier, elem ) >= 0 ) === keep;
+ return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep;
});
}
-var rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
+function createSafeFragment( document ) {
+ var list = nodeNames.split( "|" ),
+ safeFrag = document.createDocumentFragment();
+
+ if ( safeFrag.createElement ) {
+ while ( list.length ) {
+ safeFrag.createElement(
+ list.pop()
+ );
+ }
+ }
+ return safeFrag;
+}
+
+var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" +
+ "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
+ rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
+ rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"),
+ rleadingWhitespace = /^\s+/,
+ rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
rtagName = /<([\w:]+)/,
+ rtbody = /<tbody/i,
rhtml = /<|&#?\w+;/,
rnoInnerhtml = /<(?:script|style|link)/i,
manipulation_rcheckableType = /^(?:checkbox|radio)$/i,
@@ -5310,21 +5851,24 @@ var rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>
// We have to close these tags to support XHTML (#13200)
wrapMap = {
-
- // Support: IE 9
option: [ 1, "<select multiple='multiple'>", "</select>" ],
-
+ legend: [ 1, "<fieldset>", "</fieldset>" ],
+ area: [ 1, "<map>", "</map>" ],
+ param: [ 1, "<object>", "</object>" ],
thead: [ 1, "<table>", "</table>" ],
tr: [ 2, "<table><tbody>", "</tbody></table>" ],
+ col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
- _default: [ 0, "", "" ]
- };
+ // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
+ // unless wrapped in a div with non-breaking characters in front of it.
+ _default: jQuery.support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X<div>", "</div>" ]
+ },
+ safeFragment = createSafeFragment( document ),
+ fragmentDiv = safeFragment.appendChild( document.createElement("div") );
-// Support: IE 9
wrapMap.optgroup = wrapMap.option;
-
-wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.col = wrapMap.thead;
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
wrapMap.th = wrapMap.td;
jQuery.fn.extend({
@@ -5332,33 +5876,30 @@ jQuery.fn.extend({
return jQuery.access( this, function( value ) {
return value === undefined ?
jQuery.text( this ) :
- this.empty().append( ( this[ 0 ] && this[ 0 ].ownerDocument || document ).createTextNode( value ) );
+ this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );
}, null, value, arguments.length );
},
wrapAll: function( html ) {
- var wrap;
-
if ( jQuery.isFunction( html ) ) {
- return this.each(function( i ) {
- jQuery( this ).wrapAll( html.call(this, i) );
+ return this.each(function(i) {
+ jQuery(this).wrapAll( html.call(this, i) );
});
}
- if ( this[ 0 ] ) {
-
+ if ( this[0] ) {
// The elements to wrap the target around
- wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
+ var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
- if ( this[ 0 ].parentNode ) {
- wrap.insertBefore( this[ 0 ] );
+ if ( this[0].parentNode ) {
+ wrap.insertBefore( this[0] );
}
wrap.map(function() {
var elem = this;
- while ( elem.firstElementChild ) {
- elem = elem.firstElementChild;
+ while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
+ elem = elem.firstChild;
}
return elem;
@@ -5370,8 +5911,8 @@ jQuery.fn.extend({
wrapInner: function( html ) {
if ( jQuery.isFunction( html ) ) {
- return this.each(function( i ) {
- jQuery( this ).wrapInner( html.call(this, i) );
+ return this.each(function(i) {
+ jQuery(this).wrapInner( html.call(this, i) );
});
}
@@ -5391,7 +5932,7 @@ jQuery.fn.extend({
wrap: function( html ) {
var isFunction = jQuery.isFunction( html );
- return this.each(function( i ) {
+ return this.each(function(i) {
jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
});
},
@@ -5421,7 +5962,7 @@ jQuery.fn.extend({
},
before: function() {
- return this.domManip(arguments, false, function( elem ) {
+ return this.domManip( arguments, false, function( elem ) {
if ( this.parentNode ) {
this.parentNode.insertBefore( elem, this );
}
@@ -5429,7 +5970,7 @@ jQuery.fn.extend({
},
after: function() {
- return this.domManip(arguments, false, function( elem ) {
+ return this.domManip( arguments, false, function( elem ) {
if ( this.parentNode ) {
this.parentNode.insertBefore( elem, this.nextSibling );
}
@@ -5439,12 +5980,9 @@ jQuery.fn.extend({
// keepData is for internal use only--do not document
remove: function( selector, keepData ) {
var elem,
- i = 0,
- l = this.length;
-
- for ( ; i < l; i++ ) {
- elem = this[ i ];
+ i = 0;
+ for ( ; (elem = this[i]) != null; i++ ) {
if ( !selector || jQuery.filter( selector, [ elem ] ).length > 0 ) {
if ( !keepData && elem.nodeType === 1 ) {
jQuery.cleanData( getAll( elem ) );
@@ -5464,19 +6002,23 @@ jQuery.fn.extend({
empty: function() {
var elem,
- i = 0,
- l = this.length;
-
- for ( ; i < l; i++ ) {
- elem = this[ i ];
+ i = 0;
+ for ( ; (elem = this[i]) != null; i++ ) {
+ // Remove element nodes and prevent memory leaks
if ( elem.nodeType === 1 ) {
-
- // Prevent memory leaks
jQuery.cleanData( getAll( elem, false ) );
+ }
+
+ // Remove any remaining nodes
+ while ( elem.firstChild ) {
+ elem.removeChild( elem.firstChild );
+ }
- // Remove any remaining nodes
- elem.textContent = "";
+ // If this is a select, ensure that it displays empty (#12336)
+ // Support: IE<9
+ if ( elem.options && jQuery.nodeName( elem, "select" ) ) {
+ elem.options.length = 0;
}
}
@@ -5494,25 +6036,28 @@ jQuery.fn.extend({
html: function( value ) {
return jQuery.access( this, function( value ) {
- var elem = this[ 0 ] || {},
+ var elem = this[0] || {},
i = 0,
l = this.length;
- if ( value === undefined && elem.nodeType === 1 ) {
- return elem.innerHTML;
+ if ( value === undefined ) {
+ return elem.nodeType === 1 ?
+ elem.innerHTML.replace( rinlinejQuery, "" ) :
+ undefined;
}
// See if we can take a shortcut and just use innerHTML
if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
- !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
+ ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) &&
+ ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
+ !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) {
value = value.replace( rxhtmlTag, "<$1></$2>" );
try {
- for ( ; i < l; i++ ) {
- elem = this[ i ] || {};
-
+ for (; i < l; i++ ) {
// Remove element nodes and prevent memory leaks
+ elem = this[i] || {};
if ( elem.nodeType === 1 ) {
jQuery.cleanData( getAll( elem, false ) );
elem.innerHTML = value;
@@ -5522,7 +6067,7 @@ jQuery.fn.extend({
elem = 0;
// If using innerHTML throws an exception, use the fallback method
- } catch( e ) {}
+ } catch(e) {}
}
if ( elem ) {
@@ -5532,25 +6077,23 @@ jQuery.fn.extend({
},
replaceWith: function( value ) {
- var isFunction = jQuery.isFunction( value );
+ var isFunc = jQuery.isFunction( value );
// Make sure that the elements are removed from the DOM before they are inserted
// this can help fix replacing a parent with child elements
- if ( !isFunction && typeof value !== "string" ) {
+ if ( !isFunc && typeof value !== "string" ) {
value = jQuery( value ).not( this ).detach();
}
- return value !== "" ?
- this.domManip( [ value ], true, function( elem ) {
- var next = this.nextSibling,
- parent = this.parentNode;
+ return this.domManip( [ value ], true, function( elem ) {
+ var next = this.nextSibling,
+ parent = this.parentNode;
- if ( parent ) {
- jQuery( this ).remove();
- parent.insertBefore( elem, next );
- }
- }) :
- this.remove();
+ if ( parent ) {
+ jQuery( this ).remove();
+ parent.insertBefore( elem, next );
+ }
+ });
},
detach: function( selector ) {
@@ -5562,12 +6105,13 @@ jQuery.fn.extend({
// Flatten any nested arrays
args = core_concat.apply( [], args );
- var fragment, first, scripts, hasScripts, node, doc,
+ var first, node, hasScripts,
+ scripts, doc, fragment,
i = 0,
l = this.length,
set = this,
iNoClone = l - 1,
- value = args[ 0 ],
+ value = args[0],
isFunction = jQuery.isFunction( value );
// We can't cloneNode fragments that contain checked, in WebKit
@@ -5575,7 +6119,7 @@ jQuery.fn.extend({
return this.each(function( index ) {
var self = set.eq( index );
if ( isFunction ) {
- args[ 0 ] = value.call( this, index, table ? self.html() : undefined );
+ args[0] = value.call( this, index, table ? self.html() : undefined );
}
self.domManip( args, table, callback );
});
@@ -5604,16 +6148,14 @@ jQuery.fn.extend({
// Keep references to cloned scripts for later restoration
if ( hasScripts ) {
- // Support: QtWebKit
- // jQuery.merge because core_push.apply(_, arraylike) throws
jQuery.merge( scripts, getAll( node, "script" ) );
}
}
callback.call(
- table && jQuery.nodeName( this[ i ], "table" ) ?
- findOrAppend( this[ i ], "tbody" ) :
- this[ i ],
+ table && jQuery.nodeName( this[i], "table" ) ?
+ findOrAppend( this[i], "tbody" ) :
+ this[i],
node,
i
);
@@ -5629,7 +6171,7 @@ jQuery.fn.extend({
for ( i = 0; i < hasScripts; i++ ) {
node = scripts[ i ];
if ( rscriptType.test( node.type || "" ) &&
- !data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) {
+ !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) {
if ( node.src ) {
// Hope ajax is available...
@@ -5642,11 +6184,14 @@ jQuery.fn.extend({
"throws": true
});
} else {
- jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) );
+ jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) );
}
}
}
}
+
+ // Fix #11809: Avoid leaking memory
+ fragment = first = null;
}
}
@@ -5654,6 +6199,130 @@ jQuery.fn.extend({
}
});
+function findOrAppend( elem, tag ) {
+ return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) );
+}
+
+// Replace/restore the type attribute of script elements for safe DOM manipulation
+function disableScript( elem ) {
+ var attr = elem.getAttributeNode("type");
+ elem.type = ( attr && attr.specified ) + "/" + elem.type;
+ return elem;
+}
+function restoreScript( elem ) {
+ var match = rscriptTypeMasked.exec( elem.type );
+ if ( match ) {
+ elem.type = match[1];
+ } else {
+ elem.removeAttribute("type");
+ }
+ return elem;
+}
+
+// Mark scripts as having already been evaluated
+function setGlobalEval( elems, refElements ) {
+ var elem,
+ i = 0;
+ for ( ; (elem = elems[i]) != null; i++ ) {
+ jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) );
+ }
+}
+
+function cloneCopyEvent( src, dest ) {
+
+ if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
+ return;
+ }
+
+ var type, i, l,
+ oldData = jQuery._data( src ),
+ curData = jQuery._data( dest, oldData ),
+ events = oldData.events;
+
+ if ( events ) {
+ delete curData.handle;
+ curData.events = {};
+
+ for ( type in events ) {
+ for ( i = 0, l = events[ type ].length; i < l; i++ ) {
+ jQuery.event.add( dest, type, events[ type ][ i ] );
+ }
+ }
+ }
+
+ // make the cloned public data object a copy from the original
+ if ( curData.data ) {
+ curData.data = jQuery.extend( {}, curData.data );
+ }
+}
+
+function fixCloneNodeIssues( src, dest ) {
+ var nodeName, e, data;
+
+ // We do not need to do anything for non-Elements
+ if ( dest.nodeType !== 1 ) {
+ return;
+ }
+
+ nodeName = dest.nodeName.toLowerCase();
+
+ // IE6-8 copies events bound via attachEvent when using cloneNode.
+ if ( !jQuery.support.noCloneEvent && dest[ jQuery.expando ] ) {
+ data = jQuery._data( dest );
+
+ for ( e in data.events ) {
+ jQuery.removeEvent( dest, e, data.handle );
+ }
+
+ // Event data gets referenced instead of copied if the expando gets copied too
+ dest.removeAttribute( jQuery.expando );
+ }
+
+ // IE blanks contents when cloning scripts, and tries to evaluate newly-set text
+ if ( nodeName === "script" && dest.text !== src.text ) {
+ disableScript( dest ).text = src.text;
+ restoreScript( dest );
+
+ // IE6-10 improperly clones children of object elements using classid.
+ // IE10 throws NoModificationAllowedError if parent is null, #12132.
+ } else if ( nodeName === "object" ) {
+ if ( dest.parentNode ) {
+ dest.outerHTML = src.outerHTML;
+ }
+
+ // This path appears unavoidable for IE9. When cloning an object
+ // element in IE9, the outerHTML strategy above is not sufficient.
+ // If the src has innerHTML and the destination does not,
+ // copy the src.innerHTML into the dest.innerHTML. #10324
+ if ( jQuery.support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) {
+ dest.innerHTML = src.innerHTML;
+ }
+
+ } else if ( nodeName === "input" && manipulation_rcheckableType.test( src.type ) ) {
+ // 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
+
+ dest.defaultChecked = dest.checked = src.checked;
+
+ // IE6-7 get confused and end up setting the value of a cloned
+ // checkbox/radio button to an empty string instead of "on"
+ if ( dest.value !== src.value ) {
+ dest.value = src.value;
+ }
+
+ // IE6-8 fails to return the selected option to the default selected
+ // state when cloning options
+ } else if ( nodeName === "option" ) {
+ dest.defaultSelected = 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;
+ }
+}
+
jQuery.each({
appendTo: "append",
prependTo: "prepend",
@@ -5663,17 +6332,16 @@ jQuery.each({
}, function( name, original ) {
jQuery.fn[ name ] = function( selector ) {
var elems,
+ i = 0,
ret = [],
insert = jQuery( selector ),
- last = insert.length - 1,
- i = 0;
+ last = insert.length - 1;
for ( ; i <= last; i++ ) {
- elems = i === last ? this : this.clone( true );
- jQuery( insert[ i ] )[ original ]( elems );
+ elems = i === last ? this : this.clone(true);
+ jQuery( insert[i] )[ original ]( elems );
- // Support: QtWebKit
- // .get() because core_push.apply(_, arraylike) throws
+ // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()
core_push.apply( ret, elems.get() );
}
@@ -5681,22 +6349,62 @@ jQuery.each({
};
});
+function getAll( context, tag ) {
+ var elems, elem,
+ i = 0,
+ found = typeof context.getElementsByTagName !== core_strundefined ? context.getElementsByTagName( tag || "*" ) :
+ typeof context.querySelectorAll !== core_strundefined ? context.querySelectorAll( tag || "*" ) :
+ undefined;
+
+ if ( !found ) {
+ for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {
+ if ( !tag || jQuery.nodeName( elem, tag ) ) {
+ found.push( elem );
+ } else {
+ jQuery.merge( found, getAll( elem, tag ) );
+ }
+ }
+ }
+
+ return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
+ jQuery.merge( [ context ], found ) :
+ found;
+}
+
+// Used in buildFragment, fixes the defaultChecked property
+function fixDefaultChecked( elem ) {
+ if ( manipulation_rcheckableType.test( elem.type ) ) {
+ elem.defaultChecked = elem.checked;
+ }
+}
+
jQuery.extend({
clone: function( elem, dataAndEvents, deepDataAndEvents ) {
- var i, l, srcElements, destElements,
- clone = elem.cloneNode( true ),
+ var destElements, node, clone, i, srcElements,
inPage = jQuery.contains( elem.ownerDocument, elem );
- // Support: IE >=9
- // Fix Cloning issues
- if ( !jQuery.support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && !jQuery.isXMLDoc( elem ) ) {
+ if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
+ clone = elem.cloneNode( true );
+
+ // IE<=8 does not properly clone detached, unknown element nodes
+ } else {
+ fragmentDiv.innerHTML = elem.outerHTML;
+ fragmentDiv.removeChild( clone = fragmentDiv.firstChild );
+ }
+
+ if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
+ (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
destElements = getAll( clone );
srcElements = getAll( elem );
- for ( i = 0, l = srcElements.length; i < l; i++ ) {
- fixInput( srcElements[ i ], destElements[ i ] );
+ // Fix all IE cloning issues
+ for ( i = 0; (node = srcElements[i]) != null; ++i ) {
+ // Ensure that the destination node is not null; Fixes #9587
+ if ( destElements[i] ) {
+ fixCloneNodeIssues( node, destElements[i] );
+ }
}
}
@@ -5706,8 +6414,8 @@ jQuery.extend({
srcElements = srcElements || getAll( elem );
destElements = destElements || getAll( clone );
- for ( i = 0, l = srcElements.length; i < l; i++ ) {
- cloneCopyEvent( srcElements[ i ], destElements[ i ] );
+ for ( i = 0; (node = srcElements[i]) != null; i++ ) {
+ cloneCopyEvent( node, destElements[i] );
}
} else {
cloneCopyEvent( elem, clone );
@@ -5720,16 +6428,22 @@ jQuery.extend({
setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
}
+ destElements = srcElements = node = null;
+
// Return the cloned set
return clone;
},
buildFragment: function( elems, context, scripts, selection ) {
- var elem, tmp, tag, wrap, contains, j,
- i = 0,
+ var j, elem, contains,
+ tmp, tag, tbody, wrap,
l = elems.length,
- fragment = context.createDocumentFragment(),
- nodes = [];
+
+ // Ensure a safe fragment
+ safe = createSafeFragment( context ),
+
+ nodes = [],
+ i = 0;
for ( ; i < l; i++ ) {
elem = elems[ i ];
@@ -5738,8 +6452,6 @@ jQuery.extend({
// Add nodes directly
if ( jQuery.type( elem ) === "object" ) {
- // Support: QtWebKit
- // jQuery.merge because core_push.apply(_, arraylike) throws
jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
// Convert non-html into a text node
@@ -5748,35 +6460,71 @@ jQuery.extend({
// Convert html into DOM nodes
} else {
- tmp = tmp || fragment.appendChild( context.createElement("div") );
+ tmp = tmp || safe.appendChild( context.createElement("div") );
// Deserialize a standard representation
- tag = ( rtagName.exec( elem ) || ["", ""] )[ 1 ].toLowerCase();
+ tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase();
wrap = wrapMap[ tag ] || wrapMap._default;
- tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[ 2 ];
+
+ tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[2];
// Descend through wrappers to the right content
- j = wrap[ 0 ];
+ j = wrap[0];
while ( j-- ) {
- tmp = tmp.firstChild;
+ tmp = tmp.lastChild;
}
- // Support: QtWebKit
- // jQuery.merge because core_push.apply(_, arraylike) throws
- jQuery.merge( nodes, tmp.childNodes );
+ // Manually add leading whitespace removed by IE
+ if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
+ nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) );
+ }
+
+ // Remove IE's autoinserted <tbody> from table fragments
+ if ( !jQuery.support.tbody ) {
+
+ // String was a <table>, *may* have spurious <tbody>
+ elem = tag === "table" && !rtbody.test( elem ) ?
+ tmp.firstChild :
- // Remember the top-level container
- tmp = fragment.firstChild;
+ // String was a bare <thead> or <tfoot>
+ wrap[1] === "<table>" && !rtbody.test( elem ) ?
+ tmp :
+ 0;
- // Fixes #12346
- // Support: Webkit, IE
+ j = elem && elem.childNodes.length;
+ while ( j-- ) {
+ if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) {
+ elem.removeChild( tbody );
+ }
+ }
+ }
+
+ jQuery.merge( nodes, tmp.childNodes );
+
+ // Fix #12392 for WebKit and IE > 9
tmp.textContent = "";
+
+ // Fix #12392 for oldIE
+ while ( tmp.firstChild ) {
+ tmp.removeChild( tmp.firstChild );
+ }
+
+ // Remember the top-level container for proper cleanup
+ tmp = safe.lastChild;
}
}
}
- // Remove wrapper from fragment
- fragment.textContent = "";
+ // Fix #11356: Clear elements from fragment
+ if ( tmp ) {
+ safe.removeChild( tmp );
+ }
+
+ // Reset defaultChecked for any radios and checkboxes
+ // about to be appended to the DOM in IE 6/7 (#8060)
+ if ( !jQuery.support.appendChecked ) {
+ jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked );
+ }
i = 0;
while ( (elem = nodes[ i++ ]) ) {
@@ -5790,7 +6538,7 @@ jQuery.extend({
contains = jQuery.contains( elem.ownerDocument, elem );
// Append to fragment
- tmp = getAll( fragment.appendChild( elem ), "script" );
+ tmp = getAll( safe.appendChild( elem ), "script" );
// Preserve script evaluation history
if ( contains ) {
@@ -5808,135 +6556,68 @@ jQuery.extend({
}
}
- return fragment;
+ tmp = null;
+
+ return safe;
},
cleanData: function( elems, /* internal */ acceptData ) {
- var data, elem, type,
- l = elems.length,
+ var elem, type, id, data,
i = 0,
+ internalKey = jQuery.expando,
+ cache = jQuery.cache,
+ deleteExpando = jQuery.support.deleteExpando,
special = jQuery.event.special;
- for ( ; i < l; i++ ) {
- elem = elems[ i ];
+ for ( ; (elem = elems[i]) != null; i++ ) {
if ( acceptData || jQuery.acceptData( elem ) ) {
- data = data_priv.access( elem );
+ id = elem[ internalKey ];
+ data = id && cache[ id ];
if ( data ) {
- for ( type in data.events ) {
- if ( special[ type ] ) {
- jQuery.event.remove( elem, type );
+ if ( data.events ) {
+ for ( 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 );
+ // This is a shortcut to avoid jQuery.event.remove's overhead
+ } else {
+ jQuery.removeEvent( elem, type, data.handle );
+ }
}
}
- }
- }
- // Discard any remaining `private` and `user` data
- data_discard( elem );
- }
- }
-});
-
-function findOrAppend( elem, tag ) {
- return elem.getElementsByTagName( tag )[ 0 ] || elem.appendChild( elem.ownerDocument.createElement(tag) );
-}
-
-// Replace/restore the type attribute of script elements for safe DOM manipulation
-function disableScript( elem ) {
- var attr = elem.getAttributeNode("type");
- elem.type = ( attr && attr.specified ) + "/" + elem.type;
- return elem;
-}
-function restoreScript( elem ) {
- var match = rscriptTypeMasked.exec( elem.type );
-
- if ( match ) {
- elem.type = match[ 1 ];
- } else {
- elem.removeAttribute("type");
- }
-
- return elem;
-}
-// Mark scripts as having already been evaluated
-function setGlobalEval( elems, refElements ) {
- var l = elems.length,
- i = 0;
+ // Remove cache only if it was not already removed by jQuery.event.remove
+ if ( cache[ id ] ) {
- for ( ; i < l; i++ ) {
- data_priv.set(
- elems[ i ], "globalEval", !refElements || data_priv.get( refElements[ i ], "globalEval" )
- );
- }
-}
+ delete cache[ id ];
-function cloneCopyEvent( src, dest ) {
- var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
+ // 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 ( deleteExpando ) {
+ delete elem[ internalKey ];
- if ( dest.nodeType !== 1 ) {
- return;
- }
+ } else if ( typeof elem.removeAttribute !== core_strundefined ) {
+ elem.removeAttribute( internalKey );
- // 1. Copy private data: events, handlers, etc.
- if ( data_priv.hasData( src ) ) {
- pdataOld = data_priv.access( src );
- pdataCur = jQuery.extend( {}, pdataOld );
- events = pdataOld.events;
-
- data_priv.set( dest, pdataCur );
-
- if ( events ) {
- delete pdataCur.handle;
- pdataCur.events = {};
+ } else {
+ elem[ internalKey ] = null;
+ }
- for ( type in events ) {
- for ( i = 0, l = events[ type ].length; i < l; i++ ) {
- jQuery.event.add( dest, type, events[ type ][ i ] );
+ core_deletedIds.push( id );
+ }
}
}
}
}
-
- // 2. Copy user data
- if ( data_user.hasData( src ) ) {
- udataOld = data_user.access( src );
- udataCur = jQuery.extend( {}, udataOld );
-
- data_user.set( dest, udataCur );
- }
-}
-
-
-function getAll( context, tag ) {
- var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || "*" ) :
- context.querySelectorAll ? context.querySelectorAll( tag || "*" ) :
- [];
-
- return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
- jQuery.merge( [ context ], ret ) :
- ret;
-}
-
-// Support: IE >= 9
-function fixInput( src, dest ) {
- var nodeName = dest.nodeName.toLowerCase();
-
- // Fails to persist the checked state of a cloned checkbox or radio button.
- if ( nodeName === "input" && manipulation_rcheckableType.test( src.type ) ) {
- dest.checked = src.checked;
-
- // Fails to return the selected option to the default selected state when cloning options
- } else if ( nodeName === "input" || nodeName === "textarea" ) {
- dest.defaultValue = src.defaultValue;
- }
-}
-var curCSS, iframe,
+});
+var iframe, getStyles, curCSS,
+ ralpha = /alpha\([^)]*\)/i,
+ ropacity = /opacity\s*=\s*([^)]*)/,
+ rposition = /^(top|right|bottom|left)$/,
// swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
// see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
rdisplayswap = /^(none|table(?!-c[ea]).+)/,
@@ -5985,12 +6666,6 @@ function isHidden( elem, el ) {
return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
}
-// NOTE: we've included the "window" in window.getComputedStyle
-// because jsdom on node.js will break without it.
-function getStyles( elem ) {
- return window.getComputedStyle( elem, null );
-}
-
function showHide( elements, show ) {
var display, elem, hidden,
values = [],
@@ -6048,7 +6723,7 @@ function showHide( elements, show ) {
jQuery.fn.extend({
css: function( name, value ) {
return jQuery.access( this, function( elem, name, value ) {
- var styles, len,
+ var len, styles,
map = {},
i = 0;
@@ -6119,7 +6794,7 @@ jQuery.extend({
// setting or getting the value
cssProps: {
// normalize float css property
- "float": "cssFloat"
+ "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
},
// Get and set the style property on a DOM Node
@@ -6161,7 +6836,7 @@ jQuery.extend({
value += "px";
}
- // Fixes #8908, it can be done more correctly by specifying setters in cssHooks,
+ // Fixes #8908, it can be done more correctly by specifing setters in cssHooks,
// but it would mean to define eight (for every problematic property) identical functions
if ( !jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) {
style[ name ] = "inherit";
@@ -6169,7 +6844,12 @@ jQuery.extend({
// If a hook was provided, use that value, otherwise just set the specified value
if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
- style[ name ] = value;
+
+ // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
+ // Fixes bug #5509
+ try {
+ style[ name ] = value;
+ } catch(e) {}
}
} else {
@@ -6184,7 +6864,7 @@ jQuery.extend({
},
css: function( elem, name, extra, styles ) {
- var val, num, hooks,
+ var num, val, hooks,
origName = jQuery.camelCase( name );
// Make sure that we're working with the right name
@@ -6239,47 +6919,99 @@ jQuery.extend({
}
});
-curCSS = function( elem, name, _computed ) {
- var width, minWidth, maxWidth,
- computed = _computed || getStyles( elem ),
+// NOTE: we've included the "window" in window.getComputedStyle
+// because jsdom on node.js will break without it.
+if ( window.getComputedStyle ) {
+ getStyles = function( elem ) {
+ return window.getComputedStyle( elem, null );
+ };
- // Support: IE9
- // getPropertyValue is only needed for .css('filter') in IE9, see #12537
- ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined,
- style = elem.style;
+ curCSS = function( elem, name, _computed ) {
+ var width, minWidth, maxWidth,
+ computed = _computed || getStyles( elem ),
- if ( computed ) {
+ // getPropertyValue is only needed for .css('filter') in IE9, see #12537
+ ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined,
+ style = elem.style;
+
+ if ( computed ) {
+
+ if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
+ ret = jQuery.style( elem, name );
+ }
+
+ // A tribute to the "awesome hack by Dean Edwards"
+ // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right
+ // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
+ // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
+ if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
+
+ // Remember the original values
+ width = style.width;
+ minWidth = style.minWidth;
+ maxWidth = style.maxWidth;
+
+ // Put in the new values to get a computed value out
+ style.minWidth = style.maxWidth = style.width = ret;
+ ret = computed.width;
- if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
- ret = jQuery.style( elem, name );
+ // Revert the changed values
+ style.width = width;
+ style.minWidth = minWidth;
+ style.maxWidth = maxWidth;
+ }
}
- // Support: Chrome <17, Safari 5.1
- // A tribute to the "awesome hack by Dean Edwards"
- // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right
- // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
- // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
- if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
+ return ret;
+ };
+} else if ( document.documentElement.currentStyle ) {
+ getStyles = function( elem ) {
+ return elem.currentStyle;
+ };
+
+ curCSS = function( elem, name, _computed ) {
+ var left, rs, rsLeft,
+ computed = _computed || getStyles( elem ),
+ ret = computed ? computed[ name ] : undefined,
+ style = elem.style;
+
+ // Avoid setting ret to empty string here
+ // so we don't default to auto
+ if ( ret == null && style && style[ name ] ) {
+ ret = style[ name ];
+ }
+
+ // From the awesome hack by Dean Edwards
+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+ // If we're not dealing with a regular pixel number
+ // but a number that has a weird ending, we need to convert it to pixels
+ // but not position css attributes, as those are proportional to the parent element instead
+ // and we can't measure the parent instead because it might trigger a "stacking dolls" problem
+ if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
// Remember the original values
- width = style.width;
- minWidth = style.minWidth;
- maxWidth = style.maxWidth;
+ left = style.left;
+ rs = elem.runtimeStyle;
+ rsLeft = rs && rs.left;
// Put in the new values to get a computed value out
- style.minWidth = style.maxWidth = style.width = ret;
- ret = computed.width;
+ if ( rsLeft ) {
+ rs.left = elem.currentStyle.left;
+ }
+ style.left = name === "fontSize" ? "1em" : ret;
+ ret = style.pixelLeft + "px";
// Revert the changed values
- style.width = width;
- style.minWidth = minWidth;
- style.maxWidth = maxWidth;
+ style.left = left;
+ if ( rsLeft ) {
+ rs.left = rsLeft;
+ }
}
- }
-
- return ret;
-};
+ return ret === "" ? "auto" : ret;
+ };
+}
function setPositiveNumber( elem, value, subtract ) {
var matches = rnumsplit.exec( value );
@@ -6440,6 +7172,50 @@ jQuery.each([ "height", "width" ], function( i, name ) {
};
});
+if ( !jQuery.support.opacity ) {
+ jQuery.cssHooks.opacity = {
+ get: function( elem, computed ) {
+ // IE uses filters for opacity
+ return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
+ ( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
+ computed ? "1" : "";
+ },
+
+ set: function( elem, value ) {
+ var style = elem.style,
+ currentStyle = elem.currentStyle,
+ opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
+ filter = currentStyle && currentStyle.filter || style.filter || "";
+
+ // IE has trouble with opacity if it does not have layout
+ // Force it by setting the zoom level
+ style.zoom = 1;
+
+ // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
+ // if value === "", then remove inline opacity #12685
+ if ( ( value >= 1 || value === "" ) &&
+ jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
+ style.removeAttribute ) {
+
+ // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
+ // if "filter:" is present at all, clearType is disabled, we want to avoid this
+ // style.removeAttribute is IE Only, but so apparently is this code path...
+ style.removeAttribute( "filter" );
+
+ // if there is no filter style applied in a css rule or unset inline opacity, we are done
+ if ( value === "" || currentStyle && !currentStyle.filter ) {
+ return;
+ }
+ }
+
+ // otherwise, set new filter values
+ style.filter = ralpha.test( filter ) ?
+ filter.replace( ralpha, opacity ) :
+ filter + " " + opacity;
+ }
+ };
+}
+
// These hooks cannot be added until DOM ready because the support test
// for it is not run until after DOM ready
jQuery(function() {
@@ -6481,7 +7257,8 @@ if ( jQuery.expr && jQuery.expr.filters ) {
jQuery.expr.filters.hidden = function( elem ) {
// Support: Opera <= 12.12
// Opera reports offsetWidths and offsetHeights less than zero on some elements
- return elem.offsetWidth <= 0 && elem.offsetHeight <= 0;
+ return elem.offsetWidth <= 0 && elem.offsetHeight <= 0 ||
+ (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none");
};
jQuery.expr.filters.visible = function( elem ) {
@@ -6634,7 +7411,6 @@ var
// Document location
ajaxLocParts,
ajaxLocation,
-
ajax_nonce = jQuery.now(),
ajax_rquery = /\?/,
@@ -6747,7 +7523,7 @@ function inspectPrefiltersOrTransports( structure, options, originalOptions, jqX
// that takes "flat" options (not to be deep extended)
// Fixes #9887
function ajaxExtend( target, src ) {
- var key, deep,
+ var deep, key,
flatOptions = jQuery.ajaxSettings.flatOptions || {};
for ( key in src ) {
@@ -6767,7 +7543,7 @@ jQuery.fn.load = function( url, params, callback ) {
return _load.apply( this, arguments );
}
- var selector, type, response,
+ var selector, response, type,
self = this,
off = url.indexOf(" ");
@@ -6890,8 +7666,7 @@ jQuery.extend({
responseFields: {
xml: "responseXML",
- text: "responseText",
- json: "responseJSON"
+ text: "responseText"
},
// Data converters
@@ -6899,7 +7674,7 @@ jQuery.extend({
converters: {
// Convert anything to text
- "* text": String,
+ "* text": window.String,
// Text to html (true = no transformation)
"text html": true,
@@ -6949,20 +7724,23 @@ jQuery.extend({
// Force options to be an object
options = options || {};
- var transport,
+ var // Cross-domain detection vars
+ parts,
+ // Loop variable
+ i,
// URL without anti-cache param
cacheURL,
- // Response headers
+ // Response headers as string
responseHeadersString,
- responseHeaders,
// timeout handle
timeoutTimer,
- // Cross-domain detection vars
- parts,
+
// To know if global events are to be dispatched
fireGlobals,
- // Loop variable
- i,
+
+ transport,
+ // Response headers
+ responseHeaders,
// Create the final options object
s = jQuery.ajaxSetup( {}, options ),
// Callbacks context
@@ -7237,19 +8015,13 @@ jQuery.extend({
// Set readyState
jqXHR.readyState = status > 0 ? 4 : 0;
- // Determine if successful
- isSuccess = status >= 200 && status < 300 || status === 304;
-
// Get response data
if ( responses ) {
response = ajaxHandleResponses( s, jqXHR, responses );
}
- // Convert no matter what (that way responseXXX fields are always set)
- response = ajaxConvert( s, response, jqXHR, isSuccess );
-
// If successful, handle type chaining
- if ( isSuccess ) {
+ if ( status >= 200 && status < 300 || status === 304 ) {
// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
if ( s.ifModified ) {
@@ -7265,17 +8037,20 @@ jQuery.extend({
// if no content
if ( status === 204 ) {
+ isSuccess = true;
statusText = "nocontent";
// if not modified
} else if ( status === 304 ) {
+ isSuccess = true;
statusText = "notmodified";
// If we have data, let's convert it
} else {
- statusText = response.state;
- success = response.data;
- error = response.error;
+ isSuccess = ajaxConvert( s, response );
+ statusText = isSuccess.state;
+ success = isSuccess.data;
+ error = isSuccess.error;
isSuccess = !error;
}
} else {
@@ -7335,14 +8110,22 @@ jQuery.extend({
});
/* Handles responses to an ajax request:
+ * - sets all responseXXX fields accordingly
* - finds the right dataType (mediates between content-type and expected dataType)
* - returns the corresponding response
*/
function ajaxHandleResponses( s, jqXHR, responses ) {
-
- var ct, type, finalDataType, firstDataType,
+ var firstDataType, ct, finalDataType, type,
contents = s.contents,
- dataTypes = s.dataTypes;
+ dataTypes = s.dataTypes,
+ responseFields = s.responseFields;
+
+ // Fill responseXXX fields
+ for ( type in responseFields ) {
+ if ( type in responses ) {
+ jqXHR[ responseFields[type] ] = responses[ type ];
+ }
+ }
// Remove auto dataType and get content-type in the process
while( dataTypes[ 0 ] === "*" ) {
@@ -7391,14 +8174,19 @@ function ajaxHandleResponses( s, jqXHR, responses ) {
}
}
-/* Chain conversions given the request and the original response
- * Also sets the responseXXX fields on the jqXHR instance
- */
-function ajaxConvert( s, response, jqXHR, isSuccess ) {
- var conv2, current, conv, tmp, prev,
+// Chain conversions given the request and the original response
+function ajaxConvert( s, response ) {
+ var conv2, current, conv, tmp,
converters = {},
+ i = 0,
// Work with a copy of dataTypes in case we need to modify it for conversion
- dataTypes = s.dataTypes.slice();
+ dataTypes = s.dataTypes.slice(),
+ prev = dataTypes[ 0 ];
+
+ // Apply the dataFilter if provided
+ if ( s.dataFilter ) {
+ response = s.dataFilter( response, s.dataType );
+ }
// Create converters map with lowercased keys
if ( dataTypes[ 1 ] ) {
@@ -7407,32 +8195,14 @@ function ajaxConvert( s, response, jqXHR, isSuccess ) {
}
}
- current = dataTypes.shift();
-
- // Convert to each sequential dataType
- while ( current ) {
-
- if ( s.responseFields[ current ] ) {
- jqXHR[ s.responseFields[ current ] ] = response;
- }
-
- // Apply the dataFilter if provided
- if ( !prev && isSuccess && s.dataFilter ) {
- response = s.dataFilter( response, s.dataType );
- }
-
- prev = current;
- current = dataTypes.shift();
-
- if ( current ) {
+ // Convert to each sequential dataType, tolerating list modification
+ for ( ; (current = dataTypes[++i]); ) {
// There's only work to do if current dataType is non-auto
- if ( current === "*" ) {
-
- current = prev;
+ if ( current !== "*" ) {
// Convert response if prev dataType is non-auto and differs from current
- } else if ( prev !== "*" && prev !== current ) {
+ if ( prev !== "*" && prev !== current ) {
// Seek a direct converter
conv = converters[ prev + " " + current ] || converters[ "* " + current ];
@@ -7442,7 +8212,7 @@ function ajaxConvert( s, response, jqXHR, isSuccess ) {
for ( conv2 in converters ) {
// If conv2 outputs current
- tmp = conv2.split( " " );
+ tmp = conv2.split(" ");
if ( tmp[ 1 ] === current ) {
// If prev can be converted to accepted input
@@ -7456,8 +8226,9 @@ function ajaxConvert( s, response, jqXHR, isSuccess ) {
// Otherwise, insert the intermediate dataType
} else if ( converters[ conv2 ] !== true ) {
current = tmp[ 0 ];
- dataTypes.unshift( tmp[ 1 ] );
+ dataTypes.splice( i--, 0, current );
}
+
break;
}
}
@@ -7468,7 +8239,7 @@ function ajaxConvert( s, response, jqXHR, isSuccess ) {
if ( conv !== true ) {
// Unless errors are allowed to bubble, catch and return them
- if ( conv && s[ "throws" ] ) {
+ if ( conv && s["throws"] ) {
response = conv( response );
} else {
try {
@@ -7479,6 +8250,9 @@ function ajaxConvert( s, response, jqXHR, isSuccess ) {
}
}
}
+
+ // Update prev for next iteration
+ prev = current;
}
}
@@ -7500,42 +8274,71 @@ jQuery.ajaxSetup({
}
});
-// Handle cache's special case and crossDomain
+// Handle cache's special case and global
jQuery.ajaxPrefilter( "script", function( s ) {
if ( s.cache === undefined ) {
s.cache = false;
}
if ( s.crossDomain ) {
s.type = "GET";
+ s.global = false;
}
});
// Bind script tag hack transport
-jQuery.ajaxTransport( "script", function( s ) {
+jQuery.ajaxTransport( "script", function(s) {
+
// This transport only deals with cross domain requests
if ( s.crossDomain ) {
- var script, callback;
+
+ var script,
+ head = document.head || jQuery("head")[0] || document.documentElement;
+
return {
- send: function( _, complete ) {
- script = jQuery("<script>").prop({
- async: true,
- charset: s.scriptCharset,
- src: s.url
- }).on(
- "load error",
- callback = function( evt ) {
- script.remove();
- callback = null;
- if ( evt ) {
- complete( evt.type === "error" ? 404 : 200, evt.type );
+
+ send: function( _, callback ) {
+
+ script = document.createElement("script");
+
+ script.async = true;
+
+ if ( s.scriptCharset ) {
+ script.charset = s.scriptCharset;
+ }
+
+ script.src = s.url;
+
+ // Attach handlers for all browsers
+ script.onload = script.onreadystatechange = function( _, isAbort ) {
+
+ if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
+
+ // Handle memory leak in IE
+ script.onload = script.onreadystatechange = null;
+
+ // Remove the script
+ if ( script.parentNode ) {
+ script.parentNode.removeChild( script );
+ }
+
+ // Dereference the script
+ script = null;
+
+ // Callback if not abort
+ if ( !isAbort ) {
+ callback( 200, "success" );
}
}
- );
- document.head.appendChild( script[ 0 ] );
+ };
+
+ // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
+ // Use native DOM manipulation to avoid our domManip AJAX trickery
+ head.insertBefore( script, head.firstChild );
},
+
abort: function() {
- if ( callback ) {
- callback();
+ if ( script ) {
+ script.onload( undefined, true );
}
}
};
@@ -7621,117 +8424,213 @@ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
return "script";
}
});
-jQuery.ajaxSettings.xhr = function() {
+var xhrCallbacks, xhrSupported,
+ xhrId = 0,
+ // #5280: Internet Explorer will keep connections alive if we don't abort on unload
+ xhrOnUnloadAbort = window.ActiveXObject && function() {
+ // Abort all pending requests
+ var key;
+ for ( key in xhrCallbacks ) {
+ xhrCallbacks[ key ]( undefined, true );
+ }
+ };
+
+// Functions to create xhrs
+function createStandardXHR() {
try {
- return new XMLHttpRequest();
+ return new window.XMLHttpRequest();
} catch( e ) {}
-};
-
-var xhrSupported = jQuery.ajaxSettings.xhr(),
- xhrSuccessStatus = {
- // file protocol always yields status code 0, assume 200
- 0: 200,
- // Support: IE9
- // #1450: sometimes IE returns 1223 when it should be 204
- 1223: 204
- },
- // Support: IE9
- // We need to keep track of outbound xhr and abort them manually
- // because IE is not smart enough to do it all by itself
- xhrId = 0,
- xhrCallbacks = {};
+}
-if ( window.ActiveXObject ) {
- jQuery( window ).on( "unload", function() {
- for( var key in xhrCallbacks ) {
- xhrCallbacks[ key ]();
- }
- xhrCallbacks = undefined;
- });
+function createActiveXHR() {
+ try {
+ return new window.ActiveXObject("Microsoft.XMLHTTP");
+ } catch( e ) {}
}
+// 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() {
+ return !this.isLocal && createStandardXHR() || createActiveXHR();
+ } :
+ // For all other browsers, use the standard XMLHttpRequest object
+ createStandardXHR;
+
+// Determine support properties
+xhrSupported = jQuery.ajaxSettings.xhr();
jQuery.support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
-jQuery.support.ajax = xhrSupported = !!xhrSupported;
+xhrSupported = jQuery.support.ajax = !!xhrSupported;
-jQuery.ajaxTransport(function( options ) {
- var callback;
- // Cross domain only allowed if supported through XMLHttpRequest
- if ( jQuery.support.cors || xhrSupported && !options.crossDomain ) {
- return {
- send: function( headers, complete ) {
- var i, id,
- xhr = options.xhr();
- xhr.open( options.type, options.url, options.async, options.username, options.password );
- // Apply custom fields if provided
- if ( options.xhrFields ) {
- for ( i in options.xhrFields ) {
- xhr[ i ] = options.xhrFields[ i ];
+// Create transport if the browser can provide an xhr
+if ( xhrSupported ) {
+
+ 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 ) {
+
+ // Get a new xhr
+ var handle, i,
+ xhr = s.xhr();
+
+ // 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 );
}
- }
- // Override mime type if needed
- if ( options.mimeType && xhr.overrideMimeType ) {
- xhr.overrideMimeType( options.mimeType );
- }
- // X-Requested-With header
- // For cross-domain requests, seeing as conditions for a preflight are
- // akin to a jigsaw puzzle, we simply never set it to be sure.
- // (it can always be set on a per-request basis or even using ajaxSetup)
- // For same-domain requests, won't change header if already provided.
- if ( !options.crossDomain && !headers["X-Requested-With"] ) {
- headers["X-Requested-With"] = "XMLHttpRequest";
- }
- // Set headers
- for ( i in headers ) {
- xhr.setRequestHeader( i, headers[ i ] );
- }
- // Callback
- callback = function( type ) {
- return function() {
- if ( callback ) {
- delete xhrCallbacks[ id ];
- callback = xhr.onload = xhr.onerror = null;
- if ( type === "abort" ) {
- xhr.abort();
- } else if ( type === "error" ) {
- complete(
- // file protocol always yields status 0, assume 404
- xhr.status || 404,
- xhr.statusText
- );
- } else {
- complete(
- xhrSuccessStatus[ xhr.status ] || xhr.status,
- xhr.statusText,
- // Support: IE9
- // #11426: When requesting binary data, IE9 will throw an exception
- // on any attempt to access responseText
- typeof xhr.responseText === "string" ? {
- text: xhr.responseText
- } : undefined,
- xhr.getAllResponseHeaders()
- );
+
+ // Apply custom fields if provided
+ if ( s.xhrFields ) {
+ for ( i in s.xhrFields ) {
+ xhr[ i ] = s.xhrFields[ i ];
+ }
+ }
+
+ // Override mime type if needed
+ if ( s.mimeType && xhr.overrideMimeType ) {
+ xhr.overrideMimeType( s.mimeType );
+ }
+
+ // X-Requested-With header
+ // For cross-domain requests, seeing as conditions for a preflight are
+ // akin to a jigsaw puzzle, we simply never set it to be sure.
+ // (it can always be set on a per-request basis or even using ajaxSetup)
+ // For same-domain requests, won't change header if already provided.
+ if ( !s.crossDomain && !headers["X-Requested-With"] ) {
+ headers["X-Requested-With"] = "XMLHttpRequest";
+ }
+
+ // Need an extra try/catch for cross domain requests in Firefox 3
+ try {
+ for ( i in headers ) {
+ xhr.setRequestHeader( i, headers[ i ] );
+ }
+ } catch( err ) {}
+
+ // Do send the request
+ // This may raise an exception which is actually
+ // handled in jQuery.ajax (so no try/catch here)
+ xhr.send( ( s.hasContent && s.data ) || null );
+
+ // Listener
+ callback = function( _, isAbort ) {
+ var status, responseHeaders, statusText, responses;
+
+ // Firefox throws exceptions when accessing properties
+ // of an xhr when a network error occurred
+ // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
+ try {
+
+ // Was never called and is aborted or complete
+ if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
+
+ // Only called once
+ callback = undefined;
+
+ // Do not keep as active anymore
+ if ( handle ) {
+ xhr.onreadystatechange = jQuery.noop;
+ if ( xhrOnUnloadAbort ) {
+ delete xhrCallbacks[ handle ];
+ }
+ }
+
+ // If it's an abort
+ if ( isAbort ) {
+ // Abort it manually if needed
+ if ( xhr.readyState !== 4 ) {
+ xhr.abort();
+ }
+ } else {
+ responses = {};
+ status = xhr.status;
+ responseHeaders = xhr.getAllResponseHeaders();
+
+ // When requesting binary data, IE6-9 will throw an exception
+ // on any attempt to access responseText (#11426)
+ if ( typeof xhr.responseText === "string" ) {
+ responses.text = xhr.responseText;
+ }
+
+ // Firefox throws an exception when accessing
+ // statusText for faulty cross-domain requests
+ try {
+ statusText = xhr.statusText;
+ } catch( e ) {
+ // We normalize with Webkit giving an empty statusText
+ statusText = "";
+ }
+
+ // Filter status for non standard behaviors
+
+ // If the request is local and we have data: assume a success
+ // (success with no data won't get notified, that's the best we
+ // can do given current implementations)
+ if ( !status && s.isLocal && !s.crossDomain ) {
+ status = responses.text ? 200 : 404;
+ // IE - #1450: sometimes returns 1223 when it should be 204
+ } else if ( status === 1223 ) {
+ status = 204;
+ }
+ }
+ }
+ } catch( firefoxAccessException ) {
+ if ( !isAbort ) {
+ complete( -1, firefoxAccessException );
}
}
+
+ // Call complete if needed
+ if ( responses ) {
+ complete( status, statusText, responses, responseHeaders );
+ }
};
- };
- // Listen to events
- xhr.onload = callback();
- xhr.onerror = callback("error");
- // Create the abort callback
- callback = xhrCallbacks[( id = xhrId++ )] = callback("abort");
- // Do send the request
- // This may raise an exception which is actually
- // handled in jQuery.ajax (so no try/catch here)
- xhr.send( options.hasContent && options.data || null );
- },
- abort: function() {
- if ( callback ) {
- callback();
+
+ if ( !s.async ) {
+ // if we're in sync mode we fire the callback
+ callback();
+ } else if ( xhr.readyState === 4 ) {
+ // (IE6 & IE7) if it's in cache and has been
+ // retrieved directly we need to fire the callback
+ setTimeout( callback );
+ } else {
+ handle = ++xhrId;
+ if ( xhrOnUnloadAbort ) {
+ // Create the active xhrs callbacks list if needed
+ // and attach the unload handler
+ if ( !xhrCallbacks ) {
+ xhrCallbacks = {};
+ jQuery( window ).unload( xhrOnUnloadAbort );
+ }
+ // Add to list of active xhrs callbacks
+ xhrCallbacks[ handle ] = callback;
+ }
+ xhr.onreadystatechange = callback;
+ }
+ },
+
+ abort: function() {
+ if ( callback ) {
+ callback( undefined, true );
+ }
}
- }
- };
- }
-});
+ };
+ }
+ });
+}
var fxNow, timerId,
rfxtypes = /^(?:toggle|show|hide)$/,
rfxnum = new RegExp( "^(?:([+-])=|)(" + core_pnum + ")([a-z%]*)$", "i" ),
@@ -7909,7 +8808,7 @@ function Animation( elem, properties, options ) {
}
function propFilter( props, specialEasing ) {
- var index, name, easing, value, hooks;
+ var value, name, index, easing, hooks;
// camelCase, specialEasing and expand cssHook pass
for ( index in props ) {
@@ -7977,7 +8876,9 @@ jQuery.Animation = jQuery.extend( Animation, {
function defaultPrefilter( elem, props, opts ) {
/*jshint validthis:true */
- var index, prop, value, length, dataShow, toggle, tween, hooks, oldfire,
+ var prop, index, length,
+ value, dataShow, toggle,
+ tween, hooks, oldfire,
anim = this,
style = elem.style,
orig = {},
@@ -8023,17 +8924,26 @@ function defaultPrefilter( elem, props, opts ) {
if ( jQuery.css( elem, "display" ) === "inline" &&
jQuery.css( elem, "float" ) === "none" ) {
- style.display = "inline-block";
+ // inline-level elements accept inline-block;
+ // block-level elements need to be inline with layout
+ if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === "inline" ) {
+ style.display = "inline-block";
+
+ } else {
+ style.zoom = 1;
+ }
}
}
if ( opts.overflow ) {
style.overflow = "hidden";
- anim.always(function() {
- style.overflow = opts.overflow[ 0 ];
- style.overflowX = opts.overflow[ 1 ];
- style.overflowY = opts.overflow[ 2 ];
- });
+ if ( !jQuery.support.shrinkWrapBlocks ) {
+ anim.always(function() {
+ style.overflow = opts.overflow[ 0 ];
+ style.overflowX = opts.overflow[ 1 ];
+ style.overflowY = opts.overflow[ 2 ];
+ });
+ }
}
@@ -8461,8 +9371,8 @@ jQuery.fn.offset = function( options ) {
}
var docElem, win,
- elem = this[ 0 ],
box = { top: 0, left: 0 },
+ elem = this[ 0 ],
doc = elem && elem.ownerDocument;
if ( !doc ) {
@@ -8483,35 +9393,33 @@ jQuery.fn.offset = function( options ) {
}
win = getWindow( doc );
return {
- top: box.top + win.pageYOffset - docElem.clientTop,
- left: box.left + win.pageXOffset - docElem.clientLeft
+ top: box.top + ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0 ),
+ left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
};
};
jQuery.offset = {
setOffset: function( elem, options, i ) {
- var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
- position = jQuery.css( elem, "position" ),
- curElem = jQuery( elem ),
- props = {};
+ var position = jQuery.css( elem, "position" );
- // Set position first, in-case top/left are set even on static elem
+ // set position first, in-case top/left are set even on static elem
if ( position === "static" ) {
elem.style.position = "relative";
}
- curOffset = curElem.offset();
- curCSSTop = jQuery.css( elem, "top" );
- curCSSLeft = jQuery.css( elem, "left" );
- calculatePosition = ( position === "absolute" || position === "fixed" ) && ( curCSSTop + curCSSLeft ).indexOf("auto") > -1;
+ var curElem = jQuery( elem ),
+ curOffset = curElem.offset(),
+ curCSSTop = jQuery.css( elem, "top" ),
+ curCSSLeft = jQuery.css( elem, "left" ),
+ calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
+ props = {}, curPosition = {}, curTop, curLeft;
- // Need to be able to calculate position if either top or left is auto and position is either absolute or fixed
+ // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
if ( calculatePosition ) {
curPosition = curElem.position();
curTop = curPosition.top;
curLeft = curPosition.left;
-
} else {
curTop = parseFloat( curCSSTop ) || 0;
curLeft = parseFloat( curCSSLeft ) || 0;
@@ -8530,7 +9438,6 @@ jQuery.offset = {
if ( "using" in options ) {
options.using.call( elem, props );
-
} else {
curElem.css( props );
}
@@ -8546,14 +9453,13 @@ jQuery.fn.extend({
}
var offsetParent, offset,
- elem = this[ 0 ],
- parentOffset = { top: 0, left: 0 };
+ parentOffset = { top: 0, left: 0 },
+ elem = this[ 0 ];
- // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent
+ // fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent
if ( jQuery.css( elem, "position" ) === "fixed" ) {
- // We assume that getBoundingClientRect is available when computed position is fixed
+ // we assume that getBoundingClientRect is available when computed position is fixed
offset = elem.getBoundingClientRect();
-
} else {
// Get *real* offsetParent
offsetParent = this.offsetParent();
@@ -8565,26 +9471,26 @@ jQuery.fn.extend({
}
// Add offsetParent borders
- parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
+ parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
}
// Subtract parent offsets and element margins
+ // note: when an element has margin: auto the offsetLeft and marginLeft
+ // are the same in Safari causing offset.left to incorrectly be 0
return {
- top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
- left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
+ top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
+ left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true)
};
},
offsetParent: function() {
return this.map(function() {
- var offsetParent = this.offsetParent || docElem;
-
+ var offsetParent = this.offsetParent || document.documentElement;
while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position") === "static" ) ) {
offsetParent = offsetParent.offsetParent;
}
-
- return offsetParent || docElem;
+ return offsetParent || document.documentElement;
});
}
});
@@ -8592,20 +9498,22 @@ jQuery.fn.extend({
// Create scrollLeft and scrollTop methods
jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) {
- var top = "pageYOffset" === prop;
+ var top = /Y/.test( prop );
jQuery.fn[ method ] = function( val ) {
return jQuery.access( this, function( elem, method, val ) {
var win = getWindow( elem );
if ( val === undefined ) {
- return win ? win[ prop ] : elem[ method ];
+ return win ? (prop in win) ? win[ prop ] :
+ win.document.documentElement[ method ] :
+ elem[ method ];
}
if ( win ) {
win.scrollTo(
- !top ? val : window.pageXOffset,
- top ? val : window.pageYOffset
+ !top ? val : jQuery( win ).scrollLeft(),
+ top ? val : jQuery( win ).scrollTop()
);
} else {
@@ -8616,7 +9524,11 @@ jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( me
});
function getWindow( elem ) {
- return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
+ return jQuery.isWindow( elem ) ?
+ elem :
+ elem.nodeType === 9 ?
+ elem.defaultView || elem.parentWindow :
+ false;
}
// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
@@ -8662,29 +9574,24 @@ jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
// Limit scope pollution from any deprecated API
// (function() {
-jQuery.fn.andSelf = jQuery.fn.addBack;
-
// })();
-if ( typeof module === "object" && typeof module.exports === "object" ) {
- // Expose jQuery as module.exports in loaders that implement the Node
- // module pattern (including browserify). Do not create the global, since
- // the user will be storing it themselves locally, and globals are frowned
- // upon in the Node module world.
- module.exports = jQuery;
-} else {
- // Otherwise expose jQuery to the global object as usual
- window.jQuery = window.$ = jQuery;
-
- // Register as a named AMD module, since jQuery can be concatenated with other
- // files that may use define, but not via a proper concatenation script that
- // understands anonymous AMD modules. A named AMD is safest and most robust
- // way to register. Lowercase jquery is used because AMD module names are
- // derived from file names, and jQuery is normally delivered in a lowercase
- // file name. Do this after creating the global so that if an AMD module wants
- // to call noConflict to hide this version of jQuery, it will work.
- if ( typeof define === "function" && define.amd ) {
- define( "jquery", [], function () { return jQuery; } );
- }
+// Expose jQuery to the global object
+window.jQuery = window.$ = jQuery;
+
+// Expose jQuery as an AMD module, but only for AMD loaders that
+// understand the issues with loading multiple versions of jQuery
+// in a page that all might call define(). The loader will indicate
+// they have special allowances for multiple jQuery versions by
+// specifying define.amd.jQuery = true. Register as a named module,
+// since jQuery can be concatenated with other files that may use define,
+// but not use a proper concatenation script that understands anonymous
+// AMD modules. A named AMD is safest and most robust way to register.
+// Lowercase jquery is used because AMD module names are derived from
+// file names, and jQuery is normally delivered in a lowercase file name.
+// Do this after creating the global so that if an AMD module wants to call
+// noConflict to hide this version of jQuery, it will work.
+if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
+ define( "jquery", [], function () { return jQuery; } );
}
-})( this );
+})( window );