diff --git a/src/browser/StyleManager.zig b/src/browser/StyleManager.zig
index 35e436cc..723a9a51 100644
--- a/src/browser/StyleManager.zig
+++ b/src/browser/StyleManager.zig
@@ -45,6 +45,7 @@ pub const PointerEventsCache = std.AutoHashMapUnmanaged(*Element, bool);
const StyleManager = @This();
const Tag = Element.Tag;
+const Input = Element.Html.Input;
const RuleList = std.MultiArrayList(VisibilityRule);
frame: *Frame,
@@ -241,23 +242,22 @@ pub fn hasDisplayNone(self: *StyleManager, el: *Element) bool {
return self.isElementHidden(el, .{});
}
-/// True if `el` matches a UA-stylesheet display:none rule per HTML Rendering
-/// §15.3.1 "Hidden elements" — covers the `[hidden]` attribute, the unrendered
-/// tag-name list, ``, and the closed-`` non-
-/// `` direct-child rule. Centralized so `getComputedStyle().display`
-/// (via `hasDisplayNone`) and `el.checkVisibility()` (via `isHidden`) share
-/// the same UA-stylesheet truth.
+/// Centralizes UA-stylesheet display:none truth so `getComputedStyle().display`
+/// (via `hasDisplayNone`) and `el.checkVisibility()` (via `isHidden`) agree.
+/// Spec: HTML Rendering §15.3.1 "Hidden elements".
fn matchesUaDisplayNoneRule(el: *Element) bool {
- // [hidden] { display: none } — applies to all elements.
- if (el.hasAttributeSafe(comptime .wrap("hidden"))) return true;
-
+ // Tag check first: O(1) switch, exits for the ~95% of elements with
+ // ordinary tags before we touch the attribute list.
const tag = el.getTag();
if (tag.isHiddenByUaStylesheet()) return true;
+ if (el.hasAttributeSafe(comptime .wrap("hidden"))) return true;
+
// input[type="hidden" i] { display: none !important }
+ // _input_type is parsed case-insensitively at attribute-set time.
if (tag == .input) {
- if (el.getAttributeSafe(comptime .wrap("type"))) |type_val| {
- if (std.ascii.eqlIgnoreCase(type_val, "hidden")) return true;
+ if (el.is(Input)) |input| {
+ if (input._input_type == .hidden) return true;
}
}
@@ -345,14 +345,11 @@ fn isElementHidden(self: *StyleManager, el: *Element, options: CheckVisibilityOp
}
// UA stylesheet display:none rules (HTML Rendering §15.3.1 "Hidden elements").
- // Inline `display` already wins above (sets display_priority == INLINE_PRIORITY);
- // skip the UA check in that case so author inline overrides keep working.
- // Otherwise short-circuit return true: the spec lists `input[type=hidden]`
- // and `noscript` as `!important` and the rest are normal-origin UA rules
- // that author CSS could in principle override, but author overrides of
- // `