Skip to content

Commit 747a8ad

Browse files
committed
Submit input and button submits can now submit forms
1 parent 527579a commit 747a8ad

File tree

3 files changed

+57
-4
lines changed

3 files changed

+57
-4
lines changed

src/browser/html/form.zig

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,6 @@ pub const HTMLFormElement = struct {
3232
return page.submitForm(self, null);
3333
}
3434

35-
pub fn _requestSubmit(self: *parser.Form) !void {
36-
try parser.formElementSubmit(self);
37-
}
38-
3935
pub fn _reset(self: *parser.Form) !void {
4036
try parser.formElementReset(self);
4137
}

src/browser/page.zig

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,25 @@ pub const Page = struct {
553553
const href = (try parser.elementGetAttribute(element, "href")) orelse return;
554554
try self.navigateFromWebAPI(href, .{});
555555
},
556+
.input => {
557+
const element: *parser.Element = @ptrCast(node);
558+
const input_type = (try parser.elementGetAttribute(element, "type")) orelse return;
559+
if (std.ascii.eqlIgnoreCase(input_type, "submit")) {
560+
return self.elementSubmitForm(element);
561+
}
562+
},
563+
.button => {
564+
const element: *parser.Element = @ptrCast(node);
565+
const button_type = (try parser.elementGetAttribute(element, "type")) orelse return;
566+
if (std.ascii.eqlIgnoreCase(button_type, "submit")) {
567+
return self.elementSubmitForm(element);
568+
}
569+
if (std.ascii.eqlIgnoreCase(button_type, "reset")) {
570+
if (try self.formForElement(element)) |form| {
571+
return parser.formElementReset(form);
572+
}
573+
}
574+
},
556575
else => {},
557576
}
558577
}
@@ -616,6 +635,30 @@ pub const Page = struct {
616635

617636
try self.navigateFromWebAPI(action, opts);
618637
}
638+
639+
fn elementSubmitForm(self: *Page, element: *parser.Element) !void {
640+
const form = (try self.formForElement(element)) orelse return;
641+
return self.submitForm(@ptrCast(form), @ptrCast(element));
642+
}
643+
644+
fn formForElement(self: *Page, element: *parser.Element) !?*parser.Form {
645+
if (try parser.elementGetAttribute(element, "disabled") != null) {
646+
return null;
647+
}
648+
649+
if (try parser.elementGetAttribute(element, "form")) |form_id| {
650+
const document = parser.documentHTMLToDocument(self.window.document);
651+
const form_element = try parser.documentGetElementById(document, form_id) orelse return null;
652+
if (try parser.elementHTMLGetTagType(@ptrCast(form_element)) == .form) {
653+
return @ptrCast(form_element);
654+
}
655+
return null;
656+
}
657+
658+
const Element = @import("dom/element.zig").Element;
659+
const form = (try Element._closest(element, "form", self)) orelse return null;
660+
return @ptrCast(form);
661+
}
619662
};
620663

621664
const DelayedNavigation = struct {

src/browser/xhr/form_data.zig

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ fn collectForm(form: *parser.Form, submitter_: ?*parser.ElementHTML, page: *Page
268268
var entries: Entry.List = .empty;
269269
try entries.ensureTotalCapacity(arena, len);
270270

271+
var submitter_included = false;
271272
const submitter_name_ = try getSubmitterName(submitter_);
272273

273274
for (0..len) |i| {
@@ -295,6 +296,8 @@ fn collectForm(form: *parser.Form, submitter_: ?*parser.ElementHTML, page: *Page
295296
.key = try std.fmt.allocPrint(arena, "{s}.y", .{name}),
296297
.value = "0",
297298
});
299+
300+
submitter_included = true;
298301
}
299302
}
300303
continue;
@@ -309,6 +312,7 @@ fn collectForm(form: *parser.Form, submitter_: ?*parser.ElementHTML, page: *Page
309312
if (submitter_name_ == null or !std.mem.eql(u8, submitter_name_.?, name)) {
310313
continue;
311314
}
315+
submitter_included = true;
312316
}
313317
const value = (try parser.elementGetAttribute(element, "value")) orelse "";
314318
try entries.append(arena, .{ .key = name, .value = value });
@@ -326,6 +330,7 @@ fn collectForm(form: *parser.Form, submitter_: ?*parser.ElementHTML, page: *Page
326330
if (std.mem.eql(u8, submitter_name, name)) {
327331
const value = (try parser.elementGetAttribute(element, "value")) orelse "";
328332
try entries.append(arena, .{ .key = name, .value = value });
333+
submitter_included = true;
329334
}
330335
},
331336
else => {
@@ -335,6 +340,15 @@ fn collectForm(form: *parser.Form, submitter_: ?*parser.ElementHTML, page: *Page
335340
}
336341
}
337342

343+
if (submitter_included == false) {
344+
if (submitter_) |submitter| {
345+
// this can happen if the submitter is outside the form, but associated
346+
// with the form via a form=ID attribute
347+
const value = (try parser.elementGetAttribute(@ptrCast(submitter), "value")) orelse "";
348+
try entries.append(arena, .{ .key = submitter_name_.?, .value = value });
349+
}
350+
}
351+
338352
return entries;
339353
}
340354

0 commit comments

Comments
 (0)