Submit input and button submits can now submit forms

This commit is contained in:
Karl Seguin
2025-06-02 11:27:44 +08:00
parent 527579aef4
commit 747a8ad09c
3 changed files with 57 additions and 4 deletions

View File

@@ -32,10 +32,6 @@ pub const HTMLFormElement = struct {
return page.submitForm(self, null);
}
pub fn _requestSubmit(self: *parser.Form) !void {
try parser.formElementSubmit(self);
}
pub fn _reset(self: *parser.Form) !void {
try parser.formElementReset(self);
}

View File

@@ -553,6 +553,25 @@ pub const Page = struct {
const href = (try parser.elementGetAttribute(element, "href")) orelse return;
try self.navigateFromWebAPI(href, .{});
},
.input => {
const element: *parser.Element = @ptrCast(node);
const input_type = (try parser.elementGetAttribute(element, "type")) orelse return;
if (std.ascii.eqlIgnoreCase(input_type, "submit")) {
return self.elementSubmitForm(element);
}
},
.button => {
const element: *parser.Element = @ptrCast(node);
const button_type = (try parser.elementGetAttribute(element, "type")) orelse return;
if (std.ascii.eqlIgnoreCase(button_type, "submit")) {
return self.elementSubmitForm(element);
}
if (std.ascii.eqlIgnoreCase(button_type, "reset")) {
if (try self.formForElement(element)) |form| {
return parser.formElementReset(form);
}
}
},
else => {},
}
}
@@ -616,6 +635,30 @@ pub const Page = struct {
try self.navigateFromWebAPI(action, opts);
}
fn elementSubmitForm(self: *Page, element: *parser.Element) !void {
const form = (try self.formForElement(element)) orelse return;
return self.submitForm(@ptrCast(form), @ptrCast(element));
}
fn formForElement(self: *Page, element: *parser.Element) !?*parser.Form {
if (try parser.elementGetAttribute(element, "disabled") != null) {
return null;
}
if (try parser.elementGetAttribute(element, "form")) |form_id| {
const document = parser.documentHTMLToDocument(self.window.document);
const form_element = try parser.documentGetElementById(document, form_id) orelse return null;
if (try parser.elementHTMLGetTagType(@ptrCast(form_element)) == .form) {
return @ptrCast(form_element);
}
return null;
}
const Element = @import("dom/element.zig").Element;
const form = (try Element._closest(element, "form", self)) orelse return null;
return @ptrCast(form);
}
};
const DelayedNavigation = struct {

View File

@@ -268,6 +268,7 @@ fn collectForm(form: *parser.Form, submitter_: ?*parser.ElementHTML, page: *Page
var entries: Entry.List = .empty;
try entries.ensureTotalCapacity(arena, len);
var submitter_included = false;
const submitter_name_ = try getSubmitterName(submitter_);
for (0..len) |i| {
@@ -295,6 +296,8 @@ fn collectForm(form: *parser.Form, submitter_: ?*parser.ElementHTML, page: *Page
.key = try std.fmt.allocPrint(arena, "{s}.y", .{name}),
.value = "0",
});
submitter_included = true;
}
}
continue;
@@ -309,6 +312,7 @@ fn collectForm(form: *parser.Form, submitter_: ?*parser.ElementHTML, page: *Page
if (submitter_name_ == null or !std.mem.eql(u8, submitter_name_.?, name)) {
continue;
}
submitter_included = true;
}
const value = (try parser.elementGetAttribute(element, "value")) orelse "";
try entries.append(arena, .{ .key = name, .value = value });
@@ -326,6 +330,7 @@ fn collectForm(form: *parser.Form, submitter_: ?*parser.ElementHTML, page: *Page
if (std.mem.eql(u8, submitter_name, name)) {
const value = (try parser.elementGetAttribute(element, "value")) orelse "";
try entries.append(arena, .{ .key = name, .value = value });
submitter_included = true;
}
},
else => {
@@ -335,6 +340,15 @@ fn collectForm(form: *parser.Form, submitter_: ?*parser.ElementHTML, page: *Page
}
}
if (submitter_included == false) {
if (submitter_) |submitter| {
// this can happen if the submitter is outside the form, but associated
// with the form via a form=ID attribute
const value = (try parser.elementGetAttribute(@ptrCast(submitter), "value")) orelse "";
try entries.append(arena, .{ .key = submitter_name_.?, .value = value });
}
}
return entries;
}