Skip to content

Commit 66a8654

Browse files
committed
css: handle top-level semicolons in parser
1 parent bc19079 commit 66a8654

File tree

2 files changed

+27
-6
lines changed

2 files changed

+27
-6
lines changed

src/browser/css/Parser.zig

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -318,12 +318,6 @@ pub const RulesIterator = struct {
318318
var selector_start: ?usize = null;
319319
var selector_end: ?usize = null;
320320

321-
// Skip leading trivia
322-
while (self.stream.peek()) |peeked| {
323-
if (!isWhitespaceOrComment(peeked.token)) break;
324-
_ = self.stream.next();
325-
}
326-
327321
while (true) {
328322
const peeked = self.stream.peek() orelse return null;
329323

@@ -370,6 +364,11 @@ pub const RulesIterator = struct {
370364
continue;
371365
}
372366

367+
if (selector_start == null and (isWhitespaceOrComment(peeked.token) or isSemicolon(peeked.token))) {
368+
_ = self.stream.next();
369+
continue;
370+
}
371+
373372
const span = self.stream.next() orelse return null;
374373
if (!isWhitespaceOrComment(span.token)) {
375374
if (selector_start == null) selector_start = span.start;
@@ -470,3 +469,13 @@ test "RulesIterator: comments and whitespace" {
470469
try testing.expectEqualStrings(" /* comment */ color: red; ", rule.block);
471470
try testing.expectEqual(@as(?Rule, null), it.next());
472471
}
472+
473+
test "RulesIterator: top-level semicolons" {
474+
var it = RulesIterator.init("*{}; ; p{}");
475+
var rule = it.next() orelse return error.MissingRule;
476+
try testing.expectEqualStrings("*", rule.selector);
477+
478+
rule = it.next() orelse return error.MissingRule;
479+
try testing.expectEqualStrings("p", rule.selector);
480+
try testing.expectEqual(@as(?Rule, null), it.next());
481+
}

src/browser/tests/css/stylesheet.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,18 @@
468468
}
469469
</script>
470470

471+
<script id="CSSStyleSheet_insertRule_semicolon">
472+
{
473+
const style = document.createElement('style');
474+
document.head.appendChild(style);
475+
const sheet = style.sheet;
476+
477+
// Should not throw even with trailing semicolon
478+
sheet.insertRule('*{};');
479+
testing.expectEqual(1, sheet.cssRules.length);
480+
}
481+
</script>
482+
471483
<script id="CSSStyleSheet_replaceSync">
472484
{
473485
const sheet = new CSSStyleSheet();

0 commit comments

Comments
 (0)