fix(ngAnimate): fire callbacks when document is hidden
Since commit a3a7afd3aa, animations are not run
when the document is hidden (only their structural or class change effects are executed).
However, some libraries rely on the $animate.on() callbacks to be called even when no actual animation
runs.
This commit restores the behavior for the ngAnimate.$animate functions.
Note that callbacks still won't be called if animations are disabled, because this would be be a potential
breaking change, as some applications might rely on this implementation.
Fixes #14120
This commit is contained in:
@@ -343,12 +343,14 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
||||
|
||||
var isStructural = ['enter', 'move', 'leave'].indexOf(event) >= 0;
|
||||
|
||||
var documentHidden = $document[0].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
|
||||
// past this point if not enabled
|
||||
// Animations are also disabled if the document is currently hidden (page is not visible
|
||||
// to the user), because browsers slow down or do not flush calls to requestAnimationFrame
|
||||
var skipAnimations = !animationsEnabled || $document[0].hidden || disabledElementsLookup.get(node);
|
||||
var skipAnimations = !animationsEnabled || documentHidden || disabledElementsLookup.get(node);
|
||||
var existingAnimation = (!skipAnimations && activeAnimationsLookup.get(node)) || {};
|
||||
var hasExistingAnimation = !!existingAnimation.state;
|
||||
|
||||
@@ -359,7 +361,10 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
||||
}
|
||||
|
||||
if (skipAnimations) {
|
||||
// Callbacks should fire even if the document is hidden (regression fix for issue #14120)
|
||||
if (documentHidden) notifyProgress(runner, event, 'start');
|
||||
close();
|
||||
if (documentHidden) notifyProgress(runner, event, 'close');
|
||||
return runner;
|
||||
}
|
||||
|
||||
|
||||
@@ -2323,6 +2323,36 @@ describe("animations", function() {
|
||||
expect(classSpy).not.toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
|
||||
describe('because the document is hidden', function() {
|
||||
beforeEach(module(function($provide) {
|
||||
var doc = jqLite({
|
||||
body: document.body,
|
||||
hidden: true
|
||||
});
|
||||
$provide.value('$document', doc);
|
||||
}));
|
||||
|
||||
it('should trigger callbacks for an enter animation',
|
||||
inject(function($animate, $rootScope, $rootElement, $document) {
|
||||
|
||||
var callbackTriggered = false;
|
||||
var spy = jasmine.createSpy();
|
||||
$animate.on('enter', jqLite($document[0].body), spy);
|
||||
|
||||
element = jqLite('<div></div>');
|
||||
var runner = $animate.enter(element, $rootElement);
|
||||
$rootScope.$digest();
|
||||
|
||||
$animate.flush(); // Flushes the animation frames for the callbacks
|
||||
|
||||
expect(spy.calls.count()).toBe(2);
|
||||
expect(spy.calls.argsFor(0)[1]).toBe('start');
|
||||
expect(spy.calls.argsFor(1)[1]).toBe('close');
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user