diff --git a/packages/core/src/runtime/init.test.ts b/packages/core/src/runtime/init.test.ts index ab054e557..03e7a1ad1 100644 --- a/packages/core/src/runtime/init.test.ts +++ b/packages/core/src/runtime/init.test.ts @@ -211,6 +211,43 @@ describe("initSandboxRuntimeModular", () => { expect(child.style.visibility).toBe("visible"); }); + it("keeps compiled external composition hosts visible through their authored duration", async () => { + const root = document.createElement("div"); + root.setAttribute("data-composition-id", "main"); + root.setAttribute("data-root", "true"); + root.setAttribute("data-start", "0"); + root.setAttribute("data-width", "1920"); + root.setAttribute("data-height", "1080"); + document.body.appendChild(root); + + const child = document.createElement("div"); + child.setAttribute("data-composition-id", "sub"); + child.setAttribute("data-composition-file", "compositions/sub.html"); + child.setAttribute("data-start", "0"); + child.setAttribute("data-duration", "3"); + child.innerHTML = '
HOLD ME
'; + root.appendChild(child); + + (window as Window & { __timelines?: Record }).__timelines = { + main: createMockTimeline(3), + sub: createMockTimeline(1), + }; + + initSandboxRuntimeModular(); + await new Promise((resolve) => window.setTimeout(resolve, 0)); + + const player = ( + window as Window & { + __player?: { renderSeek: (timeSeconds: number) => void }; + } + ).__player; + expect(player).toBeDefined(); + + player?.renderSeek(2); + + expect(child.style.visibility).toBe("visible"); + }); + it("pads the root timeline to the authored composition schedule before seeking visibility", () => { const root = document.createElement("div"); root.setAttribute("data-composition-id", "main"); diff --git a/packages/core/src/runtime/init.ts b/packages/core/src/runtime/init.ts index 68d100329..5c677959e 100644 --- a/packages/core/src/runtime/init.ts +++ b/packages/core/src/runtime/init.ts @@ -1335,7 +1335,9 @@ export function initSandboxRuntimeModular(): void { } } - const usesExternalCompositionSlot = rawNode.hasAttribute("data-composition-src"); + const usesExternalCompositionSlot = + rawNode.hasAttribute("data-composition-src") || + rawNode.hasAttribute("data-composition-file"); // Generic child compositions retain legacy behavior and respect both // the authored parent clip window and the live child timeline duration. diff --git a/packages/producer/src/services/htmlCompiler.ts b/packages/producer/src/services/htmlCompiler.ts index ca5dec6a3..1eba3fc30 100644 --- a/packages/producer/src/services/htmlCompiler.ts +++ b/packages/producer/src/services/htmlCompiler.ts @@ -689,6 +689,7 @@ function inlineSubCompositions( host.innerHTML = contentDoc.toString(); } + host.setAttribute("data-composition-file", srcPath); host.removeAttribute("data-composition-src"); // Set explicit pixel dimensions on the host element so children using