Skip to content

Commit 0425f1e

Browse files
committed
[BUGFIX] Allow comma-separated arguments in selectors
Fixes #138. Fixes #360. Fixes #1289.
1 parent 931c406 commit 0425f1e

File tree

4 files changed

+23
-2
lines changed

4 files changed

+23
-2
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ Please also have a look at our
110110

111111
### Fixed
112112

113+
- Selector functions (like `:not`) with comma-separated arguments are now
114+
parsed correclty (#1292)
113115
- Parse quoted attribute selector value containing comma (#1323)
114116
- Allow comma in selectors (e.g. `:not(html, body)`) (#1293)
115117
- Insert `Rule` before sibling even with different property name

src/Parsing/ParserState.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,10 @@ public function consumeUntil(
345345
$start = $this->currentPosition;
346346

347347
while (!$this->isEnd()) {
348+
$comment = $this->consumeComment();
349+
if ($comment instanceof Comment) {
350+
$comments[] = $comment;
351+
}
348352
$character = $this->consume(1);
349353
if (\in_array($character, $stopCharacters, true)) {
350354
if ($includeEnd) {

src/RuleSet/DeclarationBlock.php

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,9 @@ public static function parse(ParserState $parserState, ?CSSList $list = null): ?
4343
$selectors = [];
4444
$selectorParts = [];
4545
$stringWrapperCharacter = null;
46+
$functionNestingLevel = 0;
4647
$consumedNextCharacter = false;
47-
static $stopCharacters = ['{', '}', '\'', '"', ','];
48+
static $stopCharacters = ['{', '}', '\'', '"', '(', ')', ','];
4849
do {
4950
if (!$consumedNextCharacter) {
5051
$selectorParts[] = $parserState->consume(1);
@@ -64,8 +65,21 @@ public static function parse(ParserState $parserState, ?CSSList $list = null): ?
6465
}
6566
}
6667
break;
67-
case ',':
68+
case '(':
69+
if (!\is_string($stringWrapperCharacter)) {
70+
++$functionNestingLevel;
71+
}
72+
break;
73+
case ')':
6874
if (!\is_string($stringWrapperCharacter)) {
75+
if ($functionNestingLevel <= 0) {
76+
throw new UnexpectedTokenException('anything but', ')');
77+
}
78+
--$functionNestingLevel;
79+
}
80+
break;
81+
case ',':
82+
if (!\is_string($stringWrapperCharacter) && $functionNestingLevel === 0) {
6983
$selectors[] = \implode('', $selectorParts);
7084
$selectorParts = [];
7185
$parserState->consume(1);

tests/Unit/RuleSet/DeclarationBlockTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ public static function provideSelector(): array
6767
'pseudo-class' => [':hover'],
6868
'type & pseudo-class' => ['a:hover'],
6969
'`not`' => [':not(#your-mug)'],
70+
'`not` with multiple arguments' => [':not(#your-mug, .their-mug)'],
7071
'pseudo-element' => ['::before'],
7172
'attribute with `"`' => ['[alt="{}()[]\\"\',"]'],
7273
'attribute with `\'`' => ['[alt=\'{}()[]"\\\',\']'],

0 commit comments

Comments
 (0)