/*!
- * jQuery JavaScript Library v1.8.1
+ * jQuery JavaScript Library v1.8.2
* http://jquery.com/
*
* Includes Sizzle.js
* Released under the MIT license
* http://jquery.org/license
*
- * Date: Thu Aug 30 2012 17:17:22 GMT-0400 (Eastern Daylight Time)
+ * Date: Thu Sep 20 2012 21:13:05 GMT-0400 (Eastern Daylight Time)
*/
(function( window, undefined ) {
var
selector: "",
// The current version of jQuery being used
- jquery: "1.8.1",
+ jquery: "1.8.2",
// The default length of a jQuery object is 0
length: 0,
},
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
function( text ) {
return text == null ?
"" :
- text.toString().replace( rtrim, "" );
+ ( text + "" ).replace( rtrim, "" );
},
// results is for internal usage only
};
// 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;
},
// 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 = {};
a.style.cssText = "top:1px;float:left;opacity:.5";
// Can't get basic test support
- if ( !all || !all.length || !a ) {
+ if ( !all || !all.length ) {
return {};
}
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
// 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;
}
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 ] );
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 ] + " ";
}
}
// 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 ] + " " , " " );
}
}
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;
}
}
return ret;
} else {
- elem.setAttribute( name, "" + value );
+ elem.setAttribute( name, value + "" );
return value;
}
return elem.style.cssText.toLowerCase() || undefined;
},
set: function( elem, value ) {
- return ( elem.style.cssText = "" + value );
+ return ( elem.style.cssText = value + "" );
}
};
}
handler: handler,
guid: handler.guid,
selector: selector,
+ needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
namespace: namespaces.join(".")
}, handleObjIn );
}
// 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();
}
}
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 = [];
sel = handleObj.selector;
if ( selMatch[ sel ] === undefined ) {
- selMatch[ sel ] = jQuery( sel, this ).index( cur ) >= 0;
+ selMatch[ sel ] = handleObj.needsContext ?
+ jQuery( sel, this ).index( cur ) >= 0 :
+ jQuery.find( sel, this, null, [ cur ] ).length;
}
if ( selMatch[ sel ] ) {
matches.push( handleObj );
},
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 ) {
});
/*!\r
* Sizzle CSS Selector Engine\r
- * Copyright 2012 jQuery Foundation and other contributors\r
- * Released under the MIT license\r
- * http://sizzlejs.com/\r
+ * Copyright 2012 jQuery Foundation and other contributors\r
+ * Released under the MIT license\r
+ * http://sizzlejs.com/\r
*/\r
(function( window, undefined ) {\r
\r
-var dirruns,\r
- cachedruns,\r
+var cachedruns,\r
assertGetIdNotName,\r
Expr,\r
getText,\r
compile,\r
sortOrder,\r
hasDuplicate,\r
+ outermostContext,\r
\r
baseHasDuplicate = true,\r
strundefined = "undefined",\r
\r
expando = ( "sizcache" + Math.random() ).replace( ".", "" ),\r
\r
+ Token = String,\r
document = window.document,\r
docElem = document.documentElement,\r
+ dirruns = 0,\r
done = 0,\r
- slice = [].slice,\r
+ pop = [].pop,\r
push = [].push,\r
+ slice = [].slice,\r
+ // Use a stripped-down indexOf if a native one is unavailable\r
+ indexOf = [].indexOf || function( elem ) {\r
+ var i = 0,\r
+ len = this.length;\r
+ for ( ; i < len; i++ ) {\r
+ if ( this[i] === elem ) {\r
+ return i;\r
+ }\r
+ }\r
+ return -1;\r
+ },\r
\r
// Augment a function for special use by Sizzle\r
markFunction = function( fn, value ) {\r
- fn[ expando ] = value || true;\r
+ fn[ expando ] = value == null || value;\r
return fn;\r
},\r
\r
pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)",\r
\r
// For matchExpr.POS and matchExpr.needsContext\r
- pos = ":(nth|eq|gt|lt|first|last|even|odd)(?:\\(((?:-\\d)?\\d*)\\)|)(?=[^-]|$)",\r
+ pos = ":(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +\r
+ "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)",\r
\r
// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\r
rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),\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
+ "POS": new RegExp( pos, "i" ),\r
+ "CHILD": new RegExp( "^:(only|nth|first|last)-child(?:\\(" + whitespace +\r
"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +\r
"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),\r
- "POS": new RegExp( pos, "ig" ),\r
// For use in libraries implementing .is()\r
"needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" )\r
},\r
slice.call( docElem.childNodes, 0 )[0].nodeType;\r
} catch ( e ) {\r
slice = function( i ) {\r
- var elem, results = [];\r
+ var elem,\r
+ results = [];\r
for ( ; (elem = this[i]); i++ ) {\r
results.push( elem );\r
}\r
var match, elem, xml, m,\r
nodeType = context.nodeType;\r
\r
- if ( nodeType !== 1 && nodeType !== 9 ) {\r
- return [];\r
- }\r
-\r
if ( !selector || typeof selector !== "string" ) {\r
return results;\r
}\r
\r
+ if ( nodeType !== 1 && nodeType !== 9 ) {\r
+ return [];\r
+ }\r
+\r
xml = isXML( context );\r
\r
if ( !xml && !seed ) {\r
}\r
\r
// All others\r
- return select( selector, context, results, seed, xml );\r
+ return select( selector.replace( rtrim, "$1" ), context, results, seed, xml );\r
}\r
\r
Sizzle.matches = function( expr, elements ) {\r
};\r
}\r
\r
+// Returns a function to use in pseudos for positionals\r
+function createPositionalPseudo( fn ) {\r
+ return markFunction(function( argument ) {\r
+ argument = +argument;\r
+ return markFunction(function( seed, matches ) {\r
+ var j,\r
+ matchIndexes = fn( [], seed.length, argument ),\r
+ i = matchIndexes.length;\r
+\r
+ // Match elements found at the specified indexes\r
+ while ( i-- ) {\r
+ if ( seed[ (j = matchIndexes[i]) ] ) {\r
+ seed[j] = !(matches[j] = seed[j]);\r
+ }\r
+ }\r
+ });\r
+ });\r
+}\r
+\r
/**\r
* Utility function for retrieving the text value of an array of DOM nodes\r
* @param {Array|Element} elem\r
return ret;\r
};\r
\r
-isXML = Sizzle.isXML = function isXML( elem ) {\r
+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
};\r
\r
Sizzle.attr = function( elem, name ) {\r
- var attr,\r
+ var val,\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
+ if ( (val = Expr.attrHandle[ name ]) ) {\r
+ return val( elem );\r
}\r
- if ( assertAttributes || xml ) {\r
+ if ( xml || assertAttributes ) {\r
return elem.getAttribute( name );\r
}\r
- attr = elem.getAttributeNode( name );\r
- return attr ?\r
+ val = elem.getAttributeNode( name );\r
+ return val ?\r
typeof elem[ name ] === "boolean" ?\r
elem[ name ] ? name : null :\r
- attr.specified ? attr.value : null :\r
+ val.specified ? val.value : null :\r
null;\r
};\r
\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
return results;\r
},\r
\r
- "NAME": function( tag, context ) {\r
+ "NAME": assertUsableName && function( tag, context ) {\r
if ( typeof context.getElementsByName !== strundefined ) {\r
return context.getElementsByName( name );\r
}\r
},\r
\r
- "CLASS": function( className, context, xml ) {\r
+ "CLASS": assertUsableClassName && function( className, context, xml ) {\r
if ( typeof context.getElementsByClassName !== strundefined && !xml ) {\r
return context.getElementsByClassName( className );\r
}\r
},\r
\r
"CHILD": function( match ) {\r
- /* matches from matchExpr.CHILD\r
+ /* matches from matchExpr["CHILD"]\r
1 type (only|nth|...)\r
2 argument (even|odd|\d*|\d*n([+-]\d+)?|...)\r
3 xn-component of xn+y argument ([+-]?\d*n|)\r
return match;\r
},\r
\r
- "PSEUDO": function( match, context, xml ) {\r
+ "PSEUDO": function( match ) {\r
var unquoted, excess;\r
if ( matchExpr["CHILD"].test( match[0] ) ) {\r
return null;\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
+ (excess = tokenize( unquoted, true )) &&\r
// advance to the next closing parenthesis\r
(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {\r
\r
},\r
\r
"ATTR": function( name, operator, check ) {\r
- if ( !operator ) {\r
- return function( elem ) {\r
- return Sizzle.attr( elem, name ) != null;\r
- };\r
- }\r
-\r
- return function( elem ) {\r
- var result = Sizzle.attr( elem, name ),\r
- value = result + "";\r
+ return function( elem, context ) {\r
+ var result = Sizzle.attr( elem, name );\r
\r
if ( result == null ) {\r
return operator === "!=";\r
}\r
-\r
- switch ( operator ) {\r
- case "=":\r
- return value === check;\r
- case "!=":\r
- return value !== check;\r
- case "^=":\r
- return check && value.indexOf( check ) === 0;\r
- case "*=":\r
- return check && value.indexOf( check ) > -1;\r
- case "$=":\r
- return check && value.substr( value.length - check.length ) === check;\r
- case "~=":\r
- return ( " " + value + " " ).indexOf( check ) > -1;\r
- case "|=":\r
- return value === check || value.substr( 0, check.length + 1 ) === check + "-";\r
+ if ( !operator ) {\r
+ return true;\r
}\r
+\r
+ result += "";\r
+\r
+ return operator === "=" ? result === check :\r
+ operator === "!=" ? result !== check :\r
+ operator === "^=" ? check && result.indexOf( check ) === 0 :\r
+ operator === "*=" ? check && result.indexOf( check ) > -1 :\r
+ operator === "$=" ? check && result.substr( result.length - check.length ) === check :\r
+ operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :\r
+ operator === "|=" ? result === check || result.substr( 0, check.length + 1 ) === check + "-" :\r
+ false;\r
};\r
},\r
\r
"CHILD": function( type, argument, first, last ) {\r
\r
if ( type === "nth" ) {\r
- var doneName = done++;\r
-\r
return function( elem ) {\r
- var parent, diff,\r
- count = 0,\r
- node = elem;\r
+ var node, diff,\r
+ parent = elem.parentNode;\r
\r
if ( first === 1 && last === 0 ) {\r
return true;\r
}\r
\r
- parent = elem.parentNode;\r
-\r
- if ( parent && (parent[ expando ] !== doneName || !elem.sizset) ) {\r
+ if ( parent ) {\r
+ diff = 0;\r
for ( node = parent.firstChild; node; node = node.nextSibling ) {\r
if ( node.nodeType === 1 ) {\r
- node.sizset = ++count;\r
- if ( node === elem ) {\r
+ diff++;\r
+ if ( elem === node ) {\r
break;\r
}\r
}\r
}\r
-\r
- parent[ expando ] = doneName;\r
}\r
\r
- diff = elem.sizset - last;\r
-\r
- if ( first === 0 ) {\r
- return diff === 0;\r
-\r
- } else {\r
- return ( diff % first === 0 && diff / first >= 0 );\r
- }\r
+ // Incorporate the offset (or cast to NaN), then check against cycle size\r
+ diff -= last;\r
+ return diff === first || ( diff % first === 0 && diff / first >= 0 );\r
};\r
}\r
\r
};\r
},\r
\r
- "PSEUDO": function( pseudo, argument, context, xml ) {\r
+ "PSEUDO": function( pseudo, argument ) {\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
+ // Remember that setFilters inherits from pseudos\r
var args,\r
- fn = Expr.pseudos[ pseudo ] || Expr.pseudos[ pseudo.toLowerCase() ];\r
-\r
- if ( !fn ) {\r
- Sizzle.error( "unsupported pseudo: " + pseudo );\r
- }\r
+ fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\r
+ Sizzle.error( "unsupported pseudo: " + pseudo );\r
\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[ expando ] ) {\r
- if ( fn.length > 1 ) {\r
- args = [ pseudo, pseudo, "", argument ];\r
- return function( elem ) {\r
+ if ( fn[ expando ] ) {\r
+ return fn( argument );\r
+ }\r
+\r
+ // But maintain support for old signatures\r
+ if ( fn.length > 1 ) {\r
+ args = [ pseudo, pseudo, "", argument ];\r
+ return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\r
+ markFunction(function( seed, matches ) {\r
+ var idx,\r
+ matched = fn( seed, argument ),\r
+ i = matched.length;\r
+ while ( i-- ) {\r
+ idx = indexOf.call( seed, matched[i] );\r
+ seed[ idx ] = !( matches[ idx ] = matched[i] );\r
+ }\r
+ }) :\r
+ function( elem ) {\r
return fn( elem, 0, args );\r
};\r
- }\r
- return fn;\r
}\r
\r
- return fn( argument, context, xml );\r
+ return fn;\r
}\r
},\r
\r
pseudos: {\r
- "not": markFunction(function( selector, context, xml ) {\r
+ "not": markFunction(function( selector ) {\r
// Trim the selector passed to compile\r
// to avoid treating leading and trailing\r
// spaces as combinators\r
- var matcher = compile( selector.replace( rtrim, "$1" ), context, xml );\r
+ var input = [],\r
+ results = [],\r
+ matcher = compile( selector.replace( rtrim, "$1" ) );\r
+\r
+ return matcher[ expando ] ?\r
+ markFunction(function( seed, matches, context, xml ) {\r
+ var elem,\r
+ unmatched = matcher( seed, null, xml, [] ),\r
+ i = seed.length;\r
+\r
+ // Match elements unmatched by `matcher`\r
+ while ( i-- ) {\r
+ if ( (elem = unmatched[i]) ) {\r
+ seed[i] = !(matches[i] = elem);\r
+ }\r
+ }\r
+ }) :\r
+ function( elem, context, xml ) {\r
+ input[0] = elem;\r
+ matcher( input, null, xml, results );\r
+ return !results.pop();\r
+ };\r
+ }),\r
+\r
+ "has": markFunction(function( selector ) {\r
return function( elem ) {\r
- return !matcher( elem );\r
+ return Sizzle( selector, elem ).length > 0;\r
+ };\r
+ }),\r
+\r
+ "contains": markFunction(function( text ) {\r
+ return function( elem ) {\r
+ return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\r
};\r
}),\r
\r
return true;\r
},\r
\r
- "contains": markFunction(function( text ) {\r
- return function( elem ) {\r
- return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\r
- };\r
- }),\r
-\r
- "has": markFunction(function( selector ) {\r
- return function( elem ) {\r
- return Sizzle( selector, elem ).length > 0;\r
- };\r
- }),\r
-\r
"header": function( elem ) {\r
return rheader.test( elem.nodeName );\r
},\r
\r
"active": function( elem ) {\r
return elem === elem.ownerDocument.activeElement;\r
- }\r
- },\r
-\r
- setFilters: {\r
- "first": function( elements, argument, not ) {\r
- return not ? elements.slice( 1 ) : [ elements[0] ];\r
},\r
\r
- "last": function( elements, argument, not ) {\r
- var elem = elements.pop();\r
- return not ? elements : [ elem ];\r
- },\r
+ // Positional types\r
+ "first": createPositionalPseudo(function( matchIndexes, length, argument ) {\r
+ return [ 0 ];\r
+ }),\r
\r
- "even": function( elements, argument, not ) {\r
- var results = [],\r
- i = not ? 1 : 0,\r
- len = elements.length;\r
- for ( ; i < len; i = i + 2 ) {\r
- results.push( elements[i] );\r
- }\r
- return results;\r
- },\r
+ "last": createPositionalPseudo(function( matchIndexes, length, argument ) {\r
+ return [ length - 1 ];\r
+ }),\r
\r
- "odd": function( elements, argument, not ) {\r
- var results = [],\r
- i = not ? 0 : 1,\r
- len = elements.length;\r
- for ( ; i < len; i = i + 2 ) {\r
- results.push( elements[i] );\r
+ "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {\r
+ return [ argument < 0 ? argument + length : argument ];\r
+ }),\r
+\r
+ "even": createPositionalPseudo(function( matchIndexes, length, argument ) {\r
+ for ( var i = 0; i < length; i += 2 ) {\r
+ matchIndexes.push( i );\r
}\r
- return results;\r
- },\r
+ return matchIndexes;\r
+ }),\r
\r
- "lt": function( elements, argument, not ) {\r
- return not ? elements.slice( +argument ) : elements.slice( 0, +argument );\r
- },\r
+ "odd": createPositionalPseudo(function( matchIndexes, length, argument ) {\r
+ for ( var i = 1; i < length; i += 2 ) {\r
+ matchIndexes.push( i );\r
+ }\r
+ return matchIndexes;\r
+ }),\r
\r
- "gt": function( elements, argument, not ) {\r
- return not ? elements.slice( 0, +argument + 1 ) : elements.slice( +argument + 1 );\r
- },\r
+ "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {\r
+ for ( var i = argument < 0 ? argument + length : argument; --i >= 0; ) {\r
+ matchIndexes.push( i );\r
+ }\r
+ return matchIndexes;\r
+ }),\r
\r
- "eq": function( elements, argument, not ) {\r
- var elem = elements.splice( +argument, 1 );\r
- return not ? elements : elem;\r
- }\r
+ "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {\r
+ for ( var i = argument < 0 ? argument + length : argument; ++i < length; ) {\r
+ matchIndexes.push( i );\r
+ }\r
+ return matchIndexes;\r
+ })\r
}\r
};\r
\r
throw new Error( "Syntax error, unrecognized expression: " + msg );\r
};\r
\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
+function tokenize( selector, parseOnly ) {\r
+ var matched, match, tokens, type, soFar, groups, preFilters,\r
+ cached = tokenCache[ expando ][ selector ];\r
\r
if ( cached ) {\r
- return parseOnly ? 0 : slice.call( cached, 0 );\r
+ return parseOnly ? 0 : cached.slice( 0 );\r
}\r
\r
soFar = selector;\r
groups = [];\r
- i = 0;\r
preFilters = Expr.preFilter;\r
- filters = Expr.filter;\r
\r
while ( soFar ) {\r
\r
if ( !matched || (match = rcomma.exec( soFar )) ) {\r
if ( match ) {\r
soFar = soFar.slice( match[0].length );\r
- tokens.selector = group;\r
}\r
groups.push( tokens = [] );\r
- group = "";\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
- }\r
}\r
\r
matched = false;\r
\r
// Combinators\r
if ( (match = rcombinators.exec( soFar )) ) {\r
- group += match[0];\r
- soFar = soFar.slice( match[0].length );\r
+ tokens.push( matched = new Token( match.shift() ) );\r
+ soFar = soFar.slice( matched.length );\r
\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
+ matched.type = match[0].replace( rtrim, " " );\r
}\r
\r
// Filters\r
- for ( type in filters ) {\r
+ for ( type in Expr.filter ) {\r
if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\r
- ( match = preFilters[ type ](match, context, xml) )) ) {\r
+ // The last two arguments here are (context, xml) for backCompat\r
+ (match = preFilters[ type ]( match, document, true ))) ) {\r
\r
- group += match[0];\r
- soFar = soFar.slice( match[0].length );\r
- matched = tokens.push({\r
- part: type,\r
- string: match.shift(),\r
- captures: match\r
- });\r
+ tokens.push( matched = new Token( match.shift() ) );\r
+ soFar = soFar.slice( matched.length );\r
+ matched.type = type;\r
+ matched.matches = match;\r
}\r
}\r
\r
}\r
}\r
\r
- // Attach the full group as a selector\r
- if ( group ) {\r
- tokens.selector = group;\r
- }\r
-\r
// Return the length of the invalid excess\r
// if we're just parsing\r
// Otherwise, throw an error or return tokens\r
soFar ?\r
Sizzle.error( selector ) :\r
// Cache the tokens\r
- slice.call( tokenCache(key, groups), 0 );\r
+ tokenCache( selector, groups ).slice( 0 );\r
}\r
\r
-function addCombinator( matcher, combinator, context, xml ) {\r
+function addCombinator( matcher, combinator, base ) {\r
var dir = combinator.dir,\r
+ checkNonElements = base && combinator.dir === "parentNode",\r
doneName = done++;\r
\r
- if ( !matcher ) {\r
- // If there is no matcher to check, check against the context\r
- matcher = function( elem ) {\r
- return elem === context;\r
- };\r
- }\r
return combinator.first ?\r
- function( elem ) {\r
+ // Check against closest ancestor/preceding element\r
+ function( elem, context, xml ) {\r
while ( (elem = elem[ dir ]) ) {\r
- if ( elem.nodeType === 1 ) {\r
- return matcher( elem ) && elem;\r
+ if ( checkNonElements || elem.nodeType === 1 ) {\r
+ return matcher( elem, context, xml );\r
}\r
}\r
} :\r
- xml ?\r
- function( elem ) {\r
- while ( (elem = elem[ dir ]) ) {\r
- if ( elem.nodeType === 1 ) {\r
- if ( matcher( elem ) ) {\r
- return elem;\r
- }\r
- }\r
- }\r
- } :\r
- function( elem ) {\r
+\r
+ // Check against all ancestor/preceding elements\r
+ function( elem, context, xml ) {\r
+ // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching\r
+ if ( !xml ) {\r
var cache,\r
- dirkey = doneName + "." + dirruns,\r
- cachedkey = dirkey + "." + cachedruns;\r
+ dirkey = dirruns + " " + doneName + " ",\r
+ cachedkey = dirkey + cachedruns;\r
while ( (elem = elem[ dir ]) ) {\r
- if ( elem.nodeType === 1 ) {\r
+ if ( checkNonElements || elem.nodeType === 1 ) {\r
if ( (cache = elem[ expando ]) === cachedkey ) {\r
return elem.sizset;\r
} else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) {\r
}\r
} else {\r
elem[ expando ] = cachedkey;\r
- if ( matcher( elem ) ) {\r
+ if ( matcher( elem, context, xml ) ) {\r
elem.sizset = true;\r
return elem;\r
}\r
}\r
}\r
}\r
- };\r
+ } else {\r
+ while ( (elem = elem[ dir ]) ) {\r
+ if ( checkNonElements || elem.nodeType === 1 ) {\r
+ if ( matcher( elem, context, xml ) ) {\r
+ return elem;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ };\r
}\r
\r
-function addMatcher( higher, deeper ) {\r
- return higher ?\r
- function( elem ) {\r
- var result = deeper( elem );\r
- return result && higher( result === true ? elem : result );\r
+function elementMatcher( matchers ) {\r
+ return matchers.length > 1 ?\r
+ function( elem, context, xml ) {\r
+ var i = matchers.length;\r
+ while ( i-- ) {\r
+ if ( !matchers[i]( elem, context, xml ) ) {\r
+ return false;\r
+ }\r
+ }\r
+ return true;\r
} :\r
- deeper;\r
+ matchers[0];\r
}\r
\r
-// ["TAG", ">", "ID", " ", "CLASS"]\r
-function matcherFromTokens( tokens, context, xml ) {\r
- var token, matcher,\r
- i = 0;\r
+function condense( unmatched, map, filter, context, xml ) {\r
+ var elem,\r
+ newUnmatched = [],\r
+ i = 0,\r
+ len = unmatched.length,\r
+ mapped = map != null;\r
\r
- for ( ; (token = tokens[i]); i++ ) {\r
- if ( Expr.relative[ token.part ] ) {\r
- matcher = addCombinator( matcher, Expr.relative[ token.part ], context, xml );\r
- } else {\r
- matcher = addMatcher( matcher, Expr.filter[ token.part ].apply(null, token.captures.concat( context, xml )) );\r
+ for ( ; i < len; i++ ) {\r
+ if ( (elem = unmatched[i]) ) {\r
+ if ( !filter || filter( elem, context, xml ) ) {\r
+ newUnmatched.push( elem );\r
+ if ( mapped ) {\r
+ map.push( i );\r
+ }\r
+ }\r
}\r
}\r
\r
- return matcher;\r
+ return newUnmatched;\r
}\r
\r
-function matcherFromGroupMatchers( matchers ) {\r
- return function( elem ) {\r
- var matcher,\r
- j = 0;\r
- for ( ; (matcher = matchers[j]); j++ ) {\r
- if ( matcher(elem) ) {\r
- return true;\r
- }\r
+function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\r
+ if ( postFilter && !postFilter[ expando ] ) {\r
+ postFilter = setMatcher( postFilter );\r
+ }\r
+ if ( postFinder && !postFinder[ expando ] ) {\r
+ postFinder = setMatcher( postFinder, postSelector );\r
+ }\r
+ return markFunction(function( seed, results, context, xml ) {\r
+ // Positional selectors apply to seed elements, so it is invalid to follow them with relative ones\r
+ if ( seed && postFinder ) {\r
+ return;\r
}\r
- return false;\r
- };\r
-}\r
\r
-compile = Sizzle.compile = function( selector, context, xml ) {\r
- var group, i, len,\r
- cached = compilerCache[ expando ][ selector ];\r
+ var i, elem, postFilterIn,\r
+ preMap = [],\r
+ postMap = [],\r
+ preexisting = results.length,\r
\r
- // Return a cached group function if already generated (context dependent)\r
- if ( cached && cached.context === context ) {\r
- return cached;\r
- }\r
+ // Get initial elements from seed or context\r
+ elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [], seed ),\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, len = group.length; i < len; i++ ) {\r
- group[i] = matcherFromTokens(group[i], context, xml);\r
- }\r
+ // Prefilter to get matcher input, preserving a map for seed-results synchronization\r
+ matcherIn = preFilter && ( seed || !selector ) ?\r
+ condense( elems, preMap, preFilter, context, xml ) :\r
+ elems,\r
\r
- // Cache the compiled function\r
- cached = compilerCache( selector, matcherFromGroupMatchers(group) );\r
- cached.context = context;\r
- cached.runs = cached.dirruns = 0;\r
- return cached;\r
-};\r
+ matcherOut = matcher ?\r
+ // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\r
+ postFinder || ( seed ? preFilter : preexisting || postFilter ) ?\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
+ // ...intermediate processing is necessary\r
+ [] :\r
\r
-function handlePOSGroup( selector, posfilter, argument, contexts, seed, not ) {\r
- var results,\r
- fn = Expr.setFilters[ posfilter.toLowerCase() ];\r
+ // ...otherwise use results directly\r
+ results :\r
+ matcherIn;\r
\r
- if ( !fn ) {\r
- Sizzle.error( posfilter );\r
- }\r
+ // Find primary matches\r
+ if ( matcher ) {\r
+ matcher( matcherIn, matcherOut, context, xml );\r
+ }\r
\r
- if ( selector || !(results = seed) ) {\r
- multipleContexts( selector || "*", contexts, (results = []), seed );\r
- }\r
+ // Apply postFilter\r
+ if ( postFilter ) {\r
+ postFilterIn = condense( matcherOut, postMap );\r
+ postFilter( postFilterIn, [], context, xml );\r
\r
- return results.length > 0 ? fn( results, argument, not ) : [];\r
-}\r
+ // Un-match failing elements by moving them back to matcherIn\r
+ i = postFilterIn.length;\r
+ while ( i-- ) {\r
+ if ( (elem = postFilterIn[i]) ) {\r
+ matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\r
+ }\r
+ }\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
+ // Keep seed and results synchronized\r
+ if ( seed ) {\r
+ // Ignore postFinder because it can't coexist with seed\r
+ i = preFilter && matcherOut.length;\r
+ while ( i-- ) {\r
+ if ( (elem = matcherOut[i]) ) {\r
+ seed[ preMap[i] ] = !(results[ preMap[i] ] = elem);\r
}\r
}\r
- };\r
+ } else {\r
+ matcherOut = condense(\r
+ matcherOut === results ?\r
+ matcherOut.splice( preexisting, matcherOut.length ) :\r
+ matcherOut\r
+ );\r
+ if ( postFinder ) {\r
+ postFinder( null, results, matcherOut, xml );\r
+ } else {\r
+ push.apply( results, matcherOut );\r
+ }\r
+ }\r
+ });\r
+}\r
+\r
+function matcherFromTokens( tokens ) {\r
+ var checkContext, matcher, j,\r
+ len = tokens.length,\r
+ leadingRelative = Expr.relative[ tokens[0].type ],\r
+ implicitRelative = leadingRelative || Expr.relative[" "],\r
+ i = leadingRelative ? 1 : 0,\r
+\r
+ // The foundational matcher ensures that elements are reachable from top-level context(s)\r
+ matchContext = addCombinator( function( elem ) {\r
+ return elem === checkContext;\r
+ }, implicitRelative, true ),\r
+ matchAnyContext = addCombinator( function( elem ) {\r
+ return indexOf.call( checkContext, elem ) > -1;\r
+ }, implicitRelative, true ),\r
+ matchers = [ function( elem, context, xml ) {\r
+ return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\r
+ (checkContext = context).nodeType ?\r
+ matchContext( elem, context, xml ) :\r
+ matchAnyContext( elem, context, xml ) );\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
+ if ( (matcher = Expr.relative[ tokens[i].type ]) ) {\r
+ matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];\r
+ } else {\r
+ // The concatenated values are (context, xml) for backCompat\r
+ matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\r
+\r
+ // Return special upon seeing a positional matcher\r
+ if ( matcher[ expando ] ) {\r
+ // Find the next relative operator (if any) for proper handling\r
+ j = ++i;\r
+ for ( ; j < len; j++ ) {\r
+ if ( Expr.relative[ tokens[j].type ] ) {\r
+ break;\r
+ }\r
+ }\r
+ return setMatcher(\r
+ i > 1 && elementMatcher( matchers ),\r
+ i > 1 && tokens.slice( 0, i - 1 ).join("").replace( rtrim, "$1" ),\r
+ matcher,\r
+ i < j && matcherFromTokens( tokens.slice( i, j ) ),\r
+ j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\r
+ j < len && tokens.join("")\r
+ );\r
+ }\r
+ matchers.push( matcher );\r
+ }\r
+ }\r
\r
- if ( (not = rendsWithNot.test( part )) ) {\r
- part = part.slice( 0, -5 ).replace( rcombinators, "$&*" );\r
- anchor++;\r
- }\r
+ return elementMatcher( matchers );\r
+}\r
\r
- if ( match.length > 1 ) {\r
- match[0].replace( rposgroups, setUndefined );\r
+function matcherFromGroupMatchers( elementMatchers, setMatchers ) {\r
+ var bySet = setMatchers.length > 0,\r
+ byElement = elementMatchers.length > 0,\r
+ superMatcher = function( seed, context, xml, results, expandContext ) {\r
+ var elem, j, matcher,\r
+ setMatched = [],\r
+ matchedCount = 0,\r
+ i = "0",\r
+ unmatched = seed && [],\r
+ outermost = expandContext != null,\r
+ contextBackup = outermostContext,\r
+ // We must always have either seed elements or context\r
+ elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ),\r
+ // Nested matchers should use non-integer dirruns\r
+ dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.E);\r
+\r
+ if ( outermost ) {\r
+ outermostContext = context !== document && context;\r
+ cachedruns = superMatcher.el;\r
+ }\r
+\r
+ // Add elements passing elementMatchers directly to results\r
+ for ( ; (elem = elems[i]) != null; i++ ) {\r
+ if ( byElement && elem ) {\r
+ for ( j = 0; (matcher = elementMatchers[j]); j++ ) {\r
+ if ( matcher( elem, context, xml ) ) {\r
+ results.push( elem );\r
+ break;\r
}\r
- elements = handlePOSGroup( part, match[1], match[2], currentContexts, elements, not );\r
}\r
- part = "";\r
+ if ( outermost ) {\r
+ dirruns = dirrunsUnique;\r
+ cachedruns = ++superMatcher.el;\r
+ }\r
}\r
\r
- }\r
+ // Track unmatched elements for set filters\r
+ if ( bySet ) {\r
+ // They will have gone through all possible matchers\r
+ if ( (elem = !matcher && elem) ) {\r
+ matchedCount--;\r
+ }\r
\r
- if ( !matched ) {\r
- part += selector;\r
+ // Lengthen the array for every element, matched or not\r
+ if ( seed ) {\r
+ unmatched.push( elem );\r
+ }\r
+ }\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
+ // Apply set filters to unmatched elements\r
+ matchedCount += i;\r
+ if ( bySet && i !== matchedCount ) {\r
+ for ( j = 0; (matcher = setMatchers[j]); j++ ) {\r
+ matcher( unmatched, setMatched, context, xml );\r
+ }\r
\r
- // Do not sort if this is a single filter\r
- return len === 1 ? results : Sizzle.uniqueSort( results );\r
-}\r
+ if ( seed ) {\r
+ // Reintegrate element matches to eliminate the need for sorting\r
+ if ( matchedCount > 0 ) {\r
+ while ( i-- ) {\r
+ if ( !(unmatched[i] || setMatched[i]) ) {\r
+ setMatched[i] = pop.call( results );\r
+ }\r
+ }\r
+ }\r
\r
-function select( selector, context, results, seed, xml ) {\r
- // Remove excessive whitespace\r
- selector = selector.replace( rtrim, "$1" );\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( match, context, results, seed );\r
- }\r
+ // Discard index placeholder values to get only actual matches\r
+ setMatched = condense( setMatched );\r
+ }\r
\r
- if ( seed ) {\r
- elements = slice.call( seed, 0 );\r
+ // Add matches to results\r
+ push.apply( results, setMatched );\r
\r
- // To maintain document order, only narrow the\r
- // set if there is one group\r
- } else if ( match.length === 1 ) {\r
+ // Seedless set matches succeeding multiple successful matchers stipulate sorting\r
+ if ( outermost && !seed && setMatched.length > 0 &&\r
+ ( matchedCount + setMatchers.length ) > 1 ) {\r
\r
- // Take a shortcut and set the context if the root selector is an ID\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
+ Sizzle.uniqueSort( results );\r
+ }\r
+ }\r
\r
- context = Expr.find["ID"]( token.captures[0].replace( rbackslash, "" ), context, xml )[0];\r
- if ( !context ) {\r
- return results;\r
+ // Override manipulation of globals by nested matchers\r
+ if ( outermost ) {\r
+ dirruns = dirrunsUnique;\r
+ outermostContext = contextBackup;\r
}\r
\r
- selector = selector.slice( tokens.shift().string.length );\r
- }\r
+ return unmatched;\r
+ };\r
+\r
+ superMatcher.el = 0;\r
+ return bySet ?\r
+ markFunction( superMatcher ) :\r
+ superMatcher;\r
+}\r
\r
- findContext = ( (match = rsibling.exec( tokens[0].string )) && !match.index && context.parentNode ) || context;\r
+compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {\r
+ var i,\r
+ setMatchers = [],\r
+ elementMatchers = [],\r
+ cached = compilerCache[ expando ][ selector ];\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
+ if ( !cached ) {\r
+ // Generate a function of recursive functions that can be used to check each element\r
+ if ( !group ) {\r
+ group = tokenize( selector );\r
+ }\r
+ i = group.length;\r
+ while ( i-- ) {\r
+ cached = matcherFromTokens( group[i] );\r
+ if ( cached[ expando ] ) {\r
+ setMatchers.push( cached );\r
+ } else {\r
+ elementMatchers.push( cached );\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
- } else {\r
- selector = selector.slice( 0, selector.length - lastToken.length ) +\r
- lastToken.replace( matchExpr[ type ], "" );\r
+ }\r
\r
- if ( !selector ) {\r
- push.apply( results, slice.call(elements, 0) );\r
- }\r
+ // Cache the compiled function\r
+ cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\r
+ }\r
+ return cached;\r
+};\r
\r
- break;\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
+ return results;\r
+}\r
+\r
+function select( selector, context, results, seed, xml ) {\r
+ var i, tokens, token, type, find,\r
+ match = tokenize( selector ),\r
+ j = match.length;\r
+\r
+ if ( !seed ) {\r
+ // Try to minimize operations if there is only one group\r
+ if ( match.length === 1 ) {\r
+\r
+ // Take a shortcut and set the context if the root selector is an ID\r
+ tokens = match[0] = match[0].slice( 0 );\r
+ if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&\r
+ context.nodeType === 9 && !xml &&\r
+ Expr.relative[ tokens[1].type ] ) {\r
+\r
+ context = Expr.find["ID"]( token.matches[0].replace( rbackslash, "" ), context, xml )[0];\r
+ if ( !context ) {\r
+ return results;\r
}\r
+\r
+ selector = selector.slice( tokens.shift().length );\r
}\r
- }\r
- }\r
\r
- // Only loop over the given elements once\r
- if ( selector ) {\r
- matcher = compile( selector, context, xml );\r
- dirruns = matcher.dirruns++;\r
- if ( elements == null ) {\r
- elements = Expr.find["TAG"]( "*", (rsibling.test( selector ) && context.parentNode) || context );\r
- }\r
+ // Fetch a seed set for right-to-left matching\r
+ for ( i = matchExpr["POS"].test( selector ) ? -1 : tokens.length - 1; i >= 0; i-- ) {\r
+ token = tokens[i];\r
+\r
+ // Abort if we hit a combinator\r
+ if ( Expr.relative[ (type = token.type) ] ) {\r
+ break;\r
+ }\r
+ if ( (find = Expr.find[ type ]) ) {\r
+ // Search, expanding context for leading sibling combinators\r
+ if ( (seed = find(\r
+ token.matches[0].replace( rbackslash, "" ),\r
+ rsibling.test( tokens[0].type ) && context.parentNode || context,\r
+ xml\r
+ )) ) {\r
+\r
+ // If seed is empty or no tokens remain, we can return early\r
+ tokens.splice( i, 1 );\r
+ selector = seed.length && tokens.join("");\r
+ if ( !selector ) {\r
+ push.apply( results, slice.call( seed, 0 ) );\r
+ return results;\r
+ }\r
\r
- for ( i = 0; (elem = elements[i]); i++ ) {\r
- cachedruns = matcher.runs++;\r
- if ( matcher(elem) ) {\r
- results.push( elem );\r
+ break;\r
+ }\r
+ }\r
}\r
}\r
}\r
\r
+ // Compile and execute a filtering function\r
+ // Provide `match` to avoid retokenization if we modified the selector above\r
+ compile( selector, match )(\r
+ seed,\r
+ context,\r
+ xml,\r
+ results,\r
+ rsibling.test( selector )\r
+ );\r
return results;\r
}\r
\r
oldSelect = select,\r
rescape = /'|\\/g,\r
rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,\r
- rbuggyQSA = [],\r
+\r
+ // qSa(:focus) reports false when true (Chrome 21),\r
+ // A support test would require too much code (would include document ready)\r
+ rbuggyQSA = [":focus"],\r
+\r
+ // matchesSelector(:focus) reports false when true (Chrome 21),\r
// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\r
// A support test would require too much code (would include document ready)\r
// just skip matchesSelector for :active\r
- rbuggyMatches = [":active"],\r
+ rbuggyMatches = [ ":active", ":focus" ],\r
matches = docElem.matchesSelector ||\r
docElem.mozMatchesSelector ||\r
docElem.webkitMatchesSelector ||\r
}\r
});\r
\r
- rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );\r
+ // rbuggyQSA always contains :focus, so no need for a length check\r
+ rbuggyQSA = /* rbuggyQSA.length && */ new RegExp( rbuggyQSA.join("|") );\r
\r
select = function( selector, context, results, seed, xml ) {\r
// Only use querySelectorAll when not filtering,\r
// when this is not xml,\r
// and when no QSA bugs apply\r
if ( !seed && !xml && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {\r
- if ( context.nodeType === 9 ) {\r
- try {\r
- push.apply( results, slice.call(context.querySelectorAll( selector ), 0) );\r
- return results;\r
- } catch(qsaError) {}\r
+ var groups, i,\r
+ old = true,\r
+ nid = expando,\r
+ newContext = context,\r
+ newSelector = context.nodeType === 9 && selector;\r
+\r
// qSA works strangely on Element-rooted queries\r
// We can work around this by specifying an extra ID on the root\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 groups, i, len,\r
- old = context.getAttribute("id"),\r
- nid = old || expando,\r
- newContext = rsibling.test( selector ) && context.parentNode || context;\r
-\r
- if ( old ) {\r
- nid = nid.replace( rescape, "\\$&" );\r
+ if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {\r
+ groups = tokenize( selector );\r
+\r
+ if ( (old = context.getAttribute("id")) ) {\r
+ nid = old.replace( rescape, "\\$&" );\r
} else {\r
context.setAttribute( "id", nid );\r
}\r
+ nid = "[id='" + nid + "'] ";\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
+ i = groups.length;\r
+ while ( i-- ) {\r
+ groups[i] = nid + groups[i].join("");\r
}\r
+ newContext = rsibling.test( selector ) && context.parentNode || context;\r
+ newSelector = groups.join(",");\r
+ }\r
+\r
+ if ( newSelector ) {\r
try {\r
push.apply( results, slice.call( newContext.querySelectorAll(\r
- groups.join(",")\r
+ newSelector\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( matchExpr["PSEUDO"].source, matchExpr["POS"].source, "!=" );\r
+ rbuggyMatches.push( "!=", pseudos );\r
} catch ( e ) {}\r
});\r
\r
- // rbuggyMatches always contains :active, so no need for a length check\r
+ // rbuggyMatches always contains :active and :focus, so no need for a length check\r
rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join("|") );\r
\r
Sizzle.matchesSelector = function( elem, expr ) {\r
}\r
\r
// Deprecated\r
-Expr.setFilters["nth"] = Expr.setFilters["eq"];\r
+Expr.pseudos["nth"] = Expr.pseudos["eq"];\r
\r
// Back-compat\r
-Expr.filters = Expr.pseudos;\r
+function setFilters() {}\r
+Expr.filters = setFilters.prototype = Expr.pseudos;\r
+Expr.setFilters = new setFilters();\r
\r
// Override sizzle attribute retrieval
Sizzle.attr = jQuery.attr;
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
// Set data for the fake xhr object
jqXHR.status = status;
- jqXHR.statusText = "" + ( nativeStatusText || statusText );
+ jqXHR.statusText = ( nativeStatusText || statusText ) + "";
// Success/Error
if ( isSuccess ) {
// 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[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
- ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
- );
+ parts = rurl.exec( s.url.toLowerCase() ) || false;
+ s.crossDomain = parts && ( parts.join(":") + ( parts[ 3 ] ? "" : parts[ 1 ] === "http:" ? 80 : 443 ) ) !==
+ ( ajaxLocParts.join(":") + ( ajaxLocParts[ 3 ] ? "" : ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) );
}
// Convert data if not already a string
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];
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;
});
}
- 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;
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 = {