Skip to content

Commit 73bb14e

Browse files
Merge pull request #285 from lightpanda-io/cdp-cdpcli
cdp: cdpcli compatibility
2 parents cb8b80c + daf4236 commit 73bb14e

File tree

7 files changed

+88
-33
lines changed

7 files changed

+88
-33
lines changed

src/browser/browser.zig

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,31 @@ pub const Page = struct {
214214
};
215215
}
216216

217+
// start js env.
218+
// - auxData: extra data forwarded to the Inspector
219+
// see Inspector.contextCreated
220+
pub fn start(self: *Page, auxData: ?[]const u8) !void {
221+
// start JS env
222+
log.debug("start js env", .{});
223+
try self.session.env.start();
224+
225+
// register the module loader
226+
try self.session.env.setModuleLoadFn(self.session, Session.fetchModule);
227+
228+
// add global objects
229+
log.debug("setup global env", .{});
230+
try self.session.env.bindGlobal(&self.session.window);
231+
232+
// load polyfills
233+
try polyfill.load(self.arena.allocator(), self.session.env);
234+
235+
// inspector
236+
if (self.session.inspector) |inspector| {
237+
log.debug("inspector context created", .{});
238+
inspector.contextCreated(self.session.env, "", self.origin orelse "://", auxData);
239+
}
240+
}
241+
217242
// reset js env and mem arena.
218243
pub fn end(self: *Page) void {
219244
self.session.env.stop();
@@ -373,17 +398,6 @@ pub const Page = struct {
373398

374399
// https://html.spec.whatwg.org/#read-html
375400

376-
// start JS env
377-
// TODO load the js env concurrently with the HTML parsing.
378-
log.debug("start js env", .{});
379-
try self.session.env.start();
380-
381-
// register the module loader
382-
try self.session.env.setModuleLoadFn(self.session, Session.fetchModule);
383-
384-
// load polyfills
385-
try polyfill.load(alloc, self.session.env);
386-
387401
// inspector
388402
if (self.session.inspector) |inspector| {
389403
inspector.contextCreated(self.session.env, "", self.origin.?, auxData);
@@ -395,10 +409,6 @@ pub const Page = struct {
395409
.httpClient = &self.session.httpClient,
396410
});
397411

398-
// add global objects
399-
log.debug("setup global env", .{});
400-
try self.session.env.bindGlobal(&self.session.window);
401-
402412
// browse the DOM tree to retrieve scripts
403413
// TODO execute the synchronous scripts during the HTL parsing.
404414
// TODO fetch the script resources concurrently but execute them in the

src/cdp/cdp.zig

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ pub fn dispatch(
121121
pub const State = struct {
122122
executionContextId: u32 = 0,
123123
contextID: ?[]const u8 = null,
124+
sessionID: ?[]const u8 = null,
124125
frameID: []const u8 = FrameID,
125126
url: []const u8 = URLBase,
126127
securityOrigin: []const u8 = URLBase,
@@ -221,11 +222,11 @@ pub fn sendEvent(
221222
// ------
222223

223224
// TODO: hard coded IDs
224-
pub const BrowserSessionID = "9559320D92474062597D9875C664CAC0";
225-
pub const ContextSessionID = "4FDC2CB760A23A220497A05C95417CF4";
225+
pub const BrowserSessionID = "BROWSERSESSIONID597D9875C664CAC0";
226+
pub const ContextSessionID = "CONTEXTSESSIONID0497A05C95417CF4";
226227
pub const URLBase = "chrome://newtab/";
227-
pub const FrameID = "90D14BBD8AED408A0467AC93100BCDBE";
228-
pub const LoaderID = "CFC8BED824DD2FD56CF1EF33C965C79C";
228+
pub const LoaderID = "LOADERID24DD2FD56CF1EF33C965C79C";
229+
pub const FrameID = "FRAMEIDD8AED408A0467AC93100BCDBE";
229230

230231
pub const TimestampEvent = struct {
231232
timestamp: f64,

src/cdp/page.zig

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -331,8 +331,9 @@ fn navigate(
331331
// TODO: noop event, we have no env context at this point, is it necesarry?
332332
try sendEvent(alloc, ctx, "Runtime.executionContextsCleared", void, {}, input.sessionId);
333333

334-
// Launch navigate
335-
const p = try ctx.browser.session.createPage();
334+
// Launch navigate, the page must have been created by a
335+
// target.createTarget.
336+
var p = ctx.browser.session.page orelse return error.NoPage;
336337
ctx.state.executionContextId += 1;
337338
const auxData = try std.fmt.allocPrint(
338339
alloc,

src/cdp/runtime.zig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ const result = cdp.result;
2828
const IncomingMessage = @import("msg.zig").IncomingMessage;
2929
const Input = @import("msg.zig").Input;
3030
const stringify = cdp.stringify;
31+
const target = @import("target.zig");
3132

3233
const log = std.log.scoped(.cdp);
3334

@@ -116,6 +117,8 @@ fn sendInspector(
116117
}
117118
}
118119

120+
ctx.state.sessionID = msg.sessionId;
121+
119122
// remove awaitPromise true params
120123
// TODO: delete when Promise are correctly handled by zig-js-runtime
121124
if (method == .callFunctionOn or method == .evaluate) {

src/cdp/target.zig

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ const Methods = enum {
3939
createTarget,
4040
closeTarget,
4141
sendMessageToTarget,
42+
detachFromTarget,
4243
};
4344

4445
pub fn target(
@@ -60,13 +61,14 @@ pub fn target(
6061
.createTarget => createTarget(alloc, msg, ctx),
6162
.closeTarget => closeTarget(alloc, msg, ctx),
6263
.sendMessageToTarget => sendMessageToTarget(alloc, msg, ctx),
64+
.detachFromTarget => detachFromTarget(alloc, msg, ctx),
6365
};
6466
}
6567

6668
// TODO: hard coded IDs
67-
const PageTargetID = "CFCD6EC01573CF29BB638E9DC0F52DDC";
68-
const BrowserTargetID = "2d2bdef9-1c95-416f-8c0e-83f3ab73a30c";
69-
const BrowserContextID = "65618675CB7D3585A95049E9DFE95EA9";
69+
pub const PageTargetID = "PAGETARGETIDB638E9DC0F52DDC";
70+
pub const BrowserTargetID = "browser9-targ-et6f-id0e-83f3ab73a30c";
71+
pub const BrowserContextID = "BROWSERCONTEXTIDA95049E9DFE95EA9";
7072

7173
// TODO: noop method
7274
fn setDiscoverTargets(
@@ -138,7 +140,7 @@ fn setAutoAttach(
138140
.sessionId = cdp.BrowserSessionID,
139141
.targetInfo = .{
140142
.targetId = PageTargetID,
141-
.title = "New Incognito tab",
143+
.title = "about:blank",
142144
.url = cdp.URLBase,
143145
.browserContextId = BrowserContextID,
144146
},
@@ -171,8 +173,8 @@ fn attachToTarget(
171173
const attached = AttachToTarget{
172174
.sessionId = cdp.BrowserSessionID,
173175
.targetInfo = .{
174-
.targetId = PageTargetID,
175-
.title = "New Incognito tab",
176+
.targetId = input.params.targetId,
177+
.title = "about:blank",
176178
.url = cdp.URLBase,
177179
.browserContextId = BrowserContextID,
178180
},
@@ -185,7 +187,7 @@ fn attachToTarget(
185187
sessionId: []const u8,
186188
};
187189
const output = SessionId{
188-
.sessionId = input.sessionId orelse BrowserContextID,
190+
.sessionId = input.sessionId orelse cdp.BrowserSessionID,
189191
};
190192
return result(alloc, input.id, SessionId, output, null);
191193
}
@@ -252,7 +254,7 @@ fn getBrowserContexts(
252254
return result(alloc, input.id, Resp, resp, null);
253255
}
254256

255-
const ContextID = "22648B09EDCCDD11109E2D4FEFBE4F89";
257+
const ContextID = "CONTEXTIDDCCDD11109E2D4FEFBE4F89";
256258

257259
// TODO: noop method
258260
fn createBrowserContext(
@@ -313,8 +315,8 @@ fn disposeBrowserContext(
313315
}
314316

315317
// TODO: hard coded IDs
316-
const TargetID = "57356548460A8F29706A2ADF14316298";
317-
const LoaderID = "DD4A76F842AA389647D702B4D805F49A";
318+
const TargetID = "TARGETID460A8F29706A2ADF14316298";
319+
const LoaderID = "LOADERID42AA389647D702B4D805F49A";
318320

319321
fn createTarget(
320322
alloc: std.mem.Allocator,
@@ -342,6 +344,23 @@ fn createTarget(
342344
ctx.state.securityOrigin = "://";
343345
ctx.state.secureContextType = "InsecureScheme";
344346
ctx.state.loaderID = LoaderID;
347+
ctx.state.sessionID = msg.sessionId;
348+
349+
// TODO stop the previous page instead?
350+
if (ctx.browser.session.page != null) return error.pageAlreadyExists;
351+
352+
// create the page
353+
const p = try ctx.browser.session.createPage();
354+
ctx.state.executionContextId += 1;
355+
// start the js env
356+
const auxData = try std.fmt.allocPrint(
357+
alloc,
358+
// NOTE: we assume this is the default web page
359+
"{{\"isDefault\":true,\"type\":\"default\",\"frameId\":\"{s}\"}}",
360+
.{ctx.state.frameID},
361+
);
362+
defer alloc.free(auxData);
363+
try p.start(auxData);
345364

346365
// send targetCreated event
347366
const created = TargetCreated{
@@ -361,9 +380,10 @@ fn createTarget(
361380
.sessionId = cdp.ContextSessionID,
362381
.targetInfo = .{
363382
.targetId = ctx.state.frameID,
364-
.title = "",
383+
.title = "about:blank",
365384
.url = ctx.state.url,
366385
.browserContextId = input.params.browserContextId orelse ContextID,
386+
.attached = true,
367387
},
368388
.waitingForDebugger = true,
369389
};
@@ -438,6 +458,8 @@ fn closeTarget(
438458
null,
439459
);
440460

461+
if (ctx.browser.session.page != null) ctx.browser.session.page.?.end();
462+
441463
return "";
442464
}
443465

@@ -484,3 +506,18 @@ fn sendMessageToTarget(
484506

485507
return "";
486508
}
509+
510+
// noop
511+
fn detachFromTarget(
512+
alloc: std.mem.Allocator,
513+
msg: *IncomingMessage,
514+
_: *Ctx,
515+
) ![]const u8 {
516+
// input
517+
const input = try Input(void).get(alloc, msg);
518+
defer input.deinit();
519+
log.debug("Req > id {d}, method {s}", .{ input.id, "target.detachFromTarget" });
520+
521+
// output
522+
return result(alloc, input.id, bool, true, input.sessionId);
523+
}

src/main.zig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,8 @@ pub fn main() !void {
326326

327327
// page
328328
const page = try browser.session.createPage();
329+
try page.start(null);
330+
defer page.end();
329331

330332
_ = page.navigate(opts.url, null) catch |err| switch (err) {
331333
error.UnsupportedUriScheme, error.UriMissingHost => {

src/server.zig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ pub const Ctx = struct {
175175
self.do(parts.msg) catch |err| {
176176
if (err != error.Closed) {
177177
log.err("do error: {any}", .{err});
178+
log.debug("last msg: {s}", .{parts.msg});
178179
}
179180
};
180181
}
@@ -347,7 +348,7 @@ pub const Ctx = struct {
347348
const s = try std.fmt.allocPrint(
348349
allocator,
349350
tpl,
350-
.{ msg_open, cdp.ContextSessionID },
351+
.{ msg_open, ctx.state.sessionID orelse cdp.ContextSessionID },
351352
);
352353

353354
try ctx.send(s);

0 commit comments

Comments
 (0)