From 7e779cd19565883b0f93877b0edcc70d393d2da1 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 21 Jun 2018 10:29:02 +1000 Subject: [PATCH] Replace _disposables with Disposable, add jsdoc --- src/AccessibilityManager.ts | 34 ++++++++++++++++------------------ src/EventEmitter.ts | 1 + src/Terminal.ts | 2 -- src/common/Lifecycle.ts | 15 +++++++++++++-- 4 files changed, 30 insertions(+), 22 deletions(-) diff --git a/src/AccessibilityManager.ts b/src/AccessibilityManager.ts index 6ff595ce..282a5e5a 100644 --- a/src/AccessibilityManager.ts +++ b/src/AccessibilityManager.ts @@ -8,7 +8,7 @@ import { ITerminal, IBuffer } from './Types'; import { isMac } from './shared/utils/Browser'; import { RenderDebouncer } from './utils/RenderDebouncer'; import { addDisposableDomListener } from './ui/Lifecycle'; -import { IDisposable } from 'xterm'; +import { Disposable } from './common/Lifecycle'; const MAX_ROWS_TO_READ = 20; @@ -17,7 +17,7 @@ const enum BoundaryPosition { BOTTOM } -export class AccessibilityManager implements IDisposable { +export class AccessibilityManager extends Disposable { private _accessibilityTreeRoot: HTMLElement; private _rowContainer: HTMLElement; private _rowElements: HTMLElement[]; @@ -29,8 +29,6 @@ export class AccessibilityManager implements IDisposable { private _topBoundaryFocusListener: (e: FocusEvent) => void; private _bottomBoundaryFocusListener: (e: FocusEvent) => void; - private _disposables: IDisposable[] = []; - /** * This queue has a character pushed to it for keys that are pressed, if the * next character added to the terminal is equal to the key char then it is @@ -43,6 +41,7 @@ export class AccessibilityManager implements IDisposable { private _charsToConsume: string[] = []; constructor(private _terminal: ITerminal) { + super(); this._accessibilityTreeRoot = document.createElement('div'); this._accessibilityTreeRoot.classList.add('xterm-accessibility'); @@ -72,29 +71,28 @@ export class AccessibilityManager implements IDisposable { this._terminal.element.insertAdjacentElement('afterbegin', this._accessibilityTreeRoot); - this._disposables.push(this._renderRowsDebouncer); - this._disposables.push(this._terminal.addDisposableListener('resize', data => this._onResize(data.cols, data.rows))); - this._disposables.push(this._terminal.addDisposableListener('refresh', data => this._refreshRows(data.start, data.end))); - this._disposables.push(this._terminal.addDisposableListener('scroll', data => this._refreshRows())); + this.register(this._renderRowsDebouncer); + this.register(this._terminal.addDisposableListener('resize', data => this._onResize(data.cols, data.rows))); + this.register(this._terminal.addDisposableListener('refresh', data => this._refreshRows(data.start, data.end))); + this.register(this._terminal.addDisposableListener('scroll', data => this._refreshRows())); // Line feed is an issue as the prompt won't be read out after a command is run - this._disposables.push(this._terminal.addDisposableListener('a11y.char', (char) => this._onChar(char))); - this._disposables.push(this._terminal.addDisposableListener('linefeed', () => this._onChar('\n'))); - this._disposables.push(this._terminal.addDisposableListener('a11y.tab', spaceCount => this._onTab(spaceCount))); - this._disposables.push(this._terminal.addDisposableListener('key', keyChar => this._onKey(keyChar))); - this._disposables.push(this._terminal.addDisposableListener('blur', () => this._clearLiveRegion())); + this.register(this._terminal.addDisposableListener('a11y.char', (char) => this._onChar(char))); + this.register(this._terminal.addDisposableListener('linefeed', () => this._onChar('\n'))); + this.register(this._terminal.addDisposableListener('a11y.tab', spaceCount => this._onTab(spaceCount))); + this.register(this._terminal.addDisposableListener('key', keyChar => this._onKey(keyChar))); + this.register(this._terminal.addDisposableListener('blur', () => this._clearLiveRegion())); // TODO: Maybe renderer should fire an event on terminal when the characters change and that // should be listened to instead? That would mean that the order of events are always // guarenteed - this._disposables.push(this._terminal.addDisposableListener('dprchange', () => this._refreshRowsDimensions())); - this._disposables.push(this._terminal.renderer.addDisposableListener('resize', () => this._refreshRowsDimensions())); + this.register(this._terminal.addDisposableListener('dprchange', () => this._refreshRowsDimensions())); + this.register(this._terminal.renderer.addDisposableListener('resize', () => this._refreshRowsDimensions())); // This shouldn't be needed on modern browsers but is present in case the // media query that drives the dprchange event isn't supported - this._disposables.push(addDisposableDomListener(window, 'resize', () => this._refreshRowsDimensions())); + this.register(addDisposableDomListener(window, 'resize', () => this._refreshRowsDimensions())); } public dispose(): void { - this._disposables.forEach(d => d.dispose()); - this._disposables.length = 0; + super.dispose(); this._terminal.element.removeChild(this._accessibilityTreeRoot); this._rowElements.length = 0; } diff --git a/src/EventEmitter.ts b/src/EventEmitter.ts index 1970f3e6..0de5999a 100644 --- a/src/EventEmitter.ts +++ b/src/EventEmitter.ts @@ -79,6 +79,7 @@ export class EventEmitter extends Disposable implements IEventEmitter, IDisposab } public dispose(): void { + super.dispose(); this._events = {}; } } diff --git a/src/Terminal.ts b/src/Terminal.ts index 05f47de2..ab703aa2 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -232,8 +232,6 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II public dispose(): void { super.dispose(); - this._disposables.forEach(d => d.dispose()); - this._disposables.length = 0; removeTerminalFromCache(this); this.handler = () => {}; this.write = () => {}; diff --git a/src/common/Lifecycle.ts b/src/common/Lifecycle.ts index f83f09af..b9cf1418 100644 --- a/src/common/Lifecycle.ts +++ b/src/common/Lifecycle.ts @@ -5,18 +5,29 @@ import { IDisposable } from 'xterm'; +/** + * A base class that can be extended to provide convenience methods for managing the lifecycle of an + * object and its components. + */ export abstract class Disposable implements IDisposable { protected _disposables: IDisposable[] = []; constructor() { } + /** + * Disposes the object, triggering the `dispose` method on all registered IDisposables. + */ public dispose(): void { this._disposables.forEach(d => d.dispose()); this._disposables.length = 0; } - public register(t: T): void { - this._disposables.push(t); + /** + * Registers a disposable object. + * @param d The disposable to register. + */ + public register(d: T): void { + this._disposables.push(d); } }