@@ -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 );
@@ -103,7 +103,7 @@ public function setSelectors($selectors, ?CSSList $list = null): void
103103 // Parse as if it's the opening part of a rule.
104104 try {
105105 $ parserState = new ParserState ($ selectors . '{ ' , Settings::create ());
106- $ selectorsToSet = self ::parseSelectors ($ parserState );
106+ $ selectorsToSet = self ::parseSelectors ($ parserState, $ list );
107107 $ parserState ->consume ('{ ' ); // throw exception if this is not next
108108 if (!$ parserState ->isEnd ()) {
109109 throw new UnexpectedTokenException ('EOF ' , 'more ' );
@@ -286,94 +286,22 @@ public function getArrayRepresentation(): array
286286 /**
287287 * @param list<Comment> $comments
288288 *
289- * @return list<string >
289+ * @return list<Selector >
290290 *
291291 * @throws UnexpectedTokenException
292292 */
293- private static function parseSelectors (ParserState $ parserState , array &$ comments = []): array
293+ private static function parseSelectors (ParserState $ parserState , ? CSSList $ list , array &$ comments = []): array
294294 {
295+ $ selectorClass = $ list instanceof KeyFrame ? KeyFrameSelector::class : Selector::class;
295296 $ selectors = [];
296297
297298 while (true ) {
298- $ selectors [] = self :: parseSelector ($ parserState , $ comments );
299+ $ selectors [] = $ selectorClass :: parse ($ parserState , $ comments );
299300 if (!$ parserState ->consumeIfComes (', ' )) {
300301 break ;
301302 }
302303 }
303304
304305 return $ selectors ;
305306 }
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- }
379307}
0 commit comments