mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 15:13:28 +00:00
Merge pull request #404 from lightpanda-io/cdp-documentUpdated
Some checks are pending
wpt / web platform tests (push) Waiting to run
wpt / perf-fmt (push) Blocked by required conditions
zig-test / zig build dev (push) Waiting to run
zig-test / zig build release (push) Waiting to run
zig-test / zig test (push) Waiting to run
zig-test / perf-fmt (push) Blocked by required conditions
zig-test / demo-puppeteer (push) Blocked by required conditions
Some checks are pending
wpt / web platform tests (push) Waiting to run
wpt / perf-fmt (push) Blocked by required conditions
zig-test / zig build dev (push) Waiting to run
zig-test / zig build release (push) Waiting to run
zig-test / zig test (push) Waiting to run
zig-test / perf-fmt (push) Blocked by required conditions
zig-test / demo-puppeteer (push) Blocked by required conditions
cdp: dispatch a DOM.documentUpdated event
This commit is contained in:
@@ -82,6 +82,12 @@ pub const Browser = struct {
|
|||||||
self.session.deinit();
|
self.session.deinit();
|
||||||
try Session.init(&self.session, alloc, loop, uri);
|
try Session.init(&self.session, alloc, loop, uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn currentPage(self: *Browser) ?*Page {
|
||||||
|
if (self.session.page == null) return null;
|
||||||
|
|
||||||
|
return &self.session.page.?;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Session is like a browser's tab.
|
// Session is like a browser's tab.
|
||||||
@@ -147,7 +153,7 @@ pub const Session = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn deinit(self: *Session) void {
|
fn deinit(self: *Session) void {
|
||||||
if (self.page) |*p| p.end();
|
if (self.page) |*p| p.deinit();
|
||||||
|
|
||||||
if (self.inspector) |inspector| {
|
if (self.inspector) |inspector| {
|
||||||
inspector.deinit(self.alloc);
|
inspector.deinit(self.alloc);
|
||||||
@@ -259,6 +265,7 @@ pub const Page = struct {
|
|||||||
self.session.window.replaceLocation(&self.location) catch |e| {
|
self.session.window.replaceLocation(&self.location) catch |e| {
|
||||||
log.err("reset window location: {any}", .{e});
|
log.err("reset window location: {any}", .{e});
|
||||||
};
|
};
|
||||||
|
self.doc = null;
|
||||||
|
|
||||||
// clear netsurf memory arena.
|
// clear netsurf memory arena.
|
||||||
parser.deinit();
|
parser.deinit();
|
||||||
@@ -267,6 +274,7 @@ pub const Page = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Page) void {
|
pub fn deinit(self: *Page) void {
|
||||||
|
self.end();
|
||||||
self.arena.deinit();
|
self.arena.deinit();
|
||||||
self.session.page = null;
|
self.session.page = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ const IncomingMessage = @import("msg.zig").IncomingMessage;
|
|||||||
const Input = @import("msg.zig").Input;
|
const Input = @import("msg.zig").Input;
|
||||||
const inspector = @import("inspector.zig").inspector;
|
const inspector = @import("inspector.zig").inspector;
|
||||||
const dom = @import("dom.zig").dom;
|
const dom = @import("dom.zig").dom;
|
||||||
|
const cdpdom = @import("dom.zig");
|
||||||
const css = @import("css.zig").css;
|
const css = @import("css.zig").css;
|
||||||
const security = @import("security.zig").security;
|
const security = @import("security.zig").security;
|
||||||
|
|
||||||
@@ -129,6 +130,33 @@ pub const State = struct {
|
|||||||
loaderID: []const u8 = LoaderID,
|
loaderID: []const u8 = LoaderID,
|
||||||
|
|
||||||
page_life_cycle_events: bool = false, // TODO; Target based value
|
page_life_cycle_events: bool = false, // TODO; Target based value
|
||||||
|
|
||||||
|
// DOM
|
||||||
|
nodelist: cdpdom.NodeList,
|
||||||
|
nodesearchlist: cdpdom.NodeSearchList,
|
||||||
|
|
||||||
|
pub fn init(alloc: std.mem.Allocator) State {
|
||||||
|
return .{
|
||||||
|
.nodelist = cdpdom.NodeList.init(alloc),
|
||||||
|
.nodesearchlist = cdpdom.NodeSearchList.init(alloc),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: *State) void {
|
||||||
|
self.nodelist.deinit();
|
||||||
|
|
||||||
|
// deinit all node searches.
|
||||||
|
for (self.nodesearchlist.items) |*s| s.deinit();
|
||||||
|
self.nodesearchlist.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reset(self: *State) void {
|
||||||
|
self.nodelist.reset();
|
||||||
|
|
||||||
|
// deinit all node searches.
|
||||||
|
for (self.nodesearchlist.items) |*s| s.deinit();
|
||||||
|
self.nodesearchlist.clearAndFree();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Utils
|
// Utils
|
||||||
|
|||||||
283
src/cdp/dom.zig
283
src/cdp/dom.zig
@@ -24,11 +24,18 @@ const cdp = @import("cdp.zig");
|
|||||||
const result = cdp.result;
|
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 css = @import("../dom/css.zig");
|
||||||
|
|
||||||
|
const parser = @import("netsurf");
|
||||||
|
|
||||||
const log = std.log.scoped(.cdp);
|
const log = std.log.scoped(.cdp);
|
||||||
|
|
||||||
const Methods = enum {
|
const Methods = enum {
|
||||||
enable,
|
enable,
|
||||||
|
getDocument,
|
||||||
|
performSearch,
|
||||||
|
getSearchResults,
|
||||||
|
discardSearchResults,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn dom(
|
pub fn dom(
|
||||||
@@ -42,6 +49,10 @@ pub fn dom(
|
|||||||
|
|
||||||
return switch (method) {
|
return switch (method) {
|
||||||
.enable => enable(alloc, msg, ctx),
|
.enable => enable(alloc, msg, ctx),
|
||||||
|
.getDocument => getDocument(alloc, msg, ctx),
|
||||||
|
.performSearch => performSearch(alloc, msg, ctx),
|
||||||
|
.getSearchResults => getSearchResults(alloc, msg, ctx),
|
||||||
|
.discardSearchResults => discardSearchResults(alloc, msg, ctx),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,3 +68,275 @@ fn enable(
|
|||||||
|
|
||||||
return result(alloc, input.id, null, null, input.sessionId);
|
return result(alloc, input.id, null, null, input.sessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NodeList references tree nodes with an array id.
|
||||||
|
pub const NodeList = struct {
|
||||||
|
coll: List,
|
||||||
|
|
||||||
|
const List = std.ArrayList(*parser.Node);
|
||||||
|
|
||||||
|
pub fn init(alloc: std.mem.Allocator) NodeList {
|
||||||
|
return .{
|
||||||
|
.coll = List.init(alloc),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: *NodeList) void {
|
||||||
|
self.coll.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reset(self: *NodeList) void {
|
||||||
|
self.coll.clearAndFree();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set(self: *NodeList, node: *parser.Node) !NodeId {
|
||||||
|
for (self.coll.items, 0..) |n, i| {
|
||||||
|
if (n == node) return @intCast(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
try self.coll.append(node);
|
||||||
|
return @intCast(self.coll.items.len);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const NodeId = u32;
|
||||||
|
|
||||||
|
const Node = struct {
|
||||||
|
nodeId: NodeId,
|
||||||
|
parentId: ?NodeId = null,
|
||||||
|
backendNodeId: NodeId,
|
||||||
|
nodeType: u32,
|
||||||
|
nodeName: []const u8 = "",
|
||||||
|
localName: []const u8 = "",
|
||||||
|
nodeValue: []const u8 = "",
|
||||||
|
childNodeCount: ?u32 = null,
|
||||||
|
children: ?[]const Node = null,
|
||||||
|
documentURL: ?[]const u8 = null,
|
||||||
|
baseURL: ?[]const u8 = null,
|
||||||
|
xmlVersion: []const u8 = "",
|
||||||
|
compatibilityMode: []const u8 = "NoQuirksMode",
|
||||||
|
isScrollable: bool = false,
|
||||||
|
|
||||||
|
fn init(n: *parser.Node, nlist: *NodeList) !Node {
|
||||||
|
const id = try nlist.set(n);
|
||||||
|
return .{
|
||||||
|
.nodeId = id,
|
||||||
|
.backendNodeId = id,
|
||||||
|
.nodeType = @intFromEnum(try parser.nodeType(n)),
|
||||||
|
.nodeName = try parser.nodeName(n),
|
||||||
|
.localName = try parser.nodeLocalName(n),
|
||||||
|
.nodeValue = try parser.nodeValue(n) orelse "",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn initChildren(
|
||||||
|
self: *Node,
|
||||||
|
alloc: std.mem.Allocator,
|
||||||
|
n: *parser.Node,
|
||||||
|
nlist: *NodeList,
|
||||||
|
) !std.ArrayList(Node) {
|
||||||
|
const children = try parser.nodeGetChildNodes(n);
|
||||||
|
const ln = try parser.nodeListLength(children);
|
||||||
|
self.childNodeCount = ln;
|
||||||
|
|
||||||
|
var list = try std.ArrayList(Node).initCapacity(alloc, ln);
|
||||||
|
|
||||||
|
var i: u32 = 0;
|
||||||
|
while (i < ln) {
|
||||||
|
defer i += 1;
|
||||||
|
const child = try parser.nodeListItem(children, i) orelse continue;
|
||||||
|
try list.append(try Node.init(child, nlist));
|
||||||
|
}
|
||||||
|
|
||||||
|
self.children = list.items;
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://chromedevtools.github.io/devtools-protocol/tot/DOM/#method-getDocument
|
||||||
|
fn getDocument(
|
||||||
|
alloc: std.mem.Allocator,
|
||||||
|
msg: *IncomingMessage,
|
||||||
|
ctx: *Ctx,
|
||||||
|
) ![]const u8 {
|
||||||
|
// input
|
||||||
|
const Params = struct {
|
||||||
|
depth: ?u32 = null,
|
||||||
|
pierce: ?bool = null,
|
||||||
|
};
|
||||||
|
const input = try Input(Params).get(alloc, msg);
|
||||||
|
defer input.deinit();
|
||||||
|
std.debug.assert(input.sessionId != null);
|
||||||
|
log.debug("Req > id {d}, method {s}", .{ input.id, "DOM.getDocument" });
|
||||||
|
|
||||||
|
// retrieve the root node
|
||||||
|
const page = ctx.browser.currentPage() orelse return error.NoPage;
|
||||||
|
|
||||||
|
if (page.doc == null) return error.NoDocument;
|
||||||
|
|
||||||
|
const node = parser.documentToNode(page.doc.?);
|
||||||
|
var n = try Node.init(node, &ctx.state.nodelist);
|
||||||
|
var list = try n.initChildren(alloc, node, &ctx.state.nodelist);
|
||||||
|
defer list.deinit();
|
||||||
|
|
||||||
|
// output
|
||||||
|
const Resp = struct {
|
||||||
|
root: Node,
|
||||||
|
};
|
||||||
|
const resp: Resp = .{
|
||||||
|
.root = n,
|
||||||
|
};
|
||||||
|
|
||||||
|
const res = try result(alloc, input.id, Resp, resp, input.sessionId);
|
||||||
|
try ctx.send(res);
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const NodeSearch = struct {
|
||||||
|
coll: List,
|
||||||
|
name: []u8,
|
||||||
|
alloc: std.mem.Allocator,
|
||||||
|
|
||||||
|
var count: u8 = 0;
|
||||||
|
|
||||||
|
const List = std.ArrayListUnmanaged(NodeId);
|
||||||
|
|
||||||
|
pub fn initCapacity(alloc: std.mem.Allocator, ln: usize) !NodeSearch {
|
||||||
|
count += 1;
|
||||||
|
|
||||||
|
return .{
|
||||||
|
.alloc = alloc,
|
||||||
|
.coll = try List.initCapacity(alloc, ln),
|
||||||
|
.name = try std.fmt.allocPrint(alloc, "{d}", .{count}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: *NodeSearch) void {
|
||||||
|
self.coll.deinit(self.alloc);
|
||||||
|
self.alloc.free(self.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn append(self: *NodeSearch, id: NodeId) !void {
|
||||||
|
try self.coll.append(self.alloc, id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
pub const NodeSearchList = std.ArrayList(NodeSearch);
|
||||||
|
|
||||||
|
// https://chromedevtools.github.io/devtools-protocol/tot/DOM/#method-performSearch
|
||||||
|
fn performSearch(
|
||||||
|
alloc: std.mem.Allocator,
|
||||||
|
msg: *IncomingMessage,
|
||||||
|
ctx: *Ctx,
|
||||||
|
) ![]const u8 {
|
||||||
|
// input
|
||||||
|
const Params = struct {
|
||||||
|
query: []const u8,
|
||||||
|
includeUserAgentShadowDOM: ?bool = null,
|
||||||
|
};
|
||||||
|
const input = try Input(Params).get(alloc, msg);
|
||||||
|
defer input.deinit();
|
||||||
|
std.debug.assert(input.sessionId != null);
|
||||||
|
log.debug("Req > id {d}, method {s}", .{ input.id, "DOM.performSearch" });
|
||||||
|
|
||||||
|
// retrieve the root node
|
||||||
|
const page = ctx.browser.currentPage() orelse return error.NoPage;
|
||||||
|
|
||||||
|
if (page.doc == null) return error.NoDocument;
|
||||||
|
|
||||||
|
const list = try css.querySelectorAll(alloc, parser.documentToNode(page.doc.?), input.params.query);
|
||||||
|
const ln = list.nodes.items.len;
|
||||||
|
var ns = try NodeSearch.initCapacity(alloc, ln);
|
||||||
|
|
||||||
|
for (list.nodes.items) |n| {
|
||||||
|
const id = try ctx.state.nodelist.set(n);
|
||||||
|
try ns.append(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
try ctx.state.nodesearchlist.append(ns);
|
||||||
|
|
||||||
|
// output
|
||||||
|
const Resp = struct {
|
||||||
|
searchId: []const u8,
|
||||||
|
resultCount: u32,
|
||||||
|
};
|
||||||
|
const resp: Resp = .{
|
||||||
|
.searchId = ns.name,
|
||||||
|
.resultCount = @intCast(ln),
|
||||||
|
};
|
||||||
|
|
||||||
|
return result(alloc, input.id, Resp, resp, input.sessionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://chromedevtools.github.io/devtools-protocol/tot/DOM/#method-discardSearchResults
|
||||||
|
fn discardSearchResults(
|
||||||
|
alloc: std.mem.Allocator,
|
||||||
|
msg: *IncomingMessage,
|
||||||
|
ctx: *Ctx,
|
||||||
|
) ![]const u8 {
|
||||||
|
// input
|
||||||
|
const Params = struct {
|
||||||
|
searchId: []const u8,
|
||||||
|
};
|
||||||
|
const input = try Input(Params).get(alloc, msg);
|
||||||
|
defer input.deinit();
|
||||||
|
std.debug.assert(input.sessionId != null);
|
||||||
|
log.debug("Req > id {d}, method {s}", .{ input.id, "DOM.discardSearchResults" });
|
||||||
|
|
||||||
|
// retrieve the search from context
|
||||||
|
for (ctx.state.nodesearchlist.items, 0..) |*s, i| {
|
||||||
|
if (!std.mem.eql(u8, s.name, input.params.searchId)) continue;
|
||||||
|
|
||||||
|
s.deinit();
|
||||||
|
_ = ctx.state.nodesearchlist.swapRemove(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result(alloc, input.id, null, null, input.sessionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://chromedevtools.github.io/devtools-protocol/tot/DOM/#method-getSearchResults
|
||||||
|
fn getSearchResults(
|
||||||
|
alloc: std.mem.Allocator,
|
||||||
|
msg: *IncomingMessage,
|
||||||
|
ctx: *Ctx,
|
||||||
|
) ![]const u8 {
|
||||||
|
// input
|
||||||
|
const Params = struct {
|
||||||
|
searchId: []const u8,
|
||||||
|
fromIndex: u32,
|
||||||
|
toIndex: u32,
|
||||||
|
};
|
||||||
|
const input = try Input(Params).get(alloc, msg);
|
||||||
|
defer input.deinit();
|
||||||
|
std.debug.assert(input.sessionId != null);
|
||||||
|
log.debug("Req > id {d}, method {s}", .{ input.id, "DOM.getSearchResults" });
|
||||||
|
|
||||||
|
if (input.params.fromIndex >= input.params.toIndex) return error.BadIndices;
|
||||||
|
|
||||||
|
// retrieve the search from context
|
||||||
|
var ns: ?*const NodeSearch = undefined;
|
||||||
|
for (ctx.state.nodesearchlist.items) |s| {
|
||||||
|
if (!std.mem.eql(u8, s.name, input.params.searchId)) continue;
|
||||||
|
|
||||||
|
ns = &s;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ns == null) return error.searchResultNotFound;
|
||||||
|
const items = ns.?.coll.items;
|
||||||
|
|
||||||
|
if (input.params.fromIndex >= items.len) return error.BadFromIndex;
|
||||||
|
if (input.params.toIndex > items.len) return error.BadToIndex;
|
||||||
|
|
||||||
|
// output
|
||||||
|
const Resp = struct {
|
||||||
|
nodeIds: []NodeId,
|
||||||
|
};
|
||||||
|
const resp: Resp = .{
|
||||||
|
.nodeIds = ns.?.coll.items[input.params.fromIndex..input.params.toIndex],
|
||||||
|
};
|
||||||
|
|
||||||
|
return result(alloc, input.id, Resp, resp, input.sessionId);
|
||||||
|
}
|
||||||
|
|||||||
@@ -259,6 +259,7 @@ fn navigate(
|
|||||||
log.debug("Req > id {d}, method {s}", .{ input.id, "page.navigate" });
|
log.debug("Req > id {d}, method {s}", .{ input.id, "page.navigate" });
|
||||||
|
|
||||||
// change state
|
// change state
|
||||||
|
ctx.state.reset();
|
||||||
ctx.state.url = input.params.url;
|
ctx.state.url = input.params.url;
|
||||||
// TODO: hard coded ID
|
// TODO: hard coded ID
|
||||||
ctx.state.loaderID = "AF8667A203C5392DBE9AC290044AA4C2";
|
ctx.state.loaderID = "AF8667A203C5392DBE9AC290044AA4C2";
|
||||||
@@ -333,7 +334,7 @@ fn navigate(
|
|||||||
|
|
||||||
// Launch navigate, the page must have been created by a
|
// Launch navigate, the page must have been created by a
|
||||||
// target.createTarget.
|
// target.createTarget.
|
||||||
var p = ctx.browser.session.page orelse return error.NoPage;
|
var p = ctx.browser.currentPage() 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,
|
||||||
@@ -361,6 +362,16 @@ fn navigate(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DOM.documentUpdated
|
||||||
|
try sendEvent(
|
||||||
|
alloc,
|
||||||
|
ctx,
|
||||||
|
"DOM.documentUpdated",
|
||||||
|
struct {},
|
||||||
|
.{},
|
||||||
|
input.sessionId,
|
||||||
|
);
|
||||||
|
|
||||||
// frameNavigated event
|
// frameNavigated event
|
||||||
const FrameNavigated = struct {
|
const FrameNavigated = struct {
|
||||||
frame: Frame,
|
frame: Frame,
|
||||||
|
|||||||
@@ -353,7 +353,7 @@ fn createTarget(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO stop the previous page instead?
|
// TODO stop the previous page instead?
|
||||||
if (ctx.browser.session.page != null) return error.pageAlreadyExists;
|
if (ctx.browser.currentPage() != null) return error.pageAlreadyExists;
|
||||||
|
|
||||||
// create the page
|
// create the page
|
||||||
const p = try ctx.browser.session.createPage();
|
const p = try ctx.browser.session.createPage();
|
||||||
@@ -464,7 +464,7 @@ fn closeTarget(
|
|||||||
null,
|
null,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (ctx.browser.session.page != null) ctx.browser.session.page.?.end();
|
if (ctx.browser.currentPage()) |page| page.end();
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1008,6 +1008,7 @@ pub fn nodeLocalName(node: *Node) ![]const u8 {
|
|||||||
var s: ?*String = undefined;
|
var s: ?*String = undefined;
|
||||||
const err = nodeVtable(node).dom_node_get_local_name.?(node, &s);
|
const err = nodeVtable(node).dom_node_get_local_name.?(node, &s);
|
||||||
try DOMErr(err);
|
try DOMErr(err);
|
||||||
|
if (s == null) return "";
|
||||||
var s_lower: ?*String = undefined;
|
var s_lower: ?*String = undefined;
|
||||||
const errStr = c.dom_string_tolower(s, true, &s_lower);
|
const errStr = c.dom_string_tolower(s, true, &s_lower);
|
||||||
try DOMErr(errStr);
|
try DOMErr(errStr);
|
||||||
@@ -1098,6 +1099,7 @@ pub fn nodeName(node: *Node) ![]const u8 {
|
|||||||
var s: ?*String = undefined;
|
var s: ?*String = undefined;
|
||||||
const err = nodeVtable(node).dom_node_get_node_name.?(node, &s);
|
const err = nodeVtable(node).dom_node_get_node_name.?(node, &s);
|
||||||
try DOMErr(err);
|
try DOMErr(err);
|
||||||
|
if (s == null) return "";
|
||||||
return strToData(s.?);
|
return strToData(s.?);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -69,13 +69,17 @@ pub const Ctx = struct {
|
|||||||
last_active: ?std.time.Instant = null,
|
last_active: ?std.time.Instant = null,
|
||||||
|
|
||||||
// CDP
|
// CDP
|
||||||
state: cdp.State = .{},
|
state: cdp.State = undefined,
|
||||||
|
|
||||||
// JS fields
|
// JS fields
|
||||||
browser: *Browser, // TODO: is pointer mandatory here?
|
browser: *Browser, // TODO: is pointer mandatory here?
|
||||||
sessionNew: bool,
|
sessionNew: bool,
|
||||||
// try_catch: jsruntime.TryCatch, // TODO
|
// try_catch: jsruntime.TryCatch, // TODO
|
||||||
|
|
||||||
|
pub fn deinit(self: *Ctx) void {
|
||||||
|
self.state.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
// callbacks
|
// callbacks
|
||||||
// ---------
|
// ---------
|
||||||
|
|
||||||
@@ -458,7 +462,10 @@ pub fn handle(
|
|||||||
.accept_completion = &accept_completion,
|
.accept_completion = &accept_completion,
|
||||||
.conn_completion = &conn_completion,
|
.conn_completion = &conn_completion,
|
||||||
.timeout_completion = &timeout_completion,
|
.timeout_completion = &timeout_completion,
|
||||||
|
.state = cdp.State.init(browser.session.alloc),
|
||||||
};
|
};
|
||||||
|
defer ctx.deinit();
|
||||||
|
|
||||||
try browser.session.initInspector(
|
try browser.session.initInspector(
|
||||||
&ctx,
|
&ctx,
|
||||||
Ctx.onInspectorResp,
|
Ctx.onInspectorResp,
|
||||||
|
|||||||
Reference in New Issue
Block a user