Skip to content

Commit ec8489c

Browse files
gkalpakellimist
authored andcommitted
fix($animate): improve detection on ng-animate in classNameFilter RegExp
Fixes angular#14806
1 parent 2d3af36 commit ec8489c

File tree

3 files changed

+33
-26
lines changed

3 files changed

+33
-26
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
@ngdoc error
2+
@name $animate:nongcls
3+
@fullName `ng-animate` class not allowed
4+
@description
5+
6+
This error occurs, when trying to set `$animateProvider.classNameFilter()` to a RegExp containing
7+
the reserved `ng-animate` class. Since `.ng-animate` will be added/removed by `$animate` itself,
8+
using it as part of the `classNameFilter` RegExp is not allowed.

src/ng/animate.js

+7-6
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ var $$CoreAnimateQueueProvider = /** @this */ function() {
179179
*/
180180
var $AnimateProvider = ['$provide', /** @this */ function($provide) {
181181
var provider = this;
182+
var classNameFilter = null;
182183

183184
this.$$registeredAnimations = Object.create(null);
184185

@@ -247,15 +248,15 @@ var $AnimateProvider = ['$provide', /** @this */ function($provide) {
247248
*/
248249
this.classNameFilter = function(expression) {
249250
if (arguments.length === 1) {
250-
this.$$classNameFilter = (expression instanceof RegExp) ? expression : null;
251-
if (this.$$classNameFilter) {
252-
var reservedRegex = new RegExp('(\\s+|\\/)' + NG_ANIMATE_CLASSNAME + '(\\s+|\\/)');
253-
if (reservedRegex.test(this.$$classNameFilter.toString())) {
254-
throw $animateMinErr('nongcls','$animateProvider.classNameFilter(regex) prohibits accepting a regex value which matches/contains the "{0}" CSS class.', NG_ANIMATE_CLASSNAME);
251+
classNameFilter = (expression instanceof RegExp) ? expression : null;
252+
if (classNameFilter) {
253+
var reservedRegex = new RegExp('[(\\s|\\/)]' + NG_ANIMATE_CLASSNAME + '[(\\s|\\/)]');
254+
if (reservedRegex.test(classNameFilter.toString())) {
255+
throw $animateMinErr('nongcls', '$animateProvider.classNameFilter(regex) prohibits accepting a regex value which matches/contains the "{0}" CSS class.', NG_ANIMATE_CLASSNAME);
255256
}
256257
}
257258
}
258-
return this.$$classNameFilter;
259+
return classNameFilter;
259260
};
260261

261262
this.$get = ['$$animateQueue', function($$animateQueue) {

test/ngAnimate/animateSpec.js

+18-20
Original file line numberDiff line numberDiff line change
@@ -255,29 +255,27 @@ describe('animations', function() {
255255
});
256256
});
257257

258-
it('should throw a minErr if a regex value is used which partially contains or fully matches the `ng-animate` CSS class', function() {
258+
it('should throw a minErr if a regex value is used which partially contains or fully matches the `ng-animate` CSS class',
259259
module(function($animateProvider) {
260-
assertError(/ng-animate/, true);
261-
assertError(/first ng-animate last/, true);
262-
assertError(/ng-animate-special/, false);
263-
assertError(/first ng-animate-special last/, false);
264-
assertError(/first ng-animate ng-animate-special last/, true);
265-
266-
function assertError(regex, bool) {
267-
var expectation = expect(function() {
260+
expect(setFilter(/ng-animate/)).toThrowMinErr('$animate', 'nongcls');
261+
expect(setFilter(/first ng-animate last/)).toThrowMinErr('$animate', 'nongcls');
262+
expect(setFilter(/first ng-animate ng-animate-special last/)).toThrowMinErr('$animate', 'nongcls');
263+
expect(setFilter(/(ng-animate)/)).toThrowMinErr('$animate', 'nongcls');
264+
expect(setFilter(/(foo|ng-animate|bar)/)).toThrowMinErr('$animate', 'nongcls');
265+
expect(setFilter(/(foo|)ng-animate(|bar)/)).toThrowMinErr('$animate', 'nongcls');
266+
267+
expect(setFilter(/ng-animater/)).not.toThrow();
268+
expect(setFilter(/my-ng-animate/)).not.toThrow();
269+
expect(setFilter(/first ng-animater last/)).not.toThrow();
270+
expect(setFilter(/first my-ng-animate last/)).not.toThrow();
271+
272+
function setFilter(regex) {
273+
return function() {
268274
$animateProvider.classNameFilter(regex);
269-
});
270-
271-
var message = '$animateProvider.classNameFilter(regex) prohibits accepting a regex value which matches/contains the "ng-animate" CSS class.';
272-
273-
if (bool) {
274-
expectation.toThrowMinErr('$animate', 'nongcls', message);
275-
} else {
276-
expectation.not.toThrowMinErr('$animate', 'nongcls', message);
277-
}
275+
};
278276
}
279-
});
280-
});
277+
})
278+
);
281279

282280
it('should complete the leave DOM operation in case the classNameFilter fails', function() {
283281
module(function($animateProvider) {

0 commit comments

Comments
 (0)