Skip to content

Commit

Permalink
Set the API context when using Comlink.wrap() (#1085)
Browse files Browse the repository at this point in the history
Fixes WordPress Playground Block not loading when the Site Editor is
wrapped in an iframe.

Playground uses Comlink to talk to the remote API via
`window.postMessage()`. By default, Comlink binds the `message` event
listener to the current global window object. However, when the Site
Editor is iframed, the `startPlaygroundWeb` function runs in the global
`window` context, but the Playground iframe lives inside of the Editor
Canvas iframe context. Playground's `remote.html` would then send all
its messages (via `postMessage`) to the parent window, which is Editor
Canvas and not the global `window`. As a result, Comlink would never
notice any communication and the Playground wouldn't load.

This PR ensires the `context` argument is always set to Playground's
iframe parent window.

## Testing instructions

This is convoluted:

1. Clone
https://github.com/WordPress/playground-tools/tree/trunk/packages/wordpress-playground-block
1. Update the remote URL to `http://localhost:5400/remote.html`
1. Build the `@wp-playground/client` package in this repo and substitute
the block's dependency with it (or use npm link)
1. Run the Playground block in the dev mode (as described in its README)
1. Install the Gutenberg plugin to enable iframe-based Canvas
1. Insert the Playground block
1. Confirm Playground loads correctly
  • Loading branch information
adamziel authored Mar 5, 2024
1 parent c0df8b5 commit 6cf353f
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 4 deletions.
5 changes: 3 additions & 2 deletions packages/php-wasm/web/src/lib/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ export type WithAPIState = {
export type RemoteAPI<T> = Comlink.Remote<T> & WithAPIState;

export function consumeAPI<APIType>(
remote: Worker | Window
remote: Worker | Window,
context: undefined | EventTarget = undefined
): RemoteAPI<APIType> {
setupTransferHandlers();

Expand All @@ -32,7 +33,7 @@ export function consumeAPI<APIType>(
*
* @TODO: Remove this workaround.
*/
const api = Comlink.wrap<APIType & WithAPIState>(endpoint);
const api = Comlink.wrap<APIType & WithAPIState>(endpoint, context);
const methods = proxyClone(api);
return new Proxy(methods, {
get: (target, prop) => {
Expand Down
6 changes: 4 additions & 2 deletions packages/playground/client/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ async function doStartPlaygroundWeb(
// Connect the Comlink client and wait until the
// playground is ready.
const playground = consumeAPI<PlaygroundClient>(
iframe.contentWindow!
iframe.contentWindow!,
iframe.ownerDocument!.defaultView!
) as PlaygroundClient;
await playground.isConnected();
progressTracker.pipe(playground);
Expand Down Expand Up @@ -208,7 +209,8 @@ export async function connectPlayground(
});
}
const client = consumeAPI<PlaygroundClient>(
iframe.contentWindow!
iframe.contentWindow!,
iframe.ownerDocument!.defaultView!
) as PlaygroundClient;
await client.isConnected();
return client;
Expand Down

0 comments on commit 6cf353f

Please sign in to comment.