@@ -17,7 +17,7 @@ var _SELECTOR_REGEXP = RegExpWrapper.create(
1717 '([-\\w]+)|' + // "tag"
1818 '(?:\\.([-\\w]+))|' + // ".class"
1919 '(?:\\[([-\\w*]+)(?:=([^\\]]*))?\\])|' + // "[name]", "[name=value]" or "[name*=value]"
20- '(?: \\))|' + // ")"
20+ '(\\))|' + // ")"
2121 '(\\s*,\\s*)' ) ; // ","
2222
2323/**
@@ -29,11 +29,11 @@ export class CssSelector {
2929 element : string ;
3030 classNames : List < string > ;
3131 attrs : List < string > ;
32- notSelector : CssSelector ;
32+ notSelectors : List < CssSelector > ;
3333 static parse ( selector : string ) : List < CssSelector > {
3434 var results = ListWrapper . create ( ) ;
3535 var _addResult = ( res , cssSel ) => {
36- if ( isPresent ( cssSel . notSelector ) && isBlank ( cssSel . element ) &&
36+ if ( cssSel . notSelectors . length > 0 && isBlank ( cssSel . element ) &&
3737 ListWrapper . isEmpty ( cssSel . classNames ) && ListWrapper . isEmpty ( cssSel . attrs ) ) {
3838 cssSel . element = "*" ;
3939 }
@@ -43,13 +43,15 @@ export class CssSelector {
4343 var matcher = RegExpWrapper . matcher ( _SELECTOR_REGEXP , selector ) ;
4444 var match ;
4545 var current = cssSelector ;
46+ var inNot = false ;
4647 while ( isPresent ( match = RegExpMatcherWrapper . next ( matcher ) ) ) {
4748 if ( isPresent ( match [ 1 ] ) ) {
48- if ( isPresent ( cssSelector . notSelector ) ) {
49+ if ( inNot ) {
4950 throw new BaseException ( 'Nesting :not is not allowed in a selector' ) ;
5051 }
51- current . notSelector = new CssSelector ( ) ;
52- current = current . notSelector ;
52+ inNot = true ;
53+ current = new CssSelector ( ) ;
54+ ListWrapper . push ( cssSelector . notSelectors , current ) ;
5355 }
5456 if ( isPresent ( match [ 2 ] ) ) {
5557 current . setElement ( match [ 2 ] ) ;
@@ -61,6 +63,13 @@ export class CssSelector {
6163 current . addAttribute ( match [ 4 ] , match [ 5 ] ) ;
6264 }
6365 if ( isPresent ( match [ 6 ] ) ) {
66+ inNot = false ;
67+ current = cssSelector ;
68+ }
69+ if ( isPresent ( match [ 7 ] ) ) {
70+ if ( inNot ) {
71+ throw new BaseException ( 'Multiple selectors in :not are not supported' ) ;
72+ }
6473 _addResult ( results , cssSelector ) ;
6574 cssSelector = current = new CssSelector ( ) ;
6675 }
@@ -73,12 +82,12 @@ export class CssSelector {
7382 this . element = null ;
7483 this . classNames = ListWrapper . create ( ) ;
7584 this . attrs = ListWrapper . create ( ) ;
76- this . notSelector = null ;
85+ this . notSelectors = ListWrapper . create ( ) ;
7786 }
7887
7988 isElementSelector ( ) : boolean {
8089 return isPresent ( this . element ) && ListWrapper . isEmpty ( this . classNames ) &&
81- ListWrapper . isEmpty ( this . attrs ) && isBlank ( this . notSelector ) ;
90+ ListWrapper . isEmpty ( this . attrs ) && this . notSelectors . length === 0 ;
8291 }
8392
8493 setElement ( element : string = null ) {
@@ -121,9 +130,8 @@ export class CssSelector {
121130 res += ']' ;
122131 }
123132 }
124- if ( isPresent ( this . notSelector ) ) {
125- res += ":not(" + this . notSelector . toString ( ) + ")" ;
126- }
133+ ListWrapper . forEach ( this . notSelectors ,
134+ ( notSelector ) => { res += ":not(" + notSelector . toString ( ) + ")" ; } ) ;
127135 return res ;
128136 }
129137}
@@ -133,9 +141,9 @@ export class CssSelector {
133141 * are contained in a given CssSelector.
134142 */
135143export class SelectorMatcher {
136- static createNotMatcher ( notSelector : CssSelector ) {
144+ static createNotMatcher ( notSelectors : List < CssSelector > ) {
137145 var notMatcher = new SelectorMatcher ( ) ;
138- notMatcher . _addSelectable ( notSelector , null , null ) ;
146+ notMatcher . addSelectables ( notSelectors , null ) ;
139147 return notMatcher ;
140148 }
141149
@@ -357,22 +365,22 @@ class SelectorListContext {
357365// Store context to pass back selector and context when a selector is matched
358366class SelectorContext {
359367 selector : CssSelector ;
360- notSelector : CssSelector ;
368+ notSelectors : List < CssSelector > ;
361369 cbContext ; // callback context
362370 listContext : SelectorListContext ;
363371
364372 constructor ( selector : CssSelector , cbContext : any , listContext : SelectorListContext ) {
365373 this . selector = selector ;
366- this . notSelector = selector . notSelector ;
374+ this . notSelectors = selector . notSelectors ;
367375 this . cbContext = cbContext ;
368376 this . listContext = listContext ;
369377 }
370378
371379 finalize ( cssSelector : CssSelector , callback /*: (CssSelector, any) => void*/ ) {
372380 var result = true ;
373- if ( isPresent ( this . notSelector ) &&
381+ if ( this . notSelectors . length > 0 &&
374382 ( isBlank ( this . listContext ) || ! this . listContext . alreadyMatched ) ) {
375- var notMatcher = SelectorMatcher . createNotMatcher ( this . notSelector ) ;
383+ var notMatcher = SelectorMatcher . createNotMatcher ( this . notSelectors ) ;
376384 result = ! notMatcher . match ( cssSelector , null ) ;
377385 }
378386 if ( result && isPresent ( callback ) &&
0 commit comments