diff --git a/src/browser/Frame.zig b/src/browser/Frame.zig index 1ff57df9d..a4cdb1845 100644 --- a/src/browser/Frame.zig +++ b/src/browser/Frame.zig @@ -2965,6 +2965,7 @@ pub fn attributeChange(self: *Frame, element: *Element, name: String, value: Str const old = if (old_value) |o| o.str() else null; popover.attributeChanged(element, old, value.str(), self); } else if (name.eql(comptime .wrap("style"))) { + element._flags.has_inline_style = true; self.styleAttributeChanged(element, value.str()); } } @@ -2993,7 +2994,7 @@ pub fn attributeRemove(self: *Frame, element: *Element, name: String, old_value: } fn styleAttributeChanged(self: *Frame, element: *Element, value: ?[]const u8) void { - const style = self._element_styles.get(element) orelse return; + const style = element.getStyle(self) orelse return; style.asCSSStyleDeclaration().styleAttributeChanged(value, self) catch |err| { log.err(.frame, "style attribute reparse", .{ .err = err, .type = self._type, .url = self.url }); }; diff --git a/src/browser/StyleManager.zig b/src/browser/StyleManager.zig index 6dc83ead9..8f2791751 100644 --- a/src/browser/StyleManager.zig +++ b/src/browser/StyleManager.zig @@ -1194,7 +1194,11 @@ 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: { + if (!el._flags.has_inline_style) { + // Neither a style object nor a style attribute; skip both lookups. + return null; + } + const style = el.getStyle(frame) orelse blk: { // No JS-set style object and no style attribute -> nothing inline to read. if (el.getAttributeSafe(comptime .wrap("style")) == null) return null; break :blk el.getOrCreateStyle(frame) catch |err| { diff --git a/src/browser/frame/node_factory.zig b/src/browser/frame/node_factory.zig index 6de08a90d..042d05ea3 100644 --- a/src/browser/frame/node_factory.zig +++ b/src/browser/frame/node_factory.zig @@ -1073,7 +1073,9 @@ fn initSvgElement(frame: *Frame, element: *Element, attribute_iterator: anytype) fn populateElementAttributes(frame: *Frame, element: *Element, list: anytype) !void { if (@TypeOf(list) == *Element.Attribute.List or @TypeOf(list) == *const Element.Attribute.List) { // from cloneNode - return element._attributes.cloneFrom(list, frame); + try element._attributes.cloneFrom(list, frame); + element.noteStyleAttribute(); + return; } // from the parser @@ -1090,6 +1092,7 @@ fn populateElementAttributes(frame: *Frame, element: *Element, list: anytype) !v const name = try parserAttributeName(frame, attr.name); try attributes.putNew(name, attr.value.slice(), frame); } + element.noteStyleAttribute(); } // Attributes are keyed by qualified name (no namespace model), so a prefixed diff --git a/src/browser/frame/observers.zig b/src/browser/frame/observers.zig index 60ada05ef..34126fb76 100644 --- a/src/browser/frame/observers.zig +++ b/src/browser/frame/observers.zig @@ -212,7 +212,7 @@ pub fn performScheduledResizeChecks(frame: *Frame) void { } // Only these attributes can change an element's size or visibility in our -// styling model (StyleManager.isHidden + Element.getElementDimensions), and +// styling model (StyleManager.isHidden + Element.getElementAxis), and // only for the element itself and its descendants — so a delivery is only // scheduled when an observed element is in the changed element's subtree. fn resizeAttributeChanged(frame: *Frame, element: *Element, name: String) void { diff --git a/src/browser/parser/Parser.zig b/src/browser/parser/Parser.zig index 903636adb..53020a8a9 100644 --- a/src/browser/parser/Parser.zig +++ b/src/browser/parser/Parser.zig @@ -617,6 +617,7 @@ fn _addAttrsIfMissingCallback(self: *Parser, node: *Node, attributes: h5e.Attrib // putNew only adds if the attribute doesn't already exist try attr_list.putNew(name, value, frame); } + element.noteStyleAttribute(); } fn getTemplateContentsCallback(ctx: *anyopaque, target_ref: *anyopaque) callconv(.c) ?*anyopaque { diff --git a/src/browser/tests/element/position.html b/src/browser/tests/element/position.html index 2d653d46c..6147cb0b4 100644 --- a/src/browser/tests/element/position.html +++ b/src/browser/tests/element/position.html @@ -168,6 +168,83 @@ } + + + +