Skip to content

Commit dc23a74

Browse files
committed
add <base> in the DOM tree
1 parent 5e30a39 commit dc23a74

File tree

3 files changed

+34
-12
lines changed

3 files changed

+34
-12
lines changed

src/browser/dump.zig

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ const Walker = @import("dom/walker.zig").WalkerChildren;
2323

2424
pub const Opts = struct {
2525
exclude_scripts: bool = false,
26-
include_base: ?[]const u8 = null,
2726
};
2827

2928
// writer must be a std.io.Writer
@@ -92,14 +91,6 @@ pub fn writeNode(node: *parser.Node, opts: Opts, writer: anytype) anyerror!void
9291
// void elements can't have any content.
9392
if (try isVoid(parser.nodeToElement(node))) return;
9493

95-
// If we wrote the <head> and we want to include a <base>, add it
96-
// now.
97-
if (opts.include_base != null and tag_type == .head) {
98-
try writer.writeAll("<base href=\"");
99-
try writer.writeAll(opts.include_base.?);
100-
try writer.writeAll("\">");
101-
}
102-
10394
if (tag_type == .script) {
10495
try writer.writeAll(try parser.nodeTextContent(node) orelse "");
10596
} else {

src/browser/page.zig

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,16 +141,47 @@ pub const Page = struct {
141141
repeat_delay.* = 100 * std.time.ns_per_ms;
142142
}
143143

144+
pub const DumpOpts = struct {
145+
exclude_scripts: bool = false,
146+
with_base: bool = false,
147+
};
148+
144149
// dump writes the page content into the given file.
145-
pub fn dump(self: *const Page, opts: Dump.Opts, out: std.fs.File) !void {
150+
pub fn dump(self: *const Page, opts: DumpOpts, out: std.fs.File) !void {
146151
if (self.raw_data) |raw_data| {
147152
// raw_data was set if the document was not HTML, dump the data content only.
148153
return try out.writeAll(raw_data);
149154
}
150155

151156
// if the page has a pointer to a document, dumps the HTML.
152157
const doc = parser.documentHTMLToDocument(self.window.document);
153-
try Dump.writeHTML(doc, opts, out);
158+
159+
// if the base si requested, add the base's node in the document's headers.
160+
if (opts.with_base) {
161+
try self.addDOMTreeBase();
162+
}
163+
164+
try Dump.writeHTML(doc, .{
165+
.exclude_scripts = opts.exclude_scripts,
166+
}, out);
167+
}
168+
169+
// addDOMTreeBase modifies the page's document to add a <base> tag after
170+
// <head>.
171+
// If <head> is missing, the function returns silently.
172+
fn addDOMTreeBase(self: *const Page) !void {
173+
const doc = parser.documentHTMLToDocument(self.window.document);
174+
std.debug.assert(doc.is_html);
175+
176+
// find <head> tag
177+
const list = try parser.documentGetElementsByTagName(doc, "head");
178+
const head = try parser.nodeListItem(list, 0) orelse return;
179+
180+
const base = try parser.documentCreateElement(doc, "base");
181+
try parser.elementSetAttribute(base, "href", self.url.raw);
182+
183+
const Node = @import("dom/node.zig").Node;
184+
try Node.prepend(head, &[_]Node.NodeOrText{.{ .node = parser.elementToNode(base) }});
154185
}
155186

156187
pub fn fetchModuleSource(ctx: *anyopaque, src: []const u8) !?[]const u8 {

src/main.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ fn run(alloc: Allocator) !void {
136136
if (opts.dump) {
137137
try page.dump(.{
138138
.exclude_scripts = opts.noscript,
139-
.include_base = if (opts.withbase) page.url.raw else null,
139+
.with_base = opts.withbase,
140140
}, std.io.getStdOut());
141141
}
142142
},

0 commit comments

Comments
 (0)