Repository navigation
fix(core): two scenes drawing SVGs with the same ids each show their own - #7251
Conversation
Edit accuracy: accurate 267 (base branch 267), smooth 103 of thoseThe gate passes. Quarantined, measured but not gated (8)
Unstable (2)
|
There was a problem hiding this comment.
Verdict: REQUEST CHANGES · 1 blocker · 0 important · 0 nits · head bfe2db3c
The fix itself looks right, and both named unit tests fail on main's source files when I run them. The blocker is that required CI is red: Typecheck and Test: runtime contract both fail with TS2339 at compositionLoader.ts:917 (↓ inline). It's a one-line type annotation.
Scope
Read all 6 files plus the namespaceCollidingSvgIds / selector-alias paths they feed. Ran inlineSubCompositions.test.ts and compositionLoader.test.ts locally (116/116 pass). With main's three source files restored, the two new scene tests fail and the page-level guard passes, which matches the fails without the fix: line. I checked that the annotation below clears the TS error locally. I didn't run the browser snapshot test locally; the CLI test shards pass in CI. Out of scope: scenes that sit inside a timed wrapper clip, and <svg data-start> used directly as the clip. Both stay in one scope, which is no regression.
| const hosts = composed | ||
| .filter((scope) => scope.referenceTarget !== "document") | ||
| .map(({ host }) => host); | ||
| const mounted = [ |
There was a problem hiding this comment.
blocker: TypeScript infers mounted as the union MountedSvgScope | { host; namespace; styles: never[] }, so destructuring referenceTarget at L917 fails typecheck: TS2339: Property 'referenceTarget' does not exist. That error fails CI jobs Typecheck and Test: runtime contract.
| const mounted = [ | |
| const mounted: MountedSvgScope[] = [ |
…view Adopts heygen-com#7250 (SVG stroke drawing is not a dead stretch), heygen-com#7248 (contract check reads a timeline registered in a local script), heygen-com#7252 (comma-list selectors hidden by authored CSS), heygen-com#7238 (snapshot and preview show a clip on the render frame), heygen-com#7237 (stalled cloud upload retries) and heygen-com#7251 (per-scene SVG id namespacing), with prerequisite heygen-com#6829. Defers heygen-com#7246 (needs the delivery limiter from heygen-com#6940) and heygen-com#7232 (needs the WebKit decode-first pipeline), with conditions in the ledger. Watermark advances to b108f85. Co-authored-by: Miguel Ángel <miguel.sierra@heygen.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
What
Two scenes in one composition can now draw their SVGs with the same ids. Each scene's
url(#id)andhref="#id"resolve to its own definitions in preview, snapshot and render.Why
A report:
snapshot --at 4,86,141on a film with two distinct inline SVG character portraits, one per scene, showed the first portrait again in the last scene.Both portraits were written straight into
index.html, one per scene clip, and both used the same ids (a gradient, a clip path, a symbol). The browser resolvesurl(#skin)andhref="#portrait"to the first element with that id in the page, so the second scene painted the first scene's pieces, and its own gradient painted nothing while the first scene was hidden. Render shows the same thing as snapshot. The same portraits as two sub-compositions (data-composition-src) come out right, because loading a sub-composition renames colliding SVG ids; ids written in the main page were never renamed.Related work
None.
How
svgIdNamespacing.tsalready renames colliding SVG ids per scope (each inlined composition), keeps the first definition's id, and rewrites only that scope's references. The newsceneClipRootsadds one more kind of scope: each outermost timed clip (data-start) that holds an<svg>, outside every composition host. The compiler (inlineSubCompositions) and the runtime loader (namespaceMountedSvgIds) both pass those clips to the same renamer, next to the composition hosts.What it leaves alone:
clip-1--skin) and their own references follow.Test plan
inlineSubCompositions.test.ts"gives each scene clip its own portrait when two scenes reuse the same SVG ids": each scene'sfillandhrefresolve inside that scene, and the first scene keeps its ids. "leaves a page-level definition the scenes share where it is": both scenes still useurl(#shared).compositionLoader.test.ts"resolves each top-level scene clip to its own clipPath, and a shared page-level one for both": the same at runtime.snapshot.sceneSvgIds.browser.test.ts: two red/blue portraits with the same ids, plus a corner filled from a page-level gradient, snapshotted at 4 s and 14 s, reading pixels.fails without the fix: with main's three source files, the compiler test, the loader test and the snapshot test fail (at 14 s the face is black and the corner piece red); the page-level test passes either way, as a guard.
Before and after, over every registry example, block and component and every producer regression project (549 entries):
<svg>. The census does flag the repro fixture, so it can see the case it looks for.Unit tests added/updated
Manual testing performed
Documentation updated (if applicable)
Comments follow CONTRIBUTING.md "Comments": they say why, not what, and a bug fix says what the code must do and how to reproduce the bug
Not exercised: the reporter's own project, and full renders of the regression projects; the census above is why none of them can change.