aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/ngAnimate/animate.js209
-rw-r--r--test/ngAnimate/animateSpec.js32
2 files changed, 137 insertions, 104 deletions
diff --git a/src/ngAnimate/animate.js b/src/ngAnimate/animate.js
index a55067bc..c43401ec 100644
--- a/src/ngAnimate/animate.js
+++ b/src/ngAnimate/animate.js
@@ -489,6 +489,7 @@ angular.module('ngAnimate', ['ng'])
done:done
});
+ var baseClassName = className;
if(event == 'addClass') {
className = suffixClasses(className, '-add');
} else if(event == 'removeClass') {
@@ -504,7 +505,7 @@ angular.module('ngAnimate', ['ng'])
if(animation.start) {
if(event == 'addClass' || event == 'removeClass') {
- animation.endFn = animation.start(element, className, fn);
+ animation.endFn = animation.start(element, baseClassName, fn);
} else {
animation.endFn = animation.start(element, fn);
}
@@ -520,17 +521,6 @@ angular.module('ngAnimate', ['ng'])
});
}
- function suffixClasses(classes, suffix) {
- var className = '';
- classes = angular.isArray(classes) ? classes : classes.split(/\s+/);
- forEach(classes, function(klass, i) {
- if(klass && klass.length > 0) {
- className += (i > 0 ? ' ' : '') + klass + suffix;
- }
- });
- return className;
- }
-
function progress(index) {
animations[index].done = true;
(animations[index].endFn || noop)();
@@ -550,117 +540,128 @@ angular.module('ngAnimate', ['ng'])
}
}
}]);
- }])
- .animation('', ['$window','$sniffer', '$timeout', function($window, $sniffer, $timeout) {
- var noop = angular.noop;
- var forEach = angular.forEach;
- function animate(element, className, done) {
- if (!($sniffer.transitions || $sniffer.animations)) {
- done();
- } else {
- var activeClassName = '';
- $timeout(startAnimation, 1, false);
-
- //this acts as the cancellation function in case
- //a new animation is triggered while another animation
- //is still going on (otherwise the active className
- //would still hang around until the timer is complete).
- return onEnd;
- }
+ $animateProvider.register('', ['$window','$sniffer', '$timeout', function($window, $sniffer, $timeout) {
+ var noop = angular.noop;
+ var forEach = angular.forEach;
+ function animate(element, className, done) {
+ if (!($sniffer.transitions || $sniffer.animations)) {
+ done();
+ } else {
+ var activeClassName = '';
+ $timeout(startAnimation, 1, false);
+
+ //this acts as the cancellation function in case
+ //a new animation is triggered while another animation
+ //is still going on (otherwise the active className
+ //would still hang around until the timer is complete).
+ return onEnd;
+ }
- function parseMaxTime(str) {
- var total = 0, values = angular.isString(str) ? str.split(/\s*,\s*/) : [];
- forEach(values, function(value) {
- total = Math.max(parseFloat(value) || 0, total);
- });
- return total;
- }
+ function parseMaxTime(str) {
+ var total = 0, values = angular.isString(str) ? str.split(/\s*,\s*/) : [];
+ forEach(values, function(value) {
+ total = Math.max(parseFloat(value) || 0, total);
+ });
+ return total;
+ }
- function startAnimation() {
- var duration = 0;
- forEach(className.split(' '), function(klass, i) {
- activeClassName += (i > 0 ? ' ' : '') + klass + '-active';
- });
+ function startAnimation() {
+ var duration = 0;
+ forEach(className.split(' '), function(klass, i) {
+ activeClassName += (i > 0 ? ' ' : '') + klass + '-active';
+ });
- element.addClass(activeClassName);
+ element.addClass(activeClassName);
- //one day all browsers will have these properties
- var w3cAnimationProp = 'animation';
- var w3cTransitionProp = 'transition';
+ //one day all browsers will have these properties
+ var w3cAnimationProp = 'animation';
+ var w3cTransitionProp = 'transition';
- //but some still use vendor-prefixed styles
- var vendorAnimationProp = $sniffer.vendorPrefix + 'Animation';
- var vendorTransitionProp = $sniffer.vendorPrefix + 'Transition';
+ //but some still use vendor-prefixed styles
+ var vendorAnimationProp = $sniffer.vendorPrefix + 'Animation';
+ var vendorTransitionProp = $sniffer.vendorPrefix + 'Transition';
- var durationKey = 'Duration',
- delayKey = 'Delay',
- animationIterationCountKey = 'IterationCount';
+ var durationKey = 'Duration',
+ delayKey = 'Delay',
+ animationIterationCountKey = 'IterationCount';
- //we want all the styles defined before and after
- var ELEMENT_NODE = 1;
- forEach(element, function(element) {
- if (element.nodeType == ELEMENT_NODE) {
- var elementStyles = $window.getComputedStyle(element) || {};
+ //we want all the styles defined before and after
+ var ELEMENT_NODE = 1;
+ forEach(element, function(element) {
+ if (element.nodeType == ELEMENT_NODE) {
+ var elementStyles = $window.getComputedStyle(element) || {};
- var transitionDelay = Math.max(parseMaxTime(elementStyles[w3cTransitionProp + delayKey]),
- parseMaxTime(elementStyles[vendorTransitionProp + delayKey]));
+ var transitionDelay = Math.max(parseMaxTime(elementStyles[w3cTransitionProp + delayKey]),
+ parseMaxTime(elementStyles[vendorTransitionProp + delayKey]));
- var animationDelay = Math.max(parseMaxTime(elementStyles[w3cAnimationProp + delayKey]),
- parseMaxTime(elementStyles[vendorAnimationProp + delayKey]));
+ var animationDelay = Math.max(parseMaxTime(elementStyles[w3cAnimationProp + delayKey]),
+ parseMaxTime(elementStyles[vendorAnimationProp + delayKey]));
- var transitionDuration = Math.max(parseMaxTime(elementStyles[w3cTransitionProp + durationKey]),
- parseMaxTime(elementStyles[vendorTransitionProp + durationKey]));
+ var transitionDuration = Math.max(parseMaxTime(elementStyles[w3cTransitionProp + durationKey]),
+ parseMaxTime(elementStyles[vendorTransitionProp + durationKey]));
- var animationDuration = Math.max(parseMaxTime(elementStyles[w3cAnimationProp + durationKey]),
- parseMaxTime(elementStyles[vendorAnimationProp + durationKey]));
+ var animationDuration = Math.max(parseMaxTime(elementStyles[w3cAnimationProp + durationKey]),
+ parseMaxTime(elementStyles[vendorAnimationProp + durationKey]));
- if(animationDuration > 0) {
- animationDuration *= Math.max(parseInt(elementStyles[w3cAnimationProp + animationIterationCountKey]) || 0,
- parseInt(elementStyles[vendorAnimationProp + animationIterationCountKey]) || 0,
- 1);
+ if(animationDuration > 0) {
+ animationDuration *= Math.max(parseInt(elementStyles[w3cAnimationProp + animationIterationCountKey]) || 0,
+ parseInt(elementStyles[vendorAnimationProp + animationIterationCountKey]) || 0,
+ 1);
+ }
+
+ duration = Math.max(animationDelay + animationDuration,
+ transitionDelay + transitionDuration,
+ duration);
}
+ });
- duration = Math.max(animationDelay + animationDuration,
- transitionDelay + transitionDuration,
- duration);
- }
- });
+ $timeout(done, duration * 1000, false);
+ }
- $timeout(done, duration * 1000, false);
+ //this will automatically be called by $animate so
+ //there is no need to attach this internally to the
+ //timeout done method
+ function onEnd(cancelled) {
+ element.removeClass(activeClassName);
+
+ //only when the animation is cancelled is the done()
+ //function not called for this animation therefore
+ //this must be also called
+ if(cancelled) {
+ done();
+ }
+ }
}
- //this will automatically be called by $animate so
- //there is no need to attach this internally to the
- //timeout done method
- function onEnd(cancelled) {
- element.removeClass(activeClassName);
-
- //only when the animation is cancelled is the done()
- //function not called for this animation therefore
- //this must be also called
- if(cancelled) {
- done();
+ return {
+ enter : function(element, done) {
+ return animate(element, 'ng-enter', done);
+ },
+ leave : function(element, done) {
+ return animate(element, 'ng-leave', done);
+ },
+ move : function(element, done) {
+ return animate(element, 'ng-move', done);
+ },
+ addClass : function(element, className, done) {
+ return animate(element, suffixClasses(className, '-add'), done);
+ },
+ removeClass : function(element, className, done) {
+ return animate(element, suffixClasses(className, '-remove'), done);
}
- }
- }
+ };
- return {
- enter : function(element, done) {
- return animate(element, 'ng-enter', done);
- },
- leave : function(element, done) {
- return animate(element, 'ng-leave', done);
- },
- move : function(element, done) {
- return animate(element, 'ng-move', done);
- },
- addClass : function(element, className, done) {
- return animate(element, className, done);
- },
- removeClass : function(element, className, done) {
- return animate(element, className, done);
- }
- };
+ }]);
+ function suffixClasses(classes, suffix) {
+ var className = '';
+ classes = angular.isArray(classes) ? classes : classes.split(/\s+/);
+ forEach(classes, function(klass, i) {
+ if(klass && klass.length > 0) {
+ className += (i > 0 ? ' ' : '') + klass + suffix;
+ }
+ });
+ return className;
+ }
}]);
diff --git a/test/ngAnimate/animateSpec.js b/test/ngAnimate/animateSpec.js
index e5ade9f3..30bf6ba7 100644
--- a/test/ngAnimate/animateSpec.js
+++ b/test/ngAnimate/animateSpec.js
@@ -1513,4 +1513,36 @@ describe("ngAnimate", function() {
});
});
+ it("should provide the correct CSS class to the addClass and removeClass callbacks within a JS animation", function() {
+ module(function($animateProvider) {
+ $animateProvider.register('.classify', function($timeout) {
+ return {
+ removeClass : function(element, className, done) {
+ element.data('classify','remove-' + className);
+ done();
+ },
+ addClass : function(element, className, done) {
+ element.data('classify','add-' + className);
+ done();
+ }
+ }
+ });
+ })
+ inject(function($compile, $rootScope, $animate, $timeout) {
+ var element = html($compile('<div class="classify"></div>')($rootScope));
+
+ $animate.addClass(element, 'super');
+ expect(element.data('classify')).toBe('add-super');
+ $timeout.flush();
+
+ $animate.removeClass(element, 'super');
+ expect(element.data('classify')).toBe('remove-super');
+ $timeout.flush();
+
+ $animate.addClass(element, 'superguy');
+ expect(element.data('classify')).toBe('add-superguy');
+ $timeout.flush();
+ });
+ });
+
});