use page.navigateAsync from CDP Page.navigate

also remove useless page.reset()
This commit is contained in:
Pierre Tachoire
2025-12-19 17:13:47 +01:00
parent a69efb9d3f
commit 6d8622d0b5
7 changed files with 18 additions and 38 deletions

View File

@@ -195,7 +195,7 @@ pub const HTMLDocument = struct {
} }
pub fn set_location(_: *const parser.DocumentHTML, url: []const u8, page: *Page) !void { pub fn set_location(_: *const parser.DocumentHTML, url: []const u8, page: *Page) !void {
return page.navigateFromWebAPI(url, .{ .reason = .script }, .{ .push = null }); return page.navigateAsync(url, .{ .reason = .script }, .{ .push = null });
} }
pub fn get_designMode(_: *parser.DocumentHTML) []const u8 { pub fn get_designMode(_: *parser.DocumentHTML) []const u8 {

View File

@@ -38,7 +38,7 @@ pub const Location = struct {
} }
pub fn set_href(_: *const Location, href: []const u8, page: *Page) !void { pub fn set_href(_: *const Location, href: []const u8, page: *Page) !void {
return page.navigateFromWebAPI(href, .{ .reason = .script }, .{ .push = null }); return page.navigateAsync(href, .{ .reason = .script }, .{ .push = null });
} }
pub fn set_hash(_: *const Location, hash: []const u8, page: *Page) !void { pub fn set_hash(_: *const Location, hash: []const u8, page: *Page) !void {
@@ -56,7 +56,7 @@ pub const Location = struct {
break :blk try std.fmt.allocPrint(page.arena, "#{s}", .{hash}); break :blk try std.fmt.allocPrint(page.arena, "#{s}", .{hash});
}; };
return page.navigateFromWebAPI(normalized_hash, .{ .reason = .script }, .{ .replace = null }); return page.navigateAsync(normalized_hash, .{ .reason = .script }, .{ .replace = null });
} }
pub fn get_protocol(self: *Location) []const u8 { pub fn get_protocol(self: *Location) []const u8 {
@@ -92,15 +92,15 @@ pub const Location = struct {
} }
pub fn _assign(_: *const Location, url: []const u8, page: *Page) !void { pub fn _assign(_: *const Location, url: []const u8, page: *Page) !void {
return page.navigateFromWebAPI(url, .{ .reason = .script }, .{ .push = null }); return page.navigateAsync(url, .{ .reason = .script }, .{ .push = null });
} }
pub fn _replace(_: *const Location, url: []const u8, page: *Page) !void { pub fn _replace(_: *const Location, url: []const u8, page: *Page) !void {
return page.navigateFromWebAPI(url, .{ .reason = .script }, .{ .replace = null }); return page.navigateAsync(url, .{ .reason = .script }, .{ .replace = null });
} }
pub fn _reload(_: *const Location, page: *Page) !void { pub fn _reload(_: *const Location, page: *Page) !void {
return page.navigateFromWebAPI(page.url.raw, .{ .reason = .script }, .reload); return page.navigateAsync(page.url.raw, .{ .reason = .script }, .reload);
} }
pub fn _toString(self: *Location, page: *Page) ![]const u8 { pub fn _toString(self: *Location, page: *Page) ![]const u8 {

View File

@@ -137,7 +137,7 @@ pub const Window = struct {
} }
pub fn set_location(_: *const Window, url: []const u8, page: *Page) !void { pub fn set_location(_: *const Window, url: []const u8, page: *Page) !void {
return page.navigateFromWebAPI(url, .{ .reason = .script }, .{ .push = null }); return page.navigateAsync(url, .{ .reason = .script }, .{ .push = null });
} }
// frames return the window itself, but accessing it via a pseudo // frames return the window itself, but accessing it via a pseudo

View File

@@ -257,7 +257,7 @@ pub fn navigate(
_ = try self.pushEntry(url, .{ .source = .navigation, .value = state }, page, true); _ = try self.pushEntry(url, .{ .source = .navigation, .value = state }, page, true);
} else { } else {
try page.navigateFromWebAPI(url, .{ .reason = .navigation }, kind); try page.navigateAsync(url, .{ .reason = .navigation }, kind);
} }
}, },
.replace => |state| { .replace => |state| {
@@ -270,7 +270,7 @@ pub fn navigate(
_ = try self.replaceEntry(url, .{ .source = .navigation, .value = state }, page, true); _ = try self.replaceEntry(url, .{ .source = .navigation, .value = state }, page, true);
} else { } else {
try page.navigateFromWebAPI(url, .{ .reason = .navigation }, kind); try page.navigateAsync(url, .{ .reason = .navigation }, kind);
} }
}, },
.traverse => |index| { .traverse => |index| {
@@ -283,11 +283,11 @@ pub fn navigate(
// todo: Fire navigate event // todo: Fire navigate event
try finished.resolve({}); try finished.resolve({});
} else { } else {
try page.navigateFromWebAPI(url, .{ .reason = .navigation }, kind); try page.navigateAsync(url, .{ .reason = .navigation }, kind);
} }
}, },
.reload => { .reload => {
try page.navigateFromWebAPI(url, .{ .reason = .navigation }, kind); try page.navigateAsync(url, .{ .reason = .navigation }, kind);
}, },
} }

