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

Enforce a best practice on the ng-animate CSS class #11807

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/ng/animate.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

var $animateMinErr = minErr('$animate');
var ELEMENT_NODE = 1;
var NG_ANIMATE_CLASSNAME = 'ng-animate';

function mergeClasses(a,b) {
if (!a && !b) return '';
Expand Down Expand Up @@ -231,6 +232,13 @@ var $AnimateProvider = ['$provide', function($provide) {
this.classNameFilter = function(expression) {
if (arguments.length === 1) {
this.$$classNameFilter = (expression instanceof RegExp) ? expression : null;
if (this.$$classNameFilter) {
var reservedRegex = new RegExp("(\\s+|\\/)" + NG_ANIMATE_CLASSNAME + "(\\s+|\\/)");
if (reservedRegex.test(this.$$classNameFilter.toString())) {
throw $animateMinErr('nongcls','$animateProvider.classNameFilter(regex) prohibits accepting a regex value which matches/contains the "{0}" CSS class.', NG_ANIMATE_CLASSNAME);

}
}
}
return this.$$classNameFilter;
};
Expand Down
1 change: 1 addition & 0 deletions src/ngAnimate/.jshintrc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"isElement": false,

"ELEMENT_NODE": false,
"NG_ANIMATE_CLASSNAME": false,
"NG_ANIMATE_CHILDREN_DATA": false,

"assertArg": false,
Expand Down
1 change: 0 additions & 1 deletion src/ngAnimate/animation.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict';

var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
var NG_ANIMATE_CLASSNAME = 'ng-animate';
var NG_ANIMATE_REF_ATTR = 'ng-animate-ref';

var drivers = this.drivers = [];
Expand Down
29 changes: 29 additions & 0 deletions src/ngAnimate/module.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,35 @@
*
* Stagger animations are currently only supported within CSS-defined animations.
*
* ### The `ng-animate` CSS class
*
* When ngAnimate is animating an element it will apply the `ng-animate` CSS class to the element for the duration of the animation.
* This is a temporary CSS class and it will be removed once the animation is over (for both JavaScript and CSS-based animations).
*
* Therefore, animations can be applied to an element using this temporary class directly via CSS.
*
* ```css
* .zipper.ng-animate {
* transition:0.5s linear all;
* }
* .zipper.ng-enter {
* opacity:0;
* }
* .zipper.ng-enter.ng-enter-active {
* opacity:1;
* }
* .zipper.ng-leave {
* opacity:1;
* }
* .zipper.ng-leave.ng-leave-active {
* opacity:0;
* }
* ```
*
* (Note that the `ng-animate` CSS class is reserved and it cannot be applied on an element directly since ngAnimate will always remove
* the CSS class once an animation has completed.)
*
*
* ## JavaScript-based Animations
*
* ngAnimate also allows for animations to be consumed by JavaScript code. The approach is similar to CSS-based animations (where there is a shared
Expand Down
1 change: 1 addition & 0 deletions src/ngAnimate/shared.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ var isElement = angular.isElement;
var ELEMENT_NODE = 1;
var COMMENT_NODE = 8;

var NG_ANIMATE_CLASSNAME = 'ng-animate';
var NG_ANIMATE_CHILDREN_DATA = '$$ngAnimateChildren';

var isPromiseLike = function(p) {
Expand Down
21 changes: 21 additions & 0 deletions test/ngAnimate/animateSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,27 @@ describe("animations", function() {
});
});

it('should throw a minErr if a regex value is used which partially contains or fully matches the `ng-animate` CSS class', function() {
module(function($animateProvider) {
assertError(/ng-animate/, true);
assertError(/first ng-animate last/, true);
assertError(/ng-animate-special/, false);
assertError(/first ng-animate-special last/, false);
assertError(/first ng-animate ng-animate-special last/, true);

function assertError(regex, bool) {
var expectation = expect(function() {
$animateProvider.classNameFilter(regex);
});

var message = '$animateProvider.classNameFilter(regex) prohibits accepting a regex value which matches/contains the "ng-animate" CSS class.';

bool ? expectation.toThrowMinErr('$animate', 'nongcls', message)
: expectation.not.toThrowMinErr('$animate', 'nongcls', message);
}
});
});

it('should complete the leave DOM operation in case the classNameFilter fails', function() {
module(function($animateProvider) {
$animateProvider.classNameFilter(/memorable-animation/);
Expand Down