diff --git a/src/browser/tests/css.html b/src/browser/tests/css.html
index ac0b6aba..ee0db0e0 100644
--- a/src/browser/tests/css.html
+++ b/src/browser/tests/css.html
@@ -20,8 +20,10 @@
{
testing.expectEqual('\\30 abc', CSS.escape('0abc'));
testing.expectEqual('\\31 23', CSS.escape('123'));
- testing.expectEqual('\\-test', CSS.escape('-test'));
- testing.expectEqual('\\--test', CSS.escape('--test'));
+ testing.expectEqual('\\-', CSS.escape('-'));
+ testing.expectEqual('-test', CSS.escape('-test'));
+ testing.expectEqual('--test', CSS.escape('--test'));
+ testing.expectEqual('-\\33 ', CSS.escape('-3'));
}
diff --git a/src/browser/webapi/CSS.zig b/src/browser/webapi/CSS.zig
index a2f320f7..2eed5cf3 100644
--- a/src/browser/webapi/CSS.zig
+++ b/src/browser/webapi/CSS.zig
@@ -42,15 +42,23 @@ pub fn parseDimension(value: []const u8) ?f64 {
/// https://drafts.csswg.org/cssom/#the-css.escape()-method
pub fn escape(_: *const CSS, value: []const u8, page: *Page) ![]const u8 {
if (value.len == 0) {
- return error.InvalidCharacterError;
+ return "";
}
const first = value[0];
+ if (first == '-' and value.len == 1) {
+ return "\\-";
+ }
// Count how many characters we need for the output
var out_len: usize = escapeLen(true, first);
- for (value[1..]) |c| {
- out_len += escapeLen(false, c);
+ for (value[1..], 0..) |c, i| {
+ // Second char (i==0) is a digit and first is '-', needs hex escape
+ if (i == 0 and first == '-' and c >= '0' and c <= '9') {
+ out_len += 2 + hexDigitsNeeded(c);
+ } else {
+ out_len += escapeLen(false, c);
+ }
}
if (out_len == value.len) {
@@ -67,8 +75,13 @@ pub fn escape(_: *const CSS, value: []const u8, page: *Page) ![]const u8 {
pos = 1;
}
- for (value[1..]) |c| {
- if (!needsEscape(false, c)) {
+ for (value[1..], 0..) |c, i| {
+ // Second char (i==0) is a digit and first is '-', needs hex escape
+ if (i == 0 and first == '-' and c >= '0' and c <= '9') {
+ result[pos] = '\\';
+ const hex_str = std.fmt.bufPrint(result[pos + 1 ..], "{x} ", .{c}) catch unreachable;
+ pos += 1 + hex_str.len;
+ } else if (!needsEscape(false, c)) {
result[pos] = c;
pos += 1;
} else {
@@ -105,9 +118,6 @@ fn needsEscape(comptime is_first: bool, c: u8) bool {
if (c >= '0' and c <= '9') {
return true;
}
- if (c == '-') {
- return true;
- }
}
// Characters that need escaping