Repository navigation
fix(core): name the selector when a scoped GSAP target matches nothing - #5839
Conversation
miguel-heygen
left a comment
There was a problem hiding this comment.
Thank you for this, and welcome. This is a careful first change: small, well scoped to request 1 of the issue, and the write up explains the two trailing warnings instead of hiding them.
I verified the mechanism against the GSAP source rather than the screenshots, because the fix leans on how the library builds that string. In 3.15 the Tween constructor concatenates the original argument into the warning, not the parsed target list, so the overridden toString on the array you hand in is genuinely the one that prints. I also traced what happens to that array afterwards: it goes through the library's own toArray, which flattens into a fresh array, so the tag cannot escape into the scoped utils.toArray result or into author code. I replayed the resolver under node with an always empty query to confirm the named selector, the comma joined array form, the unchanged empty case and the untouched non empty path. The scoping invariant holds: the list is still empty, so nothing outside the composition is ever targeted.
Two notes for later, neither blocking. The fix rests on a library internal that no test here pins, since the new test uses a stub, so a future GSAP upgrade could quietly take the selector back out of the warning with everything still green. If the check output ever becomes something people script against, one test driving the real library through the wrapper would be worth having. And the override makes toString an own enumerable property of the array, which is contained today because the value never leaves the resolver's call sites; defineProperty would take that edge off for one more line.
On checks: only the mergeability and WIP jobs have run at this head, so the repo suite has not actually been exercised here. The branch is also a few hundred commits behind main, so please pull main in and let a full run happen before it merges.
jrusso1020
left a comment
There was a problem hiding this comment.
Reviewed at 71d55882. Approving, on top of Miguel's approval at this head. On main, when a scoped selector matches nothing, __hfResolveGsapTarget returns an empty array or NodeList. GSAP builds its warning by string concatenation, so it prints GSAP target not found. The fix only touches that empty case. It still returns an empty array, so nothing outside the composition is targeted, and the array's toString() returns the authored selector. The non-empty path returns the same value as before.
The new test checks the three things that matter: the target is empty, String(target) is the selector, and a matching element in another composition isn't picked up. It fails on main, where String([]) is empty.
Need: yes, request 1 of #5687 · Size: ok · Reuse: nothing to reuse · Simpler: already minimal
— Rames
|
Thanks, @serdarucel. This one is approved, and it'll go into the merge queue once these are sorted:
Once it's green and signed, we'll queue it at your new head. If you push code changes beyond a rebase, we'll take another look first. — Rames |
71d5588 to
a084bee
Compare
|
Thanks! Rebased on main and signed the commit; no code changes. The timeline viewport gate failure was the |
jrusso1020
left a comment
There was a problem hiding this comment.
Re-approving at the new head. I diffed this PR's own patch against the head I approved and it is identical, so this is a rebase and re-sign.
|
Thanks, @serdarucel. CI at — Rames |
A sub-composition resolves GSAP selectors to a list of in-scope elements. When that list is empty, GSAP's "target not found" warning stringified it as an empty name, so check reported `GSAP target not found` with no hint of which selector missed. Keep the empty list but give it the authored selector as its text, matching what GSAP prints in a root composition. Refs heygen-com#5687
a084bee to
b3e911f
Compare
|
Thanks! Updated both goldens with |
miguel-heygen
left a comment
There was a problem hiding this comment.
Thanks for updating the goldens. I compared this head against the one I approved: the resolver and its test are unchanged. Each golden changes only in the __hfResolveGsapTarget block, one hunk per mount, which is the expected snapshot diff.
CI is fully green here on both Linux and Windows. My two earlier notes (a test that drives the real GSAP warning through the wrapper, and defineProperty for the toString override) are still optional follow-ups, not blockers.
Verdict: APPROVE
Reasoning: The only change since the approved head is the expected golden update, and every check passes at this head.
jrusso1020
left a comment
There was a problem hiding this comment.
Only adds the regenerated pageBuild golden snapshots, which match the source change. Re-approving at the new head.
What
When a GSAP selector inside a sub-composition matches nothing, the
hyperframes checkwarning now names the selector:instead of
GSAP target not found. https://gsap.com.Why
The empty name makes the warning not actionable: in a composition with several tweens there is no way to tell which target missed (request 1 in #5687).
Related work
Refs #5687. This covers request 1 only (selector text in the message); the
--strictescalation and a dedicated rule code (requests 2 and 3) are not part of this PR.How
__hfResolveGsapTargetinpackages/core/src/compiler/compositionScoping.tsturns a string (or array of strings) into the in-scope elements before GSAP sees it. GSAP 3.15 builds the warning as"GSAP target " + targets + " not found"(gsap-core.js, Tween constructor), so an empty array prints as an empty string.When the resolved list is empty, the resolver still returns an empty array (nothing outside the composition gets targeted), but that array's
toString()returns the authored target. The non-empty path is unchanged.The two
GSAP target not foundlines that follow the named one come from GSAP itself (thefromTofrom-stateseton the already-empty_targets). A root composition with the samefromToand no scoping prints the same three lines, so after this change a sub-composition matches root behavior.Test plan
Reproduction project: root
index.html+ one sub-composition (compositions/reco.html) withtl.fromTo('[data-part="reco-title"]', ...)against an element that only hasclass="reco-title". Rannpx tsx src/cli.ts check <proj> --no-contrastfrompackages/clion Windows 11.Before (main
e9181d0):After:
Same
fromToin a root composition (no scoping), for comparison: the same three lines as After.compositionScoping.test.ts. The resolved target is empty,String(target)is the selector, and a matching element in another composition is not targeted. The test fails on main and passes with the change.npx vitest run src/compiler/compositionScoping.test.ts: 79 passed.npx vitest run src/compilerinpackages/core: 564 passed, 2 failed. The 2 failures are thehtmlBundler.test.tssymlink tests (EPERM: operation not permitted, symlink, Windows without symlink privilege), and they fail the same way on main.oxlint,oxfmt --check,bun run typecheck(core),node scripts/check-comment-citations.mjsandnode scripts/comment-ratchet.mjsare clean.