Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit edc4a89

Browse files
committedMay 5, 2015
fix($animateCss): ensure that detection cache is flushed after animation is closed
Closes #11723
1 parent 1268b17 commit edc4a89

File tree

2 files changed

+48
-8
lines changed

2 files changed

+48
-8
lines changed
 

‎src/ngAnimate/animateCss.js

+18-8
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
424424
var KEY = "$$ngAnimateParentKey";
425425
var parentNode = node.parentNode;
426426
var parentID = parentNode[KEY] || (parentNode[KEY] = ++parentCounter);
427-
return parentID + '-' + node.getAttribute('class') + '-' + extraClasses;
427+
return parentID + '-' + (node.getAttribute('class') || '') + '-' + (extraClasses || '');
428428
}
429429

430430
function computeCachedCssStyles(node, className, cacheKey, properties) {
@@ -472,6 +472,11 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
472472
return stagger || {};
473473
}
474474

475+
function flushGCSCache() {
476+
gcsLookup.flush();
477+
gcsStaggerLookup.flush();
478+
}
479+
475480
var bod = $document[0].body;
476481
var cancelLastRAFRequest;
477482
var rafWaitQueue = [];
@@ -482,8 +487,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
482487
rafWaitQueue.push(callback);
483488
cancelLastRAFRequest = $$rAF(function() {
484489
cancelLastRAFRequest = null;
485-
gcsLookup.flush();
486-
gcsStaggerLookup.flush();
490+
flushGCSCache();
487491

488492
//the line below will force the browser to perform a repaint so
489493
//that all the animated elements within the animation frame will
@@ -514,7 +518,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
514518
? Math.max(aD, tD)
515519
: (aD || tD);
516520
timings.maxDuration = Math.max(
517-
timings.animationDuration * timings.animationIterationCount,
521+
(timings.animationDuration * timings.animationIterationCount) || 0,
518522
timings.transitionDuration);
519523

520524
return timings;
@@ -525,7 +529,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
525529
options = prepareAnimationOptions(options);
526530

527531
var temporaryStyles = [];
528-
var classes = element.attr('class');
532+
var classes = element.attr('class') || '';
529533
var styles = packageStyles(options);
530534
var animationClosed;
531535
var animationPaused;
@@ -649,7 +653,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
649653

650654
var timings = computeTimings(node, fullClassName, cacheKey);
651655
var relativeDelay = timings.maxDelay;
652-
maxDelay = Math.max(relativeDelay, 0);
656+
maxDelay = Math.max(relativeDelay || 0, 0);
653657
maxDuration = timings.maxDuration;
654658

655659
var flags = {};
@@ -765,6 +769,12 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
765769
applyAnimationClasses(element, options);
766770
applyAnimationStyles(element, options);
767771

772+
// we need to clear the cache since the post-quiet state may add and remove CSS
773+
// classes which contain follow-up animation data which will be cached.
774+
$$rAF(function() {
775+
flushGCSCache();
776+
});
777+
768778
// the reason why we have this option is to allow a synchronous closing callback
769779
// that is fired as SOON as the animation ends (when the CSS is removed) or if
770780
// the animation never takes off at all. A good example is a leave animation since
@@ -860,7 +870,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
860870

861871
timings = computeTimings(node, fullClassName, cacheKey);
862872
relativeDelay = timings.maxDelay;
863-
maxDelay = Math.max(relativeDelay, 0);
873+
maxDelay = Math.max(relativeDelay || 0, 0);
864874
maxDuration = timings.maxDuration;
865875

866876
if (maxDuration === 0) {
@@ -877,7 +887,7 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
877887
? parseFloat(options.delay)
878888
: relativeDelay;
879889

880-
maxDelay = Math.max(relativeDelay, 0);
890+
maxDelay = Math.max(relativeDelay || 0, 0);
881891

882892
var delayStyle;
883893
if (flags.applyTransitionDelay) {

‎test/ngAnimate/animateCssSpec.js

+30
Original file line numberDiff line numberDiff line change
@@ -1069,6 +1069,36 @@ describe("ngAnimate $animateCss", function() {
10691069
expect(count.normal).toBe(3);
10701070
}));
10711071

1072+
it("should cache the post-quiet state detection and flush one frame after the animation is complete",
1073+
inject(function($animateCss, $document, $rootElement, $$rAF) {
1074+
1075+
var i, animator, elms = [];
1076+
for (i = 0; i < 5; i++) {
1077+
var elm = jqLite('<div>' + i + '</div>');
1078+
$rootElement.append(elm);
1079+
animator = $animateCss(elm, { to: {color:'green'}, duration: 0.5 });
1080+
var runner = animator.start();
1081+
elms.push(elm);
1082+
}
1083+
1084+
expect(count.normal).toBe(2); //first + stagger
1085+
triggerAnimationStartFrame();
1086+
1087+
expect(count.normal).toBe(3); //first + stagger + post-quiet
1088+
for (i = 0; i < elms.length; i++) {
1089+
browserTrigger(elms[i], 'transitionend',
1090+
{ timeStamp: Date.now() + 1000, elapsedTime: 1 });
1091+
}
1092+
1093+
$$rAF.flush();
1094+
1095+
for (i = 0; i < elms.length; i++) {
1096+
animator = $animateCss(elms[i], { to: {color:'red'}, duration: 0.8 });
1097+
}
1098+
1099+
expect(count.normal).toBe(5); //first + stagger + quiet + first + stagger
1100+
}));
1101+
10721102
it("should cache frequent calls to getComputedStyle for stagger animations before the next animation frame kicks in",
10731103
inject(function($animateCss, $document, $rootElement, $$rAF) {
10741104

0 commit comments

Comments
 (0)
This repository has been archived.