From f9fce53cc45eaaba805c4387f3f690efa5e11dcd Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sat, 5 Aug 2017 13:56:38 -0700 Subject: [PATCH] Add typedef tslint rule --- src/CompositionHelper.test.ts | 16 +-- src/CompositionHelper.ts | 16 +-- src/EventEmitter.ts | 25 ++-- src/InputHandler.test.ts | 39 +++--- src/InputHandler.ts | 24 ++-- src/Interfaces.ts | 26 ++-- src/Linkifier.test.ts | 24 ++-- src/Linkifier.ts | 8 +- src/Parser.ts | 2 +- src/Renderer.ts | 12 +- src/SelectionManager.ts | 16 +-- src/Terminal.ts | 236 +++++++++++++++------------------ src/Viewport.ts | 8 +- src/handlers/Clipboard.test.ts | 4 +- src/handlers/Clipboard.ts | 17 ++- src/utils/Generic.ts | 2 +- tslint.json | 5 + 17 files changed, 230 insertions(+), 250 deletions(-) diff --git a/src/CompositionHelper.test.ts b/src/CompositionHelper.test.ts index 4a96e12a..70b23183 100644 --- a/src/CompositionHelper.test.ts +++ b/src/CompositionHelper.test.ts @@ -36,7 +36,7 @@ describe('CompositionHelper', () => { return { offsetLeft: 0, offsetTop: 0 }; } }, - handler: function (text) { + handler: (text: string) => { handledText += text; } }; @@ -45,7 +45,7 @@ describe('CompositionHelper', () => { }); describe('Input', () => { - it('Should insert simple characters', function (done) { + it('Should insert simple characters', (done) => { // First character 'ㅇ' compositionHelper.compositionstart(); compositionHelper.compositionupdate({ data: 'ㅇ' }); @@ -69,7 +69,7 @@ describe('CompositionHelper', () => { }, 0); }); - it('Should insert complex characters', function (done) { + it('Should insert complex characters', (done) => { // First character '앙' compositionHelper.compositionstart(); compositionHelper.compositionupdate({ data: 'ㅇ' }); @@ -109,7 +109,7 @@ describe('CompositionHelper', () => { }, 0); }); - it('Should insert complex characters that change with following character', function (done) { + it('Should insert complex characters that change with following character', (done) => { // First character '아' compositionHelper.compositionstart(); compositionHelper.compositionupdate({ data: 'ㅇ' }); @@ -138,7 +138,7 @@ describe('CompositionHelper', () => { }, 0); }); - it('Should insert multi-characters compositions', function (done) { + it('Should insert multi-characters compositions', (done) => { // First character 'だ' compositionHelper.compositionstart(); compositionHelper.compositionupdate({ data: 'd' }); @@ -161,7 +161,7 @@ describe('CompositionHelper', () => { }, 0); }); - it('Should insert multi-character compositions that are converted to other characters with the same length', function (done) { + it('Should insert multi-character compositions that are converted to other characters with the same length', (done) => { // First character 'だ' compositionHelper.compositionstart(); compositionHelper.compositionupdate({ data: 'd' }); @@ -189,7 +189,7 @@ describe('CompositionHelper', () => { }, 0); }); - it('Should insert multi-character compositions that are converted to other characters with different lengths', function (done) { + it('Should insert multi-character compositions that are converted to other characters with different lengths', (done) => { // First character 'い' compositionHelper.compositionstart(); compositionHelper.compositionupdate({ data: 'い' }); @@ -217,7 +217,7 @@ describe('CompositionHelper', () => { }, 0); }); - it('Should insert non-composition characters input immediately after composition characters', function (done) { + it('Should insert non-composition characters input immediately after composition characters', (done) => { // First character 'ㅇ' compositionHelper.compositionstart(); compositionHelper.compositionupdate({ data: 'ㅇ' }); diff --git a/src/CompositionHelper.ts b/src/CompositionHelper.ts index 439e2085..223a90e7 100644 --- a/src/CompositionHelper.ts +++ b/src/CompositionHelper.ts @@ -51,7 +51,7 @@ export class CompositionHelper { /** * Handles the compositionstart event, activating the composition view. */ - public compositionstart() { + public compositionstart(): void { this.isComposing = true; this.compositionPosition.start = this.textarea.value.length; this.compositionView.textContent = ''; @@ -62,7 +62,7 @@ export class CompositionHelper { * Handles the compositionupdate event, updating the composition view. * @param {CompositionEvent} ev The event. */ - public compositionupdate(ev: CompositionEvent) { + public compositionupdate(ev: CompositionEvent): void { this.compositionView.textContent = ev.data; this.updateCompositionElements(); setTimeout(() => { @@ -74,7 +74,7 @@ export class CompositionHelper { * Handles the compositionend event, hiding the composition view and sending the composition to * the handler. */ - public compositionend() { + public compositionend(): void { this.finalizeComposition(true); } @@ -83,7 +83,7 @@ export class CompositionHelper { * @param ev The keydown event. * @return Whether the Terminal should continue processing the keydown event. */ - public keydown(ev: KeyboardEvent) { + public keydown(ev: KeyboardEvent): boolean { if (this.isComposing || this.isSendingComposition) { if (ev.keyCode === 229) { // Continue composing if the keyCode is the "composition character" @@ -116,7 +116,7 @@ export class CompositionHelper { * compositionend event is triggered, such as enter, so that the composition is send before * the command is executed. */ - private finalizeComposition(waitForPropogation: boolean) { + private finalizeComposition(waitForPropogation: boolean): void { this.compositionView.classList.remove('active'); this.isComposing = false; this.clearTextareaPosition(); @@ -169,7 +169,7 @@ export class CompositionHelper { * character" (229) is triggered, in order to allow non-composition text to be entered when an * IME is active. */ - private handleAnyTextareaChanges() { + private handleAnyTextareaChanges(): void { const oldValue = this.textarea.value; setTimeout(() => { // Ignore if a composition has started since the timeout @@ -189,7 +189,7 @@ export class CompositionHelper { * @param dontRecurse Whether to use setTimeout to recursively trigger another update, this is * necessary as the IME events across browsers are not consistently triggered. */ - public updateCompositionElements(dontRecurse?: boolean) { + public updateCompositionElements(dontRecurse?: boolean): void { if (!this.isComposing) { return; } @@ -222,7 +222,7 @@ export class CompositionHelper { * Clears the textarea's position so that the cursor does not blink on IE. * @private */ - private clearTextareaPosition() { + private clearTextareaPosition(): void { this.textarea.style.left = ''; this.textarea.style.top = ''; }; diff --git a/src/EventEmitter.ts b/src/EventEmitter.ts index 3d34da75..a1768d2d 100644 --- a/src/EventEmitter.ts +++ b/src/EventEmitter.ts @@ -2,15 +2,10 @@ * @license MIT */ -import { IEventEmitter } from './Interfaces'; - -interface ListenerType { - (): void; - listener?: () => void; -}; +import { IEventEmitter, IListenerType } from './Interfaces'; export class EventEmitter implements IEventEmitter { - private _events: {[type: string]: ListenerType[]}; + private _events: {[type: string]: IListenerType[]}; constructor() { // Restore the previous events if available, this will happen if the @@ -18,12 +13,12 @@ export class EventEmitter implements IEventEmitter { this._events = this._events || {}; } - public on(type, listener): void { + public on(type: string, listener: IListenerType): void { this._events[type] = this._events[type] || []; this._events[type].push(listener); } - public off(type, listener): void { + public off(type: string, listener: IListenerType): void { if (!this._events[type]) { return; } @@ -39,20 +34,20 @@ export class EventEmitter implements IEventEmitter { } } - public removeAllListeners(type): void { + public removeAllListeners(type: string): void { if (this._events[type]) { delete this._events[type]; } } - public once(type, listener): any { - function on() { + public once(type: string, listener: IListenerType): void { + function on(): void { let args = Array.prototype.slice.call(arguments); this.off(type, on); - return listener.apply(this, args); + listener.apply(this, args); } (on).listener = listener; - return this.on(type, on); + this.on(type, on); } public emit(type: string, ...args: any[]): void { @@ -65,7 +60,7 @@ export class EventEmitter implements IEventEmitter { } } - public listeners(type): ListenerType[] { + public listeners(type: string): IListenerType[] { return this._events[type] || []; } diff --git a/src/InputHandler.test.ts b/src/InputHandler.test.ts index 95624296..b6b218df 100644 --- a/src/InputHandler.test.ts +++ b/src/InputHandler.test.ts @@ -65,7 +65,7 @@ describe('InputHandler', () => { }); }); -const old_wcwidth = (function(opts) { +const old_wcwidth = (function(opts: {nul: number, control: number}): (ucs: number) => number { // extracted from https://www.cl.cam.ac.uk/%7Emgk25/ucs/wcwidth.c // combining characters const COMBINING = [ @@ -119,7 +119,7 @@ const old_wcwidth = (function(opts) { [0xE0100, 0xE01EF] ]; // binary search - function bisearch(ucs) { + function bisearch(ucs: number): boolean { let min = 0; let max = COMBINING.length - 1; let mid; @@ -136,23 +136,26 @@ const old_wcwidth = (function(opts) { } return false; } - function wcwidth(ucs) { - // test for 8-bit control characters - if (ucs === 0) - return opts.nul; - if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) - return opts.control; - // binary search in table of non-spacing characters - if (bisearch(ucs)) - return 0; - // if we arrive here, ucs is not a combining or C0/C1 control character - if (isWide(ucs)) { - return 2; - } - return 1; + function wcwidth(ucs: number): number { + // test for 8-bit control characters + if (ucs === 0) { + return opts.nul; + } + if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) { + return opts.control; + } + // binary search in table of non-spacing characters + if (bisearch(ucs)) { + return 0; + } + // if we arrive here, ucs is not a combining or C0/C1 control character + if (isWide(ucs)) { + return 2; + } + return 1; } - function isWide(ucs) { - return ( + function isWide(ucs: number): boolean { + return ( ucs >= 0x1100 && ( ucs <= 0x115f || // Hangul Jamo init. consonants ucs === 0x2329 || diff --git a/src/InputHandler.ts b/src/InputHandler.ts index 8f566cd9..9376d182 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -221,7 +221,7 @@ export class InputHandler implements IInputHandler { * CSI Ps B * Cursor Down Ps Times (default = 1) (CUD). */ - public cursorDown(params: number[]) { + public cursorDown(params: number[]): void { let param = params[0]; if (param < 1) { param = 1; @@ -240,7 +240,7 @@ export class InputHandler implements IInputHandler { * CSI Ps C * Cursor Forward Ps Times (default = 1) (CUF). */ - public cursorForward(params: number[]) { + public cursorForward(params: number[]): void { let param = params[0]; if (param < 1) { param = 1; @@ -255,7 +255,7 @@ export class InputHandler implements IInputHandler { * CSI Ps D * Cursor Backward Ps Times (default = 1) (CUB). */ - public cursorBackward(params: number[]) { + public cursorBackward(params: number[]): void { let param = params[0]; if (param < 1) { param = 1; @@ -1460,7 +1460,7 @@ export class InputHandler implements IInputHandler { } } -export const wcwidth = (function(opts) { +export const wcwidth = (function(opts: {nul: number, control: number}): (ucs: number) => number { // extracted from https://www.cl.cam.ac.uk/%7Emgk25/ucs/wcwidth.c // combining characters const COMBINING_BMP = [ @@ -1516,7 +1516,7 @@ export const wcwidth = (function(opts) { [0xE0100, 0xE01EF] ]; // binary search - function bisearch(ucs, data) { + function bisearch(ucs: number, data: number[][]): boolean { let min = 0; let max = data.length - 1; let mid; @@ -1533,7 +1533,7 @@ export const wcwidth = (function(opts) { } return false; } - function wcwidthBMP(ucs) { + function wcwidthBMP(ucs: number): number { // test for 8-bit control characters if (ucs === 0) return opts.nul; @@ -1548,7 +1548,7 @@ export const wcwidth = (function(opts) { } return 1; } - function isWideBMP(ucs) { + function isWideBMP(ucs: number): boolean { return ( ucs >= 0x1100 && ( ucs <= 0x115f || // Hangul Jamo init. consonants @@ -1562,7 +1562,7 @@ export const wcwidth = (function(opts) { (ucs >= 0xff00 && ucs <= 0xff60) || // Fullwidth Forms (ucs >= 0xffe0 && ucs <= 0xffe6))); } - function wcwidthHigh(ucs) { + function wcwidthHigh(ucs: number): 0 | 1 | 2 { if (bisearch(ucs, COMBINING_HIGH)) return 0; if ((ucs >= 0x20000 && ucs <= 0x2fffd) || (ucs >= 0x30000 && ucs <= 0x3fffd)) { @@ -1571,8 +1571,8 @@ export const wcwidth = (function(opts) { return 1; } const control = opts.control | 0; - let table = null; - function init_table() { + let table: number[] | Uint32Array = null; + function init_table(): number[] | Uint32Array { // lookup table for BMP const CODEPOINTS = 65536; // BMP holds 65536 codepoints const BITWIDTH = 2; // a codepoint can have a width of 0, 1 or 2 @@ -1589,7 +1589,7 @@ export const wcwidth = (function(opts) { num = (num << 2) | wcwidthBMP(CODEPOINTS_PER_ITEM * i + pos); table[i] = num; } - return table; + return table; } // get width from lookup table // position in container : num / CODEPOINTS_PER_ITEM @@ -1603,7 +1603,7 @@ export const wcwidth = (function(opts) { // ==> n = n >> m e.g. m=12 000000000000FFEEDDCCBBAA99887766 // we are only interested in 2 LSBs, cut off higher bits // ==> n = n & 3 e.g. 000000000000000000000000000000XX - return function (num) { + return function (num: number): number { num = num | 0; // get asm.js like optimization under V8 if (num < 32) return control | 0; diff --git a/src/Interfaces.ts b/src/Interfaces.ts index b61c0057..875cbac8 100644 --- a/src/Interfaces.ts +++ b/src/Interfaces.ts @@ -2,7 +2,7 @@ * @license MIT */ -import { LinkMatcherOptions } from './Interfaces'; +import { ILinkMatcherOptions } from './Interfaces'; import { LinkMatcherHandler, LinkMatcherValidationCallback, Charset } from './Types'; export interface IBrowser { @@ -40,10 +40,9 @@ export interface ITerminal extends IEventEmitter { * Emit the 'data' event and populate the given data. * @param data The data to populate in the event. */ - handler(data: string); - on(event: string, callback: () => void); - scrollDisp(disp: number, suppressScrollEvent: boolean); - cancel(ev: Event, force?: boolean); + handler(data: string): void; + scrollDisp(disp: number, suppressScrollEvent?: boolean): void; + cancel(ev: Event, force?: boolean): boolean | void; log(text: string): void; reset(): void; showCursor(): void; @@ -107,7 +106,7 @@ export interface IInputHandlingTerminal extends IEventEmitter { reset(): void; showCursor(): void; refresh(start: number, end: number): void; - matchColor(r1, g1, b1): any; + matchColor(r1: number, g1: number, b1: number): any; error(text: string, data?: any): void; setOption(key: string, value: any): void; } @@ -167,7 +166,7 @@ export interface ISelectionManager { disable(): void; enable(): void; setBuffer(buffer: ICircularList<[number, string, number][]>): void; - setSelection(row: number, col: number, length: number); + setSelection(row: number, col: number, length: number): void; } export interface ICharMeasure { @@ -179,7 +178,7 @@ export interface ICharMeasure { export interface ILinkifier { linkifyRow(rowIndex: number): void; attachHypertextLinkHandler(handler: LinkMatcherHandler): void; - registerLinkMatcher(regex: RegExp, handler: LinkMatcherHandler, options?: LinkMatcherOptions): number; + registerLinkMatcher(regex: RegExp, handler: LinkMatcherHandler, options?: ILinkMatcherOptions): number; deregisterLinkMatcher(matcherId: number): boolean; } @@ -198,12 +197,17 @@ export interface ICircularList extends IEventEmitter { } export interface IEventEmitter { - on(type, listener): void; - off(type, listener): void; + on(type: string, listener: IListenerType): void; + off(type: string, listener: IListenerType): void; emit(type: string, data?: any): void; } -export interface LinkMatcherOptions { +export interface IListenerType { + (data?: any): void; + listener?: (data?: any) => void; +}; + +export interface ILinkMatcherOptions { /** * The index of the link from the regex.match(text) call. This defaults to 0 * (for regular expressions without capture groups). diff --git a/src/Linkifier.test.ts b/src/Linkifier.test.ts index 132ce5f0..414238f9 100644 --- a/src/Linkifier.test.ts +++ b/src/Linkifier.test.ts @@ -32,7 +32,7 @@ describe('Linkifier', () => { linkifier = new TestLinkifier(); }); - function addRow(html: string) { + function addRow(html: string): void { const element = document.createElement('div'); element.innerHTML = html; container.appendChild(element); @@ -57,24 +57,24 @@ describe('Linkifier', () => { document.body.appendChild(container); }); - function clickElement(element: Node) { + function clickElement(element: Node): void { const event = document.createEvent('MouseEvent'); event.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); element.dispatchEvent(event); } - function assertLinkifiesEntireRow(uri: string, done: MochaDone) { - addRow(uri); - linkifier.linkifyRow(0); - setTimeout(() => { - assert.equal((rows[0].firstChild).tagName, 'A'); - assert.equal((rows[0].firstChild).textContent, uri); - done(); - }, 0); + function assertLinkifiesEntireRow(uri: string, done: MochaDone): void { + addRow(uri); + linkifier.linkifyRow(0); + setTimeout(() => { + assert.equal((rows[0].firstChild).tagName, 'A'); + assert.equal((rows[0].firstChild).textContent, uri); + done(); + }, 0); } describe('http links', () => { - function assertLinkifiesEntireRow(uri: string, done: MochaDone) { + function assertLinkifiesEntireRow(uri: string, done: MochaDone): void { addRow(uri); linkifier.linkifyRow(0); setTimeout(() => { @@ -87,7 +87,7 @@ describe('Linkifier', () => { }); describe('link matcher', () => { - function assertLinkifiesRow(rowText: string, linkMatcherRegex: RegExp, expectedHtml: string, done: MochaDone) { + function assertLinkifiesRow(rowText: string, linkMatcherRegex: RegExp, expectedHtml: string, done: MochaDone): void { addRow(rowText); linkifier.registerLinkMatcher(linkMatcherRegex, () => {}); linkifier.linkifyRow(0); diff --git a/src/Linkifier.ts b/src/Linkifier.ts index bc4949b1..2323f226 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -2,7 +2,7 @@ * @license MIT */ -import { LinkMatcherOptions } from './Interfaces'; +import { ILinkMatcherOptions } from './Interfaces'; import { LinkMatcher, LinkMatcherHandler, LinkMatcherValidationCallback } from './Types'; const INVALID_LINK_CLASS = 'xterm-invalid-link'; @@ -60,7 +60,7 @@ export class Linkifier { * @param document The document object. * @param rows The array of rows to apply links to. */ - public attachToDom(document: Document, rows: HTMLElement[]) { + public attachToDom(document: Document, rows: HTMLElement[]): void { this._document = document; this._rows = rows; } @@ -108,10 +108,10 @@ export class Linkifier { * this searches the textContent of the rows. You will want to use \s to match * a space ' ' character for example. * @param {LinkHandler} handler The callback when the link is called. - * @param {LinkMatcherOptions} [options] Options for the link matcher. + * @param {ILinkMatcherOptions} [options] Options for the link matcher. * @return {number} The ID of the new matcher, this can be used to deregister. */ - public registerLinkMatcher(regex: RegExp, handler: LinkMatcherHandler, options: LinkMatcherOptions = {}): number { + public registerLinkMatcher(regex: RegExp, handler: LinkMatcherHandler, options: ILinkMatcherOptions = {}): number { if (this._nextLinkMatcherId !== HYPERTEXT_LINK_MATCHER_ID && !handler) { throw new Error('handler must be defined'); } diff --git a/src/Parser.ts b/src/Parser.ts index bec0af7b..90d413a7 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -613,7 +613,7 @@ export class Parser { * * @param param the parameter. */ - public setParam(param: number) { + public setParam(param: number): void { this._terminal.currentParam = param; } diff --git a/src/Renderer.ts b/src/Renderer.ts index 165594fd..f706bffc 100644 --- a/src/Renderer.ts +++ b/src/Renderer.ts @@ -37,7 +37,7 @@ export class Renderer { // Figure out whether boldness affects // the character width of monospace fonts. if (brokenBold === null) { - brokenBold = checkBoldBroken((this._terminal).element); + brokenBold = checkBoldBroken(this._terminal.element); } this._spanElementObjectPool = new DomElementObjectPool('span'); @@ -327,7 +327,7 @@ export class Renderer { * @param start The selection start. * @param end The selection end. */ - public refreshSelection(start: [number, number], end: [number, number]) { + public refreshSelection(start: [number, number], end: [number, number]): void { // Remove all selections while (this._terminal.selectionContainer.children.length) { this._terminal.selectionContainer.removeChild(this._terminal.selectionContainer.children[0]); @@ -385,16 +385,16 @@ export class Renderer { // If bold is broken, we can't use it in the terminal. -function checkBoldBroken(terminal) { - const document = terminal.ownerDocument; +function checkBoldBroken(terminalElement: HTMLElement): boolean { + const document = terminalElement.ownerDocument; const el = document.createElement('span'); el.innerHTML = 'hello world'; - terminal.appendChild(el); + terminalElement.appendChild(el); const w1 = el.offsetWidth; const h1 = el.offsetHeight; el.style.fontWeight = 'bold'; const w2 = el.offsetWidth; const h2 = el.offsetHeight; - terminal.removeChild(el); + terminalElement.removeChild(el); return w1 !== w2 || h1 !== h2; } diff --git a/src/SelectionManager.ts b/src/SelectionManager.ts index bf594f70..e3770c06 100644 --- a/src/SelectionManager.ts +++ b/src/SelectionManager.ts @@ -7,7 +7,7 @@ import * as Browser from './utils/Browser'; import { CharMeasure } from './utils/CharMeasure'; import { CircularList } from './utils/CircularList'; import { EventEmitter } from './EventEmitter'; -import { ITerminal, ICircularList } from './Interfaces'; +import { ITerminal, ICircularList, ISelectionManager } from './Interfaces'; import { SelectionModel } from './SelectionModel'; import { translateBufferLineToString } from './utils/BufferLine'; @@ -66,7 +66,7 @@ enum SelectionMode { * not handled by the SelectionManager but a 'refresh' event is fired when the * selection is ready to be redrawn. */ -export class SelectionManager extends EventEmitter { +export class SelectionManager extends EventEmitter implements ISelectionManager { protected _model: SelectionModel; /** @@ -116,7 +116,7 @@ export class SelectionManager extends EventEmitter { /** * Initializes listener variables. */ - private _initListeners() { + private _initListeners(): void { this._mouseMoveListener = event => this._onMouseMove(event); this._mouseUpListener = event => this._onMouseUp(event); @@ -267,7 +267,7 @@ export class SelectionManager extends EventEmitter { * Handle the buffer being trimmed, adjust the selection position. * @param amount The amount the buffer is being trimmed. */ - private _onTrim(amount: number) { + private _onTrim(amount: number): void { const needsRefresh = this._model.onTrim(amount); if (needsRefresh) { this.refresh(); @@ -316,7 +316,7 @@ export class SelectionManager extends EventEmitter { * Handles te mousedown event, setting up for a new selection. * @param event The mousedown event. */ - private _onMouseDown(event: MouseEvent) { + private _onMouseDown(event: MouseEvent): void { // If we have selection, we want the context menu on right click even if the // terminal is in mouse mode. if (event.button === 2 && this.hasSelection) { @@ -455,7 +455,7 @@ export class SelectionManager extends EventEmitter { * end of the selection and refreshing the selection. * @param event The mousemove event. */ - private _onMouseMove(event: MouseEvent) { + private _onMouseMove(event: MouseEvent): void { // Record the previous position so we know whether to redraw the selection // at the end. const previousSelectionEnd = this._model.selectionEnd ? [this._model.selectionEnd[0], this._model.selectionEnd[1]] : null; @@ -511,7 +511,7 @@ export class SelectionManager extends EventEmitter { * The callback that occurs every DRAG_SCROLL_INTERVAL ms that does the * scrolling of the viewport. */ - private _dragScroll() { + private _dragScroll(): void { if (this._dragScrollAmount) { this._terminal.scrollDisp(this._dragScrollAmount, false); // Re-evaluate selection @@ -528,7 +528,7 @@ export class SelectionManager extends EventEmitter { * Handles the mouseup event, removing the mousedown listeners. * @param event The mouseup event. */ - private _onMouseUp(event: MouseEvent) { + private _onMouseUp(event: MouseEvent): void { this._removeMouseDownListeners(); } diff --git a/src/Terminal.ts b/src/Terminal.ts index df313ee3..b3a27be9 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -29,8 +29,8 @@ import * as Mouse from './utils/Mouse'; import { CHARSETS } from './Charsets'; import { getRawByteCoords } from './utils/Mouse'; import { translateBufferLineToString } from './utils/BufferLine'; -import { CustomKeyEventHandler, Charset } from './Types'; -import { ITerminal, IBrowser, ITerminalOptions, IInputHandlingTerminal } from './Interfaces'; +import { CustomKeyEventHandler, Charset, LinkMatcherHandler, LinkMatcherValidationCallback } from './Types'; +import { ITerminal, IBrowser, ITerminalOptions, IInputHandlingTerminal, ILinkMatcherOptions } from './Interfaces'; // Declare for RequireJS in loadAddon declare var define: any; @@ -94,7 +94,7 @@ const tangoColors: string[] = [ // Colors 0-15 + 16-255 // Much thanks to TooTallNate for writing this. -const defaultColors: string[] = (function() { +const defaultColors: string[] = (function(): string[] { let colors = tangoColors.slice(); let r = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]; let i; @@ -113,13 +113,13 @@ const defaultColors: string[] = (function() { out(c, c, c); } - function out(r, g, b) { + function out(r: number, g: number, b: number): void { colors.push('#' + hex(r) + hex(g) + hex(b)); } - function hex(c) { - c = c.toString(16); - return c.length < 2 ? '0' + c : c; + function hex(c: number): string { + let s = c.toString(16); + return s.length < 2 ? '0' + s : s; } return colors; @@ -127,8 +127,8 @@ const defaultColors: string[] = (function() { const _colors: string[] = defaultColors.slice(); -const vcolors: number[][] = (function() { - const out = []; +const vcolors: number[][] = (function(): number[][] { + const out: number[][] = []; let color; for (let i = 0; i < 256; i++) { @@ -387,8 +387,8 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT // Create the terminal's buffers and set the current buffer this.buffers = new BufferSet(this); this.buffer = this.buffers.active; // Convenience shortcut; - this.buffers.on('activate', function (buffer) { - this._terminal.buffer = buffer; + this.buffers.on('activate', (buffer: Buffer) => { + this.buffer = buffer; }); let i = this.rows; @@ -485,11 +485,11 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT } } - private restartCursorBlinking() { + private restartCursorBlinking(): void { this.setCursorBlinking(this.options.cursorBlink); } - private setCursorBlinking(enabled) { + private setCursorBlinking(enabled: boolean): void { this.element.classList.toggle('xterm-cursor-blink', enabled); this.clearCursorBlinkingInterval(); if (enabled) { @@ -499,7 +499,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT } } - private clearCursorBlinkingInterval() { + private clearCursorBlinkingInterval(): void { this.element.classList.remove('xterm-cursor-blink-on'); if (this.cursorBlinkInterval) { clearInterval(this.cursorBlinkInterval); @@ -510,7 +510,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT /** * Binds the desired focus behavior on a given terminal object. */ - private bindFocus() { + private bindFocus(): void { globalOn(this.textarea, 'focus', (ev) => { if (this.sendFocus) { this.send(C0.ESC + '[I'); @@ -526,14 +526,14 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT /** * Blur the terminal. Delegates blur handling to the terminal's DOM element. */ - private blur() { + private blur(): void { return this.textarea.blur(); } /** * Binds the desired blur behavior on a given terminal object. */ - private bindBlur() { + private bindBlur(): void { on(this.textarea, 'blur', (ev) => { this.refresh(this.buffer.y, this.buffer.y); if (this.sendFocus) { @@ -549,7 +549,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT /** * Initialize default behavior */ - private initGlobal() { + private initGlobal(): void { this.bindKeys(); this.bindFocus(); this.bindBlur(); @@ -598,33 +598,33 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT /** * Apply key handling to the terminal */ - private bindKeys() { + private bindKeys(): void { const self = this; - on(this.element, 'keydown', function (ev) { + on(this.element, 'keydown', function (ev: KeyboardEvent): void { if (document.activeElement !== this) { return; } self.keyDown(ev); }, true); - on(this.element, 'keypress', function (ev) { + on(this.element, 'keypress', function (ev: KeyboardEvent): void { if (document.activeElement !== this) { return; } self.keyPress(ev); }, true); - on(this.element, 'keyup', (ev) => { + on(this.element, 'keyup', (ev: KeyboardEvent) => { if (!wasMondifierKeyOnlyEvent(ev)) { this.focus(); } }, true); - on(this.textarea, 'keydown', (ev) => { + on(this.textarea, 'keydown', (ev: KeyboardEvent) => { this.keyDown(ev); }, true); - on(this.textarea, 'keypress', (ev) => { + on(this.textarea, 'keypress', (ev: KeyboardEvent) => { this.keyPress(ev); // Truncate the textarea's value, since it is not needed this.textarea.value = ''; @@ -642,7 +642,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT * if no row argument is passed. Return the inserted row. * @param {HTMLElement} row (optional) The row to append to the terminal. */ - private insertRow(row?: HTMLElement) { + private insertRow(row?: HTMLElement): HTMLElement { if (typeof row !== 'object') { row = document.createElement('div'); } @@ -659,7 +659,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT * @param {HTMLElement} parent The element to create the terminal within. * @param {boolean} focus Focus the terminal, after it gets instantiated in the DOM */ - private open(parent, focus) { + private open(parent: HTMLElement, focus?: boolean): void { let i = 0; let div; @@ -802,7 +802,8 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT * @param {string} addon The name of the addon to load * @static */ - public static loadAddon(addon, callback) { + public static loadAddon(addon: string, callback?: Function): boolean | any { + // TODO: Improve return type and documentation if (typeof exports === 'object' && typeof module === 'object') { // CommonJS return require('./addons/' + addon + '/' + addon); @@ -819,7 +820,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT * Updates the helper CSS class with any changes necessary after the terminal's * character width has been changed. */ - public updateCharSizeStyles() { + public updateCharSizeStyles(): void { this.charSizeStyleElement.textContent = `.xterm-wide-char{width:${this.charMeasure.width * 2}px;}` + `.xterm-normal-char{width:${this.charMeasure.width}px;}` + @@ -836,7 +837,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT * Relevant functions in xterm/button.c: * BtnCode, EmitButtonCode, EditorButton, SendMousePosition */ - public bindMouse() { + public bindMouse(): void { const el = this.element; const self = this; let pressed = 32; @@ -844,7 +845,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT // mouseup, mousedown, wheel // left click: ^[[M 3<^[[M#3< // wheel up: ^[[M`3> - function sendButton(ev) { + function sendButton(ev: MouseEvent | WheelEvent): void { let button; let pos; @@ -857,7 +858,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT sendEvent(button, pos); - switch (ev.overrideType || ev.type) { + switch ((ev).overrideType || ev.type) { case 'mousedown': pressed = button; break; @@ -876,11 +877,9 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT // motion example of a left click: // ^[[M 3<^[[M@4<^[[M@5<^[[M@6<^[[M@7<^[[M#7< - function sendMove(ev) { + function sendMove(ev: MouseEvent): void { let button = pressed; - let pos; - - pos = getRawByteCoords(ev, self.rowContainer, self.charMeasure, self.cols, self.rows); + let pos = getRawByteCoords(ev, self.rowContainer, self.charMeasure, self.cols, self.rows); if (!pos) return; // buttons marked as motions @@ -892,13 +891,19 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT // encode button and // position to characters - function encode(data, ch) { + function encode(data: number[], ch: number): void { if (!self.utfMouse) { - if (ch === 255) return data.push(0); + if (ch === 255) { + data.push(0); + return; + } if (ch > 127) ch = 127; data.push(ch); } else { - if (ch === 2047) return data.push(0); + if (ch === 2047) { + data.push(0); + return; + } if (ch < 127) { data.push(ch); } else { @@ -915,7 +920,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT // sgr: ^[[ Cb ; Cx ; Cy M/m // vt300: ^[[ 24(1/3/5)~ [ Cx , Cy ] \r // locator: CSI P e ; P b ; P r ; P c ; P p & w - function sendEvent(button, pos) { + function sendEvent(button: number, pos: {x: number, y: number}): void { // self.emit('mouse', { // x: pos.x - 32, // y: pos.x - 32, @@ -957,7 +962,8 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT + ';' + pos.x + ';' - + (pos.page || 0) + // Not sure what page is meant to be + + (pos).page || 0 + '&w'); return; } @@ -984,7 +990,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT return; } - let data = []; + let data: number[] = []; encode(data, button); encode(data, pos.x); @@ -993,7 +999,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT self.send(C0.ESC + '[M' + String.fromCharCode.apply(String, data)); } - function getButton(ev) { + function getButton(ev: MouseEvent): number { let button; let shift; let meta; @@ -1007,7 +1013,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT // 3 = release // wheel up/down: // 1, and 2 - with 64 added - switch (ev.overrideType || ev.type) { + switch ((ev).overrideType || ev.type) { case 'mousedown': button = ev.button != null ? +ev.button @@ -1028,7 +1034,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT : 65; break; case 'wheel': - button = ev.wheelDeltaY > 0 + button = (ev).wheelDeltaY > 0 ? 64 : 65; break; @@ -1055,7 +1061,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT return button; } - on(el, 'mousedown', (ev) => { + on(el, 'mousedown', (ev: MouseEvent) => { // Prevent the focus on the textarea from getting lost // and make sure we get focused on mousedown @@ -1082,10 +1088,12 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT if (!this.x10Mouse) { const handler = (ev: MouseEvent) => { sendButton(ev); + // TODO: Seems dangerous calling this on document? if (this.normalMouse) off(this.document, 'mousemove', sendMove); off(this.document, 'mouseup', handler); return this.cancel(ev); }; + // TODO: Seems dangerous calling this on document? on(this.document, 'mouseup', handler); } @@ -1096,7 +1104,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT // on(this.document, 'mousemove', sendMove); // } - on(el, 'wheel', (ev) => { + on(el, 'wheel', (ev: WheelEvent) => { if (!this.mouseEvents) return; if (this.x10Mouse || this.vt300Mouse || this.decLocator) return; sendButton(ev); @@ -1131,8 +1139,8 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT super.destroy(); this.readable = false; this.writable = false; - this.handler = function() {}; - this.write = function() {}; + this.handler = () => {}; + this.write = () => {}; if (this.element && this.element.parentNode) { this.element.parentNode.removeChild(this.element); } @@ -1316,7 +1324,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT } } - private innerWrite() { + private innerWrite(): void { const writeBatch = this.writeBuffer.splice(0, WRITE_BATCH_SIZE); while (writeBatch.length > 0) { const data = writeBatch.shift(); @@ -1354,7 +1362,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT * Writes text to the terminal, followed by a break line character (\n). * @param {string} data The text to write to the terminal. */ - public writeln(data): void { + public writeln(data: string): void { this.write(data + '\r\n'); } @@ -1386,9 +1394,9 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT * Attaches a http(s) link handler, forcing web links to behave differently to * regular tags. This will trigger a refresh as links potentially need to be * reconstructed. Calling this with null will remove the handler. - * @param {LinkMatcherHandler} handler The handler callback function. + * @param handler The handler callback function. */ - public setHypertextLinkHandler(handler) { + public setHypertextLinkHandler(handler: LinkMatcherHandler): void { if (!this.linkifier) { throw new Error('Cannot attach a hypertext link handler before Terminal.open is called'); } @@ -1400,10 +1408,10 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT /** * Attaches a validation callback for hypertext links. This is useful to use * validation logic or to do something with the link's element and url. - * @param {LinkMatcherValidationCallback} callback The callback to use, this can + * @param callback The callback to use, this can * be cleared with null. */ - public setHypertextValidationCallback(callback) { + public setHypertextValidationCallback(callback: LinkMatcherValidationCallback): void { if (!this.linkifier) { throw new Error('Cannot attach a hypertext validation callback before Terminal.open is called'); } @@ -1413,16 +1421,16 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT } /** - * Registers a link matcher, allowing custom link patterns to be matched and - * handled. - * @param {RegExp} regex The regular expression to search for, specifically - * this searches the textContent of the rows. You will want to use \s to match - * a space ' ' character for example. - * @param {LinkMatcherHandler} handler The callback when the link is called. - * @param {LinkMatcherOptions} [options] Options for the link matcher. - * @return {number} The ID of the new matcher, this can be used to deregister. + * Registers a link matcher, allowing custom link patterns to be matched and + * handled. + * @param regex The regular expression to search for, specifically + * this searches the textContent of the rows. You will want to use \s to match + * a space ' ' character for example. + * @param handler The callback when the link is called. + * @param [options] Options for the link matcher. + * @return The ID of the new matcher, this can be used to deregister. */ - public registerLinkMatcher(regex, handler, options) { + public registerLinkMatcher(regex: RegExp, handler: LinkMatcherHandler, options: ILinkMatcherOptions): number { if (this.linkifier) { const matcherId = this.linkifier.registerLinkMatcher(regex, handler, options); this.refresh(0, this.rows - 1); @@ -1432,9 +1440,9 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT /** * Deregisters a link matcher if it has been registered. - * @param {number} matcherId The link matcher's ID (returned after register) + * @param matcherId The link matcher's ID (returned after register) */ - public deregisterLinkMatcher(matcherId) { + public deregisterLinkMatcher(matcherId: number): void { if (this.linkifier) { if (this.linkifier.deregisterLinkMatcher(matcherId)) { this.refresh(0, this.rows - 1); @@ -1445,7 +1453,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT /** * Gets whether the terminal has an active selection. */ - public hasSelection() { + public hasSelection(): boolean { return this.selectionManager ? this.selectionManager.hasSelection : false; } @@ -1453,14 +1461,14 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT * Gets the terminal's current selection, this is useful for implementing copy * behavior outside of xterm.js. */ - public getSelection() { + public getSelection(): string { return this.selectionManager ? this.selectionManager.selectionText : ''; } /** * Clears the current terminal selection. */ - public clearSelection() { + public clearSelection(): void { if (this.selectionManager) { this.selectionManager.clearSelection(); } @@ -1469,7 +1477,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT /** * Selects all text within the terminal. */ - public selectAll() { + public selectAll(): void { if (this.selectionManager) { this.selectionManager.selectAll(); } @@ -1481,7 +1489,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent * @param {KeyboardEvent} ev The keydown event to be handled. */ - private keyDown(ev) { + private keyDown(ev: KeyboardEvent): boolean { if (this.customKeyEventHandler && this.customKeyEventHandler(ev) === false) { return false; } @@ -1508,7 +1516,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT return this.cancel(ev, true); } - if (isThirdLevelShift(this, ev)) { + if (isThirdLevelShift(ev)) { return true; } @@ -1534,10 +1542,10 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT * returned value is the new key code to pass to the PTY. * * Reference: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html - * @param {KeyboardEvent} ev The keyboard event to be translated to key escape sequence. + * @param ev The keyboard event to be translated to key escape sequence. */ - private evaluateKeyEscapeSequence(ev) { - const result = { + private evaluateKeyEscapeSequence(ev: KeyboardEvent): {cancel: boolean, key: string, scrollDisp: number} { + const result: {cancel: boolean, key: string, scrollDisp: number} = { // Whether to cancel event propogation (NOTE: this may not be needed since the event is // canceled at the end of keyDown cancel: false, @@ -1546,7 +1554,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT // The number of characters to scroll, if this is defined it will cancel the event scrollDisp: undefined }; - const modifiers = ev.shiftKey << 0 | ev.altKey << 1 | ev.ctrlKey << 2 | ev.metaKey << 3; + const modifiers = (ev.shiftKey ? 1 : 0) | (ev.altKey ? 2 : 0) | (ev.ctrlKey ? 4 : 0) | (ev.metaKey ? 8 : 0); switch (ev.keyCode) { case 8: // backspace @@ -1843,7 +1851,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent * @param {KeyboardEvent} ev The keypress event to be handled. */ - private keyPress(ev) { + private keyPress(ev: KeyboardEvent): boolean { let key; if (this.customKeyEventHandler && this.customKeyEventHandler(ev) === false) { @@ -1863,7 +1871,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT } if (!key || ( - (ev.altKey || ev.ctrlKey || ev.metaKey) && !isThirdLevelShift(this, ev) + (ev.altKey || ev.ctrlKey || ev.metaKey) && !isThirdLevelShift(ev) )) { return false; } @@ -1897,7 +1905,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT * Ring the bell. * Note: We could do sweet things with webaudio here */ - public bell() { + public bell(): void { if (!this.options.visualBell) return; this.element.style.borderColor = 'white'; setTimeout(() => { @@ -2064,7 +2072,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT /** * Set the range of refreshing to the maximum value */ - public maxRange() { + public maxRange(): void { this.refreshStart = 0; this.refreshEnd = this.rows - 1; } @@ -2073,7 +2081,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT * Setup the tab stops. * @param {number} i */ - public setupStops(i?: number) { + public setupStops(i?: number): void { if (i != null) { if (!this.buffer.tabs[i]) { i = this.prevStop(i); @@ -2146,7 +2154,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT /** * Clears the entire buffer, making the prompt line the new first line. */ - public clear() { + public clear(): void { if (this.buffer.ybase === 0 && this.buffer.y === 0) { // Don't clear if it's already clear return; @@ -2197,9 +2205,9 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT /** * If cur return the back color xterm feature attribute. Else return defAttr. - * @param {object} cur + * @param cur */ - public ch(cur) { + public ch(cur?: boolean): [number, string, number] { return cur ? [this.eraseAttr(), ' ', 1] : [this.defAttr, ' ', 1]; } @@ -2237,7 +2245,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT * Emit the 'title' event and populate the given title. * @param {string} title The title to populate in the event. */ - private handleTitle(title: string) { + private handleTitle(title: string): void { /** * This event is emitted when the title of the terminal is changed * from inside the terminal. The parameter is the new title. @@ -2254,7 +2262,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT /** * ESC D Index (IND is 0x84). */ - public index() { + public index(): void { this.buffer.y++; if (this.buffer.y > this.buffer.scrollBottom) { this.buffer.y--; @@ -2271,7 +2279,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT * * Move the cursor up one row, inserting a new blank line if necessary. */ - public reverseIndex() { + public reverseIndex(): void { if (this.buffer.y === this.buffer.scrollTop) { // possibly move the code below to term.reverseScroll(); // test: echo -ne '\e[1;1H\e[44m\eM\e[0m' @@ -2308,11 +2316,11 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT /** * ESC H Tab Set (HTS is 0x88). */ - private tabSet() { + private tabSet(): void { this.buffer.tabs[this.buffer.x] = true; } - public cancel(ev: Event, force?: boolean) { + public cancel(ev: Event, force?: boolean): boolean { if (!this.options.cancelEvents && !force) { return; } @@ -2323,7 +2331,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT // Expose to InputHandler // TODO: Revise when truecolor is introduced. - public matchColor(r1, g1, b1): any { + public matchColor(r1: number, g1: number, b1: number): any { const hash = (r1 << 16) | (g1 << 8) | b1; if (matchColorCache[hash] != null) { @@ -2375,41 +2383,25 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT * Helpers */ -function globalOn(el: any, type: string, handler: (event: Event) => any, capture?: boolean) { +function globalOn(el: any, type: string, handler: (event: Event) => any, capture?: boolean): void { if (!Array.isArray(el)) { el = [el]; } - el.forEach(function (element) { + el.forEach((element: HTMLElement) => { element.addEventListener(type, handler, capture || false); }); } // TODO: Remove once everything is typed const on = globalOn; -function off(el, type, handler, capture: boolean = false) { +function off(el: any, type: string, handler: (event: Event) => any, capture: boolean = false): void { el.removeEventListener(type, handler, capture); } -function inherits(child, parent) { - function f() { - this.constructor = child; - } - f.prototype = parent.prototype; - child.prototype = new f; -} - -function indexOf(obj, el) { - let i = obj.length; - while (i--) { - if (obj[i] === el) return i; - } - return -1; -} - -function isThirdLevelShift(term, ev) { +function isThirdLevelShift(ev: KeyboardEvent): boolean { const thirdLevelKey = - (term.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) || - (term.browser.isMSWindows && ev.altKey && ev.ctrlKey && !ev.metaKey); + (Browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) || + (Browser.isMSWindows && ev.altKey && ev.ctrlKey && !ev.metaKey); if (ev.type === 'keypress') { return thirdLevelKey; @@ -2422,36 +2414,18 @@ function isThirdLevelShift(term, ev) { const matchColorCache = {}; // http://stackoverflow.com/questions/1633828 -const matchColorDistance = function(r1, g1, b1, r2, g2, b2) { +const matchColorDistance = function(r1: number, g1: number, b1: number, r2: number, g2: number, b2: number): number { return Math.pow(30 * (r1 - r2), 2) + Math.pow(59 * (g1 - g2), 2) + Math.pow(11 * (b1 - b2), 2); }; -function each(obj, iter, con) { - if (obj.forEach) return obj.forEach(iter, con); - for (let i = 0; i < obj.length; i++) { - iter.call(con, obj[i], i, obj); - } -} - -function wasMondifierKeyOnlyEvent(ev) { +function wasMondifierKeyOnlyEvent(ev: KeyboardEvent): boolean { return ev.keyCode === 16 || // Shift ev.keyCode === 17 || // Ctrl ev.keyCode === 18; // Alt } -function keys(obj) { - if (Object.keys) return Object.keys(obj); - const keys = []; - for (let key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) { - keys.push(key); - } - } - return keys; -} - /** * Expose */ diff --git a/src/Viewport.ts b/src/Viewport.ts index bd667edb..4ad4ddec 100644 --- a/src/Viewport.ts +++ b/src/Viewport.ts @@ -92,7 +92,7 @@ export class Viewport implements IViewport { * terminal to scroll to it. * @param ev The scroll event. */ - private onScroll(ev: Event) { + private onScroll(ev: Event): void { const newRow = Math.round(this.viewportElement.scrollTop / this.currentRowHeight); const diff = newRow - this.terminal.buffer.ydisp; this.terminal.scrollDisp(diff, true); @@ -104,7 +104,7 @@ export class Viewport implements IViewport { * `Viewport`. * @param ev The mouse wheel event. */ - public onWheel(ev: WheelEvent) { + public onWheel(ev: WheelEvent): void { if (ev.deltaY === 0) { // Do nothing if it's not a vertical scroll event return; @@ -125,7 +125,7 @@ export class Viewport implements IViewport { * Handles the touchstart event, recording the touch occurred. * @param ev The touch event. */ - public onTouchStart(ev: TouchEvent) { + public onTouchStart(ev: TouchEvent): void { this.lastTouchY = ev.touches[0].pageY; }; @@ -133,7 +133,7 @@ export class Viewport implements IViewport { * Handles the touchmove event, scrolling the viewport if the position shifted. * @param ev The touch event. */ - public onTouchMove(ev: TouchEvent) { + public onTouchMove(ev: TouchEvent): void { let deltaY = this.lastTouchY - ev.touches[0].pageY; this.lastTouchY = ev.touches[0].pageY; if (deltaY === 0) { diff --git a/src/handlers/Clipboard.test.ts b/src/handlers/Clipboard.test.ts index a91ab87c..e5bc3581 100644 --- a/src/handlers/Clipboard.test.ts +++ b/src/handlers/Clipboard.test.ts @@ -2,8 +2,8 @@ import { assert } from 'chai'; import * as Terminal from '../xterm'; import * as Clipboard from './Clipboard'; -describe('evaluatePastedTextProcessing', function () { - it('should replace carriage return + line feed with line feed on windows', function () { +describe('evaluatePastedTextProcessing', () => { + it('should replace carriage return + line feed with line feed on windows', () => { const pastedText = 'foo\r\nbar\r\n'; const processedText = Clipboard.prepareTextForTerminal(pastedText, false); const windowsProcessedText = Clipboard.prepareTextForTerminal(pastedText, true); diff --git a/src/handlers/Clipboard.ts b/src/handlers/Clipboard.ts index aa1c1400..ac9a7b87 100644 --- a/src/handlers/Clipboard.ts +++ b/src/handlers/Clipboard.ts @@ -10,7 +10,7 @@ import { ITerminal, ISelectionManager } from '../Interfaces'; interface IWindow extends Window { clipboardData?: { getData(format: string): string; - setData(format: string, data: string); + setData(format: string, data: string): void; }; } @@ -31,7 +31,7 @@ export function prepareTextForTerminal(text: string, isMSWindows: boolean): stri * Binds copy functionality to the given terminal. * @param {ClipboardEvent} ev The original copy event to be handled */ -export function copyHandler(ev: ClipboardEvent, term: ITerminal, selectionManager: ISelectionManager) { +export function copyHandler(ev: ClipboardEvent, term: ITerminal, selectionManager: ISelectionManager): void { if (term.browser.isMSIE) { window.clipboardData.setData('Text', selectionManager.selectionText); } else { @@ -47,18 +47,17 @@ export function copyHandler(ev: ClipboardEvent, term: ITerminal, selectionManage * @param {ClipboardEvent} ev The original paste event to be handled * @param {Terminal} term The terminal on which to apply the handled paste event */ -export function pasteHandler(ev: ClipboardEvent, term: ITerminal) { +export function pasteHandler(ev: ClipboardEvent, term: ITerminal): void { ev.stopPropagation(); let text: string; - let dispatchPaste = function(text) { + let dispatchPaste = function(text: string): void { text = prepareTextForTerminal(text, term.browser.isMSWindows); term.handler(text); term.textarea.value = ''; term.emit('paste', text); - - return term.cancel(ev); + term.cancel(ev); }; if (term.browser.isMSIE) { @@ -79,7 +78,7 @@ export function pasteHandler(ev: ClipboardEvent, term: ITerminal) { * @param ev The original right click event to be handled. * @param textarea The terminal's textarea. */ -export function moveTextAreaUnderMouseCursor(ev: MouseEvent, textarea: HTMLTextAreaElement) { +export function moveTextAreaUnderMouseCursor(ev: MouseEvent, textarea: HTMLTextAreaElement): void { // Bring textarea at the cursor position textarea.style.position = 'fixed'; textarea.style.width = '20px'; @@ -91,7 +90,7 @@ export function moveTextAreaUnderMouseCursor(ev: MouseEvent, textarea: HTMLTextA textarea.focus(); // Reset the terminal textarea's styling - setTimeout(function () { + setTimeout(() => { textarea.style.position = null; textarea.style.width = null; textarea.style.height = null; @@ -107,7 +106,7 @@ export function moveTextAreaUnderMouseCursor(ev: MouseEvent, textarea: HTMLTextA * @param textarea The terminal's textarea. * @param selectionManager The terminal's selection manager. */ -export function rightClickHandler(ev: MouseEvent, textarea: HTMLTextAreaElement, selectionManager: ISelectionManager) { +export function rightClickHandler(ev: MouseEvent, textarea: HTMLTextAreaElement, selectionManager: ISelectionManager): void { moveTextAreaUnderMouseCursor(ev, textarea); // Get textarea ready to copy from the context menu diff --git a/src/utils/Generic.ts b/src/utils/Generic.ts index ce09c1be..98072326 100644 --- a/src/utils/Generic.ts +++ b/src/utils/Generic.ts @@ -9,6 +9,6 @@ * @param {Array} array The array to search for the given element. * @param {Object} el The element to look for into the array */ -export function contains(arr: any[], el: any) { +export function contains(arr: any[], el: any): boolean { return arr.indexOf(el) >= 0; }; diff --git a/tslint.json b/tslint.json index f98fd4c4..4d4d4aa5 100644 --- a/tslint.json +++ b/tslint.json @@ -9,6 +9,11 @@ true, "spaces" ], + "typedef": [ + true, + "call-signature", + "parameter" + ], "eofline": true, "no-eval": true, "no-internal-module": true,