mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 07:03:29 +00:00
default:blank as default document
This commit is contained in:
@@ -30,7 +30,7 @@ pub const Comment = struct {
|
|||||||
|
|
||||||
pub fn constructor(data: ?[]const u8, state: *const SessionState) !*parser.Comment {
|
pub fn constructor(data: ?[]const u8, state: *const SessionState) !*parser.Comment {
|
||||||
return parser.documentCreateComment(
|
return parser.documentCreateComment(
|
||||||
parser.documentHTMLToDocument(state.window.document.?),
|
parser.documentHTMLToDocument(state.window.document),
|
||||||
data orelse "",
|
data orelse "",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,12 +41,12 @@ pub const Document = struct {
|
|||||||
|
|
||||||
pub fn constructor(state: *const SessionState) !*parser.DocumentHTML {
|
pub fn constructor(state: *const SessionState) !*parser.DocumentHTML {
|
||||||
const doc = try parser.documentCreateDocument(
|
const doc = try parser.documentCreateDocument(
|
||||||
try parser.documentHTMLGetTitle(state.window.document.?),
|
try parser.documentHTMLGetTitle(state.window.document),
|
||||||
);
|
);
|
||||||
|
|
||||||
// we have to work w/ document instead of html document.
|
// we have to work w/ document instead of html document.
|
||||||
const ddoc = parser.documentHTMLToDocument(doc);
|
const ddoc = parser.documentHTMLToDocument(doc);
|
||||||
const ccur = parser.documentHTMLToDocument(state.window.document.?);
|
const ccur = parser.documentHTMLToDocument(state.window.document);
|
||||||
try parser.documentSetDocumentURI(ddoc, try parser.documentGetDocumentURI(ccur));
|
try parser.documentSetDocumentURI(ddoc, try parser.documentGetDocumentURI(ccur));
|
||||||
try parser.documentSetInputEncoding(ddoc, try parser.documentGetInputEncoding(ccur));
|
try parser.documentSetInputEncoding(ddoc, try parser.documentGetInputEncoding(ccur));
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ pub const DocumentFragment = struct {
|
|||||||
|
|
||||||
pub fn constructor(state: *const SessionState) !*parser.DocumentFragment {
|
pub fn constructor(state: *const SessionState) !*parser.DocumentFragment {
|
||||||
return parser.documentCreateDocumentFragment(
|
return parser.documentCreateDocumentFragment(
|
||||||
parser.documentHTMLToDocument(state.window.document.?),
|
parser.documentHTMLToDocument(state.window.document),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -370,7 +370,7 @@ pub const Element = struct {
|
|||||||
pub fn _getBoundingClientRect(self: *parser.Element, state: *SessionState) !DOMRect {
|
pub fn _getBoundingClientRect(self: *parser.Element, state: *SessionState) !DOMRect {
|
||||||
// Since we are lazy rendering we need to do this check. We could store the renderer in a viewport such that it could cache these, but it would require tracking changes.
|
// Since we are lazy rendering we need to do this check. We could store the renderer in a viewport such that it could cache these, but it would require tracking changes.
|
||||||
const root = try parser.nodeGetRootNode(parser.elementToNode(self));
|
const root = try parser.nodeGetRootNode(parser.elementToNode(self));
|
||||||
if (root != parser.documentToNode(parser.documentHTMLToDocument(state.window.document.?))) {
|
if (root != parser.documentToNode(parser.documentHTMLToDocument(state.window.document))) {
|
||||||
return DOMRect{ .x = 0, .y = 0, .width = 0, .height = 0 };
|
return DOMRect{ .x = 0, .y = 0, .width = 0, .height = 0 };
|
||||||
}
|
}
|
||||||
return state.renderer.getRect(self);
|
return state.renderer.getRect(self);
|
||||||
@@ -381,7 +381,7 @@ pub const Element = struct {
|
|||||||
// Returns an empty array if the element is eventually detached from the main window
|
// Returns an empty array if the element is eventually detached from the main window
|
||||||
pub fn _getClientRects(self: *parser.Element, state: *SessionState) ![]DOMRect {
|
pub fn _getClientRects(self: *parser.Element, state: *SessionState) ![]DOMRect {
|
||||||
const root = try parser.nodeGetRootNode(parser.elementToNode(self));
|
const root = try parser.nodeGetRootNode(parser.elementToNode(self));
|
||||||
if (root != parser.documentToNode(parser.documentHTMLToDocument(state.window.document.?))) {
|
if (root != parser.documentToNode(parser.documentHTMLToDocument(state.window.document))) {
|
||||||
return &.{};
|
return &.{};
|
||||||
}
|
}
|
||||||
const heap_ptr = try state.call_arena.create(DOMRect);
|
const heap_ptr = try state.call_arena.create(DOMRect);
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ pub const IntersectionObserver = struct {
|
|||||||
// new IntersectionObserver(callback, options) [not supported yet]
|
// new IntersectionObserver(callback, options) [not supported yet]
|
||||||
pub fn constructor(callback: Env.Callback, options_: ?IntersectionObserverOptions, state: *SessionState) !IntersectionObserver {
|
pub fn constructor(callback: Env.Callback, options_: ?IntersectionObserverOptions, state: *SessionState) !IntersectionObserver {
|
||||||
var options = IntersectionObserverOptions{
|
var options = IntersectionObserverOptions{
|
||||||
.root = parser.documentToNode(parser.documentHTMLToDocument(state.window.document.?)),
|
.root = parser.documentToNode(parser.documentHTMLToDocument(state.window.document)),
|
||||||
.rootMargin = "0px 0px 0px 0px",
|
.rootMargin = "0px 0px 0px 0px",
|
||||||
.threshold = &.{0.0},
|
.threshold = &.{0.0},
|
||||||
};
|
};
|
||||||
@@ -142,7 +142,7 @@ pub const IntersectionObserverEntry = struct {
|
|||||||
// Returns a DOMRectReadOnly for the intersection observer's root.
|
// Returns a DOMRectReadOnly for the intersection observer's root.
|
||||||
pub fn get_rootBounds(self: *const IntersectionObserverEntry) !Element.DOMRect {
|
pub fn get_rootBounds(self: *const IntersectionObserverEntry) !Element.DOMRect {
|
||||||
const root = self.options.root.?;
|
const root = self.options.root.?;
|
||||||
if (@intFromPtr(root) == @intFromPtr(self.state.window.document.?)) {
|
if (@intFromPtr(root) == @intFromPtr(self.state.window.document)) {
|
||||||
return self.state.renderer.boundingRect();
|
return self.state.renderer.boundingRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ pub const ProcessingInstruction = struct {
|
|||||||
// a simple workaround.
|
// a simple workaround.
|
||||||
pub fn _cloneNode(self: *parser.ProcessingInstruction, _: ?bool, state: *SessionState) !*parser.ProcessingInstruction {
|
pub fn _cloneNode(self: *parser.ProcessingInstruction, _: ?bool, state: *SessionState) !*parser.ProcessingInstruction {
|
||||||
return try parser.documentCreateProcessingInstruction(
|
return try parser.documentCreateProcessingInstruction(
|
||||||
@ptrCast(state.window.document.?),
|
@ptrCast(state.window.document),
|
||||||
try get_target(self),
|
try get_target(self),
|
||||||
(try get_data(self)) orelse "",
|
(try get_data(self)) orelse "",
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ pub const Text = struct {
|
|||||||
|
|
||||||
pub fn constructor(data: ?[]const u8, state: *const SessionState) !*parser.Text {
|
pub fn constructor(data: ?[]const u8, state: *const SessionState) !*parser.Text {
|
||||||
return parser.documentCreateTextNode(
|
return parser.documentCreateTextNode(
|
||||||
parser.documentHTMLToDocument(state.window.document.?),
|
parser.documentHTMLToDocument(state.window.document),
|
||||||
data orelse "",
|
data orelse "",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -255,10 +255,10 @@ pub const HTMLDocument = struct {
|
|||||||
// Thus we can add the HtmlHtmlElement and it's child HTMLBodyElement to the returned list.
|
// Thus we can add the HtmlHtmlElement and it's child HTMLBodyElement to the returned list.
|
||||||
// TBD Should we instead return every parent that is an element? Note that a child does not physically need to be overlapping the parent.
|
// TBD Should we instead return every parent that is an element? Note that a child does not physically need to be overlapping the parent.
|
||||||
// Should we do a render pass on demand?
|
// Should we do a render pass on demand?
|
||||||
const doc_elem = try parser.documentGetDocumentElement(parser.documentHTMLToDocument(state.window.document.?)) orelse {
|
const doc_elem = try parser.documentGetDocumentElement(parser.documentHTMLToDocument(state.window.document)) orelse {
|
||||||
return list.items;
|
return list.items;
|
||||||
};
|
};
|
||||||
if (try parser.documentHTMLBody(state.window.document.?)) |body| {
|
if (try parser.documentHTMLBody(state.window.document)) |body| {
|
||||||
list.appendAssumeCapacity(try Element.toInterface(parser.bodyToElement(body)));
|
list.appendAssumeCapacity(try Element.toInterface(parser.bodyToElement(body)));
|
||||||
}
|
}
|
||||||
list.appendAssumeCapacity(try Element.toInterface(doc_elem));
|
list.appendAssumeCapacity(try Element.toInterface(doc_elem));
|
||||||
@@ -383,12 +383,12 @@ test "Browser.HTML.Document" {
|
|||||||
.{ "document.readyState", "loading" },
|
.{ "document.readyState", "loading" },
|
||||||
}, .{});
|
}, .{});
|
||||||
|
|
||||||
try HTMLDocument.documentIsLoaded(runner.window.document.?, &runner.state);
|
try HTMLDocument.documentIsLoaded(runner.window.document, &runner.state);
|
||||||
try runner.testCases(&.{
|
try runner.testCases(&.{
|
||||||
.{ "document.readyState", "interactive" },
|
.{ "document.readyState", "interactive" },
|
||||||
}, .{});
|
}, .{});
|
||||||
|
|
||||||
try HTMLDocument.documentIsComplete(runner.window.document.?, &runner.state);
|
try HTMLDocument.documentIsComplete(runner.window.document, &runner.state);
|
||||||
try runner.testCases(&.{
|
try runner.testCases(&.{
|
||||||
.{ "document.readyState", "complete" },
|
.{ "document.readyState", "complete" },
|
||||||
}, .{});
|
}, .{});
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ pub const Window = struct {
|
|||||||
// Extend libdom event target for pure zig struct.
|
// Extend libdom event target for pure zig struct.
|
||||||
base: parser.EventTargetTBase = parser.EventTargetTBase{},
|
base: parser.EventTargetTBase = parser.EventTargetTBase{},
|
||||||
|
|
||||||
document: ?*parser.DocumentHTML = null,
|
document: *parser.DocumentHTML,
|
||||||
target: []const u8 = "",
|
target: []const u8 = "",
|
||||||
history: History = .{},
|
history: History = .{},
|
||||||
location: Location = .{},
|
location: Location = .{},
|
||||||
@@ -60,7 +60,13 @@ pub const Window = struct {
|
|||||||
performance: Performance,
|
performance: Performance,
|
||||||
|
|
||||||
pub fn create(target: ?[]const u8, navigator: ?Navigator) !Window {
|
pub fn create(target: ?[]const u8, navigator: ?Navigator) !Window {
|
||||||
|
var fbs = std.io.fixedBufferStream("");
|
||||||
|
const html_doc = try parser.documentHTMLParse(fbs.reader(), "utf-8");
|
||||||
|
const doc = parser.documentHTMLToDocument(html_doc);
|
||||||
|
try parser.documentSetDocumentURI(doc, "about:blank");
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
|
.document = html_doc,
|
||||||
.target = target orelse "",
|
.target = target orelse "",
|
||||||
.navigator = navigator orelse .{},
|
.navigator = navigator orelse .{},
|
||||||
.performance = .{ .time_origin = try std.time.Timer.start() },
|
.performance = .{ .time_origin = try std.time.Timer.start() },
|
||||||
@@ -69,9 +75,7 @@ pub const Window = struct {
|
|||||||
|
|
||||||
pub fn replaceLocation(self: *Window, loc: Location) !void {
|
pub fn replaceLocation(self: *Window, loc: Location) !void {
|
||||||
self.location = loc;
|
self.location = loc;
|
||||||
if (self.document) |doc| {
|
try parser.documentHTMLSetLocation(Location, self.document, &self.location);
|
||||||
try parser.documentHTMLSetLocation(Location, doc, &self.location);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn replaceDocument(self: *Window, doc: *parser.DocumentHTML) !void {
|
pub fn replaceDocument(self: *Window, doc: *parser.DocumentHTML) !void {
|
||||||
|
|||||||
@@ -60,8 +60,6 @@ pub const Page = struct {
|
|||||||
// Serves are the root object of our JavaScript environment
|
// Serves are the root object of our JavaScript environment
|
||||||
window: Window,
|
window: Window,
|
||||||
|
|
||||||
doc: ?*parser.Document,
|
|
||||||
|
|
||||||
// The URL of the page
|
// The URL of the page
|
||||||
url: URL,
|
url: URL,
|
||||||
|
|
||||||
@@ -87,7 +85,6 @@ pub const Page = struct {
|
|||||||
self.* = .{
|
self.* = .{
|
||||||
.window = try Window.create(null, null),
|
.window = try Window.create(null, null),
|
||||||
.arena = arena,
|
.arena = arena,
|
||||||
.doc = null,
|
|
||||||
.raw_data = null,
|
.raw_data = null,
|
||||||
.url = URL.empty,
|
.url = URL.empty,
|
||||||
.session = session,
|
.session = session,
|
||||||
@@ -121,15 +118,14 @@ pub const Page = struct {
|
|||||||
|
|
||||||
// dump writes the page content into the given file.
|
// 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, out: std.fs.File) !void {
|
||||||
// if no HTML document pointer available, dump the data content only.
|
if (self.raw_data) |raw_data| {
|
||||||
if (self.doc == null) {
|
// raw_data was set if the document was not HTML, dump the data content only.
|
||||||
// no data loaded, nothing to do.
|
return try out.writeAll(raw_data);
|
||||||
if (self.raw_data == null) return;
|
|
||||||
return try out.writeAll(self.raw_data.?);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the page has a pointer to a document, dumps the HTML.
|
// if the page has a pointer to a document, dumps the HTML.
|
||||||
try Dump.writeHTML(self.doc.?, out);
|
const doc = parser.documentHTMLToDocument(self.window.document);
|
||||||
|
try Dump.writeHTML(doc, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fetchModuleSource(ctx: *anyopaque, specifier: []const u8) !?[]const u8 {
|
pub fn fetchModuleSource(ctx: *anyopaque, specifier: []const u8) !?[]const u8 {
|
||||||
@@ -187,7 +183,7 @@ pub const Page = struct {
|
|||||||
try self.loadHTMLDoc(fbs.reader(), "utf-8");
|
try self.loadHTMLDoc(fbs.reader(), "utf-8");
|
||||||
// We do not processHTMLDoc here as we know we don't have any scripts
|
// We do not processHTMLDoc here as we know we don't have any scripts
|
||||||
// This assumption may be false when CDP Page.addScriptToEvaluateOnNewDocument is implemented
|
// This assumption may be false when CDP Page.addScriptToEvaluateOnNewDocument is implemented
|
||||||
try HTMLDocument.documentIsComplete(self.window.document.?, &self.state);
|
try HTMLDocument.documentIsComplete(self.window.document, &self.state);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,6 +225,7 @@ pub const Page = struct {
|
|||||||
} orelse .unknown;
|
} orelse .unknown;
|
||||||
|
|
||||||
if (mime.isHTML()) {
|
if (mime.isHTML()) {
|
||||||
|
self.raw_data = null;
|
||||||
try self.loadHTMLDoc(&response, mime.charset orelse "utf-8");
|
try self.loadHTMLDoc(&response, mime.charset orelse "utf-8");
|
||||||
try self.processHTMLDoc();
|
try self.processHTMLDoc();
|
||||||
} else {
|
} else {
|
||||||
@@ -256,9 +253,6 @@ pub const Page = struct {
|
|||||||
const html_doc = try parser.documentHTMLParse(reader, ccharset);
|
const html_doc = try parser.documentHTMLParse(reader, ccharset);
|
||||||
const doc = parser.documentHTMLToDocument(html_doc);
|
const doc = parser.documentHTMLToDocument(html_doc);
|
||||||
|
|
||||||
// save a document's pointer in the page.
|
|
||||||
self.doc = doc;
|
|
||||||
|
|
||||||
// inject the URL to the document including the fragment.
|
// inject the URL to the document including the fragment.
|
||||||
try parser.documentSetDocumentURI(doc, self.url.raw);
|
try parser.documentSetDocumentURI(doc, self.url.raw);
|
||||||
|
|
||||||
@@ -270,8 +264,8 @@ pub const Page = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn processHTMLDoc(self: *Page) !void {
|
fn processHTMLDoc(self: *Page) !void {
|
||||||
const doc = self.doc.?;
|
const html_doc = self.window.document;
|
||||||
const html_doc = self.window.document.?;
|
const doc = parser.documentHTMLToDocument(html_doc);
|
||||||
|
|
||||||
const document_element = (try parser.documentGetDocumentElement(doc)) orelse return error.DocumentElementError;
|
const document_element = (try parser.documentGetDocumentElement(doc)) orelse return error.DocumentElementError;
|
||||||
try parser.eventTargetAddEventListener(
|
try parser.eventTargetAddEventListener(
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ fn getDocument(cmd: anytype) !void {
|
|||||||
|
|
||||||
const bc = cmd.browser_context orelse return error.BrowserContextNotLoaded;
|
const bc = cmd.browser_context orelse return error.BrowserContextNotLoaded;
|
||||||
const page = bc.session.currentPage() orelse return error.PageNotLoaded;
|
const page = bc.session.currentPage() orelse return error.PageNotLoaded;
|
||||||
const doc = page.doc orelse return error.DocumentNotLoaded;
|
const doc = parser.documentHTMLToDocument(page.window.document);
|
||||||
|
|
||||||
const node = try bc.node_registry.register(parser.documentToNode(doc));
|
const node = try bc.node_registry.register(parser.documentToNode(doc));
|
||||||
return cmd.sendResult(.{ .root = bc.nodeWriter(node, .{}) }, .{});
|
return cmd.sendResult(.{ .root = bc.nodeWriter(node, .{}) }, .{});
|
||||||
@@ -74,7 +74,7 @@ fn performSearch(cmd: anytype) !void {
|
|||||||
|
|
||||||
const bc = cmd.browser_context orelse return error.BrowserContextNotLoaded;
|
const bc = cmd.browser_context orelse return error.BrowserContextNotLoaded;
|
||||||
const page = bc.session.currentPage() orelse return error.PageNotLoaded;
|
const page = bc.session.currentPage() orelse return error.PageNotLoaded;
|
||||||
const doc = page.doc orelse return error.DocumentNotLoaded;
|
const doc = parser.documentHTMLToDocument(page.window.document);
|
||||||
|
|
||||||
const allocator = cmd.cdp.allocator;
|
const allocator = cmd.cdp.allocator;
|
||||||
var list = try css.querySelectorAll(allocator, parser.documentToNode(doc), params.query);
|
var list = try css.querySelectorAll(allocator, parser.documentToNode(doc), params.query);
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ fn run(arena: Allocator, test_file: []const u8, loader: *FileLoader, err_out: *?
|
|||||||
try polyfill.load(arena, runner.scope);
|
try polyfill.load(arena, runner.scope);
|
||||||
|
|
||||||
// loop over the scripts.
|
// loop over the scripts.
|
||||||
const doc = parser.documentHTMLToDocument(runner.state.window.document.?);
|
const doc = parser.documentHTMLToDocument(runner.state.window.document);
|
||||||
const scripts = try parser.documentGetElementsByTagName(doc, "script");
|
const scripts = try parser.documentGetElementsByTagName(doc, "script");
|
||||||
const script_count = try parser.nodeListLength(scripts);
|
const script_count = try parser.nodeListLength(scripts);
|
||||||
for (0..script_count) |i| {
|
for (0..script_count) |i| {
|
||||||
|
|||||||
Reference in New Issue
Block a user