Revert of Roll src/third_party/WebKit e0eac24:489c548 (svn 193311:193320) (patchset...
[chromium-blink-merge.git] / third_party / web-animations-js / sources / src / tick.js
blobcbc7ff3ae9e49f5d93bc83c2a915e53b509cb625
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 //     You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 //     See the License for the specific language governing permissions and
13 // limitations under the License.
16 (function(shared, scope, testing) {
17   var originalRequestAnimationFrame = window.requestAnimationFrame;
18   var rafCallbacks = [];
19   var rafId = 0;
20   window.requestAnimationFrame = function(f) {
21     var id = rafId++;
22     if (rafCallbacks.length == 0 && !WEB_ANIMATIONS_TESTING) {
23       originalRequestAnimationFrame(processRafCallbacks);
24     }
25     rafCallbacks.push([id, f]);
26     return id;
27   };
29   window.cancelAnimationFrame = function(id) {
30     rafCallbacks.forEach(function(entry) {
31       if (entry[0] == id) {
32         entry[1] = function() {};
33       }
34     });
35   };
37   function processRafCallbacks(t) {
38     var processing = rafCallbacks;
39     rafCallbacks = [];
40     tick(t);
41     processing.forEach(function(entry) { entry[1](t); });
42     if (needsRetick)
43       tick(t);
44     applyPendingEffects();
45   }
47   function comparePlayers(leftPlayer, rightPlayer) {
48     return leftPlayer._sequenceNumber - rightPlayer._sequenceNumber;
49   }
51   function InternalTimeline() {
52     this._players = [];
53     // Android 4.3 browser has window.performance, but not window.performance.now
54     this.currentTime = window.performance && performance.now ? performance.now() : 0;
55   };
57   InternalTimeline.prototype = {
58     _play: function(source) {
59       source._timing = shared.normalizeTimingInput(source.timing);
60       var player = new scope.Player(source);
61       player._idle = false;
62       player._timeline = this;
63       this._players.push(player);
64       scope.restart();
65       scope.invalidateEffects();
66       return player;
67     }
68   };
70   var ticking = false;
71   var hasRestartedThisFrame = false;
73   scope.restart = function() {
74     if (!ticking) {
75       ticking = true;
76       requestAnimationFrame(function() {});
77       hasRestartedThisFrame = true;
78     }
79     return hasRestartedThisFrame;
80   };
82   var needsRetick = false;
83   scope.invalidateEffects = function() {
84     needsRetick = true;
85   };
87   var pendingEffects = [];
88   function applyPendingEffects() {
89     pendingEffects.forEach(function(f) { f(); });
90   }
92   var originalGetComputedStyle = window.getComputedStyle;
93   Object.defineProperty(window, 'getComputedStyle', {
94     configurable: true,
95     enumerable: true,
96     value: function() {
97       if (needsRetick) tick(timeline.currentTime);
98       applyPendingEffects();
99       return originalGetComputedStyle.apply(this, arguments);
100     },
101   });
103   function tick(t) {
104     hasRestartedThisFrame = false;
105     var timeline = scope.timeline;
106     timeline.currentTime = t;
107     timeline._players.sort(comparePlayers);
108     ticking = false;
109     var updatingPlayers = timeline._players;
110     timeline._players = [];
112     var newPendingClears = [];
113     var newPendingEffects = [];
114     updatingPlayers = updatingPlayers.filter(function(player) {
115       player._inTimeline = player._tick(t);
117       if (!player._inEffect)
118         newPendingClears.push(player._source);
119       else
120         newPendingEffects.push(player._source);
122       if (!player.finished && !player.paused && !player._idle)
123         ticking = true;
125       return player._inTimeline;
126     });
128     pendingEffects.length = 0;
129     pendingEffects.push.apply(pendingEffects, newPendingClears);
130     pendingEffects.push.apply(pendingEffects, newPendingEffects);
132     timeline._players.push.apply(timeline._players, updatingPlayers);
133     needsRetick = false;
135     if (ticking)
136       requestAnimationFrame(function() {});
137   };
139   if (WEB_ANIMATIONS_TESTING) {
140     testing.tick = processRafCallbacks;
141     testing.isTicking = function() { return ticking; };
142     testing.setTicking = function(newVal) { ticking = newVal; };
143   }
145   var timeline = new InternalTimeline();
146   scope.timeline = timeline;
148 })(webAnimationsShared, webAnimations1, webAnimationsTesting);