http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/asserts/asserts.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/asserts/asserts.js b/externs/GCL/externs/goog/asserts/asserts.js new file mode 100644 index 0000000..95513d1 --- /dev/null +++ b/externs/GCL/externs/goog/asserts/asserts.js @@ -0,0 +1,365 @@ +// Copyright 2008 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 Utilities to check the preconditions, postconditions and + * invariants runtime. + * + * Methods in this package should be given special treatment by the compiler + * for type-inference. For example, <code>goog.asserts.assert(foo)</code> + * will restrict <code>foo</code> to a truthy value. + * + * The compiler has an option to disable asserts. So code like: + * <code> + * var x = goog.asserts.assert(foo()); goog.asserts.assert(bar()); + * </code> + * will be transformed into: + * <code> + * var x = foo(); + * </code> + * The compiler will leave in foo() (because its return value is used), + * but it will remove bar() because it assumes it does not have side-effects. + * + * @author [email protected] (Andrew Grieve) + */ + +goog.provide('goog.asserts'); +goog.provide('goog.asserts.AssertionError'); + +goog.require('goog.debug.Error'); +goog.require('goog.dom.NodeType'); +goog.require('goog.string'); + + +/** + * @define {boolean} Whether to strip out asserts or to leave them in. + */ +goog.define('goog.asserts.ENABLE_ASSERTS', goog.DEBUG); + + + +/** + * Error object for failed assertions. + * @param {string} messagePattern The pattern that was used to form message. + * @param {!Array<*>} messageArgs The items to substitute into the pattern. + * @constructor + * @extends {goog.debug.Error} + * @final + */ +goog.asserts.AssertionError = function(messagePattern, messageArgs) { + messageArgs.unshift(messagePattern); + goog.debug.Error.call(this, goog.string.subs.apply(null, messageArgs)); + // Remove the messagePattern afterwards to avoid permenantly modifying the + // passed in array. + messageArgs.shift(); + + /** + * The message pattern used to format the error message. Error handlers can + * use this to uniquely identify the assertion. + * @type {string} + */ + this.messagePattern = messagePattern; +}; +goog.inherits(goog.asserts.AssertionError, goog.debug.Error); + + +/** @override */ +goog.asserts.AssertionError.prototype.name = 'AssertionError'; + + +/** + * The default error handler. + * @param {!goog.asserts.AssertionError} e The exception to be handled. + */ +goog.asserts.DEFAULT_ERROR_HANDLER = function(e) { throw e; }; + + +/** + * The handler responsible for throwing or logging assertion errors. + * @private {function(!goog.asserts.AssertionError)} + */ +goog.asserts.errorHandler_ = goog.asserts.DEFAULT_ERROR_HANDLER; + + +/** + * Throws an exception with the given message and "Assertion failed" prefixed + * onto it. + * @param {string} defaultMessage The message to use if givenMessage is empty. + * @param {Array<*>} defaultArgs The substitution arguments for defaultMessage. + * @param {string|undefined} givenMessage Message supplied by the caller. + * @param {Array<*>} givenArgs The substitution arguments for givenMessage. + * @throws {goog.asserts.AssertionError} When the value is not a number. + * @private + */ +goog.asserts.doAssertFailure_ = + function(defaultMessage, defaultArgs, givenMessage, givenArgs) { + var message = 'Assertion failed'; + if (givenMessage) { + message += ': ' + givenMessage; + var args = givenArgs; + } else if (defaultMessage) { + message += ': ' + defaultMessage; + args = defaultArgs; + } + // The '' + works around an Opera 10 bug in the unit tests. Without it, + // a stack trace is added to var message above. With this, a stack trace is + // not added until this line (it causes the extra garbage to be added after + // the assertion message instead of in the middle of it). + var e = new goog.asserts.AssertionError('' + message, args || []); + goog.asserts.errorHandler_(e); +}; + + +/** + * Sets a custom error handler that can be used to customize the behavior of + * assertion failures, for example by turning all assertion failures into log + * messages. + * @param {function(!goog.asserts.AssertionError)} errorHandler + */ +goog.asserts.setErrorHandler = function(errorHandler) { + if (goog.asserts.ENABLE_ASSERTS) { + goog.asserts.errorHandler_ = errorHandler; + } +}; + + +/** + * Checks if the condition evaluates to true if goog.asserts.ENABLE_ASSERTS is + * true. + * @template T + * @param {T} condition The condition to check. + * @param {string=} opt_message Error message in case of failure. + * @param {...*} var_args The items to substitute into the failure message. + * @return {T} The value of the condition. + * @throws {goog.asserts.AssertionError} When the condition evaluates to false. + */ +goog.asserts.assert = function(condition, opt_message, var_args) { + if (goog.asserts.ENABLE_ASSERTS && !condition) { + goog.asserts.doAssertFailure_('', null, opt_message, + Array.prototype.slice.call(arguments, 2)); + } + return condition; +}; + + +/** + * Fails if goog.asserts.ENABLE_ASSERTS is true. This function is useful in case + * when we want to add a check in the unreachable area like switch-case + * statement: + * + * <pre> + * switch(type) { + * case FOO: doSomething(); break; + * case BAR: doSomethingElse(); break; + * default: goog.assert.fail('Unrecognized type: ' + type); + * // We have only 2 types - "default:" section is unreachable code. + * } + * </pre> + * + * @param {string=} opt_message Error message in case of failure. + * @param {...*} var_args The items to substitute into the failure message. + * @throws {goog.asserts.AssertionError} Failure. + */ +goog.asserts.fail = function(opt_message, var_args) { + if (goog.asserts.ENABLE_ASSERTS) { + goog.asserts.errorHandler_(new goog.asserts.AssertionError( + 'Failure' + (opt_message ? ': ' + opt_message : ''), + Array.prototype.slice.call(arguments, 1))); + } +}; + + +/** + * Checks if the value is a number if goog.asserts.ENABLE_ASSERTS is true. + * @param {*} value The value to check. + * @param {string=} opt_message Error message in case of failure. + * @param {...*} var_args The items to substitute into the failure message. + * @return {number} The value, guaranteed to be a number when asserts enabled. + * @throws {goog.asserts.AssertionError} When the value is not a number. + */ +goog.asserts.assertNumber = function(value, opt_message, var_args) { + if (goog.asserts.ENABLE_ASSERTS && !goog.isNumber(value)) { + goog.asserts.doAssertFailure_('Expected number but got %s: %s.', + [goog.typeOf(value), value], opt_message, + Array.prototype.slice.call(arguments, 2)); + } + return /** @type {number} */ (value); +}; + + +/** + * Checks if the value is a string if goog.asserts.ENABLE_ASSERTS is true. + * @param {*} value The value to check. + * @param {string=} opt_message Error message in case of failure. + * @param {...*} var_args The items to substitute into the failure message. + * @return {string} The value, guaranteed to be a string when asserts enabled. + * @throws {goog.asserts.AssertionError} When the value is not a string. + */ +goog.asserts.assertString = function(value, opt_message, var_args) { + if (goog.asserts.ENABLE_ASSERTS && !goog.isString(value)) { + goog.asserts.doAssertFailure_('Expected string but got %s: %s.', + [goog.typeOf(value), value], opt_message, + Array.prototype.slice.call(arguments, 2)); + } + return /** @type {string} */ (value); +}; + + +/** + * Checks if the value is a function if goog.asserts.ENABLE_ASSERTS is true. + * @param {*} value The value to check. + * @param {string=} opt_message Error message in case of failure. + * @param {...*} var_args The items to substitute into the failure message. + * @return {!Function} The value, guaranteed to be a function when asserts + * enabled. + * @throws {goog.asserts.AssertionError} When the value is not a function. + */ +goog.asserts.assertFunction = function(value, opt_message, var_args) { + if (goog.asserts.ENABLE_ASSERTS && !goog.isFunction(value)) { + goog.asserts.doAssertFailure_('Expected function but got %s: %s.', + [goog.typeOf(value), value], opt_message, + Array.prototype.slice.call(arguments, 2)); + } + return /** @type {!Function} */ (value); +}; + + +/** + * Checks if the value is an Object if goog.asserts.ENABLE_ASSERTS is true. + * @param {*} value The value to check. + * @param {string=} opt_message Error message in case of failure. + * @param {...*} var_args The items to substitute into the failure message. + * @return {!Object} The value, guaranteed to be a non-null object. + * @throws {goog.asserts.AssertionError} When the value is not an object. + */ +goog.asserts.assertObject = function(value, opt_message, var_args) { + if (goog.asserts.ENABLE_ASSERTS && !goog.isObject(value)) { + goog.asserts.doAssertFailure_('Expected object but got %s: %s.', + [goog.typeOf(value), value], + opt_message, Array.prototype.slice.call(arguments, 2)); + } + return /** @type {!Object} */ (value); +}; + + +/** + * Checks if the value is an Array if goog.asserts.ENABLE_ASSERTS is true. + * @param {*} value The value to check. + * @param {string=} opt_message Error message in case of failure. + * @param {...*} var_args The items to substitute into the failure message. + * @return {!Array<?>} The value, guaranteed to be a non-null array. + * @throws {goog.asserts.AssertionError} When the value is not an array. + */ +goog.asserts.assertArray = function(value, opt_message, var_args) { + if (goog.asserts.ENABLE_ASSERTS && !goog.isArray(value)) { + goog.asserts.doAssertFailure_('Expected array but got %s: %s.', + [goog.typeOf(value), value], opt_message, + Array.prototype.slice.call(arguments, 2)); + } + return /** @type {!Array<?>} */ (value); +}; + + +/** + * Checks if the value is a boolean if goog.asserts.ENABLE_ASSERTS is true. + * @param {*} value The value to check. + * @param {string=} opt_message Error message in case of failure. + * @param {...*} var_args The items to substitute into the failure message. + * @return {boolean} The value, guaranteed to be a boolean when asserts are + * enabled. + * @throws {goog.asserts.AssertionError} When the value is not a boolean. + */ +goog.asserts.assertBoolean = function(value, opt_message, var_args) { + if (goog.asserts.ENABLE_ASSERTS && !goog.isBoolean(value)) { + goog.asserts.doAssertFailure_('Expected boolean but got %s: %s.', + [goog.typeOf(value), value], opt_message, + Array.prototype.slice.call(arguments, 2)); + } + return /** @type {boolean} */ (value); +}; + + +/** + * Checks if the value is a DOM Element if goog.asserts.ENABLE_ASSERTS is true. + * @param {*} value The value to check. + * @param {string=} opt_message Error message in case of failure. + * @param {...*} var_args The items to substitute into the failure message. + * @return {!Element} The value, likely to be a DOM Element when asserts are + * enabled. + * @throws {goog.asserts.AssertionError} When the value is not an Element. + */ +goog.asserts.assertElement = function(value, opt_message, var_args) { + if (goog.asserts.ENABLE_ASSERTS && (!goog.isObject(value) || + value.nodeType != goog.dom.NodeType.ELEMENT)) { + goog.asserts.doAssertFailure_('Expected Element but got %s: %s.', + [goog.typeOf(value), value], opt_message, + Array.prototype.slice.call(arguments, 2)); + } + return /** @type {!Element} */ (value); +}; + + +/** + * Checks if the value is an instance of the user-defined type if + * goog.asserts.ENABLE_ASSERTS is true. + * + * The compiler may tighten the type returned by this function. + * + * @param {*} value The value to check. + * @param {function(new: T, ...)} type A user-defined constructor. + * @param {string=} opt_message Error message in case of failure. + * @param {...*} var_args The items to substitute into the failure message. + * @throws {goog.asserts.AssertionError} When the value is not an instance of + * type. + * @return {T} + * @template T + */ +goog.asserts.assertInstanceof = function(value, type, opt_message, var_args) { + if (goog.asserts.ENABLE_ASSERTS && !(value instanceof type)) { + goog.asserts.doAssertFailure_('Expected instanceof %s but got %s.', + [goog.asserts.getType_(type), goog.asserts.getType_(value)], + opt_message, Array.prototype.slice.call(arguments, 3)); + } + return value; +}; + + +/** + * Checks that no enumerable keys are present in Object.prototype. Such keys + * would break most code that use {@code for (var ... in ...)} loops. + */ +goog.asserts.assertObjectPrototypeIsIntact = function() { + for (var key in Object.prototype) { + goog.asserts.fail(key + ' should not be enumerable in Object.prototype.'); + } +}; + + +/** + * Returns the type of a value. If a constructor is passed, and a suitable + * string cannot be found, 'unknown type name' will be returned. + * @param {*} value A constructor, object, or primitive. + * @return {string} The best display name for the value, or 'unknown type name'. + * @private + */ +goog.asserts.getType_ = function(value) { + if (value instanceof Function) { + return value.displayName || value.name || 'unknown type name'; + } else if (value instanceof Object) { + return value.constructor.displayName || value.constructor.name || + Object.prototype.toString.call(value); + } else { + return value === null ? 'null' : typeof value; + } +};
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/async/animationdelay.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/async/animationdelay.js b/externs/GCL/externs/goog/async/animationdelay.js new file mode 100644 index 0000000..1e24b34 --- /dev/null +++ b/externs/GCL/externs/goog/async/animationdelay.js @@ -0,0 +1,267 @@ +// Copyright 2012 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 delayed callback that pegs to the next animation frame + * instead of a user-configurable timeout. + * + * @author [email protected] (Nick Santos) + */ + +goog.provide('goog.async.AnimationDelay'); + +goog.require('goog.Disposable'); +goog.require('goog.events'); +goog.require('goog.functions'); + + + +// TODO(nicksantos): Should we factor out the common code between this and +// goog.async.Delay? I'm not sure if there's enough code for this to really +// make sense. Subclassing seems like the wrong approach for a variety of +// reasons. Maybe there should be a common interface? + + + +/** + * A delayed callback that pegs to the next animation frame + * instead of a user configurable timeout. By design, this should have + * the same interface as goog.async.Delay. + * + * Uses requestAnimationFrame and friends when available, but falls + * back to a timeout of goog.async.AnimationDelay.TIMEOUT. + * + * For more on requestAnimationFrame and how you can use it to create smoother + * animations, see: + * @see http://paulirish.com/2011/requestanimationframe-for-smart-animating/ + * + * @param {function(number)} listener Function to call when the delay completes. + * Will be passed the timestamp when it's called, in unix ms. + * @param {Window=} opt_window The window object to execute the delay in. + * Defaults to the global object. + * @param {Object=} opt_handler The object scope to invoke the function in. + * @constructor + * @struct + * @suppress {checkStructDictInheritance} + * @extends {goog.Disposable} + * @final + */ +goog.async.AnimationDelay = function(listener, opt_window, opt_handler) { + goog.async.AnimationDelay.base(this, 'constructor'); + + /** + * Identifier of the active delay timeout, or event listener, + * or null when inactive. + * @private {goog.events.Key|number} + */ + this.id_ = null; + + /** + * If we're using dom listeners. + * @private {?boolean} + */ + this.usingListeners_ = false; + + /** + * The function that will be invoked after a delay. + * @private {function(number)} + */ + this.listener_ = listener; + + /** + * The object context to invoke the callback in. + * @private {Object|undefined} + */ + this.handler_ = opt_handler; + + /** + * @private {Window} + */ + this.win_ = opt_window || window; + + /** + * Cached callback function invoked when the delay finishes. + * @private {function()} + */ + this.callback_ = goog.bind(this.doAction_, this); +}; +goog.inherits(goog.async.AnimationDelay, goog.Disposable); + + +/** + * Default wait timeout for animations (in milliseconds). Only used for timed + * animation, which uses a timer (setTimeout) to schedule animation. + * + * @type {number} + * @const + */ +goog.async.AnimationDelay.TIMEOUT = 20; + + +/** + * Name of event received from the requestAnimationFrame in Firefox. + * + * @type {string} + * @const + * @private + */ +goog.async.AnimationDelay.MOZ_BEFORE_PAINT_EVENT_ = 'MozBeforePaint'; + + +/** + * Starts the delay timer. The provided listener function will be called + * before the next animation frame. + */ +goog.async.AnimationDelay.prototype.start = function() { + this.stop(); + this.usingListeners_ = false; + + var raf = this.getRaf_(); + var cancelRaf = this.getCancelRaf_(); + if (raf && !cancelRaf && this.win_.mozRequestAnimationFrame) { + // Because Firefox (Gecko) runs animation in separate threads, it also saves + // time by running the requestAnimationFrame callbacks in that same thread. + // Sadly this breaks the assumption of implicit thread-safety in JS, and can + // thus create thread-based inconsistencies on counters etc. + // + // Calling cycleAnimations_ using the MozBeforePaint event instead of as + // callback fixes this. + // + // Trigger this condition only if the mozRequestAnimationFrame is available, + // but not the W3C requestAnimationFrame function (as in draft) or the + // equivalent cancel functions. + this.id_ = goog.events.listen( + this.win_, + goog.async.AnimationDelay.MOZ_BEFORE_PAINT_EVENT_, + this.callback_); + this.win_.mozRequestAnimationFrame(null); + this.usingListeners_ = true; + } else if (raf && cancelRaf) { + this.id_ = raf.call(this.win_, this.callback_); + } else { + this.id_ = this.win_.setTimeout( + // Prior to Firefox 13, Gecko passed a non-standard parameter + // to the callback that we want to ignore. + goog.functions.lock(this.callback_), + goog.async.AnimationDelay.TIMEOUT); + } +}; + + +/** + * Stops the delay timer if it is active. No action is taken if the timer is not + * in use. + */ +goog.async.AnimationDelay.prototype.stop = function() { + if (this.isActive()) { + var raf = this.getRaf_(); + var cancelRaf = this.getCancelRaf_(); + if (raf && !cancelRaf && this.win_.mozRequestAnimationFrame) { + goog.events.unlistenByKey(this.id_); + } else if (raf && cancelRaf) { + cancelRaf.call(this.win_, /** @type {number} */ (this.id_)); + } else { + this.win_.clearTimeout(/** @type {number} */ (this.id_)); + } + } + this.id_ = null; +}; + + +/** + * Fires delay's action even if timer has already gone off or has not been + * started yet; guarantees action firing. Stops the delay timer. + */ +goog.async.AnimationDelay.prototype.fire = function() { + this.stop(); + this.doAction_(); +}; + + +/** + * Fires delay's action only if timer is currently active. Stops the delay + * timer. + */ +goog.async.AnimationDelay.prototype.fireIfActive = function() { + if (this.isActive()) { + this.fire(); + } +}; + + +/** + * @return {boolean} True if the delay is currently active, false otherwise. + */ +goog.async.AnimationDelay.prototype.isActive = function() { + return this.id_ != null; +}; + + +/** + * Invokes the callback function after the delay successfully completes. + * @private + */ +goog.async.AnimationDelay.prototype.doAction_ = function() { + if (this.usingListeners_ && this.id_) { + goog.events.unlistenByKey(this.id_); + } + this.id_ = null; + + // We are not using the timestamp returned by requestAnimationFrame + // because it may be either a Date.now-style time or a + // high-resolution time (depending on browser implementation). Using + // goog.now() will ensure that the timestamp used is consistent and + // compatible with goog.fx.Animation. + this.listener_.call(this.handler_, goog.now()); +}; + + +/** @override */ +goog.async.AnimationDelay.prototype.disposeInternal = function() { + this.stop(); + goog.async.AnimationDelay.base(this, 'disposeInternal'); +}; + + +/** + * @return {?function(function(number)): number} The requestAnimationFrame + * function, or null if not available on this browser. + * @private + */ +goog.async.AnimationDelay.prototype.getRaf_ = function() { + var win = this.win_; + return win.requestAnimationFrame || + win.webkitRequestAnimationFrame || + win.mozRequestAnimationFrame || + win.oRequestAnimationFrame || + win.msRequestAnimationFrame || + null; +}; + + +/** + * @return {?function(number): number} The cancelAnimationFrame function, + * or null if not available on this browser. + * @private + */ +goog.async.AnimationDelay.prototype.getCancelRaf_ = function() { + var win = this.win_; + return win.cancelAnimationFrame || + win.cancelRequestAnimationFrame || + win.webkitCancelRequestAnimationFrame || + win.mozCancelRequestAnimationFrame || + win.oCancelRequestAnimationFrame || + win.msCancelRequestAnimationFrame || + null; +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/async/conditionaldelay.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/async/conditionaldelay.js b/externs/GCL/externs/goog/async/conditionaldelay.js new file mode 100644 index 0000000..c5ff892 --- /dev/null +++ b/externs/GCL/externs/goog/async/conditionaldelay.js @@ -0,0 +1,228 @@ +// Copyright 2008 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 Defines a class useful for handling functions that must be + * invoked later when some condition holds. Examples include deferred function + * calls that return a boolean flag whether it succedeed or not. + * + * Example: + * + * function deferred() { + * var succeeded = false; + * // ... custom code + * return succeeded; + * } + * + * var deferredCall = new goog.async.ConditionalDelay(deferred); + * deferredCall.onSuccess = function() { + * alert('Success: The deferred function has been successfully executed.'); + * } + * deferredCall.onFailure = function() { + * alert('Failure: Time limit exceeded.'); + * } + * + * // Call the deferred() every 100 msec until it returns true, + * // or 5 seconds pass. + * deferredCall.start(100, 5000); + * + * // Stop the deferred function call (does nothing if it's not active). + * deferredCall.stop(); + * + */ + + +goog.provide('goog.async.ConditionalDelay'); + +goog.require('goog.Disposable'); +goog.require('goog.async.Delay'); + + + +/** + * A ConditionalDelay object invokes the associated function after a specified + * interval delay and checks its return value. If the function returns + * {@code true} the conditional delay is cancelled and {@see #onSuccess} + * is called. Otherwise this object keeps to invoke the deferred function until + * either it returns {@code true} or the timeout is exceeded. In the latter case + * the {@see #onFailure} method will be called. + * + * The interval duration and timeout can be specified each time the delay is + * started. Calling start on an active delay will reset the timer. + * + * @param {function():boolean} listener Function to call when the delay + * completes. Should return a value that type-converts to {@code true} if + * the call succeeded and this delay should be stopped. + * @param {Object=} opt_handler The object scope to invoke the function in. + * @constructor + * @struct + * @suppress {checkStructDictInheritance} + * @extends {goog.Disposable} + */ +goog.async.ConditionalDelay = function(listener, opt_handler) { + goog.async.ConditionalDelay.base(this, 'constructor'); + + /** + * The delay interval in milliseconds to between the calls to the callback. + * Note, that the callback may be invoked earlier than this interval if the + * timeout is exceeded. + * @private {number} + */ + this.interval_ = 0; + + /** + * The timeout timestamp until which the delay is to be executed. + * A negative value means no timeout. + * @private {number} + */ + this.runUntil_ = 0; + + /** + * True if the listener has been executed, and it returned {@code true}. + * @private {boolean} + */ + this.isDone_ = false; + + /** + * The function that will be invoked after a delay. + * @private {function():boolean} + */ + this.listener_ = listener; + + /** + * The object context to invoke the callback in. + * @private {Object|undefined} + */ + this.handler_ = opt_handler; + + /** + * The underlying goog.async.Delay delegate object. + * @private {goog.async.Delay} + */ + this.delay_ = new goog.async.Delay( + goog.bind(this.onTick_, this), 0 /*interval*/, this /*scope*/); +}; +goog.inherits(goog.async.ConditionalDelay, goog.Disposable); + + +/** @override */ +goog.async.ConditionalDelay.prototype.disposeInternal = function() { + this.delay_.dispose(); + delete this.listener_; + delete this.handler_; + goog.async.ConditionalDelay.superClass_.disposeInternal.call(this); +}; + + +/** + * Starts the delay timer. The provided listener function will be called + * repeatedly after the specified interval until the function returns + * {@code true} or the timeout is exceeded. Calling start on an active timer + * will stop the timer first. + * @param {number=} opt_interval The time interval between the function + * invocations (in milliseconds). Default is 0. + * @param {number=} opt_timeout The timeout interval (in milliseconds). Takes + * precedence over the {@code opt_interval}, i.e. if the timeout is less + * than the invocation interval, the function will be called when the + * timeout is exceeded. A negative value means no timeout. Default is 0. + */ +goog.async.ConditionalDelay.prototype.start = function(opt_interval, + opt_timeout) { + this.stop(); + this.isDone_ = false; + + var timeout = opt_timeout || 0; + this.interval_ = Math.max(opt_interval || 0, 0); + this.runUntil_ = timeout < 0 ? -1 : (goog.now() + timeout); + this.delay_.start( + timeout < 0 ? this.interval_ : Math.min(this.interval_, timeout)); +}; + + +/** + * Stops the delay timer if it is active. No action is taken if the timer is not + * in use. + */ +goog.async.ConditionalDelay.prototype.stop = function() { + this.delay_.stop(); +}; + + +/** + * @return {boolean} True if the delay is currently active, false otherwise. + */ +goog.async.ConditionalDelay.prototype.isActive = function() { + return this.delay_.isActive(); +}; + + +/** + * @return {boolean} True if the listener has been executed and returned + * {@code true} since the last call to {@see #start}. + */ +goog.async.ConditionalDelay.prototype.isDone = function() { + return this.isDone_; +}; + + +/** + * Called when the listener has been successfully executed and returned + * {@code true}. The {@see #isDone} method should return {@code true} by now. + * Designed for inheritance, should be overridden by subclasses or on the + * instances if they care. + */ +goog.async.ConditionalDelay.prototype.onSuccess = function() { + // Do nothing by default. +}; + + +/** + * Called when this delayed call is cancelled because the timeout has been + * exceeded, and the listener has never returned {@code true}. + * Designed for inheritance, should be overridden by subclasses or on the + * instances if they care. + */ +goog.async.ConditionalDelay.prototype.onFailure = function() { + // Do nothing by default. +}; + + +/** + * A callback function for the underlying {@code goog.async.Delay} object. When + * executed the listener function is called, and if it returns {@code true} + * the delay is stopped and the {@see #onSuccess} method is invoked. + * If the timeout is exceeded the delay is stopped and the + * {@see #onFailure} method is called. + * @private + */ +goog.async.ConditionalDelay.prototype.onTick_ = function() { + var successful = this.listener_.call(this.handler_); + if (successful) { + this.isDone_ = true; + this.onSuccess(); + } else { + // Try to reschedule the task. + if (this.runUntil_ < 0) { + // No timeout. + this.delay_.start(this.interval_); + } else { + var timeLeft = this.runUntil_ - goog.now(); + if (timeLeft <= 0) { + this.onFailure(); + } else { + this.delay_.start(Math.min(this.interval_, timeLeft)); + } + } + } +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/async/delay.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/async/delay.js b/externs/GCL/externs/goog/async/delay.js new file mode 100644 index 0000000..0b8225d --- /dev/null +++ b/externs/GCL/externs/goog/async/delay.js @@ -0,0 +1,182 @@ +// Copyright 2007 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 Defines a class useful for handling functions that must be + * invoked after a delay, especially when that delay is frequently restarted. + * Examples include delaying before displaying a tooltip, menu hysteresis, + * idle timers, etc. + * @author [email protected] (Shawn Brenneman) + * @see ../demos/timers.html + */ + + +goog.provide('goog.Delay'); +goog.provide('goog.async.Delay'); + +goog.require('goog.Disposable'); +goog.require('goog.Timer'); + + + +/** + * A Delay object invokes the associated function after a specified delay. The + * interval duration can be specified once in the constructor, or can be defined + * each time the delay is started. Calling start on an active delay will reset + * the timer. + * + * @param {function(this:THIS)} listener Function to call when the + * delay completes. + * @param {number=} opt_interval The default length of the invocation delay (in + * milliseconds). + * @param {THIS=} opt_handler The object scope to invoke the function in. + * @template THIS + * @constructor + * @struct + * @suppress {checkStructDictInheritance} + * @extends {goog.Disposable} + * @final + */ +goog.async.Delay = function(listener, opt_interval, opt_handler) { + goog.async.Delay.base(this, 'constructor'); + + /** + * The function that will be invoked after a delay. + * @private {function(this:THIS)} + */ + this.listener_ = listener; + + /** + * The default amount of time to delay before invoking the callback. + * @type {number} + * @private + */ + this.interval_ = opt_interval || 0; + + /** + * The object context to invoke the callback in. + * @type {Object|undefined} + * @private + */ + this.handler_ = opt_handler; + + + /** + * Cached callback function invoked when the delay finishes. + * @type {Function} + * @private + */ + this.callback_ = goog.bind(this.doAction_, this); +}; +goog.inherits(goog.async.Delay, goog.Disposable); + + + +/** + * A deprecated alias. + * @deprecated Use goog.async.Delay instead. + * @constructor + * @final + */ +goog.Delay = goog.async.Delay; + + +/** + * Identifier of the active delay timeout, or 0 when inactive. + * @type {number} + * @private + */ +goog.async.Delay.prototype.id_ = 0; + + +/** + * Disposes of the object, cancelling the timeout if it is still outstanding and + * removing all object references. + * @override + * @protected + */ +goog.async.Delay.prototype.disposeInternal = function() { + goog.async.Delay.base(this, 'disposeInternal'); + this.stop(); + delete this.listener_; + delete this.handler_; +}; + + +/** + * Starts the delay timer. The provided listener function will be called after + * the specified interval. Calling start on an active timer will reset the + * delay interval. + * @param {number=} opt_interval If specified, overrides the object's default + * interval with this one (in milliseconds). + */ +goog.async.Delay.prototype.start = function(opt_interval) { + this.stop(); + this.id_ = goog.Timer.callOnce( + this.callback_, + goog.isDef(opt_interval) ? opt_interval : this.interval_); +}; + + +/** + * Stops the delay timer if it is active. No action is taken if the timer is not + * in use. + */ +goog.async.Delay.prototype.stop = function() { + if (this.isActive()) { + goog.Timer.clear(this.id_); + } + this.id_ = 0; +}; + + +/** + * Fires delay's action even if timer has already gone off or has not been + * started yet; guarantees action firing. Stops the delay timer. + */ +goog.async.Delay.prototype.fire = function() { + this.stop(); + this.doAction_(); +}; + + +/** + * Fires delay's action only if timer is currently active. Stops the delay + * timer. + */ +goog.async.Delay.prototype.fireIfActive = function() { + if (this.isActive()) { + this.fire(); + } +}; + + +/** + * @return {boolean} True if the delay is currently active, false otherwise. + */ +goog.async.Delay.prototype.isActive = function() { + return this.id_ != 0; +}; + + +/** + * Invokes the callback function after the delay successfully completes. + * @private + */ +goog.async.Delay.prototype.doAction_ = function() { + this.id_ = 0; + if (this.listener_) { + this.listener_.call(this.handler_); + } +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/async/freelist.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/async/freelist.js b/externs/GCL/externs/goog/async/freelist.js new file mode 100644 index 0000000..d0331f2 --- /dev/null +++ b/externs/GCL/externs/goog/async/freelist.js @@ -0,0 +1,88 @@ +// Copyright 2015 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 Simple freelist. + * + * An anterative to goog.structs.SimplePool, it imposes the requirement that the + * objects in the list contain a "next" property that can be used to maintain + * the pool. + */ + +goog.provide('goog.async.FreeList'); + + +/** + * @template ITEM + */ +goog.async.FreeList = goog.defineClass(null, { + /** + * @param {function():ITEM} create + * @param {function(ITEM):void} reset + * @param {number} limit + */ + constructor: function(create, reset, limit) { + /** @const {number} */ + this.limit_ = limit; + /** @const {function()} */ + this.create_ = create; + /** @const {function(ITEM):void} */ + this.reset_ = reset; + + /** @type {number} */ + this.occupants_ = 0; + /** @type {ITEM} */ + this.head_ = null; + }, + + /** + * @return {ITEM} + */ + get: function() { + var item; + if (this.occupants_ > 0) { + this.occupants_--; + item = this.head_; + this.head_ = item.next; + item.next = null; + } else { + item = this.create_(); + } + return item; + }, + + /** + * @param {ITEM} item An item available for possible future reuse. + */ + put: function(item) { + this.reset_(item); + if (this.occupants_ < this.limit_) { + this.occupants_++; + item.next = this.head_; + this.head_ = item; + } + }, + + /** + * Visible for testing. + * @package + * @return {number} + */ + occupants: function() { + return this.occupants_; + } +}); + + + http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/async/nexttick.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/async/nexttick.js b/externs/GCL/externs/goog/async/nexttick.js new file mode 100644 index 0000000..bdbad6b --- /dev/null +++ b/externs/GCL/externs/goog/async/nexttick.js @@ -0,0 +1,241 @@ +// Copyright 2013 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 Provides a function to schedule running a function as soon + * as possible after the current JS execution stops and yields to the event + * loop. + * + */ + +goog.provide('goog.async.nextTick'); +goog.provide('goog.async.throwException'); + +goog.require('goog.debug.entryPointRegistry'); +goog.require('goog.dom.TagName'); +goog.require('goog.functions'); +goog.require('goog.labs.userAgent.browser'); +goog.require('goog.labs.userAgent.engine'); + + +/** + * Throw an item without interrupting the current execution context. For + * example, if processing a group of items in a loop, sometimes it is useful + * to report an error while still allowing the rest of the batch to be + * processed. + * @param {*} exception + */ +goog.async.throwException = function(exception) { + // Each throw needs to be in its own context. + goog.global.setTimeout(function() { throw exception; }, 0); +}; + + +/** + * Fires the provided callbacks as soon as possible after the current JS + * execution context. setTimeout(â¦, 0) takes at least 4ms when called from + * within another setTimeout(â¦, 0) for legacy reasons. + * + * This will not schedule the callback as a microtask (i.e. a task that can + * preempt user input or networking callbacks). It is meant to emulate what + * setTimeout(_, 0) would do if it were not throttled. If you desire microtask + * behavior, use {@see goog.Promise} instead. + * + * @param {function(this:SCOPE)} callback Callback function to fire as soon as + * possible. + * @param {SCOPE=} opt_context Object in whose scope to call the listener. + * @param {boolean=} opt_useSetImmediate Avoid the IE workaround that + * ensures correctness at the cost of speed. See comments for details. + * @template SCOPE + */ +goog.async.nextTick = function(callback, opt_context, opt_useSetImmediate) { + var cb = callback; + if (opt_context) { + cb = goog.bind(callback, opt_context); + } + cb = goog.async.nextTick.wrapCallback_(cb); + // window.setImmediate was introduced and currently only supported by IE10+, + // but due to a bug in the implementation it is not guaranteed that + // setImmediate is faster than setTimeout nor that setImmediate N is before + // setImmediate N+1. That is why we do not use the native version if + // available. We do, however, call setImmediate if it is a normal function + // because that indicates that it has been replaced by goog.testing.MockClock + // which we do want to support. + // See + // http://connect.microsoft.com/IE/feedback/details/801823/setimmediate-and-messagechannel-are-broken-in-ie10 + // + // Note we do allow callers to also request setImmediate if they are willing + // to accept the possible tradeoffs of incorrectness in exchange for speed. + // The IE fallback of readystate change is much slower. + if (goog.isFunction(goog.global.setImmediate) && + // Opt in. + (opt_useSetImmediate || + // or it isn't a browser or the environment is weird + !goog.global.Window || !goog.global.Window.prototype || + // or something redefined setImmediate in which case we (YOLO) decide + // to use it (This is so that we use the mockClock setImmediate. sigh). + goog.global.Window.prototype.setImmediate != goog.global.setImmediate)) { + goog.global.setImmediate(cb); + return; + } + + // Look for and cache the custom fallback version of setImmediate. + if (!goog.async.nextTick.setImmediate_) { + goog.async.nextTick.setImmediate_ = + goog.async.nextTick.getSetImmediateEmulator_(); + } + goog.async.nextTick.setImmediate_(cb); +}; + + +/** + * Cache for the setImmediate implementation. + * @type {function(function())} + * @private + */ +goog.async.nextTick.setImmediate_; + + +/** + * Determines the best possible implementation to run a function as soon as + * the JS event loop is idle. + * @return {function(function())} The "setImmediate" implementation. + * @private + */ +goog.async.nextTick.getSetImmediateEmulator_ = function() { + // Create a private message channel and use it to postMessage empty messages + // to ourselves. + var Channel = goog.global['MessageChannel']; + // If MessageChannel is not available and we are in a browser, implement + // an iframe based polyfill in browsers that have postMessage and + // document.addEventListener. The latter excludes IE8 because it has a + // synchronous postMessage implementation. + if (typeof Channel === 'undefined' && typeof window !== 'undefined' && + window.postMessage && window.addEventListener && + // Presto (The old pre-blink Opera engine) has problems with iframes + // and contentWindow. + !goog.labs.userAgent.engine.isPresto()) { + /** @constructor */ + Channel = function() { + // Make an empty, invisible iframe. + var iframe = document.createElement(goog.dom.TagName.IFRAME); + iframe.style.display = 'none'; + iframe.src = ''; + document.documentElement.appendChild(iframe); + var win = iframe.contentWindow; + var doc = win.document; + doc.open(); + doc.write(''); + doc.close(); + // Do not post anything sensitive over this channel, as the workaround for + // pages with file: origin could allow that information to be modified or + // intercepted. + var message = 'callImmediate' + Math.random(); + // The same origin policy rejects attempts to postMessage from file: urls + // unless the origin is '*'. + // TODO(b/16335441): Use '*' origin for data: and other similar protocols. + var origin = win.location.protocol == 'file:' ? + '*' : win.location.protocol + '//' + win.location.host; + var onmessage = goog.bind(function(e) { + // Validate origin and message to make sure that this message was + // intended for us. If the origin is set to '*' (see above) only the + // message needs to match since, for example, '*' != 'file://'. Allowing + // the wildcard is ok, as we are not concerned with security here. + if ((origin != '*' && e.origin != origin) || e.data != message) { + return; + } + this['port1'].onmessage(); + }, this); + win.addEventListener('message', onmessage, false); + this['port1'] = {}; + this['port2'] = { + postMessage: function() { + win.postMessage(message, origin); + } + }; + }; + } + if (typeof Channel !== 'undefined' && + (!goog.labs.userAgent.browser.isIE())) { + // Exclude all of IE due to + // http://codeforhire.com/2013/09/21/setimmediate-and-messagechannel-broken-on-internet-explorer-10/ + // which allows starving postMessage with a busy setTimeout loop. + // This currently affects IE10 and IE11 which would otherwise be able + // to use the postMessage based fallbacks. + var channel = new Channel(); + // Use a fifo linked list to call callbacks in the right order. + var head = {}; + var tail = head; + channel['port1'].onmessage = function() { + if (goog.isDef(head.next)) { + head = head.next; + var cb = head.cb; + head.cb = null; + cb(); + } + }; + return function(cb) { + tail.next = { + cb: cb + }; + tail = tail.next; + channel['port2'].postMessage(0); + }; + } + // Implementation for IE6+: Script elements fire an asynchronous + // onreadystatechange event when inserted into the DOM. + if (typeof document !== 'undefined' && 'onreadystatechange' in + document.createElement(goog.dom.TagName.SCRIPT)) { + return function(cb) { + var script = document.createElement(goog.dom.TagName.SCRIPT); + script.onreadystatechange = function() { + // Clean up and call the callback. + script.onreadystatechange = null; + script.parentNode.removeChild(script); + script = null; + cb(); + cb = null; + }; + document.documentElement.appendChild(script); + }; + } + // Fall back to setTimeout with 0. In browsers this creates a delay of 5ms + // or more. + return function(cb) { + goog.global.setTimeout(cb, 0); + }; +}; + + +/** + * Helper function that is overrided to protect callbacks with entry point + * monitor if the application monitors entry points. + * @param {function()} callback Callback function to fire as soon as possible. + * @return {function()} The wrapped callback. + * @private + */ +goog.async.nextTick.wrapCallback_ = goog.functions.identity; + + +// Register the callback function as an entry point, so that it can be +// monitored for exception handling, etc. This has to be done in this file +// since it requires special code to handle all browsers. +goog.debug.entryPointRegistry.register( + /** + * @param {function(!Function): !Function} transformer The transforming + * function. + */ + function(transformer) { + goog.async.nextTick.wrapCallback_ = transformer; + }); http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/async/run.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/async/run.js b/externs/GCL/externs/goog/async/run.js new file mode 100644 index 0000000..b621477 --- /dev/null +++ b/externs/GCL/externs/goog/async/run.js @@ -0,0 +1,130 @@ +// Copyright 2013 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. + +goog.provide('goog.async.run'); + +goog.require('goog.async.WorkQueue'); +goog.require('goog.async.nextTick'); +goog.require('goog.async.throwException'); +goog.require('goog.testing.watchers'); + + +/** + * Fires the provided callback just before the current callstack unwinds, or as + * soon as possible after the current JS execution context. + * @param {function(this:THIS)} callback + * @param {THIS=} opt_context Object to use as the "this value" when calling + * the provided function. + * @template THIS + */ +goog.async.run = function(callback, opt_context) { + if (!goog.async.run.schedule_) { + goog.async.run.initializeRunner_(); + } + if (!goog.async.run.workQueueScheduled_) { + // Nothing is currently scheduled, schedule it now. + goog.async.run.schedule_(); + goog.async.run.workQueueScheduled_ = true; + } + + goog.async.run.workQueue_.add(callback, opt_context); +}; + + +/** + * Initializes the function to use to process the work queue. + * @private + */ +goog.async.run.initializeRunner_ = function() { + // If native Promises are available in the browser, just schedule the callback + // on a fulfilled promise, which is specified to be async, but as fast as + // possible. + if (goog.global.Promise && goog.global.Promise.resolve) { + var promise = goog.global.Promise.resolve(); + goog.async.run.schedule_ = function() { + promise.then(goog.async.run.processWorkQueue); + }; + } else { + goog.async.run.schedule_ = function() { + goog.async.nextTick(goog.async.run.processWorkQueue); + }; + } +}; + + +/** + * Forces goog.async.run to use nextTick instead of Promise. + * + * This should only be done in unit tests. It's useful because MockClock + * replaces nextTick, but not the browser Promise implementation, so it allows + * Promise-based code to be tested with MockClock. + */ +goog.async.run.forceNextTick = function() { + goog.async.run.schedule_ = function() { + goog.async.nextTick(goog.async.run.processWorkQueue); + }; +}; + + +/** + * The function used to schedule work asynchronousely. + * @private {function()} + */ +goog.async.run.schedule_; + + +/** @private {boolean} */ +goog.async.run.workQueueScheduled_ = false; + + +/** @private {!goog.async.WorkQueue} */ +goog.async.run.workQueue_ = new goog.async.WorkQueue(); + + +if (goog.DEBUG) { + /** + * Reset the work queue. + * @private + */ + goog.async.run.resetQueue_ = function() { + goog.async.run.workQueueScheduled_ = false; + goog.async.run.workQueue_ = new goog.async.WorkQueue(); + }; + + // If there is a clock implemenation in use for testing + // and it is reset, reset the queue. + goog.testing.watchers.watchClockReset(goog.async.run.resetQueue_); +} + + +/** + * Run any pending goog.async.run work items. This function is not intended + * for general use, but for use by entry point handlers to run items ahead of + * goog.async.nextTick. + */ +goog.async.run.processWorkQueue = function() { + // NOTE: additional work queue items may be added while processing. + var item = null; + while (item = goog.async.run.workQueue_.remove()) { + try { + item.fn.call(item.scope); + } catch (e) { + goog.async.throwException(e); + } + goog.async.run.workQueue_.returnUnused(item); + } + + // There are no more work items, allow processing to be scheduled again. + goog.async.run.workQueueScheduled_ = false; +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/async/throttle.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/async/throttle.js b/externs/GCL/externs/goog/async/throttle.js new file mode 100644 index 0000000..2efa119 --- /dev/null +++ b/externs/GCL/externs/goog/async/throttle.js @@ -0,0 +1,195 @@ +// Copyright 2007 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 Definition of the goog.async.Throttle class. + * + * @see ../demos/timers.html + */ + +goog.provide('goog.Throttle'); +goog.provide('goog.async.Throttle'); + +goog.require('goog.Disposable'); +goog.require('goog.Timer'); + + + +/** + * Throttle will perform an action that is passed in no more than once + * per interval (specified in milliseconds). If it gets multiple signals + * to perform the action while it is waiting, it will only perform the action + * once at the end of the interval. + * @param {function(this: T)} listener Function to callback when the action is + * triggered. + * @param {number} interval Interval over which to throttle. The listener can + * only be called once per interval. + * @param {T=} opt_handler Object in whose scope to call the listener. + * @constructor + * @struct + * @suppress {checkStructDictInheritance} + * @extends {goog.Disposable} + * @final + * @template T + */ +goog.async.Throttle = function(listener, interval, opt_handler) { + goog.async.Throttle.base(this, 'constructor'); + + /** + * Function to callback + * @type {function(this: T)} + * @private + */ + this.listener_ = listener; + + /** + * Interval for the throttle time + * @type {number} + * @private + */ + this.interval_ = interval; + + /** + * "this" context for the listener + * @type {Object|undefined} + * @private + */ + this.handler_ = opt_handler; + + /** + * Cached callback function invoked after the throttle timeout completes + * @type {Function} + * @private + */ + this.callback_ = goog.bind(this.onTimer_, this); +}; +goog.inherits(goog.async.Throttle, goog.Disposable); + + + +/** + * A deprecated alias. + * @deprecated Use goog.async.Throttle instead. + * @constructor + * @final + */ +goog.Throttle = goog.async.Throttle; + + +/** + * Indicates that the action is pending and needs to be fired. + * @type {boolean} + * @private + */ +goog.async.Throttle.prototype.shouldFire_ = false; + + +/** + * Indicates the count of nested pauses currently in effect on the throttle. + * When this count is not zero, fired actions will be postponed until the + * throttle is resumed enough times to drop the pause count to zero. + * @type {number} + * @private + */ +goog.async.Throttle.prototype.pauseCount_ = 0; + + +/** + * Timer for scheduling the next callback + * @type {?number} + * @private + */ +goog.async.Throttle.prototype.timer_ = null; + + +/** + * Notifies the throttle that the action has happened. It will throttle the call + * so that the callback is not called too often according to the interval + * parameter passed to the constructor. + */ +goog.async.Throttle.prototype.fire = function() { + if (!this.timer_ && !this.pauseCount_) { + this.doAction_(); + } else { + this.shouldFire_ = true; + } +}; + + +/** + * Cancels any pending action callback. The throttle can be restarted by + * calling {@link #fire}. + */ +goog.async.Throttle.prototype.stop = function() { + if (this.timer_) { + goog.Timer.clear(this.timer_); + this.timer_ = null; + this.shouldFire_ = false; + } +}; + + +/** + * Pauses the throttle. All pending and future action callbacks will be + * delayed until the throttle is resumed. Pauses can be nested. + */ +goog.async.Throttle.prototype.pause = function() { + this.pauseCount_++; +}; + + +/** + * Resumes the throttle. If doing so drops the pausing count to zero, pending + * action callbacks will be executed as soon as possible, but still no sooner + * than an interval's delay after the previous call. Future action callbacks + * will be executed as normal. + */ +goog.async.Throttle.prototype.resume = function() { + this.pauseCount_--; + if (!this.pauseCount_ && this.shouldFire_ && !this.timer_) { + this.shouldFire_ = false; + this.doAction_(); + } +}; + + +/** @override */ +goog.async.Throttle.prototype.disposeInternal = function() { + goog.async.Throttle.base(this, 'disposeInternal'); + this.stop(); +}; + + +/** + * Handler for the timer to fire the throttle + * @private + */ +goog.async.Throttle.prototype.onTimer_ = function() { + this.timer_ = null; + + if (this.shouldFire_ && !this.pauseCount_) { + this.shouldFire_ = false; + this.doAction_(); + } +}; + + +/** + * Calls the callback + * @private + */ +goog.async.Throttle.prototype.doAction_ = function() { + this.timer_ = goog.Timer.callOnce(this.callback_, this.interval_); + this.listener_.call(this.handler_); +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/async/workqueue.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/async/workqueue.js b/externs/GCL/externs/goog/async/workqueue.js new file mode 100644 index 0000000..2d86c89 --- /dev/null +++ b/externs/GCL/externs/goog/async/workqueue.js @@ -0,0 +1,139 @@ +// Copyright 2015 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. + +goog.provide('goog.async.WorkItem'); +goog.provide('goog.async.WorkQueue'); + +goog.require('goog.asserts'); +goog.require('goog.async.FreeList'); + + +// TODO(johnlenz): generalize the WorkQueue if this is used by more +// than goog.async.run. + + + +/** + * A low GC workqueue. The key elements of this design: + * - avoids the need for goog.bind or equivalent by carrying scope + * - avoids the need for array reallocation by using a linked list + * - minimizes work entry objects allocation by recycling objects + * @constructor + * @final + * @struct + */ +goog.async.WorkQueue = function() { + this.workHead_ = null; + this.workTail_ = null; +}; + + +/** @define {number} The maximum number of entries to keep for recycling. */ +goog.define('goog.async.WorkQueue.DEFAULT_MAX_UNUSED', 100); + + +/** @const @private {goog.async.FreeList<goog.async.WorkItem>} */ +goog.async.WorkQueue.freelist_ = new goog.async.FreeList( + function() {return new goog.async.WorkItem(); }, + function(item) {item.reset()}, + goog.async.WorkQueue.DEFAULT_MAX_UNUSED); + + +/** + * @param {function()} fn + * @param {Object|null|undefined} scope + */ +goog.async.WorkQueue.prototype.add = function(fn, scope) { + var item = this.getUnusedItem_(); + item.set(fn, scope); + + if (this.workTail_) { + this.workTail_.next = item; + this.workTail_ = item; + } else { + goog.asserts.assert(!this.workHead_); + this.workHead_ = item; + this.workTail_ = item; + } +}; + + +/** + * @return {goog.async.WorkItem} + */ +goog.async.WorkQueue.prototype.remove = function() { + var item = null; + + if (this.workHead_) { + item = this.workHead_; + this.workHead_ = this.workHead_.next; + if (!this.workHead_) { + this.workTail_ = null; + } + item.next = null; + } + return item; +}; + + +/** + * @param {goog.async.WorkItem} item + */ +goog.async.WorkQueue.prototype.returnUnused = function(item) { + goog.async.WorkQueue.freelist_.put(item); +}; + + +/** + * @return {goog.async.WorkItem} + * @private + */ +goog.async.WorkQueue.prototype.getUnusedItem_ = function() { + return goog.async.WorkQueue.freelist_.get(); +}; + + + +/** + * @constructor + * @final + * @struct + */ +goog.async.WorkItem = function() { + /** @type {?function()} */ + this.fn = null; + /** @type {Object|null|undefined} */ + this.scope = null; + /** @type {?goog.async.WorkItem} */ + this.next = null; +}; + + +/** + * @param {function()} fn + * @param {Object|null|undefined} scope + */ +goog.async.WorkItem.prototype.set = function(fn, scope) { + this.fn = fn; + this.scope = scope; + this.next = null; +}; + + +/** Reset the work item so they don't prevent GC before reuse */ +goog.async.WorkItem.prototype.reset = function() { + this.fn = null; + this.scope = null; + this.next = null; +};
