diff --git a/src/cdp/dom.zig b/src/cdp/dom.zig index 0e8c1d66..1f8d356a 100644 --- a/src/cdp/dom.zig +++ b/src/cdp/dom.zig @@ -25,10 +25,13 @@ const result = cdp.result; const IncomingMessage = @import("msg.zig").IncomingMessage; const Input = @import("msg.zig").Input; +const parser = @import("netsurf"); + const log = std.log.scoped(.cdp); const Methods = enum { enable, + getDocument, }; pub fn dom( @@ -42,6 +45,7 @@ pub fn dom( return switch (method) { .enable => enable(alloc, msg, ctx), + .getDocument => getDocument(alloc, msg, ctx), }; } @@ -57,3 +61,79 @@ fn enable( return result(alloc, input.id, null, null, input.sessionId); } + +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, + 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) !Node { + const children = try parser.nodeGetChildNodes(n); + const ln = try parser.nodeListLength(children); + + return .{ + .nodeId = 1, + .backendNodeId = 1, + .nodeType = @intFromEnum(try parser.nodeType(n)), + .nodeName = try parser.nodeName(n), + .localName = try parser.nodeLocalName(n), + .nodeValue = try parser.nodeValue(n) orelse "", + .childNodeCount = ln, + }; + } +}; + +// 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" }); + + if (ctx.browser.session.page == null) { + return error.NoPage; + } + + // retrieve the root node + const page = ctx.browser.session.page.?; + + if (page.doc == null) { + return error.NoDocument; + } + + const root = try parser.documentGetDocumentElement(page.doc.?) orelse { + return error.NoRoot; + }; + + // output + const Resp = struct { + root: Node, + }; + const resp: Resp = .{ + .root = try Node.init(parser.elementToNode(root)), + }; + + return result(alloc, input.id, Resp, resp, input.sessionId); +}