From 72915760c4a96ff67726d0ceee800a5ab737b0da Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Mon, 16 Jun 2025 13:39:44 +0800 Subject: [PATCH] Use css.querySelectorAll to find form elements Libdom's formGetCollection doesn't work (like I would expect) for dynamically added elements. For example, given: ``` let el = document.createElement('input'); document.getElementsByTagName('form')[0].append(el); ``` (and assume the page has a form), I'd expect `el.form` to be equal to the form the input was added to. Instead, it's null. This is a problem given that `dom_html_form_element_get_elements` uses the element's `form` attribute to "collect" the elements. This uses our existing querySelector to find the form elements. --- src/browser/xhr/form_data.zig | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/browser/xhr/form_data.zig b/src/browser/xhr/form_data.zig index 485ef647..ed4782ed 100644 --- a/src/browser/xhr/form_data.zig +++ b/src/browser/xhr/form_data.zig @@ -115,17 +115,16 @@ const EntryIterable = iterator.Iterable(kv.EntryIterator, "FormDataEntryIterator // TODO: handle disabled fieldsets fn collectForm(form: *parser.Form, submitter_: ?*parser.ElementHTML, page: *Page) !kv.List { const arena = page.arena; - const collection = try parser.formGetCollection(form); - const len = try parser.htmlCollectionGetLength(collection); + const node_list = try @import("../dom/css.zig").querySelectorAll(arena, @alignCast(@ptrCast(form)), "input,select,button,textarea"); + const nodes = node_list.nodes.items; var entries: kv.List = .{}; - try entries.ensureTotalCapacity(arena, len); + try entries.ensureTotalCapacity(arena, nodes.len); var submitter_included = false; const submitter_name_ = try getSubmitterName(submitter_); - for (0..len) |i| { - const node = try parser.htmlCollectionItem(collection, @intCast(i)); + for (nodes) |node| { const element = parser.nodeToElement(node); // must have a name @@ -181,10 +180,7 @@ fn collectForm(form: *parser.Form, submitter_: ?*parser.ElementHTML, page: *Page submitter_included = true; } }, - else => { - log.warn(.web_api, "unsupported form element", .{ .tag = @tagName(tag) }); - continue; - }, + else => unreachable, } } @@ -297,6 +293,7 @@ test "Browser.FormData" { \\ \\ \\ + \\ }); defer runner.deinit(); @@ -356,6 +353,8 @@ test "Browser.FormData" { try runner.testCases(&.{ .{ "let form1 = document.getElementById('form1')", null }, + .{ "let input = document.createElement('input');", null }, + .{ "input.name = 'dyn'; input.value= 'dyn-v'; form1.appendChild(input);", null }, .{ "let submit1 = document.getElementById('s1')", null }, .{ "let f2 = new FormData(form1, submit1)", null }, .{ "acc = '';", null }, @@ -378,6 +377,7 @@ test "Browser.FormData" { \\mlt-2=water \\mlt-2=tea \\s1=s1-v + \\dyn=dyn-v }, }, .{}); }