From f470917094273ef8c8c215480575d84deba5d414 Mon Sep 17 00:00:00 2001 From: Martin Staffa Date: Tue, 8 Dec 2015 14:11:22 +0100 Subject: [PATCH 1/3] fix($animate): correctly access minErr ngMinErr is available during unit tests, but not in the build. There's currently no way to catch these access errors in automated testing. --- src/ngAnimate/shared.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ngAnimate/shared.js b/src/ngAnimate/shared.js index 501e5bd0d015..308258ec78c0 100644 --- a/src/ngAnimate/shared.js +++ b/src/ngAnimate/shared.js @@ -73,6 +73,7 @@ var isPromiseLike = function(p) { return p && p.then ? true : false; }; +var ngMinErr = angular.$$minErr('ng'); function assertArg(arg, name, reason) { if (!arg) { throw ngMinErr('areq', "Argument '{0}' is {1}", (name || '?'), (reason || "required")); From 200985eb241900075a9a08263a99c0f7ec34bfdc Mon Sep 17 00:00:00 2001 From: Martin Staffa Date: Thu, 10 Dec 2015 13:25:41 +0100 Subject: [PATCH 2/3] test($animate): ensure that pin() arguments are elements --- test/ngAnimate/animateSpec.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/test/ngAnimate/animateSpec.js b/test/ngAnimate/animateSpec.js index cdc91a59312d..713170820d2c 100644 --- a/test/ngAnimate/animateSpec.js +++ b/test/ngAnimate/animateSpec.js @@ -1431,7 +1431,24 @@ describe("animations", function() { }); })); - it('should allow an element to pinned elsewhere and still be available in animations', + it('should throw if the arguments are not elements', + inject(function($animate, $compile, $document, $rootScope, $rootElement) { + + var element = jqLite('
'); + + expect(function() { + $animate.pin(element); + }).toThrowMinErr('ng', 'areq', 'Argument \'parentElement\' is not an element'); + + expect(function() { + $animate.pin(null, $rootElement); + }).toThrowMinErr('ng', 'areq', 'Argument \'element\' is not an element'); + + dealoc(element); + })); + + + it('should allow an element to be pinned elsewhere and still be available in animations', inject(function($animate, $compile, $document, $rootElement, $rootScope) { var innerParent = jqLite('
'); From d1c89397b3b8c935a6b7cbddcfce7a12b318148c Mon Sep 17 00:00:00 2001 From: Martin Staffa Date: Wed, 2 Dec 2015 16:39:14 +0100 Subject: [PATCH 3/3] fix($animate): allow animations when pinned element is parent element Previously, the animate queue would only detect pinned elements when they were the same element as the to-be-animated element. Related #12617 Closes #13466 --- src/ngAnimate/animateQueue.js | 1 + test/ngAnimate/animateSpec.js | 50 ++++++++++++++++++++++++----------- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/ngAnimate/animateQueue.js b/src/ngAnimate/animateQueue.js index 0fdadd508609..e024c831cf3c 100644 --- a/src/ngAnimate/animateQueue.js +++ b/src/ngAnimate/animateQueue.js @@ -586,6 +586,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) { parentHost = parentElement.data(NG_ANIMATE_PIN_DATA); if (parentHost) { parentElement = parentHost; + rootElementDetected = true; } } } diff --git a/test/ngAnimate/animateSpec.js b/test/ngAnimate/animateSpec.js index 713170820d2c..dc665ead5398 100644 --- a/test/ngAnimate/animateSpec.js +++ b/test/ngAnimate/animateSpec.js @@ -1448,28 +1448,46 @@ describe("animations", function() { })); - it('should allow an element to be pinned elsewhere and still be available in animations', - inject(function($animate, $compile, $document, $rootElement, $rootScope) { + they('should animate an element inside a pinned element that is the $prop element', + ['same', 'parent', 'grandparent'], + function(elementRelation) { + inject(function($animate, $compile, $document, $rootElement, $rootScope) { - var innerParent = jqLite('
'); - jqLite($document[0].body).append(innerParent); - innerParent.append($rootElement); + var pinElement, animateElement; - var element = jqLite('
'); - jqLite($document[0].body).append(element); + var innerParent = jqLite('
'); + jqLite($document[0].body).append(innerParent); + innerParent.append($rootElement); - $animate.addClass(element, 'red'); - $rootScope.$digest(); - expect(capturedAnimation).toBeFalsy(); + switch (elementRelation) { + case 'same': + pinElement = jqLite('
'); + break; + case 'parent': + pinElement = jqLite('
'); + break; + case 'grandparent': + pinElement = jqLite('
'); + break; + } - $animate.pin(element, $rootElement); + jqLite($document[0].body).append(pinElement); + animateElement = jqLite($document[0].getElementById('animate')); - $animate.addClass(element, 'blue'); - $rootScope.$digest(); - expect(capturedAnimation).toBeTruthy(); + $animate.addClass(animateElement, 'red'); + $rootScope.$digest(); + expect(capturedAnimation).toBeFalsy(); - dealoc(element); - })); + // Pin the element to the app root to enable animations + $animate.pin(pinElement, $rootElement); + + $animate.addClass(animateElement, 'blue'); + $rootScope.$digest(); + expect(capturedAnimation).toBeTruthy(); + + dealoc(pinElement); + }); + }); it('should adhere to the disabled state of the hosted parent when an element is pinned', inject(function($animate, $compile, $document, $rootElement, $rootScope) {