From ee015da56c4818f57d9d4fdfe736b7b4163fe4c0 Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Tue, 15 Sep 2026 09:56:25 +0800 Subject: [PATCH] webapi: computedStyle are now readonly getComputedStyle returns a CSSStyleDeclaration that should be readonly. We now return a NoModificationAllowed on write. Fixes exactly 1 WPT case =) --- src/browser/tests/element/styles.html | 20 +++++++++++++++++++ .../webapi/css/CSSStyleDeclaration.zig | 19 ++++++++++++++++++ src/browser/webapi/css/CSSStyleSheet.zig | 4 ++-- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/browser/tests/element/styles.html b/src/browser/tests/element/styles.html index 740a06dc3..e178c17a9 100644 --- a/src/browser/tests/element/styles.html +++ b/src/browser/tests/element/styles.html @@ -244,3 +244,23 @@ testing.expectEqual('red', impDiv.style.getPropertyValue('color')); } + + diff --git a/src/browser/webapi/css/CSSStyleDeclaration.zig b/src/browser/webapi/css/CSSStyleDeclaration.zig index 887681123..65f04b4d3 100644 --- a/src/browser/webapi/css/CSSStyleDeclaration.zig +++ b/src/browser/webapi/css/CSSStyleDeclaration.zig @@ -153,6 +153,10 @@ pub fn getPropertyPriority(self: *const CSSStyleDeclaration, property_name: []co } pub fn setProperty(self: *CSSStyleDeclaration, property_name: []const u8, value: []const u8, priority_: ?[]const u8, frame: *Frame) !void { + if (self._is_computed) { + return error.NoModificationAllowed; + } + // Validate priority const priority = priority_ orelse ""; const important = if (priority.len > 0) blk: { @@ -218,6 +222,9 @@ fn setPropertyImpl(self: *CSSStyleDeclaration, property_name: []const u8, value: } pub fn removeProperty(self: *CSSStyleDeclaration, property_name: []const u8, frame: *Frame) ![]const u8 { + if (self._is_computed) { + return error.NoModificationAllowed; + } const result = try self.removePropertyImpl(property_name, frame); try self.syncStyleAttribute(frame); return result; @@ -277,6 +284,9 @@ fn getFloat(self: *const CSSStyleDeclaration, frame: *Frame) []const u8 { } fn setFloat(self: *CSSStyleDeclaration, value_: ?[]const u8, frame: *Frame) !void { + if (self._is_computed) { + return error.NoModificationAllowed; + } try self.setPropertyImpl("float", value_ orelse "", false, frame); try self.syncStyleAttribute(frame); } @@ -288,6 +298,15 @@ fn getCssText(self: *const CSSStyleDeclaration, frame: *Frame) ![]const u8 { } pub fn setCssText(self: *CSSStyleDeclaration, text: []const u8, frame: *Frame) !void { + if (self._is_computed) { + return error.NoModificationAllowed; + } + try self.replaceCssText(text, frame); +} + +// setCssText without the read-only check, for declarations that are never +// computed (a CSSStyleRule's style). +pub fn replaceCssText(self: *CSSStyleDeclaration, text: []const u8, frame: *Frame) !void { self.clearProperties(frame); try self.applyDeclarations(text, frame); diff --git a/src/browser/webapi/css/CSSStyleSheet.zig b/src/browser/webapi/css/CSSStyleSheet.zig index f2f1a6062..9cfc76082 100644 --- a/src/browser/webapi/css/CSSStyleSheet.zig +++ b/src/browser/webapi/css/CSSStyleSheet.zig @@ -93,7 +93,7 @@ pub fn insertRule(self: *CSSStyleSheet, rule: []const u8, maybe_index: ?u32, fra const style_props = try style_rule.getStyle(frame); const style = style_props.asCSSStyleDeclaration(); - try style.setCssText(s.block, frame); + try style.replaceCssText(s.block, frame); break :blk style_rule._proto; }, // Opaque placeholder for at-rules. The CSS engine doesn't apply @@ -182,7 +182,7 @@ fn parseInto(self: *CSSStyleSheet, text: []const u8, frame: *Frame) CSSError!voi const style_props = try style_rule.getStyle(frame); const style = style_props.asCSSStyleDeclaration(); - try style.setCssText(s.block, frame); + try style.replaceCssText(s.block, frame); break :blk style_rule._proto; }, .at_rule => |a| try CSSRule.initAtRule(atRuleTypeFor(a.keyword), a.text, frame),