EventTarget.js 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /**
  2. * Expose the _EventTarget class.
  3. */
  4. module.exports = _EventTarget;
  5. function _EventTarget() {
  6. // Do nothing if called for a native EventTarget object..
  7. if (typeof this.addEventListener === 'function') {
  8. return;
  9. }
  10. this._listeners = {};
  11. this.addEventListener = _addEventListener;
  12. this.removeEventListener = _removeEventListener;
  13. this.dispatchEvent = _dispatchEvent;
  14. }
  15. Object.defineProperties(_EventTarget.prototype, {
  16. listeners: {
  17. get: function () {
  18. return this._listeners;
  19. }
  20. }
  21. });
  22. function _addEventListener(type, newListener) {
  23. var
  24. listenersType,
  25. i, listener;
  26. if (!type || !newListener) {
  27. return;
  28. }
  29. listenersType = this._listeners[type];
  30. if (listenersType === undefined) {
  31. this._listeners[type] = listenersType = [];
  32. }
  33. for (i = 0; !!(listener = listenersType[i]); i++) {
  34. if (listener === newListener) {
  35. return;
  36. }
  37. }
  38. listenersType.push(newListener);
  39. }
  40. function _removeEventListener(type, oldListener) {
  41. var
  42. listenersType,
  43. i, listener;
  44. if (!type || !oldListener) {
  45. return;
  46. }
  47. listenersType = this._listeners[type];
  48. if (listenersType === undefined) {
  49. return;
  50. }
  51. for (i = 0; !!(listener = listenersType[i]); i++) {
  52. if (listener === oldListener) {
  53. listenersType.splice(i, 1);
  54. break;
  55. }
  56. }
  57. if (listenersType.length === 0) {
  58. delete this._listeners[type];
  59. }
  60. }
  61. function _dispatchEvent(event) {
  62. var
  63. type,
  64. listenersType,
  65. dummyListener,
  66. stopImmediatePropagation = false,
  67. i, listener;
  68. if (!event || typeof event.type !== 'string') {
  69. throw new Error('`event` must have a valid `type` property');
  70. }
  71. // Do some stuff to emulate DOM Event behavior (just if this is not a
  72. // DOM Event object)
  73. if (event._yaeti) {
  74. event.target = this;
  75. event.cancelable = true;
  76. }
  77. // Attempt to override the stopImmediatePropagation() method
  78. try {
  79. event.stopImmediatePropagation = function () {
  80. stopImmediatePropagation = true;
  81. };
  82. } catch (error) {}
  83. type = event.type;
  84. listenersType = (this._listeners[type] || []);
  85. dummyListener = this['on' + type];
  86. if (typeof dummyListener === 'function') {
  87. dummyListener.call(this, event);
  88. }
  89. for (i = 0; !!(listener = listenersType[i]); i++) {
  90. if (stopImmediatePropagation) {
  91. break;
  92. }
  93. listener.call(this, event);
  94. }
  95. return !event.defaultPrevented;
  96. }