File tree Expand file tree Collapse file tree 1 file changed +24
-1
lines changed Expand file tree Collapse file tree 1 file changed +24
-1
lines changed Original file line number Diff line number Diff line change @@ -706,12 +706,35 @@ pub const Page = struct {
706706 .a = > {
707707 const element : * parser.Element = @ptrCast (node );
708708 const href = (try parser .elementGetAttribute (element , "href" )) orelse return ;
709- return self .session .pageNavigate (href );
709+
710+ // We cannot navigate immediately as navigating will delete the DOM tree, which holds this event's node.
711+ // As such we schedule the function to be called as soon as possible.
712+ // NOTE Using the page.arena assumes that the scheduling loop does use this object after invoking the callback
713+ // If that changes we may want to consider storing DelayedNavigation in the session instead.
714+ const arena = self .arena ;
715+ const navi = try arena .create (DelayedNavigation );
716+ navi .* = .{
717+ .session = self .session ,
718+ .href = try arena .dupe (u8 , href ),
719+ };
720+ _ = try self .state .loop .timeout (0 , & navi .navigate_node );
710721 },
711722 else = > {},
712723 }
713724 }
714725
726+ const DelayedNavigation = struct {
727+ navigate_node : Loop.CallbackNode = .{ .func = DelayedNavigation .delay_navigate },
728+ session : * Session ,
729+ href : []const u8 ,
730+
731+ fn delay_navigate (node : * Loop.CallbackNode , repeat_delay : * ? u63 ) void {
732+ _ = repeat_delay ;
733+ const self : * DelayedNavigation = @fieldParentPtr ("navigate_node" , node );
734+ self .session .pageNavigate (self .href ) catch unreachable ;
735+ }
736+ };
737+
715738 const Script = struct {
716739 element : * parser.Element ,
717740 kind : Kind ,
You can’t perform that action at this time.
0 commit comments