@@ -550,23 +550,25 @@ pub const Page = struct {
550550 .a = > {
551551 const element : * parser.Element = @ptrCast (node );
552552 const href = (try parser .elementGetAttribute (element , "href" )) orelse return ;
553-
554- // We cannot navigate immediately as navigating will delete the DOM tree, which holds this event's node.
555- // As such we schedule the function to be called as soon as possible.
556- // NOTE Using the page.arena assumes that the scheduling loop does use this object after invoking the callback
557- // If that changes we may want to consider storing DelayedNavigation in the session instead.
558- const arena = self .arena ;
559- const navi = try arena .create (DelayedNavigation );
560- navi .* = .{
561- .session = self .session ,
562- .href = try arena .dupe (u8 , href ),
563- };
564- _ = try self .loop .timeout (0 , & navi .navigate_node );
553+ try self .navigateFromWebAPI (href );
565554 },
566555 else = > {},
567556 }
568557 }
569558
559+ // As such we schedule the function to be called as soon as possible.
560+ // The page.arena is safe to use here, but the transfer_arena exists
561+ // specifically for this type of lifetime.
562+ pub fn navigateFromWebAPI (self : * Page , url : []const u8 ) ! void {
563+ const arena = self .session .transfer_arena ;
564+ const navi = try arena .create (DelayedNavigation );
565+ navi .* = .{
566+ .session = self .session ,
567+ .url = try arena .dupe (u8 , url ),
568+ };
569+ _ = try self .loop .timeout (0 , & navi .navigate_node );
570+ }
571+
570572 pub fn getOrCreateNodeWrapper (self : * Page , comptime T : type , node : * parser.Node ) ! * T {
571573 if (self .getNodeWrapper (T , node )) | wrap | {
572574 return wrap ;
@@ -588,16 +590,15 @@ pub const Page = struct {
588590};
589591
590592const DelayedNavigation = struct {
591- navigate_node : Loop.CallbackNode = .{ . func = DelayedNavigation . delay_navigate } ,
593+ url : [] const u8 ,
592594 session : * Session ,
593- href : [] const u8 ,
595+ navigate_node : Loop.CallbackNode = .{ . func = delayNavigate } ,
594596
595- fn delay_navigate (node : * Loop.CallbackNode , repeat_delay : * ? u63 ) void {
597+ fn delayNavigate (node : * Loop.CallbackNode , repeat_delay : * ? u63 ) void {
596598 _ = repeat_delay ;
597599 const self : * DelayedNavigation = @fieldParentPtr ("navigate_node" , node );
598- self .session .pageNavigate (self .href ) catch | err | {
599- // TODO: should we trigger a specific event here?
600- log .err (.page , "delayed navigation error" , .{ .err = err });
600+ self .session .pageNavigate (self .url ) catch | err | {
601+ log .err (.page , "delayed navigation error" , .{ .err = err , .url = self .url });
601602 };
602603 }
603604};
0 commit comments