@hyperframes/parsers 0.7.67 → 0.7.69

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -35,6 +35,10 @@ declare function parseGsapScriptAcornForWrite(script: string): ParsedGsapAcornFo
35
35
  * Uses acorn + acorn-walk instead of recast + @babel/parser.
36
36
  */
37
37
  declare function parseGsapScriptAcorn(script: string): ParsedGsap;
38
+ /** Source offset of the first timeline or standalone GSAP MotionPathPlugin tween. */
39
+ declare function gsapScriptMotionPathFirstUseIndex(script: string): number | null;
40
+ /** True when a timeline or standalone GSAP tween authors a MotionPathPlugin property. */
41
+ declare function gsapScriptUsesMotionPath(script: string): boolean;
38
42
  interface GsapLabelEntry {
39
43
  name: string;
40
44
  position: number;
@@ -49,4 +53,4 @@ interface GsapLabelEntry {
49
53
  */
50
54
  declare function extractGsapLabels(script: string): GsapLabelEntry[];
51
55
 
52
- export { type GsapLabelEntry, type ParsedGsapAcornForWrite, type TweenCallInfo, extractGsapLabels, parseGsapScriptAcorn, parseGsapScriptAcornForWrite };
56
+ export { type GsapLabelEntry, type ParsedGsapAcornForWrite, type TweenCallInfo, extractGsapLabels, gsapScriptMotionPathFirstUseIndex, gsapScriptUsesMotionPath, parseGsapScriptAcorn, parseGsapScriptAcornForWrite };
@@ -470,6 +470,21 @@ var SCOPE_NODE_TYPES = /* @__PURE__ */ new Set([
470
470
  "FunctionExpression",
471
471
  "ArrowFunctionExpression"
472
472
  ]);
473
+ function parseProgram(script) {
474
+ try {
475
+ return acorn.parse(script, {
476
+ ecmaVersion: "latest",
477
+ sourceType: "script",
478
+ locations: true
479
+ });
480
+ } catch {
481
+ return acorn.parse(script, {
482
+ ecmaVersion: "latest",
483
+ sourceType: "module",
484
+ locations: true
485
+ });
486
+ }
487
+ }
473
488
  var CONST_NODES = /* @__PURE__ */ Symbol("hf.constNodes");
474
489
  function constNodesOf(scope) {
475
490
  return scope[CONST_NODES];
@@ -1615,11 +1630,7 @@ function parseGsapScriptAcornForWrite(script) {
1615
1630
  }
1616
1631
  function parseGsapScriptAcorn(script) {
1617
1632
  try {
1618
- const ast = acorn.parse(script, {
1619
- ecmaVersion: "latest",
1620
- sourceType: "script",
1621
- locations: true
1622
- });
1633
+ const ast = parseProgram(script);
1623
1634
  const scope = collectScopeBindings(ast);
1624
1635
  const detection = findTimelineVar(ast, scope);
1625
1636
  const ref = detection.ref ?? { kind: "identifier", name: "tl" };
@@ -1665,6 +1676,71 @@ function parseGsapScriptAcorn(script) {
1665
1676
  return { animations: [], timelineVar: "tl", preamble: "", postamble: "" };
1666
1677
  }
1667
1678
  }
1679
+ function gsapScriptMotionPathFirstUseIndex(script) {
1680
+ try {
1681
+ const ast = parseProgram(script);
1682
+ const scope = collectScopeBindings(ast);
1683
+ const identifierBindings = collectIdentifierBindingIndex(ast);
1684
+ const timelineRef = findTimelineVar(ast, scope).ref;
1685
+ const timelineDeclarations = /* @__PURE__ */ new Set();
1686
+ let firstUseIndex = null;
1687
+ acornWalk.ancestor(ast, {
1688
+ VariableDeclarator(node) {
1689
+ if (node.id?.type === "Identifier" && isGsapTimelineCall(node.init)) {
1690
+ timelineDeclarations.add(node);
1691
+ }
1692
+ },
1693
+ AssignmentExpression(node, _, ancestors) {
1694
+ if (node.left?.type === "Identifier" && isGsapTimelineCall(node.right)) {
1695
+ const declaration = findVisibleIdentifierDeclaration(
1696
+ node.left.name,
1697
+ ancestors,
1698
+ identifierBindings,
1699
+ node.start
1700
+ );
1701
+ if (declaration) timelineDeclarations.add(declaration.node);
1702
+ }
1703
+ }
1704
+ });
1705
+ acornWalk.ancestor(ast, {
1706
+ CallExpression(node, _, ancestors) {
1707
+ const callee = node.callee;
1708
+ const method = callee?.property?.name;
1709
+ if (callee?.type !== "MemberExpression" || !GSAP_METHODS2.has(method)) return;
1710
+ let rootObject = callee.object;
1711
+ while (rootObject?.type === "CallExpression") rootObject = rootObject.callee?.object;
1712
+ const isGsapRooted = rootObject?.type === "Identifier" && rootObject.name === "gsap";
1713
+ const visibleTimelineDeclaration = rootObject?.type === "Identifier" ? findVisibleIdentifierDeclaration(
1714
+ rootObject.name,
1715
+ ancestors,
1716
+ identifierBindings,
1717
+ node.start
1718
+ ) : void 0;
1719
+ const isTimelineTween = (timelineRef?.kind === "member" ? isTimelineRootedCall(node, timelineRef) : false) || !!visibleTimelineDeclaration && timelineDeclarations.has(visibleTimelineDeclaration.node);
1720
+ if (!isGsapRooted && !isTimelineTween) return;
1721
+ const varsArgs = method === "fromTo" ? [node.arguments?.[1], node.arguments?.[2]] : [node.arguments?.[1]];
1722
+ if (varsArgs.some((varsArg) => {
1723
+ if (findPropertyNode(varsArg, "motionPath")) return true;
1724
+ if (varsArg?.type !== "Identifier") return false;
1725
+ const declaration = findVisibleIdentifierDeclaration(
1726
+ varsArg.name,
1727
+ ancestors,
1728
+ identifierBindings,
1729
+ node.start
1730
+ );
1731
+ return !!findPropertyNode(declaration?.node.init, "motionPath");
1732
+ }))
1733
+ firstUseIndex = firstUseIndex === null ? node.start : Math.min(firstUseIndex, node.start);
1734
+ }
1735
+ });
1736
+ return firstUseIndex;
1737
+ } catch {
1738
+ return null;
1739
+ }
1740
+ }
1741
+ function gsapScriptUsesMotionPath(script) {
1742
+ return gsapScriptMotionPathFirstUseIndex(script) !== null;
1743
+ }
1668
1744
  function extractGsapLabels(script) {
1669
1745
  try {
1670
1746
  const ast = acorn.parse(script, {
@@ -1704,6 +1780,8 @@ export {
1704
1780
  buildArcPath,
1705
1781
  editabilityForProvenance,
1706
1782
  extractGsapLabels,
1783
+ gsapScriptMotionPathFirstUseIndex,
1784
+ gsapScriptUsesMotionPath,
1707
1785
  parseGsapScriptAcorn,
1708
1786
  parseGsapScriptAcornForWrite
1709
1787
  };