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.
74 lines
2.0 KiB
74 lines
2.0 KiB
'use strict'; |
|
|
|
var ensureCallable = function (fn) { |
|
if (typeof fn !== 'function') throw new TypeError(fn + " is not a function"); |
|
return fn; |
|
}; |
|
|
|
var byObserver = function (Observer) { |
|
var node = document.createTextNode(''), queue, currentQueue, i = 0; |
|
new Observer(function () { |
|
var callback; |
|
if (!queue) { |
|
if (!currentQueue) return; |
|
queue = currentQueue; |
|
} else if (currentQueue) { |
|
queue = currentQueue.concat(queue); |
|
} |
|
currentQueue = queue; |
|
queue = null; |
|
if (typeof currentQueue === 'function') { |
|
callback = currentQueue; |
|
currentQueue = null; |
|
callback(); |
|
return; |
|
} |
|
node.data = (i = ++i % 2); // Invoke other batch, to handle leftover callbacks in case of crash |
|
while (currentQueue) { |
|
callback = currentQueue.shift(); |
|
if (!currentQueue.length) currentQueue = null; |
|
callback(); |
|
} |
|
}).observe(node, { characterData: true }); |
|
return function (fn) { |
|
ensureCallable(fn); |
|
if (queue) { |
|
if (typeof queue === 'function') queue = [queue, fn]; |
|
else queue.push(fn); |
|
return; |
|
} |
|
queue = fn; |
|
node.data = (i = ++i % 2); |
|
}; |
|
}; |
|
|
|
module.exports = (function () { |
|
// Node.js |
|
if ((typeof process === 'object') && process && (typeof process.nextTick === 'function')) { |
|
return process.nextTick; |
|
} |
|
|
|
// queueMicrotask |
|
if (typeof queueMicrotask === "function") { |
|
return function (cb) { queueMicrotask(ensureCallable(cb)); }; |
|
} |
|
|
|
// MutationObserver |
|
if ((typeof document === 'object') && document) { |
|
if (typeof MutationObserver === 'function') return byObserver(MutationObserver); |
|
if (typeof WebKitMutationObserver === 'function') return byObserver(WebKitMutationObserver); |
|
} |
|
|
|
// W3C Draft |
|
// http://dvcs.w3.org/hg/webperf/raw-file/tip/specs/setImmediate/Overview.html |
|
if (typeof setImmediate === 'function') { |
|
return function (cb) { setImmediate(ensureCallable(cb)); }; |
|
} |
|
|
|
// Wide available standard |
|
if ((typeof setTimeout === 'function') || (typeof setTimeout === 'object')) { |
|
return function (cb) { setTimeout(ensureCallable(cb), 0); }; |
|
} |
|
|
|
return null; |
|
}());
|
|
|