ListenerHandler.class.ts 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. export default class ListenerHandler extends EventTarget {
  2. listeners: {
  3. [name: string]: Array<{
  4. cb: (event: any) => void;
  5. options: { replaceable: boolean };
  6. }>;
  7. };
  8. constructor() {
  9. super();
  10. this.listeners = {};
  11. }
  12. addEventListener(type, cb, options) {
  13. // add the listener type to listeners object
  14. if (!(type in this.listeners)) this.listeners[type] = [];
  15. const stack = this.listeners[type];
  16. // push the callback
  17. stack.push({ cb, options });
  18. const replaceableIndexes = [];
  19. // check for any replaceable callbacks
  20. stack.forEach((element, index) => {
  21. if (element.options && element.options.replaceable)
  22. replaceableIndexes.push(index);
  23. });
  24. // should always be 1 replaceable callback remaining
  25. replaceableIndexes.pop();
  26. // delete the other replaceable callbacks
  27. replaceableIndexes.forEach(index => stack.splice(index, 1));
  28. }
  29. // eslint-disable-next-line consistent-return
  30. removeEventListener(type, cb) {
  31. if (!(type in this.listeners)) return true; // event type doesn't exist
  32. const stack = this.listeners[type];
  33. stack.forEach((element, index) => {
  34. if (element.cb === cb) stack.splice(index, 1);
  35. });
  36. }
  37. dispatchEvent(event) {
  38. if (!(event.type in this.listeners)) return true; // event type doesn't exist
  39. const stack = this.listeners[event.type].slice();
  40. stack.forEach(element => element.cb.call(this, event));
  41. return !event.defaultPrevented;
  42. }
  43. }