diff --git a/src/RuleSet/RuleSet.php b/src/RuleSet/RuleSet.php index 9bf080b6..39a889c9 100644 --- a/src/RuleSet/RuleSet.php +++ b/src/RuleSet/RuleSet.php @@ -63,9 +63,11 @@ public static function parseRuleSet(ParserState $oParserState, RuleSet $oRuleSet $oRule = Rule::parse($oParserState); } catch (UnexpectedTokenException $e) { try { - $sConsume = $oParserState->consumeUntil(["\n", ';', '}'], true); + $sConsume = $oParserState->consumeUntil(["\n", ';', '{', '}'], true); // We need to “unfind” the matches to the end of the ruleSet as this will be matched later - if ($oParserState->streql(\substr($sConsume, -1), '}')) { + if ($oParserState->streql(\substr($sConsume, -1), '{')) { // We need to skip the entire block + $oParserState->consumeUntil('}', true); + } elseif ($oParserState->streql(\substr($sConsume, -1), '}')) { $oParserState->backtrack(1); } else { while ($oParserState->comes(';')) { diff --git a/tests/ParserTest.php b/tests/ParserTest.php index 2c1c7287..37481fd7 100644 --- a/tests/ParserTest.php +++ b/tests/ParserTest.php @@ -809,6 +809,19 @@ public function selectorEscapesInFile(): void self::assertSame($sExpected, $oDoc->render()); } + /** + * @test + */ + public function invalidRulesInFile(): void + { + $oDoc = $this->parsedStructureForFile('invalid-rule', Settings::create()->withMultibyteSupport(true)); + $sExpected = 'fusion-max-sh-shbp {} +@media only screen and (max-width: 800px) {.has-sidebar #content {order: 1;} + .has-sidebar #sidebar {order: 2;margin-top: 50px;} + .has-sidebar #sidebar-2 {order: 3;margin-top: 50px;}}'; + self::assertSame($sExpected, $oDoc->render()); + } + /** * @test */ diff --git a/tests/fixtures/invalid-rule.css b/tests/fixtures/invalid-rule.css new file mode 100644 index 00000000..bec2b65c --- /dev/null +++ b/tests/fixtures/invalid-rule.css @@ -0,0 +1,21 @@ + fusion-max-sh-shbp { + .fusion-mobile-nav-holder .wpml-ls-item .menu-text,.fusion-mobile-nav-holder .wpml-ls-item > a,.wpml-ls-item .menu-text, .wpml-ls-item .sub-menu a > span { + justify-content: flex-start; + } + } + + @media only screen and (max-width: 800px) { + .has-sidebar #content { + order:1; + } + + .has-sidebar #sidebar { + order: 2; + margin-top: 50px; + } + + .has-sidebar #sidebar-2 { + order: 3; + margin-top: 50px; + } + }