/** * Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author David Sehnal */ /** * setImmediate polyfill adapted from https://github.com/YuzuJS/setImmediate * Copyright (c) 2012 Barnesandnoble.com, llc, Donavon West, and Domenic Denicola * MIT license. */ declare const WorkerGlobalScope: any; function createImmediateActions() { const global: any = (function () { const _window = typeof window !== 'undefined' && window; const _self = typeof self !== 'undefined' && typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope && self; const _global = typeof global !== 'undefined' && global; return _window || _global || _self; })(); type Callback = (...args: any[]) => void; type Task = { callback: Callback, args: any[] } const tasksByHandle: { [handle: number]: Task } = { }; const doc = typeof document !== 'undefined' ? document : void 0; let nextHandle = 1; // Spec says greater than zero let registerImmediate: ((handle: number) => void); function setImmediate(callback: Callback, ...args: any[]) { // Callback can either be a function or a string if (typeof callback !== 'function') { callback = new Function('' + callback) as Callback; } // Store and register the task const task = { callback: callback, args: args }; tasksByHandle[nextHandle] = task; registerImmediate(nextHandle); return nextHandle++; } function clearImmediate(handle: number) { delete tasksByHandle[handle]; } function run(task: Task) { const callback = task.callback; const 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: number) { const task = tasksByHandle[handle]; clearImmediate(handle); run(task); } function installNextTickImplementation() { registerImmediate = function(handle) { process.nextTick(function () { runIfPresent(handle); }); }; } function canUsePostMessage() { if (global && global.postMessage && !global.importScripts) { let postMessageIsAsynchronous = true; const 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 const messagePrefix = 'setImmediate$' + Math.random() + '$'; const onGlobalMessage = function(event: any) { if (event.source === global && typeof event.data === 'string' && event.data.indexOf(messagePrefix) === 0) { runIfPresent(+event.data.slice(messagePrefix.length)); } }; if (window.addEventListener) { window.addEventListener('message', onGlobalMessage, false); } else { (window as any).attachEvent('onmessage', onGlobalMessage); } registerImmediate = function(handle) { window.postMessage(messagePrefix + handle, '*'); }; } function installMessageChannelImplementation() { const channel = new MessageChannel(); channel.port1.onmessage = function(event) { const handle = event.data; runIfPresent(handle); }; registerImmediate = function(handle) { channel.port2.postMessage(handle); }; } function installReadyStateChangeImplementation() { const html = doc!.documentElement!; registerImmediate = function(handle) { // Create a