Merge pull request #1171 from lightpanda-io/cdp-lifecycle

support url on createTarget and send lifecycle events
This commit is contained in:
Pierre Tachoire
2025-10-24 08:33:11 +02:00
committed by GitHub
4 changed files with 53 additions and 13 deletions

View File

@@ -549,14 +549,31 @@ pub const Page = struct {
.body = opts.body != null, .body = opts.body != null,
}); });
// if the url is about:blank, nothing to do. // if the url is about:blank, we load an empty HTML document in the
// page and dispatch the events.
if (std.mem.eql(u8, "about:blank", request_url)) { if (std.mem.eql(u8, "about:blank", request_url)) {
const html_doc = try parser.documentHTMLParseFromStr(""); const html_doc = try parser.documentHTMLParseFromStr("");
try self.setDocument(html_doc); try self.setDocument(html_doc);
// Assume we parsed the document.
// It's important to force a reset during the following navigation.
self.mode = .parsed;
// We do not processHTMLDoc here as we know we don't have any scripts // We do not processHTMLDoc here as we know we don't have any scripts
// This assumption may be false when CDP Page.addScriptToEvaluateOnNewDocument is implemented // This assumption may be false when CDP Page.addScriptToEvaluateOnNewDocument is implemented
try HTMLDocument.documentIsComplete(self.window.document, self); self.documentIsComplete();
self.session.browser.notification.dispatch(.page_navigate, &.{
.opts = opts,
.url = request_url,
.timestamp = timestamp(),
});
self.session.browser.notification.dispatch(.page_navigated, &.{
.url = request_url,
.timestamp = timestamp(),
});
return; return;
} }

View File

@@ -18,6 +18,7 @@
const std = @import("std"); const std = @import("std");
const Page = @import("../../browser/page.zig").Page; const Page = @import("../../browser/page.zig").Page;
const timestampF = @import("../../datetime.zig").timestamp;
const Notification = @import("../../notification.zig").Notification; const Notification = @import("../../notification.zig").Notification;
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
@@ -82,11 +83,33 @@ 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) {
try sendPageLifecycle(bc, "DOMContentLoaded", timestampF());
try sendPageLifecycle(bc, "load", timestampF());
const http_active = page.http_client.active;
const total_network_activity = http_active + page.http_client.intercepted;
if (page.notified_network_almost_idle.check(total_network_activity <= 2)) {
try sendPageLifecycle(bc, "networkAlmostIdle", timestampF());
}
if (page.notified_network_idle.check(total_network_activity == 0)) {
try sendPageLifecycle(bc, "networkIdle", timestampF());
}
}
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: []const u8 = "about:blank",
// width: ?u64 = null, // width: ?u64 = null,
// height: ?u64 = null, // height: ?u64 = null,
browserContextId: ?[]const u8 = null, browserContextId: ?[]const u8 = null,
@@ -167,7 +167,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",
}, },
@@ -178,6 +178,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,
}, .{}); }, .{});
@@ -517,7 +521,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.?;
@@ -529,7 +533,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.?;

View File

@@ -338,8 +338,6 @@ pub fn restoreOriginalProxy(self: *Client) !void {
// Enable TLS verification on all connections. // Enable TLS verification on all connections.
pub fn enableTlsVerify(self: *const Client) !void { pub fn enableTlsVerify(self: *const Client) !void {
try self.ensureNoActiveConnection();
for (self.handles.handles) |*h| { for (self.handles.handles) |*h| {
const easy = h.conn.easy; const easy = h.conn.easy;
@@ -355,8 +353,6 @@ pub fn enableTlsVerify(self: *const Client) !void {
// Disable TLS verification on all connections. // Disable TLS verification on all connections.
pub fn disableTlsVerify(self: *const Client) !void { pub fn disableTlsVerify(self: *const Client) !void {
try self.ensureNoActiveConnection();
for (self.handles.handles) |*h| { for (self.handles.handles) |*h| {
const easy = h.conn.easy; const easy = h.conn.easy;