Skip to content
Closed
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
38 changes: 22 additions & 16 deletions src/browser/page.zig
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,11 @@ pub const Page = struct {

// if the url is about:blank, nothing to do.
if (std.mem.eql(u8, "about:blank", request_url.raw)) {
var fbs = std.io.fixedBufferStream("");
try self.loadHTMLDoc(fbs.reader(), "utf-8");
// 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
try HTMLDocument.documentIsComplete(self.window.document.?, &self.state);
return;
}

Expand Down Expand Up @@ -225,6 +230,7 @@ pub const Page = struct {

if (mime.isHTML()) {
try self.loadHTMLDoc(&response, mime.charset orelse "utf-8");
try self.processHTMLDoc();
} else {
log.info("non-HTML document: {s}", .{content_type orelse "null"});
var arr: std.ArrayListUnmanaged(u8) = .{};
Expand All @@ -243,29 +249,16 @@ pub const Page = struct {

// https://html.spec.whatwg.org/#read-html
fn loadHTMLDoc(self: *Page, reader: anytype, charset: []const u8) !void {
const arena = self.arena;

log.debug("parse html with charset {s}", .{charset});

const ccharset = try arena.dupeZ(u8, charset);
const ccharset = try self.arena.dupeZ(u8, charset);

const html_doc = try parser.documentHTMLParse(reader, ccharset);
const doc = parser.documentHTMLToDocument(html_doc);

// save a document's pointer in the page.
self.doc = doc;

const document_element = (try parser.documentGetDocumentElement(doc)) orelse return error.DocumentElementError;
try parser.eventTargetAddEventListener(
parser.toEventTarget(parser.Element, document_element),
"click",
&self.window_clicked_event_node,
false,
);

// TODO set document.readyState to interactive
// https://html.spec.whatwg.org/#reporting-document-loading-status

// inject the URL to the document including the fragment.
try parser.documentSetDocumentURI(doc, self.url.raw);

Expand All @@ -274,6 +267,19 @@ pub const Page = struct {
self.window.setStorageShelf(
try self.session.storage_shed.getOrPut(try self.origin(self.arena)),
);
}

fn processHTMLDoc(self: *Page) !void {
const doc = self.doc.?;
const html_doc = self.window.document.?;

const document_element = (try parser.documentGetDocumentElement(doc)) orelse return error.DocumentElementError;
try parser.eventTargetAddEventListener(
parser.toEventTarget(parser.Element, document_element),
"click",
&self.window_clicked_event_node,
false,
);

// https://html.spec.whatwg.org/#read-html

Expand Down Expand Up @@ -320,12 +326,12 @@ pub const Page = struct {
// > parsing and evaluated as soon as it is available.
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#async
if (script.is_async) {
try async_scripts.append(arena, script);
try async_scripts.append(self.arena, script);
continue;
}

if (script.is_defer) {
try defer_scripts.append(arena, script);
try defer_scripts.append(self.arena, script);
continue;
}

Expand Down
7 changes: 7 additions & 0 deletions src/cdp/domains/target.zig
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ fn createTarget(cmd: anytype) !void {
bc.target_id = target_id;

var page = try bc.session.createPage();
// Navigate to about:blank such that the window.document are created and set
const url = @import("../../url.zig").URL.about_blank;
try page.navigate(url, .{});
{
const aux_data = try std.fmt.allocPrint(cmd.arena, "{{\"isDefault\":true,\"type\":\"default\",\"frameId\":\"{s}\"}}", .{target_id});
bc.inspector.contextCreated(
Expand Down Expand Up @@ -501,6 +504,10 @@ test "cdp.target: createTarget" {
// should create a browser context
const bc = ctx.cdp().browser_context.?;
try ctx.expectSentEvent("Target.targetCreated", .{ .targetInfo = .{ .url = "about:blank", .title = "about:blank", .attached = false, .type = "page", .canAccessOpener = false, .browserContextId = bc.id, .targetId = bc.target_id.? } }, .{});

// Even about:blank should set the window.document
const page = ctx.cdp().browser_context.?.session.page.?;
try testing.expect(page.window.document != null);
}

{
Expand Down
1 change: 1 addition & 0 deletions src/url.zig
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub const URL = struct {
raw: []const u8,

pub const empty = URL{ .uri = .{ .scheme = "" }, .raw = "" };
pub const about_blank = URL{ .uri = .{ .scheme = "" }, .raw = "about:blank" };

// We assume str will last as long as the URL
// In some cases, this is safe to do, because we know the URL is short lived.
Expand Down