mirror of
https://github.com/zhigang1992/angular.js.git
synced 2026-01-12 22:45:52 +08:00
fix($animate): clear the GCS cache even when no animation is detected
$animate will cache subsequent calls to GCS in the event that the element with the same CSS classes and the same parentNode is being animated. Once the animation is started then $animate waits for one rAF before flushing the GCS lookup cache. Prior to this fix, if GCS was unable to detect any transitions or keyframes on the element then it would simply close the animation, but it would not trigger the rAF code to flush the cache. This issue caused a bug which made it difficult to detect why certain animations are not allowed to fire if the element didn't contain any CSS-based animations beforehand. Closes #8813
This commit is contained in:
@@ -1419,6 +1419,16 @@ angular.module('ngAnimate', ['ng'])
|
||||
var parentCounter = 0;
|
||||
var animationReflowQueue = [];
|
||||
var cancelAnimationReflow;
|
||||
function clearCacheAfterReflow() {
|
||||
if (!cancelAnimationReflow) {
|
||||
cancelAnimationReflow = $$animateReflow(function() {
|
||||
animationReflowQueue = [];
|
||||
cancelAnimationReflow = null;
|
||||
lookupCache = {};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function afterReflow(element, callback) {
|
||||
if (cancelAnimationReflow) {
|
||||
cancelAnimationReflow();
|
||||
@@ -1764,6 +1774,7 @@ angular.module('ngAnimate', ['ng'])
|
||||
//to perform at all
|
||||
var preReflowCancellation = animateBefore(animationEvent, element, className);
|
||||
if (!preReflowCancellation) {
|
||||
clearCacheAfterReflow();
|
||||
animationComplete();
|
||||
return;
|
||||
}
|
||||
@@ -1820,6 +1831,7 @@ angular.module('ngAnimate', ['ng'])
|
||||
afterReflow(element, animationCompleted);
|
||||
return cancellationMethod;
|
||||
}
|
||||
clearCacheAfterReflow();
|
||||
animationCompleted();
|
||||
},
|
||||
|
||||
@@ -1829,6 +1841,7 @@ angular.module('ngAnimate', ['ng'])
|
||||
afterReflow(element, animationCompleted);
|
||||
return cancellationMethod;
|
||||
}
|
||||
clearCacheAfterReflow();
|
||||
animationCompleted();
|
||||
},
|
||||
|
||||
@@ -1838,6 +1851,7 @@ angular.module('ngAnimate', ['ng'])
|
||||
afterReflow(element, animationCompleted);
|
||||
return cancellationMethod;
|
||||
}
|
||||
clearCacheAfterReflow();
|
||||
animationCompleted();
|
||||
},
|
||||
|
||||
|
||||
@@ -3757,6 +3757,64 @@ describe("ngAnimate", function() {
|
||||
expect(inner.hasClass('on-add-active')).toBe(false);
|
||||
}));
|
||||
|
||||
it("should reset the getComputedStyle lookup cache even when no animation is found",
|
||||
inject(function($compile, $rootScope, $animate, $sniffer, $document) {
|
||||
|
||||
if (!$sniffer.transitions) return;
|
||||
|
||||
$animate.enabled();
|
||||
|
||||
var html = '<div>' +
|
||||
' <div class="toggle" ng-if="onOff">On or Off</div>' +
|
||||
'</div>';
|
||||
|
||||
ss.addRule('.activated .toggle', '-webkit-transition:1s linear all;' +
|
||||
'transition:1s linear all;');
|
||||
|
||||
var child, element = $compile(html)($rootScope);
|
||||
|
||||
$rootElement.append(element);
|
||||
jqLite($document[0].body).append($rootElement);
|
||||
|
||||
$rootScope.onOff = true;
|
||||
$rootScope.$digest();
|
||||
|
||||
child = element.find('div');
|
||||
expect(child).not.toHaveClass('ng-enter');
|
||||
expect(child.parent()[0]).toEqual(element[0]);
|
||||
$animate.triggerReflow();
|
||||
|
||||
$rootScope.onOff = false;
|
||||
$rootScope.$digest();
|
||||
|
||||
child = element.find('div');
|
||||
expect(child.parent().length).toBe(0);
|
||||
$animate.triggerReflow();
|
||||
|
||||
element.addClass('activated');
|
||||
$rootScope.$digest();
|
||||
$animate.triggerReflow();
|
||||
|
||||
$rootScope.onOff = true;
|
||||
$rootScope.$digest();
|
||||
|
||||
child = element.find('div');
|
||||
expect(child).toHaveClass('ng-enter');
|
||||
$animate.triggerReflow();
|
||||
expect(child).toHaveClass('ng-enter-active');
|
||||
|
||||
browserTrigger(child, 'transitionend',
|
||||
{ timeStamp: Date.now() + 1000, elapsedTime: 2000 });
|
||||
|
||||
$animate.triggerCallbacks();
|
||||
|
||||
$rootScope.onOff = false;
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(child).toHaveClass('ng-leave');
|
||||
$animate.triggerReflow();
|
||||
expect(child).toHaveClass('ng-leave-active');
|
||||
}));
|
||||
|
||||
it("should cancel and perform the dom operation only after the reflow has run",
|
||||
inject(function($compile, $rootScope, $animate, $sniffer) {
|
||||
|
||||
Reference in New Issue
Block a user