Skip to content

Commit d96e19f

Browse files
romiemcburgdorf
authored andcommitted
fix(animation): handle transition-delay property correctly
The code also handles situations with multiple different delay and duration values. E.g. in the following example, the correct duration would be 3 seconds: property | duration | delay height | 1s | 2s left | 2s | 1s opacity | 1s | 2s
1 parent 669d31d commit d96e19f

File tree

3 files changed

+56
-13
lines changed

3 files changed

+56
-13
lines changed

src/Angular.js

+4
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,10 @@ function reverseParams(iteratorFn) {
185185
return function(value, key) { iteratorFn(key, value) };
186186
}
187187

188+
function safelySplitByComma(str){
189+
return isUndefined(str) ? [] : str.split(',');
190+
}
191+
188192
/**
189193
* A consistent way of creating unique IDs in angular. The ID is a sequence of alpha numeric
190194
* characters such as '012ABC'. The reason why we are not using simply a number counter is that

src/ng/animator.js

+22-13
Original file line numberDiff line numberDiff line change
@@ -262,15 +262,19 @@ var $AnimatorProvider = function() {
262262
// keep at 1 for animation dom rerender
263263
$window.setTimeout(beginAnimation, 1);
264264

265-
function getMaxDuration(durationString){
266-
if (isUndefined(durationString)){
267-
return 0;
268-
}
269-
270-
var normalizedValues = map(durationString.split(','), function(val){
271-
return parseFloat(val);
272-
});
273-
return Math.max.apply(null, normalizedValues);
265+
function getMaxDuration(durationString, delayString) {
266+
var durations = safelySplitByComma(durationString),
267+
delays = safelySplitByComma(delayString),
268+
overallTimeSpent = 0;
269+
270+
for (var i = 0, ii = Math.max(durations.length, delays.length); i < ii; i++) {
271+
var combinedDuration = (parseFloat(durations.shift() || 0) + parseFloat(delays.shift() || 0));
272+
if (combinedDuration > overallTimeSpent) {
273+
overallTimeSpent = combinedDuration;
274+
}
275+
}
276+
277+
return overallTimeSpent;
274278
}
275279

276280
function beginAnimation() {
@@ -281,14 +285,19 @@ var $AnimatorProvider = function() {
281285
var vendorTransitionProp = $sniffer.vendorPrefix + 'Transition';
282286
var w3cTransitionProp = 'transition'; //one day all browsers will have this
283287

284-
var durationKey = 'Duration';
285-
var duration = 0;
288+
var durationKey = 'Duration',
289+
delayKey = 'Delay',
290+
duration = 0;
291+
286292
//we want all the styles defined before and after
287293
forEach(element, function(element) {
288294
var globalStyles = $window.getComputedStyle(element) || {};
289295
duration = Math.max(
290-
getMaxDuration(globalStyles[w3cTransitionProp + durationKey]) ||
291-
getMaxDuration(globalStyles[vendorTransitionProp + durationKey]) ||
296+
getMaxDuration(globalStyles[w3cTransitionProp + durationKey],
297+
globalStyles[w3cTransitionProp + delayKey]) ||
298+
299+
getMaxDuration(globalStyles[vendorTransitionProp + durationKey],
300+
globalStyles[vendorTransitionProp + delayKey]) ||
292301
0,
293302
duration);
294303
});

test/ng/animatorSpec.js

+30
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,36 @@ describe("$animator", function() {
335335
expect(element[0].style.display).toBe('');
336336
}));
337337

338+
it("should skip animations if disabled and run when enabled picking the longest specified duration/delay combination",
339+
inject(function($animator, $rootScope, $compile, $sniffer) {
340+
$animator.enabled(false);
341+
element = $compile(html('<div style="' + vendorPrefix +
342+
'transition-duration: 1s, 2000ms, 1s; ' + vendorPrefix +
343+
'transition-delay: 2s, 1000ms, 2s; ' + vendorPrefix +
344+
'transition-property: height, left, opacity">foo</div>'))($rootScope);
345+
346+
var animator = $animator($rootScope, {
347+
ngAnimate : '{show: \'inline-show\'}'
348+
});
349+
350+
element.css('display','none');
351+
expect(element.css('display')).toBe('none');
352+
animator.show(element);
353+
expect(element[0].style.display).toBe('');
354+
355+
$animator.enabled(true);
356+
357+
element.css('display','none');
358+
expect(element.css('display')).toBe('none');
359+
360+
animator.show(element);
361+
if ($sniffer.supportsTransitions) {
362+
window.setTimeout.expect(1).process();
363+
window.setTimeout.expect(3000).process();
364+
}
365+
expect(element[0].style.display).toBe('');
366+
}));
367+
338368
});
339369

340370
it("should throw an error when an invalid ng-animate syntax is provided", inject(function($compile, $rootScope) {

0 commit comments

Comments
 (0)