Skip to content

Commit abbd879

Browse files
thePunderWomanmattrbeck
authored andcommitted
fix(core): reverts "feat(core): add support for nested animations"
This reverts commit ea2016a. This reverts the support for nested animations due to the global scope of how nested animations were gathered. This caused issues where on route navigations, all child nodes with animations would be queued and run before the navigation would occur. We'll be revisiting the nested animations with a more tightened scope of when those leave animations will occur. fixes: #67552 (cherry picked from commit 999c14e)
1 parent c06e3a0 commit abbd879

File tree

13 files changed

+72
-724
lines changed

13 files changed

+72
-724
lines changed

packages/core/src/animation/queue.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,11 @@ export const ANIMATION_QUEUE = new InjectionToken<AnimationQueue>(
2424
typeof ngDevMode !== 'undefined' && ngDevMode ? 'AnimationQueue' : '',
2525
{
2626
factory: () => {
27-
const injector = inject(EnvironmentInjector);
28-
const queue = new Set<VoidFunction>();
29-
injector.onDestroy(() => queue.clear());
3027
return {
31-
queue,
28+
queue: new Set(),
3229
isScheduled: false,
3330
scheduler: null,
34-
injector,
31+
injector: inject(EnvironmentInjector), // should be the root injector
3532
};
3633
},
3734
},

packages/core/src/render3/node_animations.ts

Lines changed: 0 additions & 254 deletions
This file was deleted.

packages/core/src/render3/node_manipulation.ts

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,10 @@ import {profiler} from './profiler';
8383
import {ProfilerEvent} from '../../primitives/devtools';
8484
import {getLViewParent, getNativeByTNode, unwrapRNode} from './util/view_utils';
8585
import {cancelLeavingNodes, reusedNodes, trackLeavingNodes} from '../animation/utils';
86+
import {allLeavingAnimations} from '../animation/longest_animation';
8687
import {Injector} from '../di';
87-
import {maybeQueueEnterAnimation, runLeaveAnimationsWithCallback} from './node_animations';
88+
import {addToAnimationQueue, queueEnterAnimations} from '../animation/queue';
89+
import {RunLeaveAnimationFn} from '../animation/interfaces';
8890

8991
const enum WalkTNodeTreeAction {
9092
/** node create in the native environment. Run on initial creation. */
@@ -103,6 +105,18 @@ const enum WalkTNodeTreeAction {
103105
Destroy = 3,
104106
}
105107

108+
function maybeQueueEnterAnimation(
109+
parentLView: LView | undefined,
110+
parent: RElement | null,
111+
tNode: TNode,
112+
injector: Injector,
113+
): void {
114+
const enterAnimations = parentLView?.[ANIMATIONS]?.enter;
115+
if (parent !== null && enterAnimations && enterAnimations.has(tNode.index)) {
116+
queueEnterAnimations(injector, enterAnimations);
117+
}
118+
}
119+
106120
/**
107121
* NOTE: for performance reasons, the possible actions are inlined within the function instead of
108122
* being passed as an argument.
@@ -373,6 +387,61 @@ function cleanUpView(tView: TView, lView: LView): void {
373387
}
374388
}
375389

390+
function runLeaveAnimationsWithCallback(
391+
lView: LView | undefined,
392+
tNode: TNode,
393+
injector: Injector,
394+
callback: Function,
395+
) {
396+
const animations = lView?.[ANIMATIONS];
397+
398+
if (animations == null || animations.leave == undefined || !animations.leave.has(tNode.index))
399+
return callback(false);
400+
401+
if (lView) allLeavingAnimations.add(lView[ID]);
402+
403+
addToAnimationQueue(
404+
injector,
405+
() => {
406+
// it's possible that in the time between when the leave animation was
407+
// and the time it was executed, the data structure changed. So we need
408+
// to be safe here.
409+
if (animations.leave && animations.leave.has(tNode.index)) {
410+
const leaveAnimationMap = animations.leave;
411+
const leaveAnimations = leaveAnimationMap.get(tNode.index);
412+
const runningAnimations = [];
413+
if (leaveAnimations) {
414+
for (let index = 0; index < leaveAnimations.animateFns.length; index++) {
415+
const animationFn = leaveAnimations.animateFns[index];
416+
const {promise} = animationFn() as ReturnType<RunLeaveAnimationFn>;
417+
runningAnimations.push(promise);
418+
}
419+
animations.detachedLeaveAnimationFns = undefined;
420+
}
421+
animations.running = Promise.allSettled(runningAnimations);
422+
runAfterLeaveAnimations(lView!, callback);
423+
} else {
424+
if (lView) allLeavingAnimations.delete(lView[ID]);
425+
callback(false);
426+
}
427+
},
428+
animations,
429+
);
430+
}
431+
432+
function runAfterLeaveAnimations(lView: LView, callback: Function) {
433+
const runningAnimations = lView[ANIMATIONS]?.running;
434+
if (runningAnimations) {
435+
runningAnimations.then(() => {
436+
lView[ANIMATIONS]!.running = undefined;
437+
allLeavingAnimations.delete(lView[ID]);
438+
callback(true);
439+
});
440+
return;
441+
}
442+
callback(false);
443+
}
444+
376445
/** Removes listeners and unsubscribes from output subscriptions */
377446
function processCleanups(tView: TView, lView: LView): void {
378447
ngDevMode && assertNotReactive(processCleanups.name);

0 commit comments

Comments
 (0)