diff --git a/src/browser/Frame.zig b/src/browser/Frame.zig index 45555932e..1ff57df9d 100644 --- a/src/browser/Frame.zig +++ b/src/browser/Frame.zig @@ -2964,6 +2964,8 @@ pub fn attributeChange(self: *Frame, element: *Element, name: String, value: Str } else if (name.eql(comptime .wrap("popover"))) { const old = if (old_value) |o| o.str() else null; popover.attributeChanged(element, old, value.str(), self); + } else if (name.eql(comptime .wrap("style"))) { + self.styleAttributeChanged(element, value.str()); } } @@ -2985,9 +2987,18 @@ pub fn attributeRemove(self: *Frame, element: *Element, name: String, old_value: } } else if (name.eql(comptime .wrap("popover"))) { popover.attributeChanged(element, old_value.str(), null, self); + } else if (name.eql(comptime .wrap("style"))) { + self.styleAttributeChanged(element, null); } } +fn styleAttributeChanged(self: *Frame, element: *Element, value: ?[]const u8) void { + const style = self._element_styles.get(element) orelse return; + style.asCSSStyleDeclaration().styleAttributeChanged(value, self) catch |err| { + log.err(.frame, "style attribute reparse", .{ .err = err, .type = self._type, .url = self.url }); + }; +} + pub fn signalSlotChange(self: *Frame, slot: *Element.Html.Slot) void { self._slots_pending_slotchange.put(self.arena, slot, {}) catch |err| { log.err(.frame, "signalSlotChange.put", .{ .err = err, .type = self._type, .url = self.url }); diff --git a/src/browser/StyleManager.zig b/src/browser/StyleManager.zig index b054de4f3..6dc83ead9 100644 --- a/src/browser/StyleManager.zig +++ b/src/browser/StyleManager.zig @@ -1191,6 +1191,8 @@ const CheckVisibilityOptions = struct { // its field max, so a real rule can never pack to all-ones. const INLINE_PRIORITY: u64 = std.math.maxInt(u64); +// `frame` is the StyleManager's frame, which callers guarantee is el's owner +// frame (el.ownerFrame) — the map where the materialized style lives. fn getInlineStyleProperty(el: *Element, property_name: String, frame: *Frame) ?*CSSStyleProperty { const style = frame._element_styles.get(el) orelse blk: { // No JS-set style object and no style attribute -> nothing inline to read. diff --git a/src/browser/tests/element/css_style_properties.html b/src/browser/tests/element/css_style_properties.html index 3592df67e..61cb8e945 100644 --- a/src/browser/tests/element/css_style_properties.html +++ b/src/browser/tests/element/css_style_properties.html @@ -191,3 +191,32 @@ testing.expectEqual('0.5em 0.25em', div.style.margin); } + + diff --git a/src/browser/tests/frames/cross_realm_attributes.html b/src/browser/tests/frames/cross_realm_attributes.html index d06e5d45f..ac38acf20 100644 --- a/src/browser/tests/frames/cross_realm_attributes.html +++ b/src/browser/tests/frames/cross_realm_attributes.html @@ -80,4 +80,47 @@ reads of iframe data-* returned null (WPT encoding/*). }); } + + diff --git a/src/browser/tests/frames/support/cross_realm_attributes.html b/src/browser/tests/frames/support/cross_realm_attributes.html index 756e5c0d4..0629b8766 100644 --- a/src/browser/tests/frames/support/cross_realm_attributes.html +++ b/src/browser/tests/frames/support/cross_realm_attributes.html @@ -1,4 +1,5 @@ + x