index.js 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. 'use strict';
  2. var ensureCallable = function (fn) {
  3. if (typeof fn !== 'function') throw new TypeError(fn + " is not a function");
  4. return fn;
  5. };
  6. var byObserver = function (Observer) {
  7. var node = document.createTextNode(''), queue, currentQueue, i = 0;
  8. new Observer(function () {
  9. var callback;
  10. if (!queue) {
  11. if (!currentQueue) return;
  12. queue = currentQueue;
  13. } else if (currentQueue) {
  14. queue = currentQueue.concat(queue);
  15. }
  16. currentQueue = queue;
  17. queue = null;
  18. if (typeof currentQueue === 'function') {
  19. callback = currentQueue;
  20. currentQueue = null;
  21. callback();
  22. return;
  23. }
  24. node.data = (i = ++i % 2); // Invoke other batch, to handle leftover callbacks in case of crash
  25. while (currentQueue) {
  26. callback = currentQueue.shift();
  27. if (!currentQueue.length) currentQueue = null;
  28. callback();
  29. }
  30. }).observe(node, { characterData: true });
  31. return function (fn) {
  32. ensureCallable(fn);
  33. if (queue) {
  34. if (typeof queue === 'function') queue = [queue, fn];
  35. else queue.push(fn);
  36. return;
  37. }
  38. queue = fn;
  39. node.data = (i = ++i % 2);
  40. };
  41. };
  42. module.exports = (function () {
  43. // Node.js
  44. if ((typeof process === 'object') && process && (typeof process.nextTick === 'function')) {
  45. return process.nextTick;
  46. }
  47. // queueMicrotask
  48. if (typeof queueMicrotask === "function") {
  49. return function (cb) { queueMicrotask(ensureCallable(cb)); };
  50. }
  51. // MutationObserver
  52. if ((typeof document === 'object') && document) {
  53. if (typeof MutationObserver === 'function') return byObserver(MutationObserver);
  54. if (typeof WebKitMutationObserver === 'function') return byObserver(WebKitMutationObserver);
  55. }
  56. // W3C Draft
  57. // http://dvcs.w3.org/hg/webperf/raw-file/tip/specs/setImmediate/Overview.html
  58. if (typeof setImmediate === 'function') {
  59. return function (cb) { setImmediate(ensureCallable(cb)); };
  60. }
  61. // Wide available standard
  62. if ((typeof setTimeout === 'function') || (typeof setTimeout === 'object')) {
  63. return function (cb) { setTimeout(ensureCallable(cb), 0); };
  64. }
  65. return null;
  66. }());