Skip to content

Commit 802dbcc

Browse files
thePunderWomanatscott
authored andcommitted
fix(core): prevent animation events from being cleaned up on destroy (#63414)
This will allow manually subscribed animation events to still fire when using `animate.leave`. Otherwise they were being cleaned up before the animations happened. fixes: #63391 PR Close #63414
1 parent 9096d45 commit 802dbcc

File tree

5 files changed

+34
-14
lines changed

5 files changed

+34
-14
lines changed

packages/core/src/render3/view/listeners.ts

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -163,23 +163,33 @@ export function listenToDomEvent(
163163
stashEventListenerImpl(lView, target, eventName, wrappedListener);
164164

165165
const cleanupFn = renderer.listen(target as RElement, eventName, wrappedListener);
166-
const idxOrTargetGetter = eventTargetResolver
167-
? (_lView: LView) => eventTargetResolver(unwrapRNode(_lView[tNode.index]))
168-
: tNode.index;
169-
170-
storeListenerCleanup(
171-
idxOrTargetGetter,
172-
tView,
173-
lView,
174-
eventName,
175-
wrappedListener,
176-
cleanupFn,
177-
false,
178-
);
166+
167+
// We skip cleaning up animation event types to ensure leaving animation events can be used.
168+
// These events should be automatically garbage collected anyway after the element is
169+
// removed from the DOM.
170+
if (!isAnimationEventType(eventName)) {
171+
const idxOrTargetGetter = eventTargetResolver
172+
? (_lView: LView) => eventTargetResolver(unwrapRNode(_lView[tNode.index]))
173+
: tNode.index;
174+
175+
storeListenerCleanup(
176+
idxOrTargetGetter,
177+
tView,
178+
lView,
179+
eventName,
180+
wrappedListener,
181+
cleanupFn,
182+
false,
183+
);
184+
}
179185
}
180186
return hasCoalesced;
181187
}
182188

189+
function isAnimationEventType(eventName: string): boolean {
190+
return eventName.startsWith('animation') || eventName.startsWith('transition');
191+
}
192+
183193
/**
184194
* A utility function that checks if a given element has already an event handler registered for an
185195
* event with a specified name. The TView.cleanup data structure is used to find out which events

packages/core/test/acceptance/animation_spec.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,20 @@ describe('Animation', () => {
4747
`;
4848

4949
it('should delay element removal when an animation is specified', fakeAsync(() => {
50+
const logSpy = jasmine.createSpy('logSpy');
5051
@Component({
5152
selector: 'test-cmp',
5253
styles: styles,
53-
template: '<div>@if (show()) {<p animate.leave="fade">I should fade</p>}</div>',
54+
template:
55+
'<div>@if (show()) {<p animate.leave="fade" (animationend)="logMe($event)">I should fade</p>}</div>',
5456
encapsulation: ViewEncapsulation.None,
5557
})
5658
class TestComponent {
5759
show = signal(true);
60+
61+
logMe(event: AnimationEvent) {
62+
logSpy();
63+
}
5864
}
5965

6066
TestBed.configureTestingModule({animationsEnabled: true});
@@ -76,6 +82,7 @@ describe('Animation', () => {
7682
new AnimationEvent('animationend', {animationName: 'fade-out'}),
7783
);
7884
expect(fixture.nativeElement.outerHTML).not.toContain('class="fade"');
85+
expect(logSpy).toHaveBeenCalled();
7986
}));
8087

8188
it('should remove right away when animations are disabled', fakeAsync(() => {

packages/core/test/bundling/forms_reactive/bundle.golden_symbols.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,7 @@
696696
"invokeHostBindingsInCreationMode",
697697
"isAbstractControlOptions",
698698
"isAngularZoneProperty",
699+
"isAnimationEventType",
699700
"isAnimationProp",
700701
"isApplicationBootstrapConfig",
701702
"isArrayLike",

packages/core/test/bundling/forms_template_driven/bundle.golden_symbols.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,7 @@
697697
"invokeDirectivesHostBindings",
698698
"invokeHostBindingsInCreationMode",
699699
"isAngularZoneProperty",
700+
"isAnimationEventType",
700701
"isAnimationProp",
701702
"isApplicationBootstrapConfig",
702703
"isArrayLike",

packages/core/test/bundling/router/bundle.golden_symbols.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,7 @@
791791
"invokeHostBindingsInCreationMode",
792792
"isActiveMatchOptions",
793793
"isAngularZoneProperty",
794+
"isAnimationEventType",
794795
"isAnimationProp",
795796
"isApplicationBootstrapConfig",
796797
"isArrayLike",

0 commit comments

Comments
 (0)