UNPKG

@etsoo/shared

Version:

TypeScript shared utilities and functions

161 lines (160 loc) 4.23 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.EventClass = exports.EventBase = void 0; /** * Abstract event base class * T for type * D for data */ class EventBase { /** * stopImmediatePropagation called */ get propagationStopped() { return this._propagationStopped; } /** * Time stamp */ get timeStamp() { return this._timeStamp; } /** * Constructor * @param type Type */ constructor(target, type, data) { this.target = target; this.type = type; this.data = data; this._propagationStopped = false; this._timeStamp = Date.now(); } /** * Prevent all other listeners from being called */ stopImmediatePropagation() { this._propagationStopped = true; } } exports.EventBase = EventBase; /** * Event class * T for type * D for data */ class EventClass { constructor() { // Listeners this.listeners = new Map(); } /** * Has specific type and callback events * @param type Type * @param callback Callback * @returns Result */ hasEvents(type, callback) { const items = this.listeners.get(type); if (items == null || items.length === 0) return false; if (callback) { return items.some((item) => item[0] == callback); } return true; } /** * Remove specific type and callback event * @param type Type * @param callback Callback */ off(type, callback) { if (callback == null) { this.listeners.delete(type); return; } const items = this.listeners.get(type); if (items == null) return; for (let i = items.length - 1; i >= 0; i--) { if (items[i][0] == callback) { items.splice(i, 1); } } } /** * Add events * @param type Type * @param callback Callback * @param options Options */ on(type, callback, options) { if (typeof type === "object") { for (const key in type) { const item = key; const itemCallback = type[item] ?? callback; if (itemCallback) this.on(item, itemCallback, options); } return; } if (callback == null) return; this.listeners.has(type) || this.listeners.set(type, []); // String to T conversion problem // "keyofStringsOnly": true could solve part of it this.listeners.get(type)?.push([callback, options]); } /** * Trigger event * @param event Event */ trigger(event) { const items = this.listeners.get(event.type); if (items == null) return; // Len const len = items.length; if (len === 0) return; // Need to be removed indicies const indicies = []; // Capture items first let stopped = false; for (let c = 0; c < len; c++) { const item = items[c]; const [callback, options] = item; if (options == null || !options.capture) continue; callback(event); if (options.once) { indicies.push(c); } if (event.propagationStopped) { stopped = true; break; } } if (!stopped) { for (let c = 0; c < len; c++) { const item = items[c]; const [callback, options] = item; if (options?.capture) continue; callback(event); if (options?.once) { indicies.push(c); } if (event.propagationStopped) { stopped = true; break; } } } // Remove all once handlers for (let i = indicies.length - 1; i >= 0; i--) { items.splice(indicies[i], 1); } } } exports.EventClass = EventClass;