Have common only reference within common

Part of #1337
This commit is contained in:
Daniel Imms
2018-09-04 08:01:04 -07:00
parent dd7081f948
commit 443b2dbc28
15 changed files with 35 additions and 29 deletions
+2 -2
View File
@@ -3,8 +3,8 @@
* @license MIT
*/
import { EventEmitter } from '../EventEmitter';
import { ICircularList } from '../Types';
import { EventEmitter } from './EventEmitter';
import { ICircularList } from './Types';
/**
* Represents a circular list; a list with a maximum size that wraps around when push is called,
+77
View File
@@ -0,0 +1,77 @@
/**
* Copyright (c) 2017 The xterm.js authors. All rights reserved.
* @license MIT
*/
import { assert } from 'chai';
import { EventEmitter } from './EventEmitter';
describe('EventEmitter', () => {
let eventEmitter: EventEmitter;
beforeEach(() => {
eventEmitter = new EventEmitter();
});
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);
});
});
});
+85
View File
@@ -0,0 +1,85 @@
/**
* Copyright (c) 2017 The xterm.js authors. All rights reserved.
* @license MIT
*/
import { XtermListener } from './Types';
import { IEventEmitter, IDisposable } from 'xterm';
import { Disposable } from './Lifecycle';
export class EventEmitter extends Disposable implements IEventEmitter, IDisposable {
private _events: {[type: string]: XtermListener[]};
constructor() {
super();
// Restore the previous events if available, this will happen if the
// constructor is called multiple times on the same object (terminal reset).
this._events = this._events || {};
}
public on(type: string, listener: XtermListener): void {
this._events[type] = this._events[type] || [];
this._events[type].push(listener);
}
/**
* Adds a disposabe listener to the EventEmitter, returning the disposable.
* @param type The event type.
* @param handler The handler for the listener.
*/
public addDisposableListener(type: string, handler: XtermListener): IDisposable {
// TODO: Rename addDisposableEventListener to more easily disambiguate from Dom listener
this.on(type, handler);
return {
dispose: () => {
if (!handler) {
// Already disposed
return;
}
this.off(type, handler);
handler = null;
}
};
}
public off(type: string, listener: XtermListener): void {
if (!this._events[type]) {
return;
}
const obj = this._events[type];
let i = obj.length;
while (i--) {
if (obj[i] === listener) {
obj.splice(i, 1);
return;
}
}
}
public removeAllListeners(type: string): void {
if (this._events[type]) {
delete this._events[type];
}
}
public emit(type: string, ...args: any[]): void {
if (!this._events[type]) {
return;
}
const obj = this._events[type];
for (let i = 0; i < obj.length; i++) {
obj[i].apply(this, args);
}
}
public listeners(type: string): XtermListener[] {
return this._events[type] || [];
}
public dispose(): void {
super.dispose();
this._events = {};
}
}
+17
View File
@@ -3,6 +3,10 @@
* @license MIT
*/
import { IEventEmitter } from 'xterm';
export type XtermListener = (...args: any[]) => void;
/**
* A keyboard event interface which does not depend on the DOM, KeyboardEvent implicitly extends
* this event.
@@ -16,3 +20,16 @@ export interface IKeyboardEvent {
key: string;
type: string;
}
export interface ICircularList<T> extends IEventEmitter {
length: number;
maxLength: number;
get(index: number): T;
set(index: number, value: T): void;
push(value: T): void;
pop(): T;
splice(start: number, deleteCount: number, ...items: T[]): void;
trimStart(count: number): void;
shiftElements(start: number, count: number, offset: number): void;
}