browser.js 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. 'use strict';
  2. var Mutation = global.MutationObserver || global.WebKitMutationObserver;
  3. var scheduleDrain;
  4. {
  5. if (Mutation) {
  6. var called = 0;
  7. var observer = new Mutation(nextTick);
  8. var element = global.document.createTextNode('');
  9. observer.observe(element, {
  10. characterData: true
  11. });
  12. scheduleDrain = function () {
  13. element.data = (called = ++called % 2);
  14. };
  15. } else if (!global.setImmediate && typeof global.MessageChannel !== 'undefined') {
  16. var channel = new global.MessageChannel();
  17. channel.port1.onmessage = nextTick;
  18. scheduleDrain = function () {
  19. channel.port2.postMessage(0);
  20. };
  21. } else if ('document' in global && 'onreadystatechange' in global.document.createElement('script')) {
  22. scheduleDrain = function () {
  23. // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
  24. // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
  25. var scriptEl = global.document.createElement('script');
  26. scriptEl.onreadystatechange = function () {
  27. nextTick();
  28. scriptEl.onreadystatechange = null;
  29. scriptEl.parentNode.removeChild(scriptEl);
  30. scriptEl = null;
  31. };
  32. global.document.documentElement.appendChild(scriptEl);
  33. };
  34. } else {
  35. scheduleDrain = function () {
  36. setTimeout(nextTick, 0);
  37. };
  38. }
  39. }
  40. var draining;
  41. var queue = [];
  42. //named nextTick for less confusing stack traces
  43. function nextTick() {
  44. draining = true;
  45. var i, oldQueue;
  46. var len = queue.length;
  47. while (len) {
  48. oldQueue = queue;
  49. queue = [];
  50. i = -1;
  51. while (++i < len) {
  52. oldQueue[i]();
  53. }
  54. len = queue.length;
  55. }
  56. draining = false;
  57. }
  58. module.exports = immediate;
  59. function immediate(task) {
  60. if (queue.push(task) === 1 && !draining) {
  61. scheduleDrain();
  62. }
  63. }