mirror of
https://git.proxmox.com/git/mirror_xterm.js
synced 2025-10-28 00:29:51 +00:00
Merge pull request #432 from Tyriar/335_TS_EventEmitter
Convert EventEmitter to TypeScript and add tests
This commit is contained in:
commit
1fbd3c8f65
@ -1,64 +0,0 @@
|
|||||||
/**
|
|
||||||
* @license MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
function EventEmitter() {
|
|
||||||
this._events = this._events || {};
|
|
||||||
}
|
|
||||||
|
|
||||||
EventEmitter.prototype.addListener = function(type, listener) {
|
|
||||||
this._events[type] = this._events[type] || [];
|
|
||||||
this._events[type].push(listener);
|
|
||||||
};
|
|
||||||
|
|
||||||
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
|
|
||||||
|
|
||||||
EventEmitter.prototype.removeListener = function(type, listener) {
|
|
||||||
if (!this._events[type]) return;
|
|
||||||
|
|
||||||
var obj = this._events[type]
|
|
||||||
, i = obj.length;
|
|
||||||
|
|
||||||
while (i--) {
|
|
||||||
if (obj[i] === listener || obj[i].listener === listener) {
|
|
||||||
obj.splice(i, 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
|
|
||||||
|
|
||||||
EventEmitter.prototype.removeAllListeners = function(type) {
|
|
||||||
if (this._events[type]) delete this._events[type];
|
|
||||||
};
|
|
||||||
|
|
||||||
EventEmitter.prototype.once = function(type, listener) {
|
|
||||||
var self = this;
|
|
||||||
function on() {
|
|
||||||
var args = Array.prototype.slice.call(arguments);
|
|
||||||
this.removeListener(type, on);
|
|
||||||
return listener.apply(this, args);
|
|
||||||
}
|
|
||||||
on.listener = listener;
|
|
||||||
return this.on(type, on);
|
|
||||||
};
|
|
||||||
|
|
||||||
EventEmitter.prototype.emit = function(type) {
|
|
||||||
if (!this._events[type]) return;
|
|
||||||
|
|
||||||
var args = Array.prototype.slice.call(arguments, 1)
|
|
||||||
, obj = this._events[type]
|
|
||||||
, l = obj.length
|
|
||||||
, i = 0;
|
|
||||||
|
|
||||||
for (; i < l; i++) {
|
|
||||||
obj[i].apply(this, args);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
EventEmitter.prototype.listeners = function(type) {
|
|
||||||
return this._events[type] = this._events[type] || [];
|
|
||||||
};
|
|
||||||
|
|
||||||
export { EventEmitter };
|
|
||||||
84
src/EventEmitter.test.ts
Normal file
84
src/EventEmitter.test.ts
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
import { assert } from 'chai';
|
||||||
|
import { EventEmitter } from './EventEmitter';
|
||||||
|
|
||||||
|
describe('EventEmitter', () => {
|
||||||
|
let eventEmitter: EventEmitter;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
eventEmitter = new EventEmitter();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('once', () => {
|
||||||
|
it('should trigger the listener only once', () => {
|
||||||
|
let count = 0;
|
||||||
|
const listener = () => count++;
|
||||||
|
eventEmitter.once('test', listener);
|
||||||
|
eventEmitter.emit('test');
|
||||||
|
assert.equal(count, 1);
|
||||||
|
eventEmitter.emit('test');
|
||||||
|
assert.equal(count, 1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('emit', () => {
|
||||||
|
it('should emit events to listeners', () => {
|
||||||
|
let count1 = 0;
|
||||||
|
let count2 = 0;
|
||||||
|
const listener1 = () => count1++;
|
||||||
|
const listener2 = () => count2++;
|
||||||
|
eventEmitter.on('test', listener1);
|
||||||
|
eventEmitter.on('test', listener2);
|
||||||
|
eventEmitter.emit('test');
|
||||||
|
assert.equal(count1, 1);
|
||||||
|
assert.equal(count2, 1);
|
||||||
|
eventEmitter.emit('test');
|
||||||
|
assert.equal(count1, 2);
|
||||||
|
assert.equal(count2, 2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should manage multiple listener types', () => {
|
||||||
|
let count1 = 0;
|
||||||
|
let count2 = 0;
|
||||||
|
const listener1 = () => count1++;
|
||||||
|
const listener2 = () => count2++;
|
||||||
|
eventEmitter.on('test', listener1);
|
||||||
|
eventEmitter.on('foo', listener2);
|
||||||
|
eventEmitter.emit('test');
|
||||||
|
assert.equal(count1, 1);
|
||||||
|
assert.equal(count2, 0);
|
||||||
|
eventEmitter.emit('foo');
|
||||||
|
assert.equal(count1, 1);
|
||||||
|
assert.equal(count2, 1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('listeners', () => {
|
||||||
|
it('should return listeners for the type requested', () => {
|
||||||
|
assert.equal(eventEmitter.listeners('test').length, 0);
|
||||||
|
const listener = () => {};
|
||||||
|
eventEmitter.on('test', listener);
|
||||||
|
assert.deepEqual(eventEmitter.listeners('test'), [listener]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('off', () => {
|
||||||
|
it('should remove the specific listener', () => {
|
||||||
|
const listener1 = () => {};
|
||||||
|
const listener2 = () => {};
|
||||||
|
eventEmitter.on('foo', listener1);
|
||||||
|
eventEmitter.on('foo', listener2);
|
||||||
|
assert.equal(eventEmitter.listeners('foo').length, 2);
|
||||||
|
eventEmitter.off('foo', listener1);
|
||||||
|
assert.deepEqual(eventEmitter.listeners('foo'), [listener2]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('removeAllListeners', () => {
|
||||||
|
it('should clear all listeners', () => {
|
||||||
|
eventEmitter.on('foo', () => {});
|
||||||
|
assert.equal(eventEmitter.listeners('foo').length, 1);
|
||||||
|
eventEmitter.removeAllListeners('foo');
|
||||||
|
assert.equal(eventEmitter.listeners('foo').length, 0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
70
src/EventEmitter.ts
Normal file
70
src/EventEmitter.ts
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/**
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
interface ListenerType {
|
||||||
|
(): void;
|
||||||
|
listener?: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export class EventEmitter {
|
||||||
|
private _events: {[type: string]: ListenerType[]};
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this._events = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
public on(type, listener): void {
|
||||||
|
this._events[type] = this._events[type] || [];
|
||||||
|
this._events[type].push(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public off(type, listener): void {
|
||||||
|
if (!this._events[type]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let obj = this._events[type];
|
||||||
|
let i = obj.length;
|
||||||
|
|
||||||
|
while (i--) {
|
||||||
|
if (obj[i] === listener || obj[i].listener === listener) {
|
||||||
|
obj.splice(i, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public removeAllListeners(type): void {
|
||||||
|
if (this._events[type]) {
|
||||||
|
delete this._events[type];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public once(type, listener): any {
|
||||||
|
function on() {
|
||||||
|
let args = Array.prototype.slice.call(arguments);
|
||||||
|
this.off(type, on);
|
||||||
|
return listener.apply(this, args);
|
||||||
|
}
|
||||||
|
(<any>on).listener = listener;
|
||||||
|
return this.on(type, on);
|
||||||
|
}
|
||||||
|
|
||||||
|
public emit(type): void {
|
||||||
|
if (!this._events[type]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let args = Array.prototype.slice.call(arguments, 1);
|
||||||
|
let obj = this._events[type];
|
||||||
|
|
||||||
|
for (let i = 0; i < obj.length; i++) {
|
||||||
|
obj[i].apply(this, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public listeners(type): ListenerType[] {
|
||||||
|
return this._events[type] || [];
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user