diff --git a/src/ng/raf.js b/src/ng/raf.js index a487b006f606..f8bf0839b908 100644 --- a/src/ng/raf.js +++ b/src/ng/raf.js @@ -10,7 +10,7 @@ function $$RAFProvider() { //rAF $window.webkitCancelRequestAnimationFrame; var rafSupported = !!requestAnimationFrame; - var rafFn = rafSupported + var raf = rafSupported ? function(fn) { var id = requestAnimationFrame(fn); return function() { @@ -24,46 +24,8 @@ function $$RAFProvider() { //rAF }; }; - queueFn.supported = rafSupported; + raf.supported = rafSupported; - var cancelLastRAF; - var taskCount = 0; - var taskQueue = []; - return queueFn; - - function flush() { - for (var i = 0; i < taskQueue.length; i++) { - var task = taskQueue[i]; - if (task) { - taskQueue[i] = null; - task(); - } - } - taskCount = taskQueue.length = 0; - } - - function queueFn(asyncFn) { - var index = taskQueue.length; - - taskCount++; - taskQueue.push(asyncFn); - - if (index === 0) { - cancelLastRAF = rafFn(flush); - } - - return function cancelQueueFn() { - if (index >= 0) { - taskQueue[index] = null; - index = null; - - if (--taskCount === 0 && cancelLastRAF) { - cancelLastRAF(); - cancelLastRAF = null; - taskQueue.length = 0; - } - } - }; - } + return raf; }]; } diff --git a/src/ngAnimate/animateJs.js b/src/ngAnimate/animateJs.js index 9f38bf14bd92..ef356cb2a30e 100644 --- a/src/ngAnimate/animateJs.js +++ b/src/ngAnimate/animateJs.js @@ -5,8 +5,8 @@ // by the time... var $$AnimateJsProvider = ['$animateProvider', function($animateProvider) { - this.$get = ['$injector', '$$AnimateRunner', '$$rAFMutex', '$$jqLite', - function($injector, $$AnimateRunner, $$rAFMutex, $$jqLite) { + this.$get = ['$injector', '$$AnimateRunner', '$$jqLite', + function($injector, $$AnimateRunner, $$jqLite) { var applyAnimationClasses = applyAnimationClassesFactory($$jqLite); // $animateJs(element, 'enter'); diff --git a/src/ngAnimate/animateRunner.js b/src/ngAnimate/animateRunner.js index 65b1e8d48030..1a2e6264a5e5 100644 --- a/src/ngAnimate/animateRunner.js +++ b/src/ngAnimate/animateRunner.js @@ -1,18 +1,33 @@ 'use strict'; -var $$rAFMutexFactory = ['$$rAF', function($$rAF) { +var $$AnimateAsyncRunFactory = ['$$rAF', function($$rAF) { + var waitQueue = []; + + function waitForTick(fn) { + waitQueue.push(fn); + if (waitQueue.length > 1) return; + $$rAF(function() { + for (var i = 0; i < waitQueue.length; i++) { + waitQueue[i](); + } + waitQueue = []; + }); + } + return function() { var passed = false; - $$rAF(function() { + waitForTick(function() { passed = true; }); - return function(fn) { - passed ? fn() : $$rAF(fn); + return function(callback) { + passed ? callback() : waitForTick(callback); }; }; }]; -var $$AnimateRunnerFactory = ['$q', '$$rAFMutex', function($q, $$rAFMutex) { +var $$AnimateRunnerFactory = ['$q', '$sniffer', '$$animateAsyncRun', + function($q, $sniffer, $$animateAsyncRun) { + var INITIAL_STATE = 0; var DONE_PENDING_STATE = 1; var DONE_COMPLETE_STATE = 2; @@ -57,7 +72,7 @@ var $$AnimateRunnerFactory = ['$q', '$$rAFMutex', function($q, $$rAFMutex) { this.setHost(host); this._doneCallbacks = []; - this._runInAnimationFrame = $$rAFMutex(); + this._runInAnimationFrame = $$animateAsyncRun(); this._state = 0; } diff --git a/src/ngAnimate/module.js b/src/ngAnimate/module.js index 5b37e09e4bc1..2558087be939 100644 --- a/src/ngAnimate/module.js +++ b/src/ngAnimate/module.js @@ -3,7 +3,7 @@ /* global angularAnimateModule: true, $$BodyProvider, - $$rAFMutexFactory, + $$AnimateAsyncRunFactory, $$AnimateChildrenDirective, $$AnimateRunnerFactory, $$AnimateQueueProvider, @@ -745,9 +745,8 @@ angular.module('ngAnimate', []) .directive('ngAnimateChildren', $$AnimateChildrenDirective) - .factory('$$rAFMutex', $$rAFMutexFactory) - .factory('$$AnimateRunner', $$AnimateRunnerFactory) + .factory('$$animateAsyncRun', $$AnimateAsyncRunFactory) .provider('$$animateQueue', $$AnimateQueueProvider) .provider('$$animation', $$AnimationProvider) diff --git a/src/ngMock/angular-mocks.js b/src/ngMock/angular-mocks.js index 12fb19c40b31..c90c343ca034 100644 --- a/src/ngMock/angular-mocks.js +++ b/src/ngMock/angular-mocks.js @@ -763,25 +763,50 @@ angular.mock.animate = angular.module('ngAnimateMock', ['ng']) return reflowFn; }); - $provide.decorator('$animate', ['$delegate', '$timeout', '$browser', '$$rAF', '$$forceReflow', - function($delegate, $timeout, $browser, $$rAF, $$forceReflow) { + $provide.factory('$$animateAsyncRun', function() { + var queue = []; + var queueFn = function() { + return function(fn) { + queue.push(fn); + }; + }; + queueFn.flush = function() { + if (queue.length === 0) return false; + + for (var i = 0; i < queue.length; i++) { + queue[i](); + } + queue = []; + + return true; + }; + return queueFn; + }); + + $provide.decorator('$animate', ['$delegate', '$timeout', '$browser', '$$rAF', '$$forceReflow', '$$animateAsyncRun', + function($delegate, $timeout, $browser, $$rAF, $$forceReflow, $$animateAsyncRun) { var animate = { queue: [], cancel: $delegate.cancel, + on: $delegate.on, + off: $delegate.off, + pin: $delegate.pin, get reflows() { return $$forceReflow.totalReflows; }, enabled: $delegate.enabled, - triggerCallbackEvents: function() { - $$rAF.flush(); - }, - triggerCallbackPromise: function() { - $timeout.flush(0); - }, - triggerCallbacks: function() { - this.triggerCallbackEvents(); - this.triggerCallbackPromise(); + flush: function() { + var rafsFlushed = false; + if ($$rAF.queue.length) { + $$rAF.flush(); + rafsFlushed = true; + } + + var animatorsFlushed = $$animateAsyncRun.flush(); + if (!rafsFlushed && !animatorsFlushed) { + throw new Error('No pending animations ready to be closed or flushed'); + } } }; @@ -1733,28 +1758,28 @@ angular.mock.$TimeoutDecorator = ['$delegate', '$browser', function($delegate, $ }]; angular.mock.$RAFDecorator = ['$delegate', function($delegate) { - var queue = []; var rafFn = function(fn) { - var index = queue.length; - queue.push(fn); + var index = rafFn.queue.length; + rafFn.queue.push(fn); return function() { - queue.splice(index, 1); + rafFn.queue.splice(index, 1); }; }; + rafFn.queue = []; rafFn.supported = $delegate.supported; rafFn.flush = function() { - if (queue.length === 0) { + if (rafFn.queue.length === 0) { throw new Error('No rAF callbacks present'); } - var length = queue.length; + var length = rafFn.queue.length; for (var i = 0; i < length; i++) { - queue[i](); + rafFn.queue[i](); } - queue = queue.slice(i); + rafFn.queue = rafFn.queue.slice(i); }; return rafFn; diff --git a/test/ng/directive/ngClassSpec.js b/test/ng/directive/ngClassSpec.js index 28a49a6bb364..a188ba129356 100644 --- a/test/ng/directive/ngClassSpec.js +++ b/test/ng/directive/ngClassSpec.js @@ -468,7 +468,7 @@ describe('ngClass animations', function() { }; }); }); - inject(function($compile, $rootScope, $browser, $rootElement, $animate, $timeout, $$body, $$rAF) { + inject(function($compile, $rootScope, $browser, $rootElement, $animate, $timeout, $$body) { $animate.enabled(true); $rootScope.val = 'crazy'; @@ -488,7 +488,7 @@ describe('ngClass animations', function() { expect(enterComplete).toBe(false); $rootScope.$digest(); - $$rAF.flush(); + $animate.flush(); $rootScope.$digest(); expect(element.hasClass('crazy')).toBe(true); diff --git a/test/ng/directive/ngIncludeSpec.js b/test/ng/directive/ngIncludeSpec.js index 9cecde9825a8..a9725f8769ee 100644 --- a/test/ng/directive/ngIncludeSpec.js +++ b/test/ng/directive/ngIncludeSpec.js @@ -428,9 +428,11 @@ describe('ngInclude', function() { }); expect(autoScrollSpy).not.toHaveBeenCalled(); - expect($animate.queue.shift().event).toBe('enter'); - $animate.triggerCallbacks(); + $animate.flush(); + $rootScope.$digest(); + + expect($animate.queue.shift().event).toBe('enter'); expect(autoScrollSpy).toHaveBeenCalledOnce(); })); @@ -446,7 +448,6 @@ describe('ngInclude', function() { }); expect($animate.queue.shift().event).toBe('enter'); - $animate.triggerCallbacks(); $rootScope.$apply(function() { $rootScope.tpl = 'another.html'; @@ -455,7 +456,6 @@ describe('ngInclude', function() { expect($animate.queue.shift().event).toBe('leave'); expect($animate.queue.shift().event).toBe('enter'); - $animate.triggerCallbacks(); $rootScope.$apply(function() { $rootScope.tpl = 'template.html'; @@ -464,7 +464,9 @@ describe('ngInclude', function() { expect($animate.queue.shift().event).toBe('leave'); expect($animate.queue.shift().event).toBe('enter'); - $animate.triggerCallbacks(); + + $animate.flush(); + $rootScope.$digest(); expect(autoScrollSpy).toHaveBeenCalled(); expect(autoScrollSpy.callCount).toBe(3); @@ -480,7 +482,6 @@ describe('ngInclude', function() { }); expect($animate.queue.shift().event).toBe('enter'); - $animate.triggerCallbacks(); expect(autoScrollSpy).not.toHaveBeenCalled(); })); @@ -496,7 +497,6 @@ describe('ngInclude', function() { }); expect($animate.queue.shift().event).toBe('enter'); - $animate.triggerCallbacks(); $rootScope.$apply(function() { $rootScope.tpl = 'template.html'; @@ -518,7 +518,9 @@ describe('ngInclude', function() { $rootScope.$apply("tpl = 'template.html'"); expect($animate.queue.shift().event).toBe('enter'); - $animate.triggerCallbacks(); + + $animate.flush(); + $rootScope.$digest(); expect(autoScrollSpy).toHaveBeenCalledOnce(); } diff --git a/test/ng/directive/ngRepeatSpec.js b/test/ng/directive/ngRepeatSpec.js index 0c7070fb5e6d..13f2117b282d 100644 --- a/test/ng/directive/ngRepeatSpec.js +++ b/test/ng/directive/ngRepeatSpec.js @@ -1462,7 +1462,7 @@ describe('ngRepeat animations', function() { })); it('should not change the position of the block that is being animated away via a leave animation', - inject(function($compile, $rootScope, $animate, $document, $window, $sniffer, $timeout, $$rAF) { + inject(function($compile, $rootScope, $animate, $document, $window, $sniffer, $timeout) { if (!$sniffer.transitions) return; var item; @@ -1487,7 +1487,7 @@ describe('ngRepeat animations', function() { $rootScope.$digest(); expect(element.text()).toBe('123'); // the original order should be preserved - $$rAF.flush(); + $animate.flush(); $timeout.flush(1500); // 1s * 1.5 closing buffer expect(element.text()).toBe('13'); } finally { diff --git a/test/ng/rafSpec.js b/test/ng/rafSpec.js index e700d392aae4..04ac6de211bc 100644 --- a/test/ng/rafSpec.js +++ b/test/ng/rafSpec.js @@ -31,46 +31,6 @@ describe('$$rAF', function() { expect(present).toBe(true); })); - it('should only consume only one RAF if multiple async functions are registered before the first frame kicks in', inject(function($$rAF) { - if (!$$rAF.supported) return; - - //we need to create our own injector to work around the ngMock overrides - var rafLog = []; - var injector = createInjector(['ng', function($provide) { - $provide.value('$window', { - location: window.location, - history: window.history, - webkitRequestAnimationFrame: function(fn) { - rafLog.push(fn); - } - }); - }]); - - $$rAF = injector.get('$$rAF'); - - var log = []; - function logFn() { - log.push(log.length); - } - - $$rAF(logFn); - $$rAF(logFn); - $$rAF(logFn); - - expect(log).toEqual([]); - expect(rafLog.length).toBe(1); - - rafLog[0](); - - expect(log).toEqual([0,1,2]); - expect(rafLog.length).toBe(1); - - $$rAF(logFn); - - expect(log).toEqual([0,1,2]); - expect(rafLog.length).toBe(2); - })); - describe('$timeout fallback', function() { it("it should use a $timeout incase native rAF isn't suppored", function() { var timeoutSpy = jasmine.createSpy('callback'); diff --git a/test/ngAnimate/animateCssDriverSpec.js b/test/ngAnimate/animateCssDriverSpec.js index fc4f56bc62a2..62184a7893eb 100644 --- a/test/ngAnimate/animateCssDriverSpec.js +++ b/test/ngAnimate/animateCssDriverSpec.js @@ -3,6 +3,7 @@ describe("ngAnimate $$animateCssDriver", function() { beforeEach(module('ngAnimate')); + beforeEach(module('ngAnimateMock')); function int(x) { return parseInt(x, 10); @@ -414,7 +415,7 @@ describe("ngAnimate $$animateCssDriver", function() { })); it("should then do an addClass('ng-anchor-in') animation on the cloned anchor and remove the old class", - inject(function($rootElement, $$rAF) { + inject(function($rootElement) { var fromAnchor = jqLite('
'); from.append(fromAnchor); @@ -434,7 +435,6 @@ describe("ngAnimate $$animateCssDriver", function() { }).start(); captureLog.pop().runner.end(); - $$rAF.flush(); var anchorDetails = captureLog.pop().args[1]; expect(anchorDetails.removeClass.trim()).toBe('ng-anchor-out'); @@ -464,7 +464,7 @@ describe("ngAnimate $$animateCssDriver", function() { }); }); - inject(function($rootElement, $$rAF) { + inject(function($rootElement, $animate) { var fromAnchor = jqLite(''); from.append(fromAnchor); var toAnchor = jqLite(''); @@ -488,7 +488,7 @@ describe("ngAnimate $$animateCssDriver", function() { expect(animationStarted).toBe(expectedClass); runner.end(); - $$rAF.flush(); + $animate.flush(); expect(complete).toBe(true); }); }); @@ -552,7 +552,7 @@ describe("ngAnimate $$animateCssDriver", function() { expect(int(fromStyles.left)).toBeGreaterThan(149); })); - it("should append a `px` value for all seeded animation styles", inject(function($rootElement, $$rAF) { + it("should append a `px` value for all seeded animation styles", inject(function($rootElement) { ss.addRule('.starting-element', 'width:10px; height:20px; display:inline-block;'); var fromAnchor = jqLite(''); from.append(fromAnchor); @@ -614,7 +613,6 @@ describe("ngAnimate $$animateCssDriver", function() { // the out animation goes first captureLog.pop().runner.end(); - $$rAF.flush(); var anchorDetails = captureLog.pop().args[1]; expect(anchorDetails.removeClass).toMatch(/\bout\b/); @@ -623,7 +621,7 @@ describe("ngAnimate $$animateCssDriver", function() { })); it("should add the `ng-anchor` class to the cloned anchor element", - inject(function($rootElement, $$rAF) { + inject(function($rootElement) { var fromAnchor = jqLite(''); from.append(fromAnchor); @@ -647,7 +645,7 @@ describe("ngAnimate $$animateCssDriver", function() { })); it("should add and remove the `ng-animate-shim` class on the in anchor element during the animation", - inject(function($rootElement, $$rAF) { + inject(function($rootElement) { var fromAnchor = jqLite(''); from.append(fromAnchor); @@ -670,14 +668,13 @@ describe("ngAnimate $$animateCssDriver", function() { // the out animation goes first captureLog.pop().runner.end(); - $$rAF.flush(); captureLog.pop().runner.end(); expect(fromAnchor).not.toHaveClass('ng-animate-shim'); })); it("should add and remove the `ng-animate-shim` class on the out anchor element during the animation", - inject(function($rootElement, $$rAF) { + inject(function($rootElement) { var fromAnchor = jqLite(''); from.append(fromAnchor); @@ -700,7 +697,6 @@ describe("ngAnimate $$animateCssDriver", function() { // the out animation goes first captureLog.pop().runner.end(); - $$rAF.flush(); expect(toAnchor).toHaveClass('ng-animate-shim'); captureLog.pop().runner.end(); @@ -709,7 +705,7 @@ describe("ngAnimate $$animateCssDriver", function() { })); it("should create the cloned anchor with all of the classes from the from anchor element", - inject(function($rootElement, $$rAF) { + inject(function($rootElement) { var fromAnchor = jqLite(''); from.append(fromAnchor); @@ -733,7 +729,7 @@ describe("ngAnimate $$animateCssDriver", function() { })); it("should remove the classes of the starting anchor from the cloned anchor node during the in animation and also add the classes of the destination anchor within the same animation", - inject(function($rootElement, $$rAF) { + inject(function($rootElement) { var fromAnchor = jqLite(''); from.append(fromAnchor); @@ -754,7 +750,6 @@ describe("ngAnimate $$animateCssDriver", function() { // the out animation goes first captureLog.pop().runner.end(); - $$rAF.flush(); var anchorDetails = captureLog.pop().args[1]; var removedClasses = anchorDetails.removeClass.split(' '); @@ -765,7 +760,7 @@ describe("ngAnimate $$animateCssDriver", function() { })); it("should not attempt to add/remove any classes that contain a `ng-` prefix", - inject(function($rootElement, $$rAF) { + inject(function($rootElement) { var fromAnchor = jqLite(''); from.append(fromAnchor); @@ -786,7 +781,6 @@ describe("ngAnimate $$animateCssDriver", function() { // the out animation goes first captureLog.pop().runner.end(); - $$rAF.flush(); var inAnimation = captureLog.pop(); var details = inAnimation.args[1]; @@ -802,7 +796,7 @@ describe("ngAnimate $$animateCssDriver", function() { })); it("should not remove any shared CSS classes between the starting and destination anchor element during the in animation", - inject(function($rootElement, $$rAF) { + inject(function($rootElement) { var fromAnchor = jqLite(''); from.append(fromAnchor); @@ -823,7 +817,6 @@ describe("ngAnimate $$animateCssDriver", function() { // the out animation goes first captureLog.pop().runner.end(); - $$rAF.flush(); var inAnimation = captureLog.pop(); var clonedAnchor = inAnimation.element; @@ -851,7 +844,7 @@ describe("ngAnimate $$animateCssDriver", function() { })); it("should continue the anchor animation by seeding the to styles based on where the final anchor element will be positioned", - inject(function($rootElement, $$rAF) { + inject(function($rootElement) { ss.addRule('.ending-element', 'width:9999px; height:6666px; display:inline-block;'); var fromAnchor = jqLite(''); @@ -874,7 +867,6 @@ describe("ngAnimate $$animateCssDriver", function() { }).start(); captureLog.pop().runner.end(); - $$rAF.flush(); var anchorAnimation = captureLog.pop(); var anchorElement = anchorAnimation.element; @@ -889,7 +881,7 @@ describe("ngAnimate $$animateCssDriver", function() { })); it("should remove the cloned anchor node from the DOM once the 'in' animation is complete", - inject(function($rootElement, $$rAF) { + inject(function($rootElement) { var fromAnchor = jqLite(''); from.append(fromAnchor); @@ -913,7 +905,6 @@ describe("ngAnimate $$animateCssDriver", function() { var clonedAnchor = inAnimation.element; expect(clonedAnchor.parent().length).toBe(1); inAnimation.runner.end(); - $$rAF.flush(); // now the in animation completes expect(clonedAnchor.parent().length).toBe(1); @@ -923,7 +914,7 @@ describe("ngAnimate $$animateCssDriver", function() { })); it("should pass the provided domOperation into $animateCss to be run right after the element is animated if a leave animation is present", - inject(function($rootElement, $$rAF) { + inject(function($rootElement) { toAnimation.structural = true; toAnimation.event = 'enter'; @@ -949,7 +940,7 @@ describe("ngAnimate $$animateCssDriver", function() { })); it("should fire the returned runner promise when the from, to and anchor animations are all complete", - inject(function($rootElement, $rootScope, $$rAF) { + inject(function($rootElement, $rootScope, $animate) { ss.addRule('.ending-element', 'width:9999px; height:6666px; display:inline-block;'); @@ -978,7 +969,8 @@ describe("ngAnimate $$animateCssDriver", function() { captureLog.pop().runner.end(); //to captureLog.pop().runner.end(); //anchor(out) captureLog.pop().runner.end(); //anchor(in) - $$rAF.flush(); + + $animate.flush(); $rootScope.$digest(); expect(completed).toBe(true); diff --git a/test/ngAnimate/animateCssSpec.js b/test/ngAnimate/animateCssSpec.js index 854e64a43151..e06dd6dcc764 100644 --- a/test/ngAnimate/animateCssSpec.js +++ b/test/ngAnimate/animateCssSpec.js @@ -3,6 +3,7 @@ describe("ngAnimate $animateCss", function() { beforeEach(module('ngAnimate')); + beforeEach(module('ngAnimateMock')); function assertAnimationRunning(element, not) { var className = element.attr('class'); @@ -52,7 +53,7 @@ describe("ngAnimate $animateCss", function() { if (!browserSupportsCssAnimations()) return; it("should silently quit the animation and not throw when an element has no parent during preparation", - inject(function($animateCss, $$rAF, $rootScope, $document, $rootElement) { + inject(function($animateCss, $rootScope, $document, $rootElement) { var element = jqLite(''); expect(function() { @@ -385,7 +386,7 @@ describe("ngAnimate $animateCss", function() { they("should close the animation, but still accept $prop callbacks if no animation is detected", ['done', 'then'], function(method) { - inject(function($animateCss, $$rAF, $rootScope) { + inject(function($animateCss, $animate, $rootScope) { ss.addRule('.the-third-fake-animation', 'background:green;'); element.addClass('another-fake-animation'); @@ -400,7 +401,8 @@ describe("ngAnimate $animateCss", function() { }); expect(done).toBe(false); - $$rAF.flush(); + $animate.flush(); + if (method === 'then') { $rootScope.$digest(); } @@ -411,7 +413,7 @@ describe("ngAnimate $animateCss", function() { they("should close the animation, but still accept recognize runner.$prop if no animation is detected", ['done(cancel)', 'catch'], function(method) { - inject(function($animateCss, $$rAF, $rootScope) { + inject(function($animateCss, $rootScope) { ss.addRule('.the-third-fake-animation', 'background:green;'); element.addClass('another-fake-animation'); @@ -1078,7 +1080,7 @@ describe("ngAnimate $animateCss", function() { })); it("should still resolve the animation once expired", - inject(function($animateCss, $$body, $rootElement, $timeout) { + inject(function($animateCss, $$body, $rootElement, $timeout, $animate, $rootScope) { ss.addRule('.ng-enter', 'transition:10s linear all;'); @@ -1097,11 +1099,13 @@ describe("ngAnimate $animateCss", function() { triggerAnimationStartFrame(); $timeout.flush(15000); + $animate.flush(); + $rootScope.$digest(); expect(passed).toBe(true); })); it("should not resolve/reject after passing if the animation completed successfully", - inject(function($animateCss, $$body, $rootElement, $timeout, $rootScope) { + inject(function($animateCss, $$body, $rootElement, $timeout, $rootScope, $animate) { ss.addRule('.ng-enter', 'transition:10s linear all;'); @@ -1125,6 +1129,7 @@ describe("ngAnimate $animateCss", function() { browserTrigger(element, 'transitionend', { timeStamp: Date.now() + 1000, elapsedTime: 10 }); + $animate.flush(); $rootScope.$digest(); expect(passed).toBe(true); @@ -1137,7 +1142,7 @@ describe("ngAnimate $animateCss", function() { })); it("should close all stacked animations after the last timeout runs on the same element", - inject(function($animateCss, $$body, $rootElement, $timeout) { + inject(function($animateCss, $$body, $rootElement, $timeout, $animate) { var now = 0; spyOn(Date, 'now').andCallFake(function() { @@ -1176,6 +1181,8 @@ describe("ngAnimate $animateCss", function() { // this will close the animations fully fastForwardClock(3500); + $animate.flush(); + expect(doneSpy).toHaveBeenCalled(); expect(doneSpy.callCount).toBe(3); @@ -1218,7 +1225,7 @@ describe("ngAnimate $animateCss", function() { })); it("should cache frequent calls to getComputedStyle before the next animation frame kicks in", - inject(function($animateCss, $document, $rootElement, $$rAF) { + inject(function($animateCss, $document, $rootElement) { var i, elm, animator; for (i = 0; i < 5; i++) { diff --git a/test/ngAnimate/animateJsDriverSpec.js b/test/ngAnimate/animateJsDriverSpec.js index 274457965f10..d3f8722cb45d 100644 --- a/test/ngAnimate/animateJsDriverSpec.js +++ b/test/ngAnimate/animateJsDriverSpec.js @@ -3,6 +3,7 @@ describe("ngAnimate $$animateJsDriver", function() { beforeEach(module('ngAnimate')); + beforeEach(module('ngAnimateMock')); it('should register the $$animateJsDriver into the list of drivers found in $animateProvider', module(function($animateProvider) { @@ -96,7 +97,7 @@ describe("ngAnimate $$animateJsDriver", function() { })); they('should $prop both animations when $prop() is called on the runner', ['end', 'cancel'], function(method) { - inject(function($rootScope, $$rAF) { + inject(function($rootScope, $animate) { var child1 = jqLite(''); element.append(child1); var child2 = jqLite(''); @@ -127,7 +128,7 @@ describe("ngAnimate $$animateJsDriver", function() { $rootScope.$digest(); runner[method](); - $$rAF.flush(); + $animate.flush(); expect(animationsClosed).toBe(true); expect(status).toBe(method === 'end' ? true : false); @@ -135,7 +136,7 @@ describe("ngAnimate $$animateJsDriver", function() { }); they('should fully $prop when all inner animations are complete', ['end', 'cancel'], function(method) { - inject(function($rootScope, $$rAF) { + inject(function($rootScope, $animate) { var child1 = jqLite(''); element.append(child1); var child2 = jqLite(''); @@ -163,12 +164,12 @@ describe("ngAnimate $$animateJsDriver", function() { status = s; }); - $$rAF.flush(); - captureLog[0].runner[method](); expect(animationsClosed).toBe(false); captureLog[1].runner[method](); + $animate.flush(); + expect(animationsClosed).toBe(true); expect(status).toBe(method === 'end' ? true : false); diff --git a/test/ngAnimate/animateJsSpec.js b/test/ngAnimate/animateJsSpec.js index c162d678f098..99d7dcd076f6 100644 --- a/test/ngAnimate/animateJsSpec.js +++ b/test/ngAnimate/animateJsSpec.js @@ -3,6 +3,7 @@ describe("ngAnimate $$animateJs", function() { beforeEach(module('ngAnimate')); + beforeEach(module('ngAnimateMock')); function getDoneFunction(args) { for (var i = 1; i < args.length; i++) { @@ -86,7 +87,7 @@ describe("ngAnimate $$animateJs", function() { $animateProvider.register('.two', makeAnimation('enter')); $animateProvider.register('.three', makeAnimation('enter')); }); - inject(function($$animateJs, $$rAF) { + inject(function($$animateJs, $animate) { var element = jqLite(''); var animator = $$animateJs(element, 'enter'); var complete = false; @@ -97,7 +98,7 @@ describe("ngAnimate $$animateJs", function() { forEach(doneCallbacks, function(cb) { cb(); }); - $$rAF.flush(); + $animate.flush(); expect(complete).toBe(true); }); }); @@ -206,7 +207,7 @@ describe("ngAnimate $$animateJs", function() { }; }); }); - inject(function($$animateJs, $$rAF) { + inject(function($$animateJs, $animate) { var element = jqLite(''); var animator = $$animateJs(element, 'addClass', { addClass: 'red' @@ -221,12 +222,12 @@ describe("ngAnimate $$animateJs", function() { before(); expect(after).toBeUndefined(); - $$rAF.flush(); + $animate.flush(); expect(after).toBeDefined(); after(); expect(endCalled).toBeUndefined(); - $$rAF.flush(); + $animate.flush(); expect(endCalled).toBe(true); }); }); @@ -251,7 +252,7 @@ describe("ngAnimate $$animateJs", function() { }; }); }); - inject(function($$animateJs, $$rAF) { + inject(function($$animateJs, $animate) { var element = jqLite(''); var animator = $$animateJs(element, 'addClass', { domOperation: function() { @@ -264,7 +265,7 @@ describe("ngAnimate $$animateJs", function() { }); runner[method](); - $$rAF.flush(); + $animate.flush(); expect(log).toEqual( ['before addClass ' + method, 'dom addClass', @@ -278,7 +279,7 @@ describe("ngAnimate $$animateJs", function() { return { beforeAddClass: noop }; }); }); - inject(function($$animateJs, $$rAF, $rootScope) { + inject(function($$animateJs, $animate, $rootScope) { var element = jqLite(''); var animator = $$animateJs(element, 'addClass'); var runner = animator.start(); @@ -291,7 +292,7 @@ describe("ngAnimate $$animateJs", function() { }); runner.end(); - $$rAF.flush(); + $animate.flush(); $rootScope.$digest(); expect(done).toBe(true); expect(cancelled).toBe(false); @@ -304,7 +305,7 @@ describe("ngAnimate $$animateJs", function() { return { beforeAddClass: noop }; }); }); - inject(function($$animateJs, $$rAF, $rootScope) { + inject(function($$animateJs, $animate, $rootScope) { var element = jqLite(''); var animator = $$animateJs(element, 'addClass'); var runner = animator.start(); @@ -317,7 +318,7 @@ describe("ngAnimate $$animateJs", function() { }); runner.cancel(); - $$rAF.flush(); + $animate.flush(); $rootScope.$digest(); expect(done).toBe(false); expect(cancelled).toBe(true); @@ -504,7 +505,7 @@ describe("ngAnimate $$animateJs", function() { var allEvents = ['leave'].concat(otherEvents).concat(enterMoveEvents); they("$prop should asynchronously render the before$prop animation", otherEvents, function(event) { - inject(function($$rAF) { + inject(function($animate) { var beforeMethod = 'before' + event.charAt(0).toUpperCase() + event.substr(1); animations[beforeMethod] = function(element, a, b, c) { log.push('before ' + event); @@ -514,14 +515,14 @@ describe("ngAnimate $$animateJs", function() { runAnimation(event); expect(log).toEqual(['before ' + event]); - $$rAF.flush(); + $animate.flush(); expect(log).toEqual(['before ' + event, 'dom ' + event]); }); }); they("$prop should asynchronously render the $prop animation", allEvents, function(event) { - inject(function($$rAF) { + inject(function($animate) { animations[event] = function(element, a, b, c) { log.push('after ' + event); var done = getDoneFunction(arguments); @@ -534,11 +535,11 @@ describe("ngAnimate $$animateJs", function() { if (event === 'leave') { expect(log).toEqual(['after leave']); - $$rAF.flush(); + $animate.flush(); expect(log).toEqual(['after leave', 'dom leave', 'complete']); } else { expect(log).toEqual(['dom ' + event, 'after ' + event]); - $$rAF.flush(); + $animate.flush(); expect(log).toEqual(['dom ' + event, 'after ' + event, 'complete']); } }); @@ -547,7 +548,7 @@ describe("ngAnimate $$animateJs", function() { they("$prop should asynchronously render the $prop animation when a start/end animator object is returned", allEvents, function(event) { - inject(function($$rAF, $$AnimateRunner) { + inject(function($animate, $$AnimateRunner) { var runner; animations[event] = function(element, a, b, c) { return { @@ -565,12 +566,12 @@ describe("ngAnimate $$animateJs", function() { if (event === 'leave') { expect(log).toEqual(['start leave']); runner.end(); - $$rAF.flush(); + $animate.flush(); expect(log).toEqual(['start leave', 'dom leave', 'complete']); } else { expect(log).toEqual(['dom ' + event, 'start ' + event]); runner.end(); - $$rAF.flush(); + $animate.flush(); expect(log).toEqual(['dom ' + event, 'start ' + event, 'complete']); } }); @@ -579,7 +580,7 @@ describe("ngAnimate $$animateJs", function() { they("$prop should asynchronously render the $prop animation when an instance of $$AnimateRunner is returned", allEvents, function(event) { - inject(function($$rAF, $$AnimateRunner) { + inject(function($animate, $$AnimateRunner) { var runner; animations[event] = function(element, a, b, c) { log.push('start ' + event); @@ -593,19 +594,19 @@ describe("ngAnimate $$animateJs", function() { if (event === 'leave') { expect(log).toEqual(['start leave']); runner.end(); - $$rAF.flush(); + $animate.flush(); expect(log).toEqual(['start leave', 'dom leave', 'complete']); } else { expect(log).toEqual(['dom ' + event, 'start ' + event]); runner.end(); - $$rAF.flush(); + $animate.flush(); expect(log).toEqual(['dom ' + event, 'start ' + event, 'complete']); } }); }); they("$prop should asynchronously reject the before animation if the callback function is called with false", otherEvents, function(event) { - inject(function($$rAF, $rootScope) { + inject(function($animate, $rootScope) { var beforeMethod = 'before' + event.charAt(0).toUpperCase() + event.substr(1); animations[beforeMethod] = function(element, a, b, c) { log.push('before ' + event); @@ -624,13 +625,13 @@ describe("ngAnimate $$animateJs", function() { function() { log.push('fail'); }); expect(log).toEqual(['before ' + event]); - $$rAF.flush(); + $animate.flush(); expect(log).toEqual(['before ' + event, 'dom ' + event, 'fail']); }); }); they("$prop should asynchronously reject the after animation if the callback function is called with false", allEvents, function(event) { - inject(function($$rAF, $rootScope) { + inject(function($animate, $rootScope) { animations[event] = function(element, a, b, c) { log.push('after ' + event); var done = getDoneFunction(arguments); @@ -644,17 +645,17 @@ describe("ngAnimate $$animateJs", function() { var expectations = []; if (event === 'leave') { expect(log).toEqual(['after leave']); - $$rAF.flush(); + $animate.flush(); expect(log).toEqual(['after leave', 'dom leave', 'fail']); } else { expect(log).toEqual(['dom ' + event, 'after ' + event]); - $$rAF.flush(); + $animate.flush(); expect(log).toEqual(['dom ' + event, 'after ' + event, 'fail']); } }); }); - it('setClass should delegate down to addClass/removeClass if not defined', inject(function($$rAF) { + it('setClass should delegate down to addClass/removeClass if not defined', inject(function($animate) { animations.addClass = function(element, done) { log.push('addClass'); }; @@ -671,7 +672,7 @@ describe("ngAnimate $$animateJs", function() { })); it('beforeSetClass should delegate down to beforeAddClass/beforeRemoveClass if not defined', - inject(function($$rAF) { + inject(function($animate) { animations.beforeAddClass = function(element, className, done) { log.push('beforeAddClass'); @@ -686,13 +687,13 @@ describe("ngAnimate $$animateJs", function() { expect(animations.setClass).toBeFalsy(); runAnimation('setClass'); - $$rAF.flush(); + $animate.flush(); expect(log).toEqual(['beforeRemoveClass', 'beforeAddClass', 'dom setClass']); })); it('leave should always ignore the `beforeLeave` animation', - inject(function($$rAF) { + inject(function($animate) { animations.beforeLeave = function(element, done) { log.push('beforeLeave'); @@ -705,13 +706,13 @@ describe("ngAnimate $$animateJs", function() { }; runAnimation('leave'); - $$rAF.flush(); + $animate.flush(); expect(log).toEqual(['leave', 'dom leave']); })); it('should allow custom events to be triggered', - inject(function($$rAF) { + inject(function($animate) { animations.beforeFlex = function(element, done) { log.push('beforeFlex'); @@ -724,7 +725,7 @@ describe("ngAnimate $$animateJs", function() { }; runAnimation('flex'); - $$rAF.flush(); + $animate.flush(); expect(log).toEqual(['beforeFlex', 'dom flex', 'flex']); })); diff --git a/test/ngAnimate/animateRunnerSpec.js b/test/ngAnimate/animateRunnerSpec.js index 94178fba6189..f4526d8abb57 100644 --- a/test/ngAnimate/animateRunnerSpec.js +++ b/test/ngAnimate/animateRunnerSpec.js @@ -1,12 +1,12 @@ 'use strict'; -describe('$$rAFMutex', function() { +describe('$$animateAsyncRun', function() { beforeEach(module('ngAnimate')); it('should fire the callback only when one or more RAFs have passed', - inject(function($$rAF, $$rAFMutex) { + inject(function($$animateAsyncRun, $$rAF) { - var trigger = $$rAFMutex(); + var trigger = $$animateAsyncRun(); var called = false; trigger(function() { called = true; @@ -18,9 +18,9 @@ describe('$$rAFMutex', function() { })); it('should immediately fire the callback if a RAF has passed since construction', - inject(function($$rAF, $$rAFMutex) { + inject(function($$animateAsyncRun, $$rAF) { - var trigger = $$rAFMutex(); + var trigger = $$animateAsyncRun(); $$rAF.flush(); var called = false; @@ -89,7 +89,7 @@ describe("$$AnimateRunner", function() { they("should immediately resolve each combined runner in a bottom-up order when $prop is called", ['end', 'cancel'], function(method) { - inject(function($$AnimateRunner, $$rAF) { + inject(function($$AnimateRunner) { var runner1 = new $$AnimateRunner(); var runner2 = new $$AnimateRunner(); runner1.setHost(runner2); @@ -206,7 +206,7 @@ describe("$$AnimateRunner", function() { they("should immediately resolve if and when all runners have been $prop", { ended: 'end', cancelled: 'cancel' }, function(method) { - inject(function($$rAF, $$AnimateRunner) { + inject(function($$AnimateRunner) { var runner1 = new $$AnimateRunner(); var runner2 = new $$AnimateRunner(); var runner3 = new $$AnimateRunner(); @@ -227,7 +227,7 @@ describe("$$AnimateRunner", function() { }); it("should return a status of `false` if one or more runners was cancelled", - inject(function($$rAF, $$AnimateRunner) { + inject(function($$AnimateRunner) { var runner1 = new $$AnimateRunner(); var runner2 = new $$AnimateRunner(); diff --git a/test/ngAnimate/animateSpec.js b/test/ngAnimate/animateSpec.js index 754ba17a13c2..ce897fa0b48e 100644 --- a/test/ngAnimate/animateSpec.js +++ b/test/ngAnimate/animateSpec.js @@ -3,6 +3,7 @@ describe("animations", function() { beforeEach(module('ngAnimate')); + beforeEach(module('ngAnimateMock')); var element, applyAnimationClasses; afterEach(inject(function($$jqLite) { @@ -410,7 +411,7 @@ describe("animations", function() { })); it('should remove all element and comment nodes during leave animation', - inject(function($compile, $rootScope, $$rAF, $$AnimateRunner) { + inject(function($compile, $rootScope, $animate, $$AnimateRunner) { element = $compile( '