Permalink
Comparing changes
Open a pull request
- 1 commit
- 2 files changed
- 0 commit comments
- 1 contributor
Commits on May 24, 2016
In tests, the $document service might be mocked out without providing a real
document, which can lead to errors when the animator is attempting to read properties from it.
This commit provides an object {hidden: true}, if the $document service doesn't have
a document. This will prevent the animation process from trying to run any animations.
This commit also changes the check for document.hidden slightly. It
should be accessed independently of the current animationsEnabled state.
Since animations are only enabled after two digests, it's possible that
some tests never reach the animationsEnabled = true state and therefore
aren't actually checking the document.hidden state, which means that
the previous fix only works if no more than two digests happen in the test.
(#14633)
Unified
Split
Showing
with
35 additions
and 2 deletions.
- +5 −2 src/ngAnimate/animateQueue.js
- +30 −0 test/ngAnimate/animateSpec.js
| @@ -103,6 +103,9 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) { | ||
| var activeAnimationsLookup = new $$HashMap(); | ||
| var disabledElementsLookup = new $$HashMap(); | ||
| var animationsEnabled = null; | ||
| // $document might be mocked out in tests and won't include a real document. | ||
| // Providing an empty object with hidden = true will prevent animations from running | ||
| var rawDocument = $document[0] || {hidden: true}; | ||
|
|
||
| function postDigestTaskFactory() { | ||
| var postDigestCalled = false; | ||
| @@ -331,7 +334,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) { | ||
|
|
||
| var isStructural = ['enter', 'move', 'leave'].indexOf(event) >= 0; | ||
|
|
||
| var documentHidden = animationsEnabled && $document[0].hidden; | ||
| var documentHidden = rawDocument.hidden; | ||
|
|
||
| // this is a hard disable of all animations for the application or on | ||
| // the element itself, therefore there is no need to continue further | ||
| @@ -583,7 +586,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) { | ||
| * d) the element is not a child of the $rootElement | ||
| */ | ||
| function areAnimationsAllowed(element, parentElement, event) { | ||
| var bodyElement = jqLite($document[0].body); | ||
| var bodyElement = jqLite(rawDocument.body); | ||
| var bodyElementDetected = isMatchingElement(element, bodyElement) || element[0].nodeName === 'HTML'; | ||
| var rootElementDetected = isMatchingElement(element, $rootElement); | ||
| var parentAnimationDetected = false; | ||
| @@ -1404,6 +1404,36 @@ describe("animations", function() { | ||
| }); | ||
| }); | ||
|
|
||
|
|
||
| it('should not run animations if the document is unavailable', function() { | ||
| var capturedAnimation; | ||
|
|
||
| module(function($provide) { | ||
| $provide.value('$document', {}); | ||
|
|
||
| $provide.factory('$$animation', function($$AnimateRunner) { | ||
| return function(element, method, options) { | ||
| capturedAnimation = arguments; | ||
| return new $$AnimateRunner(); | ||
| }; | ||
| }); | ||
| }); | ||
|
|
||
| inject(function($animate, $rootScope, $rootElement, $document) { | ||
| $animate.enabled(true); | ||
|
|
||
| var spy = jasmine.createSpy(); | ||
|
|
||
| element = jqLite('<div></div>'); | ||
| var runner = $animate.enter(element, $rootElement); | ||
| $rootScope.$digest(); | ||
|
|
||
| $animate.flush(); | ||
|
|
||
| expect(capturedAnimation).toBeUndefined(); | ||
| }); | ||
| }); | ||
|
|
||
| describe('[ng-animate-children]', function() { | ||
| var parent, element, child, capturedAnimation, captureLog; | ||
| beforeEach(module(function($provide) { | ||