| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 | /**Some credit for this helper goes to http://github.com/YuzuJS/setImmediate*/"use strict";var root_1 = require('./root');var ImmediateDefinition = (function () {    function ImmediateDefinition(root) {        this.root = root;        if (root.setImmediate && typeof root.setImmediate === 'function') {            this.setImmediate = root.setImmediate.bind(root);            this.clearImmediate = root.clearImmediate.bind(root);        }        else {            this.nextHandle = 1;            this.tasksByHandle = {};            this.currentlyRunningATask = false;            // Don't get fooled by e.g. browserify environments.            if (this.canUseProcessNextTick()) {                // For Node.js before 0.9                this.setImmediate = this.createProcessNextTickSetImmediate();            }            else if (this.canUsePostMessage()) {                // For non-IE10 modern browsers                this.setImmediate = this.createPostMessageSetImmediate();            }            else if (this.canUseMessageChannel()) {                // For web workers, where supported                this.setImmediate = this.createMessageChannelSetImmediate();            }            else if (this.canUseReadyStateChange()) {                // For IE 6–8                this.setImmediate = this.createReadyStateChangeSetImmediate();            }            else {                // For older browsers                this.setImmediate = this.createSetTimeoutSetImmediate();            }            var ci = function clearImmediate(handle) {                delete clearImmediate.instance.tasksByHandle[handle];            };            ci.instance = this;            this.clearImmediate = ci;        }    }    ImmediateDefinition.prototype.identify = function (o) {        return this.root.Object.prototype.toString.call(o);    };    ImmediateDefinition.prototype.canUseProcessNextTick = function () {        return this.identify(this.root.process) === '[object process]';    };    ImmediateDefinition.prototype.canUseMessageChannel = function () {        return Boolean(this.root.MessageChannel);    };    ImmediateDefinition.prototype.canUseReadyStateChange = function () {        var document = this.root.document;        return Boolean(document && 'onreadystatechange' in document.createElement('script'));    };    ImmediateDefinition.prototype.canUsePostMessage = function () {        var root = this.root;        // The test against `importScripts` prevents this implementation from being installed inside a web worker,        // where `root.postMessage` means something completely different and can't be used for this purpose.        if (root.postMessage && !root.importScripts) {            var postMessageIsAsynchronous_1 = true;            var oldOnMessage = root.onmessage;            root.onmessage = function () {                postMessageIsAsynchronous_1 = false;            };            root.postMessage('', '*');            root.onmessage = oldOnMessage;            return postMessageIsAsynchronous_1;        }        return false;    };    // This function accepts the same arguments as setImmediate, but    // returns a function that requires no arguments.    ImmediateDefinition.prototype.partiallyApplied = function (handler) {        var args = [];        for (var _i = 1; _i < arguments.length; _i++) {            args[_i - 1] = arguments[_i];        }        var fn = function result() {            var _a = result, handler = _a.handler, args = _a.args;            if (typeof handler === 'function') {                handler.apply(undefined, args);            }            else {                (new Function('' + handler))();            }        };        fn.handler = handler;        fn.args = args;        return fn;    };    ImmediateDefinition.prototype.addFromSetImmediateArguments = function (args) {        this.tasksByHandle[this.nextHandle] = this.partiallyApplied.apply(undefined, args);        return this.nextHandle++;    };    ImmediateDefinition.prototype.createProcessNextTickSetImmediate = function () {        var fn = function setImmediate() {            var instance = setImmediate.instance;            var handle = instance.addFromSetImmediateArguments(arguments);            instance.root.process.nextTick(instance.partiallyApplied(instance.runIfPresent, handle));            return handle;        };        fn.instance = this;        return fn;    };    ImmediateDefinition.prototype.createPostMessageSetImmediate = function () {        // 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 root = this.root;        var messagePrefix = 'setImmediate$' + root.Math.random() + '$';        var onGlobalMessage = function globalMessageHandler(event) {            var instance = globalMessageHandler.instance;            if (event.source === root &&                typeof event.data === 'string' &&                event.data.indexOf(messagePrefix) === 0) {                instance.runIfPresent(+event.data.slice(messagePrefix.length));            }        };        onGlobalMessage.instance = this;        root.addEventListener('message', onGlobalMessage, false);        var fn = function setImmediate() {            var _a = setImmediate, messagePrefix = _a.messagePrefix, instance = _a.instance;            var handle = instance.addFromSetImmediateArguments(arguments);            instance.root.postMessage(messagePrefix + handle, '*');            return handle;        };        fn.instance = this;        fn.messagePrefix = messagePrefix;        return fn;    };    ImmediateDefinition.prototype.runIfPresent = function (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 (this.currentlyRunningATask) {            // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a            // 'too much recursion' error.            this.root.setTimeout(this.partiallyApplied(this.runIfPresent, handle), 0);        }        else {            var task = this.tasksByHandle[handle];            if (task) {                this.currentlyRunningATask = true;                try {                    task();                }                finally {                    this.clearImmediate(handle);                    this.currentlyRunningATask = false;                }            }        }    };    ImmediateDefinition.prototype.createMessageChannelSetImmediate = function () {        var _this = this;        var channel = new this.root.MessageChannel();        channel.port1.onmessage = function (event) {            var handle = event.data;            _this.runIfPresent(handle);        };        var fn = function setImmediate() {            var _a = setImmediate, channel = _a.channel, instance = _a.instance;            var handle = instance.addFromSetImmediateArguments(arguments);            channel.port2.postMessage(handle);            return handle;        };        fn.channel = channel;        fn.instance = this;        return fn;    };    ImmediateDefinition.prototype.createReadyStateChangeSetImmediate = function () {        var fn = function setImmediate() {            var instance = setImmediate.instance;            var root = instance.root;            var doc = root.document;            var html = doc.documentElement;            var handle = instance.addFromSetImmediateArguments(arguments);            // 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 () {                instance.runIfPresent(handle);                script.onreadystatechange = null;                html.removeChild(script);                script = null;            };            html.appendChild(script);            return handle;        };        fn.instance = this;        return fn;    };    ImmediateDefinition.prototype.createSetTimeoutSetImmediate = function () {        var fn = function setImmediate() {            var instance = setImmediate.instance;            var handle = instance.addFromSetImmediateArguments(arguments);            instance.root.setTimeout(instance.partiallyApplied(instance.runIfPresent, handle), 0);            return handle;        };        fn.instance = this;        return fn;    };    return ImmediateDefinition;}());exports.ImmediateDefinition = ImmediateDefinition;exports.Immediate = new ImmediateDefinition(root_1.root);//# sourceMappingURL=Immediate.js.map
 |