Skip to content

Commit 85f83e8

Browse files
committed
scollifneeded and contentQuads wip
1 parent bbeec0e commit 85f83e8

File tree

2 files changed

+97
-1
lines changed

2 files changed

+97
-1
lines changed

src/browser/dom/element.zig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,11 @@ pub const Element = struct {
389389
const s = try cssParse(state.call_arena, selectors, .{});
390390
return s.match(CssNodeWrap{ .node = parser.elementToNode(self) });
391391
}
392+
393+
pub fn _scrollIntoViewIfNeeded(self: *parser.Element, center_if_needed: ?bool) void {
394+
_ = self;
395+
_ = center_if_needed;
396+
}
392397
};
393398

394399
// Tests
@@ -575,6 +580,12 @@ test "Browser.DOM.Element" {
575580
.{ "el.matches('.notok')", "false" },
576581
}, .{});
577582

583+
try runner.testCases(&.{
584+
.{ "const el3 = document.createElement('div');", "undefined" },
585+
.{ "el3.scrollIntoViewIfNeeded();", "undefined" },
586+
.{ "el3.scrollIntoViewIfNeeded(false);", "undefined" },
587+
}, .{});
588+
578589
// before
579590
try runner.testCases(&.{
580591
.{ "const before_container = document.createElement('div');", "undefined" },

src/cdp/domains/dom.zig

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ pub fn processMessage(cmd: anytype) !void {
3131
discardSearchResults,
3232
resolveNode,
3333
describeNode,
34+
scrollIntoViewIfNeeded,
35+
getContentQuads,
3436
}, cmd.input.action) orelse return error.UnknownMethod;
3537

3638
switch (action) {
@@ -41,6 +43,8 @@ pub fn processMessage(cmd: anytype) !void {
4143
.discardSearchResults => return discardSearchResults(cmd),
4244
.resolveNode => return resolveNode(cmd),
4345
.describeNode => return describeNode(cmd),
46+
.scrollIntoViewIfNeeded => return scrollIntoViewIfNeeded(cmd),
47+
.getContentQuads => return getContentQuads(cmd),
4448
}
4549
}
4650

@@ -239,7 +243,8 @@ fn describeNode(cmd: anytype) !void {
239243

240244
const bc = cmd.browser_context orelse return error.BrowserContextNotLoaded;
241245

242-
if (params.nodeId != null) {
246+
const input_node_id = params.nodeId orelse params.backendNodeId;
247+
if (input_node_id != null) {
243248
const node = bc.node_registry.lookup_by_id.get(params.nodeId.?) orelse return error.NodeNotFound;
244249
return cmd.sendResult(.{ .node = bc.nodeWriter(node, .{}) }, .{});
245250
}
@@ -252,6 +257,86 @@ fn describeNode(cmd: anytype) !void {
252257
return error.MissingParams;
253258
}
254259

260+
// Note Element.DOMRect exists, but there is no need to couple them at this time.
261+
const Rect = struct {
262+
x: f64,
263+
y: f64,
264+
width: f64,
265+
height: f64,
266+
};
267+
268+
// An array of quad vertices, x immediately followed by y for each point, points clock-wise.
269+
// Note Y points downward
270+
// We are assuming the start/endpoint is not repeated.
271+
const Quad = [8]f64;
272+
273+
fn scrollIntoViewIfNeeded(cmd: anytype) !void {
274+
const params = (try cmd.params(struct {
275+
nodeId: ?Node.Id = null,
276+
backendNodeId: ?u32 = null,
277+
objectId: ?[]const u8 = null,
278+
rect: ?Rect = null,
279+
})) orelse return error.InvalidParams;
280+
281+
var set_count: u2 = 0; // only 1 of nodeId backendNodeId objectId may be set
282+
if (params.nodeId != null) set_count += 1;
283+
if (params.backendNodeId != null) set_count += 1;
284+
if (params.objectId != null) set_count += 1;
285+
if (set_count != 1) return error.InvalidParams;
286+
287+
// Since element.scrollIntoViewIfNeeded is a no-op we do not bother retrieving the node.
288+
// This however also means we also do not error in case the node is not found.
289+
290+
return cmd.sendResult(null, .{});
291+
}
292+
293+
fn getContentQuads(cmd: anytype) !void {
294+
const params = (try cmd.params(struct {
295+
nodeId: ?Node.Id = null,
296+
backendNodeId: ?u32 = null,
297+
objectId: ?[]const u8 = null,
298+
})) orelse return error.InvalidParams;
299+
300+
var set_count: u2 = 0; // only 1 of nodeId backendNodeId objectId may be set
301+
if (params.nodeId != null) set_count += 1;
302+
if (params.backendNodeId != null) set_count += 1;
303+
if (params.objectId != null) set_count += 1;
304+
if (set_count != 1) return error.InvalidParams;
305+
306+
const bc = cmd.browser_context orelse return error.BrowserContextNotLoaded;
307+
308+
const node = blk: {
309+
const input_node_id = params.nodeId orelse params.backendNodeId;
310+
if (input_node_id != null) {
311+
const node = bc.node_registry.lookup_by_id.get(params.nodeId.?) orelse return error.NodeNotFound;
312+
break :blk node;
313+
}
314+
if (params.objectId != null) {
315+
const parser_node = try bc.inspector.getNodePtr(cmd.arena, params.objectId.?);
316+
const node = try bc.node_registry.register(@ptrCast(parser_node));
317+
break :blk node;
318+
}
319+
unreachable;
320+
};
321+
322+
if (try parser.nodeType(node._node) != .element) return error.NodeISNotAnElement;
323+
324+
const element = parser.nodeToElement(node._node);
325+
const rect = try bc.session.page.?.state.renderer.getRect(element);
326+
const quad = Quad{
327+
rect.x,
328+
rect.y,
329+
rect.x + rect.width,
330+
rect.y,
331+
rect.x + rect.width,
332+
rect.y + rect.height,
333+
rect.x,
334+
rect.y + rect.height,
335+
};
336+
337+
return cmd.sendResult(.{ .quads = &.{quad} }, .{});
338+
}
339+
255340
const testing = @import("../testing.zig");
256341

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

0 commit comments

Comments
 (0)