mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-07 01:56:04 +00:00
fix(core): applyPositionEdits fails silently across iframe realms
applyPositionEdits(doc) guarded each element with `instanceof HTMLElement` — but `doc` is frequently an iframe's document (the SDK's edit preview, any host embedding a composition), whose elements are HTMLElement instances of THAT frame's realm, never this module's. The check silently no-ops on every single element cross-realm, so bulk position edits never apply inside an iframe. Use the document's own realm's HTMLElement constructor (doc.defaultView); duck-type on `.style` when defaultView is unavailable (a detached/synthetic document). The single-element applyPositionEditToElement was already realm-safe — only the bulk wrapper had the bug. Added a regression test using a real jsdom iframe, confirmed it fails on the old `instanceof HTMLElement` check and passes with the fix.
This commit is contained in:
@@ -115,6 +115,32 @@ describe("applyPositionEdits", () => {
|
||||
b.remove();
|
||||
});
|
||||
|
||||
it("applies edits to elements from a DIFFERENT realm (an iframe's document)", () => {
|
||||
// Regression test: a module-scope `instanceof HTMLElement` check fails for
|
||||
// elements from another window's realm even though they're genuine,
|
||||
// stylable HTMLElements — exactly the case for any iframe-hosted editor
|
||||
// (the SDK's edit preview, a host embedding a composition).
|
||||
const iframe = document.createElement("iframe");
|
||||
document.body.appendChild(iframe);
|
||||
const iframeDoc = iframe.contentDocument;
|
||||
if (!iframeDoc) throw new Error("iframe.contentDocument unavailable in this test env");
|
||||
|
||||
// Sanity check the premise: the iframe's HTMLElement is NOT this realm's.
|
||||
const iframeWindow = iframe.contentWindow as (Window & typeof globalThis) | null;
|
||||
expect(iframeWindow?.HTMLElement).not.toBe(globalThis.HTMLElement);
|
||||
|
||||
const el = iframeDoc.createElement("div");
|
||||
el.setAttribute("data-x", "50");
|
||||
el.setAttribute("data-y", "-10");
|
||||
el.setAttribute(EDIT_BASE_X_ATTR, "0");
|
||||
el.setAttribute(EDIT_BASE_Y_ATTR, "0");
|
||||
iframeDoc.body.appendChild(el);
|
||||
|
||||
expect(applyPositionEdits(iframeDoc)).toBe(1);
|
||||
expect(el.style.getPropertyValue("translate")).toBe("50px -10px");
|
||||
iframe.remove();
|
||||
});
|
||||
|
||||
it("skips re-apply when the written translate was consumed externally (GSAP fold)", () => {
|
||||
const el = makeElement({
|
||||
"data-x": "10",
|
||||
|
||||
Reference in New Issue
Block a user