mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-12-14 15:28:57 +00:00
add parsed DocType to document (and handle dumping it)
This commit is contained in:
@@ -868,7 +868,6 @@ fn notifyNetworkAlmostIdle(self: *Page) void {
|
||||
|
||||
// called from the parser
|
||||
pub fn appendNew(self: *Page, parent: *Node, child: Node.NodeOrText) !void {
|
||||
// TODO: should some of this be pushed into appendNode... ?
|
||||
const node = switch (child) {
|
||||
.node => |n| n,
|
||||
.text => |txt| blk: {
|
||||
|
||||
@@ -24,6 +24,7 @@ const Slot = @import("webapi/element/html/Slot.zig");
|
||||
pub const RootOpts = struct {
|
||||
with_base: bool = false,
|
||||
strip: Opts.Strip = .{},
|
||||
shadow: Opts.Shadow = .rendered,
|
||||
};
|
||||
|
||||
pub const Opts = struct {
|
||||
@@ -48,10 +49,10 @@ pub const Opts = struct {
|
||||
};
|
||||
};
|
||||
|
||||
pub fn root(opts: RootOpts, writer: *std.Io.Writer, page: *Page) !void {
|
||||
const doc = page.document;
|
||||
pub fn root(doc: *Node.Document, opts: RootOpts, writer: *std.Io.Writer, page: *Page) !void {
|
||||
if (opts.with_base) {
|
||||
if (doc.is(Node.Document.HTMLDocument)) |html_doc| {
|
||||
try writer.writeAll("<!DOCTYPE html>");
|
||||
const parent = if (html_doc.getHead()) |head| head.asNode() else doc.asNode();
|
||||
const base = try doc.createElement("base", null, page);
|
||||
try base.setAttributeSafe("base", page.url, page);
|
||||
@@ -59,7 +60,7 @@ pub fn root(opts: RootOpts, writer: *std.Io.Writer, page: *Page) !void {
|
||||
}
|
||||
}
|
||||
|
||||
return deep(doc.asNode(), .{ .strip = opts.strip }, writer, page);
|
||||
return deep(doc.asNode(), .{ .strip = opts.strip, .shadow = opts.shadow }, writer, page);
|
||||
}
|
||||
|
||||
pub fn deep(node: *Node, opts: Opts, writer: *std.Io.Writer, page: *Page) error{WriteFailed}!void {
|
||||
@@ -130,7 +131,29 @@ fn _deep(node: *Node, opts: Opts, comptime force_slot: bool, writer: *std.Io.Wri
|
||||
}
|
||||
},
|
||||
.document => try children(node, opts, writer, page),
|
||||
.document_type => {},
|
||||
.document_type => |dt| {
|
||||
try writer.writeAll("<!DOCTYPE ");
|
||||
try writer.writeAll(dt.getName());
|
||||
|
||||
const public_id = dt.getPublicId();
|
||||
const system_id = dt.getSystemId();
|
||||
if (public_id.len != 0 and system_id.len != 0) {
|
||||
try writer.writeAll(" PUBLIC \"");
|
||||
try writeEscapedText(public_id, writer);
|
||||
try writer.writeAll("\" \"");
|
||||
try writeEscapedText(system_id, writer);
|
||||
try writer.writeByte('"');
|
||||
} else if (public_id.len != 0) {
|
||||
try writer.writeAll(" PUBLIC \"");
|
||||
try writeEscapedText(public_id, writer);
|
||||
try writer.writeByte('"');
|
||||
} else if (system_id.len != 0) {
|
||||
try writer.writeAll(" SYSTEM \"");
|
||||
try writeEscapedText(system_id, writer);
|
||||
try writer.writeByte('"');
|
||||
}
|
||||
try writer.writeAll(">\n");
|
||||
},
|
||||
.document_fragment => try children(node, opts, writer, page),
|
||||
.attribute => unreachable,
|
||||
}
|
||||
|
||||
@@ -219,17 +219,25 @@ fn _createCommentCallback(self: *Parser, str: []const u8) !*anyopaque {
|
||||
}
|
||||
|
||||
fn appendDoctypeToDocument(ctx: *anyopaque, name: h5e.StringSlice, public_id: h5e.StringSlice, system_id: h5e.StringSlice) callconv(.c) void {
|
||||
_ = public_id;
|
||||
_ = system_id;
|
||||
|
||||
const self: *Parser = @ptrCast(@alignCast(ctx));
|
||||
self._appendDoctypeToDocument(name.slice()) catch |err| {
|
||||
self._appendDoctypeToDocument(name.slice(), public_id.slice(), system_id.slice()) catch |err| {
|
||||
self.err = .{ .err = err, .source = .append_doctype_to_document };
|
||||
};
|
||||
}
|
||||
fn _appendDoctypeToDocument(self: *Parser, name: []const u8) !void {
|
||||
_ = self;
|
||||
_ = name;
|
||||
fn _appendDoctypeToDocument(self: *Parser, name: []const u8, public_id: []const u8, system_id: []const u8) !void {
|
||||
const page = self.page;
|
||||
|
||||
// Create the DocumentType node
|
||||
const DocumentType = @import("../webapi/DocumentType.zig");
|
||||
const doctype = try page._factory.node(DocumentType{
|
||||
._proto = undefined,
|
||||
._name = try page.dupeString(name),
|
||||
._public_id = try page.dupeString(public_id),
|
||||
._system_id = try page.dupeString(system_id),
|
||||
});
|
||||
|
||||
// Append it to the document
|
||||
try page.appendNew(self.container.node, .{ .node = doctype.asNode() });
|
||||
}
|
||||
|
||||
fn addAttrsIfMissingCallback(ctx: *anyopaque, target_ref: *anyopaque, attributes: h5e.AttributeIterator) callconv(.c) void {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
</body>
|
||||
|
||||
<script id=document>
|
||||
testing.expectEqual(10, document.childNodes[0].nodeType);
|
||||
testing.expectEqual(null, document.parentNode);
|
||||
testing.expectEqual(undefined, document.getCurrentScript);
|
||||
testing.expectEqual("http://127.0.0.1:9582/src/browser/tests/document/document.html", document.URL);
|
||||
|
||||
@@ -32,7 +32,11 @@ pub fn init() XMLSerializer {
|
||||
pub fn serializeToString(self: *const XMLSerializer, node: *Node, page: *Page) ![]const u8 {
|
||||
_ = self;
|
||||
var buf = std.Io.Writer.Allocating.init(page.call_arena);
|
||||
try dump.deep(node, .{ .shadow = .skip }, &buf.writer, page);
|
||||
if (node.is(Node.Document)) |doc| {
|
||||
try dump.root(doc, .{ .shadow = .skip }, &buf.writer, page);
|
||||
} else {
|
||||
try dump.deep(node, .{ .shadow = .skip }, &buf.writer, page);
|
||||
}
|
||||
return buf.written();
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ pub fn fetch(app: *App, url: [:0]const u8, opts: FetchOpts) !void {
|
||||
_ = session.fetchWait(opts.wait_ms);
|
||||
|
||||
const writer = opts.writer orelse return;
|
||||
try dump.root(opts.dump, writer, page);
|
||||
try dump.root(page.window._document, opts.dump, writer, page);
|
||||
try writer.flush();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user