diff --git a/src/browser/page.zig b/src/browser/page.zig index 88f61764..06fdf018 100644 --- a/src/browser/page.zig +++ b/src/browser/page.zig @@ -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; } @@ -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) = .{}; @@ -243,11 +249,9 @@ 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); @@ -255,17 +259,6 @@ pub const Page = struct { // 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); @@ -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 @@ -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; } diff --git a/src/cdp/domains/target.zig b/src/cdp/domains/target.zig index fca78351..662deb34 100644 --- a/src/cdp/domains/target.zig +++ b/src/cdp/domains/target.zig @@ -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( @@ -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); } { diff --git a/src/url.zig b/src/url.zig index 3313eca5..fb28c4af 100644 --- a/src/url.zig +++ b/src/url.zig @@ -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.