mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-01 19:42:03 +00:00
fix(core): update nested timed element visibility on seek (#823)
This commit is contained in:
@@ -263,6 +263,58 @@ describe("initSandboxRuntimeModular", () => {
|
||||
expect(video.currentTime).toBe(9);
|
||||
});
|
||||
|
||||
it("updates visibility for timed elements inside nested compositions", () => {
|
||||
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", "nested");
|
||||
child.setAttribute("data-start", "10");
|
||||
child.setAttribute("data-duration", "10");
|
||||
root.appendChild(child);
|
||||
|
||||
const sceneA = document.createElement("section");
|
||||
sceneA.id = "scene-a";
|
||||
sceneA.setAttribute("data-start", "0");
|
||||
sceneA.setAttribute("data-duration", "4");
|
||||
child.appendChild(sceneA);
|
||||
|
||||
const sceneB = document.createElement("section");
|
||||
sceneB.id = "scene-b";
|
||||
sceneB.setAttribute("data-start", "4");
|
||||
sceneB.setAttribute("data-duration", "4");
|
||||
child.appendChild(sceneB);
|
||||
|
||||
(window as Window & { __timelines?: Record<string, RuntimeTimelineLike> }).__timelines = {
|
||||
main: createMockTimeline(20),
|
||||
nested: createMockTimeline(8),
|
||||
};
|
||||
|
||||
initSandboxRuntimeModular();
|
||||
|
||||
const player = (
|
||||
window as Window & {
|
||||
__player?: { seek: (timeSeconds: number) => void };
|
||||
}
|
||||
).__player;
|
||||
expect(player).toBeDefined();
|
||||
|
||||
player?.seek(11);
|
||||
|
||||
expect(sceneA.style.visibility).toBe("visible");
|
||||
expect(sceneB.style.visibility).toBe("hidden");
|
||||
|
||||
player?.seek(15);
|
||||
|
||||
expect(sceneA.style.visibility).toBe("hidden");
|
||||
expect(sceneB.style.visibility).toBe("visible");
|
||||
});
|
||||
|
||||
it("clamps nested media to the authored host window on seek", () => {
|
||||
const root = document.createElement("div");
|
||||
root.setAttribute("data-composition-id", "main");
|
||||
|
||||
@@ -1316,27 +1316,12 @@ export function initSandboxRuntimeModular(): void {
|
||||
postRuntimeMessage({ source: "hf-preview", type: "media-autoplay-blocked" });
|
||||
},
|
||||
});
|
||||
const rootCompId =
|
||||
document.querySelector("[data-composition-id]")?.getAttribute("data-composition-id") ?? null;
|
||||
const visibilityNodes = Array.from(document.querySelectorAll("[data-start]"));
|
||||
for (const rawNode of visibilityNodes) {
|
||||
if (!(rawNode instanceof HTMLElement)) continue;
|
||||
const tag = rawNode.tagName.toLowerCase();
|
||||
if (tag === "script" || tag === "style" || tag === "link" || tag === "meta") continue;
|
||||
|
||||
// Skip elements INSIDE sub-compositions — their visibility is managed by GSAP,
|
||||
// not the global time-based adapter. Only manage visibility for:
|
||||
// 1. Composition host elements (have data-composition-id themselves)
|
||||
// 2. Direct children of root composition (audio, etc.)
|
||||
// Skip: elements whose nearest composition ancestor is NOT the root
|
||||
const ownCompId = rawNode.getAttribute("data-composition-id");
|
||||
if (!ownCompId) {
|
||||
// Not a composition host — check if it's inside a sub-composition
|
||||
const parentComp = rawNode.closest("[data-composition-id]");
|
||||
const parentCompId = parentComp?.getAttribute("data-composition-id") ?? null;
|
||||
if (parentCompId && parentCompId !== rootCompId) continue;
|
||||
}
|
||||
|
||||
const start = resolveStartForElement(rawNode, 0);
|
||||
let duration = resolveDurationForElement(rawNode);
|
||||
const compId = rawNode.getAttribute("data-composition-id");
|
||||
|
||||
Reference in New Issue
Block a user