From b9744992bf2cce951f8f3fd5d3e9ca1ac332c536 Mon Sep 17 00:00:00 2001 From: Francis Bouvier Date: Sun, 12 Jul 2026 12:03:36 +0200 Subject: [PATCH] webapi: document.head matches by local name; getElementsByName is HTML-only Fixes two WPT files (1 subtest each, both fully green): - /html/dom/documents/dom-tree-accessors/document.head-02.html: document.head is the first html-namespace child of the document element whose LOCAL name is head. A createElementNS(HTML_NS, "blah:head") element is an HTMLUnknownElement in our type system, so the old is(Html.Head) walk skipped it; getHead now matches on namespace + local name (and returns *Element accordingly). - .../document.getElementsByName/document.getElementsByName-namespace.html: getElementsByName must only consider HTML-namespace elements; the live collection's name filter now rejects foreign elements, matching the earlier fix for name-based access on HTMLCollections. Co-Authored-By: Claude Fable 5 --- src/browser/webapi/HTMLDocument.zig | 13 ++++++++----- src/browser/webapi/collections/node_live.zig | 2 ++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/browser/webapi/HTMLDocument.zig b/src/browser/webapi/HTMLDocument.zig index d8e5a757f..5bb438baa 100644 --- a/src/browser/webapi/HTMLDocument.zig +++ b/src/browser/webapi/HTMLDocument.zig @@ -44,14 +44,17 @@ pub fn asEventTarget(self: *HTMLDocument) *@import("EventTarget.zig") { } // HTML-specific accessors -pub fn getHead(self: *HTMLDocument) ?*Element.Html.Head { +// The head is the first html-namespace child of the document element whose +// local name is head, whatever its Zig element type (e.g. a createElementNS +// "blah:head" is an HTMLUnknownElement but still qualifies). +pub fn getHead(self: *HTMLDocument) ?*Element { const doc_el = self._proto.getDocumentElement() orelse return null; var child = doc_el.asNode().firstChild(); - while (child) |node| { - if (node.is(Element.Html.Head)) |head| { - return head; + while (child) |node| : (child = node.nextSibling()) { + const el = node.is(Element) orelse continue; + if (el._namespace == .html and std.mem.eql(u8, el.getLocalName(), "head")) { + return el; } - child = node.nextSibling(); } return null; } diff --git a/src/browser/webapi/collections/node_live.zig b/src/browser/webapi/collections/node_live.zig index 79b4bf87f..800e5dc60 100644 --- a/src/browser/webapi/collections/node_live.zig +++ b/src/browser/webapi/collections/node_live.zig @@ -283,6 +283,8 @@ pub fn NodeLive(comptime mode: Mode) type { }, .name => { const el = node.is(Element) orelse return false; + // getElementsByName only considers HTML elements. + if (el._namespace != .html) return false; const name_attr = el.getAttributeSafe(comptime .wrap("name")) orelse return false; return std.mem.eql(u8, name_attr, self._filter); },