support url on createTarget and send lifecycle events

Support url parameter on createTarget. we now navigate on createTarget
to dispatch events correctly, even in case of about:blank
This commit is contained in:
Pierre Tachoire
2025-12-09 10:07:32 +01:00
parent e98bb16255
commit 0d8dd84df5
4 changed files with 42 additions and 12 deletions

View File

@@ -109,13 +109,13 @@ pub const PageRemove = struct {};
pub const PageNavigate = struct { pub const PageNavigate = struct {
timestamp: u64, timestamp: u64,
url: []const u8, url: [:0]const u8,
opts: Page.NavigateOpts, opts: Page.NavigateOpts,
}; };
pub const PageNavigated = struct { pub const PageNavigated = struct {
timestamp: u64, timestamp: u64,
url: []const u8, url: [:0]const u8,
}; };
pub const PageNetworkIdle = struct { pub const PageNetworkIdle = struct {

View File

@@ -63,7 +63,7 @@ const timestamp = @import("../datetime.zig").timestamp;
const milliTimestamp = @import("../datetime.zig").milliTimestamp; const milliTimestamp = @import("../datetime.zig").milliTimestamp;
pub threadlocal var current: *Page = undefined; pub threadlocal var current: *Page = undefined;
var default_url = URL{ ._raw = "about/blank" }; var default_url = URL{ ._raw = "about:blank" };
pub var default_location: Location = Location{ ._url = &default_url }; pub var default_location: Location = Location{ ._url = &default_url };
pub const BUF_SIZE = 1024; pub const BUF_SIZE = 1024;
@@ -201,7 +201,7 @@ fn reset(self: *Page, comptime initializing: bool) !void {
self._factory = Factory.init(self); self._factory = Factory.init(self);
self.version = 0; self.version = 0;
self.url = "about/blank"; self.url = "about:blank";
self.document = (try self._factory.document(Node.Document.HTMLDocument{ ._proto = undefined })).asDocument(); self.document = (try self._factory.document(Node.Document.HTMLDocument{ ._proto = undefined })).asDocument();

View File

@@ -19,6 +19,7 @@
const std = @import("std"); const std = @import("std");
const Page = @import("../../browser/Page.zig"); const Page = @import("../../browser/Page.zig");
const Notification = @import("../../Notification.zig"); const Notification = @import("../../Notification.zig");
const timestampF = @import("../../datetime.zig").timestamp;
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
@@ -47,7 +48,7 @@ pub fn processMessage(cmd: anytype) !void {
const Frame = struct { const Frame = struct {
id: []const u8, id: []const u8,
loaderId: []const u8, loaderId: []const u8,
url: []const u8, url: [:0]const u8,
domainAndRegistry: []const u8 = "", domainAndRegistry: []const u8 = "",
securityOrigin: []const u8, securityOrigin: []const u8,
mimeType: []const u8 = "text/html", mimeType: []const u8 = "text/html",
@@ -82,11 +83,36 @@ fn setLifecycleEventsEnabled(cmd: anytype) !void {
})) orelse return error.InvalidParams; })) orelse return error.InvalidParams;
const bc = cmd.browser_context orelse return error.BrowserContextNotLoaded; const bc = cmd.browser_context orelse return error.BrowserContextNotLoaded;
if (params.enabled) {
try bc.lifecycleEventsEnable(); if (params.enabled == false) {
} else {
bc.lifecycleEventsDisable(); bc.lifecycleEventsDisable();
return cmd.sendResult(null, .{});
} }
// Enable lifecycle events.
try bc.lifecycleEventsEnable();
// When we enable lifecycle events, we must dispatch events for all
// attached targets.
const page = bc.session.currentPage() orelse return error.PageNotLoaded;
if (page._load_state == .complete) {
const now = timestampF(.monotonic);
const http_client = page._session.browser.http_client;
try sendPageLifecycle(bc, "DOMContentLoaded", now);
try sendPageLifecycle(bc, "load", now);
const http_active = http_client.active;
const total_network_activity = http_active + http_client.intercepted;
if (page._notified_network_almost_idle.check(total_network_activity <= 2)) {
try sendPageLifecycle(bc, "networkAlmostIdle", now);
}
if (page._notified_network_idle.check(total_network_activity == 0)) {
try sendPageLifecycle(bc, "networkIdle", now);
}
}
return cmd.sendResult(null, .{}); return cmd.sendResult(null, .{});
} }

View File

@@ -109,7 +109,7 @@ fn disposeBrowserContext(cmd: anytype) !void {
fn createTarget(cmd: anytype) !void { fn createTarget(cmd: anytype) !void {
const params = (try cmd.params(struct { const params = (try cmd.params(struct {
// url: []const u8, url: [:0]const u8 = "about:blank",
// width: ?u64 = null, // width: ?u64 = null,
// height: ?u64 = null, // height: ?u64 = null,
browserContextId: ?[]const u8 = null, browserContextId: ?[]const u8 = null,
@@ -168,7 +168,7 @@ fn createTarget(cmd: anytype) !void {
.targetInfo = TargetInfo{ .targetInfo = TargetInfo{
.attached = false, .attached = false,
.targetId = target_id, .targetId = target_id,
.title = "about:blank", .title = params.url,
.browserContextId = bc.id, .browserContextId = bc.id,
.url = "about:blank", .url = "about:blank",
}, },
@@ -179,6 +179,10 @@ fn createTarget(cmd: anytype) !void {
try doAttachtoTarget(cmd, target_id); try doAttachtoTarget(cmd, target_id);
} }
try page.navigate(params.url, .{
.reason = .address_bar,
});
try cmd.sendResult(.{ try cmd.sendResult(.{
.targetId = target_id, .targetId = target_id,
}, .{}); }, .{});
@@ -518,7 +522,7 @@ test "cdp.target: createTarget" {
{ {
var ctx = testing.context(); var ctx = testing.context();
defer ctx.deinit(); defer ctx.deinit();
try ctx.processMessage(.{ .id = 10, .method = "Target.createTarget", .params = .{ .url = "about/blank" } }); try ctx.processMessage(.{ .id = 10, .method = "Target.createTarget", .params = .{ .url = "about:blank" } });
// should create a browser context // should create a browser context
const bc = ctx.cdp().browser_context.?; const bc = ctx.cdp().browser_context.?;
@@ -530,7 +534,7 @@ test "cdp.target: createTarget" {
defer ctx.deinit(); defer ctx.deinit();
// active auto attach to get the Target.attachedToTarget event. // active auto attach to get the Target.attachedToTarget event.
try ctx.processMessage(.{ .id = 9, .method = "Target.setAutoAttach", .params = .{ .autoAttach = true, .waitForDebuggerOnStart = false } }); try ctx.processMessage(.{ .id = 9, .method = "Target.setAutoAttach", .params = .{ .autoAttach = true, .waitForDebuggerOnStart = false } });
try ctx.processMessage(.{ .id = 10, .method = "Target.createTarget", .params = .{ .url = "about/blank" } }); try ctx.processMessage(.{ .id = 10, .method = "Target.createTarget", .params = .{ .url = "about:blank" } });
// should create a browser context // should create a browser context
const bc = ctx.cdp().browser_context.?; const bc = ctx.cdp().browser_context.?;