Skip to content

Commit d0a3dfa

Browse files
committed
css: allow escaped first char in identifier name
1 parent 29671ac commit d0a3dfa

File tree

1 file changed

+34
-1
lines changed

1 file changed

+34
-1
lines changed

src/browser/css/parser.zig

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ pub const Parser = struct {
204204
}
205205

206206
const c = p.s[p.i];
207-
if (!nameStart(c) or c == '\\') {
207+
if (!nameStart(c) and c != '\\') {
208208
return ParseError.ExpectedSelector;
209209
}
210210

@@ -949,3 +949,36 @@ test "parser.parseString" {
949949
};
950950
}
951951
}
952+
953+
test "parser.parse" {
954+
var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
955+
defer arena.deinit();
956+
const alloc = arena.allocator();
957+
958+
const testcases = [_]struct {
959+
s: []const u8, // given value
960+
exp: Selector, // expected value
961+
err: bool = false,
962+
}{
963+
.{ .s = "root", .exp = .{ .tag = "root" } },
964+
.{ .s = ".root", .exp = .{ .class = "root" } },
965+
.{ .s = ":root", .exp = .{ .pseudo_class = .root } },
966+
.{ .s = ".\\:bar", .exp = .{ .class = ":bar" } },
967+
.{ .s = ".foo\\:bar", .exp = .{ .class = "foo:bar" } },
968+
};
969+
970+
for (testcases) |tc| {
971+
var p = Parser{ .s = tc.s, .opts = .{} };
972+
const sel = p.parse(alloc) catch |e| {
973+
// if error was expected, continue.
974+
if (tc.err) continue;
975+
976+
std.debug.print("test case {s}\n", .{tc.s});
977+
return e;
978+
};
979+
std.testing.expectEqualDeep(tc.exp, sel) catch |e| {
980+
std.debug.print("test case {s} : {}\n", .{ tc.s, sel });
981+
return e;
982+
};
983+
}
984+
}

0 commit comments

Comments
 (0)