CDP: implement LP.getSemanticTree for native semantic DOM extraction

This commit is contained in:
Adrià Arrufat
2026-03-06 14:47:29 +09:00
parent 7322f90af4
commit 0f46277b1f
5 changed files with 266 additions and 2 deletions

View File

@@ -18,19 +18,53 @@
const std = @import("std");
const lp = @import("lightpanda");
const log = @import("../../log.zig");
const markdown = lp.markdown;
const Node = @import("../Node.zig");
const DOMNode = @import("../../browser/webapi/Node.zig");
const SemanticTree = @import("../semantic_tree.zig");
pub fn processMessage(cmd: anytype) !void {
const action = std.meta.stringToEnum(enum {
getMarkdown,
getSemanticTree,
}, cmd.input.action) orelse return error.UnknownMethod;
switch (action) {
.getMarkdown => return getMarkdown(cmd),
.getSemanticTree => return getSemanticTree(cmd),
}
}
const SemanticTreeResult = struct {
dom_node: *DOMNode,
registry: *Node.Registry,
page: *lp.Page,
arena: std.mem.Allocator,
pub fn jsonStringify(self: @This(), jw: *std.json.Stringify) error{WriteFailed}!void {
SemanticTree.dump(self.dom_node, self.registry, jw, self.page, self.arena) catch |err| {
log.err(.cdp, "semantic tree dump failed", .{ .err = err });
return error.WriteFailed;
};
}
};
fn getSemanticTree(cmd: anytype) !void {
const bc = cmd.browser_context orelse return error.NoBrowserContext;
const page = bc.session.currentPage() orelse return error.PageNotLoaded;
const dom_node = page.document.asNode();
return cmd.sendResult(.{
.semanticTree = .{
.dom_node = dom_node,
.registry = &bc.node_registry,
.page = page,
.arena = cmd.arena,
},
}, .{});
}
fn getMarkdown(cmd: anytype) !void {
const Params = struct {
nodeId: ?Node.Id = null,
@@ -45,7 +79,7 @@ fn getMarkdown(cmd: anytype) !void {
else
page.document.asNode();
var aw = std.Io.Writer.Allocating.init(cmd.arena);
var aw: std.Io.Writer.Allocating = .init(cmd.arena);
defer aw.deinit();
try markdown.dump(dom_node, .{}, &aw.writer, page);