Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

fix(ngAnimate): ensure that delays are always considered before an animation closes #4150

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 21 additions & 6 deletions src/ngAnimate/animate.js
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,7 @@ angular.module('ngAnimate', ['ng'])

var durationKey = 'Duration',
propertyKey = 'Property',
delayKey = 'Delay',
animationIterationCountKey = 'IterationCount',
ELEMENT_NODE = 1;

Expand Down Expand Up @@ -593,6 +594,12 @@ angular.module('ngAnimate', ['ng'])
if (element.nodeType == ELEMENT_NODE) {
var elementStyles = $window.getComputedStyle(element) || {};

var transitionDelay = Math.max(parseMaxTime(elementStyles[w3cTransitionProp + delayKey]),
parseMaxTime(elementStyles[vendorTransitionProp + delayKey]));

var animationDelay = Math.max(parseMaxTime(elementStyles[w3cAnimationProp + delayKey]),
parseMaxTime(elementStyles[vendorAnimationProp + delayKey]));

var transitionDuration = Math.max(parseMaxTime(elementStyles[w3cTransitionProp + durationKey]),
parseMaxTime(elementStyles[vendorTransitionProp + durationKey]));

Expand All @@ -605,17 +612,18 @@ angular.module('ngAnimate', ['ng'])
1);
}

transitionTime = Math.max(transitionDuration, transitionTime);
animationTime = Math.max(animationDuration, animationTime);
transitionTime = Math.max(transitionDelay + transitionDuration, transitionTime);
animationTime = Math.max(animationDelay + animationDuration, animationTime);
}
});

/* there is no point in performing a reflow if the animation
timeout is empty (this would cause a flicker bug normally
in the page */
var totalTime = Math.max(transitionTime,animationTime);
if(totalTime > 0) {
var node = element[0];
var maxTime = Math.max(transitionTime,animationTime) * 1000;
if(maxTime > 0) {
var node = element[0],
startTime = Date.now();

//temporarily disable the transition so that the enter styles
//don't animate twice (this is here to avoid a bug in Chrome/FF).
Expand Down Expand Up @@ -659,7 +667,14 @@ angular.module('ngAnimate', ['ng'])
}

function onAnimationProgress(event) {
(event.elapsedTime || (event.originalEvent && event.originalEvent.elapsedTime)) >= totalTime && done();
event.stopPropagation();
var ev = event.originalEvent || event;
/* $manualTimeStamp is a mocked timeStamp value which is set
* within browserTrigger(). This is only here so that tests can
* mock animations properly. Real events fallback to event.timeStamp. */
if((ev.$manualTimeStamp || ev.timeStamp) - startTime >= maxTime) {
done();
}
}

function parseMaxTime(str) {
Expand Down
9 changes: 7 additions & 2 deletions src/ngScenario/browserTrigger.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@
}
catch(e) {
evnt = document.createEvent('TransitionEvent');
evnt.initTransitionEvent(eventType, null, null, null, eventData.elapsedTime);
evnt.initTransitionEvent(eventType, null, null, null, eventData.elapsedTime || 0);
}
}
}
Expand All @@ -116,7 +116,7 @@
}
catch(e) {
evnt = document.createEvent('AnimationEvent');
evnt.initAnimationEvent(eventType, null, null, null, eventData.elapsedTime);
evnt.initAnimationEvent(eventType, null, null, null, eventData.elapsedTime || 0);
}
}
}
Expand All @@ -128,6 +128,11 @@
pressed('shift'), pressed('meta'), 0, element);
}

/* we're unable to change the timeStamp value directly so this
* is only here to allow for testing where the timeStamp value is
* read */
evnt.$manualTimeStamp = eventData.timeStamp;

if(!evnt) return;

var originalPreventDefault = evnt.preventDefault,
Expand Down
Loading