From ec17fb9179b39a1af6a21b0880910d8307c33f3d Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 18 Jan 2018 12:48:19 -0800 Subject: [PATCH] Use Terminal type in attach, fit and fullscreen --- src/addons/attach/Intefaces.ts | 18 +++++ src/addons/attach/attach.test.ts | 2 +- src/addons/attach/attach.ts | 89 ++++++++++++------------ src/addons/fit/fit.test.ts | 2 +- src/addons/fit/fit.ts | 20 +++--- src/addons/fullscreen/fullscreen.test.ts | 2 +- src/addons/fullscreen/fullscreen.ts | 16 +++-- src/addons/search/Interfaces.ts | 2 +- src/addons/search/search.ts | 10 +-- 9 files changed, 94 insertions(+), 67 deletions(-) create mode 100644 src/addons/attach/Intefaces.ts diff --git a/src/addons/attach/Intefaces.ts b/src/addons/attach/Intefaces.ts new file mode 100644 index 000000000..ab809af9c --- /dev/null +++ b/src/addons/attach/Intefaces.ts @@ -0,0 +1,18 @@ +/** + * Copyright (c) 2018 The xterm.js authors. All rights reserved. + * @license MIT + * + * Implements the attach method, that attaches the terminal to a WebSocket stream. + */ + +import { Terminal } from 'xterm'; + +export interface IAttachAddonTerminal extends Terminal { + __socket?: WebSocket; + __attachSocketBuffer?: string; + + __getMessage?(ev: MessageEvent): void; + __flushBuffer?(): void; + __pushToBuffer?(data: string): void; + __sendData?(data: string): void; +} diff --git a/src/addons/attach/attach.test.ts b/src/addons/attach/attach.test.ts index a13885bbc..018cfb31c 100644 --- a/src/addons/attach/attach.test.ts +++ b/src/addons/attach/attach.test.ts @@ -12,7 +12,7 @@ class MockTerminal {} describe('attach addon', () => { describe('apply', () => { it('should do register the `attach` and `detach` methods', () => { - attach.apply(MockTerminal); + attach.apply(MockTerminal); assert.equal(typeof (MockTerminal).prototype.attach, 'function'); assert.equal(typeof (MockTerminal).prototype.detach, 'function'); }); diff --git a/src/addons/attach/attach.ts b/src/addons/attach/attach.ts index ba9386958..d963a658f 100644 --- a/src/addons/attach/attach.ts +++ b/src/addons/attach/attach.ts @@ -5,38 +5,42 @@ * Implements the attach method, that attaches the terminal to a WebSocket stream. */ +/// + +import { Terminal } from 'xterm'; +import { IAttachAddonTerminal } from './Intefaces'; + /** * Attaches the given terminal to the given socket. * - * @param {Terminal} term - The terminal to be attached to the given socket. - * @param {WebSocket} socket - The socket to attach the current terminal. - * @param {boolean} bidirectional - Whether the terminal should send data - * to the socket as well. - * @param {boolean} buffered - Whether the rendering of incoming data - * should happen instantly or at a maximum - * frequency of 1 rendering per 10ms. + * @param term The terminal to be attached to the given socket. + * @param socket The socket to attach the current terminal. + * @param bidirectional Whether the terminal should send data to the socket as well. + * @param buffered Whether the rendering of incoming data should happen instantly or at a maximum + * frequency of 1 rendering per 10ms. */ -export function attach(term: any, socket: WebSocket, bidirectional: boolean, buffered: boolean): void { +export function attach(term: Terminal, socket: WebSocket, bidirectional: boolean, buffered: boolean): void { + const addonTerminal = term; bidirectional = (typeof bidirectional === 'undefined') ? true : bidirectional; - term.socket = socket; + addonTerminal.__socket = socket; - term._flushBuffer = () => { - term.write(term._attachSocketBuffer); - term._attachSocketBuffer = null; + addonTerminal.__flushBuffer = () => { + addonTerminal.write(addonTerminal.__attachSocketBuffer); + addonTerminal.__attachSocketBuffer = null; }; - term._pushToBuffer = (data: string) => { - if (term._attachSocketBuffer) { - term._attachSocketBuffer += data; + addonTerminal.__pushToBuffer = (data: string) => { + if (addonTerminal.__attachSocketBuffer) { + addonTerminal.__attachSocketBuffer += data; } else { - term._attachSocketBuffer = data; - setTimeout(term._flushBuffer, 10); + addonTerminal.__attachSocketBuffer = data; + setTimeout(addonTerminal.__flushBuffer, 10); } }; let myTextDecoder; - term._getMessage = function(ev: MessageEvent): void { + addonTerminal.__getMessage = function(ev: MessageEvent): void { let str; if (typeof ev.data === 'object') { if (ev.data instanceof ArrayBuffer) { @@ -51,71 +55,68 @@ export function attach(term: any, socket: WebSocket, bidirectional: boolean, buf } if (buffered) { - term._pushToBuffer(str || ev.data); + addonTerminal.__pushToBuffer(str || ev.data); } else { - term.write(str || ev.data); + addonTerminal.write(str || ev.data); } }; - term._sendData = (data: string) => { + addonTerminal.__sendData = (data: string) => { if (socket.readyState !== 1) { return; } socket.send(data); }; - socket.addEventListener('message', term._getMessage); + socket.addEventListener('message', addonTerminal.__getMessage); if (bidirectional) { - term.on('data', term._sendData); + addonTerminal.on('data', addonTerminal.__sendData); } - socket.addEventListener('close', term.detach.bind(term, socket)); - socket.addEventListener('error', term.detach.bind(term, socket)); + socket.addEventListener('close', () => detach(addonTerminal, socket)); + socket.addEventListener('error', () => detach(addonTerminal, socket)); } /** * Detaches the given terminal from the given socket * - * @param {Terminal} term - The terminal to be detached from the given socket. - * @param {WebSocket} socket - The socket from which to detach the current - * terminal. + * @param term The terminal to be detached from the given socket. + * @param socket The socket from which to detach the current terminal. */ -export function detach(term: any, socket: WebSocket): void { - term.off('data', term._sendData); +export function detach(term: Terminal, socket: WebSocket): void { + const addonTerminal = term; + addonTerminal.off('data', addonTerminal.__sendData); - socket = (typeof socket === 'undefined') ? term.socket : socket; + socket = (typeof socket === 'undefined') ? addonTerminal.__socket : socket; if (socket) { - socket.removeEventListener('message', term._getMessage); + socket.removeEventListener('message', addonTerminal.__getMessage); } - delete term.socket; + delete addonTerminal.__socket; } -export function apply(terminalConstructor: any): void { +export function apply(terminalConstructor: typeof Terminal): void { /** * Attaches the current terminal to the given socket * - * @param {WebSocket} socket - The socket to attach the current terminal. - * @param {boolean} bidirectional - Whether the terminal should send data - * to the socket as well. - * @param {boolean} buffered - Whether the rendering of incoming data - * should happen instantly or at a maximum - * frequency of 1 rendering per 10ms. + * @param socket The socket to attach the current terminal. + * @param bidirectional Whether the terminal should send data to the socket as well. + * @param buffered Whether the rendering of incoming data should happen instantly or at a maximum + * frequency of 1 rendering per 10ms. */ - terminalConstructor.prototype.attach = function (socket: WebSocket, bidirectional: boolean, buffered: boolean): void { + (terminalConstructor.prototype).attach = function (socket: WebSocket, bidirectional: boolean, buffered: boolean): void { attach(this, socket, bidirectional, buffered); }; /** * Detaches the current terminal from the given socket. * - * @param {WebSocket} socket - The socket from which to detach the current - * terminal. + * @param socket The socket from which to detach the current terminal. */ - terminalConstructor.prototype.detach = function (socket: WebSocket): void { + (terminalConstructor.prototype).detach = function (socket: WebSocket): void { detach(this, socket); }; } diff --git a/src/addons/fit/fit.test.ts b/src/addons/fit/fit.test.ts index 0dc179630..9a6d89fd0 100644 --- a/src/addons/fit/fit.test.ts +++ b/src/addons/fit/fit.test.ts @@ -12,7 +12,7 @@ class MockTerminal {} describe('fit addon', () => { describe('apply', () => { it('should do register the `proposeGeometry` and `fit` methods', () => { - fit.apply(MockTerminal); + fit.apply(MockTerminal); assert.equal(typeof (MockTerminal).prototype.proposeGeometry, 'function'); assert.equal(typeof (MockTerminal).prototype.fit, 'function'); }); diff --git a/src/addons/fit/fit.ts b/src/addons/fit/fit.ts index 631110941..75e854d97 100644 --- a/src/addons/fit/fit.ts +++ b/src/addons/fit/fit.ts @@ -13,12 +13,16 @@ * row and truncate its width with the current number of columns). */ +/// + +import { Terminal } from 'xterm'; + export interface IGeometry { rows: number; cols: number; } -export function proposeGeometry(term: any): IGeometry { +export function proposeGeometry(term: Terminal): IGeometry { if (!term.element.parentElement) { return null; } @@ -31,30 +35,30 @@ export function proposeGeometry(term: any): IGeometry { const availableHeight = parentElementHeight - elementPaddingVer; const availableWidth = parentElementWidth - elementPaddingHor; const geometry = { - cols: Math.floor(availableWidth / term.renderer.dimensions.actualCellWidth), - rows: Math.floor(availableHeight / term.renderer.dimensions.actualCellHeight) + cols: Math.floor(availableWidth / (term).renderer.dimensions.actualCellWidth), + rows: Math.floor(availableHeight / (term).renderer.dimensions.actualCellHeight) }; return geometry; } -export function fit(term: any): void { +export function fit(term: Terminal): void { const geometry = proposeGeometry(term); if (geometry) { // Force a full render if (term.rows !== geometry.rows || term.cols !== geometry.cols) { - term.renderer.clear(); + (term).renderer.clear(); term.resize(geometry.cols, geometry.rows); } } } -export function apply(terminalConstructor: any): void { - terminalConstructor.prototype.proposeGeometry = function (): IGeometry { +export function apply(terminalConstructor: typeof Terminal): void { + (terminalConstructor.prototype).proposeGeometry = function (): IGeometry { return proposeGeometry(this); }; - terminalConstructor.prototype.fit = function (): void { + (terminalConstructor.prototype).fit = function (): void { fit(this); }; } diff --git a/src/addons/fullscreen/fullscreen.test.ts b/src/addons/fullscreen/fullscreen.test.ts index 9326ac4e7..bb98bd30d 100644 --- a/src/addons/fullscreen/fullscreen.test.ts +++ b/src/addons/fullscreen/fullscreen.test.ts @@ -12,7 +12,7 @@ class MockTerminal {} describe('fullscreen addon', () => { describe('apply', () => { it('should do register the `toggleFullscreen` method', () => { - fullscreen.apply(MockTerminal); + fullscreen.apply(MockTerminal); assert.equal(typeof (MockTerminal).prototype.toggleFullScreen, 'function'); }); }); diff --git a/src/addons/fullscreen/fullscreen.ts b/src/addons/fullscreen/fullscreen.ts index 2e5b72e1f..474406677 100644 --- a/src/addons/fullscreen/fullscreen.ts +++ b/src/addons/fullscreen/fullscreen.ts @@ -3,13 +3,17 @@ * @license MIT */ +/// + +import { Terminal } from 'xterm'; + /** * Toggle the given terminal's fullscreen mode. - * @param {Terminal} term - The terminal to toggle full screen mode - * @param {boolean} fullscreen - Toggle fullscreen on (true) or off (false) + * @param term The terminal to toggle full screen mode + * @param fullscreen Toggle fullscreen on (true) or off (false) */ -export function toggleFullScreen(term: any, fullscreen: boolean): void { - let fn; +export function toggleFullScreen(term: Terminal, fullscreen: boolean): void { + let fn: string; if (typeof fullscreen === 'undefined') { fn = (term.element.classList.contains('fullscreen')) ? 'remove' : 'add'; @@ -22,8 +26,8 @@ export function toggleFullScreen(term: any, fullscreen: boolean): void { term.element.classList[fn]('fullscreen'); } -export function apply(terminalConstructor: any): void { - terminalConstructor.prototype.toggleFullScreen = function (fullscreen: boolean): void { +export function apply(terminalConstructor: typeof Terminal): void { + (terminalConstructor.prototype).toggleFullScreen = function (fullscreen: boolean): void { toggleFullScreen(this, fullscreen); }; } diff --git a/src/addons/search/Interfaces.ts b/src/addons/search/Interfaces.ts index 7a7a87cc7..6faa03e2e 100644 --- a/src/addons/search/Interfaces.ts +++ b/src/addons/search/Interfaces.ts @@ -6,7 +6,7 @@ import { Terminal } from 'xterm'; export interface ISearchAddonTerminal extends Terminal { - __searchHelper: ISearchHelper; + __searchHelper?: ISearchHelper; // TODO: Reuse ITerminal from core buffer: any; diff --git a/src/addons/search/search.ts b/src/addons/search/search.ts index 2f5db9224..5c0b2b96d 100644 --- a/src/addons/search/search.ts +++ b/src/addons/search/search.ts @@ -16,7 +16,7 @@ import { ISearchAddonTerminal } from './Interfaces'; * @return Whether a result was found. */ export function findNext(terminal: Terminal, term: string): boolean { - const addonTerminal = (terminal); + const addonTerminal = terminal; if (!addonTerminal.__searchHelper) { addonTerminal.__searchHelper = new SearchHelper(addonTerminal); } @@ -30,19 +30,19 @@ export function findNext(terminal: Terminal, term: string): boolean { * @return Whether a result was found. */ export function findPrevious(terminal: Terminal, term: string): boolean { - const addonTerminal = (terminal); + const addonTerminal = terminal; if (!addonTerminal.__searchHelper) { addonTerminal.__searchHelper = new SearchHelper(addonTerminal); } return addonTerminal.__searchHelper.findPrevious(term); } -export function apply(terminalConstructor: any): void { - terminalConstructor.prototype.findNext = function(term: string): boolean { +export function apply(terminalConstructor: typeof Terminal): void { + (terminalConstructor.prototype).findNext = function(term: string): boolean { return findNext(this, term); }; - terminalConstructor.prototype.findPrevious = function(term: string): boolean { + (terminalConstructor.prototype).findPrevious = function(term: string): boolean { return findPrevious(this, term); }; }