@@ -12,16 +12,17 @@ var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^
1212
1313var Sizzle = function ( selector , context , results , seed ) {
1414 results = results || [ ] ;
15- context = context || document ;
15+ var origContext = context = context || document ;
1616
17- if ( context . nodeType !== 1 && context . nodeType !== 9 )
17+ if ( context . nodeType !== 1 && context . nodeType !== 9 ) {
1818 return [ ] ;
19+ }
1920
2021 if ( ! selector || typeof selector !== "string" ) {
2122 return results ;
2223 }
2324
24- var parts = [ ] , m , set , checkSet , check , mode , extra , prune = true ;
25+ var parts = [ ] , m , set , checkSet , check , mode , extra , prune = true , contextXML = isXML ( context ) ;
2526
2627 // Reset the position of the chunker regexp (start from head)
2728 chunker . lastIndex = 0 ;
@@ -53,31 +54,43 @@ var Sizzle = function(selector, context, results, seed) {
5354 }
5455 }
5556 } else {
56- var ret = seed ?
57- { expr : parts . pop ( ) , set : makeArray ( seed ) } :
58- Sizzle . find ( parts . pop ( ) , parts . length === 1 && context . parentNode ? context . parentNode : context , isXML ( context ) ) ;
59- set = Sizzle . filter ( ret . expr , ret . set ) ;
60-
61- if ( parts . length > 0 ) {
62- checkSet = makeArray ( set ) ;
63- } else {
64- prune = false ;
57+ // Take a shortcut and set the context if the root selector is an ID
58+ // (but not if it'll be faster if the inner selector is an ID)
59+ if ( ! seed && parts . length > 1 && context . nodeType === 9 && ! contextXML &&
60+ Expr . match . ID . test ( parts [ 0 ] ) && ! Expr . match . ID . test ( parts [ parts . length - 1 ] ) ) {
61+ var ret = Sizzle . find ( parts . shift ( ) , context , contextXML ) ;
62+ context = ret . expr ? Sizzle . filter ( ret . expr , ret . set ) [ 0 ] : ret . set [ 0 ] ;
6563 }
6664
67- while ( parts . length ) {
68- var cur = parts . pop ( ) , pop = cur ;
65+ if ( context ) {
66+ var ret = seed ?
67+ { expr : parts . pop ( ) , set : makeArray ( seed ) } :
68+ Sizzle . find ( parts . pop ( ) , parts . length === 1 && context . parentNode ? context . parentNode : context , contextXML ) ;
69+ set = ret . expr ? Sizzle . filter ( ret . expr , ret . set ) : ret . set ;
6970
70- if ( ! Expr . relative [ cur ] ) {
71- cur = "" ;
71+ if ( parts . length > 0 ) {
72+ checkSet = makeArray ( set ) ;
7273 } else {
73- pop = parts . pop ( ) ;
74+ prune = false ;
7475 }
7576
76- if ( pop == null ) {
77- pop = context ;
78- }
77+ while ( parts . length ) {
78+ var cur = parts . pop ( ) , pop = cur ;
79+
80+ if ( ! Expr . relative [ cur ] ) {
81+ cur = "" ;
82+ } else {
83+ pop = parts . pop ( ) ;
84+ }
85+
86+ if ( pop == null ) {
87+ pop = context ;
88+ }
7989
80- Expr . relative [ cur ] ( checkSet , pop , isXML ( context ) ) ;
90+ Expr . relative [ cur ] ( checkSet , pop , contextXML ) ;
91+ }
92+ } else {
93+ checkSet = parts = [ ] ;
8194 }
8295 }
8396
@@ -92,7 +105,7 @@ var Sizzle = function(selector, context, results, seed) {
92105 if ( toString . call ( checkSet ) === "[object Array]" ) {
93106 if ( ! prune ) {
94107 results . push . apply ( results , checkSet ) ;
95- } else if ( context . nodeType === 1 ) {
108+ } else if ( context && context . nodeType === 1 ) {
96109 for ( var i = 0 ; checkSet [ i ] != null ; i ++ ) {
97110 if ( checkSet [ i ] && ( checkSet [ i ] === true || checkSet [ i ] . nodeType === 1 && contains ( context , checkSet [ i ] ) ) ) {
98111 results . push ( set [ i ] ) ;
@@ -110,7 +123,7 @@ var Sizzle = function(selector, context, results, seed) {
110123 }
111124
112125 if ( extra ) {
113- Sizzle ( extra , context , results , seed ) ;
126+ Sizzle ( extra , origContext , results , seed ) ;
114127
115128 if ( sortOrder ) {
116129 hasDuplicate = false ;
0 commit comments