Skip to content

Commit 5805c51

Browse files
author
Peter Deak
committed
fix(ngAnimate): Correctly retain existing styles while animating, and also ensure that outdated styles aren't restored on completion. Fixes angular#4869.
1 parent 4612705 commit 5805c51

File tree

2 files changed

+37
-15
lines changed

2 files changed

+37
-15
lines changed

src/ngAnimate/animate.js

+10-15
Original file line numberDiff line numberDiff line change
@@ -842,13 +842,6 @@ angular.module('ngAnimate', ['ng'])
842842
}, 10, false);
843843
}
844844

845-
function applyStyle(node, style) {
846-
var oldStyle = node.getAttribute('style') || '';
847-
var newStyle = (oldStyle.length > 0 ? '; ' : '') + style;
848-
node.setAttribute('style', newStyle);
849-
return oldStyle;
850-
}
851-
852845
function getElementAnimationDetails(element, cacheKey) {
853846
var data = cacheKey ? lookupCache[cacheKey] : null;
854847
if(!data) {
@@ -1002,10 +995,9 @@ angular.module('ngAnimate', ['ng'])
1002995
var maxDelayTime = Math.max(timings.transitionDelay, timings.animationDelay) * 1000;
1003996
var startTime = Date.now();
1004997
var css3AnimationEvents = ANIMATIONEND_EVENT + ' ' + TRANSITIONEND_EVENT;
1005-
var formerStyle;
1006998
var ii = data.ii;
1007999

1008-
var applyFallbackStyle, style = '';
1000+
var applyFallbackStyle, style = '', appliedStyles = [];
10091001
if(timings.transitionDuration > 0) {
10101002
node.style[TRANSITION_PROP + PROPERTY_KEY] = '';
10111003

@@ -1015,6 +1007,8 @@ angular.module('ngAnimate', ['ng'])
10151007
var fallbackProperty = $sniffer.msie ? '-ms-zoom' : 'clip';
10161008
style += CSS_PREFIX + 'transition-property: ' + propertyStyle + ', ' + fallbackProperty + '; ';
10171009
style += CSS_PREFIX + 'transition-duration: ' + timings.transitionDurationStyle + ', ' + timings.transitionDuration + 's; ';
1010+
appliedStyles.push(CSS_PREFIX + 'transition-property');
1011+
appliedStyles.push(CSS_PREFIX + 'transition-duration');
10181012
}
10191013
}
10201014

@@ -1027,16 +1021,19 @@ angular.module('ngAnimate', ['ng'])
10271021

10281022
style += CSS_PREFIX + 'transition-delay: ' +
10291023
prepareStaggerDelay(delayStyle, stagger.transitionDelay, ii) + '; ';
1024+
appliedStyles.push(CSS_PREFIX + 'transition-delay');
10301025
}
10311026

10321027
if(stagger.animationDelay > 0 && stagger.animationDuration === 0) {
10331028
style += CSS_PREFIX + 'animation-delay: ' +
10341029
prepareStaggerDelay(timings.animationDelayStyle, stagger.animationDelay, ii) + '; ';
1030+
appliedStyles.push(CSS_PREFIX + 'animation-delay');
10351031
}
10361032
}
10371033

1038-
if(style.length > 0) {
1039-
formerStyle = applyStyle(node, style);
1034+
if(appliedStyles.length > 0) {
1035+
var oldStyle = node.getAttribute('style') || '';
1036+
node.setAttribute('style', oldStyle + '; ' + style);
10401037
}
10411038

10421039
element.on(css3AnimationEvents, onAnimationProgress);
@@ -1049,10 +1046,8 @@ angular.module('ngAnimate', ['ng'])
10491046
element.off(css3AnimationEvents, onAnimationProgress);
10501047
element.removeClass(activeClassName);
10511048
animateClose(element, className);
1052-
if(formerStyle != null) {
1053-
formerStyle.length > 0 ?
1054-
node.setAttribute('style', formerStyle) :
1055-
node.removeAttribute('style');
1049+
for (var i in appliedStyles) {
1050+
node.style[appliedStyles[i]] = "";
10561051
}
10571052
};
10581053

test/ngAnimate/animateSpec.js

+27
Original file line numberDiff line numberDiff line change
@@ -975,6 +975,33 @@ describe("ngAnimate", function() {
975975
expect(element).toBeShown();
976976
}));
977977

978+
it("should NOT overwrite styles with outdated values when animation completes",
979+
inject(function($animate, $rootScope, $compile, $sniffer, $timeout) {
980+
981+
var style = '-webkit-transition-duration: 1s, 2000ms, 1s;' +
982+
'-webkit-transition-property: height, left, opacity;' +
983+
'transition-duration: 1s, 2000ms, 1s;' +
984+
'transition-property: height, left, opacity;';
985+
986+
ss.addRule('.ng-hide-add', style);
987+
ss.addRule('.ng-hide-remove', style);
988+
989+
element = $compile(html('<div style="width: 100px">foo</div>'))($rootScope);
990+
element.addClass('ng-hide');
991+
992+
$animate.removeClass(element, 'ng-hide');
993+
994+
if ($sniffer.transitions) {
995+
$timeout.flush();
996+
var now = Date.now();
997+
browserTrigger(element,'transitionend', { timeStamp: now + 1000, elapsedTime: 1 });
998+
browserTrigger(element,'transitionend', { timeStamp: now + 1000, elapsedTime: 1 });
999+
element.css('width', '200px');
1000+
browserTrigger(element,'transitionend', { timeStamp: now + 2000, elapsedTime: 2 });
1001+
expect(element.css('width')).toBe("200px");
1002+
}
1003+
}));
1004+
9781005
it("should animate for the highest duration",
9791006
inject(function($animate, $rootScope, $compile, $sniffer, $timeout) {
9801007
var style = '-webkit-transition:1s linear all 2s;' +

0 commit comments

Comments
 (0)