diff options
| author | Matias Niemelä | 2014-01-11 23:44:43 -0500 | 
|---|---|---|
| committer | Matias Niemelä | 2014-01-14 13:20:50 -0500 | 
| commit | ed53100a0dbc9119d5dfc8b7248845d4f6989df2 (patch) | |
| tree | e2190d53e3489259bfba4d4a67355745e1a75d3f | |
| parent | 6df598d9f5a52085b90085b41631ef34f3edc386 (diff) | |
| download | angular.js-ed53100a0dbc9119d5dfc8b7248845d4f6989df2.tar.bz2 | |
fix($animate): ensure the final closing timeout respects staggering animations
| -rw-r--r-- | src/ngAnimate/animate.js | 22 | ||||
| -rw-r--r-- | test/ngAnimate/animateSpec.js | 44 | 
2 files changed, 56 insertions, 10 deletions
| diff --git a/src/ngAnimate/animate.js b/src/ngAnimate/animate.js index f3a86f82..22a9dde7 100644 --- a/src/ngAnimate/animate.js +++ b/src/ngAnimate/animate.js @@ -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 @@ -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]; @@ -1113,7 +1117,7 @@ angular.module('ngAnimate', ['ng'])            classes : className + ' ' + activeClassName,            timings : timings,            stagger : stagger, -          ii : ii +          itemIndex : itemIndex          });          return true; @@ -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) { @@ -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');            }          } diff --git a/test/ngAnimate/animateSpec.js b/test/ngAnimate/animateSpec.js index 2a83f2d5..1bb818af 100644 --- a/test/ngAnimate/animateSpec.js +++ b/test/ngAnimate/animateSpec.js @@ -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; @@ -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) { | 
