jQuery.extend({
expr: {
- "": "m[2]=='*'||jQuery.nodeName(a,m[2])",
- "#": "a.getAttribute('id')==m[2]",
+ "": function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},
+ "#": function(a,i,m){return a.getAttribute("id")==m[2];},
":": {
// Position Checks
- lt: "i<m[3]-0",
- gt: "i>m[3]-0",
- nth: "m[3]-0==i",
- eq: "m[3]-0==i",
- first: "i==0",
- last: "i==r.length-1",
- even: "i%2==0",
- odd: "i%2",
+ lt: function(a,i,m){return i<m[3]-0;},
+ gt: function(a,i,m){return i>m[3]-0;},
+ nth: function(a,i,m){return m[3]-0==i;},
+ eq: function(a,i,m){return m[3]-0==i;},
+ first: function(a,i){return i==0;},
+ last: function(a,i,m,r){return i==r.length-1;},
+ even: function(a,i){return i%2==0;},
+ odd: function(a,i){return i%2;},
// Child Checks
- "first-child": "a.parentNode.getElementsByTagName('*')[0]==a",
- "last-child": "jQuery.nth(a.parentNode.lastChild,1,'previousSibling')==a",
- "only-child": "!jQuery.nth(a.parentNode.lastChild,2,'previousSibling')",
+ "first-child": function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},
+ "last-child": function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},
+ "only-child": function(a){return !jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},
// Parent Checks
- parent: "a.firstChild",
- empty: "!a.firstChild",
+ parent: function(a){return a.firstChild;},
+ empty: function(a){return !a.firstChild;},
// Text Check
- contains: "(a.textContent||a.innerText||'').indexOf(m[3])>=0",
+ contains: function(a,i,m){return (a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},
// Visibility
- visible: '"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden"',
- hidden: '"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden"',
+ visible: function(a){return "hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},
+ hidden: function(a){return "hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},
// Form attributes
- enabled: "!a.disabled",
- disabled: "a.disabled",
- checked: "a.checked",
- selected: "a.selected||jQuery.attr(a,'selected')",
+ enabled: function(a){return !a.disabled;},
+ disabled: function(a){return a.disabled;},
+ checked: function(a){return a.checked;},
+ selected: function(a){return a.selected||jQuery.attr(a,"selected");},
// Form elements
- text: "'text'==a.type",
- radio: "'radio'==a.type",
- checkbox: "'checkbox'==a.type",
- file: "'file'==a.type",
- password: "'password'==a.type",
- submit: "'submit'==a.type",
- image: "'image'==a.type",
- reset: "'reset'==a.type",
- button: '"button"==a.type||jQuery.nodeName(a,"button")',
- input: "/input|select|textarea|button/i.test(a.nodeName)",
+ text: function(a){return "text"==a.type;},
+ radio: function(a){return "radio"==a.type;},
+ checkbox: function(a){return "checkbox"==a.type;},
+ file: function(a){return "file"==a.type;},
+ password: function(a){return "password"==a.type;},
+ submit: function(a){return "submit"==a.type;},
+ image: function(a){return "image"==a.type;},
+ reset: function(a){return "reset"==a.type;},
+ button: function(a){return "button"==a.type||jQuery.nodeName(a,"button");},
+ input: function(a){return /input|select|textarea|button/i.test(a.nodeName);},
// :has()
- has: "jQuery.find(m[3],a).length",
+ has: function(a,i,m){return jQuery.find(m[3],a).length;},
// :header
- header: "/h\\d/i.test(a.nodeName)",
+ header: function(a){return /h\d/i.test(a.nodeName);},
// :animated
- animated: "jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length"
+ animated: function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}
}
},
if ( typeof t != "string" )
return [ t ];
- // Make sure that the context is a DOM Element
- if ( context && !context.nodeType )
- context = null;
+ // check to make sure context is a DOM element or a document
+ if ( context && context.nodeType != 1 && context.nodeType != 9)
+ return [ ];
// Set the correct context (if none is provided)
context = context || document;
// Initialize the search
- var ret = [context], done = [], last;
+ var ret = [context], done = [], last, nodeName;
// Continue while a selector expression exists, and while
// we're no longer looping upon ourselves
var m = re.exec(t);
if ( m ) {
- var nodeName = m[1].toUpperCase();
+ nodeName = m[1].toUpperCase();
// Perform our own iteration and filter
for ( var i = 0; ret[i]; i++ )
for ( var c = ret[i].firstChild; c; c = c.nextSibling )
- if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName.toUpperCase()) )
+ if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName) )
r.push( c );
ret = r;
if ( (m = re.exec(t)) != null ) {
r = [];
- var nodeName = m[2], merge = {};
+ var merge = {};
+ nodeName = m[2].toUpperCase();
m = m[1];
for ( var j = 0, rl = ret.length; j < rl; j++ ) {
if ( m == "~" && merge[id] ) break;
- if (!nodeName || n.nodeName.toUpperCase() == nodeName.toUpperCase() ) {
+ if (!nodeName || n.nodeName.toUpperCase() == nodeName ) {
if ( m == "~" ) merge[id] = true;
r.push( n );
}
// Re-organize the results, so that they're consistent
if ( m ) {
- m = [ 0, m[2], m[3], m[1] ];
+ m = [ 0, m[2], m[3], m[1] ];
} else {
// Otherwise, do a traditional filter check for
var last;
// Look for common filter expressions
- while ( t && t != last ) {
+ while ( t && t != last ) {
last = t;
var p = jQuery.parse, m;
// :not() is a special case that can be optimized by
// keeping it out of the expression list
if ( m[1] == ":" && m[2] == "not" )
- r = jQuery.filter(m[3], r, true).r;
+ // optimize if only one selector found (most common case)
+ r = isSimple.test( m[3] ) ?
+ jQuery.filter(m[3], r, true).r :
+ jQuery( r ).not( m[3] );
// We can get a big speed boost by filtering by class here
else if ( m[1] == "." )
// We can get a speed boost by handling nth-child here
} else if ( m[1] == ":" && m[2] == "nth-child" ) {
var merge = {}, tmp = [],
- test = /(\d*)n\+?(\d*)/.exec(
+ // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
+ test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" ||
- !/\D/.test(m[3]) && "n+" + m[3] || m[3]),
- first = (test[1] || 1) - 0, last = test[2] - 0;
-
+ !/\D/.test(m[3]) && "0n+" + m[3] || m[3]),
+ // calculate the numbers (first)n+(last) including if they are negative
+ first = (test[1] + (test[2] || 1)) - 0, last = test[3] - 0;
+
+ // loop through all the elements left in the jQuery object
for ( var i = 0, rl = r.length; i < rl; i++ ) {
var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode);
var add = false;
- if ( first == 1 ) {
- if ( last == 0 || node.nodeIndex == last )
+ if ( first == 0 ) {
+ if ( node.nodeIndex == last )
add = true;
- } else if ( (node.nodeIndex + last) % first == 0 )
+ } else if ( (node.nodeIndex - last) % first == 0 && (node.nodeIndex - last) / first >= 0 )
add = true;
if ( add ^ not )
// Otherwise, find the expression to execute
} else {
- var f = jQuery.expr[m[1]];
- if ( typeof f != "string" )
- f = jQuery.expr[m[1]][m[2]];
+ var fn = jQuery.expr[ m[1] ];
+ if ( typeof fn == "object" )
+ fn = fn[ m[2] ];
- // Build a custom macro to enclose it
- f = eval("false||function(a,i){return " + f + "}");
+ if ( typeof fn == "string" )
+ fn = eval("false||function(a,i){return " + fn + ";}");
// Execute it against the current filter
- r = jQuery.grep( r, f, not );
+ r = jQuery.grep( r, function(elem, i){
+ return fn(elem, i, m, r);
+ }, not );
}
}
return { r: r, t: t };
},
- parents: function( elem ){
+ dir: function( elem, dir ){
var matched = [];
- var cur = elem.parentNode;
+ var cur = elem[dir];
while ( cur && cur != document ) {
- matched.push( cur );
- cur = cur.parentNode;
+ if ( cur.nodeType == 1 )
+ matched.push( cur );
+ cur = cur[dir];
}
return matched;
},
return r;
}
});
+