mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 04:38:33 +00:00
fix: flatten inlined composition roots
This commit is contained in:
@@ -41,15 +41,26 @@ body { margin: 0; }
|
|||||||
expect(wrapped).not.toContain("requestAnimationFrame");
|
expect(wrapped).not.toContain("requestAnimationFrame");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("normalizes root timing attributes when scoping selectors", () => {
|
||||||
|
const scoped = scopeCssToComposition(
|
||||||
|
'[data-composition-id="scene"][data-start="0"] .title { opacity: 0; }',
|
||||||
|
"scene",
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(scoped).toContain('[data-composition-id="scene"] .title { opacity: 0; }');
|
||||||
|
expect(scoped).not.toContain('[data-start="0"]');
|
||||||
|
});
|
||||||
|
|
||||||
it("executes document and GSAP selectors inside the composition root", () => {
|
it("executes document and GSAP selectors inside the composition root", () => {
|
||||||
const { document } = parseHTML(`
|
const { document } = parseHTML(`
|
||||||
<div data-composition-id="scene"><h1 class="title">Scene</h1></div>
|
<div data-composition-id="scene" data-start="intro"><h1 class="title">Scene</h1></div>
|
||||||
<div data-composition-id="other"><h1 class="title">Other</h1></div>
|
<div data-composition-id="other"><h1 class="title">Other</h1></div>
|
||||||
`);
|
`);
|
||||||
const gsapTargets: string[][] = [];
|
const gsapTargets: string[][] = [];
|
||||||
const fakeWindow = {
|
const fakeWindow = {
|
||||||
document,
|
document,
|
||||||
__selectedTitle: "",
|
__selectedTitle: "",
|
||||||
|
__selectedRootTitle: "",
|
||||||
__timelines: {},
|
__timelines: {},
|
||||||
gsap: {
|
gsap: {
|
||||||
timeline: () => ({
|
timeline: () => ({
|
||||||
@@ -64,7 +75,9 @@ body { margin: 0; }
|
|||||||
`
|
`
|
||||||
const tl = gsap.timeline({ paused: true });
|
const tl = gsap.timeline({ paused: true });
|
||||||
tl.to('.title', { opacity: 1 });
|
tl.to('.title', { opacity: 1 });
|
||||||
|
tl.to('[data-composition-id="scene"][data-start="0"] .title', { opacity: 1 });
|
||||||
window.__selectedTitle = document.querySelector('.title')?.textContent || '';
|
window.__selectedTitle = document.querySelector('.title')?.textContent || '';
|
||||||
|
window.__selectedRootTitle = document.querySelector('[data-composition-id="scene"][data-start="0"] .title')?.textContent || '';
|
||||||
window.__timelines.scene = tl;
|
window.__timelines.scene = tl;
|
||||||
`,
|
`,
|
||||||
"scene",
|
"scene",
|
||||||
@@ -73,6 +86,7 @@ window.__timelines.scene = tl;
|
|||||||
new Function("window", "gsap", wrapped)(fakeWindow, fakeWindow.gsap);
|
new Function("window", "gsap", wrapped)(fakeWindow, fakeWindow.gsap);
|
||||||
|
|
||||||
expect(fakeWindow.__selectedTitle).toBe("Scene");
|
expect(fakeWindow.__selectedTitle).toBe("Scene");
|
||||||
expect(gsapTargets).toEqual([["Scene"]]);
|
expect(fakeWindow.__selectedRootTitle).toBe("Scene");
|
||||||
|
expect(gsapTargets).toEqual([["Scene"], ["Scene"]]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -138,18 +138,36 @@ function splitSelectorList(selectorText: string): string[] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function scopeSelector(selector: string, scope: string, compositionId: string): string {
|
function scopeSelector(selector: string, scope: string, compositionId: string): string {
|
||||||
const trimmed = selector.trim();
|
const selectorWithoutRootTiming = normalizeCompositionRootSelector(
|
||||||
|
selector,
|
||||||
|
scope,
|
||||||
|
compositionId,
|
||||||
|
);
|
||||||
|
const trimmed = selectorWithoutRootTiming.trim();
|
||||||
if (!trimmed) return selector;
|
if (!trimmed) return selector;
|
||||||
if (/^(html|body|:root|\*)$/i.test(trimmed)) return selector;
|
if (/^(html|body|:root|\*)$/i.test(trimmed)) return selector;
|
||||||
const compositionIdPattern = new RegExp(
|
const compositionIdPattern = new RegExp(
|
||||||
`data-composition-id\\s*=\\s*(["'])${escapeRegExp(compositionId)}\\1`,
|
`data-composition-id\\s*=\\s*(["'])${escapeRegExp(compositionId)}\\1`,
|
||||||
);
|
);
|
||||||
if (compositionIdPattern.test(trimmed)) return selector;
|
if (compositionIdPattern.test(trimmed)) return selectorWithoutRootTiming;
|
||||||
const leading = selector.match(/^\s*/)?.[0] ?? "";
|
const leading = selectorWithoutRootTiming.match(/^\s*/)?.[0] ?? "";
|
||||||
const trailing = selector.match(/\s*$/)?.[0] ?? "";
|
const trailing = selectorWithoutRootTiming.match(/\s*$/)?.[0] ?? "";
|
||||||
return `${leading}${scope} ${trimmed}${trailing}`;
|
return `${leading}${scope} ${trimmed}${trailing}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizeCompositionRootSelector(
|
||||||
|
selector: string,
|
||||||
|
scope: string,
|
||||||
|
compositionId: string,
|
||||||
|
): string {
|
||||||
|
const quotedCompId = escapeRegExp(compositionId);
|
||||||
|
const compAttr = String.raw`\[\s*data-composition-id\s*=\s*(?:"${quotedCompId}"|'${quotedCompId}')\s*\]`;
|
||||||
|
const timingAttr = String.raw`\s*\[\s*data-(?:start|duration)\s*=\s*(?:"[^"]*"|'[^']*')\s*\]`;
|
||||||
|
return selector
|
||||||
|
.replace(new RegExp(`${compAttr}(?:${timingAttr})+`, "g"), scope)
|
||||||
|
.replace(new RegExp(`(?:${timingAttr})+${compAttr}`, "g"), scope);
|
||||||
|
}
|
||||||
|
|
||||||
function scopeSelectorList(selectorText: string, scope: string, compositionId: string): string {
|
function scopeSelectorList(selectorText: string, scope: string, compositionId: string): string {
|
||||||
return splitSelectorList(selectorText)
|
return splitSelectorList(selectorText)
|
||||||
.map((selector) => scopeSelector(selector, scope, compositionId))
|
.map((selector) => scopeSelector(selector, scope, compositionId))
|
||||||
@@ -213,6 +231,13 @@ export function wrapScopedCompositionScript(
|
|||||||
): string {
|
): string {
|
||||||
const compositionIdLiteral = JSON.stringify(compositionId);
|
const compositionIdLiteral = JSON.stringify(compositionId);
|
||||||
const errorLabelLiteral = JSON.stringify(errorLabel);
|
const errorLabelLiteral = JSON.stringify(errorLabel);
|
||||||
|
const escapedCompositionId = escapeRegExp(compositionId);
|
||||||
|
const rootSelectorPatternLiteral = JSON.stringify(
|
||||||
|
String.raw`\[\s*data-composition-id\s*=\s*(?:"${escapedCompositionId}"|'${escapedCompositionId}')\s*\]`,
|
||||||
|
);
|
||||||
|
const timingSelectorPatternLiteral = JSON.stringify(
|
||||||
|
String.raw`\s*\[\s*data-(?:start|duration)\s*=\s*(?:"[^"]*"|'[^']*')\s*\]`,
|
||||||
|
);
|
||||||
return `(function(){
|
return `(function(){
|
||||||
var __hfCompId = ${compositionIdLiteral};
|
var __hfCompId = ${compositionIdLiteral};
|
||||||
var __hfErrorLabel = ${errorLabelLiteral};
|
var __hfErrorLabel = ${errorLabelLiteral};
|
||||||
@@ -223,6 +248,14 @@ export function wrapScopedCompositionScript(
|
|||||||
? '[data-composition-id="' + __hfEscapeAttr(__hfCompId) + '"]'
|
? '[data-composition-id="' + __hfEscapeAttr(__hfCompId) + '"]'
|
||||||
: "";
|
: "";
|
||||||
var __hfRoot = null;
|
var __hfRoot = null;
|
||||||
|
var __hfRootSelectorPattern = ${rootSelectorPatternLiteral};
|
||||||
|
var __hfTimingSelectorPattern = ${timingSelectorPatternLiteral};
|
||||||
|
var __hfNormalizeSelector = function(selector) {
|
||||||
|
if (!__hfCompId || typeof selector !== "string") return selector;
|
||||||
|
return selector
|
||||||
|
.replace(new RegExp(__hfRootSelectorPattern + '(?:' + __hfTimingSelectorPattern + ')+', 'g'), __hfRootSelector)
|
||||||
|
.replace(new RegExp('(?:' + __hfTimingSelectorPattern + ')+' + __hfRootSelectorPattern, 'g'), __hfRootSelector);
|
||||||
|
};
|
||||||
var __hfFindRoot = function() {
|
var __hfFindRoot = function() {
|
||||||
if (!__hfRoot && __hfRootSelector) {
|
if (!__hfRoot && __hfRootSelector) {
|
||||||
__hfRoot = window.document.querySelector(__hfRootSelector);
|
__hfRoot = window.document.querySelector(__hfRootSelector);
|
||||||
@@ -238,7 +271,7 @@ export function wrapScopedCompositionScript(
|
|||||||
if (!root || typeof selector !== "string") {
|
if (!root || typeof selector !== "string") {
|
||||||
return window.document.querySelectorAll(selector);
|
return window.document.querySelectorAll(selector);
|
||||||
}
|
}
|
||||||
return Array.prototype.filter.call(window.document.querySelectorAll(selector), function(node) {
|
return Array.prototype.filter.call(window.document.querySelectorAll(__hfNormalizeSelector(selector)), function(node) {
|
||||||
return __hfContains(node);
|
return __hfContains(node);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import { mkdtempSync, writeFileSync, mkdirSync } from "node:fs";
|
import { mkdtempSync, writeFileSync, mkdirSync } from "node:fs";
|
||||||
import { tmpdir } from "node:os";
|
import { tmpdir } from "node:os";
|
||||||
import { join } from "node:path";
|
import { join } from "node:path";
|
||||||
|
import { parseHTML } from "linkedom";
|
||||||
import { describe, it, expect } from "vitest";
|
import { describe, it, expect } from "vitest";
|
||||||
import { bundleToSingleHtml } from "./htmlBundler";
|
import { bundleToSingleHtml } from "./htmlBundler";
|
||||||
|
|
||||||
@@ -196,7 +197,7 @@ describe("bundleToSingleHtml", () => {
|
|||||||
expect(bundled).toContain("Sized content");
|
expect(bundled).toContain("Sized content");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("preserves the sub-composition root when inlining external compositions", async () => {
|
it("flattens the sub-composition root onto the host when inlining external compositions", async () => {
|
||||||
const dir = makeTempProject({
|
const dir = makeTempProject({
|
||||||
"index.html": `<!doctype html>
|
"index.html": `<!doctype html>
|
||||||
<html><head></head><body>
|
<html><head></head><body>
|
||||||
@@ -225,9 +226,20 @@ describe("bundleToSingleHtml", () => {
|
|||||||
|
|
||||||
const bundled = await bundleToSingleHtml(dir);
|
const bundled = await bundleToSingleHtml(dir);
|
||||||
|
|
||||||
expect(bundled).toContain('id="scene-host"');
|
const { document } = parseHTML(bundled);
|
||||||
expect(bundled).toContain('data-composition-id="scene" data-start="0"');
|
const host = document.querySelector("#scene-host");
|
||||||
expect(bundled).toContain('[data-composition-id="scene"][data-start="0"]');
|
|
||||||
|
expect(host?.getAttribute("data-composition-id")).toBe("scene");
|
||||||
|
expect(host?.getAttribute("data-start")).toBe("intro");
|
||||||
|
expect(host?.getAttribute("data-width")).toBe("1920");
|
||||||
|
expect(host?.querySelector(".title")?.textContent).toBe("Scene");
|
||||||
|
expect(
|
||||||
|
Array.from(host?.children ?? []).some(
|
||||||
|
(child) => child.getAttribute("data-composition-id") === "scene",
|
||||||
|
),
|
||||||
|
).toBe(false);
|
||||||
|
expect(bundled).toContain('[data-composition-id="scene"] .title');
|
||||||
|
expect(bundled).toContain("__hfNormalizeSelector");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("scopes external sub-composition styles and classic scripts", async () => {
|
it("scopes external sub-composition styles and classic scripts", async () => {
|
||||||
|
|||||||
@@ -3,11 +3,7 @@ import { join, resolve, isAbsolute, sep } from "path";
|
|||||||
import { parseHTML } from "linkedom";
|
import { parseHTML } from "linkedom";
|
||||||
import { transformSync } from "esbuild";
|
import { transformSync } from "esbuild";
|
||||||
import { compileHtml, type MediaDurationProber } from "./htmlCompiler";
|
import { compileHtml, type MediaDurationProber } from "./htmlCompiler";
|
||||||
import {
|
import { rewriteAssetPaths, rewriteCssAssetUrls } from "./rewriteSubCompPaths";
|
||||||
rewriteAssetPaths,
|
|
||||||
rewriteCssAssetUrls,
|
|
||||||
rewriteInlineStyleAssetUrls,
|
|
||||||
} from "./rewriteSubCompPaths";
|
|
||||||
import { scopeCssToComposition, wrapScopedCompositionScript } from "./compositionScoping";
|
import { scopeCssToComposition, wrapScopedCompositionScript } from "./compositionScoping";
|
||||||
import { validateHyperframeHtmlContract } from "./staticGuard";
|
import { validateHyperframeHtmlContract } from "./staticGuard";
|
||||||
|
|
||||||
@@ -514,7 +510,7 @@ export async function bundleToSingleHtml(
|
|||||||
if (innerW && !hostEl.getAttribute("data-width")) hostEl.setAttribute("data-width", innerW);
|
if (innerW && !hostEl.getAttribute("data-width")) hostEl.setAttribute("data-width", innerW);
|
||||||
if (innerH && !hostEl.getAttribute("data-height")) hostEl.setAttribute("data-height", innerH);
|
if (innerH && !hostEl.getAttribute("data-height")) hostEl.setAttribute("data-height", innerH);
|
||||||
for (const child of [...innerRoot.querySelectorAll("style, script")]) child.remove();
|
for (const child of [...innerRoot.querySelectorAll("style, script")]) child.remove();
|
||||||
hostEl.innerHTML = innerRoot.outerHTML || "";
|
hostEl.innerHTML = innerRoot.innerHTML || "";
|
||||||
} else {
|
} else {
|
||||||
for (const child of [...contentDoc.querySelectorAll("style, script")]) child.remove();
|
for (const child of [...contentDoc.querySelectorAll("style, script")]) child.remove();
|
||||||
hostEl.innerHTML = contentDoc.body.innerHTML || "";
|
hostEl.innerHTML = contentDoc.body.innerHTML || "";
|
||||||
@@ -578,8 +574,7 @@ export async function bundleToSingleHtml(
|
|||||||
if (innerW && !host.getAttribute("data-width")) host.setAttribute("data-width", innerW);
|
if (innerW && !host.getAttribute("data-width")) host.setAttribute("data-width", innerW);
|
||||||
if (innerH && !host.getAttribute("data-height")) host.setAttribute("data-height", innerH);
|
if (innerH && !host.getAttribute("data-height")) host.setAttribute("data-height", innerH);
|
||||||
|
|
||||||
// Preserve the inner composition root so bundled previews match the runtime loader.
|
host.innerHTML = innerRoot.innerHTML || "";
|
||||||
host.innerHTML = innerRoot.outerHTML || "";
|
|
||||||
} else {
|
} else {
|
||||||
// No matching inner root — inject all template content directly
|
// No matching inner root — inject all template content directly
|
||||||
for (const styleEl of [...innerDoc.querySelectorAll("style")]) {
|
for (const styleEl of [...innerDoc.querySelectorAll("style")]) {
|
||||||
|
|||||||
@@ -51,11 +51,16 @@ describe("loadExternalCompositions", () => {
|
|||||||
await loadExternalCompositions({ ...defaultParams });
|
await loadExternalCompositions({ ...defaultParams });
|
||||||
|
|
||||||
const mountedParagraph = host.querySelector("p");
|
const mountedParagraph = host.querySelector("p");
|
||||||
const innerRoot = host.firstElementChild;
|
|
||||||
|
|
||||||
expect(mountedParagraph).toBeTruthy();
|
expect(mountedParagraph).toBeTruthy();
|
||||||
expect(mountedParagraph?.textContent).toBe("Hello World");
|
expect(mountedParagraph?.textContent).toBe("Hello World");
|
||||||
expect(innerRoot?.getAttribute("data-composition-id")).toBe("scene-1");
|
expect(host.getAttribute("data-width")).toBe("1920");
|
||||||
|
expect(host.getAttribute("data-height")).toBe("1080");
|
||||||
|
expect(
|
||||||
|
Array.from(host.children).some(
|
||||||
|
(child) => child.getAttribute("data-composition-id") === "scene-1",
|
||||||
|
),
|
||||||
|
).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("injects styles into document head", async () => {
|
it("injects styles into document head", async () => {
|
||||||
@@ -230,6 +235,12 @@ describe("loadExternalCompositions", () => {
|
|||||||
expect(injectedStyles[0]?.textContent).toContain('[data-composition-id="scene"] .title');
|
expect(injectedStyles[0]?.textContent).toContain('[data-composition-id="scene"] .title');
|
||||||
expect(injectedScripts[0]?.textContent).toContain('var __hfCompId = "scene";');
|
expect(injectedScripts[0]?.textContent).toContain('var __hfCompId = "scene";');
|
||||||
expect(injectedScripts[0]?.textContent).toContain("new Proxy(window.document");
|
expect(injectedScripts[0]?.textContent).toContain("new Proxy(window.document");
|
||||||
|
expect(host.querySelector(".title")?.textContent).toBe("Scene");
|
||||||
|
expect(
|
||||||
|
Array.from(host.children).some(
|
||||||
|
(child) => child.getAttribute("data-composition-id") === "scene",
|
||||||
|
),
|
||||||
|
).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("handles multiple compositions in parallel", async () => {
|
it("handles multiple compositions in parallel", async () => {
|
||||||
|
|||||||
@@ -198,16 +198,13 @@ async function mountCompositionContent(params: {
|
|||||||
const heightRaw = innerRoot.getAttribute("data-height");
|
const heightRaw = innerRoot.getAttribute("data-height");
|
||||||
const widthPx = params.parseDimensionPx(widthRaw);
|
const widthPx = params.parseDimensionPx(widthRaw);
|
||||||
const heightPx = params.parseDimensionPx(heightRaw);
|
const heightPx = params.parseDimensionPx(heightRaw);
|
||||||
imported.style.position = "relative";
|
|
||||||
imported.style.width = widthPx || "100%";
|
|
||||||
imported.style.height = heightPx || "100%";
|
|
||||||
if (widthPx) imported.style.setProperty("--comp-width", widthPx);
|
|
||||||
if (heightPx) imported.style.setProperty("--comp-height", heightPx);
|
|
||||||
if (widthRaw) params.host.setAttribute("data-width", widthRaw);
|
if (widthRaw) params.host.setAttribute("data-width", widthRaw);
|
||||||
if (heightRaw) params.host.setAttribute("data-height", heightRaw);
|
if (heightRaw) params.host.setAttribute("data-height", heightRaw);
|
||||||
if (widthPx && params.host instanceof HTMLElement) params.host.style.width = widthPx;
|
if (widthPx && params.host instanceof HTMLElement) params.host.style.width = widthPx;
|
||||||
if (heightPx && params.host instanceof HTMLElement) params.host.style.height = heightPx;
|
if (heightPx && params.host instanceof HTMLElement) params.host.style.height = heightPx;
|
||||||
params.host.appendChild(imported);
|
while (imported.firstChild) {
|
||||||
|
params.host.appendChild(imported.firstChild);
|
||||||
|
}
|
||||||
} else if (params.hasTemplate) {
|
} else if (params.hasTemplate) {
|
||||||
params.host.appendChild(document.importNode(contentNode, true));
|
params.host.appendChild(document.importNode(contentNode, true));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { describe, expect, it, mock, beforeAll } from "bun:test";
|
|||||||
import { mkdtempSync, writeFileSync, mkdirSync } from "node:fs";
|
import { mkdtempSync, writeFileSync, mkdirSync } from "node:fs";
|
||||||
import { tmpdir } from "node:os";
|
import { tmpdir } from "node:os";
|
||||||
import { join } from "node:path";
|
import { join } from "node:path";
|
||||||
|
import { parseHTML } from "linkedom";
|
||||||
import {
|
import {
|
||||||
collectExternalAssets,
|
collectExternalAssets,
|
||||||
compileForRender,
|
compileForRender,
|
||||||
@@ -598,7 +599,7 @@ describe("template-wrapped sub-composition media offsets", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("preserves the sub-composition root in compiled render HTML", async () => {
|
it("flattens the sub-composition root onto the host in compiled render HTML", async () => {
|
||||||
const { projectDir, indexPath } = writeTemplateWrappedProject(
|
const { projectDir, indexPath } = writeTemplateWrappedProject(
|
||||||
'data-start="20" data-duration="6" data-width="640" data-height="360"',
|
'data-start="20" data-duration="6" data-width="640" data-height="360"',
|
||||||
'data-start="1.5" data-duration="4"',
|
'data-start="1.5" data-duration="4"',
|
||||||
@@ -606,9 +607,20 @@ describe("template-wrapped sub-composition media offsets", () => {
|
|||||||
|
|
||||||
const compiled = await compileForRender(projectDir, indexPath, projectDir);
|
const compiled = await compileForRender(projectDir, indexPath, projectDir);
|
||||||
|
|
||||||
expect(compiled.html).toContain('id="scene-host"');
|
const { document } = parseHTML(compiled.html);
|
||||||
expect(compiled.html).toContain('data-composition-id="scene" data-start="0"');
|
const host = document.querySelector("#scene-host");
|
||||||
|
|
||||||
|
expect(host?.getAttribute("data-composition-id")).toBe("scene");
|
||||||
|
expect(host?.getAttribute("data-start")).toBe("20");
|
||||||
|
expect(host?.getAttribute("data-width")).toBe("640");
|
||||||
|
expect(host?.querySelector(".title")?.textContent).toBe("Scene");
|
||||||
|
expect(
|
||||||
|
Array.from(host?.children ?? []).some(
|
||||||
|
(child) => child.getAttribute("data-composition-id") === "scene",
|
||||||
|
),
|
||||||
|
).toBe(false);
|
||||||
expect(compiled.html).toContain('[data-composition-id="scene"] .title');
|
expect(compiled.html).toContain('[data-composition-id="scene"] .title');
|
||||||
expect(compiled.html).toContain("new Proxy(window.document");
|
expect(compiled.html).toContain("new Proxy(window.document");
|
||||||
|
expect(compiled.html).toContain("__hfNormalizeSelector");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -655,7 +655,7 @@ function inlineSubCompositions(
|
|||||||
if (innerW && !host.getAttribute("data-width")) host.setAttribute("data-width", innerW);
|
if (innerW && !host.getAttribute("data-width")) host.setAttribute("data-width", innerW);
|
||||||
if (innerH && !host.getAttribute("data-height")) host.setAttribute("data-height", innerH);
|
if (innerH && !host.getAttribute("data-height")) host.setAttribute("data-height", innerH);
|
||||||
innerRoot.querySelectorAll("style, script").forEach((el) => el.remove());
|
innerRoot.querySelectorAll("style, script").forEach((el) => el.remove());
|
||||||
host.innerHTML = innerRoot.outerHTML || "";
|
host.innerHTML = innerRoot.innerHTML || "";
|
||||||
} else {
|
} else {
|
||||||
contentDoc.querySelectorAll("style, script").forEach((el) => el.remove());
|
contentDoc.querySelectorAll("style, script").forEach((el) => el.remove());
|
||||||
host.innerHTML = contentDoc.toString();
|
host.innerHTML = contentDoc.toString();
|
||||||
@@ -663,16 +663,6 @@ function inlineSubCompositions(
|
|||||||
|
|
||||||
host.removeAttribute("data-composition-src");
|
host.removeAttribute("data-composition-src");
|
||||||
|
|
||||||
// Propagate data-start from the host element to the inserted inner composition
|
|
||||||
// node so runtime timeline nesting resolves the correct start offset.
|
|
||||||
const hostDataStart = host.getAttribute("data-start");
|
|
||||||
if (hostDataStart != null) {
|
|
||||||
const innerComp = host.querySelector("[data-composition-id]");
|
|
||||||
if (innerComp && !innerComp.getAttribute("data-start")) {
|
|
||||||
innerComp.setAttribute("data-start", hostDataStart);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set explicit pixel dimensions on the host element so children using
|
// Set explicit pixel dimensions on the host element so children using
|
||||||
// width/height: 100% resolve correctly. The runtime does this
|
// width/height: 100% resolve correctly. The runtime does this
|
||||||
// automatically but compiled HTML needs it inline.
|
// automatically but compiled HTML needs it inline.
|
||||||
|
|||||||
Reference in New Issue
Block a user