scheduler.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import { process } from './process';
  2. import { global } from './global';
  3. import { queueResizeObserver } from './queueResizeObserver';
  4. var watching = 0;
  5. var isWatching = function () { return !!watching; };
  6. var CATCH_PERIOD = 250;
  7. var observerConfig = { attributes: true, characterData: true, childList: true, subtree: true };
  8. var events = [
  9. 'resize',
  10. 'load',
  11. 'transitionend',
  12. 'animationend',
  13. 'animationstart',
  14. 'animationiteration',
  15. 'keyup',
  16. 'keydown',
  17. 'mouseup',
  18. 'mousedown',
  19. 'mouseover',
  20. 'mouseout',
  21. 'blur',
  22. 'focus'
  23. ];
  24. var time = function (timeout) {
  25. if (timeout === void 0) { timeout = 0; }
  26. return Date.now() + timeout;
  27. };
  28. var scheduled = false;
  29. var Scheduler = (function () {
  30. function Scheduler() {
  31. var _this = this;
  32. this.stopped = true;
  33. this.listener = function () { return _this.schedule(); };
  34. }
  35. Scheduler.prototype.run = function (timeout) {
  36. var _this = this;
  37. if (timeout === void 0) { timeout = CATCH_PERIOD; }
  38. if (scheduled) {
  39. return;
  40. }
  41. scheduled = true;
  42. var until = time(timeout);
  43. queueResizeObserver(function () {
  44. var elementsHaveResized = false;
  45. try {
  46. elementsHaveResized = process();
  47. }
  48. finally {
  49. scheduled = false;
  50. timeout = until - time();
  51. if (!isWatching()) {
  52. return;
  53. }
  54. if (elementsHaveResized) {
  55. _this.run(1000);
  56. }
  57. else if (timeout > 0) {
  58. _this.run(timeout);
  59. }
  60. else {
  61. _this.start();
  62. }
  63. }
  64. });
  65. };
  66. Scheduler.prototype.schedule = function () {
  67. this.stop();
  68. this.run();
  69. };
  70. Scheduler.prototype.observe = function () {
  71. var _this = this;
  72. var cb = function () { return _this.observer && _this.observer.observe(document.body, observerConfig); };
  73. document.body ? cb() : global.addEventListener('DOMContentLoaded', cb);
  74. };
  75. Scheduler.prototype.start = function () {
  76. var _this = this;
  77. if (this.stopped) {
  78. this.stopped = false;
  79. this.observer = new MutationObserver(this.listener);
  80. this.observe();
  81. events.forEach(function (name) { return global.addEventListener(name, _this.listener, true); });
  82. }
  83. };
  84. Scheduler.prototype.stop = function () {
  85. var _this = this;
  86. if (!this.stopped) {
  87. this.observer && this.observer.disconnect();
  88. events.forEach(function (name) { return global.removeEventListener(name, _this.listener, true); });
  89. this.stopped = true;
  90. }
  91. };
  92. return Scheduler;
  93. }());
  94. var scheduler = new Scheduler();
  95. var updateCount = function (n) {
  96. !watching && n > 0 && scheduler.start();
  97. watching += n;
  98. !watching && scheduler.stop();
  99. };
  100. export { scheduler, updateCount };