From 09d032f6f8e1f775f8e434a299a143562857109e Mon Sep 17 00:00:00 2001 From: Pierre Tachoire Date: Wed, 25 Oct 2023 17:30:55 +0200 Subject: [PATCH] dom: implement HTMLCollection.namedItem() --- src/dom/document.zig | 1 + src/dom/html_collection.zig | 63 +++++++++++++++++++++++++++++++++++-- src/netsurf.zig | 3 ++ 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/src/dom/document.zig b/src/dom/document.zig index 5a4e496d..9320ddf6 100644 --- a/src/dom/document.zig +++ b/src/dom/document.zig @@ -85,6 +85,7 @@ pub fn testExecFn( .{ .src = "getElementsByTagNameAll.item(0).localName", .ex = "html" }, .{ .src = "getElementsByTagNameAll.item(1).localName", .ex = "head" }, .{ .src = "getElementsByTagNameAll.item(2).localName", .ex = "body" }, + .{ .src = "getElementsByTagNameAll.namedItem('para-empty-child').localName", .ex = "span" }, }; try checkCases(js_env, &getElementsByTagName); diff --git a/src/dom/html_collection.zig b/src/dom/html_collection.zig index b96d7bec..35068092 100644 --- a/src/dom/html_collection.zig +++ b/src/dom/html_collection.zig @@ -128,8 +128,67 @@ pub const HTMLCollection = struct { } pub fn _namedItem(self: *HTMLCollection, name: []const u8) ?*parser.Element { - _ = name; - _ = self; + if (name.len == 0) { + return null; + } + + var node: ?*parser.Node = self.root; + var ntype: parser.NodeType = undefined; + + var is_wildcard = std.mem.eql(u8, self.match, "*"); + + var buffer: [128]u8 = undefined; + const imatch = std.ascii.upperString(&buffer, self.match); + + while (node != null) { + ntype = parser.nodeType(node.?); + if (ntype == .element) { + if (is_wildcard or std.mem.eql(u8, imatch, parser.nodeName(node.?))) { + const elem = @as(*parser.Element, @ptrCast(node)); + + var attr = parser.elementGetAttribute(elem, "id"); + // check if the node id corresponds to the name argument. + if (attr != null and std.mem.eql(u8, name, attr.?)) { + return elem; + } + + attr = parser.elementGetAttribute(elem, "name"); + // check if the node id corresponds to the name argument. + if (attr != null and std.mem.eql(u8, name, attr.?)) { + return elem; + } + } + } + + // Iterate hover the DOM tree. + var next = parser.nodeFirstChild(node.?); + if (next != null) { + node = next; + continue; + } + + next = parser.nodeNextSibling(node.?); + if (next != null) { + node = next; + continue; + } + + var parent = parser.nodeParentNode(node.?); + var lastchild = parser.nodeLastChild(parent.?); + while (node.? != self.root and node.? == lastchild) { + node = parent; + parent = parser.nodeParentNode(node.?); + lastchild = parser.nodeLastChild(parent.?); + } + + if (node.? == self.root) { + node = null; + continue; + } + + node = parser.nodeNextSibling(node.?); + } + return null; } }; diff --git a/src/netsurf.zig b/src/netsurf.zig index 159db9c1..aa2ed825 100644 --- a/src/netsurf.zig +++ b/src/netsurf.zig @@ -597,6 +597,9 @@ pub fn textSplitText(text: *Text, offset: u32) *Text { // Comment pub const Comment = c.dom_comment; +// Attribute +pub const Attribute = c.dom_attr; + // Element pub const Element = c.dom_element;