X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=resources%2Fjquery%2Fjquery.js;h=a86bf797a8bf75f65b0753e3a6f2d99d2ca440af;hb=9f1bca77eb6b71576ef21682d10804a0a00e7929;hp=07706829477ba50051cef233232023adec461e07;hpb=fae05504fedd31eee393b5c2263521874c9383a8;p=lhc%2Fweb%2Fwiklou.git diff --git a/resources/jquery/jquery.js b/resources/jquery/jquery.js index 0770682947..a86bf797a8 100644 --- a/resources/jquery/jquery.js +++ b/resources/jquery/jquery.js @@ -1,5 +1,5 @@ /*! - * jQuery JavaScript Library v1.8.0 + * jQuery JavaScript Library v1.8.3 * http://jquery.com/ * * Includes Sizzle.js @@ -9,7 +9,7 @@ * Released under the MIT license * http://jquery.org/license * - * Date: Thu Aug 09 2012 16:24:48 GMT-0400 (Eastern Daylight Time) + * Date: Tue Nov 13 2012 08:20:33 GMT-0500 (Eastern Standard Time) */ (function( window, undefined ) { var @@ -51,8 +51,8 @@ var core_rnotwhite = /\S/, core_rspace = /\s+/, - // IE doesn't match non-breaking spaces with \s - rtrim = core_rnotwhite.test("\xA0") ? (/^[\s\xA0]+|[\s\xA0]+$/g) : /^\s+|\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 to avoid XSS via location.hash (#9521) @@ -186,7 +186,7 @@ jQuery.fn = jQuery.prototype = { selector: "", // The current version of jQuery being used - jquery: "1.8.0", + jquery: "1.8.3", // The default length of a jQuery object is 0 length: 0, @@ -573,7 +573,7 @@ jQuery.extend({ }, nodeName: function( elem, name ) { - return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); }, // args is for internal usage only @@ -619,7 +619,7 @@ jQuery.extend({ }, // Use native String.trim function wherever possible - trim: core_trim ? + trim: core_trim && !core_trim.call("\uFEFF\xA0") ? function( text ) { return text == null ? "" : @@ -630,7 +630,7 @@ jQuery.extend({ function( text ) { return text == null ? "" : - text.toString().replace( rtrim, "" ); + ( text + "" ).replace( rtrim, "" ); }, // results is for internal usage only @@ -776,7 +776,7 @@ jQuery.extend({ }; // Set the guid of unique handler to the same of original handler, so it can be removed - proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; + proxy.guid = fn.guid = fn.guid || jQuery.guid++; return proxy; }, @@ -844,9 +844,10 @@ jQuery.ready.promise = function( obj ) { readyList = jQuery.Deferred(); - // Catch cases where $(document).ready() is called after the - // browser event has already occurred. - if ( document.readyState === "complete" || ( document.readyState !== "loading" && document.addEventListener ) ) { + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { // Handle it asynchronously to allow scripts the opportunity to delay ready setTimeout( jQuery.ready, 1 ); @@ -997,9 +998,12 @@ jQuery.Callbacks = function( options ) { var start = list.length; (function add( args ) { jQuery.each( args, function( _, arg ) { - if ( jQuery.isFunction( arg ) && ( !options.unique || !self.has( arg ) ) ) { - list.push( arg ); - } else if ( arg && arg.length ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { // Inspect recursively add( arg ); } @@ -1141,7 +1145,7 @@ jQuery.extend({ // Get a promise for this deferred // If obj is provided, the promise aspect is added to the object promise: function( obj ) { - return typeof obj === "object" ? jQuery.extend( obj, promise ) : promise; + return obj != null ? jQuery.extend( obj, promise ) : promise; } }, deferred = {}; @@ -1251,24 +1255,23 @@ jQuery.support = (function() { clickFn, div = document.createElement("div"); - // Preliminary tests + // Setup div.setAttribute( "className", "t" ); div.innerHTML = "
a"; + // Support tests won't run in some limited or non-browser environments all = div.getElementsByTagName("*"); a = div.getElementsByTagName("a")[ 0 ]; - a.style.cssText = "top:1px;float:left;opacity:.5"; - - // Can't get basic test support - if ( !all || !all.length || !a ) { + if ( !all || !a || !all.length ) { return {}; } - // First batch of supports tests + // 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 = { // IE strips leading whitespace when .innerHTML is used leadingWhitespace: ( div.firstChild.nodeType === 3 ), @@ -1310,7 +1313,7 @@ jQuery.support = (function() { // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) getSetAttribute: div.className !== "t", - // Tests for enctype support on a form(#6743) + // Tests for enctype support on a form (#6743) enctype: !!document.createElement("form").enctype, // Makes sure cloning an html5 element does not cause problems @@ -1452,10 +1455,8 @@ jQuery.support = (function() { support.boxSizing = ( div.offsetWidth === 4 ); support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 ); - // NOTE: To any future maintainer, window.getComputedStyle was used here - // instead of getComputedStyle because it gave a better gzip size. - // The difference between window.getComputedStyle and getComputedStyle is - // 7 bytes + // NOTE: To any future maintainer, we've window.getComputedStyle + // because jsdom on node.js will break without it. if ( window.getComputedStyle ) { support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; @@ -1505,7 +1506,7 @@ jQuery.support = (function() { return support; })(); -var rbrace = /^(?:\{.*\}|\[.*\])$/, +var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, rmultiDash = /([A-Z])/g; jQuery.extend({ @@ -1513,7 +1514,7 @@ jQuery.extend({ deletedIds: [], - // Please use with caution + // Remove at next major release (1.9/2.0) uuid: 0, // Unique for each copy of jQuery on the page @@ -1565,7 +1566,7 @@ jQuery.extend({ // 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 = jQuery.deletedIds.pop() || ++jQuery.uuid; + elem[ internalKey ] = id = jQuery.deletedIds.pop() || jQuery.guid++; } else { id = internalKey; } @@ -1739,7 +1740,7 @@ jQuery.fn.extend({ for ( l = attr.length; i < l; i++ ) { name = attr[i].name; - if ( name.indexOf( "data-" ) === 0 ) { + if ( !name.indexOf( "data-" ) ) { name = jQuery.camelCase( name.substring(5) ); dataAttr( elem, name, data[ name ] ); @@ -1868,6 +1869,7 @@ jQuery.extend({ type = type || "fx"; var queue = jQuery.queue( elem, type ), + startLength = queue.length, fn = queue.shift(), hooks = jQuery._queueHooks( elem, type ), next = function() { @@ -1877,6 +1879,7 @@ jQuery.extend({ // If the fx queue is dequeued, always remove the progress sentinel if ( fn === "inprogress" ) { fn = queue.shift(); + startLength--; } if ( fn ) { @@ -1891,7 +1894,8 @@ jQuery.extend({ delete hooks.stop; fn.call( elem, next, hooks ); } - if ( !queue.length && hooks ) { + + if ( !startLength && hooks ) { hooks.empty.fire(); } }, @@ -1977,7 +1981,8 @@ jQuery.fn.extend({ type = type || "fx"; while( i-- ) { - if ( (tmp = jQuery._data( elements[ i ], type + "queueHooks" )) && tmp.empty ) { + tmp = jQuery._data( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { count++; tmp.empty.add( resolve ); } @@ -2045,7 +2050,7 @@ jQuery.fn.extend({ setClass = " " + elem.className + " "; for ( c = 0, cl = classNames.length; c < cl; c++ ) { - if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { + if ( setClass.indexOf( " " + classNames[ c ] + " " ) < 0 ) { setClass += classNames[ c ] + " "; } } @@ -2078,7 +2083,7 @@ jQuery.fn.extend({ // loop over each item in the removal list for ( c = 0, cl = removes.length; c < cl; c++ ) { // Remove until there is nothing to remove, - while ( className.indexOf(" " + removes[ c ] + " ") > -1 ) { + while ( className.indexOf(" " + removes[ c ] + " ") >= 0 ) { className = className.replace( " " + removes[ c ] + " " , " " ); } } @@ -2132,7 +2137,7 @@ jQuery.fn.extend({ i = 0, l = this.length; for ( ; i < l; i++ ) { - if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { return true; } } @@ -2213,26 +2218,25 @@ jQuery.extend({ }, select: { get: function( elem ) { - var value, i, max, option, - index = elem.selectedIndex, - values = [], + var value, option, options = elem.options, - one = elem.type === "select-one"; - - // Nothing was selected - if ( index < 0 ) { - return null; - } + index = elem.selectedIndex, + one = elem.type === "select-one" || index < 0, + values = one ? null : [], + max = one ? index + 1 : options.length, + i = index < 0 ? + max : + one ? index : 0; // Loop through all the selected options - i = one ? index : 0; - max = one ? index + 1 : options.length; for ( ; i < max; i++ ) { option = options[ i ]; - // Don't return options that are disabled or in a disabled optgroup - if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && - (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { + // oldIE doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + // Don't return options that are disabled or in a disabled optgroup + ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) && + ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { // Get the specific value for the option value = jQuery( option ).val(); @@ -2247,11 +2251,6 @@ jQuery.extend({ } } - // Fixes Bug #2551 -- select.val() broken in IE after form.reset() - if ( one && !values.length && options.length ) { - return jQuery( options[ index ] ).val(); - } - return values; }, @@ -2310,7 +2309,7 @@ jQuery.extend({ return ret; } else { - elem.setAttribute( name, "" + value ); + elem.setAttribute( name, value + "" ); return value; } @@ -2574,7 +2573,7 @@ if ( !jQuery.support.style ) { return elem.style.cssText.toLowerCase() || undefined; }, set: function( elem, value ) { - return ( elem.style.cssText = "" + value ); + return ( elem.style.cssText = value + "" ); } }; } @@ -2707,6 +2706,7 @@ jQuery.event = { handler: handler, guid: handler.guid, selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), namespace: namespaces.join(".") }, handleObjIn ); @@ -2942,7 +2942,7 @@ jQuery.event = { } // Note that this is a bare JS function and not a jQuery handler handle = ontype && cur[ ontype ]; - if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) { + if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) { event.preventDefault(); } } @@ -2987,10 +2987,10 @@ jQuery.event = { // Make a writable jQuery.Event from the native event object event = jQuery.event.fix( event || window.event ); - var i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related, + var i, j, cur, ret, selMatch, matched, matches, handleObj, sel, related, handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), delegateCount = handlers.delegateCount, - args = [].slice.call( arguments ), + args = core_slice.call( arguments ), run_all = !event.exclusive && !event.namespace, special = jQuery.event.special[ event.type ] || {}, handlerQueue = []; @@ -3008,23 +3008,20 @@ jQuery.event = { // Avoid non-left-click bubbling in Firefox (#3861) if ( delegateCount && !(event.button && event.type === "click") ) { - // Pregenerate a single jQuery object for reuse with .is() - jqcur = jQuery(this); - jqcur.context = this; - for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { - // Don't process clicks (ONLY) on disabled elements (#6911, #8165, #xxxx) + // Don't process clicks (ONLY) on disabled elements (#6911, #8165, #11382, #11764) if ( cur.disabled !== true || event.type !== "click" ) { selMatch = {}; matches = []; - jqcur[0] = cur; for ( i = 0; i < delegateCount; i++ ) { handleObj = handlers[ i ]; sel = handleObj.selector; if ( selMatch[ sel ] === undefined ) { - selMatch[ sel ] = jqcur.is( sel ); + selMatch[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; } if ( selMatch[ sel ] ) { matches.push( handleObj ); @@ -3165,11 +3162,6 @@ jQuery.event = { }, special: { - ready: { - // Make sure the ready event is setup - setup: jQuery.bindReady - }, - load: { // Prevent triggered image.load events from bubbling to window.load noBubble: true @@ -3236,7 +3228,7 @@ jQuery.removeEvent = document.removeEventListener ? if ( elem.detachEvent ) { - // #8545, #7054, preventing memory leaks for custom events in IE6-8 – + // #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 ] === "undefined" ) { elem[ name ] = null; @@ -3458,7 +3450,7 @@ if ( !jQuery.support.changeBubbles ) { teardown: function() { jQuery.event.remove( this, "._change" ); - return rformElems.test( this.nodeName ); + return !rformElems.test( this.nodeName ); } }; } @@ -3599,7 +3591,7 @@ jQuery.fn.extend({ }, undelegate: function( selector, types, fn ) { // ( namespace ) or ( selector, types [, fn] ) - return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); + return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); }, trigger: function( type, data ) { @@ -3670,29 +3662,72 @@ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblcl }); /*! * Sizzle CSS Selector Engine - * Copyright 2012 jQuery Foundation and other contributors - * Released under the MIT license - * http://sizzlejs.com/ + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license + * http://sizzlejs.com/ */ (function( window, undefined ) { var cachedruns, - dirruns, - sortOrder, - siblingCheck, assertGetIdNotName, + Expr, + getText, + isXML, + contains, + compile, + sortOrder, + hasDuplicate, + outermostContext, + + baseHasDuplicate = true, + strundefined = "undefined", + + expando = ( "sizcache" + Math.random() ).replace( ".", "" ), + Token = String, document = window.document, docElem = document.documentElement, - - strundefined = "undefined", - hasDuplicate = false, - baseHasDuplicate = true, + dirruns = 0, done = 0, - slice = [].slice, + pop = [].pop, push = [].push, + slice = [].slice, + // Use a stripped-down indexOf if a native one is unavailable + indexOf = [].indexOf || function( elem ) { + var i = 0, + len = this.length; + for ( ; i < len; i++ ) { + if ( this[i] === elem ) { + return i; + } + } + return -1; + }, - expando = ( "sizcache" + Math.random() ).replace( ".", "" ), + // Augment a function for special use by Sizzle + markFunction = function( fn, value ) { + fn[ expando ] = value == null || value; + return fn; + }, + + createCache = function() { + var cache = {}, + keys = []; + + return markFunction(function( key, value ) { + // Only keep the most recent entries + if ( keys.push( key ) > Expr.cacheLength ) { + delete cache[ keys.shift() ]; + } + + // Retrieve with (key + " ") to avoid collision with native Object.prototype properties (see Issue #157) + return (cache[ key + " " ] = value); + }, cache ); + }, + + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), // Regex @@ -3710,29 +3745,29 @@ var cachedruns, operators = "([*^$|!~]?=)", attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]", - pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|((?:[^,]|\\\\,|(?:,(?=[^\\[]*\\]))|(?:,(?=[^\\(]*\\))))*))\\)|)", - pos = ":(nth|eq|gt|lt|first|last|even|odd)(?:\\((\\d*)\\)|)(?=[^-]|$)", - combinators = whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*", - groups = "(?=[^\\x20\\t\\r\\n\\f])(?:\\\\.|" + attributes + "|" + pseudos.replace( 2, 7 ) + "|[^\\\\(),])+", - - // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter - rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), - rcombinators = new RegExp( "^" + combinators ), + // Prefer arguments not in parens/brackets, + // then attribute selectors and non-pseudos (denoted by :), + // then anything else + // These preferences are here to reduce the number of selectors + // needing tokenize in the PSEUDO preFilter + pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)", - // All simple (non-comma) selectors, excluding insignifant trailing whitespace - rgroups = new RegExp( groups + "?(?=" + whitespace + "*,|$)", "g" ), + // For matchExpr.POS and matchExpr.needsContext + pos = ":(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", - // A selector, or everything after leading whitespace - // Optionally followed in either case by a ")" for terminating sub-selectors - rselector = new RegExp( "^(?:(?!,)(?:(?:^|,)" + whitespace + "*" + groups + ")*?|" + whitespace + "*(.*?))(\\)|$)" ), + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), - // All combinators and selector components (attribute test, tag, pseudo, etc.), the latter appearing together when consecutive - rtokens = new RegExp( groups.slice( 19, -6 ) + "\\x20\\t\\r\\n\\f>+~])+|" + combinators, "g" ), + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ), + rpseudo = new RegExp( pseudos ), // Easily-parseable/retrievable ID or TAG or CLASS selectors rquickExpr = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/, + rnot = /^:not/, rsibling = /[\x20\t\r\n\f]*[+~]/, rendsWithNot = /:not\($/, @@ -3745,56 +3780,46 @@ var cachedruns, "ID": new RegExp( "^#(" + characterEncoding + ")" ), "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ), - "TAG": new RegExp( "^(" + characterEncoding.replace( "[-", "[-\\*" ) + ")" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), "ATTR": new RegExp( "^" + attributes ), "PSEUDO": new RegExp( "^" + pseudos ), - "CHILD": new RegExp( "^:(only|nth|last|first)-child(?:\\(" + whitespace + + "POS": new RegExp( pos, "i" ), + "CHILD": new RegExp( "^:(only|nth|first|last)-child(?:\\(" + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), - "POS": new RegExp( pos, "ig" ), // For use in libraries implementing .is() "needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" ) }, - classCache = {}, - cachedClasses = [], - compilerCache = {}, - cachedSelectors = [], - - // Mark a function for use in filtering - markFunction = function( fn ) { - fn.sizzleFilter = true; - return fn; - }, - - // Returns a function to use in pseudos for input types - createInputFunction = function( type ) { - return function( elem ) { - // Check the input's nodeName and type - return elem.nodeName.toLowerCase() === "input" && elem.type === type; - }; - }, - - // Returns a function to use in pseudos for buttons - createButtonFunction = function( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return (name === "input" || name === "button") && elem.type === type; - }; - }, + // Support // Used for testing something on an element assert = function( fn ) { - var pass = false, - div = document.createElement("div"); + var div = document.createElement("div"); + try { - pass = fn( div ); - } catch (e) {} - // release memory in IE - div = null; - return pass; + return fn( div ); + } catch (e) { + return false; + } finally { + // release memory in IE + div = null; + } }, + // Check if getElementsByTagName("*") returns only elements + assertTagNameNoComments = assert(function( div ) { + div.appendChild( document.createComment("") ); + return !div.getElementsByTagName("*").length; + }), + + // Check if getAttribute returns normalized href attributes + assertHrefNotNormalized = assert(function( div ) { + div.innerHTML = ""; + return div.firstChild && typeof div.firstChild.getAttribute !== strundefined && + div.firstChild.getAttribute("href") === "#"; + }), + // Check if attributes should be retrieved by attribute nodes assertAttributes = assert(function( div ) { div.innerHTML = ""; @@ -3803,6 +3828,19 @@ var cachedruns, return type !== "boolean" && type !== "string"; }), + // Check if getElementsByClassName can be trusted + assertUsableClassName = assert(function( div ) { + // Opera can't find a second classname (in 9.6) + div.innerHTML = ""; + if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) { + return false; + } + + // Safari 3.2 caches class attributes and doesn't catch changes + div.lastChild.className = "e"; + return div.getElementsByClassName("e").length === 2; + }), + // Check if getElementById returns elements by name // Check if getElementsByName privileges form controls or returns elements by ID assertUsableName = assert(function( div ) { @@ -3814,58 +3852,45 @@ var cachedruns, // Test var pass = document.getElementsByName && // buggy browsers will return fewer than the correct 2 - document.getElementsByName( expando ).length === + document.getElementsByName( expando ).length === 2 + // buggy browsers will return more than the correct 0 - 2 + document.getElementsByName( expando + 0 ).length; + document.getElementsByName( expando + 0 ).length; assertGetIdNotName = !document.getElementById( expando ); // Cleanup docElem.removeChild( div ); return pass; - }), - - // Check if the browser returns only elements - // when doing getElementsByTagName("*") - assertTagNameNoComments = assert(function( div ) { - div.appendChild( document.createComment("") ); - return div.getElementsByTagName("*").length === 0; - }), - - // Check if getAttribute returns normalized href attributes - assertHrefNotNormalized = assert(function( div ) { - div.innerHTML = ""; - return div.firstChild && typeof div.firstChild.getAttribute !== strundefined && - div.firstChild.getAttribute("href") === "#"; - }), + }); - // Check if getElementsByClassName can be trusted - assertUsableClassName = assert(function( div ) { - // Opera can't find a second classname (in 9.6) - div.innerHTML = ""; - if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { - return false; +// If slice is not available, provide a backup +try { + slice.call( docElem.childNodes, 0 )[0].nodeType; +} catch ( e ) { + slice = function( i ) { + var elem, + results = []; + for ( ; (elem = this[i]); i++ ) { + results.push( elem ); } + return results; + }; +} - // Safari caches class attributes, doesn't catch changes (in 3.2) - div.lastChild.className = "e"; - return div.getElementsByClassName("e").length !== 1; - }); - -var Sizzle = function( selector, context, results, seed ) { +function Sizzle( selector, context, results, seed ) { results = results || []; context = context || document; var match, elem, xml, m, nodeType = context.nodeType; - if ( nodeType !== 1 && nodeType !== 9 ) { - return []; - } - if ( !selector || typeof selector !== "string" ) { return results; } + if ( nodeType !== 1 && nodeType !== 9 ) { + return []; + } + xml = isXML( context ); if ( !xml && !seed ) { @@ -3909,22 +3934,158 @@ var Sizzle = function( selector, context, results, seed ) { } // All others - return select( selector, context, results, seed, xml ); + return select( selector.replace( rtrim, "$1" ), context, results, seed, xml ); +} + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); }; -var Expr = Sizzle.selectors = { +Sizzle.matchesSelector = function( elem, expr ) { + return Sizzle( expr, null, null, [ elem ] ).length > 0; +}; - // Can be adjusted by the user - cacheLength: 50, +// Returns a function to use in pseudos for input types +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} - match: matchExpr, +// Returns a function to use in pseudos for buttons +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +// Returns a function to use in pseudos for positionals +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( nodeType ) { + if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (see #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + } else { - order: [ "ID", "TAG" ], + // If no nodeType, this is expected to be an array + for ( ; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } + return ret; +}; - attrHandle: {}, +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +// Element contains another +contains = Sizzle.contains = docElem.contains ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) ); + } : + docElem.compareDocumentPosition ? + function( a, b ) { + return b && !!( a.compareDocumentPosition( b ) & 16 ); + } : + function( a, b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + return false; + }; + +Sizzle.attr = function( elem, name ) { + var val, + xml = isXML( elem ); + + if ( !xml ) { + name = name.toLowerCase(); + } + if ( (val = Expr.attrHandle[ name ]) ) { + return val( elem ); + } + if ( xml || assertAttributes ) { + return elem.getAttribute( name ); + } + val = elem.getAttributeNode( name ); + return val ? + typeof elem[ name ] === "boolean" ? + elem[ name ] ? name : null : + val.specified ? val.value : null : + null; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, createPseudo: markFunction, + match: matchExpr, + + // IE6/7 return a modified href + attrHandle: assertHrefNotNormalized ? + {} : + { + "href": function( elem ) { + return elem.getAttribute( "href", 2 ); + }, + "type": function( elem ) { + return elem.getAttribute("type"); + } + }, + find: { "ID": assertGetIdNotName ? function( id, context, xml ) { @@ -3971,7 +4132,19 @@ var Expr = Sizzle.selectors = { return tmp; } return results; + }, + + "NAME": assertUsableName && function( tag, context ) { + if ( typeof context.getElementsByName !== strundefined ) { + return context.getElementsByName( name ); } + }, + + "CLASS": assertUsableClassName && function( className, context, xml ) { + if ( typeof context.getElementsByClassName !== strundefined && !xml ) { + return context.getElementsByClassName( className ); + } + } }, relative: { @@ -3996,7 +4169,7 @@ var Expr = Sizzle.selectors = { }, "CHILD": function( match ) { - /* matches from matchExpr.CHILD + /* matches from matchExpr["CHILD"] 1 type (only|nth|...) 2 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 3 xn-component of xn+y argument ([+-]?\d*n|) @@ -4027,24 +4200,30 @@ var Expr = Sizzle.selectors = { }, "PSEUDO": function( match ) { - var argument, - unquoted = match[4]; - + var unquoted, excess; if ( matchExpr["CHILD"].test( match[0] ) ) { return null; } - // Relinquish our claim on characters in `unquoted` from a closing parenthesis on - if ( unquoted && (argument = rselector.exec( unquoted )) && argument.pop() ) { - - match[0] = match[0].slice( 0, argument[0].length - unquoted.length - 1 ); - unquoted = argument[0].slice( 0, -1 ); + if ( match[3] ) { + match[2] = match[3]; + } else if ( (unquoted = match[4]) ) { + // Only check arguments that contain a pseudo + if ( rpseudo.test(unquoted) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + unquoted = unquoted.slice( 0, excess ); + match[0] = match[0].slice( 0, excess ); + } + match[2] = unquoted; } - // Quoted or unquoted, we have the full argument // Return only captures needed by the pseudo filter method (type and argument) - match.splice( 2, 3, unquoted || match[3] ); - return match; + return match.slice( 0, 3 ); } }, @@ -4076,91 +4255,65 @@ var Expr = Sizzle.selectors = { }, "CLASS": function( className ) { - var pattern = classCache[ className ]; - if ( !pattern ) { - pattern = classCache[ className ] = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" ); - cachedClasses.push( className ); - // Avoid too large of a cache - if ( cachedClasses.length > Expr.cacheLength ) { - delete classCache[ cachedClasses.shift() ]; - } - } - return function( elem ) { - return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" ); - }; + var pattern = classCache[ expando ][ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" ); + }); }, "ATTR": function( name, operator, check ) { - if ( !operator ) { - return function( elem ) { - return Sizzle.attr( elem, name ) != null; - }; - } - - return function( elem ) { - var result = Sizzle.attr( elem, name ), - value = result + ""; + return function( elem, context ) { + var result = Sizzle.attr( elem, name ); if ( result == null ) { return operator === "!="; } - - switch ( operator ) { - case "=": - return value === check; - case "!=": - return value !== check; - case "^=": - return check && value.indexOf( check ) === 0; - case "*=": - return check && value.indexOf( check ) > -1; - case "$=": - return check && value.substr( value.length - check.length ) === check; - case "~=": - return ( " " + value + " " ).indexOf( check ) > -1; - case "|=": - return value === check || value.substr( 0, check.length + 1 ) === check + "-"; + if ( !operator ) { + return true; } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.substr( result.length - check.length ) === check : + operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.substr( 0, check.length + 1 ) === check + "-" : + false; }; }, "CHILD": function( type, argument, first, last ) { if ( type === "nth" ) { - var doneName = done++; - return function( elem ) { - var parent, diff, - count = 0, - node = elem; + var node, diff, + parent = elem.parentNode; if ( first === 1 && last === 0 ) { return true; } - parent = elem.parentNode; - - if ( parent && (parent[ expando ] !== doneName || !elem.sizset) ) { + if ( parent ) { + diff = 0; for ( node = parent.firstChild; node; node = node.nextSibling ) { if ( node.nodeType === 1 ) { - node.sizset = ++count; - if ( node === elem ) { + diff++; + if ( elem === node ) { break; } } } - - parent[ expando ] = doneName; } - diff = elem.sizset - last; - - if ( first === 0 ) { - return diff === 0; - - } else { - return ( diff % first === 0 && diff / first >= 0 ); - } + // Incorporate the offset (or cast to NaN), then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); }; } @@ -4195,35 +4348,82 @@ var Expr = Sizzle.selectors = { }; }, - "PSEUDO": function( pseudo, argument, context, xml ) { + "PSEUDO": function( pseudo, argument ) { // pseudo-class names are case-insensitive // http://www.w3.org/TR/selectors/#pseudo-classes // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters - var fn = Expr.pseudos[ pseudo ] || Expr.pseudos[ pseudo.toLowerCase() ]; + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); - if ( !fn ) { - Sizzle.error( "unsupported pseudo: " + pseudo ); + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); } - // The user may set fn.sizzleFilter to indicate - // that arguments are needed to create the filter function - // just as Sizzle does - if ( !fn.sizzleFilter ) { - return fn; + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf.call( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; } - return fn( argument, context, xml ); + return fn; } }, pseudos: { - "not": markFunction(function( selector, context, xml ) { + "not": markFunction(function( selector ) { // Trim the selector passed to compile // to avoid treating leading and trailing // spaces as combinators - var matcher = compile( selector.replace( rtrim, "$1" ), context, xml ); + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { return function( elem ) { - return !matcher( elem ); + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; }; }), @@ -4273,18 +4473,6 @@ var Expr = Sizzle.selectors = { return true; }, - "contains": markFunction(function( text ) { - return function( elem ) { - return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; - }; - }), - - "has": markFunction(function( selector ) { - return function( elem ) { - return Sizzle( selector, elem ).length > 0; - }; - }), - "header": function( elem ) { return rheader.test( elem.nodeName ); }, @@ -4299,14 +4487,14 @@ var Expr = Sizzle.selectors = { }, // Input types - "radio": createInputFunction("radio"), - "checkbox": createInputFunction("checkbox"), - "file": createInputFunction("file"), - "password": createInputFunction("password"), - "image": createInputFunction("image"), + "radio": createInputPseudo("radio"), + "checkbox": createInputPseudo("checkbox"), + "file": createInputPseudo("file"), + "password": createInputPseudo("password"), + "image": createInputPseudo("image"), - "submit": createButtonFunction("submit"), - "reset": createButtonFunction("reset"), + "submit": createButtonPseudo("submit"), + "reset": createButtonPseudo("reset"), "button": function( elem ) { var name = elem.nodeName.toLowerCase(); @@ -4319,210 +4507,76 @@ var Expr = Sizzle.selectors = { "focus": function( elem ) { var doc = elem.ownerDocument; - return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href); + return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); }, "active": function( elem ) { return elem === elem.ownerDocument.activeElement; - } - }, - - setFilters: { - "first": function( elements, argument, not ) { - return not ? elements.slice( 1 ) : [ elements[0] ]; - }, - - "last": function( elements, argument, not ) { - var elem = elements.pop(); - return not ? elements : [ elem ]; - }, - - "even": function( elements, argument, not ) { - var results = [], - i = not ? 1 : 0, - len = elements.length; - for ( ; i < len; i = i + 2 ) { - results.push( elements[i] ); - } - return results; - }, - - "odd": function( elements, argument, not ) { - var results = [], - i = not ? 0 : 1, - len = elements.length; - for ( ; i < len; i = i + 2 ) { - results.push( elements[i] ); - } - return results; - }, - - "lt": function( elements, argument, not ) { - return not ? elements.slice( +argument ) : elements.slice( 0, +argument ); - }, - - "gt": function( elements, argument, not ) { - return not ? elements.slice( 0, +argument + 1 ) : elements.slice( +argument + 1 ); - }, - - "eq": function( elements, argument, not ) { - var elem = elements.splice( +argument, 1 ); - return not ? elements : elem; - } - } -}; - -// Deprecated -Expr.setFilters["nth"] = Expr.setFilters["eq"]; - -// Back-compat -Expr.filters = Expr.pseudos; - -// IE6/7 return a modified href -if ( !assertHrefNotNormalized ) { - Expr.attrHandle = { - "href": function( elem ) { - return elem.getAttribute( "href", 2 ); }, - "type": function( elem ) { - return elem.getAttribute("type"); - } - }; -} - -// Add getElementsByName if usable -if ( assertUsableName ) { - Expr.order.push("NAME"); - Expr.find["NAME"] = function( name, context ) { - if ( typeof context.getElementsByName !== strundefined ) { - return context.getElementsByName( name ); - } - }; -} - -// Add getElementsByClassName if usable -if ( assertUsableClassName ) { - Expr.order.splice( 1, 0, "CLASS" ); - Expr.find["CLASS"] = function( className, context, xml ) { - if ( typeof context.getElementsByClassName !== strundefined && !xml ) { - return context.getElementsByClassName( className ); - } - }; -} - -// If slice is not available, provide a backup -try { - slice.call( docElem.childNodes, 0 )[0].nodeType; -} catch ( e ) { - slice = function( i ) { - var elem, results = []; - for ( ; (elem = this[i]); i++ ) { - results.push( elem ); - } - return results; - }; -} -var isXML = Sizzle.isXML = function( elem ) { - // documentElement is verified for cases where it doesn't yet exist - // (such as loading iframes in IE - #4833) - var documentElement = elem && (elem.ownerDocument || elem).documentElement; - return documentElement ? documentElement.nodeName !== "HTML" : false; -}; + // Positional types + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), -// Element contains another -var contains = Sizzle.contains = docElem.compareDocumentPosition ? - function( a, b ) { - return !!( a.compareDocumentPosition( b ) & 16 ); - } : - docElem.contains ? - function( a, b ) { - var adown = a.nodeType === 9 ? a.documentElement : a, - bup = b.parentNode; - return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) ); - } : - function( a, b ) { - while ( (b = b.parentNode) ) { - if ( b === a ) { - return true; - } - } - return false; - }; + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), -/** - * Utility function for retrieving the text value of an array of DOM nodes - * @param {Array|Element} elem - */ -var getText = Sizzle.getText = function( elem ) { - var node, - ret = "", - i = 0, - nodeType = elem.nodeType; + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), - if ( nodeType ) { - if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { - // Use textContent for elements - // innerText usage removed for consistency of new lines (see #11153) - if ( typeof elem.textContent === "string" ) { - return elem.textContent; - } else { - // Traverse its children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { - ret += getText( elem ); - } + "even": createPositionalPseudo(function( matchIndexes, length ) { + for ( var i = 0; i < length; i += 2 ) { + matchIndexes.push( i ); } - } else if ( nodeType === 3 || nodeType === 4 ) { - return elem.nodeValue; - } - // Do not include comment or processing instruction nodes - } else { + return matchIndexes; + }), - // If no nodeType, this is expected to be an array - for ( ; (node = elem[i]); i++ ) { - // Do not traverse comment nodes - ret += getText( node ); - } - } - return ret; -}; + "odd": createPositionalPseudo(function( matchIndexes, length ) { + for ( var i = 1; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), -Sizzle.attr = function( elem, name ) { - var attr, - xml = isXML( elem ); + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + for ( var i = argument < 0 ? argument + length : argument; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), - if ( !xml ) { - name = name.toLowerCase(); - } - if ( Expr.attrHandle[ name ] ) { - return Expr.attrHandle[ name ]( elem ); - } - if ( assertAttributes || xml ) { - return elem.getAttribute( name ); + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + for ( var i = argument < 0 ? argument + length : argument; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) } - attr = elem.getAttributeNode( name ); - return attr ? - typeof elem[ name ] === "boolean" ? - elem[ name ] ? name : null : - attr.specified ? attr.value : null : - null; }; -Sizzle.error = function( msg ) { - throw new Error( "Syntax error, unrecognized expression: " + msg ); -}; +function siblingCheck( a, b, ret ) { + if ( a === b ) { + return ret; + } + + var cur = a.nextSibling; + + while ( cur ) { + if ( cur === b ) { + return -1; + } -// Check if the JavaScript engine is using some sort of -// optimization where it does not always call our comparision -// function. If that is the case, discard the hasDuplicate value. -// Thus far that includes Google Chrome. -[0, 0].sort(function() { - return (baseHasDuplicate = 0); -}); + cur = cur.nextSibling; + } + return 1; +} -if ( docElem.compareDocumentPosition ) { - sortOrder = function( a, b ) { +sortOrder = docElem.compareDocumentPosition ? + function( a, b ) { if ( a === b ) { hasDuplicate = true; return 0; @@ -4532,10 +4586,8 @@ if ( docElem.compareDocumentPosition ) { a.compareDocumentPosition : a.compareDocumentPosition(b) & 4 ) ? -1 : 1; - }; - -} else { - sortOrder = function( a, b ) { + } : + function( a, b ) { // The nodes are identical, we can exit early if ( a === b ) { hasDuplicate = true; @@ -4595,397 +4647,532 @@ if ( docElem.compareDocumentPosition ) { siblingCheck( ap[i], b, 1 ); }; - siblingCheck = function( a, b, ret ) { - if ( a === b ) { - return ret; - } - - var cur = a.nextSibling; - - while ( cur ) { - if ( cur === b ) { - return -1; - } - - cur = cur.nextSibling; - } - - return 1; - }; -} +// Always assume the presence of duplicates if sort doesn't +// pass them to our comparison function (as in Google Chrome). +[0, 0].sort( sortOrder ); +baseHasDuplicate = !hasDuplicate; // Document sorting and removing duplicates Sizzle.uniqueSort = function( results ) { var elem, - i = 1; + duplicates = [], + i = 1, + j = 0; - if ( sortOrder ) { - hasDuplicate = baseHasDuplicate; - results.sort( sortOrder ); + hasDuplicate = baseHasDuplicate; + results.sort( sortOrder ); - if ( hasDuplicate ) { - for ( ; (elem = results[i]); i++ ) { - if ( elem === results[ i - 1 ] ) { - results.splice( i--, 1 ); - } + if ( hasDuplicate ) { + for ( ; (elem = results[i]); i++ ) { + if ( elem === results[ i - 1 ] ) { + j = duplicates.push( i ); } } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } } return results; }; -function multipleContexts( selector, contexts, results, seed ) { - var i = 0, - len = contexts.length; - for ( ; i < len; i++ ) { - Sizzle( selector, contexts[i], results, seed ); - } -} - -function handlePOSGroup( selector, posfilter, argument, contexts, seed, not ) { - var results, - fn = Expr.setFilters[ posfilter.toLowerCase() ]; +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; - if ( !fn ) { - Sizzle.error( posfilter ); - } +function tokenize( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ expando ][ selector + " " ]; - if ( selector || !(results = seed) ) { - multipleContexts( selector || "*", contexts, (results = []), seed ); + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); } - return results.length > 0 ? fn( results, argument, not ) : []; -} - -function handlePOS( selector, context, results, seed, groups ) { - var match, not, anchor, ret, elements, currentContexts, part, lastIndex, - i = 0, - len = groups.length, - rpos = matchExpr["POS"], - // This is generated here in case matchExpr["POS"] is extended - rposgroups = new RegExp( "^" + rpos.source + "(?!" + whitespace + ")", "i" ), - // This is for making sure non-participating - // matching groups are represented cross-browser (IE6-8) - setUndefined = function() { - var i = 1, - len = arguments.length - 2; - for ( ; i < len; i++ ) { - if ( arguments[i] === undefined ) { - match[i] = undefined; - } - } - }; - - for ( ; i < len; i++ ) { - // Reset regex index to 0 - rpos.exec(""); - selector = groups[i]; - ret = []; - anchor = 0; - elements = seed; - while ( (match = rpos.exec( selector )) ) { - lastIndex = rpos.lastIndex = match.index + match[0].length; - if ( lastIndex > anchor ) { - part = selector.slice( anchor, match.index ); - anchor = lastIndex; - currentContexts = [ context ]; - - if ( rcombinators.test(part) ) { - if ( elements ) { - currentContexts = elements; - } - elements = seed; - } - - if ( (not = rendsWithNot.test( part )) ) { - part = part.slice( 0, -5 ).replace( rcombinators, "$&*" ); - } - - if ( match.length > 1 ) { - match[0].replace( rposgroups, setUndefined ); - } - elements = handlePOSGroup( part, match[1], match[2], currentContexts, elements, not ); - } - } + soFar = selector; + groups = []; + preFilters = Expr.preFilter; - if ( elements ) { - ret = ret.concat( elements ); + while ( soFar ) { - if ( (part = selector.slice( anchor )) && part !== ")" ) { - if ( rcombinators.test(part) ) { - multipleContexts( part, ret, results, seed ); - } else { - Sizzle( part, context, results, seed ? seed.concat(elements) : elements ); - } - } else { - push.apply( results, ret ); + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; } - } else { - Sizzle( selector, context, results, seed ); + groups.push( tokens = [] ); } - } - // Do not sort if this is a single filter - return len === 1 ? results : Sizzle.uniqueSort( results ); -} - -function tokenize( selector, context, xml ) { - var tokens, soFar, type, - groups = [], - i = 0, - - // Catch obvious selector issues: terminal ")"; nonempty fallback match - // rselector never fails to match *something* - match = rselector.exec( selector ), - matched = !match.pop() && !match.pop(), - selectorGroups = matched && selector.match( rgroups ) || [""], + matched = false; - preFilters = Expr.preFilter, - filters = Expr.filter, - checkContext = !xml && context !== document; + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + tokens.push( matched = new Token( match.shift() ) ); + soFar = soFar.slice( matched.length ); - for ( ; (soFar = selectorGroups[i]) != null && matched; i++ ) { - groups.push( tokens = [] ); - - // Need to make sure we're within a narrower context if necessary - // Adding a descendant combinator will generate what is needed - if ( checkContext ) { - soFar = " " + soFar; + // Cast descendant combinators to space + matched.type = match[0].replace( rtrim, " " ); } - while ( soFar ) { - matched = false; - - // Combinators - if ( (match = rcombinators.exec( soFar )) ) { - soFar = soFar.slice( match[0].length ); - - // Cast descendant combinators to space - matched = tokens.push({ part: match.pop().replace( rtrim, " " ), captures: match }); - } - - // Filters - for ( type in filters ) { - if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || - (match = preFilters[ type ]( match, context, xml )) ) ) { - - soFar = soFar.slice( match.shift().length ); - matched = tokens.push({ part: type, captures: match }); - } - } + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { - if ( !matched ) { - break; + tokens.push( matched = new Token( match.shift() ) ); + soFar = soFar.slice( matched.length ); + matched.type = type; + matched.matches = match; } } - } - if ( !matched ) { - Sizzle.error( selector ); + if ( !matched ) { + break; + } } - return groups; + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); } -function addCombinator( matcher, combinator, context ) { +function addCombinator( matcher, combinator, base ) { var dir = combinator.dir, + checkNonElements = base && combinator.dir === "parentNode", doneName = done++; - if ( !matcher ) { - // If there is no matcher to check, check against the context - matcher = function( elem ) { - return elem === context; - }; - } return combinator.first ? - function( elem, context ) { + // Check against closest ancestor/preceding element + function( elem, context, xml ) { while ( (elem = elem[ dir ]) ) { - if ( elem.nodeType === 1 ) { - return matcher( elem, context ) && elem; + if ( checkNonElements || elem.nodeType === 1 ) { + return matcher( elem, context, xml ); } } } : - function( elem, context ) { - var cache, - dirkey = doneName + "." + dirruns, - cachedkey = dirkey + "." + cachedruns; - while ( (elem = elem[ dir ]) ) { - if ( elem.nodeType === 1 ) { - if ( (cache = elem[ expando ]) === cachedkey ) { - return elem.sizset; - } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) { - if ( elem.sizset ) { - return elem; + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( !xml ) { + var cache, + dirkey = dirruns + " " + doneName + " ", + cachedkey = dirkey + cachedruns; + while ( (elem = elem[ dir ]) ) { + if ( checkNonElements || elem.nodeType === 1 ) { + if ( (cache = elem[ expando ]) === cachedkey ) { + return elem.sizset; + } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) { + if ( elem.sizset ) { + return elem; + } + } else { + elem[ expando ] = cachedkey; + if ( matcher( elem, context, xml ) ) { + elem.sizset = true; + return elem; + } + elem.sizset = false; } - } else { - elem[ expando ] = cachedkey; - if ( matcher( elem, context ) ) { - elem.sizset = true; + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( checkNonElements || elem.nodeType === 1 ) { + if ( matcher( elem, context, xml ) ) { return elem; } - elem.sizset = false; } } } }; } -function addMatcher( higher, deeper ) { - return higher ? - function( elem, context ) { - var result = deeper( elem, context ); - return result && higher( result === true ? elem : result, context ); +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; } : - deeper; + matchers[0]; } -// ["TAG", ">", "ID", " ", "CLASS"] -function matcherFromTokens( tokens, context, xml ) { - var token, matcher, - i = 0; +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; - for ( ; (token = tokens[i]); i++ ) { - if ( Expr.relative[ token.part ] ) { - matcher = addCombinator( matcher, Expr.relative[ token.part ], context ); - } else { - token.captures.push( context, xml ); - matcher = addMatcher( matcher, Expr.filter[ token.part ].apply( null, token.captures ) ); + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } } } - return matcher; + return newUnmatched; } -function matcherFromGroupMatchers( matchers ) { - return function( elem, context ) { - var matcher, - j = 0; - for ( ; (matcher = matchers[j]); j++ ) { - if ( matcher(elem, context) ) { - return true; - } +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); } - return false; - }; -} -var compile = Sizzle.compile = function( selector, context, xml ) { - var tokens, group, i, - cached = compilerCache[ selector ]; + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); - // Return a cached group function if already generated (context dependent) - if ( cached && cached.context === context ) { - return cached; - } + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } - // Generate a function of recursive functions that can be used to check each element - group = tokenize( selector, context, xml ); - for ( i = 0; (tokens = group[i]); i++ ) { - group[i] = matcherFromTokens( tokens, context, xml ); - } + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } - // Cache the compiled function - cached = compilerCache[ selector ] = matcherFromGroupMatchers( group ); - cached.context = context; - cached.runs = cached.dirruns = 0; - cachedSelectors.push( selector ); - // Ensure only the most recent are cached - if ( cachedSelectors.length > Expr.cacheLength ) { - delete compilerCache[ cachedSelectors.shift() ]; - } - return cached; -}; + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { -Sizzle.matches = function( expr, elements ) { - return Sizzle( expr, null, null, elements ); -}; + seed[temp] = !(results[temp] = elem); + } + } + } -Sizzle.matchesSelector = function( elem, expr ) { - return Sizzle( expr, null, null, [ elem ] ).length > 0; -}; + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} -var select = function( selector, context, results, seed, xml ) { - // Remove excessive whitespace - selector = selector.replace( rtrim, "$1" ); - var elements, matcher, i, len, elem, token, - type, findContext, notTokens, - match = selector.match( rgroups ), - tokens = selector.match( rtokens ), - contextNodeType = context.nodeType; - - // POS handling - if ( matchExpr["POS"].test(selector) ) { - return handlePOS( selector, context, results, seed, match ); +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf.call( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && tokens.slice( 0, i - 1 ).join("").replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && tokens.join("") + ); + } + matchers.push( matcher ); + } } - if ( seed ) { - elements = slice.call( seed, 0 ); + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, expandContext ) { + var elem, j, matcher, + setMatched = [], + matchedCount = 0, + i = "0", + unmatched = seed && [], + outermost = expandContext != null, + contextBackup = outermostContext, + // We must always have either seed elements or context + elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ), + // Nested matchers should use non-integer dirruns + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.E); + + if ( outermost ) { + outermostContext = context !== document && context; + cachedruns = superMatcher.el; + } - // To maintain document order, only narrow the - // set if there is one group - } else if ( match && match.length === 1 ) { + // Add elements passing elementMatchers directly to results + for ( ; (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + for ( j = 0; (matcher = elementMatchers[j]); j++ ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + cachedruns = ++superMatcher.el; + } + } - // Take a shortcut and set the context if the root selector is an ID - if ( tokens.length > 1 && contextNodeType === 9 && !xml && - (match = matchExpr["ID"].exec( tokens[0] )) ) { + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } - context = Expr.find["ID"]( match[1], context, xml )[0]; - if ( !context ) { - return results; + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } } - selector = selector.slice( tokens.shift().length ); - } + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + for ( j = 0; (matcher = setMatchers[j]); j++ ) { + matcher( unmatched, setMatched, context, xml ); + } - findContext = ( (match = rsibling.exec( tokens[0] )) && !match.index && context.parentNode ) || context; + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } - // Get the last token, excluding :not - notTokens = tokens.pop(); - token = notTokens.split(":not")[0]; + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } - for ( i = 0, len = Expr.order.length; i < len; i++ ) { - type = Expr.order[i]; + // Add matches to results + push.apply( results, setMatched ); - if ( (match = matchExpr[ type ].exec( token )) ) { - elements = Expr.find[ type ]( (match[1] || "").replace( rbackslash, "" ), findContext, xml ); + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { - if ( elements == null ) { - continue; + Sizzle.uniqueSort( results ); } + } - if ( token === notTokens ) { - selector = selector.slice( 0, selector.length - notTokens.length ) + - token.replace( matchExpr[ type ], "" ); + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } - if ( !selector ) { - push.apply( results, slice.call(elements, 0) ); - } - } - break; + return unmatched; + }; + + superMatcher.el = 0; + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ expando ][ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !group ) { + group = tokenize( selector ); + } + i = group.length; + while ( i-- ) { + cached = matcherFromTokens( group[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); } } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + } + return cached; +}; + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); } + return results; +} - // Only loop over the given elements once - // If selector is empty, we're already done - if ( selector ) { - matcher = compile( selector, context, xml ); - dirruns = matcher.dirruns++; +function select( selector, context, results, seed, xml ) { + var i, tokens, token, type, find, + match = tokenize( selector ), + j = match.length; - if ( elements == null ) { - elements = Expr.find["TAG"]( "*", (rsibling.test( selector ) && context.parentNode) || context ); - } - for ( i = 0; (elem = elements[i]); i++ ) { - cachedruns = matcher.runs++; - if ( matcher(elem, context) ) { - results.push( elem ); + if ( !seed ) { + // Try to minimize operations if there is only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + context.nodeType === 9 && !xml && + Expr.relative[ tokens[1].type ] ) { + + context = Expr.find["ID"]( token.matches[0].replace( rbackslash, "" ), context, xml )[0]; + if ( !context ) { + return results; + } + + selector = selector.slice( tokens.shift().length ); + } + + // Fetch a seed set for right-to-left matching + for ( i = matchExpr["POS"].test( selector ) ? -1 : tokens.length - 1; i >= 0; i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( rbackslash, "" ), + rsibling.test( tokens[0].type ) && context.parentNode || context, + xml + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && tokens.join(""); + if ( !selector ) { + push.apply( results, slice.call( seed, 0 ) ); + return results; + } + + break; + } + } } } } + // Compile and execute a filtering function + // Provide `match` to avoid retokenization if we modified the selector above + compile( selector, match )( + seed, + context, + xml, + results, + rsibling.test( selector ) + ); return results; -}; +} if ( document.querySelectorAll ) { (function() { @@ -4993,11 +5180,15 @@ if ( document.querySelectorAll ) { oldSelect = select, rescape = /'|\\/g, rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g, - rbuggyQSA = [], + + // qSa(:focus) reports false when true (Chrome 21), no need to also add to buggyMatches since matches checks buggyQSA + // A support test would require too much code (would include document ready) + rbuggyQSA = [ ":focus" ], + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) // A support test would require too much code (would include document ready) // just skip matchesSelector for :active - rbuggyMatches = [":active"], + rbuggyMatches = [ ":active" ], matches = docElem.matchesSelector || docElem.mozMatchesSelector || docElem.webkitMatchesSelector || @@ -5007,7 +5198,12 @@ if ( document.querySelectorAll ) { // Build QSA regex // Regex strategy adopted from Diego Perini assert(function( div ) { - div.innerHTML = ""; + // Select is set to empty string on purpose + // This is to test IE's treatment of not explictly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + div.innerHTML = ""; // IE8 - Some boolean attributes are not treated correctly if ( !div.querySelectorAll("[selected]").length ) { @@ -5033,42 +5229,52 @@ if ( document.querySelectorAll ) { // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) // IE8 throws error here (do not put tests after this one) - div.innerHTML = ""; + div.innerHTML = ""; if ( !div.querySelectorAll(":enabled").length ) { rbuggyQSA.push(":enabled", ":disabled"); } }); - rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + // rbuggyQSA always contains :focus, so no need for a length check + rbuggyQSA = /* rbuggyQSA.length && */ new RegExp( rbuggyQSA.join("|") ); select = function( selector, context, results, seed, xml ) { // Only use querySelectorAll when not filtering, // when this is not xml, // and when no QSA bugs apply - if ( !seed && !xml && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { - if ( context.nodeType === 9 ) { - try { - push.apply( results, slice.call(context.querySelectorAll( selector ), 0) ); - return results; - } catch(qsaError) {} + if ( !seed && !xml && !rbuggyQSA.test( selector ) ) { + var groups, i, + old = true, + nid = expando, + newContext = context, + newSelector = context.nodeType === 9 && selector; + // qSA works strangely on Element-rooted queries // We can work around this by specifying an extra ID on the root // and working up from there (Thanks to Andrew Dupont for the technique) // IE 8 doesn't work on object elements - } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { - var old = context.getAttribute("id"), - nid = old || expando, - newContext = rsibling.test( selector ) && context.parentNode || context; + if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); - if ( old ) { - nid = nid.replace( rescape, "\\$&" ); + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); } else { context.setAttribute( "id", nid ); } + nid = "[id='" + nid + "'] "; + i = groups.length; + while ( i-- ) { + groups[i] = nid + groups[i].join(""); + } + newContext = rsibling.test( selector ) && context.parentNode || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { try { push.apply( results, slice.call( newContext.querySelectorAll( - selector.replace( rgroups, "[id='" + nid + "'] $&" ) + newSelector ), 0 ) ); return results; } catch(qsaError) { @@ -5093,11 +5299,11 @@ if ( document.querySelectorAll ) { // Gecko does not error, returns false instead try { matches.call( div, "[test!='']:sizzle" ); - rbuggyMatches.push( Expr.match.PSEUDO ); + rbuggyMatches.push( "!=", pseudos ); } catch ( e ) {} }); - // rbuggyMatches always contains :active, so no need for a length check + // rbuggyMatches always contains :active and :focus, so no need for a length check rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join("|") ); Sizzle.matchesSelector = function( elem, expr ) { @@ -5105,7 +5311,7 @@ if ( document.querySelectorAll ) { expr = expr.replace( rattributeQuotes, "='$1']" ); // rbuggyMatches always contains :active, so no need for an existence check - if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && (!rbuggyQSA || !rbuggyQSA.test( expr )) ) { + if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && !rbuggyQSA.test( expr ) ) { try { var ret = matches.call( elem, expr ); @@ -5125,6 +5331,14 @@ if ( document.querySelectorAll ) { })(); } +// Deprecated +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Back-compat +function setFilters() {} +Expr.filters = setFilters.prototype = Expr.pseudos; +Expr.setFilters = new setFilters(); + // Override sizzle attribute retrieval Sizzle.attr = jQuery.attr; jQuery.find = Sizzle; @@ -5923,15 +6137,11 @@ jQuery.buildFragment = function( args, context, scripts ) { first = args[ 0 ]; // Set context from what may come in as undefined or a jQuery collection or a node + // Updated to fix #12266 where accessing context[0] could throw an exception in IE9/10 & + // also doubles as fix for #8950 where plain objects caused createDocumentFragment exception context = context || document; - context = (context[0] || context).ownerDocument || context[0] || context; - - // Ensure that an attr object doesn't incorrectly stand in as a document object - // Chrome and Firefox seem to allow this to occur and will throw exception - // Fixes #8950 - if ( typeof context.createDocumentFragment === "undefined" ) { - context = document; - } + context = !context.nodeType && context[0] || context; + context = context.ownerDocument || context; // Only cache "small" (1/2 KB) HTML strings that are associated with the main document // Cloning options loses the selected state, so don't cache them @@ -6076,8 +6286,8 @@ jQuery.extend({ }, clean: function( elems, context, fragment, scripts ) { - var j, safe, elem, tag, wrap, depth, div, hasBody, tbody, len, handleScript, jsTags, - i = 0, + var i, j, elem, tag, wrap, depth, div, hasBody, tbody, len, handleScript, jsTags, + safe = context === document && safeFragment, ret = []; // Ensure that context is a document @@ -6086,7 +6296,7 @@ jQuery.extend({ } // Use the already-created safe fragment if context permits - for ( safe = context === document && safeFragment; (elem = elems[i]) != null; i++ ) { + for ( i = 0; (elem = elems[i]) != null; i++ ) { if ( typeof elem === "number" ) { elem += ""; } @@ -6102,7 +6312,8 @@ jQuery.extend({ } else { // Ensure a safe container in which to render the html safe = safe || createSafeFragment( context ); - div = div || safe.appendChild( context.createElement("div") ); + div = context.createElement("div"); + safe.appendChild( div ); // Fix "XHTML"-style tags in all browsers elem = elem.replace(rxhtmlTag, "<$1>"); @@ -6145,21 +6356,20 @@ jQuery.extend({ elem = div.childNodes; - // Remember the top-level container for proper cleanup - div = safe.lastChild; + // Take out of fragment container (we need a fresh div each time) + div.parentNode.removeChild( div ); } } if ( elem.nodeType ) { ret.push( elem ); } else { - ret = jQuery.merge( ret, elem ); + jQuery.merge( ret, elem ); } } // Fix #11356: Clear elements from safeFragment if ( div ) { - safe.removeChild( div ); elem = div = safe = null; } @@ -6294,9 +6504,10 @@ if ( matched.browser ) { browser.version = matched.version; } -// Deprecated, use jQuery.browser.webkit instead -// Maintained for back-compat only -if ( browser.webkit ) { +// Chrome is Webkit, but Webkit is also Safari. +if ( browser.chrome ) { + browser.webkit = true; +} else if ( browser.webkit ) { browser.safari = true; } @@ -6322,23 +6533,25 @@ jQuery.sub = function() { var rootjQuerySub = jQuerySub(document); return jQuerySub; }; - + })(); var curCSS, iframe, iframeDoc, ralpha = /alpha\([^)]*\)/i, ropacity = /opacity=([^)]*)/, 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]).+)/, rmargin = /^margin/, rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ), rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ), rrelNum = new RegExp( "^([-+])=(" + core_pnum + ")", "i" ), - elemdisplay = {}, + elemdisplay = { BODY: "block" }, cssShow = { position: "absolute", visibility: "hidden", display: "block" }, cssNormalTransform = { letterSpacing: 0, - fontWeight: 400, - lineHeight: 1 + fontWeight: 400 }, cssExpand = [ "Top", "Right", "Bottom", "Left" ], @@ -6604,18 +6817,20 @@ jQuery.extend({ } }); -// NOTE: To any future maintainer, we've used both window.getComputedStyle -// and getComputedStyle here to produce a better gzip size +// NOTE: To any future maintainer, we've window.getComputedStyle +// because jsdom on node.js will break without it. if ( window.getComputedStyle ) { curCSS = function( elem, name ) { var ret, width, minWidth, maxWidth, - computed = getComputedStyle( elem, null ), + computed = window.getComputedStyle( elem, null ), style = elem.style; if ( computed ) { - ret = computed[ name ]; - if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) { + // getPropertyValue is only needed for .css('filter') in IE9, see #12537 + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { ret = jQuery.style( elem, name ); } @@ -6738,7 +6953,10 @@ function getWidthOrHeight( elem, name, extra ) { valueIsBorderBox = true, isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box"; - if ( val <= 0 ) { + // some non-html elements return undefined for offsetWidth, so check for null/undefined + // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 + // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 + if ( val <= 0 || val == null ) { // Fall back to computed then uncomputed css if necessary val = curCSS( elem, name ); if ( val < 0 || val == null ) { @@ -6817,12 +7035,14 @@ jQuery.each([ "height", "width" ], function( i, name ) { jQuery.cssHooks[ name ] = { get: function( elem, computed, extra ) { if ( computed ) { - if ( elem.offsetWidth !== 0 || curCSS( elem, "display" ) !== "none" ) { - return getWidthOrHeight( elem, name, extra ); - } else { + // certain elements can have dimension info if we invisibly show them + // however, it must have a current display style that would benefit from this + if ( elem.offsetWidth === 0 && rdisplayswap.test( curCSS( elem, "display" ) ) ) { return jQuery.swap( elem, cssShow, function() { return getWidthOrHeight( elem, name, extra ); }); + } else { + return getWidthOrHeight( elem, name, extra ); } } }, @@ -7056,10 +7276,10 @@ function buildParams( prefix, obj, traditional, add ) { add( prefix, obj ); } } -var // Document location - ajaxLocation, - // Document location segments +var + // Document location ajaxLocParts, + ajaxLocation, rhash = /#.*$/, rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL @@ -7228,7 +7448,7 @@ jQuery.fn.load = function( url, params, callback ) { params = undefined; // Otherwise, build a param string - } else if ( typeof params === "object" ) { + } else if ( params && typeof params === "object" ) { type = "POST"; } @@ -7576,7 +7796,7 @@ jQuery.extend({ // Set data for the fake xhr object jqXHR.status = status; - jqXHR.statusText = "" + ( nativeStatusText || statusText ); + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; // Success/Error if ( isSuccess ) { @@ -7636,11 +7856,11 @@ jQuery.extend({ // Extract dataTypes list s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( core_rspace ); - // Determine if a cross-domain request is in order + // A cross-domain request is in order when we have a protocol:host:port mismatch if ( s.crossDomain == null ) { parts = rurl.exec( s.url.toLowerCase() ); s.crossDomain = !!( parts && - ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] || + ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] || ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) != ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) ) ); @@ -8262,7 +8482,7 @@ if ( jQuery.support.ajax ) { // on any attempt to access responseText (#11426) try { responses.text = xhr.responseText; - } catch( _ ) { + } catch( e ) { } // Firefox throws an exception when accessing @@ -8338,12 +8558,13 @@ var fxNow, timerId, animationPrefilters = [ defaultPrefilter ], tweeners = { "*": [function( prop, value ) { - var end, unit, prevScale, + var end, unit, tween = this.createTween( prop, value ), parts = rfxnum.exec( value ), target = tween.cur(), start = +target || 0, - scale = 1; + scale = 1, + maxIterations = 20; if ( parts ) { end = +parts[2]; @@ -8359,17 +8580,15 @@ var fxNow, timerId, do { // If previous iteration zeroed out, double until we get *something* // Use a string for doubling factor so we don't accidentally see scale as unchanged below - prevScale = scale = scale || ".5"; + scale = scale || ".5"; // Adjust and apply start = start / scale; jQuery.style( tween.elem, prop, start + unit ); - // Update scale, tolerating zeroes from tween.cur() - scale = tween.cur() / target; - - // Stop looping if we've hit the mark or scale is unchanged - } while ( scale !== 1 && scale !== prevScale ); + // Update scale, tolerating zero or NaN from tween.cur() + // And breaking the loop if scale is unchanged or perfect, or if we've just had enough + } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations ); } tween.unit = unit; @@ -8416,7 +8635,9 @@ function Animation( elem, properties, options ) { tick = function() { var currentTime = fxNow || createFxNow(), remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), - percent = 1 - ( remaining / animation.duration || 0 ), + // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, index = 0, length = animation.tweens.length; @@ -8568,7 +8789,7 @@ jQuery.Animation = jQuery.extend( Animation, { }); function defaultPrefilter( elem, props, opts ) { - var index, prop, value, length, dataShow, tween, hooks, oldfire, + var index, prop, value, length, dataShow, toggle, tween, hooks, oldfire, anim = this, style = elem.style, orig = {}, @@ -8642,6 +8863,7 @@ function defaultPrefilter( elem, props, opts ) { value = props[ index ]; if ( rfxtypes.exec( value ) ) { delete props[ index ]; + toggle = toggle || value === "toggle"; if ( value === ( hidden ? "hide" : "show" ) ) { continue; } @@ -8652,6 +8874,14 @@ function defaultPrefilter( elem, props, opts ) { length = handled.length; if ( length ) { dataShow = jQuery._data( elem, "fxshow" ) || jQuery._data( elem, "fxshow", {} ); + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + + // store state if its toggle - enables .stop().toggle() to "reverse" + if ( toggle ) { + dataShow.hidden = !hidden; + } if ( hidden ) { jQuery( elem ).show(); } else { @@ -8709,7 +8939,13 @@ Tween.prototype = { var eased, hooks = Tween.propHooks[ this.prop ]; - this.pos = eased = jQuery.easing[ this.easing ]( percent, this.options.duration * percent, 0, 1, this.options.duration ); + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } this.now = ( this.end - this.start ) * eased + this.start; if ( this.options.step ) { @@ -8867,6 +9103,7 @@ function genFx( type, includeWidth ) { // if we include width, step value is 1 to do all cssExpand values, // if we don't include width, step value is 2 to skip over Left and Right + includeWidth = includeWidth? 1 : 0; for( ; i < 4 ; i += 2 - includeWidth ) { which = cssExpand[ i ]; attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; @@ -8941,6 +9178,8 @@ jQuery.fx.tick = function() { timers = jQuery.timers, i = 0; + fxNow = jQuery.now(); + for ( ; i < timers.length; i++ ) { timer = timers[ i ]; // Checks the timer has not already been removed @@ -8952,6 +9191,7 @@ jQuery.fx.tick = function() { if ( !timers.length ) { jQuery.fx.stop(); } + fxNow = undefined; }; jQuery.fx.timer = function( timer ) { @@ -8995,7 +9235,8 @@ jQuery.fn.offset = function( options ) { }); } - var box, docElem, body, win, clientTop, clientLeft, scrollTop, scrollLeft, top, left, + var docElem, body, win, clientTop, clientLeft, scrollTop, scrollLeft, + box = { top: 0, left: 0 }, elem = this[ 0 ], doc = elem && elem.ownerDocument; @@ -9009,21 +9250,25 @@ jQuery.fn.offset = function( options ) { docElem = doc.documentElement; - // Make sure we're not dealing with a disconnected DOM node + // Make sure it's not a disconnected DOM node if ( !jQuery.contains( docElem, elem ) ) { - return { top: 0, left: 0 }; + return box; } - box = elem.getBoundingClientRect(); + // If we don't have gBCR, just use 0,0 rather than error + // BlackBerry 5, iOS 3 (original iPhone) + if ( typeof elem.getBoundingClientRect !== "undefined" ) { + box = elem.getBoundingClientRect(); + } win = getWindow( doc ); clientTop = docElem.clientTop || body.clientTop || 0; clientLeft = docElem.clientLeft || body.clientLeft || 0; scrollTop = win.pageYOffset || docElem.scrollTop; scrollLeft = win.pageXOffset || docElem.scrollLeft; - top = box.top + scrollTop - clientTop; - left = box.left + scrollLeft - clientLeft; - - return { top: top, left: left }; + return { + top: box.top + scrollTop - clientTop, + left: box.left + scrollLeft - clientLeft + }; }; jQuery.offset = { @@ -9201,7 +9446,7 @@ jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { // Set width or height on the element jQuery.style( elem, type, value, extra ); - }, type, chainable ? margin : undefined, chainable ); + }, type, chainable ? margin : undefined, chainable, null ); }; }); });