Index: third_party/google_input_tools/third_party/closure_library/closure/goog/timer/timer.js |
diff --git a/third_party/google_input_tools/third_party/closure_library/closure/goog/timer/timer.js b/third_party/google_input_tools/third_party/closure_library/closure/goog/timer/timer.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ccee170d00cc3cc79bbf58d1836e2517bf0e7cc1 |
--- /dev/null |
+++ b/third_party/google_input_tools/third_party/closure_library/closure/goog/timer/timer.js |
@@ -0,0 +1,292 @@ |
+// Copyright 2006 The Closure Library Authors. 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. |
+ |
+/** |
+ * @fileoverview A timer class to which other classes and objects can |
+ * listen on. This is only an abstraction above setInterval. |
+ * |
+ * @see ../demos/timers.html |
+ */ |
+ |
+goog.provide('goog.Timer'); |
+ |
+goog.require('goog.events.EventTarget'); |
+ |
+ |
+ |
+/** |
+ * Class for handling timing events. |
+ * |
+ * @param {number=} opt_interval Number of ms between ticks (Default: 1ms). |
+ * @param {Object=} opt_timerObject An object that has setTimeout, setInterval, |
+ * clearTimeout and clearInterval (eg Window). |
+ * @constructor |
+ * @extends {goog.events.EventTarget} |
+ */ |
+goog.Timer = function(opt_interval, opt_timerObject) { |
+ goog.events.EventTarget.call(this); |
+ |
+ /** |
+ * Number of ms between ticks |
+ * @type {number} |
+ * @private |
+ */ |
+ this.interval_ = opt_interval || 1; |
+ |
+ /** |
+ * An object that implements setTimeout, setInterval, clearTimeout and |
+ * clearInterval. We default to the window object. Changing this on |
+ * goog.Timer.prototype changes the object for all timer instances which can |
+ * be useful if your environment has some other implementation of timers than |
+ * the window object. |
+ * @type {Object} |
+ * @private |
+ */ |
+ this.timerObject_ = opt_timerObject || goog.Timer.defaultTimerObject; |
+ |
+ /** |
+ * Cached tick_ bound to the object for later use in the timer. |
+ * @type {Function} |
+ * @private |
+ */ |
+ this.boundTick_ = goog.bind(this.tick_, this); |
+ |
+ /** |
+ * Firefox browser often fires the timer event sooner |
+ * (sometimes MUCH sooner) than the requested timeout. So we |
+ * compare the time to when the event was last fired, and |
+ * reschedule if appropriate. See also goog.Timer.intervalScale |
+ * @type {number} |
+ * @private |
+ */ |
+ this.last_ = goog.now(); |
+}; |
+goog.inherits(goog.Timer, goog.events.EventTarget); |
+ |
+ |
+/** |
+ * Maximum timeout value. |
+ * |
+ * Timeout values too big to fit into a signed 32-bit integer may cause |
+ * overflow in FF, Safari, and Chrome, resulting in the timeout being |
+ * scheduled immediately. It makes more sense simply not to schedule these |
+ * timeouts, since 24.8 days is beyond a reasonable expectation for the |
+ * browser to stay open. |
+ * |
+ * @type {number} |
+ * @private |
+ */ |
+goog.Timer.MAX_TIMEOUT_ = 2147483647; |
+ |
+ |
+/** |
+ * Whether this timer is enabled |
+ * @type {boolean} |
+ */ |
+goog.Timer.prototype.enabled = false; |
+ |
+ |
+/** |
+ * An object that implements setTimout, setInterval, clearTimeout and |
+ * clearInterval. We default to the global object. Changing |
+ * goog.Timer.defaultTimerObject changes the object for all timer instances |
+ * which can be useful if your environment has some other implementation of |
+ * timers you'd like to use. |
+ * @type {Object} |
+ */ |
+goog.Timer.defaultTimerObject = goog.global; |
+ |
+ |
+/** |
+ * A variable that controls the timer error correction. If the |
+ * timer is called before the requested interval times |
+ * intervalScale, which often happens on mozilla, the timer is |
+ * rescheduled. See also this.last_ |
+ * @type {number} |
+ */ |
+goog.Timer.intervalScale = 0.8; |
+ |
+ |
+/** |
+ * Variable for storing the result of setInterval |
+ * @type {?number} |
+ * @private |
+ */ |
+goog.Timer.prototype.timer_ = null; |
+ |
+ |
+/** |
+ * Gets the interval of the timer. |
+ * @return {number} interval Number of ms between ticks. |
+ */ |
+goog.Timer.prototype.getInterval = function() { |
+ return this.interval_; |
+}; |
+ |
+ |
+/** |
+ * Sets the interval of the timer. |
+ * @param {number} interval Number of ms between ticks. |
+ */ |
+goog.Timer.prototype.setInterval = function(interval) { |
+ this.interval_ = interval; |
+ if (this.timer_ && this.enabled) { |
+ // Stop and then start the timer to reset the interval. |
+ this.stop(); |
+ this.start(); |
+ } else if (this.timer_) { |
+ this.stop(); |
+ } |
+}; |
+ |
+ |
+/** |
+ * Callback for the setTimeout used by the timer |
+ * @private |
+ */ |
+goog.Timer.prototype.tick_ = function() { |
+ if (this.enabled) { |
+ var elapsed = goog.now() - this.last_; |
+ if (elapsed > 0 && |
+ elapsed < this.interval_ * goog.Timer.intervalScale) { |
+ this.timer_ = this.timerObject_.setTimeout(this.boundTick_, |
+ this.interval_ - elapsed); |
+ return; |
+ } |
+ |
+ // Prevents setInterval from registering a duplicate timeout when called |
+ // in the timer event handler. |
+ if (this.timer_) { |
+ this.timerObject_.clearTimeout(this.timer_); |
+ this.timer_ = null; |
+ } |
+ |
+ this.dispatchTick(); |
+ // The timer could be stopped in the timer event handler. |
+ if (this.enabled) { |
+ this.timer_ = this.timerObject_.setTimeout(this.boundTick_, |
+ this.interval_); |
+ this.last_ = goog.now(); |
+ } |
+ } |
+}; |
+ |
+ |
+/** |
+ * Dispatches the TICK event. This is its own method so subclasses can override. |
+ */ |
+goog.Timer.prototype.dispatchTick = function() { |
+ this.dispatchEvent(goog.Timer.TICK); |
+}; |
+ |
+ |
+/** |
+ * Starts the timer. |
+ */ |
+goog.Timer.prototype.start = function() { |
+ this.enabled = true; |
+ |
+ // If there is no interval already registered, start it now |
+ if (!this.timer_) { |
+ // IMPORTANT! |
+ // window.setInterval in FireFox has a bug - it fires based on |
+ // absolute time, rather than on relative time. What this means |
+ // is that if a computer is sleeping/hibernating for 24 hours |
+ // and the timer interval was configured to fire every 1000ms, |
+ // then after the PC wakes up the timer will fire, in rapid |
+ // succession, 3600*24 times. |
+ // This bug is described here and is already fixed, but it will |
+ // take time to propagate, so for now I am switching this over |
+ // to setTimeout logic. |
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=376643 |
+ // |
+ this.timer_ = this.timerObject_.setTimeout(this.boundTick_, |
+ this.interval_); |
+ this.last_ = goog.now(); |
+ } |
+}; |
+ |
+ |
+/** |
+ * Stops the timer. |
+ */ |
+goog.Timer.prototype.stop = function() { |
+ this.enabled = false; |
+ if (this.timer_) { |
+ this.timerObject_.clearTimeout(this.timer_); |
+ this.timer_ = null; |
+ } |
+}; |
+ |
+ |
+/** @override */ |
+goog.Timer.prototype.disposeInternal = function() { |
+ goog.Timer.superClass_.disposeInternal.call(this); |
+ this.stop(); |
+ delete this.timerObject_; |
+}; |
+ |
+ |
+/** |
+ * Constant for the timer's event type |
+ * @type {string} |
+ */ |
+goog.Timer.TICK = 'tick'; |
+ |
+ |
+/** |
+ * Calls the given function once, after the optional pause. |
+ * |
+ * The function is always called asynchronously, even if the delay is 0. This |
+ * is a common trick to schedule a function to run after a batch of browser |
+ * event processing. |
+ * |
+ * @param {function(this:SCOPE)|{handleEvent:function()}|null} listener Function |
+ * or object that has a handleEvent method. |
+ * @param {number=} opt_delay Milliseconds to wait; default is 0. |
+ * @param {SCOPE=} opt_handler Object in whose scope to call the listener. |
+ * @return {number} A handle to the timer ID. |
+ * @template SCOPE |
+ */ |
+goog.Timer.callOnce = function(listener, opt_delay, opt_handler) { |
+ if (goog.isFunction(listener)) { |
+ if (opt_handler) { |
+ listener = goog.bind(listener, opt_handler); |
+ } |
+ } else if (listener && typeof listener.handleEvent == 'function') { |
+ // using typeof to prevent strict js warning |
+ listener = goog.bind(listener.handleEvent, listener); |
+ } else { |
+ throw Error('Invalid listener argument'); |
+ } |
+ |
+ if (opt_delay > goog.Timer.MAX_TIMEOUT_) { |
+ // Timeouts greater than MAX_INT return immediately due to integer |
+ // overflow in many browsers. Since MAX_INT is 24.8 days, just don't |
+ // schedule anything at all. |
+ return -1; |
+ } else { |
+ return goog.Timer.defaultTimerObject.setTimeout( |
+ listener, opt_delay || 0); |
+ } |
+}; |
+ |
+ |
+/** |
+ * Clears a timeout initiated by callOnce |
+ * @param {?number} timerId a timer ID. |
+ */ |
+goog.Timer.clear = function(timerId) { |
+ goog.Timer.defaultTimerObject.clearTimeout(timerId); |
+}; |