Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/browser/dom/element.zig
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,13 @@ pub const Element = struct {

pub fn get_innerHTML(self: *parser.Element, page: *Page) ![]const u8 {
var buf = std.ArrayList(u8).init(page.arena);
try dump.writeChildren(parser.elementToNode(self), buf.writer());
try dump.writeChildren(parser.elementToNode(self), .{}, buf.writer());
return buf.items;
}

pub fn get_outerHTML(self: *parser.Element, page: *Page) ![]const u8 {
var buf = std.ArrayList(u8).init(page.arena);
try dump.writeNode(parser.elementToNode(self), buf.writer());
try dump.writeNode(parser.elementToNode(self), .{}, buf.writer());
return buf.items;
}

Expand Down
25 changes: 17 additions & 8 deletions src/browser/dump.zig
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,14 @@ const std = @import("std");
const parser = @import("netsurf.zig");
const Walker = @import("dom/walker.zig").WalkerChildren;

pub const Opts = struct {
exclude_scripts: bool = false,
};

// writer must be a std.io.Writer
pub fn writeHTML(doc: *parser.Document, writer: anytype) !void {
pub fn writeHTML(doc: *parser.Document, opts: Opts, writer: anytype) !void {
try writer.writeAll("<!DOCTYPE html>\n");
try writeChildren(parser.documentToNode(doc), writer);
try writeChildren(parser.documentToNode(doc), opts, writer);
try writer.writeAll("\n");
}

Expand Down Expand Up @@ -54,10 +58,15 @@ pub fn writeDocType(doc_type: *parser.DocumentType, writer: anytype) !void {
try writer.writeAll(">");
}

pub fn writeNode(node: *parser.Node, writer: anytype) anyerror!void {
pub fn writeNode(node: *parser.Node, opts: Opts, writer: anytype) anyerror!void {
switch (try parser.nodeType(node)) {
.element => {
// open the tag
const tag_type = try parser.elementHTMLGetTagType(@ptrCast(node));
if (tag_type == .script and opts.exclude_scripts) {
return;
}

const tag = try parser.nodeLocalName(node);
try writer.writeAll("<");
try writer.writeAll(tag);
Expand All @@ -82,12 +91,12 @@ pub fn writeNode(node: *parser.Node, writer: anytype) anyerror!void {
// void elements can't have any content.
if (try isVoid(parser.nodeToElement(node))) return;

if (try parser.elementHTMLGetTagType(@ptrCast(node)) == .script) {
if (tag_type == .script) {
try writer.writeAll(try parser.nodeTextContent(node) orelse "");
} else {
// write the children
// TODO avoid recursion
try writeChildren(node, writer);
try writeChildren(node, opts, writer);
}

// close the tag
Expand Down Expand Up @@ -129,12 +138,12 @@ pub fn writeNode(node: *parser.Node, writer: anytype) anyerror!void {
}

// writer must be a std.io.Writer
pub fn writeChildren(root: *parser.Node, writer: anytype) !void {
pub fn writeChildren(root: *parser.Node, opts: Opts, writer: anytype) !void {
const walker = Walker{};
var next: ?*parser.Node = null;
while (true) {
next = try walker.get_next(root, next) orelse break;
try writeNode(next.?, writer);
try writeNode(next.?, opts, writer);
}
}

Expand Down Expand Up @@ -238,6 +247,6 @@ fn testWriteFullHTML(comptime expected: []const u8, src: []const u8) !void {
defer parser.documentHTMLClose(doc_html) catch {};

const doc = parser.documentHTMLToDocument(doc_html);
try writeHTML(doc, buf.writer(testing.allocator));
try writeHTML(doc, .{}, buf.writer(testing.allocator));
try testing.expectEqualStrings(expected, buf.items);
}
4 changes: 2 additions & 2 deletions src/browser/page.zig
Original file line number Diff line number Diff line change
Expand Up @@ -142,15 +142,15 @@ pub const Page = struct {
}

// dump writes the page content into the given file.
pub fn dump(self: *const Page, out: std.fs.File) !void {
pub fn dump(self: *const Page, opts: Dump.Opts, 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);
}

// if the page has a pointer to a document, dumps the HTML.
const doc = parser.documentHTMLToDocument(self.window.document);
try Dump.writeHTML(doc, out);
try Dump.writeHTML(doc, opts, out);
}

pub fn fetchModuleSource(ctx: *anyopaque, src: []const u8) !?[]const u8 {
Expand Down
4 changes: 2 additions & 2 deletions src/browser/xmlserializer/xmlserializer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ pub const XMLSerializer = struct {
pub fn _serializeToString(_: *const XMLSerializer, root: *parser.Node, page: *Page) ![]const u8 {
var buf = std.ArrayList(u8).init(page.arena);
switch (try parser.nodeType(root)) {
.document => try dump.writeHTML(@as(*parser.Document, @ptrCast(root)), buf.writer()),
.document => try dump.writeHTML(@as(*parser.Document, @ptrCast(root)), .{}, buf.writer()),
.document_type => try dump.writeDocType(@as(*parser.DocumentType, @ptrCast(root)), buf.writer()),
else => try dump.writeNode(root, buf.writer()),
else => try dump.writeNode(root, .{}, buf.writer()),
}
return buf.items;
}
Expand Down
14 changes: 13 additions & 1 deletion src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ fn run(alloc: Allocator) !void {

// dump
if (opts.dump) {
try page.dump(std.io.getStdOut());
try page.dump(.{ .exclude_scripts = opts.noscript }, std.io.getStdOut());
}
},
else => unreachable,
Expand Down Expand Up @@ -212,6 +212,7 @@ const Command = struct {
url: []const u8,
dump: bool = false,
common: Common,
noscript: bool = false,
};

const Common = struct {
Expand Down Expand Up @@ -275,6 +276,7 @@ const Command = struct {
\\Options:
\\--dump Dumps document to stdout.
\\ Defaults to false.
\\--noscript Exclude <script> tags in dump. Defaults to false.
\\
++ common_options ++
\\
Expand Down Expand Up @@ -352,6 +354,9 @@ fn inferMode(opt: []const u8) ?App.RunMode {
if (std.mem.eql(u8, opt, "--dump")) {
return .fetch;
}
if (std.mem.eql(u8, opt, "--noscript")) {
return .fetch;
}
if (std.mem.startsWith(u8, opt, "--") == false) {
return .fetch;
}
Expand Down Expand Up @@ -437,6 +442,7 @@ fn parseFetchArgs(
args: *std.process.ArgIterator,
) !Command.Fetch {
var dump: bool = false;
var noscript: bool = true;
var url: ?[]const u8 = null;
var common: Command.Common = .{};

Expand All @@ -446,6 +452,11 @@ fn parseFetchArgs(
continue;
}

if (std.mem.eql(u8, "--noscript", opt)) {
noscript = true;
continue;
}

if (try parseCommonArg(allocator, opt, args, &common)) {
continue;
}
Expand All @@ -471,6 +482,7 @@ fn parseFetchArgs(
.url = url.?,
.dump = dump,
.common = common,
.noscript = noscript,
};
}

Expand Down