Summary
Interactive scene iframes reload (re-execute their HTML/scripts) whenever the playback chrome unmounts and remounts. The most visible trigger is toggling Pro mode (edit ↔ playback), but the root cause is structural and not specific to the editor: any path that tears down and rebuilds PlaybackChromeRoot re-mounts the iframe from scratch.
Steps to reproduce
- Open a classroom whose current scene is an interactive (iframe) scene.
- Toggle Pro mode on, then off (or trigger any flow that unmounts/remounts the playback chrome).
- Observe the interactive scene reload: the iframe re-parses its HTML and re-runs its scripts, losing any in-iframe state.
Root cause
Stage switches between EditChromeRoot and PlaybackChromeRoot via AnimatePresence as two mutually exclusive branches keyed by mode. Entering Pro mode unmounts the whole PlaybackChromeRoot subtree; exiting rebuilds it.
Stage (mode swap via AnimatePresence)
└─ PlaybackChromeRoot ← unmounted on edit, rebuilt on return
└─ CanvasArea
└─ SceneRenderer
└─ InteractiveRenderer ← <iframe srcDoc> mounts fresh
InteractiveRenderer renders <iframe srcDoc={patchedHtml}> directly in the React tree (components/scene-renderers/interactive-renderer.tsx). There is no iframe reuse/persistence (e.g. portaling a single iframe into a stable host node), so a remount means a full reload.
This is pre-existing behavior of the playback chrome. The editor work merely adds a prominent new way to trigger it.
Impact
- Interactive widget state is lost on every Pro mode toggle.
- Visible reload flash; wasted work re-parsing/re-running iframe content.
- Affects any future remount trigger, not just Pro mode.
Candidate fixes (need a direction decision)
- Persist the iframe: portal one iframe instance into a stable DOM host outside the mode-swap subtree, show/hide instead of unmount.
- Keep
PlaybackChromeRoot mounted across mode swaps (hidden, not unmounted) so its iframe survives.
- Cache/restore iframe state at the widget messaging layer (
widget-iframe store) — partial, only covers state the widget cooperates on.
Option 1 or 2 fixes it generally; both touch the playback chrome architecture, so this should land as its own change rather than riding along with the slide-editor PR.
Notes
Out of scope for the MAIC Editor slide-surface PR (#615) — filing separately so that PR stays focused.
Summary
Interactive scene iframes reload (re-execute their HTML/scripts) whenever the playback chrome unmounts and remounts. The most visible trigger is toggling Pro mode (edit ↔ playback), but the root cause is structural and not specific to the editor: any path that tears down and rebuilds
PlaybackChromeRootre-mounts the iframe from scratch.Steps to reproduce
Root cause
Stageswitches betweenEditChromeRootandPlaybackChromeRootviaAnimatePresenceas two mutually exclusive branches keyed by mode. Entering Pro mode unmounts the wholePlaybackChromeRootsubtree; exiting rebuilds it.InteractiveRendererrenders<iframe srcDoc={patchedHtml}>directly in the React tree (components/scene-renderers/interactive-renderer.tsx). There is no iframe reuse/persistence (e.g. portaling a single iframe into a stable host node), so a remount means a full reload.This is pre-existing behavior of the playback chrome. The editor work merely adds a prominent new way to trigger it.
Impact
Candidate fixes (need a direction decision)
PlaybackChromeRootmounted across mode swaps (hidden, not unmounted) so its iframe survives.widget-iframestore) — partial, only covers state the widget cooperates on.Option 1 or 2 fixes it generally; both touch the playback chrome architecture, so this should land as its own change rather than riding along with the slide-editor PR.
Notes
Out of scope for the MAIC Editor slide-surface PR (#615) — filing separately so that PR stays focused.