You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
(function (global, undefined) { "use strict";
if (global.setImmediate) { return; }
var nextHandle = 1; // Spec says greater than zero
var tasksByHandle = {}; var currentlyRunningATask = false; var doc = global.document; var registerImmediate;
function setImmediate(callback) { // Callback can either be a function or a string
if (typeof callback !== "function") { callback = new Function("" + callback); } // Copy function arguments
var args = new Array(arguments.length - 1); for (var i = 0; i < args.length; i++) { args[i] = arguments[i + 1]; } // Store and register the task
var task = { callback: callback, args: args }; tasksByHandle[nextHandle] = task; registerImmediate(nextHandle); return nextHandle++; }
function clearImmediate(handle) { delete tasksByHandle[handle]; }
function run(task) { var callback = task.callback; var args = task.args; switch (args.length) { case 0: callback(); break; case 1: callback(args[0]); break; case 2: callback(args[0], args[1]); break; case 3: callback(args[0], args[1], args[2]); break; default: callback.apply(undefined, args); break; } }
function runIfPresent(handle) { // From the spec: "Wait until any invocations of this algorithm started before this one have completed."
// So if we're currently running a task, we'll need to delay this invocation.
if (currentlyRunningATask) { // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a
// "too much recursion" error.
setTimeout(runIfPresent, 0, handle); } else { var task = tasksByHandle[handle]; if (task) { currentlyRunningATask = true; try { run(task); } finally { clearImmediate(handle); currentlyRunningATask = false; } } } }
function installNextTickImplementation() { registerImmediate = function(handle) { process.nextTick(function () { runIfPresent(handle); }); }; }
function canUsePostMessage() { // The test against `importScripts` prevents this implementation from being installed inside a web worker,
// where `global.postMessage` means something completely different and can't be used for this purpose.
if (global.postMessage && !global.importScripts) { var postMessageIsAsynchronous = true; var oldOnMessage = global.onmessage; global.onmessage = function() { postMessageIsAsynchronous = false; }; global.postMessage("", "*"); global.onmessage = oldOnMessage; return postMessageIsAsynchronous; } }
function installPostMessageImplementation() { // Installs an event handler on `global` for the `message` event: see
// * https://developer.mozilla.org/en/DOM/window.postMessage
// * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages
var messagePrefix = "setImmediate$" + Math.random() + "$"; var onGlobalMessage = function(event) { if (event.source === global && typeof event.data === "string" && event.data.indexOf(messagePrefix) === 0) { runIfPresent(+event.data.slice(messagePrefix.length)); } };
if (global.addEventListener) { global.addEventListener("message", onGlobalMessage, false); } else { global.attachEvent("onmessage", onGlobalMessage); }
registerImmediate = function(handle) { global.postMessage(messagePrefix + handle, "*"); }; }
function installMessageChannelImplementation() { var channel = new MessageChannel(); channel.port1.onmessage = function(event) { var handle = event.data; runIfPresent(handle); };
registerImmediate = function(handle) { channel.port2.postMessage(handle); }; }
function installReadyStateChangeImplementation() { var html = doc.documentElement; registerImmediate = function(handle) { // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
// into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
var script = doc.createElement("script"); script.onreadystatechange = function () { runIfPresent(handle); script.onreadystatechange = null; html.removeChild(script); script = null; }; html.appendChild(script); }; }
function installSetTimeoutImplementation() { registerImmediate = function(handle) { setTimeout(runIfPresent, 0, handle); }; }
// If supported, we should attach to the prototype of global, since that is where setTimeout et al. live.
var attachTo = Object.getPrototypeOf && Object.getPrototypeOf(global); attachTo = attachTo && attachTo.setTimeout ? attachTo : global;
// Don't get fooled by e.g. browserify environments.
if ({}.toString.call(global.process) === "[object process]") { // For Node.js before 0.9
installNextTickImplementation();
} else if (canUsePostMessage()) { // For non-IE10 modern browsers
installPostMessageImplementation();
} else if (global.MessageChannel) { // For web workers, where supported
installMessageChannelImplementation();
} else if (doc && "onreadystatechange" in doc.createElement("script")) { // For IE 6–8
installReadyStateChangeImplementation();
} else { // For older browsers
installSetTimeoutImplementation(); }
attachTo.setImmediate = setImmediate; attachTo.clearImmediate = clearImmediate; }(typeof self === "undefined" ? typeof global === "undefined" ? this : global : self));
|