Merge pull request #649 from lightpanda-io/html_collection_named_properties

Fix HTMLCollection named property issues
This commit is contained in:
Karl Seguin
2025-05-16 14:47:02 +08:00
committed by GitHub
3 changed files with 25 additions and 11 deletions

View File

@@ -406,10 +406,16 @@ pub const HTMLCollection = struct {
for (0..len) |i| { for (0..len) |i| {
const node = try self.item(@intCast(i)) orelse unreachable; const node = try self.item(@intCast(i)) orelse unreachable;
const e = @as(*parser.Element, @ptrCast(node)); const e = @as(*parser.Element, @ptrCast(node));
try js_this.setIndex(@intCast(i), e); try js_this.setIndex(@intCast(i), e, .{});
if (try item_name(e)) |name| { if (try item_name(e)) |name| {
try js_this.set(name, e); // 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, e, .{ .DONT_ENUM = true });
}
} }
} }
} }

View File

@@ -173,7 +173,7 @@ pub const NodeList = struct {
const len = self.get_length(); const len = self.get_length();
for (0..len) |i| { for (0..len) |i| {
const node = try self._item(@intCast(i)) orelse unreachable; const node = try self._item(@intCast(i)) orelse unreachable;
try js_this.setIndex(i, node); try js_this.setIndex(@intCast(i), node, .{});
} }
} }
}; };

View File

@@ -894,20 +894,28 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
// for this declaration is _a lot_ easier. // for this declaration is _a lot_ easier.
const _JSOBJECT_ID_KLUDGE = true; const _JSOBJECT_ID_KLUDGE = true;
pub fn setIndex(self: JsObject, index: usize, value: anytype) !void { const SetOpts = packed struct(u32) {
READ_ONLY: bool = false,
DONT_ENUM: bool = false,
DONT_DELETE: bool = false,
_: u29 = 0,
};
pub fn setIndex(self: JsObject, index: u32, value: anytype, opts: SetOpts) !void {
const key = switch (index) { const key = switch (index) {
inline 0...1000 => |i| std.fmt.comptimePrint("{d}", .{i}), inline 0...1000 => |i| std.fmt.comptimePrint("{d}", .{i}),
else => try std.fmt.allocPrint(self.scope.scope_arena, "{d}", .{index}), else => try std.fmt.allocPrint(self.scope.scope_arena, "{d}", .{index}),
}; };
return self.set(key, value); return self.set(key, value, opts);
} }
pub fn set(self: JsObject, key: []const u8, value: anytype) !void { pub fn set(self: JsObject, key: []const u8, value: anytype, opts: SetOpts) !void {
const scope = self.scope; const scope = self.scope;
const js_key = v8.String.initUtf8(scope.isolate, key); const js_key = v8.String.initUtf8(scope.isolate, key);
const js_value = try scope.zigValueToJs(value); const js_value = try scope.zigValueToJs(value);
if (!self.js_obj.setValue(scope.context, js_key, js_value)) {
const res = self.js_obj.defineOwnProperty(scope.context, js_key.toName(), js_value, @bitCast(opts)) orelse false;
if (!res) {
return error.FailedToSet; return error.FailedToSet;
} }
} }
@@ -957,12 +965,12 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
const _JSTHIS_ID_KLUDGE = true; const _JSTHIS_ID_KLUDGE = true;
pub fn setIndex(self: JsThis, index: usize, value: anytype) !void { pub fn setIndex(self: JsThis, index: u32, value: anytype, opts: JsObject.SetOpts) !void {
return self.obj.setIndex(index, value); return self.obj.setIndex(index, value, opts);
} }
pub fn set(self: JsThis, key: []const u8, value: anytype) !void { pub fn set(self: JsThis, key: []const u8, value: anytype, opts: JsObject.SetOpts) !void {
return self.obj.set(key, value); return self.obj.set(key, value, opts);
} }
}; };