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
4 changes: 4 additions & 0 deletions src/cdp/cdp.zig
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,9 @@ pub fn BrowserContext(comptime CDP_T: type) type {
node_registry: Node.Registry,
node_search_list: Node.Search.List,

// Holds the data to be able recreate the fake isolated world, see: @isolated_world
fake_isolatedworld: ?@import("domains/runtime.zig").ExecutionContextCreated,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not against having a src/cdp/execution_context.zig with a Created struct inside. Also can keep as-is.


const Self = @This();

fn init(self: *Self, id: []const u8, cdp: *CDP_T) !void {
Expand All @@ -323,6 +326,7 @@ pub fn BrowserContext(comptime CDP_T: type) type {
.page_life_cycle_events = false, // TODO; Target based value
.node_registry = registry,
.node_search_list = undefined,
.fake_isolatedworld = null,
};
self.node_search_list = Node.Search.List.init(allocator, &self.node_registry);
}
Expand Down
58 changes: 37 additions & 21 deletions src/cdp/domains/page.zig
Original file line number Diff line number Diff line change
Expand Up @@ -98,35 +98,46 @@ fn addScriptToEvaluateOnNewDocument(cmd: anytype) !void {
}

// TODO: hard coded method
/// @isolated_world The current understanding is that an isolated world should be a separate isolate and context
/// that would live in the BrowserContext. We think Puppetee creates this to be able to create variables
/// that are not interfering with the normal namespace of he webpage.
/// Similar to the main context we need to pretend to recreate it after a executionContextsCleared event
/// which happens when navigating to a new page.
/// Since we do not actually create an isolated context operations on this context are still performed
/// in the main context, we suspect this may lead to unexpected variables and value overwrites.
fn createIsolatedWorld(cmd: anytype) !void {
_ = cmd.browser_context orelse return error.BrowserContextNotLoaded;

const session_id = cmd.input.session_id orelse return error.SessionIdRequired;

const params = (try cmd.params(struct {
frameId: []const u8,
worldName: []const u8,
grantUniveralAccess: bool,
})) orelse return error.InvalidParams;

// noop executionContextCreated event
try cmd.sendEvent("Runtime.executionContextCreated", .{
.context = runtime.ExecutionContextCreated{
.id = 0,
.origin = "",
.name = params.worldName,
// TODO: hard coded ID
.uniqueId = "7102379147004877974.3265385113993241162",
.auxData = .{
.isDefault = false,
.type = "isolated",
.frameId = params.frameId,
},
const bc = cmd.browser_context orelse return error.BrowserContextNotLoaded;
const session_id = cmd.input.session_id orelse return error.SessionIdRequired;

const name_copy = try bc.session.arena.allocator().dupe(u8, params.worldName);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could also give the bc its own arena. My only concern with using the Session's arena is that it's easy to forget the BrowserContext is using it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. One more push to making me think that we should stop with the OO separation of these data structs, especially when we start sending notifications from one to the other, while they are just next to each other.

const frame_id_copy = try bc.session.arena.allocator().dupe(u8, params.frameId);
const fake_id = 0;

bc.fake_isolatedworld = .{
.id = fake_id,
.origin = "", // The 2nd time chrome sends this it is "://"
.name = name_copy,
// TODO: hard coded ID, should change when context is recreated
.uniqueId = "7102379147004877974.3265385113993241162",
.auxData = .{
.isDefault = false,
.type = "isolated",
.frameId = frame_id_copy,
},
}, .{ .session_id = session_id });
};

return cmd.sendResult(.{
.executionContextId = 0,
// Inform the client of the creation of the isolated world and its ID.
// Note: Puppeteer uses the ID from this event and actually ignores the executionContextId return value
try cmd.sendEvent("Runtime.executionContextCreated", .{ .context = bc.fake_isolatedworld }, .{ .session_id = session_id });

try cmd.sendResult(.{
.executionContextId = fake_id,
}, .{});
}

Expand Down Expand Up @@ -202,9 +213,14 @@ pub fn pageNavigate(bc: anytype, event: *const Notification.PageEvent) !void {
}, .{ .session_id = session_id });
}

// Send Runtime.executionContextsCleared event
// TODO: noop event, we have no env context at this point, is it necesarry?
// Sending this events will tell make the client drop its contexts and wait for new ones to be created.
try cdp.sendEvent("Runtime.executionContextsCleared", null, .{ .session_id = session_id });

// When the execution contexts are cleared the client expect us to send executionContextCreated events with the new ID for each context.
// Since we do not actually maintain an isolated context we just send the same message as we did initially.
// The contextCreated message is send for the main context by the session by calling the inspector.contextCreated when navigating.
if (bc.fake_isolatedworld) |isolatedworld| try cdp.sendEvent("Runtime.executionContextCreated", .{ .context = isolatedworld }, .{ .session_id = session_id });
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI: you can capture a reference to it:

if (bc.fake_isolatedworld) |*isolatedworld| { .... }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to know. Generally I don't worry about stack copies. I'd be surprised if this would end up in the final binary.

}

pub fn pageNavigated(bc: anytype, event: *const Notification.PageEvent) !void {
Expand Down
Loading