Spaces:
Running
Running
| export class EventEmitter { | |
| constructor() { | |
| this.events = {}; | |
| } | |
| addEventListener(event, listener, options = {}) { | |
| if (!this.events[event]) { | |
| this.events[event] = []; | |
| } | |
| const wrappedListener = { | |
| callback: listener, | |
| once: options.once || false | |
| }; | |
| this.events[event].push(wrappedListener); | |
| } | |
| removeEventListener(event, listener) { | |
| if (!this.events[event]) return; | |
| this.events[event] = this.events[event].filter( | |
| wrappedListener => wrappedListener.callback !== listener | |
| ); | |
| } | |
| dispatchEvent(event) { | |
| const eventName = event.type; | |
| if (!this.events[eventName]) return; | |
| this.events[eventName] = this.events[eventName].filter(wrappedListener => { | |
| wrappedListener.callback.call(this, event); | |
| return !wrappedListener.once; | |
| }); | |
| } | |
| emit(eventName, data) { | |
| const event = new CustomEvent(eventName, { detail: data }); | |
| this.dispatchEvent(event); | |
| } | |
| } | |
| export class CustomEvent { | |
| constructor(type, options = {}) { | |
| this.type = type; | |
| this.detail = options.detail; | |
| this.target = null; | |
| this.currentTarget = null; | |
| this.defaultPrevented = false; | |
| this.bubbles = options.bubbles || false; | |
| this.cancelable = options.cancelable || false; | |
| } | |
| preventDefault() { | |
| if (this.cancelable) { | |
| this.defaultPrevented = true; | |
| } | |
| } | |
| } |