Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Unified Diff: third_party/google_input_tools/third_party/closure_library/closure/goog/async/nexttick.js

Issue 1257313003: Update Google Input Tools (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Free up grd resources. Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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
index ad2cb9e5891857429d256b70401bb62b0d9528ee..bdbad6b804c88a92558abe22f8687b5719ddbc50 100644
--- 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
@@ -23,7 +23,10 @@ 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');
/**
@@ -41,8 +44,8 @@ goog.async.throwException = function(exception) {
/**
* Fires the provided callbacks as soon as possible after the current JS
- * execution context. setTimeout(…, 0) always takes at least 5ms for legacy
- * reasons.
+ * 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
@@ -52,19 +55,41 @@ goog.async.throwException = function(exception) {
* @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) {
+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);
- // Introduced and currently only supported by IE10.
- if (goog.isFunction(goog.global.setImmediate)) {
+ // 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_ =
@@ -97,11 +122,14 @@ goog.async.nextTick.getSetImmediateEmulator_ = function() {
// document.addEventListener. The latter excludes IE8 because it has a
// synchronous postMessage implementation.
if (typeof Channel === 'undefined' && typeof window !== 'undefined' &&
- window.postMessage && window.addEventListener) {
+ 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('iframe');
+ var iframe = document.createElement(goog.dom.TagName.IFRAME);
iframe.style.display = 'none';
iframe.src = '';
document.documentElement.appendChild(iframe);
@@ -121,8 +149,10 @@ goog.async.nextTick.getSetImmediateEmulator_ = function() {
'*' : 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) {
+ // 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();
@@ -136,16 +166,24 @@ goog.async.nextTick.getSetImmediateEmulator_ = function() {
};
};
}
- if (typeof Channel !== 'undefined') {
+ 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() {
- head = head.next;
- var cb = head.cb;
- head.cb = null;
- cb();
+ if (goog.isDef(head.next)) {
+ head = head.next;
+ var cb = head.cb;
+ head.cb = null;
+ cb();
+ }
};
return function(cb) {
tail.next = {
@@ -155,12 +193,12 @@ goog.async.nextTick.getSetImmediateEmulator_ = function() {
channel['port2'].postMessage(0);
};
}
- // Implementation for IE6-8: Script elements fire an asynchronous
+ // Implementation for IE6+: Script elements fire an asynchronous
// onreadystatechange event when inserted into the DOM.
if (typeof document !== 'undefined' && 'onreadystatechange' in
- document.createElement('script')) {
+ document.createElement(goog.dom.TagName.SCRIPT)) {
return function(cb) {
- var script = document.createElement('script');
+ var script = document.createElement(goog.dom.TagName.SCRIPT);
script.onreadystatechange = function() {
// Clean up and call the callback.
script.onreadystatechange = null;

Powered by Google App Engine
This is Rietveld 408576698