/** * Declarative variable bindings — the no-script consumption channel for * composition variables (values are fixed for the page's lifetime, so this is * seek-safe and deterministic): * * - `data-var-src="id"` — sets the element's `src` from the variable value * (a URL string or an image value `{url}`). Only allowed on media elements * (img/video/audio/source) and only for safe URL protocols — a src on a * script-executing tag or a `javascript:`/`data:text/html` value is refused. * The authored src stays as the fallback when the variable resolves to nothing. * - `data-var-text="id"` — sets the element's OWN text from a scalar variable * value. Elements with element children keep them: only the direct text * node is replaced, mirroring the SDK's setOwnText semantics — a text * binding must never delete nested clips or animation targets. * - Every scalar variable (and a font value's family name) is applied as a * `--{id}` CSS custom property on its composition root, so CSS bindings * like `color: var(--accent)` respond to render/preview overrides instead * of only the persisted default. * * Values resolve against the element's owning composition — the same scope * chain the color-grading runtime uses: `__hfVariablesByComp[compId]` for * inlined sub-compositions, then the top-level merged `getVariables()`. * * Applied at init AND re-applied after the composition loader inlines * external / template sub-compositions (their DOM and per-instance scoped * values don't exist at init). Idempotent: re-applying writes the same * values. */ import { readVariablesForElement } from "./variableScope"; import { isScalarVariableValue as isScalar } from "@hyperframes/parsers/composition"; // data-var-src only rebinds media `src` on media elements. A user-controlled // variable value assigned to a src is an XSS surface on tags whose src executes // (`