From d7ce6bdeff2098ceebcb5d1538b4c9a819dc8eb8 Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Mon, 29 Sep 2025 14:03:59 +0800 Subject: [PATCH] Replace HTMLCollection postAttach's with indexed/named getter This solves two issues. First, it's more correct, the indexers should be live. Second, it makes sure that anything with an HTMLCollection prototype, like HTMLOptionsCollection, also gets access to the index getters. We could solve the 2nd issue by making `postAttach` work up the prototype chain, but since postAttach is wrong (not live), I prefer this solution. --- src/browser/dom/html_collection.zig | 31 ++++++++++++++--------------- src/tests/html/select.html | 5 +++++ 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/browser/dom/html_collection.zig b/src/browser/dom/html_collection.zig index 738d454e..a3c7ccc0 100644 --- a/src/browser/dom/html_collection.zig +++ b/src/browser/dom/html_collection.zig @@ -429,24 +429,23 @@ pub const HTMLCollection = struct { return null; } - pub fn postAttach(self: *HTMLCollection, js_this: JsThis) !void { - const len = try self.get_length(); - for (0..len) |i| { - const node = try self.item(@intCast(i)) orelse unreachable; - const e = @as(*parser.Element, @ptrCast(node)); - const as_interface = try Element.toInterface(e); - try js_this.setIndex(@intCast(i), as_interface, .{}); + pub fn indexed_get(self: *HTMLCollection, index: u32, has_value: *bool) !?Union { + return (try _item(self, index)) orelse { + has_value.* = false; + return undefined; + }; + } - if (try item_name(e)) |name| { - // Even though an entry might have an empty id, the spec says - // that namedItem("") should always return null - if (name.len > 0) { - // Named fields should not be enumerable (it is defined with - // the LegacyUnenumerableNamedProperties flag.) - try js_this.set(name, as_interface, .{ .DONT_ENUM = true }); - } - } + pub fn named_get(self: *const HTMLCollection, name: []const u8, has_value: *bool) !?Union { + // Even though an entry might have an empty id, the spec says + // that namedItem("") should always return null + if (name.len == 0) { + return null; } + return (try _namedItem(self, name)) orelse { + has_value.* = false; + return undefined; + }; } }; diff --git a/src/tests/html/select.html b/src/tests/html/select.html index 217483a2..f18dfdab 100644 --- a/src/tests/html/select.html +++ b/src/tests/html/select.html @@ -55,6 +55,7 @@ o3.value = 'o3'; options.add(o3) testing.expectEqual(3, options.length); + testing.expectEqual('o3', options[2].value); testing.expectEqual('o3', options.item(2).value); let o4 = document.createElement('option'); @@ -71,5 +72,9 @@ options.remove(3) testing.expectEqual(4, options.length); + testing.expectEqual('o3', options[3].value); testing.expectEqual('o3', options.item(3).value); + + testing.expectEqual(undefined, options[10]); + testing.expectEqual(null, options.item(10));