View File

@@ -167,21 +167,6 @@ pub const Page = struct {
self.script_manager.deinit(); self.script_manager.deinit();
} }
fn reset(self: *Page) !void {
// Force running the micro task to drain the queue.
self.session.browser.env.runMicrotasks();
self.scheduler.reset();
self.http_client.abort();
self.script_manager.reset();
self.load_state = .parsing;
self.mode = .{ .pre = {} };
_ = self.session.browser.page_arena.reset(.{ .retain_with_limit = 1 * 1024 * 1024 });
try self.registerBackgroundTasks();
}
fn registerBackgroundTasks(self: *Page) !void { fn registerBackgroundTasks(self: *Page) !void {
if (comptime builtin.is_test) { if (comptime builtin.is_test) {
// HTML test runner manually calls these as necessary // HTML test runner manually calls these as necessary
@@ -544,14 +529,9 @@ pub const Page = struct {
}; };
} }
// You are no supposed to call this function directly.
// spec reference: https://html.spec.whatwg.org/#document-lifecycle // spec reference: https://html.spec.whatwg.org/#document-lifecycle
pub fn navigate(self: *Page, request_url: []const u8, opts: NavigateOpts) !void { pub fn navigate(self: *Page, request_url: []const u8, opts: NavigateOpts) !void {
if (self.mode != .pre) {
// it's possible for navigate to be called multiple times on the
// same page (via CDP). We want to reset the page between each call.
try self.reset();
}
const req_id = self.http_client.nextReqId(); const req_id = self.http_client.nextReqId();
log.info(.http, "navigate", .{ log.info(.http, "navigate", .{
@@ -964,7 +944,7 @@ pub const Page = struct {
const element: *parser.Element = @ptrCast(node); const element: *parser.Element = @ptrCast(node);
const href = (try parser.elementGetAttribute(element, "href")) orelse return; const href = (try parser.elementGetAttribute(element, "href")) orelse return;
log.debug(.input, "window click on link", .{ .tag = tag, .href = href }); log.debug(.input, "window click on link", .{ .tag = tag, .href = href });
try self.navigateFromWebAPI(href, .{}, .{ .push = null }); try self.navigateAsync(href, .{}, .{ .push = null });
return; return;
}, },
.input => { .input => {
@@ -1118,7 +1098,7 @@ pub const Page = struct {
// As such we schedule the function to be called as soon as possible. // As such we schedule the function to be called as soon as possible.
// The page.arena is safe to use here, but the transfer_arena exists // The page.arena is safe to use here, but the transfer_arena exists
// specifically for this type of lifetime. // specifically for this type of lifetime.
pub fn navigateFromWebAPI(self: *Page, url: []const u8, opts: NavigateOpts, kind: NavigationKind) !void { pub fn navigateAsync(self: *Page, url: []const u8, opts: NavigateOpts, kind: NavigationKind) !void {
const session = self.session; const session = self.session;
const stitched_url = try URL.stitch( const stitched_url = try URL.stitch(
session.transfer_arena, session.transfer_arena,
@@ -1221,7 +1201,7 @@ pub const Page = struct {
} else { } else {
action = try URL.concatQueryString(transfer_arena, action, buf.items); action = try URL.concatQueryString(transfer_arena, action, buf.items);
} }
try self.navigateFromWebAPI(action, opts, .{ .push = null }); try self.navigateAsync(action, opts, .{ .push = null });
} }
pub fn isNodeAttached(self: *const Page, node: *parser.Node) bool { pub fn isNodeAttached(self: *const Page, node: *parser.Node) bool {

View File

@@ -191,7 +191,7 @@ pub const Session = struct {
// bad if old requests went to the new page, so let's make double sure // bad if old requests went to the new page, so let's make double sure
self.browser.http_client.abort(); self.browser.http_client.abort();
// Page.navigateFromWebAPI terminatedExecution. If we don't resume // Page.navigateAsync terminatedExecution. If we don't resume
// it before doing a shutdown we'll get an error. // it before doing a shutdown we'll get an error.
self.executor.resumeExecution(); self.executor.resumeExecution();
self.removePage(); self.removePage();

View File

@@ -216,10 +216,10 @@ fn navigate(cmd: anytype) !void {
var page = bc.session.currentPage() orelse return error.PageNotLoaded; var page = bc.session.currentPage() orelse return error.PageNotLoaded;
try page.navigate(params.url, .{ try page.navigateAsync(params.url, .{
.reason = .address_bar, .reason = .address_bar,
.cdp_id = cmd.input.id, .cdp_id = cmd.input.id,
}); }, .{ .push = null });
} }
pub fn pageNavigate(arena: Allocator, bc: anytype, event: *const Notification.PageNavigate) !void { pub fn pageNavigate(arena: Allocator, bc: anytype, event: *const Notification.PageNavigate) !void {