mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-02-04 14:33:47 +00:00
backport a variety of smaller CDP changes
This commit is contained in:
@@ -283,6 +283,13 @@ fn registerBackgroundTasks(self: *Page) !void {
|
|||||||
}.runMessageLoop, 250, .{ .name = "page.messageLoop" });
|
}.runMessageLoop, 250, .{ .name = "page.messageLoop" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn getTitle(self: *Page) !?[]const u8 {
|
||||||
|
if (self.window._document.is(Document.HTMLDocument)) |html_doc| {
|
||||||
|
return try html_doc.getTitle(self);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn navigate(self: *Page, request_url: [:0]const u8, opts: NavigateOpts, kind: NavigationKind) !void {
|
pub fn navigate(self: *Page, request_url: [:0]const u8, opts: NavigateOpts, kind: NavigationKind) !void {
|
||||||
const session = self._session;
|
const session = self._session;
|
||||||
|
|
||||||
|
|||||||
@@ -469,6 +469,14 @@ pub fn BrowserContext(comptime CDP_T: type) type {
|
|||||||
return if (url.len == 0) null else url;
|
return if (url.len == 0) null else url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn getTitle(self: *const Self) ?[]const u8 {
|
||||||
|
const page = self.session.currentPage() orelse return null;
|
||||||
|
return page.getTitle() catch |err| {
|
||||||
|
log.err(.cdp, "page title", .{ .err = err });
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub fn networkEnable(self: *Self) !void {
|
pub fn networkEnable(self: *Self) !void {
|
||||||
try self.cdp.browser.notification.register(.http_request_fail, self, onHttpRequestFail);
|
try self.cdp.browser.notification.register(.http_request_fail, self, onHttpRequestFail);
|
||||||
try self.cdp.browser.notification.register(.http_request_start, self, onHttpRequestStart);
|
try self.cdp.browser.notification.register(.http_request_start, self, onHttpRequestStart);
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ pub fn processMessage(cmd: anytype) !void {
|
|||||||
createIsolatedWorld,
|
createIsolatedWorld,
|
||||||
navigate,
|
navigate,
|
||||||
stopLoading,
|
stopLoading,
|
||||||
|
close,
|
||||||
}, cmd.input.action) orelse return error.UnknownMethod;
|
}, cmd.input.action) orelse return error.UnknownMethod;
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
@@ -43,6 +44,7 @@ pub fn processMessage(cmd: anytype) !void {
|
|||||||
.createIsolatedWorld => return createIsolatedWorld(cmd),
|
.createIsolatedWorld => return createIsolatedWorld(cmd),
|
||||||
.navigate => return navigate(cmd),
|
.navigate => return navigate(cmd),
|
||||||
.stopLoading => return cmd.sendResult(null, .{}),
|
.stopLoading => return cmd.sendResult(null, .{}),
|
||||||
|
.close => return close(cmd),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,6 +135,43 @@ fn addScriptToEvaluateOnNewDocument(cmd: anytype) !void {
|
|||||||
}, .{});
|
}, .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn close(cmd: anytype) !void {
|
||||||
|
const bc = cmd.browser_context orelse return error.BrowserContextNotLoaded;
|
||||||
|
|
||||||
|
const target_id = bc.target_id orelse return error.TargetNotLoaded;
|
||||||
|
|
||||||
|
// can't be null if we have a target_id
|
||||||
|
std.debug.assert(bc.session.page != null);
|
||||||
|
|
||||||
|
try cmd.sendResult(.{}, .{});
|
||||||
|
|
||||||
|
// Following code is similar to target.closeTarget
|
||||||
|
//
|
||||||
|
// could be null, created but never attached
|
||||||
|
if (bc.session_id) |session_id| {
|
||||||
|
// Inspector.detached event
|
||||||
|
try cmd.sendEvent("Inspector.detached", .{
|
||||||
|
.reason = "Render process gone.",
|
||||||
|
}, .{ .session_id = session_id });
|
||||||
|
|
||||||
|
// detachedFromTarget event
|
||||||
|
try cmd.sendEvent("Target.detachedFromTarget", .{
|
||||||
|
.targetId = target_id,
|
||||||
|
.sessionId = session_id,
|
||||||
|
.reason = "Render process gone.",
|
||||||
|
}, .{});
|
||||||
|
|
||||||
|
bc.session_id = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
bc.session.removePage();
|
||||||
|
for (bc.isolated_worlds.items) |*world| {
|
||||||
|
world.deinit();
|
||||||
|
}
|
||||||
|
bc.isolated_worlds.clearRetainingCapacity();
|
||||||
|
bc.target_id = null;
|
||||||
|
}
|
||||||
|
|
||||||
fn createIsolatedWorld(cmd: anytype) !void {
|
fn createIsolatedWorld(cmd: anytype) !void {
|
||||||
const params = (try cmd.params(struct {
|
const params = (try cmd.params(struct {
|
||||||
frameId: []const u8,
|
frameId: []const u8,
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ const LOADER_ID = "LOADERID42AA389647D702B4D805F49A";
|
|||||||
|
|
||||||
pub fn processMessage(cmd: anytype) !void {
|
pub fn processMessage(cmd: anytype) !void {
|
||||||
const action = std.meta.stringToEnum(enum {
|
const action = std.meta.stringToEnum(enum {
|
||||||
|
getTargets,
|
||||||
attachToTarget,
|
attachToTarget,
|
||||||
closeTarget,
|
closeTarget,
|
||||||
createBrowserContext,
|
createBrowserContext,
|
||||||
@@ -38,6 +39,7 @@ pub fn processMessage(cmd: anytype) !void {
|
|||||||
}, cmd.input.action) orelse return error.UnknownMethod;
|
}, cmd.input.action) orelse return error.UnknownMethod;
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
|
.getTargets => return getTargets(cmd),
|
||||||
.attachToTarget => return attachToTarget(cmd),
|
.attachToTarget => return attachToTarget(cmd),
|
||||||
.closeTarget => return closeTarget(cmd),
|
.closeTarget => return closeTarget(cmd),
|
||||||
.createBrowserContext => return createBrowserContext(cmd),
|
.createBrowserContext => return createBrowserContext(cmd),
|
||||||
@@ -52,6 +54,31 @@ pub fn processMessage(cmd: anytype) !void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn getTargets(cmd: anytype) !void {
|
||||||
|
// Some clients like Stagehand expects to have an existing context.
|
||||||
|
const bc = cmd.browser_context orelse cmd.createBrowserContext() catch |err| switch (err) {
|
||||||
|
error.AlreadyExists => unreachable,
|
||||||
|
else => return err,
|
||||||
|
};
|
||||||
|
|
||||||
|
const target_id = bc.target_id orelse {
|
||||||
|
return cmd.sendResult(.{
|
||||||
|
.targetInfos = [_]TargetInfo{},
|
||||||
|
}, .{ .include_session_id = false });
|
||||||
|
};
|
||||||
|
|
||||||
|
return cmd.sendResult(.{
|
||||||
|
.targetInfos = [_]TargetInfo{.{
|
||||||
|
.targetId = target_id,
|
||||||
|
.type = "page",
|
||||||
|
.title = bc.getTitle() orelse "about:blank",
|
||||||
|
.url = bc.getURL() orelse "about:blank",
|
||||||
|
.attached = true,
|
||||||
|
.canAccessOpener = false,
|
||||||
|
}},
|
||||||
|
}, .{ .include_session_id = false });
|
||||||
|
}
|
||||||
|
|
||||||
fn getBrowserContexts(cmd: anytype) !void {
|
fn getBrowserContexts(cmd: anytype) !void {
|
||||||
var browser_context_ids: []const []const u8 = undefined;
|
var browser_context_ids: []const []const u8 = undefined;
|
||||||
if (cmd.browser_context) |bc| {
|
if (cmd.browser_context) |bc| {
|
||||||
@@ -168,7 +195,7 @@ fn createTarget(cmd: anytype) !void {
|
|||||||
.targetInfo = TargetInfo{
|
.targetInfo = TargetInfo{
|
||||||
.attached = false,
|
.attached = false,
|
||||||
.targetId = target_id,
|
.targetId = target_id,
|
||||||
.title = params.url,
|
.title = "about:blank",
|
||||||
.browserContextId = bc.id,
|
.browserContextId = bc.id,
|
||||||
.url = "about:blank",
|
.url = "about:blank",
|
||||||
},
|
},
|
||||||
@@ -179,11 +206,13 @@ fn createTarget(cmd: anytype) !void {
|
|||||||
try doAttachtoTarget(cmd, target_id);
|
try doAttachtoTarget(cmd, target_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
try page.navigate(
|
if (!std.mem.eql(u8, "about:blank", params.url)) {
|
||||||
params.url,
|
try page.navigate(
|
||||||
.{ .reason = .address_bar },
|
params.url,
|
||||||
.{ .push = null },
|
.{ .reason = .address_bar },
|
||||||
);
|
.{ .push = null },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
try cmd.sendResult(.{
|
try cmd.sendResult(.{
|
||||||
.targetId = target_id,
|
.targetId = target_id,
|
||||||
@@ -206,7 +235,9 @@ fn attachToTarget(cmd: anytype) !void {
|
|||||||
return error.SessionAlreadyLoaded;
|
return error.SessionAlreadyLoaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
try doAttachtoTarget(cmd, target_id);
|
if (bc.session_id == null) {
|
||||||
|
try doAttachtoTarget(cmd, target_id);
|
||||||
|
}
|
||||||
|
|
||||||
return cmd.sendResult(
|
return cmd.sendResult(
|
||||||
.{ .sessionId = bc.session_id },
|
.{ .sessionId = bc.session_id },
|
||||||
@@ -272,8 +303,8 @@ fn getTargetInfo(cmd: anytype) !void {
|
|||||||
.targetInfo = TargetInfo{
|
.targetInfo = TargetInfo{
|
||||||
.targetId = target_id,
|
.targetId = target_id,
|
||||||
.type = "page",
|
.type = "page",
|
||||||
.title = "",
|
.title = bc.getTitle() orelse "about:blank",
|
||||||
.url = "",
|
.url = bc.getURL() orelse "about:blank",
|
||||||
.attached = true,
|
.attached = true,
|
||||||
.canAccessOpener = false,
|
.canAccessOpener = false,
|
||||||
},
|
},
|
||||||
@@ -284,8 +315,8 @@ fn getTargetInfo(cmd: anytype) !void {
|
|||||||
.targetInfo = TargetInfo{
|
.targetInfo = TargetInfo{
|
||||||
.targetId = "TID-STARTUP-B",
|
.targetId = "TID-STARTUP-B",
|
||||||
.type = "browser",
|
.type = "browser",
|
||||||
.title = "",
|
.title = "about:blank",
|
||||||
.url = "",
|
.url = "about:blank",
|
||||||
.attached = true,
|
.attached = true,
|
||||||
.canAccessOpener = false,
|
.canAccessOpener = false,
|
||||||
},
|
},
|
||||||
@@ -631,8 +662,8 @@ test "cdp.target: getTargetInfo" {
|
|||||||
try ctx.expectSentResult(.{
|
try ctx.expectSentResult(.{
|
||||||
.targetInfo = .{
|
.targetInfo = .{
|
||||||
.type = "browser",
|
.type = "browser",
|
||||||
.title = "",
|
.title = "about:blank",
|
||||||
.url = "",
|
.url = "about:blank",
|
||||||
.attached = true,
|
.attached = true,
|
||||||
.canAccessOpener = false,
|
.canAccessOpener = false,
|
||||||
},
|
},
|
||||||
@@ -665,7 +696,7 @@ test "cdp.target: getTargetInfo" {
|
|||||||
.targetId = "TID-A",
|
.targetId = "TID-A",
|
||||||
.type = "page",
|
.type = "page",
|
||||||
.title = "",
|
.title = "",
|
||||||
.url = "",
|
.url = "about:blank",
|
||||||
.attached = true,
|
.attached = true,
|
||||||
.canAccessOpener = false,
|
.canAccessOpener = false,
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user