diff --git a/src/Angular.js b/src/Angular.js index bf64c6c27de5..945849757182 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -185,6 +185,10 @@ function reverseParams(iteratorFn) { return function(value, key) { iteratorFn(key, value) }; } +function safelySplitByComma(str){ + return isUndefined(str) ? [] : str.split(','); +} + /** * A consistent way of creating unique IDs in angular. The ID is a sequence of alpha numeric * characters such as '012ABC'. The reason why we are not using simply a number counter is that diff --git a/src/ng/animator.js b/src/ng/animator.js index 536c93c13b7d..c7224981bfff 100644 --- a/src/ng/animator.js +++ b/src/ng/animator.js @@ -261,6 +261,21 @@ var $AnimatorProvider = function() { // $window.setTimeout(beginAnimation, 0); this was causing the element not to animate // keep at 1 for animation dom rerender $window.setTimeout(beginAnimation, 1); + + function getMaxDuration(durationString, delayString) { + var durations = safelySplitByComma(durationString), + delays = safelySplitByComma(delayString), + overallTimeSpent = 0; + + for (var i = 0, ii = Math.max(durations.length, delays.length); i < ii; i++) { + var combinedDuration = (parseFloat(durations.shift() || 0) + parseFloat(delays.shift() || 0)); + if (combinedDuration > overallTimeSpent) { + overallTimeSpent = combinedDuration; + } + } + + return overallTimeSpent; + } function beginAnimation() { element.addClass(startClass); @@ -270,14 +285,19 @@ var $AnimatorProvider = function() { var vendorTransitionProp = $sniffer.vendorPrefix + 'Transition'; var w3cTransitionProp = 'transition'; //one day all browsers will have this - var durationKey = 'Duration'; - var duration = 0; + var durationKey = 'Duration', + delayKey = 'Delay', + duration = 0; + //we want all the styles defined before and after forEach(element, function(element) { var globalStyles = $window.getComputedStyle(element) || {}; duration = Math.max( - parseFloat(globalStyles[w3cTransitionProp + durationKey]) || - parseFloat(globalStyles[vendorTransitionProp + durationKey]) || + getMaxDuration(globalStyles[w3cTransitionProp + durationKey], + globalStyles[w3cTransitionProp + delayKey]) || + + getMaxDuration(globalStyles[vendorTransitionProp + durationKey], + globalStyles[vendorTransitionProp + delayKey]) || 0, duration); }); diff --git a/test/ng/animatorSpec.js b/test/ng/animatorSpec.js index 1b393e9114f3..0911b36d7da1 100644 --- a/test/ng/animatorSpec.js +++ b/test/ng/animatorSpec.js @@ -309,10 +309,10 @@ describe("$animator", function() { }) }); - it("should skip animations if disabled and run when enabled", - inject(function($animator, $rootScope, $compile, $sniffer) { + it("should skip animations if disabled and run when enabled picking the longest specified duration", + inject(function($animator, $rootScope, $compile, $sniffer) { $animator.enabled(false); - element = $compile(html('
1
'))($rootScope); + element = $compile(html('
foo
'))($rootScope); var animator = $animator($rootScope, { ngAnimate : '{show: \'inline-show\'}' }); @@ -330,10 +330,41 @@ describe("$animator", function() { animator.show(element); if ($sniffer.supportsTransitions) { window.setTimeout.expect(1).process(); - window.setTimeout.expect(1000).process(); + window.setTimeout.expect(2000).process(); } expect(element[0].style.display).toBe(''); })); + + it("should skip animations if disabled and run when enabled picking the longest specified duration/delay combination", + inject(function($animator, $rootScope, $compile, $sniffer) { + $animator.enabled(false); + element = $compile(html('
foo
'))($rootScope); + + var animator = $animator($rootScope, { + ngAnimate : '{show: \'inline-show\'}' + }); + + element.css('display','none'); + expect(element.css('display')).toBe('none'); + animator.show(element); + expect(element[0].style.display).toBe(''); + + $animator.enabled(true); + + element.css('display','none'); + expect(element.css('display')).toBe('none'); + + animator.show(element); + if ($sniffer.supportsTransitions) { + window.setTimeout.expect(1).process(); + window.setTimeout.expect(3000).process(); + } + expect(element[0].style.display).toBe(''); + })); + }); it("should throw an error when an invalid ng-animate syntax is provided", inject(function($compile, $rootScope) {