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.
This commit is contained in:
Karl Seguin
2025-09-29 14:03:59 +08:00
parent 220775715d
commit d7ce6bdeff
2 changed files with 20 additions and 16 deletions

View File

@@ -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;
};
}
};

View File

@@ -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));
</script>