Skip to content

Commit 4870566

Browse files
authored
[BUGFIX] Include comments for all rules in declaration block (#1182)
This is the v8.x backport of #1169. - `Rule::parse()` will no longer consume anything after the semicolon terminating the rule - it does not belong to that rule; - The whitespace and comments before a rule will be processed by `RuleSet::parseRuleSet()` and passed as a parameter to `Rule::parse()` - - This is only required while 'strict mode' parsing is an option, to avoid having an exception thrown during normal operation (i.e. when `Rule::parse()` encounters normal `}` as opposed to some other junk, which is not distinguished). Fixes #173. See also #663, #672, #741.
1 parent 78f1860 commit 4870566

File tree

4 files changed

+50
-9
lines changed

4 files changed

+50
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
3333

3434
### Fixed
3535

36+
- Include comments for all rules in declaration block (#1169)
3637
- Render rules in line and column number order (#1059)
3738
- Create `Size` with correct types in `expandBackgroundShorthand` (#814)
3839
- Parse `@font-face` `src` property as comma-delimited list (#794)

src/Rule/Rule.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,16 +75,18 @@ public function __construct($sRule, $iLineNo = 0, $iColNo = 0)
7575
}
7676

7777
/**
78+
* @param array<int, Comment> $commentsBeforeRule
79+
*
7880
* @return Rule
7981
*
8082
* @throws UnexpectedEOFException
8183
* @throws UnexpectedTokenException
8284
*
8385
* @internal since V8.8.0
8486
*/
85-
public static function parse(ParserState $oParserState)
87+
public static function parse(ParserState $oParserState, $commentsBeforeRule = [])
8688
{
87-
$aComments = $oParserState->consumeWhiteSpace();
89+
$aComments = \array_merge($commentsBeforeRule, $oParserState->consumeWhiteSpace());
8890
$oRule = new Rule(
8991
$oParserState->parseIdentifier(!$oParserState->comes("--")),
9092
$oParserState->currentLine(),
@@ -114,8 +116,6 @@ public static function parse(ParserState $oParserState)
114116
$oParserState->consume(';');
115117
}
116118

117-
$oParserState->consumeWhiteSpace();
118-
119119
return $oRule;
120120
}
121121

src/RuleSet/RuleSet.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,15 @@ public static function parseRuleSet(ParserState $oParserState, RuleSet $oRuleSet
6767
while ($oParserState->comes(';')) {
6868
$oParserState->consume(';');
6969
}
70-
while (!$oParserState->comes('}')) {
70+
while (true) {
71+
$commentsBeforeRule = $oParserState->consumeWhiteSpace();
72+
if ($oParserState->comes('}')) {
73+
break;
74+
}
7175
$oRule = null;
7276
if ($oParserState->getSettings()->bLenientParsing) {
7377
try {
74-
$oRule = Rule::parse($oParserState);
78+
$oRule = Rule::parse($oParserState, $commentsBeforeRule);
7579
} catch (UnexpectedTokenException $e) {
7680
try {
7781
$sConsume = $oParserState->consumeUntil(["\n", ";", '}'], true);
@@ -89,7 +93,7 @@ public static function parseRuleSet(ParserState $oParserState, RuleSet $oRuleSet
8993
}
9094
}
9195
} else {
92-
$oRule = Rule::parse($oParserState);
96+
$oRule = Rule::parse($oParserState, $commentsBeforeRule);
9397
}
9498
if ($oRule) {
9599
$oRuleSet->addRule($oRule);

tests/ParserTest.php

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,26 +1167,62 @@ public function flatCommentExtractingOneComment()
11671167
{
11681168
$parser = new Parser('div {/*Find Me!*/left:10px; text-align:left;}');
11691169
$doc = $parser->parse();
1170+
11701171
$contents = $doc->getContents();
11711172
$divRules = $contents[0]->getRules();
11721173
$comments = $divRules[0]->getComments();
1174+
11731175
self::assertCount(1, $comments);
11741176
self::assertSame("Find Me!", $comments[0]->getComment());
11751177
}
11761178

11771179
/**
11781180
* @test
11791181
*/
1180-
public function flatCommentExtractingTwoComments()
1182+
public function flatCommentExtractingTwoConjoinedCommentsForOneRule()
11811183
{
1182-
self::markTestSkipped('This is currently broken.');
1184+
$parser = new Parser('div {/*Find Me!*//*Find Me Too!*/left:10px; text-align:left;}');
1185+
$document = $parser->parse();
11831186

1187+
$contents = $document->getContents();
1188+
$divRules = $contents[0]->getRules();
1189+
$comments = $divRules[0]->getComments();
1190+
1191+
self::assertCount(2, $comments);
1192+
self::assertSame('Find Me!', $comments[0]->getComment());
1193+
self::assertSame('Find Me Too!', $comments[1]->getComment());
1194+
}
1195+
1196+
/**
1197+
* @test
1198+
*/
1199+
public function flatCommentExtractingTwoSpaceSeparatedCommentsForOneRule()
1200+
{
1201+
$parser = new Parser('div { /*Find Me!*/ /*Find Me Too!*/ left:10px; text-align:left;}');
1202+
$document = $parser->parse();
1203+
1204+
$contents = $document->getContents();
1205+
$divRules = $contents[0]->getRules();
1206+
$comments = $divRules[0]->getComments();
1207+
1208+
self::assertCount(2, $comments);
1209+
self::assertSame('Find Me!', $comments[0]->getComment());
1210+
self::assertSame('Find Me Too!', $comments[1]->getComment());
1211+
}
1212+
1213+
/**
1214+
* @test
1215+
*/
1216+
public function flatCommentExtractingCommentsForTwoRules()
1217+
{
11841218
$parser = new Parser('div {/*Find Me!*/left:10px; /*Find Me Too!*/text-align:left;}');
11851219
$doc = $parser->parse();
1220+
11861221
$contents = $doc->getContents();
11871222
$divRules = $contents[0]->getRules();
11881223
$rule1Comments = $divRules[0]->getComments();
11891224
$rule2Comments = $divRules[1]->getComments();
1225+
11901226
self::assertCount(1, $rule1Comments);
11911227
self::assertCount(1, $rule2Comments);
11921228
self::assertEquals('Find Me!', $rule1Comments[0]->getComment());

0 commit comments

Comments
 (0)