(parsed: ParsedDocument, ids: HfId[])
| 591 | } |
| 592 | |
| 593 | function handleRemoveElement(parsed: ParsedDocument, ids: HfId[]): MutationResult { |
| 594 | const result: MutationResult = { forward: [], inverse: [] }; |
| 595 | const origScript = getGsapScript(parsed.document); |
| 596 | let currentScript = origScript; |
| 597 | |
| 598 | for (const id of ids) { |
| 599 | const el = resolveScoped(parsed.document, id); |
| 600 | if (!el) continue; |
| 601 | const parentEl = el.parentElement; |
| 602 | const parentId = parentEl?.getAttribute("data-hf-id") ?? null; |
| 603 | const siblingIndex = getSiblingIndex(el); |
| 604 | const html = el.outerHTML; |
| 605 | |
| 606 | // Collect all bare hf-ids in the subtree BEFORE removal so GSAP cascade |
| 607 | // removes animations targeting any sub-composition element, not just the host. |
| 608 | const subtreeIds = collectSubtreeHfIds(el); |
| 609 | |
| 610 | el.remove(); |
| 611 | |
| 612 | const path = elementPath(id); |
| 613 | result.forward.push(patchRemove(path)); |
| 614 | result.inverse.push(patchAdd(path, { html, parentId, siblingIndex })); |
| 615 | |
| 616 | if (currentScript) { |
| 617 | for (const subtreeId of subtreeIds) { |
| 618 | currentScript = cascadeRemoveAnimations(currentScript, subtreeId); |
| 619 | } |
| 620 | } |
| 621 | } |
| 622 | |
| 623 | if (origScript && currentScript && currentScript !== origScript) { |
| 624 | setGsapScript(parsed.document, currentScript); |
| 625 | const gsapResult = gsapScriptChange(origScript, currentScript); |
| 626 | result.forward.push(...gsapResult.forward); |
| 627 | result.inverse.push(...gsapResult.inverse); |
| 628 | } |
| 629 | |
| 630 | return result; |
| 631 | } |
| 632 | |
| 633 | // ─── addElement handler ─────────────────────────────────────────────────────── |
| 634 |
no test coverage detected