/*!
- * jQuery JavaScript Library v1.8.0
+ * jQuery JavaScript Library v1.8.1
* http://jquery.com/
*
* Includes Sizzle.js
* Released under the MIT license
* http://jquery.org/license
*
- * Date: Thu Aug 09 2012 16:24:48 GMT-0400 (Eastern Daylight Time)
+ * Date: Thu Aug 30 2012 17:17:22 GMT-0400 (Eastern Daylight Time)
*/
(function( window, undefined ) {
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 <tag> to avoid XSS via location.hash (#9521)
selector: "",
// The current version of jQuery being used
- jquery: "1.8.0",
+ jquery: "1.8.1",
// The default length of a jQuery object is 0
length: 0,
},
// Use native String.trim function wherever possible
- trim: core_trim ?
+ trim: core_trim && !core_trim.call("\uFEFF\xA0") ?
function( text ) {
return text == null ?
"" :
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 );
var start = list.length;
(function add( args ) {
jQuery.each( args, function( _, arg ) {
- if ( jQuery.isFunction( arg ) && ( !options.unique || !self.has( arg ) ) ) {
+ var type = jQuery.type( arg );
+ if ( type === "function" && ( !options.unique || !self.has( arg ) ) ) {
list.push( arg );
- } else if ( arg && arg.length ) {
+ } else if ( arg && arg.length && type !== "string" ) {
// Inspect recursively
add( arg );
}
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";
return support;
})();
-var rbrace = /^(?:\{.*\}|\[.*\])$/,
+var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/,
rmultiDash = /([A-Z])/g;
jQuery.extend({
type = type || "fx";
var queue = jQuery.queue( elem, type ),
+ startLength = queue.length,
fn = queue.shift(),
hooks = jQuery._queueHooks( elem, type ),
next = function() {
// If the fx queue is dequeued, always remove the progress sentinel
if ( fn === "inprogress" ) {
fn = queue.shift();
+ startLength--;
}
if ( fn ) {
delete hooks.stop;
fn.call( elem, next, hooks );
}
- if ( !queue.length && hooks ) {
+
+ if ( !startLength && hooks ) {
hooks.empty.fire();
}
},
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 );
}
// 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 ),
// 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 ] = jQuery( sel, this ).index( cur ) >= 0;
}
if ( selMatch[ sel ] ) {
matches.push( handleObj );
},
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
teardown: function() {
jQuery.event.remove( this, "._change" );
- return rformElems.test( this.nodeName );
+ return !rformElems.test( this.nodeName );
}
};
}
*/\r
(function( window, undefined ) {\r
\r
-var cachedruns,\r
- dirruns,\r
- sortOrder,\r
- siblingCheck,\r
+var dirruns,\r
+ cachedruns,\r
assertGetIdNotName,\r
+ Expr,\r
+ getText,\r
+ isXML,\r
+ contains,\r
+ compile,\r
+ sortOrder,\r
+ hasDuplicate,\r
+\r
+ baseHasDuplicate = true,\r
+ strundefined = "undefined",\r
+\r
+ expando = ( "sizcache" + Math.random() ).replace( ".", "" ),\r
\r
document = window.document,\r
docElem = document.documentElement,\r
-\r
- strundefined = "undefined",\r
- hasDuplicate = false,\r
- baseHasDuplicate = true,\r
done = 0,\r
slice = [].slice,\r
push = [].push,\r
\r
- expando = ( "sizcache" + Math.random() ).replace( ".", "" ),\r
+ // Augment a function for special use by Sizzle\r
+ markFunction = function( fn, value ) {\r
+ fn[ expando ] = value || true;\r
+ return fn;\r
+ },\r
+\r
+ createCache = function() {\r
+ var cache = {},\r
+ keys = [];\r
+\r
+ return markFunction(function( key, value ) {\r
+ // Only keep the most recent entries\r
+ if ( keys.push( key ) > Expr.cacheLength ) {\r
+ delete cache[ keys.shift() ];\r
+ }\r
+\r
+ return (cache[ key ] = value);\r
+ }, cache );\r
+ },\r
+\r
+ classCache = createCache(),\r
+ tokenCache = createCache(),\r
+ compilerCache = createCache(),\r
\r
// Regex\r
\r
operators = "([*^$|!~]?=)",\r
attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +\r
"*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",\r
- pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|((?:[^,]|\\\\,|(?:,(?=[^\\[]*\\]))|(?:,(?=[^\\(]*\\))))*))\\)|)",\r
- pos = ":(nth|eq|gt|lt|first|last|even|odd)(?:\\((\\d*)\\)|)(?=[^-]|$)",\r
- combinators = whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*",\r
- groups = "(?=[^\\x20\\t\\r\\n\\f])(?:\\\\.|" + attributes + "|" + pseudos.replace( 2, 7 ) + "|[^\\\\(),])+",\r
-\r
- // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\r
- rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),\r
\r
- rcombinators = new RegExp( "^" + combinators ),\r
+ // Prefer arguments not in parens/brackets,\r
+ // then attribute selectors and non-pseudos (denoted by :),\r
+ // then anything else\r
+ // These preferences are here to reduce the number of selectors\r
+ // needing tokenize in the PSEUDO preFilter\r
+ pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)",\r
\r
- // All simple (non-comma) selectors, excluding insignifant trailing whitespace\r
- rgroups = new RegExp( groups + "?(?=" + whitespace + "*,|$)", "g" ),\r
+ // For matchExpr.POS and matchExpr.needsContext\r
+ pos = ":(nth|eq|gt|lt|first|last|even|odd)(?:\\(((?:-\\d)?\\d*)\\)|)(?=[^-]|$)",\r
\r
- // A selector, or everything after leading whitespace\r
- // Optionally followed in either case by a ")" for terminating sub-selectors\r
- rselector = new RegExp( "^(?:(?!,)(?:(?:^|,)" + whitespace + "*" + groups + ")*?|" + whitespace + "*(.*?))(\\)|$)" ),\r
+ // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\r
+ rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),\r
\r
- // All combinators and selector components (attribute test, tag, pseudo, etc.), the latter appearing together when consecutive\r
- rtokens = new RegExp( groups.slice( 19, -6 ) + "\\x20\\t\\r\\n\\f>+~])+|" + combinators, "g" ),\r
+ rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),\r
+ rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ),\r
+ rpseudo = new RegExp( pseudos ),\r
\r
// Easily-parseable/retrievable ID or TAG or CLASS selectors\r
rquickExpr = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,\r
\r
+ rnot = /^:not/,\r
rsibling = /[\x20\t\r\n\f]*[+~]/,\r
rendsWithNot = /:not\($/,\r
\r
"ID": new RegExp( "^#(" + characterEncoding + ")" ),\r
"CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),\r
"NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ),\r
- "TAG": new RegExp( "^(" + characterEncoding.replace( "[-", "[-\\*" ) + ")" ),\r
+ "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),\r
"ATTR": new RegExp( "^" + attributes ),\r
"PSEUDO": new RegExp( "^" + pseudos ),\r
"CHILD": new RegExp( "^:(only|nth|last|first)-child(?:\\(" + whitespace +\r
"needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" )\r
},\r
\r
- classCache = {},\r
- cachedClasses = [],\r
- compilerCache = {},\r
- cachedSelectors = [],\r
-\r
- // Mark a function for use in filtering\r
- markFunction = function( fn ) {\r
- fn.sizzleFilter = true;\r
- return fn;\r
- },\r
-\r
- // Returns a function to use in pseudos for input types\r
- createInputFunction = function( type ) {\r
- return function( elem ) {\r
- // Check the input's nodeName and type\r
- return elem.nodeName.toLowerCase() === "input" && elem.type === type;\r
- };\r
- },\r
-\r
- // Returns a function to use in pseudos for buttons\r
- createButtonFunction = function( type ) {\r
- return function( elem ) {\r
- var name = elem.nodeName.toLowerCase();\r
- return (name === "input" || name === "button") && elem.type === type;\r
- };\r
- },\r
+ // Support\r
\r
// Used for testing something on an element\r
assert = function( fn ) {\r
- var pass = false,\r
- div = document.createElement("div");\r
+ var div = document.createElement("div");\r
+\r
try {\r
- pass = fn( div );\r
- } catch (e) {}\r
- // release memory in IE\r
- div = null;\r
- return pass;\r
+ return fn( div );\r
+ } catch (e) {\r
+ return false;\r
+ } finally {\r
+ // release memory in IE\r
+ div = null;\r
+ }\r
},\r
\r
+ // Check if getElementsByTagName("*") returns only elements\r
+ assertTagNameNoComments = assert(function( div ) {\r
+ div.appendChild( document.createComment("") );\r
+ return !div.getElementsByTagName("*").length;\r
+ }),\r
+\r
+ // Check if getAttribute returns normalized href attributes\r
+ assertHrefNotNormalized = assert(function( div ) {\r
+ div.innerHTML = "<a href='#'></a>";\r
+ return div.firstChild && typeof div.firstChild.getAttribute !== strundefined &&\r
+ div.firstChild.getAttribute("href") === "#";\r
+ }),\r
+\r
// Check if attributes should be retrieved by attribute nodes\r
assertAttributes = assert(function( div ) {\r
div.innerHTML = "<select></select>";\r
return type !== "boolean" && type !== "string";\r
}),\r
\r
+ // Check if getElementsByClassName can be trusted\r
+ assertUsableClassName = assert(function( div ) {\r
+ // Opera can't find a second classname (in 9.6)\r
+ div.innerHTML = "<div class='hidden e'></div><div class='hidden'></div>";\r
+ if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) {\r
+ return false;\r
+ }\r
+\r
+ // Safari 3.2 caches class attributes and doesn't catch changes\r
+ div.lastChild.className = "e";\r
+ return div.getElementsByClassName("e").length === 2;\r
+ }),\r
+\r
// Check if getElementById returns elements by name\r
// Check if getElementsByName privileges form controls or returns elements by ID\r
assertUsableName = assert(function( div ) {\r
// Test\r
var pass = document.getElementsByName &&\r
// buggy browsers will return fewer than the correct 2\r
- document.getElementsByName( expando ).length ===\r
+ document.getElementsByName( expando ).length === 2 +\r
// buggy browsers will return more than the correct 0\r
- 2 + document.getElementsByName( expando + 0 ).length;\r
+ document.getElementsByName( expando + 0 ).length;\r
assertGetIdNotName = !document.getElementById( expando );\r
\r
// Cleanup\r
docElem.removeChild( div );\r
\r
return pass;\r
- }),\r
-\r
- // Check if the browser returns only elements\r
- // when doing getElementsByTagName("*")\r
- assertTagNameNoComments = assert(function( div ) {\r
- div.appendChild( document.createComment("") );\r
- return div.getElementsByTagName("*").length === 0;\r
- }),\r
-\r
- // Check if getAttribute returns normalized href attributes\r
- assertHrefNotNormalized = assert(function( div ) {\r
- div.innerHTML = "<a href='#'></a>";\r
- return div.firstChild && typeof div.firstChild.getAttribute !== strundefined &&\r
- div.firstChild.getAttribute("href") === "#";\r
- }),\r
+ });\r
\r
- // Check if getElementsByClassName can be trusted\r
- assertUsableClassName = assert(function( div ) {\r
- // Opera can't find a second classname (in 9.6)\r
- div.innerHTML = "<div class='hidden e'></div><div class='hidden'></div>";\r
- if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {\r
- return false;\r
+// If slice is not available, provide a backup\r
+try {\r
+ slice.call( docElem.childNodes, 0 )[0].nodeType;\r
+} catch ( e ) {\r
+ slice = function( i ) {\r
+ var elem, results = [];\r
+ for ( ; (elem = this[i]); i++ ) {\r
+ results.push( elem );\r
}\r
+ return results;\r
+ };\r
+}\r
\r
- // Safari caches class attributes, doesn't catch changes (in 3.2)\r
- div.lastChild.className = "e";\r
- return div.getElementsByClassName("e").length !== 1;\r
- });\r
-\r
-var Sizzle = function( selector, context, results, seed ) {\r
+function Sizzle( selector, context, results, seed ) {\r
results = results || [];\r
context = context || document;\r
var match, elem, xml, m,\r
\r
// All others\r
return select( selector, context, results, seed, xml );\r
+}\r
+\r
+Sizzle.matches = function( expr, elements ) {\r
+ return Sizzle( expr, null, null, elements );\r
};\r
\r
-var Expr = Sizzle.selectors = {\r
+Sizzle.matchesSelector = function( elem, expr ) {\r
+ return Sizzle( expr, null, null, [ elem ] ).length > 0;\r
+};\r
\r
- // Can be adjusted by the user\r
- cacheLength: 50,\r
+// Returns a function to use in pseudos for input types\r
+function createInputPseudo( type ) {\r
+ return function( elem ) {\r
+ var name = elem.nodeName.toLowerCase();\r
+ return name === "input" && elem.type === type;\r
+ };\r
+}\r
\r
- match: matchExpr,\r
+// Returns a function to use in pseudos for buttons\r
+function createButtonPseudo( type ) {\r
+ return function( elem ) {\r
+ var name = elem.nodeName.toLowerCase();\r
+ return (name === "input" || name === "button") && elem.type === type;\r
+ };\r
+}\r
\r
- order: [ "ID", "TAG" ],\r
+/**\r
+ * Utility function for retrieving the text value of an array of DOM nodes\r
+ * @param {Array|Element} elem\r
+ */\r
+getText = Sizzle.getText = function( elem ) {\r
+ var node,\r
+ ret = "",\r
+ i = 0,\r
+ nodeType = elem.nodeType;\r
\r
- attrHandle: {},\r
+ if ( nodeType ) {\r
+ if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\r
+ // Use textContent for elements\r
+ // innerText usage removed for consistency of new lines (see #11153)\r
+ if ( typeof elem.textContent === "string" ) {\r
+ return elem.textContent;\r
+ } else {\r
+ // Traverse its children\r
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\r
+ ret += getText( elem );\r
+ }\r
+ }\r
+ } else if ( nodeType === 3 || nodeType === 4 ) {\r
+ return elem.nodeValue;\r
+ }\r
+ // Do not include comment or processing instruction nodes\r
+ } else {\r
+\r
+ // If no nodeType, this is expected to be an array\r
+ for ( ; (node = elem[i]); i++ ) {\r
+ // Do not traverse comment nodes\r
+ ret += getText( node );\r
+ }\r
+ }\r
+ return ret;\r
+};\r
+\r
+isXML = Sizzle.isXML = function isXML( elem ) {\r
+ // documentElement is verified for cases where it doesn't yet exist\r
+ // (such as loading iframes in IE - #4833)\r
+ var documentElement = elem && (elem.ownerDocument || elem).documentElement;\r
+ return documentElement ? documentElement.nodeName !== "HTML" : false;\r
+};\r
+\r
+// Element contains another\r
+contains = Sizzle.contains = docElem.contains ?\r
+ function( a, b ) {\r
+ var adown = a.nodeType === 9 ? a.documentElement : a,\r
+ bup = b && b.parentNode;\r
+ return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) );\r
+ } :\r
+ docElem.compareDocumentPosition ?\r
+ function( a, b ) {\r
+ return b && !!( a.compareDocumentPosition( b ) & 16 );\r
+ } :\r
+ function( a, b ) {\r
+ while ( (b = b.parentNode) ) {\r
+ if ( b === a ) {\r
+ return true;\r
+ }\r
+ }\r
+ return false;\r
+ };\r
+\r
+Sizzle.attr = function( elem, name ) {\r
+ var attr,\r
+ xml = isXML( elem );\r
+\r
+ if ( !xml ) {\r
+ name = name.toLowerCase();\r
+ }\r
+ if ( Expr.attrHandle[ name ] ) {\r
+ return Expr.attrHandle[ name ]( elem );\r
+ }\r
+ if ( assertAttributes || xml ) {\r
+ return elem.getAttribute( name );\r
+ }\r
+ attr = elem.getAttributeNode( name );\r
+ return attr ?\r
+ typeof elem[ name ] === "boolean" ?\r
+ elem[ name ] ? name : null :\r
+ attr.specified ? attr.value : null :\r
+ null;\r
+};\r
+\r
+Expr = Sizzle.selectors = {\r
+\r
+ // Can be adjusted by the user\r
+ cacheLength: 50,\r
\r
createPseudo: markFunction,\r
\r
+ match: matchExpr,\r
+\r
+ order: new RegExp( "ID|TAG" +\r
+ (assertUsableName ? "|NAME" : "") +\r
+ (assertUsableClassName ? "|CLASS" : "")\r
+ ),\r
+\r
+ // IE6/7 return a modified href\r
+ attrHandle: assertHrefNotNormalized ?\r
+ {} :\r
+ {\r
+ "href": function( elem ) {\r
+ return elem.getAttribute( "href", 2 );\r
+ },\r
+ "type": function( elem ) {\r
+ return elem.getAttribute("type");\r
+ }\r
+ },\r
+\r
find: {\r
"ID": assertGetIdNotName ?\r
function( id, context, xml ) {\r
return tmp;\r
}\r
return results;\r
+ },\r
+\r
+ "NAME": function( tag, context ) {\r
+ if ( typeof context.getElementsByName !== strundefined ) {\r
+ return context.getElementsByName( name );\r
}\r
+ },\r
+\r
+ "CLASS": function( className, context, xml ) {\r
+ if ( typeof context.getElementsByClassName !== strundefined && !xml ) {\r
+ return context.getElementsByClassName( className );\r
+ }\r
+ }\r
},\r
\r
relative: {\r
return match;\r
},\r
\r
- "PSEUDO": function( match ) {\r
- var argument,\r
- unquoted = match[4];\r
-\r
+ "PSEUDO": function( match, context, xml ) {\r
+ var unquoted, excess;\r
if ( matchExpr["CHILD"].test( match[0] ) ) {\r
return null;\r
}\r
\r
- // Relinquish our claim on characters in `unquoted` from a closing parenthesis on\r
- if ( unquoted && (argument = rselector.exec( unquoted )) && argument.pop() ) {\r
-\r
- match[0] = match[0].slice( 0, argument[0].length - unquoted.length - 1 );\r
- unquoted = argument[0].slice( 0, -1 );\r
+ if ( match[3] ) {\r
+ match[2] = match[3];\r
+ } else if ( (unquoted = match[4]) ) {\r
+ // Only check arguments that contain a pseudo\r
+ if ( rpseudo.test(unquoted) &&\r
+ // Get excess from tokenize (recursively)\r
+ (excess = tokenize( unquoted, context, xml, true )) &&\r
+ // advance to the next closing parenthesis\r
+ (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {\r
+\r
+ // excess is a negative index\r
+ unquoted = unquoted.slice( 0, excess );\r
+ match[0] = match[0].slice( 0, excess );\r
+ }\r
+ match[2] = unquoted;\r
}\r
\r
- // Quoted or unquoted, we have the full argument\r
// Return only captures needed by the pseudo filter method (type and argument)\r
- match.splice( 2, 3, unquoted || match[3] );\r
- return match;\r
+ return match.slice( 0, 3 );\r
}\r
},\r
\r
},\r
\r
"CLASS": function( className ) {\r
- var pattern = classCache[ className ];\r
+ var pattern = classCache[ expando ][ className ];\r
if ( !pattern ) {\r
- pattern = classCache[ className ] = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" );\r
- cachedClasses.push( className );\r
- // Avoid too large of a cache\r
- if ( cachedClasses.length > Expr.cacheLength ) {\r
- delete classCache[ cachedClasses.shift() ];\r
- }\r
+ pattern = classCache( className, new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)") );\r
}\r
return function( elem ) {\r
return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" );\r
// pseudo-class names are case-insensitive\r
// http://www.w3.org/TR/selectors/#pseudo-classes\r
// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\r
- var fn = Expr.pseudos[ pseudo ] || Expr.pseudos[ pseudo.toLowerCase() ];\r
+ var args,\r
+ fn = Expr.pseudos[ pseudo ] || Expr.pseudos[ pseudo.toLowerCase() ];\r
\r
if ( !fn ) {\r
Sizzle.error( "unsupported pseudo: " + pseudo );\r
}\r
\r
- // The user may set fn.sizzleFilter to indicate\r
- // that arguments are needed to create the filter function\r
+ // The user may use createPseudo to indicate that\r
+ // arguments are needed to create the filter function\r
// just as Sizzle does\r
- if ( !fn.sizzleFilter ) {\r
+ if ( !fn[ expando ] ) {\r
+ if ( fn.length > 1 ) {\r
+ args = [ pseudo, pseudo, "", argument ];\r
+ return function( elem ) {\r
+ return fn( elem, 0, args );\r
+ };\r
+ }\r
return fn;\r
}\r
\r
},\r
\r
// Input types\r
- "radio": createInputFunction("radio"),\r
- "checkbox": createInputFunction("checkbox"),\r
- "file": createInputFunction("file"),\r
- "password": createInputFunction("password"),\r
- "image": createInputFunction("image"),\r
+ "radio": createInputPseudo("radio"),\r
+ "checkbox": createInputPseudo("checkbox"),\r
+ "file": createInputPseudo("file"),\r
+ "password": createInputPseudo("password"),\r
+ "image": createInputPseudo("image"),\r
\r
- "submit": createButtonFunction("submit"),\r
- "reset": createButtonFunction("reset"),\r
+ "submit": createButtonPseudo("submit"),\r
+ "reset": createButtonPseudo("reset"),\r
\r
"button": function( elem ) {\r
var name = elem.nodeName.toLowerCase();\r
for ( ; i < len; i = i + 2 ) {\r
results.push( elements[i] );\r
}\r
- return results;\r
- },\r
-\r
- "lt": function( elements, argument, not ) {\r
- return not ? elements.slice( +argument ) : elements.slice( 0, +argument );\r
- },\r
-\r
- "gt": function( elements, argument, not ) {\r
- return not ? elements.slice( 0, +argument + 1 ) : elements.slice( +argument + 1 );\r
- },\r
-\r
- "eq": function( elements, argument, not ) {\r
- var elem = elements.splice( +argument, 1 );\r
- return not ? elements : elem;\r
- }\r
- }\r
-};\r
-\r
-// Deprecated\r
-Expr.setFilters["nth"] = Expr.setFilters["eq"];\r
-\r
-// Back-compat\r
-Expr.filters = Expr.pseudos;\r
-\r
-// IE6/7 return a modified href\r
-if ( !assertHrefNotNormalized ) {\r
- Expr.attrHandle = {\r
- "href": function( elem ) {\r
- return elem.getAttribute( "href", 2 );\r
- },\r
- "type": function( elem ) {\r
- return elem.getAttribute("type");\r
- }\r
- };\r
-}\r
-\r
-// Add getElementsByName if usable\r
-if ( assertUsableName ) {\r
- Expr.order.push("NAME");\r
- Expr.find["NAME"] = function( name, context ) {\r
- if ( typeof context.getElementsByName !== strundefined ) {\r
- return context.getElementsByName( name );\r
- }\r
- };\r
-}\r
-\r
-// Add getElementsByClassName if usable\r
-if ( assertUsableClassName ) {\r
- Expr.order.splice( 1, 0, "CLASS" );\r
- Expr.find["CLASS"] = function( className, context, xml ) {\r
- if ( typeof context.getElementsByClassName !== strundefined && !xml ) {\r
- return context.getElementsByClassName( className );\r
- }\r
- };\r
-}\r
-\r
-// If slice is not available, provide a backup\r
-try {\r
- slice.call( docElem.childNodes, 0 )[0].nodeType;\r
-} catch ( e ) {\r
- slice = function( i ) {\r
- var elem, results = [];\r
- for ( ; (elem = this[i]); i++ ) {\r
- results.push( elem );\r
- }\r
- return results;\r
- };\r
-}\r
-\r
-var isXML = Sizzle.isXML = function( elem ) {\r
- // documentElement is verified for cases where it doesn't yet exist\r
- // (such as loading iframes in IE - #4833)\r
- var documentElement = elem && (elem.ownerDocument || elem).documentElement;\r
- return documentElement ? documentElement.nodeName !== "HTML" : false;\r
-};\r
-\r
-// Element contains another\r
-var contains = Sizzle.contains = docElem.compareDocumentPosition ?\r
- function( a, b ) {\r
- return !!( a.compareDocumentPosition( b ) & 16 );\r
- } :\r
- docElem.contains ?\r
- function( a, b ) {\r
- var adown = a.nodeType === 9 ? a.documentElement : a,\r
- bup = b.parentNode;\r
- return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) );\r
- } :\r
- function( a, b ) {\r
- while ( (b = b.parentNode) ) {\r
- if ( b === a ) {\r
- return true;\r
- }\r
- }\r
- return false;\r
- };\r
-\r
-/**\r
- * Utility function for retrieving the text value of an array of DOM nodes\r
- * @param {Array|Element} elem\r
- */\r
-var getText = Sizzle.getText = function( elem ) {\r
- var node,\r
- ret = "",\r
- i = 0,\r
- nodeType = elem.nodeType;\r
-\r
- if ( nodeType ) {\r
- if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\r
- // Use textContent for elements\r
- // innerText usage removed for consistency of new lines (see #11153)\r
- if ( typeof elem.textContent === "string" ) {\r
- return elem.textContent;\r
- } else {\r
- // Traverse its children\r
- for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\r
- ret += getText( elem );\r
- }\r
- }\r
- } else if ( nodeType === 3 || nodeType === 4 ) {\r
- return elem.nodeValue;\r
- }\r
- // Do not include comment or processing instruction nodes\r
- } else {\r
+ return results;\r
+ },\r
\r
- // If no nodeType, this is expected to be an array\r
- for ( ; (node = elem[i]); i++ ) {\r
- // Do not traverse comment nodes\r
- ret += getText( node );\r
+ "lt": function( elements, argument, not ) {\r
+ return not ? elements.slice( +argument ) : elements.slice( 0, +argument );\r
+ },\r
+\r
+ "gt": function( elements, argument, not ) {\r
+ return not ? elements.slice( 0, +argument + 1 ) : elements.slice( +argument + 1 );\r
+ },\r
+\r
+ "eq": function( elements, argument, not ) {\r
+ var elem = elements.splice( +argument, 1 );\r
+ return not ? elements : elem;\r
}\r
}\r
- return ret;\r
};\r
\r
-Sizzle.attr = function( elem, name ) {\r
- var attr,\r
- xml = isXML( elem );\r
-\r
- if ( !xml ) {\r
- name = name.toLowerCase();\r
- }\r
- if ( Expr.attrHandle[ name ] ) {\r
- return Expr.attrHandle[ name ]( elem );\r
+function siblingCheck( a, b, ret ) {\r
+ if ( a === b ) {\r
+ return ret;\r
}\r
- if ( assertAttributes || xml ) {\r
- return elem.getAttribute( name );\r
- }\r
- attr = elem.getAttributeNode( name );\r
- return attr ?\r
- typeof elem[ name ] === "boolean" ?\r
- elem[ name ] ? name : null :\r
- attr.specified ? attr.value : null :\r
- null;\r
-};\r
\r
-Sizzle.error = function( msg ) {\r
- throw new Error( "Syntax error, unrecognized expression: " + msg );\r
-};\r
+ var cur = a.nextSibling;\r
+\r
+ while ( cur ) {\r
+ if ( cur === b ) {\r
+ return -1;\r
+ }\r
\r
-// Check if the JavaScript engine is using some sort of\r
-// optimization where it does not always call our comparision\r
-// function. If that is the case, discard the hasDuplicate value.\r
-// Thus far that includes Google Chrome.\r
-[0, 0].sort(function() {\r
- return (baseHasDuplicate = 0);\r
-});\r
+ cur = cur.nextSibling;\r
+ }\r
\r
+ return 1;\r
+}\r
\r
-if ( docElem.compareDocumentPosition ) {\r
- sortOrder = function( a, b ) {\r
+sortOrder = docElem.compareDocumentPosition ?\r
+ function( a, b ) {\r
if ( a === b ) {\r
hasDuplicate = true;\r
return 0;\r
a.compareDocumentPosition :\r
a.compareDocumentPosition(b) & 4\r
) ? -1 : 1;\r
- };\r
-\r
-} else {\r
- sortOrder = function( a, b ) {\r
+ } :\r
+ function( a, b ) {\r
// The nodes are identical, we can exit early\r
if ( a === b ) {\r
hasDuplicate = true;\r
siblingCheck( ap[i], b, 1 );\r
};\r
\r
- siblingCheck = function( a, b, ret ) {\r
- if ( a === b ) {\r
- return ret;\r
- }\r
-\r
- var cur = a.nextSibling;\r
-\r
- while ( cur ) {\r
- if ( cur === b ) {\r
- return -1;\r
- }\r
-\r
- cur = cur.nextSibling;\r
- }\r
-\r
- return 1;\r
- };\r
-}\r
+// Always assume the presence of duplicates if sort doesn't\r
+// pass them to our comparison function (as in Google Chrome).\r
+[0, 0].sort( sortOrder );\r
+baseHasDuplicate = !hasDuplicate;\r
\r
// Document sorting and removing duplicates\r
Sizzle.uniqueSort = function( results ) {\r
var elem,\r
i = 1;\r
\r
- if ( sortOrder ) {\r
- hasDuplicate = baseHasDuplicate;\r
- results.sort( sortOrder );\r
+ hasDuplicate = baseHasDuplicate;\r
+ results.sort( sortOrder );\r
\r
- if ( hasDuplicate ) {\r
- for ( ; (elem = results[i]); i++ ) {\r
- if ( elem === results[ i - 1 ] ) {\r
- results.splice( i--, 1 );\r
- }\r
+ if ( hasDuplicate ) {\r
+ for ( ; (elem = results[i]); i++ ) {\r
+ if ( elem === results[ i - 1 ] ) {\r
+ results.splice( i--, 1 );\r
}\r
}\r
}\r
return results;\r
};\r
\r
-function multipleContexts( selector, contexts, results, seed ) {\r
- var i = 0,\r
- len = contexts.length;\r
- for ( ; i < len; i++ ) {\r
- Sizzle( selector, contexts[i], results, seed );\r
- }\r
-}\r
-\r
-function handlePOSGroup( selector, posfilter, argument, contexts, seed, not ) {\r
- var results,\r
- fn = Expr.setFilters[ posfilter.toLowerCase() ];\r
-\r
- if ( !fn ) {\r
- Sizzle.error( posfilter );\r
- }\r
+Sizzle.error = function( msg ) {\r
+ throw new Error( "Syntax error, unrecognized expression: " + msg );\r
+};\r
\r
- if ( selector || !(results = seed) ) {\r
- multipleContexts( selector || "*", contexts, (results = []), seed );\r
+function tokenize( selector, context, xml, parseOnly ) {\r
+ var matched, match, tokens, type,\r
+ soFar, groups, group, i,\r
+ preFilters, filters,\r
+ checkContext = !xml && context !== document,\r
+ // Token cache should maintain spaces\r
+ key = ( checkContext ? "<s>" : "" ) + selector.replace( rtrim, "$1<s>" ),\r
+ cached = tokenCache[ expando ][ key ];\r
+\r
+ if ( cached ) {\r
+ return parseOnly ? 0 : slice.call( cached, 0 );\r
}\r
\r
- return results.length > 0 ? fn( results, argument, not ) : [];\r
-}\r
-\r
-function handlePOS( selector, context, results, seed, groups ) {\r
- var match, not, anchor, ret, elements, currentContexts, part, lastIndex,\r
- i = 0,\r
- len = groups.length,\r
- rpos = matchExpr["POS"],\r
- // This is generated here in case matchExpr["POS"] is extended\r
- rposgroups = new RegExp( "^" + rpos.source + "(?!" + whitespace + ")", "i" ),\r
- // This is for making sure non-participating\r
- // matching groups are represented cross-browser (IE6-8)\r
- setUndefined = function() {\r
- var i = 1,\r
- len = arguments.length - 2;\r
- for ( ; i < len; i++ ) {\r
- if ( arguments[i] === undefined ) {\r
- match[i] = undefined;\r
- }\r
- }\r
- };\r
-\r
- for ( ; i < len; i++ ) {\r
- // Reset regex index to 0\r
- rpos.exec("");\r
- selector = groups[i];\r
- ret = [];\r
- anchor = 0;\r
- elements = seed;\r
- while ( (match = rpos.exec( selector )) ) {\r
- lastIndex = rpos.lastIndex = match.index + match[0].length;\r
- if ( lastIndex > anchor ) {\r
- part = selector.slice( anchor, match.index );\r
- anchor = lastIndex;\r
- currentContexts = [ context ];\r
-\r
- if ( rcombinators.test(part) ) {\r
- if ( elements ) {\r
- currentContexts = elements;\r
- }\r
- elements = seed;\r
- }\r
+ soFar = selector;\r
+ groups = [];\r
+ i = 0;\r
+ preFilters = Expr.preFilter;\r
+ filters = Expr.filter;\r
\r
- if ( (not = rendsWithNot.test( part )) ) {\r
- part = part.slice( 0, -5 ).replace( rcombinators, "$&*" );\r
- }\r
+ while ( soFar ) {\r
\r
- if ( match.length > 1 ) {\r
- match[0].replace( rposgroups, setUndefined );\r
- }\r
- elements = handlePOSGroup( part, match[1], match[2], currentContexts, elements, not );\r
+ // Comma and first run\r
+ if ( !matched || (match = rcomma.exec( soFar )) ) {\r
+ if ( match ) {\r
+ soFar = soFar.slice( match[0].length );\r
+ tokens.selector = group;\r
}\r
- }\r
-\r
- if ( elements ) {\r
- ret = ret.concat( elements );\r
+ groups.push( tokens = [] );\r
+ group = "";\r
\r
- if ( (part = selector.slice( anchor )) && part !== ")" ) {\r
- if ( rcombinators.test(part) ) {\r
- multipleContexts( part, ret, results, seed );\r
- } else {\r
- Sizzle( part, context, results, seed ? seed.concat(elements) : elements );\r
- }\r
- } else {\r
- push.apply( results, ret );\r
+ // Need to make sure we're within a narrower context if necessary\r
+ // Adding a descendant combinator will generate what is needed\r
+ if ( checkContext ) {\r
+ soFar = " " + soFar;\r
}\r
- } else {\r
- Sizzle( selector, context, results, seed );\r
}\r
- }\r
-\r
- // Do not sort if this is a single filter\r
- return len === 1 ? results : Sizzle.uniqueSort( results );\r
-}\r
-\r
-function tokenize( selector, context, xml ) {\r
- var tokens, soFar, type,\r
- groups = [],\r
- i = 0,\r
-\r
- // Catch obvious selector issues: terminal ")"; nonempty fallback match\r
- // rselector never fails to match *something*\r
- match = rselector.exec( selector ),\r
- matched = !match.pop() && !match.pop(),\r
- selectorGroups = matched && selector.match( rgroups ) || [""],\r
\r
- preFilters = Expr.preFilter,\r
- filters = Expr.filter,\r
- checkContext = !xml && context !== document;\r
+ matched = false;\r
\r
- for ( ; (soFar = selectorGroups[i]) != null && matched; i++ ) {\r
- groups.push( tokens = [] );\r
+ // Combinators\r
+ if ( (match = rcombinators.exec( soFar )) ) {\r
+ group += match[0];\r
+ soFar = soFar.slice( match[0].length );\r
\r
- // Need to make sure we're within a narrower context if necessary\r
- // Adding a descendant combinator will generate what is needed\r
- if ( checkContext ) {\r
- soFar = " " + soFar;\r
+ // Cast descendant combinators to space\r
+ matched = tokens.push({\r
+ part: match.pop().replace( rtrim, " " ),\r
+ string: match[0],\r
+ captures: match\r
+ });\r
}\r
\r
- while ( soFar ) {\r
- matched = false;\r
+ // Filters\r
+ for ( type in filters ) {\r
+ if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\r
+ ( match = preFilters[ type ](match, context, xml) )) ) {\r
\r
- // Combinators\r
- if ( (match = rcombinators.exec( soFar )) ) {\r
+ group += match[0];\r
soFar = soFar.slice( match[0].length );\r
-\r
- // Cast descendant combinators to space\r
- matched = tokens.push({ part: match.pop().replace( rtrim, " " ), captures: match });\r
- }\r
-\r
- // Filters\r
- for ( type in filters ) {\r
- if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\r
- (match = preFilters[ type ]( match, context, xml )) ) ) {\r
-\r
- soFar = soFar.slice( match.shift().length );\r
- matched = tokens.push({ part: type, captures: match });\r
- }\r
+ matched = tokens.push({\r
+ part: type,\r
+ string: match.shift(),\r
+ captures: match\r
+ });\r
}\r
+ }\r
\r
- if ( !matched ) {\r
- break;\r
- }\r
+ if ( !matched ) {\r
+ break;\r
}\r
}\r
\r
- if ( !matched ) {\r
- Sizzle.error( selector );\r
+ // Attach the full group as a selector\r
+ if ( group ) {\r
+ tokens.selector = group;\r
}\r
\r
- return groups;\r
+ // Return the length of the invalid excess\r
+ // if we're just parsing\r
+ // Otherwise, throw an error or return tokens\r
+ return parseOnly ?\r
+ soFar.length :\r
+ soFar ?\r
+ Sizzle.error( selector ) :\r
+ // Cache the tokens\r
+ slice.call( tokenCache(key, groups), 0 );\r
}\r
\r
-function addCombinator( matcher, combinator, context ) {\r
+function addCombinator( matcher, combinator, context, xml ) {\r
var dir = combinator.dir,\r
doneName = done++;\r
\r
};\r
}\r
return combinator.first ?\r
- function( elem, context ) {\r
+ function( elem ) {\r
while ( (elem = elem[ dir ]) ) {\r
if ( elem.nodeType === 1 ) {\r
- return matcher( elem, context ) && elem;\r
+ return matcher( elem ) && elem;\r
}\r
}\r
} :\r
- function( elem, context ) {\r
- var cache,\r
- dirkey = doneName + "." + dirruns,\r
- cachedkey = dirkey + "." + cachedruns;\r
- while ( (elem = elem[ dir ]) ) {\r
- if ( elem.nodeType === 1 ) {\r
- if ( (cache = elem[ expando ]) === cachedkey ) {\r
- return elem.sizset;\r
- } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) {\r
- if ( elem.sizset ) {\r
+ xml ?\r
+ function( elem ) {\r
+ while ( (elem = elem[ dir ]) ) {\r
+ if ( elem.nodeType === 1 ) {\r
+ if ( matcher( elem ) ) {\r
return elem;\r
}\r
- } else {\r
- elem[ expando ] = cachedkey;\r
- if ( matcher( elem, context ) ) {\r
- elem.sizset = true;\r
- return elem;\r
+ }\r
+ }\r
+ } :\r
+ function( elem ) {\r
+ var cache,\r
+ dirkey = doneName + "." + dirruns,\r
+ cachedkey = dirkey + "." + cachedruns;\r
+ while ( (elem = elem[ dir ]) ) {\r
+ if ( elem.nodeType === 1 ) {\r
+ if ( (cache = elem[ expando ]) === cachedkey ) {\r
+ return elem.sizset;\r
+ } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) {\r
+ if ( elem.sizset ) {\r
+ return elem;\r
+ }\r
+ } else {\r
+ elem[ expando ] = cachedkey;\r
+ if ( matcher( elem ) ) {\r
+ elem.sizset = true;\r
+ return elem;\r
+ }\r
+ elem.sizset = false;\r
}\r
- elem.sizset = false;\r
}\r
}\r
- }\r
- };\r
+ };\r
}\r
\r
function addMatcher( higher, deeper ) {\r
return higher ?\r
- function( elem, context ) {\r
- var result = deeper( elem, context );\r
- return result && higher( result === true ? elem : result, context );\r
+ function( elem ) {\r
+ var result = deeper( elem );\r
+ return result && higher( result === true ? elem : result );\r
} :\r
deeper;\r
}\r
\r
for ( ; (token = tokens[i]); i++ ) {\r
if ( Expr.relative[ token.part ] ) {\r
- matcher = addCombinator( matcher, Expr.relative[ token.part ], context );\r
+ matcher = addCombinator( matcher, Expr.relative[ token.part ], context, xml );\r
} else {\r
- token.captures.push( context, xml );\r
- matcher = addMatcher( matcher, Expr.filter[ token.part ].apply( null, token.captures ) );\r
+ matcher = addMatcher( matcher, Expr.filter[ token.part ].apply(null, token.captures.concat( context, xml )) );\r
}\r
}\r
\r
}\r
\r
function matcherFromGroupMatchers( matchers ) {\r
- return function( elem, context ) {\r
+ return function( elem ) {\r
var matcher,\r
j = 0;\r
for ( ; (matcher = matchers[j]); j++ ) {\r
- if ( matcher(elem, context) ) {\r
+ if ( matcher(elem) ) {\r
return true;\r
}\r
}\r
};\r
}\r
\r
-var compile = Sizzle.compile = function( selector, context, xml ) {\r
- var tokens, group, i,\r
- cached = compilerCache[ selector ];\r
+compile = Sizzle.compile = function( selector, context, xml ) {\r
+ var group, i, len,\r
+ cached = compilerCache[ expando ][ selector ];\r
\r
// Return a cached group function if already generated (context dependent)\r
if ( cached && cached.context === context ) {\r
\r
// Generate a function of recursive functions that can be used to check each element\r
group = tokenize( selector, context, xml );\r
- for ( i = 0; (tokens = group[i]); i++ ) {\r
- group[i] = matcherFromTokens( tokens, context, xml );\r
+ for ( i = 0, len = group.length; i < len; i++ ) {\r
+ group[i] = matcherFromTokens(group[i], context, xml);\r
}\r
\r
// Cache the compiled function\r
- cached = compilerCache[ selector ] = matcherFromGroupMatchers( group );\r
+ cached = compilerCache( selector, matcherFromGroupMatchers(group) );\r
cached.context = context;\r
cached.runs = cached.dirruns = 0;\r
- cachedSelectors.push( selector );\r
- // Ensure only the most recent are cached\r
- if ( cachedSelectors.length > Expr.cacheLength ) {\r
- delete compilerCache[ cachedSelectors.shift() ];\r
- }\r
return cached;\r
};\r
\r
-Sizzle.matches = function( expr, elements ) {\r
- return Sizzle( expr, null, null, elements );\r
-};\r
+function multipleContexts( selector, contexts, results, seed ) {\r
+ var i = 0,\r
+ len = contexts.length;\r
+ for ( ; i < len; i++ ) {\r
+ Sizzle( selector, contexts[i], results, seed );\r
+ }\r
+}\r
\r
-Sizzle.matchesSelector = function( elem, expr ) {\r
- return Sizzle( expr, null, null, [ elem ] ).length > 0;\r
-};\r
+function handlePOSGroup( selector, posfilter, argument, contexts, seed, not ) {\r
+ var results,\r
+ fn = Expr.setFilters[ posfilter.toLowerCase() ];\r
+\r
+ if ( !fn ) {\r
+ Sizzle.error( posfilter );\r
+ }\r
+\r
+ if ( selector || !(results = seed) ) {\r
+ multipleContexts( selector || "*", contexts, (results = []), seed );\r
+ }\r
+\r
+ return results.length > 0 ? fn( results, argument, not ) : [];\r
+}\r
+\r
+function handlePOS( groups, context, results, seed ) {\r
+ var group, part, j, groupLen, token, selector,\r
+ anchor, elements, match, matched,\r
+ lastIndex, currentContexts, not,\r
+ i = 0,\r
+ len = groups.length,\r
+ rpos = matchExpr["POS"],\r
+ // This is generated here in case matchExpr["POS"] is extended\r
+ rposgroups = new RegExp( "^" + rpos.source + "(?!" + whitespace + ")", "i" ),\r
+ // This is for making sure non-participating\r
+ // matching groups are represented cross-browser (IE6-8)\r
+ setUndefined = function() {\r
+ var i = 1,\r
+ len = arguments.length - 2;\r
+ for ( ; i < len; i++ ) {\r
+ if ( arguments[i] === undefined ) {\r
+ match[i] = undefined;\r
+ }\r
+ }\r
+ };\r
+\r
+ for ( ; i < len; i++ ) {\r
+ group = groups[i];\r
+ part = "";\r
+ elements = seed;\r
+ for ( j = 0, groupLen = group.length; j < groupLen; j++ ) {\r
+ token = group[j];\r
+ selector = token.string;\r
+ if ( token.part === "PSEUDO" ) {\r
+ // Reset regex index to 0\r
+ rpos.exec("");\r
+ anchor = 0;\r
+ while ( (match = rpos.exec( selector )) ) {\r
+ matched = true;\r
+ lastIndex = rpos.lastIndex = match.index + match[0].length;\r
+ if ( lastIndex > anchor ) {\r
+ part += selector.slice( anchor, match.index );\r
+ anchor = lastIndex;\r
+ currentContexts = [ context ];\r
+\r
+ if ( rcombinators.test(part) ) {\r
+ if ( elements ) {\r
+ currentContexts = elements;\r
+ }\r
+ elements = seed;\r
+ }\r
+\r
+ if ( (not = rendsWithNot.test( part )) ) {\r
+ part = part.slice( 0, -5 ).replace( rcombinators, "$&*" );\r
+ anchor++;\r
+ }\r
+\r
+ if ( match.length > 1 ) {\r
+ match[0].replace( rposgroups, setUndefined );\r
+ }\r
+ elements = handlePOSGroup( part, match[1], match[2], currentContexts, elements, not );\r
+ }\r
+ part = "";\r
+ }\r
+\r
+ }\r
+\r
+ if ( !matched ) {\r
+ part += selector;\r
+ }\r
+ matched = false;\r
+ }\r
+\r
+ if ( part ) {\r
+ if ( rcombinators.test(part) ) {\r
+ multipleContexts( part, elements || [ context ], results, seed );\r
+ } else {\r
+ Sizzle( part, context, results, seed ? seed.concat(elements) : elements );\r
+ }\r
+ } else {\r
+ push.apply( results, elements );\r
+ }\r
+ }\r
+\r
+ // Do not sort if this is a single filter\r
+ return len === 1 ? results : Sizzle.uniqueSort( results );\r
+}\r
\r
-var select = function( selector, context, results, seed, xml ) {\r
+function select( selector, context, results, seed, xml ) {\r
// Remove excessive whitespace\r
selector = selector.replace( rtrim, "$1" );\r
- var elements, matcher, i, len, elem, token,\r
- type, findContext, notTokens,\r
- match = selector.match( rgroups ),\r
- tokens = selector.match( rtokens ),\r
+ var elements, matcher, cached, elem,\r
+ i, tokens, token, lastToken, findContext, type,\r
+ match = tokenize( selector, context, xml ),\r
contextNodeType = context.nodeType;\r
\r
// POS handling\r
if ( matchExpr["POS"].test(selector) ) {\r
- return handlePOS( selector, context, results, seed, match );\r
+ return handlePOS( match, context, results, seed );\r
}\r
\r
if ( seed ) {\r
\r
// To maintain document order, only narrow the\r
// set if there is one group\r
- } else if ( match && match.length === 1 ) {\r
+ } else if ( match.length === 1 ) {\r
\r
// Take a shortcut and set the context if the root selector is an ID\r
- if ( tokens.length > 1 && contextNodeType === 9 && !xml &&\r
- (match = matchExpr["ID"].exec( tokens[0] )) ) {\r
+ if ( (tokens = slice.call( match[0], 0 )).length > 2 &&\r
+ (token = tokens[0]).part === "ID" &&\r
+ contextNodeType === 9 && !xml &&\r
+ Expr.relative[ tokens[1].part ] ) {\r
\r
- context = Expr.find["ID"]( match[1], context, xml )[0];\r
+ context = Expr.find["ID"]( token.captures[0].replace( rbackslash, "" ), context, xml )[0];\r
if ( !context ) {\r
return results;\r
}\r
\r
- selector = selector.slice( tokens.shift().length );\r
+ selector = selector.slice( tokens.shift().string.length );\r
}\r
\r
- findContext = ( (match = rsibling.exec( tokens[0] )) && !match.index && context.parentNode ) || context;\r
-\r
- // Get the last token, excluding :not\r
- notTokens = tokens.pop();\r
- token = notTokens.split(":not")[0];\r
-\r
- for ( i = 0, len = Expr.order.length; i < len; i++ ) {\r
- type = Expr.order[i];\r
-\r
- if ( (match = matchExpr[ type ].exec( token )) ) {\r
- elements = Expr.find[ type ]( (match[1] || "").replace( rbackslash, "" ), findContext, xml );\r
+ findContext = ( (match = rsibling.exec( tokens[0].string )) && !match.index && context.parentNode ) || context;\r
\r
+ // Reduce the set if possible\r
+ lastToken = "";\r
+ for ( i = tokens.length - 1; i >= 0; i-- ) {\r
+ token = tokens[i];\r
+ type = token.part;\r
+ lastToken = token.string + lastToken;\r
+ if ( Expr.relative[ type ] ) {\r
+ break;\r
+ }\r
+ if ( Expr.order.test(type) ) {\r
+ elements = Expr.find[ type ]( token.captures[0].replace( rbackslash, "" ), findContext, xml );\r
if ( elements == null ) {\r
continue;\r
- }\r
-\r
- if ( token === notTokens ) {\r
- selector = selector.slice( 0, selector.length - notTokens.length ) +\r
- token.replace( matchExpr[ type ], "" );\r
+ } else {\r
+ selector = selector.slice( 0, selector.length - lastToken.length ) +\r
+ lastToken.replace( matchExpr[ type ], "" );\r
\r
if ( !selector ) {\r
push.apply( results, slice.call(elements, 0) );\r
}\r
+\r
+ break;\r
}\r
- break;\r
}\r
}\r
}\r
\r
// Only loop over the given elements once\r
- // If selector is empty, we're already done\r
if ( selector ) {\r
matcher = compile( selector, context, xml );\r
dirruns = matcher.dirruns++;\r
-\r
if ( elements == null ) {\r
elements = Expr.find["TAG"]( "*", (rsibling.test( selector ) && context.parentNode) || context );\r
}\r
+\r
for ( i = 0; (elem = elements[i]); i++ ) {\r
cachedruns = matcher.runs++;\r
- if ( matcher(elem, context) ) {\r
+ if ( matcher(elem) ) {\r
results.push( elem );\r
}\r
}\r
}\r
\r
return results;\r
-};\r
+}\r
\r
if ( document.querySelectorAll ) {\r
(function() {\r
// Build QSA regex\r
// Regex strategy adopted from Diego Perini\r
assert(function( div ) {\r
- div.innerHTML = "<select><option selected></option></select>";\r
+ // Select is set to empty string on purpose\r
+ // This is to test IE's treatment of not explictly\r
+ // setting a boolean content attribute,\r
+ // since its presence should be enough\r
+ // http://bugs.jquery.com/ticket/12359\r
+ div.innerHTML = "<select><option selected=''></option></select>";\r
\r
// IE8 - Some boolean attributes are not treated correctly\r
if ( !div.querySelectorAll("[selected]").length ) {\r
\r
// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\r
// IE8 throws error here (do not put tests after this one)\r
- div.innerHTML = "<input type='hidden'>";\r
+ div.innerHTML = "<input type='hidden'/>";\r
if ( !div.querySelectorAll(":enabled").length ) {\r
rbuggyQSA.push(":enabled", ":disabled");\r
}\r
// and working up from there (Thanks to Andrew Dupont for the technique)\r
// IE 8 doesn't work on object elements\r
} else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {\r
- var old = context.getAttribute("id"),\r
+ var groups, i, len,\r
+ old = context.getAttribute("id"),\r
nid = old || expando,\r
newContext = rsibling.test( selector ) && context.parentNode || context;\r
\r
context.setAttribute( "id", nid );\r
}\r
\r
+ groups = tokenize(selector, context, xml);\r
+ // Trailing space is unnecessary\r
+ // There is always a context check\r
+ nid = "[id='" + nid + "']";\r
+ for ( i = 0, len = groups.length; i < len; i++ ) {\r
+ groups[i] = nid + groups[i].selector;\r
+ }\r
try {\r
push.apply( results, slice.call( newContext.querySelectorAll(\r
- selector.replace( rgroups, "[id='" + nid + "'] $&" )\r
+ groups.join(",")\r
), 0 ) );\r
return results;\r
} catch(qsaError) {\r
// Gecko does not error, returns false instead\r
try {\r
matches.call( div, "[test!='']:sizzle" );\r
- rbuggyMatches.push( Expr.match.PSEUDO );\r
+ rbuggyMatches.push( matchExpr["PSEUDO"].source, matchExpr["POS"].source, "!=" );\r
} catch ( e ) {}\r
});\r
\r
})();\r
}\r
\r
+// Deprecated\r
+Expr.setFilters["nth"] = Expr.setFilters["eq"];\r
+\r
+// Back-compat\r
+Expr.filters = Expr.pseudos;\r
+\r
// Override sizzle attribute retrieval
Sizzle.attr = jQuery.attr;
jQuery.find = Sizzle;
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
},
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
}
// 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 += "";
}
} 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></$2>");
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;
}
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;
}
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" ),
cssShow = { position: "absolute", visibility: "hidden", display: "block" },
cssNormalTransform = {
letterSpacing: 0,
- fontWeight: 400,
- lineHeight: 1
+ fontWeight: 400
},
cssExpand = [ "Top", "Right", "Bottom", "Left" ],
}
});
-// 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 ) ) {
+ if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
ret = jQuery.style( elem, name );
}
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 ) {
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 );
}
}
},
params = undefined;
// Otherwise, build a param string
- } else if ( typeof params === "object" ) {
+ } else if ( params && typeof params === "object" ) {
type = "POST";
}
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 ) {
// 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;
// Set width or height on the element
jQuery.style( elem, type, value, extra );
- }, type, chainable ? margin : undefined, chainable );
+ }, type, chainable ? margin : undefined, chainable, null );
};
});
});