mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-01 19:42:03 +00:00
fix(player): defer initial iframe navigation
This commit is contained in:
@@ -525,6 +525,7 @@ describe("HyperframesPlayer shader transition options", () => {
|
||||
const player = document.createElement("hyperframes-player") as PlayerWithIframe;
|
||||
player.setAttribute("shader-capture-scale", "0.5");
|
||||
player.setAttribute("shader-loading", "player");
|
||||
document.body.appendChild(player);
|
||||
player.setAttribute("src", "/api/projects/demo/preview?x=1#stage");
|
||||
|
||||
const url = new URL(player.iframeElement.src);
|
||||
@@ -539,6 +540,7 @@ describe("HyperframesPlayer shader transition options", () => {
|
||||
const player = document.createElement("hyperframes-player") as PlayerWithIframe;
|
||||
player.setAttribute("shader-capture-scale", "0.5");
|
||||
player.setAttribute("shader-loading", "player");
|
||||
document.body.appendChild(player);
|
||||
player.setAttribute(
|
||||
"srcdoc",
|
||||
'<!doctype html><html><head><script src="composition.js"></script></head><body></body></html>',
|
||||
@@ -1512,6 +1514,36 @@ describe("HyperframesPlayer srcdoc attribute", () => {
|
||||
player.remove();
|
||||
});
|
||||
|
||||
it("does not navigate initial srcdoc before the runtime listener is connected", () => {
|
||||
// React assigns custom-element attributes before inserting the element. If the observed
|
||||
// attribute callback navigates the child iframe immediately, a fast srcdoc runtime can post
|
||||
// its one-shot `ready` message before connectedCallback subscribes to `window.message`.
|
||||
// Retained runtime data then waits forever and a caption style appears stuck on its bootstrap
|
||||
// frame. The connect path owns the first navigation; attributeChangedCallback owns only
|
||||
// subsequent swaps.
|
||||
const player = document.createElement("hyperframes-player") as PlayerInternal;
|
||||
player.setAttribute("srcdoc", "<!doctype html><html><body>deferred</body></html>");
|
||||
|
||||
expect(player.iframe.hasAttribute("srcdoc")).toBe(false);
|
||||
|
||||
document.body.appendChild(player);
|
||||
expect(player.iframe.getAttribute("srcdoc")).toContain("<body>deferred</body>");
|
||||
|
||||
player.remove();
|
||||
});
|
||||
|
||||
it("does not navigate initial src before the runtime listener is connected", () => {
|
||||
const player = document.createElement("hyperframes-player") as PlayerInternal;
|
||||
player.setAttribute("src", "/api/projects/deferred/preview");
|
||||
|
||||
expect(player.iframe.hasAttribute("src")).toBe(false);
|
||||
|
||||
document.body.appendChild(player);
|
||||
expect(player.iframe.getAttribute("src")).toBe("/api/projects/deferred/preview");
|
||||
|
||||
player.remove();
|
||||
});
|
||||
|
||||
it("forwards a srcdoc attribute set after connect to the iframe", () => {
|
||||
// The composition-switching flow: same player element, new HTML.
|
||||
// Without `attributeChangedCallback` wiring this would no-op.
|
||||
|
||||
@@ -218,6 +218,11 @@ class HyperframesPlayer extends HTMLElement {
|
||||
attributeChangedCallback(name: string, oldVal: string | null, val: string | null) {
|
||||
switch (name) {
|
||||
case "src":
|
||||
// Custom-element attributes are normally assigned before insertion (React does this for
|
||||
// every render). Navigating the inner iframe here would let its one-shot runtime `ready`
|
||||
// message fire before connectedCallback installs the parent message listener. Initial
|
||||
// attributes are applied below by connectedCallback; only live changes navigate here.
|
||||
if (!this.isConnected) break;
|
||||
if (val) {
|
||||
this._ready = false;
|
||||
this._runtimeBridgeReady = false;
|
||||
@@ -228,6 +233,7 @@ class HyperframesPlayer extends HTMLElement {
|
||||
}
|
||||
break;
|
||||
case "srcdoc":
|
||||
if (!this.isConnected) break;
|
||||
this._ready = false;
|
||||
this._runtimeBridgeReady = false;
|
||||
this._rejectAllRuntimeDataDeliveries(
|
||||
|
||||
Reference in New Issue
Block a user