@hyperframes/parsers 0.8.127 → 0.8.128

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.
@@ -3,6 +3,7 @@ import * as recast from "recast";
3
3
  import { parse as babelParse } from "@babel/parser";
4
4
 
5
5
  // src/gsapConstants.ts
6
+ var GSAP_DEFAULT_DURATION = 0.5;
6
7
  var SUPPORTED_PROPS = [
7
8
  // 2D Transforms
8
9
  "x",
@@ -101,16 +102,14 @@ function positionHoldForAnimation(animation, animations) {
101
102
  if (!animation.keyframes) return null;
102
103
  const start = knownStart(animation) ?? 0;
103
104
  if (!(start > 1e-3)) return null;
104
- const first = [...animation.keyframes.keyframes].sort(
105
- (left, right) => left.percentage - right.percentage
106
- )[0];
107
- if (!first) return null;
105
+ const atStart = animation.keyframes.keyframes.find((keyframe) => keyframe.percentage === 0);
106
+ if (!atStart) return null;
108
107
  const earlier = animations.filter((other) => {
109
108
  const otherStart = knownStart(other);
110
109
  return other !== animation && !other.global && other.targetSelector === animation.targetSelector && otherStart !== void 0 && otherStart < start - 1e-3;
111
110
  });
112
111
  const position = {};
113
- for (const [property, value] of Object.entries(first.properties)) {
112
+ for (const [property, value] of Object.entries(atStart.properties)) {
114
113
  if (classifyPropertyGroup(property) !== "position" || typeof value !== "number") continue;
115
114
  if (earlier.some((other) => writesProperty(other, property))) continue;
116
115
  position[property] = value;
@@ -156,6 +155,9 @@ var SUPPORTED_EASES = [
156
155
  ];
157
156
 
158
157
  // src/gsapSerialize.ts
158
+ function authorsKeyframes(anim) {
159
+ return anim.keyframes !== void 0 || anim.hasUnresolvedKeyframes === true;
160
+ }
159
161
  function mergePercentageKeyframes(keyframes) {
160
162
  const byPercentage = /* @__PURE__ */ new Map();
161
163
  for (const keyframe of keyframes) {
@@ -401,14 +403,25 @@ function resolveConversionProps(anim, resolvedFromValues) {
401
403
  }
402
404
 
403
405
  // src/clipTweens.ts
404
- function clipTweenMatcher(clipSelectors, root) {
406
+ function clipTweenMatcher(clipSelectors, root, queries = /* @__PURE__ */ new Map()) {
405
407
  const own = typeof clipSelectors === "string" ? [clipSelectors] : clipSelectors;
406
- const clips = root ? own.flatMap((selector) => queryAll(root, selector)) : [];
408
+ if (!root)
409
+ return ({ targetSelector, hasPartialSelector }) => !hasPartialSelector && own.includes(targetSelector);
410
+ const queryAll = (selector) => {
411
+ if (ID_SELECTOR.test(selector)) {
412
+ if (!queries.has(ALL_IDS)) indexIds(root, queries);
413
+ return queries.get(selector) ?? [];
414
+ }
415
+ let found = queries.get(selector);
416
+ if (!found) queries.set(selector, found = queryRoot(root, selector));
417
+ return found;
418
+ };
419
+ const clips = own.flatMap((selector) => queryAll(selector));
407
420
  return ({ targetSelector, hasPartialSelector }) => {
408
421
  if (hasPartialSelector) return false;
409
422
  if (own.includes(targetSelector)) return true;
410
- if (!root || clips.length === 0) return false;
411
- const targets = queryAll(root, targetSelector);
423
+ if (clips.length === 0) return false;
424
+ const targets = queryAll(targetSelector);
412
425
  return targets.length > 0 && targets.every((target) => {
413
426
  const owner = target.closest("[data-start]");
414
427
  return clips.includes(target) || owner !== null && clips.includes(owner);
@@ -418,7 +431,20 @@ function clipTweenMatcher(clipSelectors, root) {
418
431
  function hasExplicitTime(animation) {
419
432
  return typeof animation.position === "number" && !animation.implicitPosition;
420
433
  }
421
- function queryAll(root, selector) {
434
+ var ID_SELECTOR = /^#-?[A-Za-z_][\w-]*$/;
435
+ var ALL_IDS = "[id]";
436
+ function indexIds(root, queries) {
437
+ const all = queryRoot(root, ALL_IDS);
438
+ queries.set(ALL_IDS, all);
439
+ for (const el of all) {
440
+ const key = `#${el.id}`;
441
+ if (!ID_SELECTOR.test(key)) continue;
442
+ const list = queries.get(key);
443
+ if (list) list.push(el);
444
+ else queries.set(key, [el]);
445
+ }
446
+ }
447
+ function queryRoot(root, selector) {
422
448
  try {
423
449
  return Array.from(root.querySelectorAll(selector));
424
450
  } catch {
@@ -430,34 +456,27 @@ function queryAll(root, selector) {
430
456
  var roundPercentage = (percentage) => Math.round(percentage * 10) / 10;
431
457
  var OBJECT_ARRAY_PERCENTAGE_TOLERANCE = 2;
432
458
  function getObjectArrayKeyframeTiming(durations) {
433
- const hasAuthoredDuration = durations.some((duration) => duration !== void 0);
434
- if (hasAuthoredDuration) {
435
- if (!durations.every(
436
- (duration) => typeof duration === "number" && Number.isFinite(duration) && duration > 0
437
- )) {
438
- return null;
439
- }
440
- const totalDuration = durations.reduce((sum, duration) => sum + duration, 0);
441
- let cumulative = 0;
442
- return {
443
- percentages: durations.map((duration) => {
444
- cumulative += duration;
445
- return roundPercentage(cumulative / totalDuration * 100);
446
- }),
447
- totalDuration
448
- };
459
+ const steps = durations.map((duration) => duration ?? GSAP_DEFAULT_DURATION);
460
+ if (!steps.every(
461
+ (duration) => typeof duration === "number" && Number.isFinite(duration) && duration > 0
462
+ )) {
463
+ return null;
449
464
  }
450
- const lastIndex = durations.length - 1;
465
+ const totalDuration = steps.reduce((sum, duration) => sum + duration, 0);
466
+ let cumulative = 0;
451
467
  return {
452
- percentages: durations.map(
453
- (_, index) => lastIndex > 0 ? roundPercentage(index / lastIndex * 100) : 0
454
- )
468
+ percentages: steps.map((duration) => {
469
+ cumulative += duration;
470
+ return roundPercentage(cumulative / totalDuration * 100);
471
+ }),
472
+ totalDuration
455
473
  };
456
474
  }
457
475
  function getCompatibleObjectArrayKeyframeTiming(durations, outerDuration) {
458
476
  const timing = getObjectArrayKeyframeTiming(durations);
459
477
  if (!timing) return null;
460
- if (timing.totalDuration === void 0 || outerDuration === void 0) return timing;
478
+ const stepsAuthorDuration = durations.some((duration) => duration !== void 0);
479
+ if (!stepsAuthorDuration || outerDuration === void 0) return timing;
461
480
  if (typeof outerDuration === "number" && Math.abs(outerDuration - timing.totalDuration) <= Number.EPSILON) {
462
481
  return timing;
463
482
  }
@@ -1201,7 +1220,7 @@ function tweenCallToAnimation(call, scope) {
1201
1220
  percentage: waypoints.length > 1 ? Math.round(i / (waypoints.length - 1) * 100) : 0,
1202
1221
  properties: { x: wp.x, y: wp.y }
1203
1222
  }));
1204
- keyframesData = { format: "percentage", keyframes: kf };
1223
+ keyframesData = { format: "percentage", keyframes: kf, fromMotionPath: true };
1205
1224
  } else {
1206
1225
  const kfs = keyframesData.keyframes;
1207
1226
  if (kfs.length === waypoints.length) {
@@ -1258,7 +1277,6 @@ function tweenCallToAnimation(call, scope) {
1258
1277
  if (call.selectorPartial) anim.hasPartialSelector = true;
1259
1278
  return anim;
1260
1279
  }
1261
- var GSAP_DEFAULT_DURATION = 0.5;
1262
1280
  function resolvePositionString(pos, cursor, prevStart) {
1263
1281
  const trimmed = pos.trim();
1264
1282
  if (trimmed === "") return cursor;
@@ -1290,7 +1308,7 @@ function applyTimelineDefaults(anims, defaults) {
1290
1308
  if (anim.duration === void 0 && defaults.duration !== void 0) {
1291
1309
  anim.duration = defaults.duration;
1292
1310
  }
1293
- if (anim.ease === void 0 && defaults.ease !== void 0) {
1311
+ if (anim.ease === void 0 && defaults.ease !== void 0 && (!anim.keyframes || anim.keyframes.fromMotionPath)) {
1294
1312
  anim.ease = defaults.ease;
1295
1313
  }
1296
1314
  }
@@ -1526,7 +1544,7 @@ function updateAnimationInScript(script, animationId, updates) {
1526
1544
  return script;
1527
1545
  }
1528
1546
  const target = parsed.located.find((l) => l.id === animationId);
1529
- if (!target) return script;
1547
+ if (!target || updates.properties && target.animation.hasUnresolvedKeyframes) return script;
1530
1548
  applyUpdatesToCall(target.call, updates);
1531
1549
  return recast.print(parsed.ast).code;
1532
1550
  }
@@ -1796,12 +1814,12 @@ function splitAnimationsInScript(script, opts) {
1796
1814
  const pos = typeof anim.position === "number" ? anim.position : 0;
1797
1815
  const dur = anim.duration ?? 0;
1798
1816
  const animEnd = pos + dur;
1799
- if (anim.keyframes) {
1817
+ if (authorsKeyframes(anim)) {
1800
1818
  if (pos >= opts.splitTime) {
1801
1819
  result = updateAnimationSelector(result, anim.id, newSelector);
1802
1820
  } else if (animEnd > opts.splitTime) {
1803
1821
  skippedSelectors.push(`${originalSelector} (keyframes spanning split)`);
1804
- const kfs = anim.keyframes.keyframes;
1822
+ const kfs = anim.keyframes?.keyframes ?? [];
1805
1823
  for (const kf of kfs) {
1806
1824
  const kfTime = pos + kf.percentage / 100 * dur;
1807
1825
  if (kfTime <= opts.splitTime) {
@@ -1811,7 +1829,10 @@ function splitAnimationsInScript(script, opts) {
1811
1829
  }
1812
1830
  }
1813
1831
  } else {
1814
- const kfs = anim.keyframes.keyframes;
1832
+ if (anim.hasUnresolvedKeyframes) {
1833
+ skippedSelectors.push(`${originalSelector} (unreadable keyframes before split)`);
1834
+ }
1835
+ const kfs = anim.keyframes?.keyframes ?? [];
1815
1836
  if (kfs.length > 0) {
1816
1837
  for (const [k, v] of Object.entries(kfs[kfs.length - 1].properties)) {
1817
1838
  inheritedProps[k] = v;
@@ -1991,7 +2012,7 @@ function convertArrayKeyframesToObjectNode(varsArg, scope) {
1991
2012
  outerDuration
1992
2013
  );
1993
2014
  if (!timing) return null;
1994
- if (timing.totalDuration !== void 0 && findPropertyNode(varsArg, "duration") === void 0) {
2015
+ if (findPropertyNode(varsArg, "duration") === void 0) {
1995
2016
  setVarsKey(varsArg, "duration", timing.totalDuration);
1996
2017
  }
1997
2018
  const entries = els.map((el, i) => {
@@ -2000,7 +2021,7 @@ function convertArrayKeyframesToObjectNode(varsArg, scope) {
2000
2021
  );
2001
2022
  return `${JSON.stringify(`${timing.percentages[i]}%`)}: ${recast.print(el).code}`;
2002
2023
  });
2003
- prop.value = parseExpr(`{ ${entries.join(", ")} }`);
2024
+ prop.value = parseExpr(`{ ${entries.join(", ")}, easeEach: "none" }`);
2004
2025
  return prop.value;
2005
2026
  }
2006
2027
  function filterPercentageProps(kfNode) {
@@ -2300,7 +2321,7 @@ function convertToKeyframesInScript(script, animationId, resolvedFromValues, set
2300
2321
  let loc = locateAnimationWithFallback(script, animationId);
2301
2322
  if (!loc) return script;
2302
2323
  const anim = loc.target.animation;
2303
- if (anim.keyframes) return script;
2324
+ if (authorsKeyframes(anim)) return script;
2304
2325
  const { fromProps, toProps } = resolveConversionProps(anim, resolvedFromValues);
2305
2326
  const varsArg = loc.target.call.varsArg;
2306
2327
  const originalEase = anim.ease;
@@ -2635,6 +2656,7 @@ function splitIntoPropertyGroups(script, animationId) {
2635
2656
  let loc = locateAnimationWithFallback(script, animationId);
2636
2657
  if (!loc) return { script, ids: [animationId] };
2637
2658
  const anim = loc.target.animation;
2659
+ if (anim.hasUnresolvedKeyframes) return { script, ids: [animationId] };
2638
2660
  const allPropKeys = /* @__PURE__ */ new Set();
2639
2661
  if (anim.keyframes) {
2640
2662
  for (const kf of anim.keyframes.keyframes) {