diff --git a/src/browser/tests/element/html/htmlelement-props.html b/src/browser/tests/element/html/htmlelement-props.html
index d8f8c905..a008adc5 100644
--- a/src/browser/tests/element/html/htmlelement-props.html
+++ b/src/browser/tests/element/html/htmlelement-props.html
@@ -30,10 +30,27 @@
i1.tabIndex = 10;
testing.expectEqual(10, i1.tabIndex);
+ // Non-interactive elements default to -1
const d3 = document.getElementById('d3');
testing.expectEqual(-1, d3.tabIndex);
d3.tabIndex = 0;
testing.expectEqual(0, d3.tabIndex);
+
+ // Interactive elements default to 0 per spec
+ const input = document.createElement('input');
+ testing.expectEqual(0, input.tabIndex);
+
+ const button = document.createElement('button');
+ testing.expectEqual(0, button.tabIndex);
+
+ const a = document.createElement('a');
+ testing.expectEqual(0, a.tabIndex);
+
+ const select = document.createElement('select');
+ testing.expectEqual(0, select.tabIndex);
+
+ const textarea = document.createElement('textarea');
+ testing.expectEqual(0, textarea.tabIndex);
}
diff --git a/src/browser/webapi/element/Html.zig b/src/browser/webapi/element/Html.zig
index 7639d204..ba6361d3 100644
--- a/src/browser/webapi/element/Html.zig
+++ b/src/browser/webapi/element/Html.zig
@@ -342,6 +342,8 @@ pub fn click(self: *HtmlElement, page: *Page) !void {
try page._event_manager.dispatch(self.asEventTarget(), event);
}
+// TODO: Per spec, hidden is a tristate: true | false | "until-found".
+// We only support boolean for now; "until-found" would need bridge union support.
pub fn getHidden(self: *HtmlElement) bool {
return self.asElement().getAttributeSafe(comptime .wrap("hidden")) != null;
}
@@ -355,7 +357,13 @@ pub fn setHidden(self: *HtmlElement, hidden: bool, page: *Page) !void {
}
pub fn getTabIndex(self: *HtmlElement) i32 {
- const attr = self.asElement().getAttributeSafe(comptime .wrap("tabindex")) orelse return -1;
+ const attr = self.asElement().getAttributeSafe(comptime .wrap("tabindex")) orelse {
+ // Per spec, interactive/focusable elements default to 0 when tabindex is absent
+ return switch (self._type) {
+ .anchor, .area, .button, .input, .select, .textarea, .iframe => 0,
+ else => -1,
+ };
+ };
return std.fmt.parseInt(i32, attr, 10) catch -1;
}