mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 07:03:29 +00:00
Merge pull request #285 from lightpanda-io/cdp-cdpcli
Some checks failed
wpt / web platform tests (push) Has been cancelled
zig-test / zig build dev (push) Has been cancelled
zig-test / zig build release (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
wpt / perf-fmt (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
zig-test / demo-puppeteer (push) Has been cancelled
Some checks failed
wpt / web platform tests (push) Has been cancelled
zig-test / zig build dev (push) Has been cancelled
zig-test / zig build release (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
wpt / perf-fmt (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
zig-test / demo-puppeteer (push) Has been cancelled
cdp: cdpcli compatibility
This commit is contained in:
@@ -214,6 +214,31 @@ pub const Page = struct {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// start js env.
|
||||||
|
// - auxData: extra data forwarded to the Inspector
|
||||||
|
// see Inspector.contextCreated
|
||||||
|
pub fn start(self: *Page, auxData: ?[]const u8) !void {
|
||||||
|
// start JS env
|
||||||
|
log.debug("start js env", .{});
|
||||||
|
try self.session.env.start();
|
||||||
|
|
||||||
|
// register the module loader
|
||||||
|
try self.session.env.setModuleLoadFn(self.session, Session.fetchModule);
|
||||||
|
|
||||||
|
// add global objects
|
||||||
|
log.debug("setup global env", .{});
|
||||||
|
try self.session.env.bindGlobal(&self.session.window);
|
||||||
|
|
||||||
|
// load polyfills
|
||||||
|
try polyfill.load(self.arena.allocator(), self.session.env);
|
||||||
|
|
||||||
|
// inspector
|
||||||
|
if (self.session.inspector) |inspector| {
|
||||||
|
log.debug("inspector context created", .{});
|
||||||
|
inspector.contextCreated(self.session.env, "", self.origin orelse "://", auxData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// reset js env and mem arena.
|
// reset js env and mem arena.
|
||||||
pub fn end(self: *Page) void {
|
pub fn end(self: *Page) void {
|
||||||
self.session.env.stop();
|
self.session.env.stop();
|
||||||
@@ -373,17 +398,6 @@ pub const Page = struct {
|
|||||||
|
|
||||||
// https://html.spec.whatwg.org/#read-html
|
// https://html.spec.whatwg.org/#read-html
|
||||||
|
|
||||||
// start JS env
|
|
||||||
// TODO load the js env concurrently with the HTML parsing.
|
|
||||||
log.debug("start js env", .{});
|
|
||||||
try self.session.env.start();
|
|
||||||
|
|
||||||
// register the module loader
|
|
||||||
try self.session.env.setModuleLoadFn(self.session, Session.fetchModule);
|
|
||||||
|
|
||||||
// load polyfills
|
|
||||||
try polyfill.load(alloc, self.session.env);
|
|
||||||
|
|
||||||
// inspector
|
// inspector
|
||||||
if (self.session.inspector) |inspector| {
|
if (self.session.inspector) |inspector| {
|
||||||
inspector.contextCreated(self.session.env, "", self.origin.?, auxData);
|
inspector.contextCreated(self.session.env, "", self.origin.?, auxData);
|
||||||
@@ -395,10 +409,6 @@ pub const Page = struct {
|
|||||||
.httpClient = &self.session.httpClient,
|
.httpClient = &self.session.httpClient,
|
||||||
});
|
});
|
||||||
|
|
||||||
// add global objects
|
|
||||||
log.debug("setup global env", .{});
|
|
||||||
try self.session.env.bindGlobal(&self.session.window);
|
|
||||||
|
|
||||||
// browse the DOM tree to retrieve scripts
|
// browse the DOM tree to retrieve scripts
|
||||||
// TODO execute the synchronous scripts during the HTL parsing.
|
// TODO execute the synchronous scripts during the HTL parsing.
|
||||||
// TODO fetch the script resources concurrently but execute them in the
|
// TODO fetch the script resources concurrently but execute them in the
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ pub fn dispatch(
|
|||||||
pub const State = struct {
|
pub const State = struct {
|
||||||
executionContextId: u32 = 0,
|
executionContextId: u32 = 0,
|
||||||
contextID: ?[]const u8 = null,
|
contextID: ?[]const u8 = null,
|
||||||
|
sessionID: ?[]const u8 = null,
|
||||||
frameID: []const u8 = FrameID,
|
frameID: []const u8 = FrameID,
|
||||||
url: []const u8 = URLBase,
|
url: []const u8 = URLBase,
|
||||||
securityOrigin: []const u8 = URLBase,
|
securityOrigin: []const u8 = URLBase,
|
||||||
@@ -221,11 +222,11 @@ pub fn sendEvent(
|
|||||||
// ------
|
// ------
|
||||||
|
|
||||||
// TODO: hard coded IDs
|
// TODO: hard coded IDs
|
||||||
pub const BrowserSessionID = "9559320D92474062597D9875C664CAC0";
|
pub const BrowserSessionID = "BROWSERSESSIONID597D9875C664CAC0";
|
||||||
pub const ContextSessionID = "4FDC2CB760A23A220497A05C95417CF4";
|
pub const ContextSessionID = "CONTEXTSESSIONID0497A05C95417CF4";
|
||||||
pub const URLBase = "chrome://newtab/";
|
pub const URLBase = "chrome://newtab/";
|
||||||
pub const FrameID = "90D14BBD8AED408A0467AC93100BCDBE";
|
pub const LoaderID = "LOADERID24DD2FD56CF1EF33C965C79C";
|
||||||
pub const LoaderID = "CFC8BED824DD2FD56CF1EF33C965C79C";
|
pub const FrameID = "FRAMEIDD8AED408A0467AC93100BCDBE";
|
||||||
|
|
||||||
pub const TimestampEvent = struct {
|
pub const TimestampEvent = struct {
|
||||||
timestamp: f64,
|
timestamp: f64,
|
||||||
|
|||||||
@@ -331,8 +331,9 @@ fn navigate(
|
|||||||
// TODO: noop event, we have no env context at this point, is it necesarry?
|
// TODO: noop event, we have no env context at this point, is it necesarry?
|
||||||
try sendEvent(alloc, ctx, "Runtime.executionContextsCleared", void, {}, input.sessionId);
|
try sendEvent(alloc, ctx, "Runtime.executionContextsCleared", void, {}, input.sessionId);
|
||||||
|
|
||||||
// Launch navigate
|
// Launch navigate, the page must have been created by a
|
||||||
const p = try ctx.browser.session.createPage();
|
// target.createTarget.
|
||||||
|
var p = ctx.browser.session.page orelse return error.NoPage;
|
||||||
ctx.state.executionContextId += 1;
|
ctx.state.executionContextId += 1;
|
||||||
const auxData = try std.fmt.allocPrint(
|
const auxData = try std.fmt.allocPrint(
|
||||||
alloc,
|
alloc,
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ const result = cdp.result;
|
|||||||
const IncomingMessage = @import("msg.zig").IncomingMessage;
|
const IncomingMessage = @import("msg.zig").IncomingMessage;
|
||||||
const Input = @import("msg.zig").Input;
|
const Input = @import("msg.zig").Input;
|
||||||
const stringify = cdp.stringify;
|
const stringify = cdp.stringify;
|
||||||
|
const target = @import("target.zig");
|
||||||
|
|
||||||
const log = std.log.scoped(.cdp);
|
const log = std.log.scoped(.cdp);
|
||||||
|
|
||||||
@@ -116,6 +117,8 @@ fn sendInspector(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx.state.sessionID = msg.sessionId;
|
||||||
|
|
||||||
// remove awaitPromise true params
|
// remove awaitPromise true params
|
||||||
// TODO: delete when Promise are correctly handled by zig-js-runtime
|
// TODO: delete when Promise are correctly handled by zig-js-runtime
|
||||||
if (method == .callFunctionOn or method == .evaluate) {
|
if (method == .callFunctionOn or method == .evaluate) {
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ const Methods = enum {
|
|||||||
createTarget,
|
createTarget,
|
||||||
closeTarget,
|
closeTarget,
|
||||||
sendMessageToTarget,
|
sendMessageToTarget,
|
||||||
|
detachFromTarget,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn target(
|
pub fn target(
|
||||||
@@ -60,13 +61,14 @@ pub fn target(
|
|||||||
.createTarget => createTarget(alloc, msg, ctx),
|
.createTarget => createTarget(alloc, msg, ctx),
|
||||||
.closeTarget => closeTarget(alloc, msg, ctx),
|
.closeTarget => closeTarget(alloc, msg, ctx),
|
||||||
.sendMessageToTarget => sendMessageToTarget(alloc, msg, ctx),
|
.sendMessageToTarget => sendMessageToTarget(alloc, msg, ctx),
|
||||||
|
.detachFromTarget => detachFromTarget(alloc, msg, ctx),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: hard coded IDs
|
// TODO: hard coded IDs
|
||||||
const PageTargetID = "CFCD6EC01573CF29BB638E9DC0F52DDC";
|
pub const PageTargetID = "PAGETARGETIDB638E9DC0F52DDC";
|
||||||
const BrowserTargetID = "2d2bdef9-1c95-416f-8c0e-83f3ab73a30c";
|
pub const BrowserTargetID = "browser9-targ-et6f-id0e-83f3ab73a30c";
|
||||||
const BrowserContextID = "65618675CB7D3585A95049E9DFE95EA9";
|
pub const BrowserContextID = "BROWSERCONTEXTIDA95049E9DFE95EA9";
|
||||||
|
|
||||||
// TODO: noop method
|
// TODO: noop method
|
||||||
fn setDiscoverTargets(
|
fn setDiscoverTargets(
|
||||||
@@ -138,7 +140,7 @@ fn setAutoAttach(
|
|||||||
.sessionId = cdp.BrowserSessionID,
|
.sessionId = cdp.BrowserSessionID,
|
||||||
.targetInfo = .{
|
.targetInfo = .{
|
||||||
.targetId = PageTargetID,
|
.targetId = PageTargetID,
|
||||||
.title = "New Incognito tab",
|
.title = "about:blank",
|
||||||
.url = cdp.URLBase,
|
.url = cdp.URLBase,
|
||||||
.browserContextId = BrowserContextID,
|
.browserContextId = BrowserContextID,
|
||||||
},
|
},
|
||||||
@@ -171,8 +173,8 @@ fn attachToTarget(
|
|||||||
const attached = AttachToTarget{
|
const attached = AttachToTarget{
|
||||||
.sessionId = cdp.BrowserSessionID,
|
.sessionId = cdp.BrowserSessionID,
|
||||||
.targetInfo = .{
|
.targetInfo = .{
|
||||||
.targetId = PageTargetID,
|
.targetId = input.params.targetId,
|
||||||
.title = "New Incognito tab",
|
.title = "about:blank",
|
||||||
.url = cdp.URLBase,
|
.url = cdp.URLBase,
|
||||||
.browserContextId = BrowserContextID,
|
.browserContextId = BrowserContextID,
|
||||||
},
|
},
|
||||||
@@ -185,7 +187,7 @@ fn attachToTarget(
|
|||||||
sessionId: []const u8,
|
sessionId: []const u8,
|
||||||
};
|
};
|
||||||
const output = SessionId{
|
const output = SessionId{
|
||||||
.sessionId = input.sessionId orelse BrowserContextID,
|
.sessionId = input.sessionId orelse cdp.BrowserSessionID,
|
||||||
};
|
};
|
||||||
return result(alloc, input.id, SessionId, output, null);
|
return result(alloc, input.id, SessionId, output, null);
|
||||||
}
|
}
|
||||||
@@ -252,7 +254,7 @@ fn getBrowserContexts(
|
|||||||
return result(alloc, input.id, Resp, resp, null);
|
return result(alloc, input.id, Resp, resp, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ContextID = "22648B09EDCCDD11109E2D4FEFBE4F89";
|
const ContextID = "CONTEXTIDDCCDD11109E2D4FEFBE4F89";
|
||||||
|
|
||||||
// TODO: noop method
|
// TODO: noop method
|
||||||
fn createBrowserContext(
|
fn createBrowserContext(
|
||||||
@@ -313,8 +315,8 @@ fn disposeBrowserContext(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: hard coded IDs
|
// TODO: hard coded IDs
|
||||||
const TargetID = "57356548460A8F29706A2ADF14316298";
|
const TargetID = "TARGETID460A8F29706A2ADF14316298";
|
||||||
const LoaderID = "DD4A76F842AA389647D702B4D805F49A";
|
const LoaderID = "LOADERID42AA389647D702B4D805F49A";
|
||||||
|
|
||||||
fn createTarget(
|
fn createTarget(
|
||||||
alloc: std.mem.Allocator,
|
alloc: std.mem.Allocator,
|
||||||
@@ -342,6 +344,23 @@ fn createTarget(
|
|||||||
ctx.state.securityOrigin = "://";
|
ctx.state.securityOrigin = "://";
|
||||||
ctx.state.secureContextType = "InsecureScheme";
|
ctx.state.secureContextType = "InsecureScheme";
|
||||||
ctx.state.loaderID = LoaderID;
|
ctx.state.loaderID = LoaderID;
|
||||||
|
ctx.state.sessionID = msg.sessionId;
|
||||||
|
|
||||||
|
// TODO stop the previous page instead?
|
||||||
|
if (ctx.browser.session.page != null) return error.pageAlreadyExists;
|
||||||
|
|
||||||
|
// create the page
|
||||||
|
const p = try ctx.browser.session.createPage();
|
||||||
|
ctx.state.executionContextId += 1;
|
||||||
|
// start the js env
|
||||||
|
const auxData = try std.fmt.allocPrint(
|
||||||
|
alloc,
|
||||||
|
// NOTE: we assume this is the default web page
|
||||||
|
"{{\"isDefault\":true,\"type\":\"default\",\"frameId\":\"{s}\"}}",
|
||||||
|
.{ctx.state.frameID},
|
||||||
|
);
|
||||||
|
defer alloc.free(auxData);
|
||||||
|
try p.start(auxData);
|
||||||
|
|
||||||
// send targetCreated event
|
// send targetCreated event
|
||||||
const created = TargetCreated{
|
const created = TargetCreated{
|
||||||
@@ -361,9 +380,10 @@ fn createTarget(
|
|||||||
.sessionId = cdp.ContextSessionID,
|
.sessionId = cdp.ContextSessionID,
|
||||||
.targetInfo = .{
|
.targetInfo = .{
|
||||||
.targetId = ctx.state.frameID,
|
.targetId = ctx.state.frameID,
|
||||||
.title = "",
|
.title = "about:blank",
|
||||||
.url = ctx.state.url,
|
.url = ctx.state.url,
|
||||||
.browserContextId = input.params.browserContextId orelse ContextID,
|
.browserContextId = input.params.browserContextId orelse ContextID,
|
||||||
|
.attached = true,
|
||||||
},
|
},
|
||||||
.waitingForDebugger = true,
|
.waitingForDebugger = true,
|
||||||
};
|
};
|
||||||
@@ -438,6 +458,8 @@ fn closeTarget(
|
|||||||
null,
|
null,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (ctx.browser.session.page != null) ctx.browser.session.page.?.end();
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -484,3 +506,18 @@ fn sendMessageToTarget(
|
|||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// noop
|
||||||
|
fn detachFromTarget(
|
||||||
|
alloc: std.mem.Allocator,
|
||||||
|
msg: *IncomingMessage,
|
||||||
|
_: *Ctx,
|
||||||
|
) ![]const u8 {
|
||||||
|
// input
|
||||||
|
const input = try Input(void).get(alloc, msg);
|
||||||
|
defer input.deinit();
|
||||||
|
log.debug("Req > id {d}, method {s}", .{ input.id, "target.detachFromTarget" });
|
||||||
|
|
||||||
|
// output
|
||||||
|
return result(alloc, input.id, bool, true, input.sessionId);
|
||||||
|
}
|
||||||
|
|||||||
@@ -326,6 +326,8 @@ pub fn main() !void {
|
|||||||
|
|
||||||
// page
|
// page
|
||||||
const page = try browser.session.createPage();
|
const page = try browser.session.createPage();
|
||||||
|
try page.start(null);
|
||||||
|
defer page.end();
|
||||||
|
|
||||||
_ = page.navigate(opts.url, null) catch |err| switch (err) {
|
_ = page.navigate(opts.url, null) catch |err| switch (err) {
|
||||||
error.UnsupportedUriScheme, error.UriMissingHost => {
|
error.UnsupportedUriScheme, error.UriMissingHost => {
|
||||||
|
|||||||
@@ -175,6 +175,7 @@ pub const Ctx = struct {
|
|||||||
self.do(parts.msg) catch |err| {
|
self.do(parts.msg) catch |err| {
|
||||||
if (err != error.Closed) {
|
if (err != error.Closed) {
|
||||||
log.err("do error: {any}", .{err});
|
log.err("do error: {any}", .{err});
|
||||||
|
log.debug("last msg: {s}", .{parts.msg});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -347,7 +348,7 @@ pub const Ctx = struct {
|
|||||||
const s = try std.fmt.allocPrint(
|
const s = try std.fmt.allocPrint(
|
||||||
allocator,
|
allocator,
|
||||||
tpl,
|
tpl,
|
||||||
.{ msg_open, cdp.ContextSessionID },
|
.{ msg_open, ctx.state.sessionID orelse cdp.ContextSessionID },
|
||||||
);
|
);
|
||||||
|
|
||||||
try ctx.send(s);
|
try ctx.send(s);
|
||||||
|
|||||||
Reference in New Issue
Block a user