WIP: Fix Gutenberg site editor under Document-Isolation-Policy#3320
Closed
WIP: Fix Gutenberg site editor under Document-Isolation-Policy#3320
Conversation
…Gutenberg site editor Gutenberg 26.2 uses SharedArrayBuffer in the site editor, which requires cross-origin isolation. Playground achieves this via Document-Isolation-Policy (DIP) instead of COEP/COOP because the entire parent frame chain would need COEP/COOP headers – including third-party sites that embed Playground. However, when only the child iframe has DIP but the parent doesn't, window.frameElement becomes null and contentDocument access is blocked. Gutenberg's site editor directly manipulates iframe.contentDocument to build the editing canvas, so it breaks. The fix is to serve DIP on all HTML responses in Playground – both from the service worker and from the Vite dev servers. When both parent and child frames have DIP, frameElement and contentDocument access work correctly. This is WIP/exploratory – several guards are commented out and debug logging is present.
Collaborator
Author
|
I'm closing this since it's not meant for merging. It's more of a demonstration of the problem. I won't be able to keep advancing this stream of work, please feel free to take over. |
adamziel
commented
Feb 27, 2026
| */ | ||
| add_filter('wp_client_side_media_processing_enabled', '__return_false'); | ||
| // add_filter('wp_client_side_media_processing_enabled', '__return_false'); | ||
| define( 'DISABLE_WP_CRON', true ); |
Collaborator
Author
There was a problem hiding this comment.
it's so slow on beta-2, I don't know why. Should we disable it entirely until we have multi-worker in the browser? @brandonpayton
Collaborator
Member
|
@bgrgicak / @adamziel - Would it help Pl;yground using DIP if we use DIP in core/Gutenberg instead of COEP/COOP? I am proposing we do that and support firefox/safari via a plugin. See WordPress/wordpress-develop#11098 / WordPress/gutenberg#75991 |
Collaborator
Author
|
I think so @adamsilverstein, thank you so much for following up here! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Gutenberg 26.2 uses
SharedArrayBufferin the site editor. That requires cross-origin isolation. WordPress serves the editor frame with COEP/COOP headers. It's pretty difficult to do the same in Playground, so instead we rewrite those headers asDocument-Isolation-Policy. However, DIP has subtle side effect that breaks how Gutenberg sets up its editor canvas. I think (?) it wasn't a problem at the time #3028 was merged, but Gutenberg internals changed in WordPress/gutenberg#74418 (and likely a few other PRs) so the situation needs to be re-evaluated now.This is a WIP branch capturing the debugging so far.
Why Playground can't use COEP/COOP
COEP/COOP require the entire frame ancestry to participate. To get
SharedArrayBufferinside the site editor iframe, headers must be set on:remote.htmlPlayground frame above itplayground.wordpress.nethost page above thatThat last point is the blocker. Playground is embedded on WordPress.org, in documentation, in tutorials. Those pages don't send COEP/COOP, and we can't make them.
Native WordPress doesn't have this problem — wp-admin does full-page reloads, so COEP/COOP only needs to cover the current page. In Playground, the top-level frame stays alive for the entire session.
Perhaps we could introduce a query param such as
?coop=1or so and use a magic default value depending on whether Playground is loaded from an iframe, but that sounds fragile.The DIP problem
Document-Isolation-Policyisolates a single document without requiring parent cooperation. But it has a catch:When only the child frame has DIP but the parent doesn't:
window.frameElementbecomesnullcontentDocumentaccess is blockedGutenberg's site editor calls
iframe.contentWindow.contentDocumentdirectly to set up the block editor canvas. WhencontentDocumentis blocked, it crashes.When both parent and child have DIP:
window.frameElementis definedcontentDocumentaccess worksWhat this branch does
Serves
Document-Isolation-Policy: isolate-and-credentiallesson all HTML responses in Playground — from the service worker and from both Vite dev servers — so that the parent-child DIP requirement is satisfied.To try it, go to http://localhost:5400/website-server/?wp=beta&url=%2Fwp-admin%2Fsite-editor.php#ewogICJwbHVnaW5zIjogW10sCiAgInN0ZXBzIjogW10sCiAgInByZWZlcnJlZFZlcnNpb25zIjogewogICAgInBocCI6ICI4LjMiLAogICAgIndwIjogImJldGEiCiAgfSwKICAiZmVhdHVyZXMiOiB7fSwKICAibG9naW4iOiB0cnVlLAogICJsYW5kaW5nUGFnZSI6ICIvd3AtYWRtaW4vc2l0ZS1lZGl0b3IucGhwIgp9
It has some very rough edges, e.g. all the blocks crash and I don't know why. Also, I'm not sure about the impact of this on Playgrounds embedded on sites without the
Document-Isolation-Policyheader. Also, it further complicates the Chrome vs FF/Safari maintenance split. Finally, I'm not sure if client-side media processing actually works in this PR. But I know SharedArrayBuffer is available in the right iframe, and that's already a lot. This PR is just a debugging exploration to understand the phenomenon. It's not meant for merging.cc @brandonpayton @JanJakes @adamsilverstein @swissspidy
related to #2954