Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merged some recent fixes in from Sizzle.

  • Loading branch information...
commit 8e8d7ade434de3d79cc6145f370866f297a07b54 1 parent cde93dc
@jeresig jeresig authored
Showing with 68 additions and 46 deletions.
  1. +41 −43 src/selector.js
  2. +1 −1  test/index.html
  3. +26 −2 test/unit/selector.js
View
84 src/selector.js
@@ -35,34 +35,21 @@ var Sizzle = function(selector, context, results, seed) {
}
}
- if ( parts.length > 1 && Expr.match.POS.exec( selector ) ) {
+ if ( parts.length > 1 && origPOS.exec( selector ) ) {
if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
- var later = "", match;
-
- // Position selectors must be done after the filter
- while ( (match = Expr.match.POS.exec( selector )) ) {
- later += match[0];
- selector = selector.replace( Expr.match.POS, "" );
- }
-
- set = Sizzle.filter( later, Sizzle( /\s$/.test(selector) ? selector + "*" : selector, context ) );
+ set = posProcess( parts[0] + parts[1], context );
} else {
set = Expr.relative[ parts[0] ] ?
[ context ] :
Sizzle( parts.shift(), context );
while ( parts.length ) {
- var tmpSet = [];
-
selector = parts.shift();
+
if ( Expr.relative[ selector ] )
selector += parts.shift();
- for ( var i = 0, l = set.length; i < l; i++ ) {
- Sizzle( selector, set[i], tmpSet );
- }
-
- set = tmpSet;
+ set = posProcess( selector, set );
}
}
} else {
@@ -170,7 +157,7 @@ Sizzle.filter = function(expr, set, inplace, not){
while ( expr && set.length ) {
for ( var type in Expr.filter ) {
if ( (match = Expr.match[ type ].exec( expr )) != null ) {
- var filter = Expr.filter[ type ], goodArray = null, goodPos = 0, found, item;
+ var filter = Expr.filter[ type ], found, item;
anyFound = false;
if ( curLoop == result ) {
@@ -184,26 +171,13 @@ Sizzle.filter = function(expr, set, inplace, not){
anyFound = found = true;
} else if ( match === true ) {
continue;
- } else if ( match[0] === true ) {
- goodArray = [];
- var last = null, elem;
- for ( var i = 0; (elem = curLoop[i]) !== undefined; i++ ) {
- if ( elem && last !== elem ) {
- goodArray.push( elem );
- last = elem;
- }
- }
}
}
if ( match ) {
- for ( var i = 0; (item = curLoop[i]) !== undefined; i++ ) {
+ for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
if ( item ) {
- if ( goodArray && item != goodArray[goodPos] ) {
- goodPos++;
- }
-
- found = filter( item, match, goodPos, goodArray );
+ found = filter( item, match, i, curLoop );
var pass = not ^ !!found;
if ( inplace && found != null ) {
@@ -358,12 +332,14 @@ var Expr = Sizzle.selectors = {
CLASS: function(match, curLoop, inplace, result, not){
match = " " + match[1].replace(/\\/g, "") + " ";
- for ( var i = 0; curLoop[i]; i++ ) {
- if ( not ^ (" " + curLoop[i].className + " ").indexOf(match) >= 0 ) {
- if ( !inplace )
- result.push( curLoop[i] );
- } else if ( inplace ) {
- curLoop[i] = false;
+ for ( var i = 0; curLoop[i] != null; i++ ) {
+ if ( curLoop[i] ) {
+ if ( not ^ (" " + curLoop[i].className + " ").indexOf(match) >= 0 ) {
+ if ( !inplace )
+ result.push( curLoop[i] );
+ } else if ( inplace ) {
+ curLoop[i] = false;
+ }
}
}
@@ -373,8 +349,8 @@ var Expr = Sizzle.selectors = {
return match[1].replace(/\\/g, "");
},
TAG: function(match, curLoop){
- for ( var i = 0; !curLoop[i]; i++ ){}
- return isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
+ for ( var i = 0; curLoop[i] === false; i++ ){}
+ return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
},
CHILD: function(match){
if ( match[1] == "nth" ) {
@@ -394,7 +370,7 @@ var Expr = Sizzle.selectors = {
return match;
},
ATTR: function(match){
- var name = match[1];
+ var name = match[1].replace(/\\/g, "");
if ( Expr.attrMap[name] ) {
match[1] = Expr.attrMap[name];
@@ -616,6 +592,8 @@ var Expr = Sizzle.selectors = {
}
};
+var origPOS = Expr.match.POS;
+
for ( var type in Expr.match ) {
Expr.match[ type ] = RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
}
@@ -750,7 +728,7 @@ if ( document.querySelectorAll ) (function(){
Sizzle.matches = oldSizzle.matches;
})();
-if ( document.documentElement.getElementsByClassName ) {
+if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) {
Expr.order.splice(1, 0, "CLASS");
Expr.find.CLASS = function(match, context) {
return context.getElementsByClassName(match[1]);
@@ -835,6 +813,26 @@ var isXML = function(elem){
elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
};
+var posProcess = function(selector, context){
+ var tmpSet = [], later = "", match,
+ root = context.nodeType ? [context] : context;
+
+ // Position selectors must be done after the filter
+ // And so must :not(positional) so we move all PSEUDOs to the end
+ while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
+ later += match[0];
+ selector = selector.replace( Expr.match.PSEUDO, "" );
+ }
+
+ selector = Expr.relative[selector] ? selector + "*" : selector;
+
+ for ( var i = 0, l = root.length; i < l; i++ ) {
+ Sizzle( selector, root[i], tmpSet );
+ }
+
+ return Sizzle.filter( later, tmpSet );
+}
+
// EXPOSE
jQuery.find = Sizzle;
jQuery.filter = Sizzle.filter;
View
2  test/index.html
@@ -29,7 +29,7 @@ <h2 id="banner"></h2>
<h2 id="userAgent"></h2>
<!-- Test HTML -->
- <div id="nothiddendiv" style="height:1px;background:white;">
+ <div id="nothiddendiv" style="height:1px;background:white;" class="nothiddendiv">
<div id="nothiddendivchild"></div>
</div>
<!-- this iframe is outside the #main so it won't reload constantly wasting time, but it means the tests must be "safe" and clean up after themselves -->
View
28 test/unit/selector.js
@@ -141,7 +141,7 @@ test("multiple", function() {
});
test("child and adjacent", function() {
- expect(41);
+ expect(44);
t( "Child", "p > a", ["simon1","google","groups","mark","yahoo","simon"] );
t( "Child", "p> a", ["simon1","google","groups","mark","yahoo","simon"] );
t( "Child", "p >a", ["simon1","google","groups","mark","yahoo","simon"] );
@@ -156,6 +156,11 @@ test("child and adjacent", function() {
t( "Adjacent", "p + p", ["ap","en","sap"] );
t( "Comma, Child, and Adjacent", "a + a, code > a", ["groups","anchor1","anchor2"] );
+ t( "Verify deep class selector", "div.blah > p > a", [] );
+
+ t( "No element deep selector", "div.foo > span > a", [] );
+ t( "No element not selector", ".container div:not(.excluded) div", [] );
+
isSet( jQuery("> :first", document.getElementById("nothiddendiv")), q("nothiddendivchild"), "Verify child context positional selctor" );
isSet( jQuery("> :eq(0)", document.getElementById("nothiddendiv")), q("nothiddendivchild"), "Verify child context positional selctor" );
isSet( jQuery("> *:first", document.getElementById("nothiddendiv")), q("nothiddendivchild"), "Verify child context positional selctor" );
@@ -239,7 +244,7 @@ test("attributes", function() {
});
test("pseudo (:) selectors", function() {
- expect(34);
+ expect(51);
t( "First Child", "p:first-child", ["firstp","sndp"] );
t( "Last Child", "p:last-child", ["sap"] );
t( "Only Child", "a:only-child", ["simon1","anchor1","yahoo","anchor2"] );
@@ -267,6 +272,25 @@ test("pseudo (:) selectors", function() {
t( "Is A Parent", "p:parent", ["firstp","ap","sndp","en","sap","first"] );
t( "Is Visible", "#form input:visible", ["text1","text2","radio1","radio2","check1","check2","name"] );
t( "Is Hidden", "#form input:hidden", ["hidden1","hidden2"] );
+
+ t( "Check position filtering", "div#nothiddendiv:eq(0)", ["nothiddendiv"] );
+ t( "Check position filtering", "div#nothiddendiv:last", ["nothiddendiv"] );
+ t( "Check position filtering", "div#nothiddendiv:not(:gt(0))", ["nothiddendiv"] );
+ t( "Check position filtering", "#foo > :not(:first)", ["en", "sap"] );
+ t( "Check position filtering", "select > :not(:gt(2))", ["option1a", "option1b", "option1c"] );
+ t( "Check position filtering", "select:lt(2) :not(:first)", ["option1b", "option1c", "option1d", "option2a", "option2b", "option2c", "option2d"] );
+ t( "Check position filtering", "div.nothiddendiv:eq(0)", ["nothiddendiv"] );
+ t( "Check position filtering", "div.nothiddendiv:last", ["nothiddendiv"] );
+ t( "Check position filtering", "div.nothiddendiv:not(:gt(0))", ["nothiddendiv"] );
+
+ t( "Check element position", "div div:eq(0)", ["nothiddendivchild"] );
+ t( "Check element position", "div div:eq(5)", ["fadeout"] );
+ t( "Check element position", "div div:eq(27)", ["t2037"] );
+ t( "Check element position", "div div:first", ["nothiddendivchild"] );
+ t( "Check element position", "div > div:first", ["nothiddendivchild"] );
+ t( "Check element position", "#dl div:first div:first", ["foo"] );
+ t( "Check element position", "#dl div:first > div:first", ["foo"] );
+ t( "Check element position", "div#nothiddendiv:first > div:first", ["nothiddendivchild"] );
t( "Form element :input", "#form :input", ["text1", "text2", "radio1", "radio2", "check1", "check2", "hidden1", "hidden2", "name", "button", "area1", "select1", "select2", "select3"] );
t( "Form element :radio", "#form :radio", ["radio1", "radio2"] );
Please sign in to comment.
Something went wrong with that request. Please try again.