Skip to content

Conversation

@adamziel
Copy link
Collaborator

@adamziel adamziel commented Nov 20, 2025

Explores making all iframes controlled by the Playground service worker.

Iframes created as about:blank / srcdoc / data / blob are not controlled by this
service worker. This means that all network calls initiated by these iframes are
sent directly to the network. This means Gutenberg cannot load any CSS files,
TInyMCE can't load media images, etc.

Only iframes created with src pointing to a URL already controlled by this service worker
are themselves controlled.

Explored solution

We inject a iframes-trap.js script into every HTML page to override a set of DOM
methods used to create iframes. Whenever an src/srcdoc attribute is set on an iframe,
we intercept that and:

  1. Store the initial HTML of the iframe in CacheStorage.
  2. Set the iframe's src to iframeLoaderUrl (coming from a controlled URL).
  3. The loader replaces the iframe's content with the cached HTML.
  4. The loader ensures iframes-trap.js is also loaded and executed inside the iframe
    to cover any nested iframes.

As a result, every same-origin iframe is forced onto a real navigation that the SW can control,
so all fetches (including inside editors like TinyMCE) go through our handler
without per-product patches. This replaces the former Gutenberg-only shim.

Downsides

When a DOM reference to an element inside an iframe is grabbed early on, rewriting the HTML inside that iframe invalidates those reference. I think it breaks "bold", "italic", etc buttons in TinyMCE at the moment (but it doesn't break the "Add Media" feature).

This is a deal-breaker in the current PR. I think we can make it work without destroying the DOM nodes already in the iframe. TinyMCE seems to be doing iframe.contentWindow.contentDocument.write( newHTML ) and document.write() makes a controlled iframe uncontrolled again. We'll need to wrap every part of the process and replace the document.write() logic with something closer to innerHTML or a redirection to loader.html?initialHTML={markup}.

References

Fixes #2919
Fixes #42

cc @akirk @brandonpayton @ellatrix @draganescu

@adamziel adamziel changed the title Explore making all iframes controlled [Website] Make all iframes controlled by the service worker Nov 20, 2025
@adamziel adamziel marked this pull request as draft November 20, 2025 17:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Classic editor doesn't show images from media library CSS files are not loading in the site editor

2 participants