Index: third_party/google_input_tools/third_party/closure_library/closure/goog/async/nexttick.js |
diff --git a/third_party/google_input_tools/third_party/closure_library/closure/goog/async/nexttick.js b/third_party/google_input_tools/third_party/closure_library/closure/goog/async/nexttick.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ad2cb9e5891857429d256b70401bb62b0d9528ee |
--- /dev/null |
+++ b/third_party/google_input_tools/third_party/closure_library/closure/goog/async/nexttick.js |
@@ -0,0 +1,203 @@ |
+// 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.functions'); |
+ |
+ |
+/** |
+ * 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) always takes at least 5ms 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. |
+ * @template SCOPE |
+ */ |
+goog.async.nextTick = function(callback, opt_context) { |
+ var cb = callback; |
+ if (opt_context) { |
+ cb = goog.bind(callback, opt_context); |
+ } |
+ cb = goog.async.nextTick.wrapCallback_(cb); |
+ // Introduced and currently only supported by IE10. |
+ if (goog.isFunction(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) { |
+ /** @constructor */ |
+ Channel = function() { |
+ // Make an empty, invisible iframe. |
+ var iframe = document.createElement('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 (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') { |
+ 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() { |
+ 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-8: Script elements fire an asynchronous |
+ // onreadystatechange event when inserted into the DOM. |
+ if (typeof document !== 'undefined' && 'onreadystatechange' in |
+ document.createElement('script')) { |
+ return function(cb) { |
+ var script = document.createElement('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; |
+ }); |