diff --git a/src/ngAnimate/animate.js b/src/ngAnimate/animate.js index e66fcd6e1cfc..f78adcdc372f 100644 --- a/src/ngAnimate/animate.js +++ b/src/ngAnimate/animate.js @@ -1419,6 +1419,16 @@ angular.module('ngAnimate', ['ng']) var parentCounter = 0; var animationReflowQueue = []; var cancelAnimationReflow; + function clearCacheAfterReflow() { + if (!cancelAnimationReflow) { + cancelAnimationReflow = $$animateReflow(function() { + animationReflowQueue = []; + cancelAnimationReflow = null; + lookupCache = {}; + }); + } + } + function afterReflow(element, callback) { if (cancelAnimationReflow) { cancelAnimationReflow(); @@ -1764,6 +1774,7 @@ angular.module('ngAnimate', ['ng']) //to perform at all var preReflowCancellation = animateBefore(animationEvent, element, className); if (!preReflowCancellation) { + clearCacheAfterReflow(); animationComplete(); return; } @@ -1820,6 +1831,7 @@ angular.module('ngAnimate', ['ng']) afterReflow(element, animationCompleted); return cancellationMethod; } + clearCacheAfterReflow(); animationCompleted(); }, @@ -1829,6 +1841,7 @@ angular.module('ngAnimate', ['ng']) afterReflow(element, animationCompleted); return cancellationMethod; } + clearCacheAfterReflow(); animationCompleted(); }, @@ -1838,6 +1851,7 @@ angular.module('ngAnimate', ['ng']) afterReflow(element, animationCompleted); return cancellationMethod; } + clearCacheAfterReflow(); animationCompleted(); }, diff --git a/test/ngAnimate/animateSpec.js b/test/ngAnimate/animateSpec.js index a571464e2142..b738f1e1ef61 100644 --- a/test/ngAnimate/animateSpec.js +++ b/test/ngAnimate/animateSpec.js @@ -3757,6 +3757,64 @@ describe("ngAnimate", function() { expect(inner.hasClass('on-add-active')).toBe(false); })); + it("should reset the getComputedStyle lookup cache even when no animation is found", + inject(function($compile, $rootScope, $animate, $sniffer, $document) { + + if (!$sniffer.transitions) return; + + $animate.enabled(); + + var html = '
' + + '
On or Off
' + + '
'; + + ss.addRule('.activated .toggle', '-webkit-transition:1s linear all;' + + 'transition:1s linear all;'); + + var child, element = $compile(html)($rootScope); + + $rootElement.append(element); + jqLite($document[0].body).append($rootElement); + + $rootScope.onOff = true; + $rootScope.$digest(); + + child = element.find('div'); + expect(child).not.toHaveClass('ng-enter'); + expect(child.parent()[0]).toEqual(element[0]); + $animate.triggerReflow(); + + $rootScope.onOff = false; + $rootScope.$digest(); + + child = element.find('div'); + expect(child.parent().length).toBe(0); + $animate.triggerReflow(); + + element.addClass('activated'); + $rootScope.$digest(); + $animate.triggerReflow(); + + $rootScope.onOff = true; + $rootScope.$digest(); + + child = element.find('div'); + expect(child).toHaveClass('ng-enter'); + $animate.triggerReflow(); + expect(child).toHaveClass('ng-enter-active'); + + browserTrigger(child, 'transitionend', + { timeStamp: Date.now() + 1000, elapsedTime: 2000 }); + + $animate.triggerCallbacks(); + + $rootScope.onOff = false; + $rootScope.$digest(); + + expect(child).toHaveClass('ng-leave'); + $animate.triggerReflow(); + expect(child).toHaveClass('ng-leave-active'); + })); it("should cancel and perform the dom operation only after the reflow has run", inject(function($compile, $rootScope, $animate, $sniffer) {