From 949a43735401a314bf1c66109c881018cd68f7a5 Mon Sep 17 00:00:00 2001 From: lorenzozanee Date: Fri, 18 Sep 2026 23:11:29 +0800 Subject: [PATCH] fix(core): scope GSAP selector arrays within compositions --- .../src/compiler/compositionScoping.test.ts | 40 +++++++++++++++++++ .../core/src/compiler/compositionScoping.ts | 11 ++++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/packages/core/src/compiler/compositionScoping.test.ts b/packages/core/src/compiler/compositionScoping.test.ts index 3a8d3613fb8..65d56fd88ea 100644 --- a/packages/core/src/compiler/compositionScoping.test.ts +++ b/packages/core/src/compiler/compositionScoping.test.ts @@ -384,6 +384,46 @@ window.__timelines.scene = tl; expect(gsapTargets).toEqual([["Scene"], ["Scene"]]); }); + it("scopes each selector in a GSAP target array to the composition root", () => { + const { document } = parseHTML(` +
+

Scene title

+

Scene subtitle

+
+
+

Other title

+

Other subtitle

+
+ `); + const targetCompositions: Array = []; + const fakeWindow = { + document, + __timelines: {}, + gsap: { + to(targets: Array) { + const resolvedTargets = targets.flatMap((target) => + typeof target === "string" ? Array.from(document.querySelectorAll(target)) : [target], + ); + targetCompositions.push( + ...resolvedTargets.map( + (target) => + target.closest("[data-composition-id]")?.getAttribute("data-composition-id") ?? + null, + ), + ); + }, + }, + }; + const wrapped = wrapScopedCompositionScript( + `gsap.to(['.title', '.subtitle'], { opacity: 1 });`, + "scene", + ); + + new Function("window", "gsap", wrapped)(fakeWindow, fakeWindow.gsap); + + expect(targetCompositions).toEqual(["scene", "scene"]); + }); + it("scopes getElementById when duplicate IDs exist across composition roots", () => { const { document } = parseHTML(`
diff --git a/packages/core/src/compiler/compositionScoping.ts b/packages/core/src/compiler/compositionScoping.ts index 7b184131b8d..8b2af76bc1a 100644 --- a/packages/core/src/compiler/compositionScoping.ts +++ b/packages/core/src/compiler/compositionScoping.ts @@ -524,8 +524,15 @@ export function wrapScopedCompositionScript( }) : window; var __hfResolveGsapTarget = function(target) { - if (typeof target !== "string") return target; - return __hfQueryAll(target); + if (typeof target === "string") return __hfQueryAll(target); + if (!Array.isArray(target)) return target; + return target.reduce(function(resolved, item) { + if (typeof item === "string") { + return resolved.concat(Array.prototype.slice.call(__hfQueryAll(item))); + } + resolved.push(item); + return resolved; + }, []); }; var __hfScopeTimeline = function(timeline) { if (!timeline || timeline.__hfScopedCompositionRoot === __hfFindRoot()) return timeline;