UNPKG

synthetic-event

Version:

A collection of base classes for custom events and event targets.

132 lines (130 loc) 3.94 kB
/** * synthetic-event v2.0.0 build Sat Jan 10 2026 * https://github.com/vanruesc/synthetic-event * Copyright 2026 Raoul van Rüschen * @license Zlib */ // src/EventTarget.ts var EventTarget = class { /** * A collection of event listener functions. */ listenerFunctions; /** * A collection of event listener objects. */ listenerObjects; /** * Constructs a new event target. */ constructor() { this.listenerFunctions = /* @__PURE__ */ new Map(); this.listenerObjects = /* @__PURE__ */ new Map(); } /** * Registers an event handler of a specific event type on the event target. * * @param type - The event type to listen for. * @param listener - An event listener or callback. */ addEventListener(type, listener) { if (typeof listener === "function") { if (this.listenerFunctions.has(type)) { const listeners = this.listenerFunctions.get(type); listeners.add(listener); } else { const listeners = /* @__PURE__ */ new Set([listener]); this.listenerFunctions.set(type, listeners); } return; } if (this.listenerObjects.has(type)) { const listeners = this.listenerObjects.get(type); listeners.add(listener); } else { const listeners = /* @__PURE__ */ new Set([listener]); this.listenerObjects.set(type, listeners); } } /** * Removes an event handler of a specific event type from the event target. * * @param type - The event type to remove. * @param listener - The event listener to remove. */ hasEventListener(type, listener) { if (typeof listener === "function") { if (!this.listenerFunctions.has(type)) { return false; } const listeners2 = this.listenerFunctions.get(type); return listeners2.has(listener); } if (!this.listenerObjects.has(type)) { return false; } const listeners = this.listenerObjects.get(type); return listeners.has(listener); } /** * Removes an event handler of a specific event type from the event target. * * @param type - The event type to remove. * @param listener - The event listener to remove. */ removeEventListener(type, listener) { if (typeof listener === "function") { if (!this.listenerFunctions.has(type)) { return; } const listeners2 = this.listenerFunctions.get(type); if (listeners2.delete(listener) && listeners2.size === 0) { this.listenerFunctions.delete(type); } return; } if (!this.listenerObjects.has(type)) { return; } const listeners = this.listenerObjects.get(type); if (listeners.delete(listener) && listeners.size === 0) { this.listenerObjects.delete(type); } } /** * Dispatches an event at the specified event target, invoking the affected event listeners in the appropriate order. * * Event listeners can safely be added and removed while an event is being dispatched. * * @see https://262.ecma-international.org/#sec-map.prototype.foreach for more information on the iteration behavior. * @param event - The event to dispatch. * @param target - An event target. */ dispatchEvent(event, target = this) { const listenerFunctions = target.listenerFunctions; const listenerObjects = target.listenerObjects; event.target = target; if (listenerFunctions.has(event.type)) { const listeners = listenerFunctions.get(event.type); for (const listener of listeners) { listener.call(target, event); } } if (listenerObjects.has(event.type)) { const listeners = listenerObjects.get(event.type); for (const listener of listeners) { listener.handleEvent(event); } } } /** * Removes all listeners. */ clearEventListeners() { this.listenerFunctions.clear(); this.listenerObjects.clear(); } }; export { EventTarget };