From 12ab1fa58d3acca0104d95139345101f66a9e389 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matias=20Niemel=C3=A4?= Date: Wed, 6 Jan 2016 11:20:23 -0800 Subject: [PATCH] fix($animate): allow enabled children to animate on disabled parents Prior to this fix if a parent container disabled animations for itself then no children could be enabled explicity via `$animate.enabled`. This patch allows for that to work. Closes #13179 Closes #13695 --- src/ngAnimate/animateQueue.js | 30 ++++++++++++++++++++++-------- test/ngAnimate/animateSpec.js | 29 +++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/src/ngAnimate/animateQueue.js b/src/ngAnimate/animateQueue.js index fbfc0cc78426..026db5d44b24 100644 --- a/src/ngAnimate/animateQueue.js +++ b/src/ngAnimate/animateQueue.js @@ -256,12 +256,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); } } } @@ -574,6 +569,17 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) { var parentAnimationDetected = false; var animateChildren; + var PARENT_STATE_DISABLED = 1; + var PARENT_STATE_ENABLED = 2; + var parentElementDisabledState = 0; + + var elementDisabledStatus = disabledElementsLookup.get(getDomNode(element)); + if (elementDisabledStatus === true) { + parentElementDisabledState = PARENT_STATE_DISABLED; + } else if (elementDisabledStatus === false) { + parentElementDisabledState = PARENT_STATE_ENABLED; + } + var parentHost = element.data(NG_ANIMATE_PIN_DATA); if (parentHost) { parentElement = parentHost; @@ -597,7 +603,15 @@ 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 disabledStatus = disabledElementsLookup.get(parentNode); + + // the user has `explicitly` allowed for animations to be enabled on this container + if (disabledStatus === true && parentElementDisabledState != PARENT_STATE_ENABLED) { + parentElementDisabledState = PARENT_STATE_DISABLED; + } else if (disabledStatus === false) { + parentElementDisabledState = PARENT_STATE_ENABLED; + } + parentAnimationDetected = details.structural; } if (isUndefined(animateChildren) || animateChildren === true) { @@ -632,7 +646,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) { parentElement = parentElement.parent(); } - var allowAnimation = !parentAnimationDetected || animateChildren; + var allowAnimation = (!parentAnimationDetected || animateChildren) && parentElementDisabledState != PARENT_STATE_DISABLED; return allowAnimation && rootElementDetected && bodyElementDetected; } diff --git a/test/ngAnimate/animateSpec.js b/test/ngAnimate/animateSpec.js index dc665ead5398..82e9b2d6697a 100644 --- a/test/ngAnimate/animateSpec.js +++ b/test/ngAnimate/animateSpec.js @@ -304,6 +304,35 @@ describe("animations", function() { $rootScope.$digest(); expect(capturedAnimation).toBeTruthy(); })); + + iit('should enable animations on the child element if explicitly allowed 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',