MCPcopy
hub / github.com/angular/angular / runEnterAnimation

Function runEnterAnimation

packages/core/src/render3/instructions/animation.ts:94–166  ·  view source on GitHub ↗
(
  lView: LView,
  tNode: TNode,
  value: string | AnimationClassBindingFn,
  ngZone: NgZone,
)

Source from the content-addressed store, hash-verified

92}
93
94export function runEnterAnimation(
95 lView: LView,
96 tNode: TNode,
97 value: string | AnimationClassBindingFn,
98 ngZone: NgZone,
99): void {
100 const nativeElement = getNativeByTNode(tNode, lView) as HTMLElement;
101
102 ngDevMode && assertElementNodes(nativeElement, 'animate.enter');
103
104 const renderer = lView[RENDERER];
105
106 // Retrieve the actual class list from the value. This will resolve any resolver functions from
107 // bindings.
108 const activeClasses = getClassListFromValue(value);
109 const cleanupFns: VoidFunction[] = [];
110 let hasCompleted = false;
111
112 // In the case where multiple animations are happening on the element, we need
113 // to get the longest animation to ensure we don't complete animations early.
114 // This also allows us to setup cancellation of animations in progress if the
115 // gets removed early.
116 const handleEnterAnimationStart = (event: AnimationEvent | TransitionEvent) => {
117 // this early exit case is to prevent issues with bubbling events that are from child element animations
118 if (getEventTarget(event) !== nativeElement) return;
119
120 const eventName = event instanceof AnimationEvent ? 'animationend' : 'transitionend';
121 ngZone.runOutsideAngular(() => {
122 renderer.listen(nativeElement, eventName, handleEnterAnimationEnd);
123 });
124 };
125
126 // When the longest animation ends, we can remove all the classes
127 const handleEnterAnimationEnd = (event: AnimationEvent | TransitionEvent) => {
128 // this early exit case is to prevent issues with bubbling events that are from child element animations
129 if (getEventTarget(event) !== nativeElement) return;
130
131 if (isLongestAnimation(event, nativeElement)) {
132 hasCompleted = true;
133 }
134 enterAnimationEnd(event, nativeElement, renderer);
135 };
136
137 // We only need to add these event listeners if there are actual classes to apply
138 if (activeClasses && activeClasses.length > 0) {
139 ngZone.runOutsideAngular(() => {
140 cleanupFns.push(renderer.listen(nativeElement, 'animationstart', handleEnterAnimationStart));
141 cleanupFns.push(renderer.listen(nativeElement, 'transitionstart', handleEnterAnimationStart));
142 });
143
144 trackEnterClasses(nativeElement, activeClasses, cleanupFns);
145
146 for (const klass of activeClasses) {
147 renderer.addClass(nativeElement, klass);
148 }
149
150 // In the case that the classes added have no animations, we need to remove
151 // the classes right away. This could happen because someone is intentionally

Callers 1

ɵɵanimateEnterFunction · 0.85

Calls 12

getNativeByTNodeFunction · 0.90
assertElementNodesFunction · 0.90
getClassListFromValueFunction · 0.90
trackEnterClassesFunction · 0.90
cleanupEnterClassDataFunction · 0.90
listenMethod · 0.65
addClassMethod · 0.65
hasMethod · 0.65
removeClassMethod · 0.65
runOutsideAngularMethod · 0.45
pushMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…