Skip to content

Commit af1d49b

Browse files
committed
describeNode
1 parent 6e6660e commit af1d49b

File tree

3 files changed

+71
-4
lines changed

3 files changed

+71
-4
lines changed

src/cdp/domains/dom.zig

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ pub fn processMessage(cmd: anytype) !void {
3030
getSearchResults,
3131
discardSearchResults,
3232
resolveNode,
33+
describeNode,
3334
}, cmd.input.action) orelse return error.UnknownMethod;
3435

3536
switch (action) {
@@ -39,6 +40,7 @@ pub fn processMessage(cmd: anytype) !void {
3940
.getSearchResults => return getSearchResults(cmd),
4041
.discardSearchResults => return discardSearchResults(cmd),
4142
.resolveNode => return resolveNode(cmd),
43+
.describeNode => return describeNode(cmd),
4244
}
4345
}
4446

@@ -151,6 +153,37 @@ fn resolveNode(cmd: anytype) !void {
151153
} }, .{});
152154
}
153155

156+
fn describeNode(cmd: anytype) !void {
157+
const params = (try cmd.params(struct {
158+
nodeId: ?Node.Id = null,
159+
backendNodeId: ?Node.Id = null,
160+
objectId: ?[]const u8 = null,
161+
depth: u32 = 1,
162+
pierce: bool = false,
163+
})) orelse return error.InvalidParams;
164+
if (params.backendNodeId != null or params.depth != 1 or params.pierce) {
165+
return error.NotYetImplementedParams;
166+
}
167+
168+
const bc = cmd.browser_context orelse return error.BrowserContextNotLoaded;
169+
170+
if (params.nodeId != null) {
171+
const node = bc.node_registry.lookup_by_id.get(params.nodeId.?) orelse return error.NodeNotFound;
172+
return cmd.sendResult(.{ .node = bc.nodeWriter(node, .{}) }, .{});
173+
} else if (params.objectId != null) {
174+
175+
// Retrieve the object from which ever context it is in.
176+
const js_value = try bc.session.inspector.getValueByObjectId(cmd.arena, bc.session.executor, params.objectId.?);
177+
const entry = js_value.taggedAnyOpaque() orelse return error.ObjectIdIsNotANode;
178+
const subtype = entry.subtype orelse return error.ObjectIdIsNotANode;
179+
if (subtype != .node) return error.ObjectIdIsNotANode;
180+
181+
const node = try bc.node_registry.register(@ptrCast(entry.ptr));
182+
return cmd.sendResult(.{ .node = bc.nodeWriter(node, .{}) }, .{});
183+
}
184+
return error.MissingParams;
185+
}
186+
154187
const testing = @import("../testing.zig");
155188

156189
test "cdp.dom: getSearchResults unknown search id" {

src/cdp/testing.zig

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,13 @@ const Browser = struct {
5555
if (self.session != null) {
5656
return error.MockBrowserSessionAlreadyExists;
5757
}
58-
5958
const arena = self.arena.allocator();
59+
const executor = arena.create(Executor) catch unreachable;
6060
self.session = try arena.create(Session);
6161
self.session.?.* = .{
6262
.page = null,
6363
.arena = arena,
64-
.executor = .{},
64+
.executor = executor,
6565
.inspector = .{},
6666
};
6767
return self.session.?;
@@ -78,7 +78,7 @@ const Browser = struct {
7878
const Session = struct {
7979
page: ?Page = null,
8080
arena: Allocator,
81-
executor: Executor,
81+
executor: *Executor,
8282
inspector: Inspector,
8383

8484
pub fn currentPage(self: *Session) ?*Page {
@@ -112,7 +112,7 @@ const Executor = struct {};
112112
const Inspector = struct {
113113
pub fn getRemoteObject(
114114
self: *const Inspector,
115-
executor: Executor,
115+
executor: *Executor,
116116
group: []const u8,
117117
value: anytype,
118118
) !RemoteObject {
@@ -122,6 +122,27 @@ const Inspector = struct {
122122
_ = value;
123123
return RemoteObject{};
124124
}
125+
pub fn getValueByObjectId(self: Inspector, alloc: std.mem.Allocator, executor: *const Executor, object_id: []const u8) !Value {
126+
_ = self;
127+
_ = alloc;
128+
_ = executor;
129+
_ = object_id;
130+
return .{};
131+
}
132+
};
133+
const Value = struct {
134+
pub fn taggedAnyOpaque(self: Value) ?*TaggedAnyOpaque {
135+
_ = self;
136+
return null;
137+
}
138+
};
139+
const TaggedAnyOpaque = struct {
140+
ptr: *anyopaque,
141+
subtype: ?SubType = .node,
142+
};
143+
144+
const SubType = enum {
145+
node,
125146
};
126147

127148
const RemoteObject = struct {

src/runtime/js.zig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1306,6 +1306,15 @@ pub fn Env(comptime S: type, comptime types: anytype) type {
13061306
generate_preview,
13071307
);
13081308
}
1309+
1310+
// Gets a value by object ID regardless of which context it is in.
1311+
// unwrapping the object also tells us the context, for now we assume it is always the default one.
1312+
// The executor argument is likely to change to somthing to allow us to find the right Executer with the given context
1313+
pub fn getValueByObjectId(self: Inspector, allocator: std.mem.Allocator, executor: *const Executor, object_id: []const u8) !Value {
1314+
const unwrapped = try self.session.unwrapObject(allocator, object_id);
1315+
// std.debug.assert(executor.context.handle == unwrapped.context.handle);
1316+
return .{ .value = unwrapped.value, .executor = executor }; // The values context and groupId are not used here
1317+
}
13091318
};
13101319

13111320
pub const RemoteObject = v8.RemoteObject;
@@ -1319,6 +1328,10 @@ pub fn Env(comptime S: type, comptime types: anytype) type {
13191328
const executor = self.executor;
13201329
return valueToString(allocator, self.value, executor.isolate, executor.context);
13211330
}
1331+
1332+
pub fn taggedAnyOpaque(self: Value) ?*TaggedAnyOpaque {
1333+
return getTaggedAnyOpaque(self.value);
1334+
}
13221335
};
13231336

13241337
// Reverses the mapZigInstanceToJs, making sure that our TaggedAnyOpaque

0 commit comments

Comments
 (0)