From 11357ccd46fa7b45eb94f2fbee545391234bfb5c Mon Sep 17 00:00:00 2001 From: Martin Staffa Date: Fri, 11 Dec 2015 12:20:31 +0100 Subject: [PATCH] fix($animateCss): only (de)register listeners when events have been added Previously, when an animation was closed because no animation styles where found, it would call .off() with an empty string as the argument. For both jquery/jqlite this is the same as calling .off() without any argument, which deregisters all event listeners on an element. Closes #13514 --- src/ngAnimate/animateCss.js | 9 ++++++--- test/ngAnimate/animateCssSpec.js | 33 ++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/ngAnimate/animateCss.js b/src/ngAnimate/animateCss.js index 1039db3425df..df2c27a8f9c2 100644 --- a/src/ngAnimate/animateCss.js +++ b/src/ngAnimate/animateCss.js @@ -749,8 +749,8 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) { options.onDone(); } - // Remove the transitionend / animationend listener(s) - if (events) { + if (events && events.length) { + // Remove the transitionend / animationend listener(s) element.off(events.join(' '), onAnimationProgress); } @@ -960,7 +960,10 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) { element.data(ANIMATE_TIMER_KEY, animationsData); } - element.on(events.join(' '), onAnimationProgress); + if (events.length) { + element.on(events.join(' '), onAnimationProgress); + } + if (options.to) { if (options.cleanupStyles) { registerRestorableStyles(restoreStyles, node, Object.keys(options.to)); diff --git a/test/ngAnimate/animateCssSpec.js b/test/ngAnimate/animateCssSpec.js index 4a828ecc372e..131252eca692 100644 --- a/test/ngAnimate/animateCssSpec.js +++ b/test/ngAnimate/animateCssSpec.js @@ -1502,6 +1502,39 @@ describe("ngAnimate $animateCss", function() { expect(elementOffSpy.mostRecentCall.args[0]).toBe(event); }); }); + + they("should not add or remove $prop event listeners when no animation styles are detected", + [TRANSITIONEND_EVENT, ANIMATIONEND_EVENT], function(event) { + inject(function($animateCss, $timeout) { + + progress = event === TRANSITIONEND_EVENT ? transitionProgress : keyframeProgress; + + // Make sure other event listeners are not affected + var otherEndSpy = jasmine.createSpy('otherEndSpy'); + element.on(event, otherEndSpy); + + expect(elementOnSpy).toHaveBeenCalledOnce(); + elementOnSpy.reset(); + + var animator = $animateCss(element, { + event: 'enter', + structural: true + }); + + expect(animator.$$willAnimate).toBeFalsy(); + + // This will close the animation because no styles have been detected + var runner = animator.start(); + triggerAnimationStartFrame(); + + expect(elementOnSpy).not.toHaveBeenCalled(); + expect(elementOffSpy).not.toHaveBeenCalled(); + + progress(element, 10); + expect(otherEndSpy).toHaveBeenCalledOnce(); + }); + }); + }); });