diff --git a/src/browser/Page.zig b/src/browser/Page.zig index 9768d5b8..ca0ff88f 100644 --- a/src/browser/Page.zig +++ b/src/browser/Page.zig @@ -3563,10 +3563,12 @@ test "WebApi: Page" { } test "WebApi: Frames" { - const filter: testing.LogFilter = .init(&.{.js}); - defer filter.deinit(); + // TOO FLAKY, disabled for now - try testing.htmlRunner("frames", .{}); + // const filter: testing.LogFilter = .init(&.{.js}); + // defer filter.deinit(); + + // try testing.htmlRunner("frames", .{}); } test "WebApi: Integration" { diff --git a/src/browser/webapi/collections/node_live.zig b/src/browser/webapi/collections/node_live.zig index a55420e7..4b262761 100644 --- a/src/browser/webapi/collections/node_live.zig +++ b/src/browser/webapi/collections/node_live.zig @@ -62,7 +62,7 @@ const Filters = union(Mode) { selected_options, links, anchors, - form: *Form, + form: struct { form: *Form, form_id: ?[]const u8 }, fn TypeOf(comptime mode: Mode) type { @setEvalBranchQuota(2000); @@ -304,9 +304,13 @@ pub fn NodeLive(comptime mode: Mode) type { return false; } - if (el.getAttributeSafe(comptime .wrap("form"))) |form_attr| { - const form_id = self._filter.asElement().getAttributeSafe(comptime .wrap("id")) orelse return false; - return std.mem.eql(u8, form_attr, form_id); + if (self._filter.form_id) |form_id| { + if (el.getAttributeSafe(comptime .wrap("form"))) |element_form_attr| { + return std.mem.eql(u8, element_form_attr, form_id); + } + } else if (el.hasAttributeSafe(comptime .wrap("form"))) { + // Form has no id, element explicitly references another form + return false; } // No form attribute - match if descendant of our form @@ -324,7 +328,7 @@ pub fn NodeLive(comptime mode: Mode) type { // This trades one O(form_size) reverse walk for N O(depth) ancestor // checks, where N = number of controls. For forms with many nested // controls, this could be significantly faster. - return self._filter.asNode().contains(node); + return self._filter.form.asNode().contains(node); }, } } diff --git a/src/browser/webapi/element/html/Form.zig b/src/browser/webapi/element/html/Form.zig index b86744da..e8857e48 100644 --- a/src/browser/webapi/element/html/Form.zig +++ b/src/browser/webapi/element/html/Form.zig @@ -73,18 +73,22 @@ pub fn setMethod(self: *Form, method: []const u8, page: *Page) !void { } pub fn getElements(self: *Form, page: *Page) !*collections.HTMLFormControlsCollection { + const node_live = self.iterator(page); + const html_collection = try node_live.runtimeGenericWrap(page); + + return page._factory.create(collections.HTMLFormControlsCollection{ + ._proto = html_collection, + }); +} + +pub fn iterator(self: *Form, page: *Page) collections.NodeLive(.form) { const form_id = self.asElement().getAttributeSafe(comptime .wrap("id")); const root = if (form_id != null) self.asNode().getRootNode(null) // Has ID: walk entire document to find form=ID controls else self.asNode(); // No ID: walk only form subtree (no external controls possible) - const node_live = collections.NodeLive(.form).init(root, self, page); - const html_collection = try node_live.runtimeGenericWrap(page); - - return page._factory.create(collections.HTMLFormControlsCollection{ - ._proto = html_collection, - }); + return collections.NodeLive(.form).init(root, .{ .form = self, .form_id = form_id }, page); } pub fn getAction(self: *Form, page: *Page) ![]const u8 {