Skip to content

Conversation

@karlseguin
Copy link
Collaborator

@karlseguin karlseguin commented Apr 29, 2025

PR does 2 cleanups and 1 hack.

1 - Moves a lot of the Executor and Session logic/data down to the Scope and the Page. This provides correct isolation when navigating from page-to-page and minimizes some of the v8 scoping. A Page/Scope now owns the window (globla), session_state (ooopps, should rename this to page_state?) and its own v8.Context.

2 - Moves the inspector out of the Session and into the BrowserContext. The inspector, it's callback hookup, it's aux_data and everything else, is fully managed by the CDP layer. Browser/Session are now inspector-unaware.

3 - To fix the isolated world crash, I force-create the isolated world before the page is created and always shutdown the page before shutting down the isolated world.

(3) is a hack, but I'm still not sure what the correct long term solution is, but I think (1) and (2) move us in a better direction.

- Pages within the same session have proper isolation
  - they have their own window
  - they have their own SessionState
  - they have their own v8.Context

- Move inspector to CDP browser context
  - Browser now knows nothing about the inspector

- Use notification to emit a context-created message
  - This is still a bit hacky, but again, it decouples browser from CDP
emit contextCreated when it's needed, not when it actually happens.

I thought we could make this sync-up, but we'd need to create 3 contexts to
satisfy both puppeteer and chromedp. So rather than having it partially
driven by notifications from Browser, I rather just fake it all for now.
@karlseguin
Copy link
Collaborator Author

karlseguin commented Apr 29, 2025

I initially wanted to have the contextCreated events we emit be based on what actually happens. That's how the first commit worked. But it didn't work on chromedp - I missed a message.

It turns out that:
1 - chromedp wants a contextCreated message emitted when the target is created (I assume this relates to the tab)
2 - puppeteer (and possibly chromedp also) wants a contextCreated prior to the Page.frameNavigated (puppeteer is pretty sensitive to the timing).
3 - puppeteer also wants a context created when the isolate world is created.

No doubt this is how chrome actually behaves. A context for the tab. A context for the page (and then one per frame) and, if you create an isolated world, a context for that.

Since we aren't currently creating 3 contexts, I decided to go back to fully faking this. However thanks to (1) from the PR details above, this is less of a lie than it was before and thanks to (2) this mess is completely removed from Browser - it's purely a CDP concern.

Now, whether we actually need 3+ distinct contexts created, and whether they need to be created at those exact points in time, is still TDB.

_ = page_arena.reset(.{ .retain_with_limit = 1 * 1024 * 1024 });

self.page = Page.init(self);
self.page = @as(Page, undefined);
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this OK?
In Page.init we are using the values of the current state as input for the new state!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm not sure what you mean by "the values of the current state". Do you mean things like:

self.* = .{
  .url = URL.empty,
  .state = .{
    .url = &self.url,
  }
};

Isn't state.url being given a valid/correct address? The value might not be initialized, but it will be by the time the statement end.

var world = &self.isolated_world.?;

// TODO: can we do something better than passing `undefined` for the state?
world.scope = try world.executor.startScope(&world.global, undefined, {});
Copy link
Contributor

Choose a reason for hiding this comment

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

Just a note, doesn't need to be fixed in this PR.
(When grantUniversalAccess is true)
I'm fairly certain we should put in the page's Window, such that they share the same DOM tree.
I expect we keep running into issues if we combine steps like creating a scope and a context.

@krichprollsch krichprollsch merged commit 93c0df3 into main Apr 29, 2025
12 checks passed
@krichprollsch krichprollsch deleted the scope_tightening branch April 29, 2025 16:46
@github-actions github-actions bot locked and limited conversation to collaborators Apr 29, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants