@@ -40,19 +40,48 @@ public static function parse(ParserState $parserState, ?CSSList $list = null): ?
4040 $ comments = [];
4141 $ result = new DeclarationBlock ($ parserState ->currentLine ());
4242 try {
43+ $ selectors = [];
4344 $ selectorParts = [];
45+ $ functionNestingLevel = 0 ;
4446 do {
4547 $ selectorParts [] = $ parserState ->consume (1 )
46- . $ parserState ->consumeUntil (['{ ' , '} ' , '\'' , '" ' ], false , false , $ comments );
47- if (\in_array ($ parserState ->peek (), ['\'' , '" ' ], true ) && \substr (\end ($ selectorParts ), -1 ) != '\\' ) {
48- if (!isset ($ stringWrapperCharacter )) {
49- $ stringWrapperCharacter = $ parserState ->peek ();
50- } elseif ($ stringWrapperCharacter === $ parserState ->peek ()) {
51- unset($ stringWrapperCharacter );
52- }
48+ . $ parserState ->consumeUntil (['{ ' , '} ' , '\'' , '" ' , '( ' , ') ' , ', ' ], false , false , $ comments );
49+ $ nextCharacter = $ parserState ->peek ();
50+ switch ($ nextCharacter ) {
51+ case '\'' :
52+ case '" ' :
53+ if (!isset ($ stringWrapperCharacter )) {
54+ $ stringWrapperCharacter = $ nextCharacter ;
55+ } elseif ($ stringWrapperCharacter === $ nextCharacter ) {
56+ if (\substr (\end ($ selectorParts ), -1 ) !== '\\' ) {
57+ unset($ stringWrapperCharacter );
58+ }
59+ }
60+ break ;
61+ case '( ' :
62+ if (!isset ($ stringWrapperCharacter )) {
63+ ++$ functionNestingLevel ;
64+ }
65+ break ;
66+ case ') ' :
67+ if (!isset ($ stringWrapperCharacter )) {
68+ if ($ functionNestingLevel <= 0 ) {
69+ throw new UnexpectedTokenException ('anything but ' , ') ' );
70+ }
71+ --$ functionNestingLevel ;
72+ }
73+ break ;
74+ case ', ' :
75+ if (!isset ($ stringWrapperCharacter ) && $ functionNestingLevel === 0 ) {
76+ $ selectors [] = \implode ('' , $ selectorParts );
77+ $ selectorParts = [];
78+ $ parserState ->consume (1 );
79+ }
80+ break ;
5381 }
54- } while (!\in_array ($ parserState ->peek (), ['{ ' , '} ' ], true ) || isset ($ stringWrapperCharacter ));
55- $ result ->setSelectors (\implode ('' , $ selectorParts ), $ list );
82+ } while (!\in_array ($ nextCharacter , ['{ ' , '} ' ], true ) || isset ($ stringWrapperCharacter ));
83+ $ selectors [] = \implode ('' , $ selectorParts ); // add final or only selector
84+ $ result ->setSelectors ($ selectors , $ list );
5685 if ($ parserState ->comes ('{ ' )) {
5786 $ parserState ->consume (1 );
5887 }
@@ -89,7 +118,7 @@ public function setSelectors($selectors, ?CSSList $list = null): void
89118 if (!Selector::isValid ($ selector )) {
90119 throw new UnexpectedTokenException (
91120 "Selector did not match ' " . Selector::SELECTOR_VALIDATION_RX . "'. " ,
92- $ selectors ,
121+ $ selector ,
93122 'custom '
94123 );
95124 }
0 commit comments