mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-16 23:30:23 +00:00
feat(ngAnimate): provide configuration support to match specific className values to trigger animations
Closes #5357 Closes #5283
This commit is contained in:
parent
937caab647
commit
cef084ade9
3 changed files with 86 additions and 4 deletions
|
|
@ -61,6 +61,28 @@ var $AnimateProvider = ['$provide', function($provide) {
|
||||||
$provide.factory(key, factory);
|
$provide.factory(key, factory);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc function
|
||||||
|
* @name ng.$animateProvider#classNameFilter
|
||||||
|
* @methodOf ng.$animateProvider
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Sets and/or returns the CSS class regular expression that is checked when performing
|
||||||
|
* an animation. Upon bootstrap the classNameFilter value is not set at all and will
|
||||||
|
* therefore enable $animate to attempt to perform an animation on any element.
|
||||||
|
* When setting the classNameFilter value, animations will only be performed on elements
|
||||||
|
* that successfully match the filter expression. This in turn can boost performance
|
||||||
|
* for low-powered devices as well as applications containing a lot of structural operations.
|
||||||
|
* @param {RegExp=} expression The className expression which will be checked against all animations
|
||||||
|
* @return {RegExp} The current CSS className expression value. If null then there is no expression value
|
||||||
|
*/
|
||||||
|
this.classNameFilter = function(expression) {
|
||||||
|
if(arguments.length === 1) {
|
||||||
|
this.$$classNameFilter = (expression instanceof RegExp) ? expression : null;
|
||||||
|
}
|
||||||
|
return this.$$classNameFilter;
|
||||||
|
};
|
||||||
|
|
||||||
this.$get = ['$timeout', function($timeout) {
|
this.$get = ['$timeout', function($timeout) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -288,6 +288,13 @@ angular.module('ngAnimate', ['ng'])
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var classNameFilter = $animateProvider.classNameFilter();
|
||||||
|
var isAnimatableClassName = !classNameFilter
|
||||||
|
? function() { return true; }
|
||||||
|
: function(className) {
|
||||||
|
return classNameFilter.test(className);
|
||||||
|
};
|
||||||
|
|
||||||
function lookup(name) {
|
function lookup(name) {
|
||||||
if (name) {
|
if (name) {
|
||||||
var matches = [],
|
var matches = [],
|
||||||
|
|
@ -569,17 +576,20 @@ angular.module('ngAnimate', ['ng'])
|
||||||
and the onComplete callback will be fired once the animation is fully complete.
|
and the onComplete callback will be fired once the animation is fully complete.
|
||||||
*/
|
*/
|
||||||
function performAnimation(animationEvent, className, element, parentElement, afterElement, domOperation, doneCallback) {
|
function performAnimation(animationEvent, className, element, parentElement, afterElement, domOperation, doneCallback) {
|
||||||
var node = extractElementNode(element);
|
var currentClassName, classes, node = extractElementNode(element);
|
||||||
|
if(node) {
|
||||||
|
currentClassName = node.className;
|
||||||
|
classes = currentClassName + ' ' + className;
|
||||||
|
}
|
||||||
|
|
||||||
//transcluded directives may sometimes fire an animation using only comment nodes
|
//transcluded directives may sometimes fire an animation using only comment nodes
|
||||||
//best to catch this early on to prevent any animation operations from occurring
|
//best to catch this early on to prevent any animation operations from occurring
|
||||||
if(!node) {
|
if(!node || !isAnimatableClassName(classes)) {
|
||||||
fireDOMOperation();
|
fireDOMOperation();
|
||||||
closeAnimation();
|
closeAnimation();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentClassName = node.className;
|
|
||||||
var classes = currentClassName + ' ' + className;
|
|
||||||
var animationLookup = (' ' + classes).replace(/\s+/g,'.');
|
var animationLookup = (' ' + classes).replace(/\s+/g,'.');
|
||||||
if (!parentElement) {
|
if (!parentElement) {
|
||||||
parentElement = afterElement ? afterElement.parent() : element.parent();
|
parentElement = afterElement ? afterElement.parent() : element.parent();
|
||||||
|
|
|
||||||
|
|
@ -2947,5 +2947,55 @@ describe("ngAnimate", function() {
|
||||||
expect(capturedAnimation).toBe('leave');
|
expect(capturedAnimation).toBe('leave');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should animate only the specified CSS className', function() {
|
||||||
|
var captures = {};
|
||||||
|
module(function($animateProvider) {
|
||||||
|
$animateProvider.classNameFilter(/prefixed-animation/);
|
||||||
|
$animateProvider.register('.capture', function() {
|
||||||
|
return {
|
||||||
|
enter : buildFn('enter'),
|
||||||
|
leave : buildFn('leave')
|
||||||
|
};
|
||||||
|
|
||||||
|
function buildFn(key) {
|
||||||
|
return function(element, className, done) {
|
||||||
|
captures[key] = true;
|
||||||
|
(done || className)();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
inject(function($rootScope, $compile, $rootElement, $document, $timeout, $templateCache, $sniffer, $animate) {
|
||||||
|
if(!$sniffer.transitions) return;
|
||||||
|
|
||||||
|
var element = $compile('<div class="capture"></div>')($rootScope);
|
||||||
|
$rootElement.append(element);
|
||||||
|
jqLite($document[0].body).append($rootElement);
|
||||||
|
|
||||||
|
var enterDone = false;
|
||||||
|
$animate.enter(element, $rootElement, null, function() {
|
||||||
|
enterDone = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
$rootScope.$digest();
|
||||||
|
$timeout.flush();
|
||||||
|
|
||||||
|
expect(captures['enter']).toBeUndefined();
|
||||||
|
expect(enterDone).toBe(true);
|
||||||
|
|
||||||
|
element.addClass('prefixed-animation');
|
||||||
|
|
||||||
|
var leaveDone = false;
|
||||||
|
$animate.leave(element, function() {
|
||||||
|
leaveDone = true;
|
||||||
|
});
|
||||||
|
$rootScope.$digest();
|
||||||
|
$timeout.flush();
|
||||||
|
|
||||||
|
expect(captures['leave']).toBe(true);
|
||||||
|
expect(leaveDone).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue