Skip to content

fix(play): absorb malformed HTML + warn when runner script is swallowed - #435

Draft
caugner wants to merge 3 commits into
436-play-runner-uuid-isolationfrom
1440-playground-runner-breakout-guard
Draft

fix(play): absorb malformed HTML + warn when runner script is swallowed#435
caugner wants to merge 3 commits into
436-play-runner-uuid-isolationfrom
1440-playground-runner-breakout-guard

Conversation

@caugner

@caugner caugner commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

(⚠️ Mirrored from mdn/fred#1705. ⚠️ )

Description

Update the mirrored Playground runner (cloud-function/src/internal/play/index.js) so malformed HTML no longer swallows the user's JS, and warn when it still does:

  • Insert <!-- "" '' --> after the HTML, which closes an unclosed tag, attribute value, or comment before the runner script.
  • Set window.__mdnPlayJsStarted in a script before the runner and window.__mdnPlayJsEnded in the script after it.
  • Add a <head> check on DOMContentLoaded that warns via console.warn if either flag is missing.

Ports the unit test from mdn/fred#1705 to cloud-function/src/internal/play/index.test.js, next to the runner. The sync workflow only overwrites index.js, so the test survives future syncs.

Motivation

Ensure a typo like <o in the HTML no longer renders the JS as text, and that users get a hint in the remaining cases (e.g. an unclosed <textarea>), where the JS silently does not run (mdn/fred#1440).

This file serves the Playground runner in review and production, so the fix only takes effect outside local dev once this lands.

Additional details

Flags instead of marker elements: user JS that replaces the body's children (e.g. document.body.innerHTML = ..., as several live samples do) removes the script elements but not the flags.

Verified with headless Chrome:

HTML JS runs Warning
<p>ok</p> yes no
annn <o jwj, <div class=", unclosed <!-- yes no
JS replacing document.body children yes no
unclosed <textarea>, <template>, <math> no yes

Related issues and pull requests

Mirrors mdn/fred#1705, the fix for mdn/fred#1440.

Depends on: #437.

@caugner caugner changed the title fix(play): guard the Playground runner against markup break-out fix(playground): guard runner against markup break-out Jul 17, 2026
@caugner
caugner force-pushed the 1440-playground-runner-breakout-guard branch from 20f59b0 to b5e6b5c Compare July 17, 2026 14:46
@caugner
caugner force-pushed the 1440-playground-runner-breakout-guard branch from b5e6b5c to 104c389 Compare September 3, 2026 11:40
@caugner caugner changed the title fix(playground): guard runner against markup break-out fix(play): guard runner against markup break-out Sep 3, 2026
@caugner
caugner force-pushed the 1440-playground-runner-breakout-guard branch 2 times, most recently from e3ddac4 to 1d919f0 Compare September 3, 2026 19:42
@caugner caugner changed the title fix(play): guard runner against markup break-out fix(play): warn when malformed HTML swallows the runner script Sep 3, 2026
@caugner
caugner force-pushed the 1440-playground-runner-breakout-guard branch 2 times, most recently from f839e5c to 791199b Compare September 9, 2026 14:12
@caugner
caugner changed the base branch from main to 436-play-runner-uuid-isolation September 9, 2026 14:12
@caugner
caugner added this pull request to stack #516 September 9, 2026 14:12
@caugner
caugner removed this pull request from stack #516 September 9, 2026 14:38
@caugner
caugner added this pull request to stack #517 September 9, 2026 14:39
Add `id="mdn-play-js"` and `id="mdn-play-js-end"` markers to the runner
script and the script following it, and check from the head after
`DOMContentLoaded` that both are present as script elements. If either
is missing, log a console warning.

Unclosed or malformed tags in the HTML input can absorb the runner
script, so the JavaScript never executes and the playground silently
does nothing.

Mirrors mdn/fred.
Assert that the runner output carries the `mdn-play-js` and
`mdn-play-js-end` markers and that the swallow detection runs from the
`<head>` after `DOMContentLoaded`. Ported from `mdn/fred`, where the
test lives outside the vendored directory.
@caugner
caugner force-pushed the 1440-playground-runner-breakout-guard branch from f17d1c7 to cf56ea8 Compare September 9, 2026 14:41
@caugner caugner changed the title fix(play): warn when malformed HTML swallows the runner script fix(play): absorb malformed HTML + warn when runner script is swallowed Sep 9, 2026
Insert `<!-- "" '' -->` after the HTML so an unclosed tag, attribute
value, or comment ends there instead of swallowing the runner script.
Set `window.__mdnPlayJsStarted` and `window.__mdnPlayJsEnded` around the
runner and check those in `<head>`, since the script elements disappear
when user JS replaces the body's children (a false positive in live
samples using `document.body.innerHTML`).
@caugner
caugner force-pushed the 1440-playground-runner-breakout-guard branch from ecc49dc to 27d1047 Compare September 9, 2026 15:27
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.

2 participants