(
parsed: ParsedDocument,
op: Extract<EditOp, { type: "replaceWithKeyframes" }>,
)
| 931 | } |
| 932 | |
| 933 | function handleReplaceWithKeyframes( |
| 934 | parsed: ParsedDocument, |
| 935 | op: Extract<EditOp, { type: "replaceWithKeyframes" }>, |
| 936 | ): MutationResult { |
| 937 | const script = getGsapScript(parsed.document); |
| 938 | if (!script) throw new Error("No GSAP script block found in the composition."); |
| 939 | if (op.keyframes.length === 0) return EMPTY; |
| 940 | // #11: tween IDs are position-derived and re-point after any structural edit, |
| 941 | // so a stale `animationId` can resolve to a DIFFERENT tween. Require the |
| 942 | // located animation to still target the selector the caller expects; if it is |
| 943 | // absent or now points at another element, bail rather than silently replace |
| 944 | // the wrong tween. (validateOp's gsapAnimationMissing only catches absent ids.) |
| 945 | const located = locateGsapAnimation(parsed, op.animationId); |
| 946 | if (!located || located.animation.targetSelector !== op.targetSelector) return EMPTY; |
| 947 | // Step 1: remove the existing tween. Position-derived IDs renumber, so the |
| 948 | // inverse patch restores the full GSAP script rather than trying to re-insert |
| 949 | // by ID (handled by the coarse gsapScriptChange patch pair). |
| 950 | const afterRemove = removeAnimationFromScript(script, op.animationId); |
| 951 | // Defense in depth: if the id resolved to nothing the script is unchanged — |
| 952 | // bail rather than degrade the replace into a plain add (duplicate tween). |
| 953 | if (afterRemove === script) return EMPTY; |
| 954 | // Step 2: insert the replacement keyframed tween. |
| 955 | const { script: newScript, id: animationId } = addAnimationWithKeyframesToScript( |
| 956 | afterRemove, |
| 957 | op.targetSelector, |
| 958 | op.position, |
| 959 | op.duration, |
| 960 | op.keyframes, |
| 961 | op.ease, |
| 962 | ); |
| 963 | if (!animationId) return EMPTY; |
| 964 | setGsapScript(parsed.document, newScript); |
| 965 | return { ...gsapScriptChange(script, newScript), meta: { animationId } }; |
| 966 | } |
| 967 | |
| 968 | // ─── setClassStyle handler ──────────────────────────────────────────────────── |
| 969 |
no test coverage detected