diff --git a/src/ngAnimate/animateQueue.js b/src/ngAnimate/animateQueue.js index 89fe6cad31f0..6432f80936c6 100644 --- a/src/ngAnimate/animateQueue.js +++ b/src/ngAnimate/animateQueue.js @@ -263,12 +263,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) { bool = !recordExists; } else { // (element, bool) - Element setter - bool = !!bool; - if (!bool) { - disabledElementsLookup.put(node, true); - } else if (recordExists) { - disabledElementsLookup.remove(node); - } + disabledElementsLookup.put(node, !bool); } } } @@ -580,6 +575,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) { var rootElementDetected = isMatchingElement(element, $rootElement); var parentAnimationDetected = false; var animateChildren; + var elementDisabled = disabledElementsLookup.get(getDomNode(element)); var parentHost = element.data(NG_ANIMATE_PIN_DATA); if (parentHost) { @@ -604,7 +600,16 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) { // therefore we can't allow any animations to take place // but if a parent animation is class-based then that's ok if (!parentAnimationDetected) { - parentAnimationDetected = details.structural || disabledElementsLookup.get(parentNode); + var parentElementDisabled = disabledElementsLookup.get(parentNode); + + // disable animations if the user hasn't explicitly enabled animations on the + // current element + if (parentElementDisabled === true && elementDisabled !== false) { + elementDisabled = true; + } else if (parentElementDisabled === false) { + elementDisabled = false; + } + parentAnimationDetected = details.structural; } if (isUndefined(animateChildren) || animateChildren === true) { @@ -639,7 +644,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) { parentElement = parentElement.parent(); } - var allowAnimation = !parentAnimationDetected || animateChildren; + var allowAnimation = (!parentAnimationDetected || animateChildren) && elementDisabled !== true; return allowAnimation && rootElementDetected && bodyElementDetected; } diff --git a/test/ngAnimate/animateSpec.js b/test/ngAnimate/animateSpec.js index 56efecef20a3..09e78af4c132 100644 --- a/test/ngAnimate/animateSpec.js +++ b/test/ngAnimate/animateSpec.js @@ -304,6 +304,35 @@ describe("animations", function() { $rootScope.$digest(); expect(capturedAnimation).toBeTruthy(); })); + + it('should run animations on an element and its children if explicitly enabled, even if animations are disabled on the parent', + inject(function($animate, $rootScope) { + + var child = jqLite('
'); + element.append(child); + parent.append(element); + + $animate.enabled(parent, false); + + $animate.addClass(element, 'red'); + $rootScope.$digest(); + expect(capturedAnimation).toBeFalsy(); + + $animate.addClass(child, 'red'); + $rootScope.$digest(); + expect(capturedAnimation).toBeFalsy(); + + $animate.enabled(element, true); + + $animate.addClass(element, 'blue'); + $rootScope.$digest(); + expect(capturedAnimation).toBeTruthy(); + capturedAnimation = null; + + $animate.addClass(child, 'blue'); + $rootScope.$digest(); + expect(capturedAnimation).toBeTruthy(); + })); }); it('should strip all comment nodes from the animation and not issue an animation if not real elements are found',