mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-12-15 15:58: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
|
// called from the parser
|
||||||
pub fn appendNew(self: *Page, parent: *Node, child: Node.NodeOrText) !void {
|
pub fn appendNew(self: *Page, parent: *Node, child: Node.NodeOrText) !void {
|
||||||
// TODO: should some of this be pushed into appendNode... ?
|
|
||||||
const node = switch (child) {
|
const node = switch (child) {
|
||||||
.node => |n| n,
|
.node => |n| n,
|
||||||
.text => |txt| blk: {
|
.text => |txt| blk: {
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ const Slot = @import("webapi/element/html/Slot.zig");
|
|||||||
pub const RootOpts = struct {
|
pub const RootOpts = struct {
|
||||||
with_base: bool = false,
|
with_base: bool = false,
|
||||||
strip: Opts.Strip = .{},
|
strip: Opts.Strip = .{},
|
||||||
|
shadow: Opts.Shadow = .rendered,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Opts = struct {
|
pub const Opts = struct {
|
||||||
@@ -48,10 +49,10 @@ pub const Opts = struct {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn root(opts: RootOpts, writer: *std.Io.Writer, page: *Page) !void {
|
pub fn root(doc: *Node.Document, opts: RootOpts, writer: *std.Io.Writer, page: *Page) !void {
|
||||||
const doc = page.document;
|
|
||||||
if (opts.with_base) {
|
if (opts.with_base) {
|
||||||
if (doc.is(Node.Document.HTMLDocument)) |html_doc| {
|
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 parent = if (html_doc.getHead()) |head| head.asNode() else doc.asNode();
|
||||||
const base = try doc.createElement("base", null, page);
|
const base = try doc.createElement("base", null, page);
|
||||||
try base.setAttributeSafe("base", page.url, 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 {
|
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 => 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),
|
.document_fragment => try children(node, opts, writer, page),
|
||||||
.attribute => unreachable,
|
.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 {
|
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));
|
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 };
|
self.err = .{ .err = err, .source = .append_doctype_to_document };
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
fn _appendDoctypeToDocument(self: *Parser, name: []const u8) !void {
|
fn _appendDoctypeToDocument(self: *Parser, name: []const u8, public_id: []const u8, system_id: []const u8) !void {
|
||||||
_ = self;
|
const page = self.page;
|
||||||
_ = name;
|
|
||||||
|
// 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 {
|
fn addAttrsIfMissingCallback(ctx: *anyopaque, target_ref: *anyopaque, attributes: h5e.AttributeIterator) callconv(.c) void {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
</body>
|
</body>
|
||||||
|
|
||||||
<script id=document>
|
<script id=document>
|
||||||
|
testing.expectEqual(10, document.childNodes[0].nodeType);
|
||||||
testing.expectEqual(null, document.parentNode);
|
testing.expectEqual(null, document.parentNode);
|
||||||
testing.expectEqual(undefined, document.getCurrentScript);
|
testing.expectEqual(undefined, document.getCurrentScript);
|
||||||
testing.expectEqual("http://127.0.0.1:9582/src/browser/tests/document/document.html", document.URL);
|
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 {
|
pub fn serializeToString(self: *const XMLSerializer, node: *Node, page: *Page) ![]const u8 {
|
||||||
_ = self;
|
_ = self;
|
||||||
var buf = std.Io.Writer.Allocating.init(page.call_arena);
|
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();
|
return buf.written();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ pub fn fetch(app: *App, url: [:0]const u8, opts: FetchOpts) !void {
|
|||||||
_ = session.fetchWait(opts.wait_ms);
|
_ = session.fetchWait(opts.wait_ms);
|
||||||
|
|
||||||
const writer = opts.writer orelse return;
|
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();
|
try writer.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user