diff --git a/src/Notification.zig b/src/Notification.zig index 91fcb673..d01492c8 100644 --- a/src/Notification.zig +++ b/src/Notification.zig @@ -73,6 +73,7 @@ const EventListeners = struct { page_navigated: List = .{}, page_network_idle: List = .{}, page_network_almost_idle: List = .{}, + page_frame_created: List = .{}, http_request_fail: List = .{}, http_request_start: List = .{}, http_request_intercept: List = .{}, @@ -89,6 +90,7 @@ const Events = union(enum) { page_navigated: *const PageNavigated, page_network_idle: *const PageNetworkIdle, page_network_almost_idle: *const PageNetworkAlmostIdle, + page_frame_created: *const PageFrameCreated, http_request_fail: *const RequestFail, http_request_start: *const RequestStart, http_request_intercept: *const RequestIntercept, @@ -129,6 +131,12 @@ pub const PageNetworkAlmostIdle = struct { timestamp: u64, }; +pub const PageFrameCreated = struct { + page_id: u32, + parent_id: u32, + timestamp: u64, +}; + pub const RequestStart = struct { transfer: *Transfer, }; diff --git a/src/browser/Page.zig b/src/browser/Page.zig index c2f94c6d..e44fbc86 100644 --- a/src/browser/Page.zig +++ b/src/browser/Page.zig @@ -1201,16 +1201,23 @@ pub fn iframeAddedCallback(self: *Page, iframe: *Element.Html.IFrame) !void { return; } - const session = self._session; - iframe._executed = true; + + const session = self._session; + const page_id = session.nextPageId(); const page_frame = try self.arena.create(Page); - try Page.init(page_frame, session.nextPageId(), session, self); + try Page.init(page_frame, page_id, session, self); self._pending_loads += 1; page_frame.iframe = iframe; iframe._content_window = page_frame.window; + self._session.notification.dispatch(.page_frame_created, &.{ + .page_id = page_id, + .parent_id = self.id, + .timestamp = timestamp(.monotonic), + }); + page_frame.navigate(src, .{ .reason = .initialFrameNavigation }) catch |err| { log.warn(.page, "iframe navigate failure", .{ .url = src, .err = err }); self._pending_loads -= 1; diff --git a/src/cdp/cdp.zig b/src/cdp/cdp.zig index ae83ad17..d8ccfb2b 100644 --- a/src/cdp/cdp.zig +++ b/src/cdp/cdp.zig @@ -431,6 +431,7 @@ pub fn BrowserContext(comptime CDP_T: type) type { try notification.register(.page_created, self, onPageCreated); try notification.register(.page_navigate, self, onPageNavigate); try notification.register(.page_navigated, self, onPageNavigated); + try notification.register(.page_frame_created, self, onPageFrameCreated); } pub fn deinit(self: *Self) void { @@ -587,7 +588,6 @@ pub fn BrowserContext(comptime CDP_T: type) type { pub fn onPageNavigate(ctx: *anyopaque, msg: *const Notification.PageNavigate) !void { const self: *Self = @ptrCast(@alignCast(ctx)); - defer self.resetNotificationArena(); return @import("domains/page.zig").pageNavigate(self, msg); } @@ -597,6 +597,11 @@ pub fn BrowserContext(comptime CDP_T: type) type { return @import("domains/page.zig").pageNavigated(self.notification_arena, self, msg); } + pub fn onPageFrameCreated(ctx: *anyopaque, msg: *const Notification.PageFrameCreated) !void { + const self: *Self = @ptrCast(@alignCast(ctx)); + return @import("domains/page.zig").pageFrameCreated(self, msg); + } + pub fn onPageNetworkIdle(ctx: *anyopaque, msg: *const Notification.PageNetworkIdle) !void { const self: *Self = @ptrCast(@alignCast(ctx)); return @import("domains/page.zig").pageNetworkIdle(self, msg); @@ -609,19 +614,16 @@ pub fn BrowserContext(comptime CDP_T: type) type { pub fn onHttpRequestStart(ctx: *anyopaque, msg: *const Notification.RequestStart) !void { const self: *Self = @ptrCast(@alignCast(ctx)); - defer self.resetNotificationArena(); try @import("domains/network.zig").httpRequestStart(self, msg); } pub fn onHttpRequestIntercept(ctx: *anyopaque, msg: *const Notification.RequestIntercept) !void { const self: *Self = @ptrCast(@alignCast(ctx)); - defer self.resetNotificationArena(); try @import("domains/fetch.zig").requestIntercept(self, msg); } pub fn onHttpRequestFail(ctx: *anyopaque, msg: *const Notification.RequestFail) !void { const self: *Self = @ptrCast(@alignCast(ctx)); - defer self.resetNotificationArena(); return @import("domains/network.zig").httpRequestFail(self, msg); } @@ -633,7 +635,6 @@ pub fn BrowserContext(comptime CDP_T: type) type { pub fn onHttpRequestDone(ctx: *anyopaque, msg: *const Notification.RequestDone) !void { const self: *Self = @ptrCast(@alignCast(ctx)); - defer self.resetNotificationArena(); return @import("domains/network.zig").httpRequestDone(self, msg); } diff --git a/src/cdp/domains/page.zig b/src/cdp/domains/page.zig index 2c4aad75..5639cfde 100644 --- a/src/cdp/domains/page.zig +++ b/src/cdp/domains/page.zig @@ -302,6 +302,27 @@ pub fn pageCreated(bc: anytype, page: *Page) !void { bc.captured_responses = .empty; } +pub fn pageFrameCreated(bc: anytype, event: *const Notification.PageFrameCreated) !void { + const session_id = bc.session_id orelse return; + + const cdp = bc.cdp; + const frame_id = &id.toFrameId(event.page_id); + + try cdp.sendEvent("Page.frameAttached", .{ .params = .{ + .frameId = frame_id, + .parentFrameId = &id.toFrameId(event.parent_id), + } }, .{ .session_id = session_id }); + + if (bc.page_life_cycle_events) { + try cdp.sendEvent("Page.lifecycleEvent", LifecycleEvent{ + .name = "init", + .frameId = frame_id, + .loaderId = &id.toLoaderId(event.page_id), + .timestamp = event.timestamp, + }, .{ .session_id = session_id }); + } +} + pub fn pageNavigated(arena: Allocator, bc: anytype, event: *const Notification.PageNavigated) !void { // detachTarget could be called, in which case, we still have a page doing // things, but no session.