@@ -67,7 +67,7 @@ public static function parse(ParserState $parserState, ?CSSList $list = null): ?
6767 $ comments = [];
6868 $ result = new DeclarationBlock ($ parserState ->currentLine ());
6969 try {
70- $ selectors = self ::parseSelectors ($ parserState , $ comments );
70+ $ selectors = self ::parseSelectors ($ parserState , $ list , $ comments );
7171 $ result ->setSelectors ($ selectors , $ list );
7272 if ($ parserState ->comes ('{ ' )) {
7373 $ parserState ->consume (1 );
@@ -100,11 +100,9 @@ public function setSelectors($selectors, ?CSSList $list = null): void
100100 $ selectorsToSet = $ selectors ;
101101 } else {
102102 // A string of comma-separated selectors requires parsing.
103- // Parse as if it's the opening part of a rule.
104103 try {
105- $ parserState = new ParserState ($ selectors . '{ ' , Settings::create ());
106- $ selectorsToSet = self ::parseSelectors ($ parserState );
107- $ parserState ->consume ('{ ' ); // throw exception if this is not next
104+ $ parserState = new ParserState ($ selectors , Settings::create ());
105+ $ selectorsToSet = self ::parseSelectors ($ parserState , $ list );
108106 if (!$ parserState ->isEnd ()) {
109107 throw new UnexpectedTokenException ('EOF ' , 'more ' );
110108 }
@@ -286,94 +284,22 @@ public function getArrayRepresentation(): array
286284 /**
287285 * @param list<Comment> $comments
288286 *
289- * @return list<string >
287+ * @return list<Selector >
290288 *
291289 * @throws UnexpectedTokenException
292290 */
293- private static function parseSelectors (ParserState $ parserState , array &$ comments = []): array
291+ private static function parseSelectors (ParserState $ parserState , ? CSSList $ list , array &$ comments = []): array
294292 {
293+ $ selectorClass = $ list instanceof KeyFrame ? KeyFrameSelector::class : Selector::class;
295294 $ selectors = [];
296295
297296 while (true ) {
298- $ selectors [] = self :: parseSelector ($ parserState , $ comments );
297+ $ selectors [] = $ selectorClass :: parse ($ parserState , $ comments );
299298 if (!$ parserState ->consumeIfComes (', ' )) {
300299 break ;
301300 }
302301 }
303302
304303 return $ selectors ;
305304 }
306-
307- /**
308- * @param list<Comment> $comments
309- *
310- * @throws UnexpectedTokenException
311- */
312- private static function parseSelector (ParserState $ parserState , array &$ comments = []): string
313- {
314- $ selectorParts = [];
315- $ stringWrapperCharacter = null ;
316- $ functionNestingLevel = 0 ;
317- static $ stopCharacters = ['{ ' , '} ' , '\'' , '" ' , '( ' , ') ' , ', ' ];
318-
319- while (true ) {
320- $ selectorParts [] = $ parserState ->consumeUntil ($ stopCharacters , false , false , $ comments );
321- $ nextCharacter = $ parserState ->peek ();
322- switch ($ nextCharacter ) {
323- case '\'' :
324- // The fallthrough is intentional.
325- case '" ' :
326- if (!\is_string ($ stringWrapperCharacter )) {
327- $ stringWrapperCharacter = $ nextCharacter ;
328- } elseif ($ stringWrapperCharacter === $ nextCharacter ) {
329- if (\substr (\end ($ selectorParts ), -1 ) !== '\\' ) {
330- $ stringWrapperCharacter = null ;
331- }
332- }
333- break ;
334- case '( ' :
335- if (!\is_string ($ stringWrapperCharacter )) {
336- ++$ functionNestingLevel ;
337- }
338- break ;
339- case ') ' :
340- if (!\is_string ($ stringWrapperCharacter )) {
341- if ($ functionNestingLevel <= 0 ) {
342- throw new UnexpectedTokenException (
343- 'anything but ' ,
344- ') ' ,
345- 'literal ' ,
346- $ parserState ->currentLine ()
347- );
348- }
349- --$ functionNestingLevel ;
350- }
351- break ;
352- case '{ ' :
353- // The fallthrough is intentional.
354- case '} ' :
355- if (!\is_string ($ stringWrapperCharacter )) {
356- break 2 ;
357- }
358- break ;
359- case ', ' :
360- if (!\is_string ($ stringWrapperCharacter ) && $ functionNestingLevel === 0 ) {
361- break 2 ;
362- }
363- break ;
364- }
365- $ selectorParts [] = $ parserState ->consume (1 );
366- }
367-
368- if ($ functionNestingLevel !== 0 ) {
369- throw new UnexpectedTokenException (') ' , $ nextCharacter , 'literal ' , $ parserState ->currentLine ());
370- }
371-
372- $ selector = \trim (\implode ('' , $ selectorParts ));
373- if ($ selector === '' ) {
374- throw new UnexpectedTokenException ('selector ' , $ nextCharacter , 'literal ' , $ parserState ->currentLine ());
375- }
376-
377- return $ selector ;
378- }
379305}
0 commit comments