mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 23:23:28 +00:00
dom.querySelector
This commit is contained in:
@@ -31,6 +31,8 @@ pub fn processMessage(cmd: anytype) !void {
|
|||||||
performSearch,
|
performSearch,
|
||||||
getSearchResults,
|
getSearchResults,
|
||||||
discardSearchResults,
|
discardSearchResults,
|
||||||
|
querySelector,
|
||||||
|
querySelectorAll,
|
||||||
resolveNode,
|
resolveNode,
|
||||||
describeNode,
|
describeNode,
|
||||||
scrollIntoViewIfNeeded,
|
scrollIntoViewIfNeeded,
|
||||||
@@ -43,6 +45,8 @@ pub fn processMessage(cmd: anytype) !void {
|
|||||||
.performSearch => return performSearch(cmd),
|
.performSearch => return performSearch(cmd),
|
||||||
.getSearchResults => return getSearchResults(cmd),
|
.getSearchResults => return getSearchResults(cmd),
|
||||||
.discardSearchResults => return discardSearchResults(cmd),
|
.discardSearchResults => return discardSearchResults(cmd),
|
||||||
|
.querySelector => return querySelector(cmd),
|
||||||
|
.querySelectorAll => return querySelectorAll(cmd),
|
||||||
.resolveNode => return resolveNode(cmd),
|
.resolveNode => return resolveNode(cmd),
|
||||||
.describeNode => return describeNode(cmd),
|
.describeNode => return describeNode(cmd),
|
||||||
.scrollIntoViewIfNeeded => return scrollIntoViewIfNeeded(cmd),
|
.scrollIntoViewIfNeeded => return scrollIntoViewIfNeeded(cmd),
|
||||||
@@ -188,6 +192,61 @@ fn getSearchResults(cmd: anytype) !void {
|
|||||||
return cmd.sendResult(.{ .nodeIds = node_ids[params.fromIndex..params.toIndex] }, .{});
|
return cmd.sendResult(.{ .nodeIds = node_ids[params.fromIndex..params.toIndex] }, .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn querySelector(cmd: anytype) !void {
|
||||||
|
const params = (try cmd.params(struct {
|
||||||
|
nodeId: Node.Id,
|
||||||
|
selector: []const u8,
|
||||||
|
})) orelse return error.InvalidParams;
|
||||||
|
|
||||||
|
const bc = cmd.browser_context orelse return error.BrowserContextNotLoaded;
|
||||||
|
|
||||||
|
const node = bc.node_registry.lookup_by_id.get(params.nodeId) orelse return error.UnknownNode;
|
||||||
|
|
||||||
|
const selected_node = try css.querySelector(
|
||||||
|
cmd.arena,
|
||||||
|
node._node,
|
||||||
|
params.selector,
|
||||||
|
) orelse return error.NodeNotFoundForGivenId;
|
||||||
|
|
||||||
|
const registered_node = try bc.node_registry.register(selected_node);
|
||||||
|
|
||||||
|
// Dispatch setChildNodesEvents to inform the client of the subpart of node tree covering the results.
|
||||||
|
var array = [1]*parser.Node{selected_node};
|
||||||
|
try dispatchSetChildNodes(cmd, array[0..]);
|
||||||
|
|
||||||
|
return cmd.sendResult(.{
|
||||||
|
.nodeId = registered_node.id,
|
||||||
|
}, .{});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn querySelectorAll(cmd: anytype) !void {
|
||||||
|
const params = (try cmd.params(struct {
|
||||||
|
nodeId: Node.Id,
|
||||||
|
selector: []const u8,
|
||||||
|
})) orelse return error.InvalidParams;
|
||||||
|
|
||||||
|
const bc = cmd.browser_context orelse return error.BrowserContextNotLoaded;
|
||||||
|
|
||||||
|
const node = bc.node_registry.lookup_by_id.get(params.nodeId) orelse return error.UnknownNode;
|
||||||
|
|
||||||
|
const arena = cmd.arena;
|
||||||
|
var selected_nodes = try css.querySelectorAll(arena, node._node, params.selector);
|
||||||
|
defer selected_nodes.deinit(arena);
|
||||||
|
|
||||||
|
const nodes = selected_nodes.nodes.items;
|
||||||
|
const node_ids = try arena.alloc(Node.Id, nodes.len);
|
||||||
|
for (nodes, node_ids) |selected_node, *node_id| {
|
||||||
|
node_id.* = (try bc.node_registry.register(selected_node)).id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dispatch setChildNodesEvents to inform the client of the subpart of node tree covering the results.
|
||||||
|
try dispatchSetChildNodes(cmd, nodes);
|
||||||
|
|
||||||
|
return cmd.sendResult(.{
|
||||||
|
.nodeIds = node_ids,
|
||||||
|
}, .{});
|
||||||
|
}
|
||||||
|
|
||||||
fn resolveNode(cmd: anytype) !void {
|
fn resolveNode(cmd: anytype) !void {
|
||||||
const params = (try cmd.params(struct {
|
const params = (try cmd.params(struct {
|
||||||
nodeId: ?Node.Id = null,
|
nodeId: ?Node.Id = null,
|
||||||
@@ -399,3 +458,78 @@ test "cdp.dom: search flow" {
|
|||||||
.params = .{ .searchId = "0", .fromIndex = 0, .toIndex = 1 },
|
.params = .{ .searchId = "0", .fromIndex = 0, .toIndex = 1 },
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "cdp.dom: querySelector unknown search id" {
|
||||||
|
var ctx = testing.context();
|
||||||
|
defer ctx.deinit();
|
||||||
|
|
||||||
|
_ = try ctx.loadBrowserContext(.{ .id = "BID-A", .html = "<p>1</p> <p>2</p>" });
|
||||||
|
|
||||||
|
try testing.expectError(error.UnknownNode, ctx.processMessage(.{
|
||||||
|
.id = 9,
|
||||||
|
.method = "DOM.querySelector",
|
||||||
|
.params = .{ .nodeId = 99, .selector = "" },
|
||||||
|
}));
|
||||||
|
try testing.expectError(error.UnknownNode, ctx.processMessage(.{
|
||||||
|
.id = 9,
|
||||||
|
.method = "DOM.querySelectorAll",
|
||||||
|
.params = .{ .nodeId = 99, .selector = "" },
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
test "cdp.dom: querySelector Node not found" {
|
||||||
|
var ctx = testing.context();
|
||||||
|
defer ctx.deinit();
|
||||||
|
|
||||||
|
_ = try ctx.loadBrowserContext(.{ .id = "BID-A", .html = "<p>1</p> <p>2</p>" });
|
||||||
|
|
||||||
|
try ctx.processMessage(.{ // Hacky way to make sure nodeId 0 exists in the registry
|
||||||
|
.id = 3,
|
||||||
|
.method = "DOM.performSearch",
|
||||||
|
.params = .{ .query = "p" },
|
||||||
|
});
|
||||||
|
try ctx.expectSentResult(.{ .searchId = "0", .resultCount = 2 }, .{ .id = 3 });
|
||||||
|
|
||||||
|
try testing.expectError(error.NodeNotFoundForGivenId, ctx.processMessage(.{
|
||||||
|
.id = 4,
|
||||||
|
.method = "DOM.querySelector",
|
||||||
|
.params = .{ .nodeId = 0, .selector = "a" },
|
||||||
|
}));
|
||||||
|
|
||||||
|
try ctx.processMessage(.{
|
||||||
|
.id = 5,
|
||||||
|
.method = "DOM.querySelectorAll",
|
||||||
|
.params = .{ .nodeId = 0, .selector = "a" },
|
||||||
|
});
|
||||||
|
try ctx.expectSentResult(.{ .nodeIds = &[_]u32{} }, .{ .id = 5 });
|
||||||
|
}
|
||||||
|
|
||||||
|
test "cdp.dom: querySelector Nodes found" {
|
||||||
|
var ctx = testing.context();
|
||||||
|
defer ctx.deinit();
|
||||||
|
|
||||||
|
_ = try ctx.loadBrowserContext(.{ .id = "BID-A", .html = "<div><p>2</p></div>" });
|
||||||
|
|
||||||
|
try ctx.processMessage(.{ // Hacky way to make sure nodeId 0 exists in the registry
|
||||||
|
.id = 3,
|
||||||
|
.method = "DOM.performSearch",
|
||||||
|
.params = .{ .query = "div" },
|
||||||
|
});
|
||||||
|
try ctx.expectSentResult(.{ .searchId = "0", .resultCount = 1 }, .{ .id = 3 });
|
||||||
|
|
||||||
|
try ctx.processMessage(.{
|
||||||
|
.id = 4,
|
||||||
|
.method = "DOM.querySelector",
|
||||||
|
.params = .{ .nodeId = 0, .selector = "p" },
|
||||||
|
});
|
||||||
|
// TODO Check 1 or more "DOM.setChildNodes" was send
|
||||||
|
try ctx.expectSentResult(.{ .nodeId = 5 }, .{ .id = 4 });
|
||||||
|
|
||||||
|
try ctx.processMessage(.{
|
||||||
|
.id = 5,
|
||||||
|
.method = "DOM.querySelectorAll",
|
||||||
|
.params = .{ .nodeId = 0, .selector = "p" },
|
||||||
|
});
|
||||||
|
// TODO Check 1 or more "DOM.setChildNodes" was send
|
||||||
|
try ctx.expectSentResult(.{ .nodeIds = &.{5} }, .{ .id = 5 });
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user