@hyperframes/parsers 0.7.23 → 0.7.25
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/gsapParserAcorn.js +278 -20
- package/dist/gsapParserAcorn.js.map +1 -1
- package/dist/gsapParserExports.js +278 -20
- package/dist/gsapParserExports.js.map +1 -1
- package/dist/gsapWriterAcorn.js +156 -19
- package/dist/gsapWriterAcorn.js.map +1 -1
- package/dist/index.d.ts +61 -1
- package/dist/index.js +349 -20
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/gsapWriterAcorn.js
CHANGED
|
@@ -169,6 +169,49 @@ var SCOPE_NODE_TYPES = /* @__PURE__ */ new Set([
|
|
|
169
169
|
"FunctionExpression",
|
|
170
170
|
"ArrowFunctionExpression"
|
|
171
171
|
]);
|
|
172
|
+
var CONST_NODES = /* @__PURE__ */ Symbol("hf.constNodes");
|
|
173
|
+
function constNodesOf(scope) {
|
|
174
|
+
return scope[CONST_NODES];
|
|
175
|
+
}
|
|
176
|
+
var MATH_FNS = /* @__PURE__ */ new Set(["min", "max", "round", "floor", "ceil", "abs", "sqrt", "sign", "trunc"]);
|
|
177
|
+
var MATH_CONSTS = { PI: Math.PI, E: Math.E, SQRT2: Math.SQRT2 };
|
|
178
|
+
function resolveMemberNode(node, scope) {
|
|
179
|
+
if (node.object?.type === "Identifier" && node.object.name === "Math") {
|
|
180
|
+
const key = node.property?.name;
|
|
181
|
+
return typeof key === "string" ? MATH_CONSTS[key] : void 0;
|
|
182
|
+
}
|
|
183
|
+
const objNode = resolveConstNode(node.object, scope);
|
|
184
|
+
if (!objNode) return void 0;
|
|
185
|
+
let valueNode;
|
|
186
|
+
if (node.computed) {
|
|
187
|
+
const idx = resolveNode(node.property, scope);
|
|
188
|
+
if (objNode.type === "ArrayExpression" && typeof idx === "number") {
|
|
189
|
+
valueNode = objNode.elements?.[idx];
|
|
190
|
+
} else if (objNode.type === "ObjectExpression" && (typeof idx === "string" || typeof idx === "number")) {
|
|
191
|
+
valueNode = findPropertyNode(objNode, String(idx));
|
|
192
|
+
}
|
|
193
|
+
} else if (objNode.type === "ObjectExpression") {
|
|
194
|
+
valueNode = findPropertyNode(objNode, node.property?.name ?? node.property?.value);
|
|
195
|
+
}
|
|
196
|
+
return valueNode ? resolveNode(valueNode, scope) : void 0;
|
|
197
|
+
}
|
|
198
|
+
function resolveConstMember(objNode, node, scope) {
|
|
199
|
+
if (!node.computed) {
|
|
200
|
+
return objNode.type === "ObjectExpression" ? findPropertyNode(objNode, node.property?.name ?? node.property?.value) : void 0;
|
|
201
|
+
}
|
|
202
|
+
const idx = resolveNode(node.property, scope);
|
|
203
|
+
if (objNode.type === "ArrayExpression" && typeof idx === "number") return objNode.elements?.[idx];
|
|
204
|
+
if (objNode.type === "ObjectExpression") return findPropertyNode(objNode, String(idx));
|
|
205
|
+
return void 0;
|
|
206
|
+
}
|
|
207
|
+
function resolveConstNode(node, scope) {
|
|
208
|
+
if (!node) return void 0;
|
|
209
|
+
if (node.type === "ArrayExpression" || node.type === "ObjectExpression") return node;
|
|
210
|
+
if (node.type === "Identifier") return constNodesOf(scope)?.get(node.name);
|
|
211
|
+
if (node.type !== "MemberExpression") return void 0;
|
|
212
|
+
const objNode = resolveConstNode(node.object, scope);
|
|
213
|
+
return objNode ? resolveConstMember(objNode, node, scope) : void 0;
|
|
214
|
+
}
|
|
172
215
|
function resolveNode(node, scope) {
|
|
173
216
|
if (!node) return void 0;
|
|
174
217
|
if (node.type === "NumericLiteral" || node.type === "Literal" && typeof node.value === "number")
|
|
@@ -205,6 +248,15 @@ function resolveNode(node, scope) {
|
|
|
205
248
|
if (node.type === "TemplateLiteral" && node.expressions?.length === 0) {
|
|
206
249
|
return node.quasis?.[0]?.value?.cooked ?? void 0;
|
|
207
250
|
}
|
|
251
|
+
if (node.type === "MemberExpression") {
|
|
252
|
+
return resolveMemberNode(node, scope);
|
|
253
|
+
}
|
|
254
|
+
if (node.type === "CallExpression" && node.callee?.type === "MemberExpression" && node.callee.object?.type === "Identifier" && node.callee.object.name === "Math" && MATH_FNS.has(node.callee.property?.name)) {
|
|
255
|
+
const args = (node.arguments ?? []).map((a) => resolveNode(a, scope));
|
|
256
|
+
if (args.every((a) => typeof a === "number")) {
|
|
257
|
+
return Math[node.callee.property.name](...args);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
208
260
|
return void 0;
|
|
209
261
|
}
|
|
210
262
|
function extractLiteralValue(node, scope) {
|
|
@@ -262,14 +314,19 @@ function resolveCollectionSelector(node, ancestors, scope, bindings) {
|
|
|
262
314
|
}
|
|
263
315
|
function collectScopeBindings(ast) {
|
|
264
316
|
const bindings = /* @__PURE__ */ new Map();
|
|
317
|
+
const constNodes = /* @__PURE__ */ new Map();
|
|
318
|
+
Object.defineProperty(bindings, CONST_NODES, { value: constNodes, enumerable: false });
|
|
265
319
|
acornWalk.simple(ast, {
|
|
266
320
|
VariableDeclarator(node) {
|
|
267
321
|
const name = node.id?.name;
|
|
268
322
|
const init = node.init;
|
|
269
|
-
if (name
|
|
270
|
-
|
|
271
|
-
|
|
323
|
+
if (!name || !init) return;
|
|
324
|
+
if (init.type === "ArrayExpression" || init.type === "ObjectExpression") {
|
|
325
|
+
constNodes.set(name, init);
|
|
326
|
+
return;
|
|
272
327
|
}
|
|
328
|
+
const val = resolveNode(init, bindings);
|
|
329
|
+
if (val !== void 0) bindings.set(name, val);
|
|
273
330
|
}
|
|
274
331
|
});
|
|
275
332
|
return bindings;
|
|
@@ -311,6 +368,25 @@ function collectTargetBindings(ast, scope) {
|
|
|
311
368
|
}
|
|
312
369
|
}
|
|
313
370
|
});
|
|
371
|
+
const COLLECTION_ALIAS_METHODS = /* @__PURE__ */ new Set(["slice", "filter", "concat", "reverse"]);
|
|
372
|
+
acornWalk.ancestor(ast, {
|
|
373
|
+
// fallow-ignore-next-line complexity
|
|
374
|
+
VariableDeclarator(node, _, ancestors) {
|
|
375
|
+
const name = node.id?.name;
|
|
376
|
+
const init = node.init;
|
|
377
|
+
if (!name || !init) return;
|
|
378
|
+
let sourceVar;
|
|
379
|
+
if (init.type === "MemberExpression" && init.object?.type === "Identifier") {
|
|
380
|
+
sourceVar = init.object.name;
|
|
381
|
+
} else if (init.type === "CallExpression" && init.callee?.type === "MemberExpression" && init.callee.object?.type === "Identifier" && init.callee.property?.type === "Identifier" && COLLECTION_ALIAS_METHODS.has(init.callee.property.name)) {
|
|
382
|
+
sourceVar = init.callee.object.name;
|
|
383
|
+
}
|
|
384
|
+
if (!sourceVar) return;
|
|
385
|
+
const selector = lookupBindingFromAncestors(sourceVar, ancestors, bindings);
|
|
386
|
+
if (selector)
|
|
387
|
+
addBinding(bindings, enclosingScopeNodeFromAncestors(ancestors), name, selector);
|
|
388
|
+
}
|
|
389
|
+
});
|
|
314
390
|
return bindings;
|
|
315
391
|
}
|
|
316
392
|
function resolveTargetSelector(node, ancestors, scope, bindings) {
|
|
@@ -333,6 +409,32 @@ function resolveTargetSelector(node, ancestors, scope, bindings) {
|
|
|
333
409
|
}
|
|
334
410
|
return null;
|
|
335
411
|
}
|
|
412
|
+
function describeProxyTarget(targetNode, varsNode, scope) {
|
|
413
|
+
const objNode = targetNode?.type === "ObjectExpression" ? targetNode : targetNode?.type === "Identifier" ? resolveConstNode(targetNode, scope) : void 0;
|
|
414
|
+
if (objNode?.type !== "ObjectExpression") return null;
|
|
415
|
+
const onUpdate = findPropertyNode(varsNode, "onUpdate");
|
|
416
|
+
const driven = onUpdate ? drivenDomChannel(onUpdate) : void 0;
|
|
417
|
+
if (driven) return `proxy \u2192 ${driven}`;
|
|
418
|
+
return "dwell/hold";
|
|
419
|
+
}
|
|
420
|
+
function isStyleAssignmentTarget(left) {
|
|
421
|
+
return left?.type === "MemberExpression" && left.object?.type === "MemberExpression" && left.object.property?.name === "style" && !!left.property?.name;
|
|
422
|
+
}
|
|
423
|
+
function drivenDomChannel(fnNode) {
|
|
424
|
+
let found;
|
|
425
|
+
acornWalk.simple(fnNode, {
|
|
426
|
+
CallExpression(node) {
|
|
427
|
+
if (node.callee?.type === "MemberExpression" && node.callee.property?.name === "setAttribute" && typeof node.arguments?.[0]?.value === "string") {
|
|
428
|
+
found ??= node.arguments[0].value;
|
|
429
|
+
}
|
|
430
|
+
},
|
|
431
|
+
AssignmentExpression(node) {
|
|
432
|
+
const left = node.left;
|
|
433
|
+
if (isStyleAssignmentTarget(left)) found ??= `style.${left.property.name}`;
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
return found;
|
|
437
|
+
}
|
|
336
438
|
function isObjectProperty(prop) {
|
|
337
439
|
return prop?.type === "ObjectProperty" || prop?.type === "Property";
|
|
338
440
|
}
|
|
@@ -798,8 +900,13 @@ function tweenCallToAnimation(call, scope, source) {
|
|
|
798
900
|
if (duration === void 0 && keyframesData) {
|
|
799
901
|
duration = computeKeyframesTotalDuration(call.varsArg, scope, source);
|
|
800
902
|
}
|
|
903
|
+
let selector = call.selector;
|
|
904
|
+
if (selector === "__unresolved__") {
|
|
905
|
+
const proxyLabel = describeProxyTarget(call.node.arguments?.[0], call.varsArg, scope);
|
|
906
|
+
if (proxyLabel) selector = proxyLabel;
|
|
907
|
+
}
|
|
801
908
|
const anim = {
|
|
802
|
-
targetSelector:
|
|
909
|
+
targetSelector: selector,
|
|
803
910
|
method: call.method,
|
|
804
911
|
position,
|
|
805
912
|
properties,
|
|
@@ -822,7 +929,7 @@ function tweenCallToAnimation(call, scope, source) {
|
|
|
822
929
|
if (keyframesData) anim.keyframes = keyframesData;
|
|
823
930
|
if (motionPathResult) anim.arcPath = motionPathResult.arcPath;
|
|
824
931
|
if (hasUnresolvedKeyframes) anim.hasUnresolvedKeyframes = true;
|
|
825
|
-
if (
|
|
932
|
+
if (selector === "__unresolved__") anim.hasUnresolvedSelector = true;
|
|
826
933
|
const provenance = readProvenance(call.node);
|
|
827
934
|
if (provenance) anim.provenance = provenance;
|
|
828
935
|
return anim;
|
|
@@ -864,31 +971,61 @@ function applyTimelineDefaults(anims, defaults) {
|
|
|
864
971
|
}
|
|
865
972
|
}
|
|
866
973
|
}
|
|
867
|
-
function
|
|
974
|
+
function resolveLabelPosition(pos, labels, cursor) {
|
|
975
|
+
const m = /^([A-Za-z_$][\w$]*)\s*(?:([+-])=\s*([\d.]+))?$/.exec(pos.trim());
|
|
976
|
+
if (!m) return null;
|
|
977
|
+
const name = m[1];
|
|
978
|
+
let base = labels.get(name);
|
|
979
|
+
if (base === void 0) {
|
|
980
|
+
base = cursor;
|
|
981
|
+
labels.set(name, base);
|
|
982
|
+
}
|
|
983
|
+
if (m[2] && m[3]) {
|
|
984
|
+
const n = Number.parseFloat(m[3]);
|
|
985
|
+
if (Number.isFinite(n)) return m[2] === "+" ? base + n : base - n;
|
|
986
|
+
}
|
|
987
|
+
return base;
|
|
988
|
+
}
|
|
989
|
+
function resolveAnimStart(anim, cursor, prevStart, labels) {
|
|
990
|
+
if (anim.implicitPosition) return cursor;
|
|
991
|
+
if (typeof anim.position === "number") return anim.position;
|
|
992
|
+
if (typeof anim.position === "string") {
|
|
993
|
+
return resolveLabelPosition(anim.position, labels, cursor) ?? resolvePositionString(anim.position, cursor, prevStart);
|
|
994
|
+
}
|
|
995
|
+
return cursor;
|
|
996
|
+
}
|
|
997
|
+
function resolveTimelinePositions(anims, labelDefs = []) {
|
|
868
998
|
let cursor = 0;
|
|
869
999
|
let prevStart = 0;
|
|
870
|
-
|
|
1000
|
+
const labels = /* @__PURE__ */ new Map();
|
|
1001
|
+
let labelIdx = 0;
|
|
1002
|
+
const sortedLabels = [...labelDefs].sort((a, b) => a.order - b.order);
|
|
1003
|
+
const defineLabel = (def) => {
|
|
1004
|
+
let value;
|
|
1005
|
+
if (typeof def.position === "number") value = def.position;
|
|
1006
|
+
else if (typeof def.position === "string") {
|
|
1007
|
+
value = resolveLabelPosition(def.position, labels, cursor) ?? cursor;
|
|
1008
|
+
} else value = cursor;
|
|
1009
|
+
labels.set(def.name, Math.max(0, value));
|
|
1010
|
+
};
|
|
1011
|
+
anims.forEach((anim, i) => {
|
|
1012
|
+
while (labelIdx < sortedLabels.length && sortedLabels[labelIdx].order <= i) {
|
|
1013
|
+
defineLabel(sortedLabels[labelIdx]);
|
|
1014
|
+
labelIdx++;
|
|
1015
|
+
}
|
|
871
1016
|
if (anim.method === "set" && anim.global) {
|
|
872
1017
|
anim.resolvedStart = 0;
|
|
873
|
-
|
|
1018
|
+
return;
|
|
874
1019
|
}
|
|
875
1020
|
const duration = anim.method === "set" ? 0 : anim.duration ?? GSAP_DEFAULT_DURATION;
|
|
876
|
-
|
|
877
|
-
if (anim.implicitPosition) {
|
|
878
|
-
start = cursor;
|
|
879
|
-
} else if (typeof anim.position === "number") {
|
|
880
|
-
start = anim.position;
|
|
881
|
-
} else if (typeof anim.position === "string") {
|
|
882
|
-
start = resolvePositionString(anim.position, cursor, prevStart);
|
|
883
|
-
} else {
|
|
884
|
-
start = cursor;
|
|
885
|
-
}
|
|
1021
|
+
const start = resolveAnimStart(anim, cursor, prevStart, labels);
|
|
886
1022
|
if (start != null) {
|
|
887
1023
|
anim.resolvedStart = Math.max(0, start);
|
|
888
1024
|
prevStart = anim.resolvedStart;
|
|
889
1025
|
cursor = Math.max(cursor, anim.resolvedStart + duration);
|
|
890
1026
|
}
|
|
891
|
-
}
|
|
1027
|
+
});
|
|
1028
|
+
while (labelIdx < sortedLabels.length) defineLabel(sortedLabels[labelIdx++]);
|
|
892
1029
|
}
|
|
893
1030
|
function compareByLoc(a, b) {
|
|
894
1031
|
const aLoc = a.node.callee?.property?.loc?.start;
|