Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Commit

Permalink
feat($animator): allow to globally disable and enable animations
Browse files Browse the repository at this point in the history
  • Loading branch information
matsko authored and mhevery committed Apr 11, 2013
1 parent d9d5347 commit 5476cb6
Show file tree
Hide file tree
Showing 2 changed files with 141 additions and 38 deletions.
97 changes: 61 additions & 36 deletions src/ng/animator.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,21 +121,24 @@
*
*/

/**
* @ngdoc function
* @name ng.$animator
*
* @description
* The $animator service provides the DOM manipulation API which is decorated with animations.
*
* @param {Scope} scope the scope for the ng-animate.
* @param {Attributes} attr the attributes object which contains the ngAnimate key / value pair. (The attributes are
* passed into the linking function of the directive using the `$animator`.)
* @return {object} the animator object which contains the enter, leave, move, show, hide and animate methods.
*/
var $AnimatorProvider = function() {
this.$get = ['$animation', '$window', '$sniffer', function($animation, $window, $sniffer) {
return function(scope, attrs) {
var globalAnimationEnabled = true;

this.$get = ['$animation', '$window', '$sniffer', '$rootScope', function($animation, $window, $sniffer, $rootScope) {
/**
* @ngdoc function
* @name ng.$animator
* @function
*
* @description
* The $animator.create service provides the DOM manipulation API which is decorated with animations.
*
* @param {Scope} scope the scope for the ng-animate.
* @param {Attributes} attr the attributes object which contains the ngAnimate key / value pair. (The attributes are
* passed into the linking function of the directive using the `$animator`.)
* @return {object} the animator object which contains the enter, leave, move, show, hide and animate methods.
*/
var AnimatorService = function(scope, attrs) {
var ngAnimateAttr = attrs.ngAnimate;
var animator = {};

Expand Down Expand Up @@ -230,7 +233,7 @@ var $AnimatorProvider = function() {
var startClass = className + '-start';

return function(element, parent, after) {
if (!$sniffer.supportsTransitions && !polyfillSetup && !polyfillStart) {
if (!globalAnimationEnabled || !$sniffer.supportsTransitions && !polyfillSetup && !polyfillStart) {
beforeFn(element, parent, after);
afterFn(element, parent, after);
return;
Expand Down Expand Up @@ -280,32 +283,54 @@ var $AnimatorProvider = function() {
}
}
}
}

function show(element) {
element.css('display', '');
}
function show(element) {
element.css('display', '');
}

function hide(element) {
element.css('display', 'none');
}
function hide(element) {
element.css('display', 'none');
}

function insert(element, parent, after) {
if (after) {
after.after(element);
} else {
parent.append(element);
function insert(element, parent, after) {
if (after) {
after.after(element);
} else {
parent.append(element);
}
}

function remove(element) {
element.remove();
}
}

function remove(element) {
element.remove();
}
function move(element, parent, after) {
// Do not remove element before insert. Removing will cause data associated with the
// element to be dropped. Insert will implicitly do the remove.
insert(element, parent, after);
}
};

/**
* @ngdoc function
* @name ng.animator#enabled
* @methodOf ng.$animator
* @function
*
* @param {Boolean=} If provided then set the animation on or off.
* @return {Boolean} Current animation state.
*
* @description
* Globally enables/disables animations.
*
*/
AnimatorService.enabled = function(value) {
if (arguments.length) {
globalAnimationEnabled = !!value;
}
return globalAnimationEnabled;
};

function move(element, parent, after) {
// Do not remove element before insert. Removing will cause data associated with the
// element to be dropped. Insert will implicitly do the remove.
insert(element, parent, after);
}
return AnimatorService;
}];
};
82 changes: 80 additions & 2 deletions test/ng/animatorSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,20 @@ describe("$animator", function() {
dealoc(element);
});

describe("enable / disable", function() {

it("should disable and enable the animations", inject(function($animator) {
expect($animator.enabled()).toBe(true);

expect($animator.enabled(0)).toBe(false);
expect($animator.enabled()).toBe(false);

expect($animator.enabled(1)).toBe(true);
expect($animator.enabled()).toBe(true);
}));

});

describe("without animation", function() {
var window, animator;

Expand Down Expand Up @@ -46,20 +60,27 @@ describe("$animator", function() {
expect(element.text()).toBe('21');
}));

it("should animate the show animation event", inject(function($animator, $compile, $rootScope) {
it("should animate the show animation event", inject(function() {
element.css('display','none');
expect(element.css('display')).toBe('none');
animator.show(element);
expect(element[0].style.display).toBe('');
}));

it("should animate the hide animation event", inject(function($animator, $compile, $rootScope) {
it("should animate the hide animation event", inject(function() {
element.css('display','block');
expect(element.css('display')).toBe('block');
animator.hide(element);
expect(element.css('display')).toBe('none');
}));

it("should still perform DOM operations even if animations are disabled", inject(function($animator) {
$animator.enabled(false);
element.css('display','block');
expect(element.css('display')).toBe('block');
animator.hide(element);
expect(element.css('display')).toBe('none');
}));
});

describe("with polyfill", function() {
Expand Down Expand Up @@ -206,6 +227,63 @@ describe("$animator", function() {
window.setTimeout.expect(1).process();
expect(element.text()).toBe('memento');
}));

it("should not run if animations are disabled", inject(function($animator, $rootScope) {
$animator.enabled(false);

animator = $animator($rootScope, {
ngAnimate : '{show: \'setup-memo\'}'
});
element.text('123');
expect(element.text()).toBe('123');
animator.show(element);
expect(element.text()).toBe('123');

$animator.enabled(true);

animator.show(element);
window.setTimeout.expect(1).process();
expect(element.text()).toBe('memento');
}));
});

describe("with css3", function() {
var window, animator, prefix, vendorPrefix;

beforeEach(function() {
module(function($animationProvider, $provide) {
$provide.value('$window', window = angular.mock.createMockWindow());
return function($sniffer) {
vendorPrefix = '-' + $sniffer.vendorPrefix + '-';
};
})
});

it("should skip animations if disabled and run when enabled",
inject(function($animator, $rootScope, $compile, $sniffer) {
$animator.enabled(false);
element = $compile('<div style="transition: 1s linear all">1</div>')($rootScope);
var animator = $animator($rootScope, {
ngAnimate : '{show: \'inline-show\'}'
});

element.css('display','none');
expect(element.css('display')).toBe('none');
animator.show(element);
expect(element[0].style.display).toBe('');

$animator.enabled(true);

element.css('display','none');
expect(element.css('display')).toBe('none');

animator.show(element);
if ($sniffer.supportsTransitions) {
window.setTimeout.expect(1).process();
window.setTimeout.expect(1000).process();
}
expect(element[0].style.display).toBe('');
}));
});

it("should throw an error when an invalid ng-animate syntax is provided", inject(function($compile, $rootScope) {
Expand Down

3 comments on commit 5476cb6

@Pablito13
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In version 1.1.5 there is this code:
AnimatorService.enabled = function(value) {
if (arguments.length) {
rootAnimateController.running = !value;
}
return !rootAnimateController.running;
};
and it doesn't work.

@damrbaby
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@damrbaby
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Workaround would be to wrap $animator.enabled(false) in a setTimeout function with a run block.

setTimeout -> $animator.enabled false

Please sign in to comment.