Skip to content

Commit

Permalink
fix($animate): ensure the final closing timeout respects staggering a…
Browse files Browse the repository at this point in the history
…nimations
  • Loading branch information
matsko authored and jamesdaily committed Jan 27, 2014
1 parent 5f70886 commit 66c5250
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 10 deletions.
22 changes: 13 additions & 9 deletions src/ngAnimate/animate.js
Original file line number Diff line number Diff line change
Expand Up @@ -930,8 +930,12 @@ angular.module('ngAnimate', ['ng'])
animationElementQueue.push(element);

var elementData = element.data(NG_ANIMATE_CSS_DATA_KEY);
closingAnimationTime = Math.max(closingAnimationTime,
(elementData.maxDelay + elementData.maxDuration) * CLOSING_TIME_BUFFER * ONE_SECOND);

var stagger = elementData.stagger;
var staggerTime = elementData.itemIndex * (Math.max(stagger.animationDelay, stagger.transitionDelay) || 0);

var animationTime = (elementData.maxDelay + elementData.maxDuration) * CLOSING_TIME_BUFFER;
closingAnimationTime = Math.max(closingAnimationTime, (staggerTime + animationTime) * ONE_SECOND);

//by placing a counter we can avoid an accidental
//race condition which may close an animation when
Expand Down Expand Up @@ -1058,9 +1062,9 @@ angular.module('ngAnimate', ['ng'])
var cacheKey = getCacheKey(element);
var eventCacheKey = cacheKey + ' ' + className;
var stagger = {};
var ii = lookupCache[eventCacheKey] ? ++lookupCache[eventCacheKey].total : 0;
var itemIndex = lookupCache[eventCacheKey] ? ++lookupCache[eventCacheKey].total : 0;

if(ii > 0) {
if(itemIndex > 0) {
var staggerClassName = className + '-stagger';
var staggerCacheKey = cacheKey + ' ' + staggerClassName;
var applyClasses = !lookupCache[staggerCacheKey];
Expand Down Expand Up @@ -1113,7 +1117,7 @@ angular.module('ngAnimate', ['ng'])
classes : className + ' ' + activeClassName,
timings : timings,
stagger : stagger,
ii : ii
itemIndex : itemIndex
});

return true;
Expand Down Expand Up @@ -1158,7 +1162,7 @@ angular.module('ngAnimate', ['ng'])
var maxDelayTime = Math.max(timings.transitionDelay, timings.animationDelay) * ONE_SECOND;
var startTime = Date.now();
var css3AnimationEvents = ANIMATIONEND_EVENT + ' ' + TRANSITIONEND_EVENT;
var ii = elementData.ii;
var itemIndex = elementData.itemIndex;

var style = '', appliedStyles = [];
if(timings.transitionDuration > 0) {
Expand All @@ -1171,17 +1175,17 @@ angular.module('ngAnimate', ['ng'])
}
}

if(ii > 0) {
if(itemIndex > 0) {
if(stagger.transitionDelay > 0 && stagger.transitionDuration === 0) {
var delayStyle = timings.transitionDelayStyle;
style += CSS_PREFIX + 'transition-delay: ' +
prepareStaggerDelay(delayStyle, stagger.transitionDelay, ii) + '; ';
prepareStaggerDelay(delayStyle, stagger.transitionDelay, itemIndex) + '; ';
appliedStyles.push(CSS_PREFIX + 'transition-delay');
}

if(stagger.animationDelay > 0 && stagger.animationDuration === 0) {
style += CSS_PREFIX + 'animation-delay: ' +
prepareStaggerDelay(timings.animationDelayStyle, stagger.animationDelay, ii) + '; ';
prepareStaggerDelay(timings.animationDelayStyle, stagger.animationDelay, itemIndex) + '; ';
appliedStyles.push(CSS_PREFIX + 'animation-delay');
}
}
Expand Down
44 changes: 43 additions & 1 deletion test/ngAnimate/animateSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1155,7 +1155,7 @@ describe("ngAnimate", function() {
}));


it("apply a closing timeout to close all pending transitions",
it("should apply a closing timeout to close all pending transitions",
inject(function($animate, $rootScope, $compile, $sniffer, $timeout) {

if (!$sniffer.transitions) return;
Expand All @@ -1174,6 +1174,48 @@ describe("ngAnimate", function() {
expect(element.hasClass('some-class-add-active')).toBe(false);
}));

it("apply a closing timeout with respect to a staggering animation",
inject(function($animate, $rootScope, $compile, $sniffer, $timeout) {

if (!$sniffer.transitions) return;

ss.addRule('.entering-element.ng-enter',
'-webkit-transition:5s linear all;' +
'transition:5s linear all;');

ss.addRule('.entering-element.ng-enter-stagger',
'-webkit-transition-delay:0.5s;' +
'transition-delay:0.5s;');

element = $compile(html('<div></div>'))($rootScope);
var kids = [];
for(var i = 0; i < 5; i++) {
kids.push(angular.element('<div class="entering-element"></div>'));
$animate.enter(kids[i], element);
}
$rootScope.$digest();

$timeout.flush(10); //reflow
expect(element.children().length).toBe(5);

for(var i = 0; i < 5; i++) {
expect(kids[i].hasClass('ng-enter-active')).toBe(true);
}

$timeout.flush(7500);

for(var i = 0; i < 5; i++) {
expect(kids[i].hasClass('ng-enter-active')).toBe(true);
}

//(stagger * index) + (duration + delay) * 150%
$timeout.flush(9500); //0.5 * 4 + 5 * 1.5 = 9500;

for(var i = 0; i < 5; i++) {
expect(kids[i].hasClass('ng-enter-active')).toBe(false);
}
}));


it("should not allow the closing animation to close off a successive animation midway",
inject(function($animate, $rootScope, $compile, $sniffer, $timeout) {
Expand Down

0 comments on commit 66c5250

Please sign in to comment.