Index: third_party/polymer/components/web-animations-js/src/tick.js |
diff --git a/third_party/polymer/components/web-animations-js/src/tick.js b/third_party/polymer/components/web-animations-js/src/tick.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..08b0a140909bdd3ccd4db06f855db4ddcf864e47 |
--- /dev/null |
+++ b/third_party/polymer/components/web-animations-js/src/tick.js |
@@ -0,0 +1,181 @@ |
+// Copyright 2014 Google Inc. All rights reserved. |
+// |
+// Licensed under the Apache License, Version 2.0 (the "License"); |
+// you may not use this file except in compliance with the License. |
+// You may obtain a copy of the License at |
+// |
+// http://www.apache.org/licenses/LICENSE-2.0 |
+// |
+// Unless required by applicable law or agreed to in writing, software |
+// distributed under the License is distributed on an "AS IS" BASIS, |
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+// See the License for the specific language governing permissions and |
+// limitations under the License. |
+ |
+ |
+(function(shared, scope, testing) { |
+ var originalRequestAnimationFrame = window.requestAnimationFrame; |
+ var rafCallbacks = []; |
+ var rafId = 0; |
+ window.requestAnimationFrame = function(f) { |
+ var id = rafId++; |
+ if (rafCallbacks.length == 0 && !WEB_ANIMATIONS_TESTING) { |
+ originalRequestAnimationFrame(processRafCallbacks); |
+ } |
+ rafCallbacks.push([id, f]); |
+ return id; |
+ }; |
+ |
+ window.cancelAnimationFrame = function(id) { |
+ rafCallbacks.forEach(function(entry) { |
+ if (entry[0] == id) { |
+ entry[1] = function() {}; |
+ } |
+ }); |
+ }; |
+ |
+ function processRafCallbacks(t) { |
+ var processing = rafCallbacks; |
+ rafCallbacks = []; |
+ if (t < timeline.currentTime) |
+ t = timeline.currentTime; |
+ timeline._animations.sort(compareAnimations); |
+ timeline._animations = tick(t, true, timeline._animations)[0]; |
+ processing.forEach(function(entry) { entry[1](t); }); |
+ applyPendingEffects(); |
+ _now = undefined; |
+ } |
+ |
+ function compareAnimations(leftAnimation, rightAnimation) { |
+ return leftAnimation._sequenceNumber - rightAnimation._sequenceNumber; |
+ } |
+ |
+ function InternalTimeline() { |
+ this._animations = []; |
+ // Android 4.3 browser has window.performance, but not window.performance.now |
+ this.currentTime = window.performance && performance.now ? performance.now() : 0; |
+ }; |
+ |
+ InternalTimeline.prototype = { |
+ _play: function(effect) { |
+ effect._timing = shared.normalizeTimingInput(effect.timing); |
+ var animation = new scope.Animation(effect); |
+ animation._idle = false; |
+ animation._timeline = this; |
+ this._animations.push(animation); |
+ scope.restart(); |
+ scope.applyDirtiedAnimation(animation); |
+ return animation; |
+ } |
+ }; |
+ |
+ var _now = undefined; |
+ |
+ if (WEB_ANIMATIONS_TESTING) { |
+ var now = function() { return timeline.currentTime; }; |
+ } else { |
+ var now = function() { |
+ if (_now == undefined) |
+ _now = window.performance && performance.now ? performance.now() : Date.now(); |
+ return _now; |
+ }; |
+ } |
+ |
+ var ticking = false; |
+ var hasRestartedThisFrame = false; |
+ |
+ scope.restart = function() { |
+ if (!ticking) { |
+ ticking = true; |
+ requestAnimationFrame(function() {}); |
+ hasRestartedThisFrame = true; |
+ } |
+ return hasRestartedThisFrame; |
+ }; |
+ |
+ // RAF is supposed to be the last script to occur before frame rendering but not |
+ // all browsers behave like this. This function is for synchonously updating an |
+ // animation's effects whenever its state is mutated by script to work around |
+ // incorrect script execution ordering by the browser. |
+ scope.applyDirtiedAnimation = function(animation) { |
+ if (inTick) { |
+ return; |
+ } |
+ animation._markTarget(); |
+ var animations = animation._targetAnimations(); |
+ animations.sort(compareAnimations); |
+ var inactiveAnimations = tick(scope.timeline.currentTime, false, animations.slice())[1]; |
+ inactiveAnimations.forEach(function(animation) { |
+ var index = timeline._animations.indexOf(animation); |
+ if (index !== -1) { |
+ timeline._animations.splice(index, 1); |
+ } |
+ }); |
+ applyPendingEffects(); |
+ }; |
+ |
+ var pendingEffects = []; |
+ function applyPendingEffects() { |
+ pendingEffects.forEach(function(f) { f(); }); |
+ pendingEffects.length = 0; |
+ } |
+ |
+ var t60hz = 1000 / 60; |
+ |
+ var inTick = false; |
+ function tick(t, isAnimationFrame, updatingAnimations) { |
+ inTick = true; |
+ hasRestartedThisFrame = false; |
+ var timeline = scope.timeline; |
+ |
+ timeline.currentTime = t; |
+ ticking = false; |
+ |
+ var newPendingClears = []; |
+ var newPendingEffects = []; |
+ var activeAnimations = []; |
+ var inactiveAnimations = []; |
+ updatingAnimations.forEach(function(animation) { |
+ animation._tick(t, isAnimationFrame); |
+ |
+ if (!animation._inEffect) { |
+ newPendingClears.push(animation._effect); |
+ animation._unmarkTarget(); |
+ } else { |
+ newPendingEffects.push(animation._effect); |
+ animation._markTarget(); |
+ } |
+ |
+ if (animation._needsTick) |
+ ticking = true; |
+ |
+ var alive = animation._inEffect || animation._needsTick; |
+ animation._inTimeline = alive; |
+ if (alive) { |
+ activeAnimations.push(animation); |
+ } else { |
+ inactiveAnimations.push(animation); |
+ } |
+ }); |
+ |
+ // FIXME: Should remove dupliactes from pendingEffects. |
+ pendingEffects.push.apply(pendingEffects, newPendingClears); |
+ pendingEffects.push.apply(pendingEffects, newPendingEffects); |
+ |
+ if (ticking) |
+ requestAnimationFrame(function() {}); |
+ |
+ inTick = false; |
+ return [activeAnimations, inactiveAnimations]; |
+ }; |
+ |
+ if (WEB_ANIMATIONS_TESTING) { |
+ testing.tick = function(t) { timeline.currentTime = t; processRafCallbacks(t); }; |
+ testing.isTicking = function() { return ticking; }; |
+ testing.setTicking = function(newVal) { ticking = newVal; }; |
+ } |
+ |
+ var timeline = new InternalTimeline(); |
+ scope.timeline = timeline; |
+ |
+})(webAnimationsShared, webAnimations1, webAnimationsTesting); |