aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStanislav Sysoev2014-02-14 15:11:58 +0400
committerMatias Niemelä2014-02-26 15:39:54 -0500
commitc914cd99b3aaf932e3c0e2a585eead7b76621f1b (patch)
treebd24d1a6efba101c5fd11374f6b56fbcf2420f86
parente9881991ca0a5019d3a4215477738ed247898ba0 (diff)
downloadangular.js-c914cd99b3aaf932e3c0e2a585eead7b76621f1b.tar.bz2
fix(ngAnimate): TypeError Cannot call method 'querySelectorAll' in cancelChildAnimations
When an element containing both ng-repeat and ng-if directives attempts to remove any items from the repeat collection, the following error is thrown: "TypeError Cannot call method 'querySelectorAll' of undefined". This happens because the cancelChildAnimations code naively belives that the jqLite object always has an element node within it. The fix in this commit addresses to securely check to see if a node was properly extracted before any child elements are inspected. Closes #6205
-rw-r--r--src/ngAnimate/animate.js25
-rw-r--r--test/ngAnimate/animateSpec.js16
2 files changed, 31 insertions, 10 deletions
diff --git a/src/ngAnimate/animate.js b/src/ngAnimate/animate.js
index 6b1eedfc..0e5fda98 100644
--- a/src/ngAnimate/animate.js
+++ b/src/ngAnimate/animate.js
@@ -942,16 +942,21 @@ angular.module('ngAnimate', ['ng'])
function cancelChildAnimations(element) {
var node = extractElementNode(element);
- forEach(node.querySelectorAll('.' + NG_ANIMATE_CLASS_NAME), function(element) {
- element = angular.element(element);
- var data = element.data(NG_ANIMATE_STATE);
- if(data && data.active) {
- angular.forEach(data.active, function(operation) {
- (operation.done || noop)(true);
- cancelAnimations(operation.animations);
- });
- }
- });
+ if (node) {
+ var nodes = angular.isFunction(node.getElementsByClassName) ?
+ node.getElementsByClassName(NG_ANIMATE_CLASS_NAME) :
+ node.querySelectorAll('.' + NG_ANIMATE_CLASS_NAME);
+ forEach(nodes, function(element) {
+ element = angular.element(element);
+ var data = element.data(NG_ANIMATE_STATE);
+ if(data && data.active) {
+ angular.forEach(data.active, function(operation) {
+ (operation.done || noop)(true);
+ cancelAnimations(operation.animations);
+ });
+ }
+ });
+ }
}
function cancelAnimations(animations) {
diff --git a/test/ngAnimate/animateSpec.js b/test/ngAnimate/animateSpec.js
index a30b5fe9..9179eb2b 100644
--- a/test/ngAnimate/animateSpec.js
+++ b/test/ngAnimate/animateSpec.js
@@ -3370,5 +3370,21 @@ describe("ngAnimate", function() {
expect(stat).toBe('gone');
});
});
+
+ it('should not throw an error when only comment nodes are rendered in the animation',
+ inject(function($rootScope, $compile) {
+
+ $rootScope.items = [1,2,3,4,5];
+
+ var element = html($compile('<div><div class="animated" ng-if="valid" ng-repeat="item in items"></div></div>')($rootScope));
+
+ $rootScope.$digest();
+
+ $rootScope.items = [];
+
+ $rootScope.$digest();
+
+ expect(element.children().length).toBe(0);
+ }));
});
});