From dc23a74e7bf0138049f3aa313c638b08c4d954c5 Mon Sep 17 00:00:00 2001 From: Pierre Tachoire Date: Fri, 8 Aug 2025 18:31:08 +0200 Subject: [PATCH] add in the DOM tree --- src/browser/dump.zig | 9 --------- src/browser/page.zig | 35 +++++++++++++++++++++++++++++++++-- src/main.zig | 2 +- 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/browser/dump.zig b/src/browser/dump.zig index cf110420..68dc6086 100644 --- a/src/browser/dump.zig +++ b/src/browser/dump.zig @@ -23,7 +23,6 @@ const Walker = @import("dom/walker.zig").WalkerChildren; pub const Opts = struct { exclude_scripts: bool = false, - include_base: ?[]const u8 = null, }; // writer must be a std.io.Writer @@ -92,14 +91,6 @@ pub fn writeNode(node: *parser.Node, opts: Opts, writer: anytype) anyerror!void // void elements can't have any content. if (try isVoid(parser.nodeToElement(node))) return; - // If we wrote the and we want to include a , add it - // now. - if (opts.include_base != null and tag_type == .head) { - try writer.writeAll(""); - } - if (tag_type == .script) { try writer.writeAll(try parser.nodeTextContent(node) orelse ""); } else { diff --git a/src/browser/page.zig b/src/browser/page.zig index eff09152..ba57167b 100644 --- a/src/browser/page.zig +++ b/src/browser/page.zig @@ -141,8 +141,13 @@ pub const Page = struct { repeat_delay.* = 100 * std.time.ns_per_ms; } + pub const DumpOpts = struct { + exclude_scripts: bool = false, + with_base: bool = false, + }; + // dump writes the page content into the given file. - pub fn dump(self: *const Page, opts: Dump.Opts, out: std.fs.File) !void { + pub fn dump(self: *const Page, opts: DumpOpts, out: std.fs.File) !void { if (self.raw_data) |raw_data| { // raw_data was set if the document was not HTML, dump the data content only. return try out.writeAll(raw_data); @@ -150,7 +155,33 @@ pub const Page = struct { // if the page has a pointer to a document, dumps the HTML. const doc = parser.documentHTMLToDocument(self.window.document); - try Dump.writeHTML(doc, opts, out); + + // if the base si requested, add the base's node in the document's headers. + if (opts.with_base) { + try self.addDOMTreeBase(); + } + + try Dump.writeHTML(doc, .{ + .exclude_scripts = opts.exclude_scripts, + }, out); + } + + // addDOMTreeBase modifies the page's document to add a tag after + // . + // If is missing, the function returns silently. + fn addDOMTreeBase(self: *const Page) !void { + const doc = parser.documentHTMLToDocument(self.window.document); + std.debug.assert(doc.is_html); + + // find tag + const list = try parser.documentGetElementsByTagName(doc, "head"); + const head = try parser.nodeListItem(list, 0) orelse return; + + const base = try parser.documentCreateElement(doc, "base"); + try parser.elementSetAttribute(base, "href", self.url.raw); + + const Node = @import("dom/node.zig").Node; + try Node.prepend(head, &[_]Node.NodeOrText{.{ .node = parser.elementToNode(base) }}); } pub fn fetchModuleSource(ctx: *anyopaque, src: []const u8) !?[]const u8 { diff --git a/src/main.zig b/src/main.zig index 70dda469..4ca6db09 100644 --- a/src/main.zig +++ b/src/main.zig @@ -136,7 +136,7 @@ fn run(alloc: Allocator) !void { if (opts.dump) { try page.dump(.{ .exclude_scripts = opts.noscript, - .include_base = if (opts.withbase) page.url.raw else null, + .with_base = opts.withbase, }, std.io.getStdOut()); } },