@@ -92,6 +92,9 @@ pub const Page = struct {
9292 // current_script could by fetch module to resolve module's url to fetch.
9393 current_script : ? * const Script = null ,
9494
95+ // indicates intention to navigate to another page on the next loop execution.
96+ delayed_navigation : bool = false ,
97+
9598 pub fn init (self : * Page , arena : Allocator , session : * Session ) ! void {
9699 const browser = session .browser ;
97100 self .* = .{
@@ -553,6 +556,25 @@ pub const Page = struct {
553556 const href = (try parser .elementGetAttribute (element , "href" )) orelse return ;
554557 try self .navigateFromWebAPI (href , .{});
555558 },
559+ .input = > {
560+ const element : * parser.Element = @ptrCast (node );
561+ const input_type = (try parser .elementGetAttribute (element , "type" )) orelse return ;
562+ if (std .ascii .eqlIgnoreCase (input_type , "submit" )) {
563+ return self .elementSubmitForm (element );
564+ }
565+ },
566+ .button = > {
567+ const element : * parser.Element = @ptrCast (node );
568+ const button_type = (try parser .elementGetAttribute (element , "type" )) orelse return ;
569+ if (std .ascii .eqlIgnoreCase (button_type , "submit" )) {
570+ return self .elementSubmitForm (element );
571+ }
572+ if (std .ascii .eqlIgnoreCase (button_type , "reset" )) {
573+ if (try self .formForElement (element )) | form | {
574+ return parser .formElementReset (form );
575+ }
576+ }
577+ },
556578 else = > {},
557579 }
558580 }
@@ -561,6 +583,7 @@ pub const Page = struct {
561583 // The page.arena is safe to use here, but the transfer_arena exists
562584 // specifically for this type of lifetime.
563585 pub fn navigateFromWebAPI (self : * Page , url : []const u8 , opts : NavigateOpts ) ! void {
586+ self .delayed_navigation = true ;
564587 const arena = self .session .transfer_arena ;
565588 const navi = try arena .create (DelayedNavigation );
566589 navi .* = .{
@@ -616,6 +639,30 @@ pub const Page = struct {
616639
617640 try self .navigateFromWebAPI (action , opts );
618641 }
642+
643+ fn elementSubmitForm (self : * Page , element : * parser.Element ) ! void {
644+ const form = (try self .formForElement (element )) orelse return ;
645+ return self .submitForm (@ptrCast (form ), @ptrCast (element ));
646+ }
647+
648+ fn formForElement (self : * Page , element : * parser.Element ) ! ? * parser.Form {
649+ if (try parser .elementGetAttribute (element , "disabled" ) != null ) {
650+ return null ;
651+ }
652+
653+ if (try parser .elementGetAttribute (element , "form" )) | form_id | {
654+ const document = parser .documentHTMLToDocument (self .window .document );
655+ const form_element = try parser .documentGetElementById (document , form_id ) orelse return null ;
656+ if (try parser .elementHTMLGetTagType (@ptrCast (form_element )) == .form ) {
657+ return @ptrCast (form_element );
658+ }
659+ return null ;
660+ }
661+
662+ const Element = @import ("dom/element.zig" ).Element ;
663+ const form = (try Element ._closest (element , "form" , self )) orelse return null ;
664+ return @ptrCast (form );
665+ }
619666};
620667
621668const DelayedNavigation = struct {
0 commit comments