Skip to content

feat(frame): add isolated worlds to evaluate JavaScript hidden from the page - #670

Merged
route merged 1 commit into
mainfrom
feat/isolated-worlds
Oct 21, 2026
Merged

route merged 1 commit into
mainfrom
feat/isolated-worlds

Conversation

@route

@route route commented Oct 21, 2026

Copy link
Copy Markdown
Member

page.evaluate_on_new_document(source, world_name:) could inject a script into an isolated world, but nothing let you evaluate in that world afterwards or create one on demand.

world = page.isolated_world("ferrum")  # or frame.isolated_world(name)
world.execute("window.secret = 'top'")
world.evaluate("window.secret")         # => "top"
page.evaluate("window.secret")          # => nil
world.evaluate("document.title")        # same DOM as the page

Changes

  • Ferrum::IsolatedWorld includes Frame::Runtime, so it has the same evaluate, evaluate_async, execute, evaluate_func and evaluate_on as a frame, with its own execution context.
  • The world is created with Page.createIsolatedWorld when the current document has none for that name. Chrome returns the same context for the same name, so it's the world evaluate_on_new_document(world_name:) runs in.
  • Frame#isolated_world(name) and Frame#isolated_worlds. Page and Browser delegate isolated_world to the main frame.
  • Runtime.executionContextCreated checks auxData.isDefault: only the default context sets the frame's execution_id, named isolated contexts go to their world. Destroyed and cleared contexts clear world ids too, so a world starts empty in a new document while the object stays usable.
  • Nodes are resolved into the world's context (DOM.resolveNode with executionContextId), so page nodes can be passed in and nodes come back.

Test

spec/isolated_world_spec.rb: separate globals with a shared DOM, the world of evaluate_on_new_document(world_name:), a fresh world after navigation, nodes in and out, and a world in an iframe.

…he page

page.isolated_world(name) and frame.isolated_world(name) return an IsolatedWorld with the frame's evaluation methods,
running in a world created with Page.createIsolatedWorld, the same one evaluate_on_new_document(world_name:) uses.

Only the default execution context sets the frame's execution_id now, named isolated ones go to their world.
@route
route merged commit d7a9902 into main Oct 21, 2026
6 checks passed
@route
route deleted the feat/isolated-worlds branch October 21, 2026 19:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant