UNPKG

neo-neo-bblessed

Version:

A fork of neo-blessed (which is a fork of blessed) with bug fixes and maintenance.

243 lines (209 loc) 5.84 kB
// @ts-nocheck /** * events.js - event emitter for blessed * Copyright (c) 2013-2015, Christopher Jeffrey and contributors (MIT License). * https://github.com/chjj/blessed */ const slice = Array.prototype.slice; /** * Type definitions */ import { EventEmitter as NodeEventEmitter } from 'events'; import { EventEmitterInterface } from './types/index.d'; type Listener = (...args: any[]) => any; interface ListenerWithOriginal extends Listener { listener?: Listener; } /** * EventEmitter */ function _EventEmitter(this: EventEmitterInterface): void { this._events ??= {}; } NodeEventEmitter.prototype.setMaxListeners = function ( this: EventEmitterInterface, n: number ): void { this._maxListeners = n; }; NodeEventEmitter.prototype.addListener = function ( this: EventEmitterInterface, type: string, listener: Listener ): void { this._events ??= {}; if (!this._events[type]) { this._events[type] = listener; } else if (typeof this._events[type] === 'function') { this._events[type] = [this._events[type] as Listener, listener]; } else { (this._events[type] as Listener[]).push(listener); } this._emit('newListener', [type, listener]); }; NodeEventEmitter.prototype.on = NodeEventEmitter.prototype.addListener; NodeEventEmitter.prototype.removeListener = function ( this: EventEmitterInterface, type: string, listener: Listener ): void { if (!this._events) return; const handler = this._events[type]; if (!handler) return; if (typeof handler === 'function' || (handler as Listener[])?.length === 1) { delete this._events[type]; this._emit('removeListener', [type, listener]); return; } const handlers = handler as ListenerWithOriginal[]; for (let i = 0; i < handlers.length; i++) { if (handlers[i] === listener || handlers[i]?.listener === listener) { handlers.splice(i, 1); this._emit('removeListener', [type, listener]); return; } } }; NodeEventEmitter.prototype.off = NodeEventEmitter.prototype.removeListener; NodeEventEmitter.prototype.removeAllListeners = function ( this: EventEmitterInterface, type?: string ): void { if (!this._events) { this._events = {}; return; } if (type) { delete this._events[type]; } else { this._events = {}; } }; NodeEventEmitter.prototype.once = function ( this: EventEmitterInterface, type: string, listener: Listener ): EventEmitterInterface { const self = this; function on(this: EventEmitterInterface, ...args: any[]): any { self.removeListener(type, on); return listener.apply(this, args); } (on as ListenerWithOriginal).listener = listener; return this.on(type, on); }; NodeEventEmitter.prototype.listeners = function ( this: EventEmitterInterface, type: string ): Listener[] { if (!this._events) return []; const handler = this._events?.[type]; return typeof handler === 'function' ? [handler as Listener] : (handler as Listener[]) || []; }; NodeEventEmitter.prototype._emit = function ( this: EventEmitterInterface, type: string, args: any[] ): any { if (!this._events) return; const handler = this._events?.[type]; let ret: any; // if (type !== 'event') { // this._emit('event', [type.replace(/^element /, '')].concat(args)); // } if (!handler) { if (type === 'error') { throw new args[0](); } return; } if (typeof handler === 'function') { return handler?.apply(this, args); } const handlers = handler as Listener[]; for (let i = 0; i < handlers.length; i++) { if (handlers[i]?.apply(this, args) === false) { ret = false; } } return ret !== false; }; NodeEventEmitter.prototype.emit = function ( this: EventEmitterInterface, type: string, ..._eventArgs: any[] ): boolean { const args = slice.call(arguments, 1); const params = slice.call(arguments); let el: EventEmitterInterface | undefined = this; this._emit('event', params); if ((this as any).type === 'screen') { return this._emit(type, args); } if (this._emit(type, args) === false) { return false; } const elementType = 'element ' + String(type); args.unshift(this); // `element` prefix // params = [elementType].concat(args); // no `element` prefix // params.splice(1, 0, this); do { // el._emit('event', params); if (!el._events?.[elementType]) continue; if (el._emit(elementType, args) === false) { return false; } } while ((el = (el as any).parent)); return true; }; // For hooking into the main EventEmitter if we want to. // Might be better to do things this way being that it // will always be compatible with node, not to mention // it gives us domain support as well. // Node.prototype._emit = Node.prototype.emit; // Node.prototype.emit = function(type) { // var args, el; // // if (this.type === 'screen') { // return this._emit.apply(this, arguments); // } // // this._emit.apply(this, arguments); // if (this._bubbleStopped) return false; // // args = slice.call(arguments, 1); // el = this; // // args.unshift('element ' + type, this); // this._bubbleStopped = false; // //args.push(stopBubble); // // do { // if (!el._events || !el._events[type]) continue; // el._emit.apply(el, args); // if (this._bubbleStopped) return false; // } while (el = el.parent); // // return true; // }; // // Node.prototype._addListener = Node.prototype.addListener; // Node.prototype.on = // Node.prototype.addListener = function(type, listener) { // function on() { // if (listener.apply(this, arguments) === false) { // this._bubbleStopped = true; // } // } // on.listener = listener; // return this._addListener(type, on); // }; /** * Expose */ export default NodeEventEmitter; export { NodeEventEmitter as EventEmitter };