@hyperframes/parsers 0.7.15 → 0.7.16
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.
- package/dist/gsapParser.js +76 -25
- package/dist/gsapParser.js.map +1 -1
- package/dist/gsapParserAcorn.js +67 -27
- package/dist/gsapParserAcorn.js.map +1 -1
- package/dist/gsapParserExports.js +60 -22
- package/dist/gsapParserExports.js.map +1 -1
- package/dist/gsapWriterAcorn.js +70 -26
- package/dist/gsapWriterAcorn.js.map +1 -1
- package/dist/index.js +64 -25
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/gsapParserAcorn.js
CHANGED
|
@@ -663,6 +663,34 @@ function objectExpressionToRecord(node, scope, source) {
|
|
|
663
663
|
function isGsapTimelineCall(node) {
|
|
664
664
|
return node?.type === "CallExpression" && node.callee?.type === "MemberExpression" && node.callee.object?.name === "gsap" && node.callee.property?.name === "timeline";
|
|
665
665
|
}
|
|
666
|
+
function staticMemberKey(node) {
|
|
667
|
+
if (!node || node.type !== "MemberExpression") return null;
|
|
668
|
+
if (node.computed) {
|
|
669
|
+
const p = node.property;
|
|
670
|
+
if (p?.type === "Literal" && typeof p.value === "string") return p.value;
|
|
671
|
+
return null;
|
|
672
|
+
}
|
|
673
|
+
return node.property?.type === "Identifier" ? node.property.name : null;
|
|
674
|
+
}
|
|
675
|
+
function isStaticMemberRef(node) {
|
|
676
|
+
return node?.type === "MemberExpression" && staticMemberKey(node) !== null;
|
|
677
|
+
}
|
|
678
|
+
function sameMemberAccess(a, b) {
|
|
679
|
+
if (a?.type !== "MemberExpression" || b?.type !== "MemberExpression") return false;
|
|
680
|
+
if (staticMemberKey(a) !== staticMemberKey(b) || staticMemberKey(a) === null) return false;
|
|
681
|
+
const ao = a.object;
|
|
682
|
+
const bo = b.object;
|
|
683
|
+
if (ao?.type === "Identifier" && bo?.type === "Identifier") return ao.name === bo.name;
|
|
684
|
+
if (ao?.type === "MemberExpression" && bo?.type === "MemberExpression")
|
|
685
|
+
return sameMemberAccess(ao, bo);
|
|
686
|
+
return false;
|
|
687
|
+
}
|
|
688
|
+
function timelineRootSource(ref, script) {
|
|
689
|
+
return ref.kind === "identifier" ? ref.name : script.slice(ref.node.start, ref.node.end);
|
|
690
|
+
}
|
|
691
|
+
function escapeRegExp(s) {
|
|
692
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
693
|
+
}
|
|
666
694
|
function extractTimelineDefaults(callNode, scope) {
|
|
667
695
|
const arg = callNode.arguments?.[0];
|
|
668
696
|
if (!arg || arg.type !== "ObjectExpression") return void 0;
|
|
@@ -682,6 +710,7 @@ function extractTimelineDefaults(callNode, scope) {
|
|
|
682
710
|
}
|
|
683
711
|
function findTimelineVar(ast, scope) {
|
|
684
712
|
let timelineVar = null;
|
|
713
|
+
let ref = null;
|
|
685
714
|
let timelineCount = 0;
|
|
686
715
|
let defaults;
|
|
687
716
|
const emptyScope = scope ?? /* @__PURE__ */ new Map();
|
|
@@ -689,8 +718,9 @@ function findTimelineVar(ast, scope) {
|
|
|
689
718
|
VariableDeclarator(node) {
|
|
690
719
|
if (isGsapTimelineCall(node.init)) {
|
|
691
720
|
timelineCount += 1;
|
|
692
|
-
if (!
|
|
693
|
-
timelineVar = node.id
|
|
721
|
+
if (!ref && node.id?.type === "Identifier") {
|
|
722
|
+
timelineVar = node.id.name;
|
|
723
|
+
ref = { kind: "identifier", name: node.id.name };
|
|
694
724
|
defaults = extractTimelineDefaults(node.init, emptyScope);
|
|
695
725
|
}
|
|
696
726
|
}
|
|
@@ -698,15 +728,21 @@ function findTimelineVar(ast, scope) {
|
|
|
698
728
|
AssignmentExpression(node) {
|
|
699
729
|
if (isGsapTimelineCall(node.right)) {
|
|
700
730
|
timelineCount += 1;
|
|
701
|
-
if (!
|
|
731
|
+
if (!ref) {
|
|
702
732
|
const left = node.left;
|
|
703
|
-
if (left?.type === "Identifier")
|
|
704
|
-
|
|
733
|
+
if (left?.type === "Identifier") {
|
|
734
|
+
timelineVar = left.name;
|
|
735
|
+
ref = { kind: "identifier", name: left.name };
|
|
736
|
+
defaults = extractTimelineDefaults(node.right, emptyScope);
|
|
737
|
+
} else if (isStaticMemberRef(left)) {
|
|
738
|
+
ref = { kind: "member", node: left };
|
|
739
|
+
defaults = extractTimelineDefaults(node.right, emptyScope);
|
|
740
|
+
}
|
|
705
741
|
}
|
|
706
742
|
}
|
|
707
743
|
}
|
|
708
744
|
});
|
|
709
|
-
return { timelineVar, timelineCount, defaults };
|
|
745
|
+
return { timelineVar, ref, timelineCount, defaults };
|
|
710
746
|
}
|
|
711
747
|
var BUILTIN_VAR_KEYS = /* @__PURE__ */ new Set(["duration", "ease", "delay"]);
|
|
712
748
|
var DROPPED_VAR_KEYS = /* @__PURE__ */ new Set(["onComplete", "onStart", "onUpdate", "onRepeat"]);
|
|
@@ -719,14 +755,15 @@ var EXTRAS_KEYS = /* @__PURE__ */ new Set([
|
|
|
719
755
|
"overwrite",
|
|
720
756
|
"immediateRender"
|
|
721
757
|
]);
|
|
722
|
-
function isTimelineRootedCall(callNode,
|
|
758
|
+
function isTimelineRootedCall(callNode, ref) {
|
|
723
759
|
let obj = callNode.callee?.object;
|
|
724
760
|
while (obj?.type === "CallExpression") {
|
|
725
761
|
obj = obj.callee?.object;
|
|
726
762
|
}
|
|
727
|
-
return obj?.type === "Identifier" && obj.name ===
|
|
763
|
+
if (ref.kind === "identifier") return obj?.type === "Identifier" && obj.name === ref.name;
|
|
764
|
+
return sameMemberAccess(obj, ref.node);
|
|
728
765
|
}
|
|
729
|
-
function findAllTweenCalls(ast,
|
|
766
|
+
function findAllTweenCalls(ast, ref, scope, targetBindings) {
|
|
730
767
|
const results = [];
|
|
731
768
|
function visit(node, ancestors) {
|
|
732
769
|
if (!node || typeof node !== "object") return;
|
|
@@ -735,7 +772,7 @@ function findAllTweenCalls(ast, timelineVar, scope, targetBindings) {
|
|
|
735
772
|
const callee = node.callee;
|
|
736
773
|
const gsapSetArg = node.arguments?.[0];
|
|
737
774
|
const isGlobalSet = callee?.type === "MemberExpression" && callee.object?.type === "Identifier" && callee.object.name === "gsap" && callee.property?.type === "Identifier" && callee.property.name === "set" && (gsapSetArg?.type === "StringLiteral" || gsapSetArg?.type === "Literal" && typeof gsapSetArg.value === "string");
|
|
738
|
-
if (callee?.type === "MemberExpression" && callee.property?.type === "Identifier" && (isTimelineRootedCall(node,
|
|
775
|
+
if (callee?.type === "MemberExpression" && callee.property?.type === "Identifier" && (isTimelineRootedCall(node, ref) || isGlobalSet) && GSAP_METHODS2.has(callee.property.name)) {
|
|
739
776
|
const method = callee.property.name;
|
|
740
777
|
const args = node.arguments;
|
|
741
778
|
const selectorValue = args.length >= 1 ? resolveTargetSelector(args[0], nodeAncestors, scope, targetBindings) ?? "__unresolved__" : "__unresolved__";
|
|
@@ -1188,8 +1225,9 @@ function parseGsapScriptAcornForWrite(script) {
|
|
|
1188
1225
|
const scope = collectScopeBindings(ast);
|
|
1189
1226
|
const targetBindings = collectTargetBindings(ast, scope);
|
|
1190
1227
|
const detection = findTimelineVar(ast, scope);
|
|
1191
|
-
const
|
|
1192
|
-
const
|
|
1228
|
+
const ref = detection.ref ?? { kind: "identifier", name: "tl" };
|
|
1229
|
+
const timelineVar = timelineRootSource(ref, script);
|
|
1230
|
+
const calls = findAllTweenCalls(ast, ref, scope, targetBindings);
|
|
1193
1231
|
sortBySourcePosition(calls);
|
|
1194
1232
|
const rawAnims = calls.map((call) => tweenCallToAnimation(call, scope, script));
|
|
1195
1233
|
applyTimelineDefaults(rawAnims, detection.defaults);
|
|
@@ -1200,7 +1238,7 @@ function parseGsapScriptAcornForWrite(script) {
|
|
|
1200
1238
|
call,
|
|
1201
1239
|
animation: animations[i]
|
|
1202
1240
|
}));
|
|
1203
|
-
return { ast, timelineVar, hasTimeline: detection.
|
|
1241
|
+
return { ast, timelineVar, hasTimeline: detection.ref !== null, located };
|
|
1204
1242
|
} catch {
|
|
1205
1243
|
return null;
|
|
1206
1244
|
}
|
|
@@ -1214,24 +1252,25 @@ function parseGsapScriptAcorn(script) {
|
|
|
1214
1252
|
});
|
|
1215
1253
|
const scope = collectScopeBindings(ast);
|
|
1216
1254
|
const detection = findTimelineVar(ast, scope);
|
|
1217
|
-
const
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1255
|
+
const ref = detection.ref ?? { kind: "identifier", name: "tl" };
|
|
1256
|
+
const timelineVar = timelineRootSource(ref, script);
|
|
1257
|
+
if (ref.kind === "identifier") {
|
|
1258
|
+
try {
|
|
1259
|
+
inlineComputedTimelines(ast, timelineVar, (node) => resolveNode(node, scope));
|
|
1260
|
+
} catch {
|
|
1261
|
+
}
|
|
1221
1262
|
}
|
|
1222
1263
|
const targetBindings = collectTargetBindings(ast, scope);
|
|
1223
|
-
const calls = findAllTweenCalls(ast,
|
|
1264
|
+
const calls = findAllTweenCalls(ast, ref, scope, targetBindings);
|
|
1224
1265
|
sortBySourcePosition(calls);
|
|
1225
1266
|
const rawAnims = calls.map((call) => tweenCallToAnimation(call, scope, script));
|
|
1226
1267
|
applyTimelineDefaults(rawAnims, detection.defaults);
|
|
1227
1268
|
resolveTimelinePositions(rawAnims);
|
|
1228
1269
|
const animations = assignStableIds(rawAnims);
|
|
1229
|
-
const
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
);
|
|
1234
|
-
const preamble = timelineMatch?.[0] ?? `const ${timelineVar} = gsap.timeline({ paused: true });`;
|
|
1270
|
+
const declPattern = ref.kind === "identifier" ? `(?:const|let|var)\\s+${timelineVar}\\s*=\\s*gsap\\.timeline\\s*\\([^)]*\\)\\s*;?` : `${escapeRegExp(timelineVar)}\\s*=\\s*gsap\\.timeline\\s*\\([^)]*\\)\\s*;?`;
|
|
1271
|
+
const timelineMatch = script.match(new RegExp(`^[\\s\\S]*?${declPattern}`));
|
|
1272
|
+
const fallbackPreamble = ref.kind === "identifier" ? `const ${timelineVar} = gsap.timeline({ paused: true });` : `${timelineVar} = gsap.timeline({ paused: true });`;
|
|
1273
|
+
const preamble = timelineMatch?.[0] ?? fallbackPreamble;
|
|
1235
1274
|
const lastCallIdx = script.lastIndexOf(`${timelineVar}.`);
|
|
1236
1275
|
let postamble = "";
|
|
1237
1276
|
if (lastCallIdx !== -1) {
|
|
@@ -1243,7 +1282,7 @@ function parseGsapScriptAcorn(script) {
|
|
|
1243
1282
|
}
|
|
1244
1283
|
const result = { animations, timelineVar, preamble, postamble };
|
|
1245
1284
|
if (detection.timelineCount > 1) result.multipleTimelines = true;
|
|
1246
|
-
if (detection.timelineCount > 0 && detection.
|
|
1285
|
+
if (detection.timelineCount > 0 && detection.ref === null)
|
|
1247
1286
|
result.unsupportedTimelinePattern = true;
|
|
1248
1287
|
return result;
|
|
1249
1288
|
} catch {
|
|
@@ -1259,7 +1298,7 @@ function extractGsapLabels(script) {
|
|
|
1259
1298
|
});
|
|
1260
1299
|
const scope = collectScopeBindings(ast);
|
|
1261
1300
|
const detection = findTimelineVar(ast, scope);
|
|
1262
|
-
const
|
|
1301
|
+
const ref = detection.ref ?? { kind: "identifier", name: "tl" };
|
|
1263
1302
|
const labels = [];
|
|
1264
1303
|
acornWalk.simple(ast, {
|
|
1265
1304
|
// fallow-ignore-next-line complexity
|
|
@@ -1267,7 +1306,8 @@ function extractGsapLabels(script) {
|
|
|
1267
1306
|
const expr = node.expression;
|
|
1268
1307
|
if (!expr || expr.type !== "CallExpression") return;
|
|
1269
1308
|
const callee = expr.callee;
|
|
1270
|
-
|
|
1309
|
+
const objMatches = ref.kind === "identifier" ? callee.object?.type === "Identifier" && callee.object.name === ref.name : sameMemberAccess(callee.object, ref.node);
|
|
1310
|
+
if (callee?.type !== "MemberExpression" || !objMatches || callee.property?.name !== "addLabel")
|
|
1271
1311
|
return;
|
|
1272
1312
|
const args = expr.arguments ?? [];
|
|
1273
1313
|
const nameNode = args[0];
|