diff --git a/src/Buffer.test.ts b/src/Buffer.test.ts index 210d2971..0607a573 100644 --- a/src/Buffer.test.ts +++ b/src/Buffer.test.ts @@ -4,7 +4,7 @@ */ import { assert } from 'chai'; -import { ITerminal } from './Interfaces'; +import { ITerminal } from './Types'; import { Buffer } from './Buffer'; import { CircularList } from './utils/CircularList'; import { MockTerminal } from './utils/TestUtils.test'; diff --git a/src/Buffer.ts b/src/Buffer.ts index 39b0726c..462cde56 100644 --- a/src/Buffer.ts +++ b/src/Buffer.ts @@ -3,9 +3,8 @@ * @license MIT */ -import { ITerminal, IBuffer } from './Interfaces'; import { CircularList } from './utils/CircularList'; -import { LineData, CharData } from './Types'; +import { LineData, CharData, ITerminal, IBuffer } from './Types'; export const CHAR_DATA_ATTR_INDEX = 0; export const CHAR_DATA_CHAR_INDEX = 1; diff --git a/src/BufferSet.test.ts b/src/BufferSet.test.ts index b9c1824d..009ebf2e 100644 --- a/src/BufferSet.test.ts +++ b/src/BufferSet.test.ts @@ -4,7 +4,7 @@ */ import { assert } from 'chai'; -import { ITerminal } from './Interfaces'; +import { ITerminal } from './Types'; import { BufferSet } from './BufferSet'; import { Buffer } from './Buffer'; import { MockTerminal } from './utils/TestUtils.test'; diff --git a/src/BufferSet.ts b/src/BufferSet.ts index da8c75f2..553b2056 100644 --- a/src/BufferSet.ts +++ b/src/BufferSet.ts @@ -3,7 +3,7 @@ * @license MIT */ -import { ITerminal, IBufferSet } from './Interfaces'; +import { ITerminal, IBufferSet } from './Types'; import { Buffer } from './Buffer'; import { EventEmitter } from './EventEmitter'; diff --git a/src/Charsets.ts b/src/Charsets.ts index e62e3f9c..fe0112ec 100644 --- a/src/Charsets.ts +++ b/src/Charsets.ts @@ -3,7 +3,7 @@ * @license MIT */ -import { ICharset } from './Interfaces'; +import { ICharset } from './Types'; /** * The character sets supported by the terminal. These enable several languages diff --git a/src/CompositionHelper.ts b/src/CompositionHelper.ts index e588be78..2aa0449f 100644 --- a/src/CompositionHelper.ts +++ b/src/CompositionHelper.ts @@ -3,7 +3,7 @@ * @license MIT */ -import { ITerminal } from './Interfaces'; +import { ITerminal } from './Types'; interface IPosition { start: number; diff --git a/src/EventEmitter.test.ts b/src/EventEmitter.test.ts index c1f0a0ab..f2d31cf6 100644 --- a/src/EventEmitter.test.ts +++ b/src/EventEmitter.test.ts @@ -13,18 +13,6 @@ describe('EventEmitter', () => { 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; diff --git a/src/EventEmitter.ts b/src/EventEmitter.ts index 414eac89..440eab2b 100644 --- a/src/EventEmitter.ts +++ b/src/EventEmitter.ts @@ -3,10 +3,10 @@ * @license MIT */ -import { IEventEmitter, IListenerType } from './Interfaces'; +import { IEventEmitter } from 'xterm'; export class EventEmitter implements IEventEmitter { - private _events: {[type: string]: IListenerType[]}; + private _events: {[type: string]: ((...args: any[]) => void)[]}; constructor() { // Restore the previous events if available, this will happen if the @@ -14,12 +14,12 @@ export class EventEmitter implements IEventEmitter { this._events = this._events || {}; } - public on(type: string, listener: IListenerType): void { + public on(type: string, listener: ((...args: any[]) => void)): void { this._events[type] = this._events[type] || []; this._events[type].push(listener); } - public off(type: string, listener: IListenerType): void { + public off(type: string, listener: ((...args: any[]) => void)): void { if (!this._events[type]) { return; } @@ -28,7 +28,7 @@ export class EventEmitter implements IEventEmitter { let i = obj.length; while (i--) { - if (obj[i] === listener || obj[i].listener === listener) { + if (obj[i] === listener) { obj.splice(i, 1); return; } @@ -41,16 +41,6 @@ export class EventEmitter implements IEventEmitter { } } - public once(type: string, listener: IListenerType): void { - function on(): void { - let args = Array.prototype.slice.call(arguments); - this.off(type, on); - listener.apply(this, args); - } - (on).listener = listener; - this.on(type, on); - } - public emit(type: string, ...args: any[]): void { if (!this._events[type]) { return; @@ -61,7 +51,7 @@ export class EventEmitter implements IEventEmitter { } } - public listeners(type: string): IListenerType[] { + public listeners(type: string): ((...args: any[]) => void)[] { return this._events[type] || []; } diff --git a/src/InputHandler.ts b/src/InputHandler.ts index 96e34cc0..f71117f8 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -4,10 +4,9 @@ * @license MIT */ -import { IInputHandler, ITerminal, IInputHandlingTerminal } from './Interfaces'; +import { CharData, IInputHandler, IInputHandlingTerminal, ITerminal } from './Types'; import { C0 } from './EscapeSequences'; import { DEFAULT_CHARSET } from './Charsets'; -import { CharData } from './Types'; import { CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX } from './Buffer'; import { FLAGS } from './renderer/Types'; import { wcwidth } from './CharWidth'; diff --git a/src/Interfaces.ts b/src/Interfaces.ts deleted file mode 100644 index 34ab143b..00000000 --- a/src/Interfaces.ts +++ /dev/null @@ -1,378 +0,0 @@ -/** - * Copyright (c) 2017 The xterm.js authors. All rights reserved. - * @license MIT - */ - -import { ICharset, ILinkMatcherOptions } from './Interfaces'; -import { LinkMatcherHandler, LinkMatcherValidationCallback, LineData } from './Types'; -import { IColorSet, IRenderer } from './renderer/Interfaces'; -import { IMouseZoneManager } from './input/Interfaces'; -import { FontWeight } from './shared/Types'; - -export interface IBrowser { - isNode: boolean; - userAgent: string; - platform: string; - isFirefox: boolean; - isMSIE: boolean; - isMac: boolean; - isIpad: boolean; - isIphone: boolean; - isMSWindows: boolean; -} - -export interface IBufferAccessor { - buffer: IBuffer; -} - -export interface IElementAccessor { - element: HTMLElement; -} - -export interface ILinkifierAccessor { - linkifier: ILinkifier; -} - -export interface ITerminal extends ILinkifierAccessor, IBufferAccessor, IElementAccessor, IEventEmitter { - selectionManager: ISelectionManager; - charMeasure: ICharMeasure; - textarea: HTMLTextAreaElement; - renderer: IRenderer; - rows: number; - cols: number; - browser: IBrowser; - writeBuffer: string[]; - cursorHidden: boolean; - cursorState: number; - defAttr: number; - options: ITerminalOptions; - buffers: IBufferSet; - isFocused: boolean; - mouseHelper: IMouseHelper; - bracketedPasteMode: boolean; - - /** - * Emit the 'data' event and populate the given data. - * @param data The data to populate in the event. - */ - handler(data: string): void; - scrollLines(disp: number, suppressScrollEvent?: boolean): void; - cancel(ev: Event, force?: boolean): boolean | void; - log(text: string): void; - reset(): void; - showCursor(): void; - blankLine(cur?: boolean, isWrapped?: boolean, cols?: number): LineData; - refresh(start: number, end: number): void; -} - -/** - * This interface encapsulates everything needed from the Terminal by the - * InputHandler. This cleanly separates the large amount of methods needed by - * InputHandler cleanly from the ITerminal interface. - */ -export interface IInputHandlingTerminal extends IEventEmitter { - element: HTMLElement; - options: ITerminalOptions; - cols: number; - rows: number; - charset: ICharset; - gcharset: number; - glevel: number; - charsets: ICharset[]; - applicationKeypad: boolean; - applicationCursor: boolean; - originMode: boolean; - insertMode: boolean; - wraparoundMode: boolean; - bracketedPasteMode: boolean; - defAttr: number; - curAttr: number; - prefix: string; - savedCols: number; - x10Mouse: boolean; - vt200Mouse: boolean; - normalMouse: boolean; - mouseEvents: boolean; - sendFocus: boolean; - utfMouse: boolean; - sgrMouse: boolean; - urxvtMouse: boolean; - cursorHidden: boolean; - - buffers: IBufferSet; - buffer: IBuffer; - viewport: IViewport; - selectionManager: ISelectionManager; - - bell(): void; - focus(): void; - convertEol: boolean; - updateRange(y: number): void; - scroll(isWrapped?: boolean): void; - setgLevel(g: number): void; - eraseAttr(): number; - eraseRight(x: number, y: number): void; - eraseLine(y: number): void; - eraseLeft(x: number, y: number): void; - blankLine(cur?: boolean, isWrapped?: boolean): LineData; - is(term: string): boolean; - send(data: string): void; - setgCharset(g: number, charset: ICharset): void; - resize(x: number, y: number): void; - log(text: string, data?: any): void; - reset(): void; - showCursor(): void; - refresh(start: number, end: number): void; - matchColor(r1: number, g1: number, b1: number): number; - error(text: string, data?: any): void; - setOption(key: string, value: any): void; -} - -export interface ITerminalOptions { - bellSound?: string; - bellStyle?: string; - cancelEvents?: boolean; - cols?: number; - convertEol?: boolean; - cursorBlink?: boolean; - cursorStyle?: string; - debug?: boolean; - disableStdin?: boolean; - enableBold?: boolean; - fontSize?: number; - fontFamily?: string; - fontWeight?: FontWeight; - fontWeightBold?: FontWeight; - handler?: (data: string) => void; - letterSpacing?: number; - lineHeight?: number; - macOptionIsMeta?: boolean; - rows?: number; - screenKeys?: boolean; - scrollback?: number; - tabStopWidth?: number; - termName?: string; - theme?: ITheme; - useFlowControl?: boolean; -} - -export interface IBuffer { - lines: ICircularList; - ydisp: number; - ybase: number; - y: number; - x: number; - tabs: any; - scrollBottom: number; - scrollTop: number; - savedY: number; - savedX: number; - isCursorInViewport: boolean; - translateBufferLineToString(lineIndex: number, trimRight: boolean, startCol?: number, endCol?: number): string; - nextStop(x?: number): number; - prevStop(x?: number): number; -} - -export interface IBufferSet extends IEventEmitter { - alt: IBuffer; - normal: IBuffer; - active: IBuffer; - - activateNormalBuffer(): void; - activateAltBuffer(): void; -} - -export interface IMouseHelper { - getCoords(event: {pageX: number, pageY: number}, element: HTMLElement, charMeasure: ICharMeasure, lineHeight: number, colCount: number, rowCount: number, isSelection?: boolean): [number, number]; - getRawByteCoords(event: MouseEvent, element: HTMLElement, charMeasure: ICharMeasure, lineHeight: number, colCount: number, rowCount: number): { x: number, y: number }; -} - -export interface IViewport { - syncScrollArea(): void; - onWheel(ev: WheelEvent): void; - onTouchStart(ev: TouchEvent): void; - onTouchMove(ev: TouchEvent): void; - onThemeChanged(colors: IColorSet): void; -} - -export interface ISelectionManager { - selectionText: string; - selectionStart: [number, number]; - selectionEnd: [number, number]; - - disable(): void; - enable(): void; - setSelection(row: number, col: number, length: number): void; -} - -export interface ICompositionHelper { - compositionstart(): void; - compositionupdate(ev: CompositionEvent): void; - compositionend(): void; - updateCompositionElements(dontRecurse?: boolean): void; - keydown(ev: KeyboardEvent): boolean; -} - -export interface ICharMeasure { - width: number; - height: number; - measure(options: ITerminalOptions): void; -} - -export interface ILinkifier extends IEventEmitter { - attachToDom(mouseZoneManager: IMouseZoneManager): void; - linkifyRows(start: number, end: number): void; - setHypertextLinkHandler(handler: LinkMatcherHandler): void; - setHypertextValidationCallback(callback: LinkMatcherValidationCallback): void; - registerLinkMatcher(regex: RegExp, handler: LinkMatcherHandler, options?: ILinkMatcherOptions): number; - deregisterLinkMatcher(matcherId: number): boolean; -} - -export interface ICircularList extends IEventEmitter { - length: number; - maxLength: number; - forEach: (callbackfn: (value: T, index: number) => void) => void; - - 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; -} - -export interface IEventEmitter { - on(type: string, listener: IListenerType): void; - off(type: string, listener: IListenerType): void; - emit(type: string, data?: any): void; -} - -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). - */ - matchIndex?: number; - /** - * A callback that validates an individual link, returning true if valid and - * false if invalid. - */ - validationCallback?: LinkMatcherValidationCallback; - /** - * A callback that fires when the mouse hovers over a link. - */ - tooltipCallback?: LinkMatcherHandler; - /** - * A callback that fires when the mouse leaves a link that was hovered. - */ - leaveCallback?: () => void; - /** - * The priority of the link matcher, this defines the order in which the link - * matcher is evaluated relative to others, from highest to lowest. The - * default value is 0. - */ - priority?: number; -} - -/** - * Handles actions generated by the parser. - */ -export interface IInputHandler { - addChar(char: string, code: number): void; - - /** C0 BEL */ bell(): void; - /** C0 LF */ lineFeed(): void; - /** C0 CR */ carriageReturn(): void; - /** C0 BS */ backspace(): void; - /** C0 HT */ tab(): void; - /** C0 SO */ shiftOut(): void; - /** C0 SI */ shiftIn(): void; - - /** CSI @ */ insertChars(params?: number[]): void; - /** CSI A */ cursorUp(params?: number[]): void; - /** CSI B */ cursorDown(params?: number[]): void; - /** CSI C */ cursorForward(params?: number[]): void; - /** CSI D */ cursorBackward(params?: number[]): void; - /** CSI E */ cursorNextLine(params?: number[]): void; - /** CSI F */ cursorPrecedingLine(params?: number[]): void; - /** CSI G */ cursorCharAbsolute(params?: number[]): void; - /** CSI H */ cursorPosition(params?: number[]): void; - /** CSI I */ cursorForwardTab(params?: number[]): void; - /** CSI J */ eraseInDisplay(params?: number[]): void; - /** CSI K */ eraseInLine(params?: number[]): void; - /** CSI L */ insertLines(params?: number[]): void; - /** CSI M */ deleteLines(params?: number[]): void; - /** CSI P */ deleteChars(params?: number[]): void; - /** CSI S */ scrollUp(params?: number[]): void; - /** CSI T */ scrollDown(params?: number[]): void; - /** CSI X */ eraseChars(params?: number[]): void; - /** CSI Z */ cursorBackwardTab(params?: number[]): void; - /** CSI ` */ charPosAbsolute(params?: number[]): void; - /** CSI a */ HPositionRelative(params?: number[]): void; - /** CSI b */ repeatPrecedingCharacter(params?: number[]): void; - /** CSI c */ sendDeviceAttributes(params?: number[]): void; - /** CSI d */ linePosAbsolute(params?: number[]): void; - /** CSI e */ VPositionRelative(params?: number[]): void; - /** CSI f */ HVPosition(params?: number[]): void; - /** CSI g */ tabClear(params?: number[]): void; - /** CSI h */ setMode(params?: number[]): void; - /** CSI l */ resetMode(params?: number[]): void; - /** CSI m */ charAttributes(params?: number[]): void; - /** CSI n */ deviceStatus(params?: number[]): void; - /** CSI p */ softReset(params?: number[]): void; - /** CSI q */ setCursorStyle(params?: number[]): void; - /** CSI r */ setScrollRegion(params?: number[]): void; - /** CSI s */ saveCursor(params?: number[]): void; - /** CSI u */ restoreCursor(params?: number[]): void; -} - -export interface ITheme { - foreground?: string; - background?: string; - cursor?: string; - cursorAccent?: string; - selection?: string; - black?: string; - red?: string; - green?: string; - yellow?: string; - blue?: string; - magenta?: string; - cyan?: string; - white?: string; - brightBlack?: string; - brightRed?: string; - brightGreen?: string; - brightYellow?: string; - brightBlue?: string; - brightMagenta?: string; - brightCyan?: string; - brightWhite?: string; -} - -export interface ILinkMatcher { - id: number; - regex: RegExp; - handler: LinkMatcherHandler; - hoverTooltipCallback?: LinkMatcherHandler; - hoverLeaveCallback?: () => void; - matchIndex?: number; - validationCallback?: LinkMatcherValidationCallback; - priority?: number; -} - -export interface ICharset { - [key: string]: string; -} - -export interface ILinkHoverEvent { - x: number; - y: number; - length: number; -} diff --git a/src/Linkifier.test.ts b/src/Linkifier.test.ts index 8b66dcaa..14b1ac0f 100644 --- a/src/Linkifier.test.ts +++ b/src/Linkifier.test.ts @@ -4,10 +4,9 @@ */ import { assert } from 'chai'; -import { ITerminal, ILinkifier, ILinkMatcher, IBuffer, IBufferAccessor, IElementAccessor } from './Interfaces'; +import { IMouseZoneManager, IMouseZone } from './input/Types'; +import { ILinkMatcher, LineData, ITerminal, ILinkifier, IBuffer, IBufferAccessor, IElementAccessor } from './Types'; import { Linkifier } from './Linkifier'; -import { LineData } from './Types'; -import { IMouseZoneManager, IMouseZone } from './input/Interfaces'; import { MockBuffer } from './utils/TestUtils.test'; import { CircularList } from './utils/CircularList'; diff --git a/src/Linkifier.ts b/src/Linkifier.ts index b5f30b56..da901a6e 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -3,9 +3,8 @@ * @license MIT */ -import { ILinkHoverEvent, ILinkMatcher, ILinkMatcherOptions, ITerminal, IBufferAccessor, ILinkifier, IElementAccessor } from './Interfaces'; -import { LinkMatcherHandler, LinkMatcherValidationCallback, LineData, LinkHoverEventTypes } from './Types'; -import { IMouseZoneManager } from './input/Interfaces'; +import { IMouseZoneManager } from './input/Types'; +import { ILinkHoverEvent, ILinkMatcher, LinkMatcherHandler, LinkMatcherValidationCallback, LineData, LinkHoverEventTypes, ILinkMatcherOptions, ITerminal, IBufferAccessor, ILinkifier, IElementAccessor } from './Types'; import { MouseZone } from './input/MouseZoneManager'; import { EventEmitter } from './EventEmitter'; diff --git a/src/Parser.ts b/src/Parser.ts index 6f4b0932..3ac03e4f 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -5,7 +5,7 @@ */ import { C0 } from './EscapeSequences'; -import { IInputHandler } from './Interfaces'; +import { IInputHandler } from './Types'; import { CHARSETS, DEFAULT_CHARSET } from './Charsets'; const normalStateHandler: {[key: string]: (parser: Parser, handler: IInputHandler) => void} = {}; diff --git a/src/SelectionManager.test.ts b/src/SelectionManager.test.ts index 97afcf2b..5c53565f 100644 --- a/src/SelectionManager.test.ts +++ b/src/SelectionManager.test.ts @@ -5,14 +5,13 @@ import jsdom = require('jsdom'); import { assert } from 'chai'; -import { ITerminal, ICircularList, IBuffer } from './Interfaces'; import { CharMeasure } from './utils/CharMeasure'; import { CircularList } from './utils/CircularList'; import { SelectionManager } from './SelectionManager'; import { SelectionModel } from './SelectionModel'; import { BufferSet } from './BufferSet'; +import { LineData, CharData, ITerminal, ICircularList, IBuffer } from './Types'; import { MockTerminal } from './utils/TestUtils.test'; -import { LineData, CharData } from './Types'; class TestMockTerminal extends MockTerminal { emit(event: string, data: any): void {} diff --git a/src/SelectionManager.ts b/src/SelectionManager.ts index 934f6c6b..10612c5c 100644 --- a/src/SelectionManager.ts +++ b/src/SelectionManager.ts @@ -3,14 +3,13 @@ * @license MIT */ +import { ITerminal, ICircularList, ISelectionManager, IBuffer, LineData, CharData } from './Types'; import { MouseHelper } from './utils/MouseHelper'; import * as Browser from './shared/utils/Browser'; import { CharMeasure } from './utils/CharMeasure'; import { CircularList } from './utils/CircularList'; import { EventEmitter } from './EventEmitter'; -import { ITerminal, ICircularList, ISelectionManager, IBuffer, IListenerType } from './Interfaces'; import { SelectionModel } from './SelectionModel'; -import { LineData, CharData } from './Types'; import { CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CHAR_INDEX } from './Buffer'; /** @@ -95,7 +94,7 @@ export class SelectionManager extends EventEmitter implements ISelectionManager private _mouseMoveListener: EventListener; private _mouseUpListener: EventListener; - private _trimListener: IListenerType; + private _trimListener: (...args: any[]) => void; constructor( private _terminal: ITerminal, diff --git a/src/SelectionModel.test.ts b/src/SelectionModel.test.ts index eda94718..ed483dbe 100644 --- a/src/SelectionModel.test.ts +++ b/src/SelectionModel.test.ts @@ -4,7 +4,7 @@ */ import { assert } from 'chai'; -import { ITerminal } from './Interfaces'; +import { ITerminal } from './Types'; import { SelectionModel } from './SelectionModel'; import { BufferSet } from './BufferSet'; import { MockTerminal } from './utils/TestUtils.test'; diff --git a/src/SelectionModel.ts b/src/SelectionModel.ts index 5982b1e9..a9a3c89e 100644 --- a/src/SelectionModel.ts +++ b/src/SelectionModel.ts @@ -3,7 +3,7 @@ * @license MIT */ -import { ITerminal } from './Interfaces'; +import { ITerminal } from './Types'; /** * Represents a selection within the buffer. This model only cares about column diff --git a/src/Terminal.ts b/src/Terminal.ts index 3746cb58..5536cf03 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -21,6 +21,9 @@ * http://linux.die.net/man/7/urxvt */ +import { ICharset, IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminalOptions, ITerminal, IBrowser, ILinkifier, ILinkMatcherOptions, CustomKeyEventHandler, LinkMatcherHandler, LinkMatcherValidationCallback, CharData, LineData } from './Types'; +import { IMouseZoneManager } from './input/Types'; +import { IRenderer } from './renderer/Types'; import { BufferSet } from './BufferSet'; import { Buffer, MAX_BUFFER_SIZE } from './Buffer'; import { CompositionHelper } from './CompositionHelper'; @@ -38,13 +41,10 @@ import { CharMeasure } from './utils/CharMeasure'; import * as Browser from './shared/utils/Browser'; import { MouseHelper } from './utils/MouseHelper'; import { CHARSETS } from './Charsets'; -import { CustomKeyEventHandler, LinkMatcherHandler, LinkMatcherValidationCallback, CharData, LineData } from './Types'; -import { ITerminal, IBrowser, ICharset, ITerminalOptions, IInputHandlingTerminal, ILinkMatcherOptions, IViewport, ICompositionHelper, ITheme, ILinkifier } from './Interfaces'; import { BELL_SOUND } from './utils/Sounds'; import { DEFAULT_ANSI_COLORS } from './renderer/ColorManager'; -import { IMouseZoneManager } from './input/Interfaces'; import { MouseZoneManager } from './input/MouseZoneManager'; -import { IRenderer } from './renderer/Interfaces'; +import { ITheme } from 'xterm'; // Let it work inside Node.js for automated testing purposes. const document = (typeof window !== 'undefined') ? window.document : null; @@ -2137,13 +2137,15 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT } private visualBell(): boolean { - return this.options.bellStyle === 'visual' || - this.options.bellStyle === 'both'; + return false; + // return this.options.bellStyle === 'visual' || + // this.options.bellStyle === 'both'; } private soundBell(): boolean { - return this.options.bellStyle === 'sound' || - this.options.bellStyle === 'both'; + return this.options.bellStyle === 'sound'; + // return this.options.bellStyle === 'sound' || + // this.options.bellStyle === 'both'; } private syncBellSound(): void { diff --git a/src/Types.ts b/src/Types.ts index 3263282e..f3e9bb94 100644 --- a/src/Types.ts +++ b/src/Types.ts @@ -3,16 +3,332 @@ * @license MIT */ -export type LinkMatcherHandler = (event: MouseEvent, uri: string) => boolean | void; -export type LinkMatcherValidationCallback = (uri: string, callback: (isValid: boolean) => void) => void; +import { Terminal as PublicTerminal, ITerminalOptions as IPublicTerminalOptions, IEventEmitter } from 'xterm'; +import { IColorSet, IRenderer } from './renderer/Types'; +import { IMouseZoneManager } from './input/Types'; export type CustomKeyEventHandler = (event: KeyboardEvent) => boolean; export type CharData = [number, string, number, number]; export type LineData = CharData[]; +export type LinkMatcherHandler = (event: MouseEvent, uri: string) => boolean | void; +export type LinkMatcherValidationCallback = (uri: string, callback: (isValid: boolean) => void) => void; + export enum LinkHoverEventTypes { HOVER = 'linkhover', TOOLTIP = 'linktooltip', LEAVE = 'linkleave' } + +/** + * This interface encapsulates everything needed from the Terminal by the + * InputHandler. This cleanly separates the large amount of methods needed by + * InputHandler cleanly from the ITerminal interface. + */ +export interface IInputHandlingTerminal extends IEventEmitter { + element: HTMLElement; + options: ITerminalOptions; + cols: number; + rows: number; + charset: ICharset; + gcharset: number; + glevel: number; + charsets: ICharset[]; + applicationKeypad: boolean; + applicationCursor: boolean; + originMode: boolean; + insertMode: boolean; + wraparoundMode: boolean; + bracketedPasteMode: boolean; + defAttr: number; + curAttr: number; + prefix: string; + savedCols: number; + x10Mouse: boolean; + vt200Mouse: boolean; + normalMouse: boolean; + mouseEvents: boolean; + sendFocus: boolean; + utfMouse: boolean; + sgrMouse: boolean; + urxvtMouse: boolean; + cursorHidden: boolean; + + buffers: IBufferSet; + buffer: IBuffer; + viewport: IViewport; + selectionManager: ISelectionManager; + + bell(): void; + focus(): void; + convertEol: boolean; + updateRange(y: number): void; + scroll(isWrapped?: boolean): void; + setgLevel(g: number): void; + eraseAttr(): number; + eraseRight(x: number, y: number): void; + eraseLine(y: number): void; + eraseLeft(x: number, y: number): void; + blankLine(cur?: boolean, isWrapped?: boolean): LineData; + is(term: string): boolean; + send(data: string): void; + setgCharset(g: number, charset: ICharset): void; + resize(x: number, y: number): void; + log(text: string, data?: any): void; + reset(): void; + showCursor(): void; + refresh(start: number, end: number): void; + matchColor(r1: number, g1: number, b1: number): number; + error(text: string, data?: any): void; + setOption(key: string, value: any): void; +} + +export interface IViewport { + syncScrollArea(): void; + onWheel(ev: WheelEvent): void; + onTouchStart(ev: TouchEvent): void; + onTouchMove(ev: TouchEvent): void; + onThemeChanged(colors: IColorSet): void; +} + +export interface ICompositionHelper { + compositionstart(): void; + compositionupdate(ev: CompositionEvent): void; + compositionend(): void; + updateCompositionElements(dontRecurse?: boolean): void; + keydown(ev: KeyboardEvent): boolean; +} + +/** + * Handles actions generated by the parser. + */ +export interface IInputHandler { + addChar(char: string, code: number): void; + + /** C0 BEL */ bell(): void; + /** C0 LF */ lineFeed(): void; + /** C0 CR */ carriageReturn(): void; + /** C0 BS */ backspace(): void; + /** C0 HT */ tab(): void; + /** C0 SO */ shiftOut(): void; + /** C0 SI */ shiftIn(): void; + + /** CSI @ */ insertChars(params?: number[]): void; + /** CSI A */ cursorUp(params?: number[]): void; + /** CSI B */ cursorDown(params?: number[]): void; + /** CSI C */ cursorForward(params?: number[]): void; + /** CSI D */ cursorBackward(params?: number[]): void; + /** CSI E */ cursorNextLine(params?: number[]): void; + /** CSI F */ cursorPrecedingLine(params?: number[]): void; + /** CSI G */ cursorCharAbsolute(params?: number[]): void; + /** CSI H */ cursorPosition(params?: number[]): void; + /** CSI I */ cursorForwardTab(params?: number[]): void; + /** CSI J */ eraseInDisplay(params?: number[]): void; + /** CSI K */ eraseInLine(params?: number[]): void; + /** CSI L */ insertLines(params?: number[]): void; + /** CSI M */ deleteLines(params?: number[]): void; + /** CSI P */ deleteChars(params?: number[]): void; + /** CSI S */ scrollUp(params?: number[]): void; + /** CSI T */ scrollDown(params?: number[]): void; + /** CSI X */ eraseChars(params?: number[]): void; + /** CSI Z */ cursorBackwardTab(params?: number[]): void; + /** CSI ` */ charPosAbsolute(params?: number[]): void; + /** CSI a */ HPositionRelative(params?: number[]): void; + /** CSI b */ repeatPrecedingCharacter(params?: number[]): void; + /** CSI c */ sendDeviceAttributes(params?: number[]): void; + /** CSI d */ linePosAbsolute(params?: number[]): void; + /** CSI e */ VPositionRelative(params?: number[]): void; + /** CSI f */ HVPosition(params?: number[]): void; + /** CSI g */ tabClear(params?: number[]): void; + /** CSI h */ setMode(params?: number[]): void; + /** CSI l */ resetMode(params?: number[]): void; + /** CSI m */ charAttributes(params?: number[]): void; + /** CSI n */ deviceStatus(params?: number[]): void; + /** CSI p */ softReset(params?: number[]): void; + /** CSI q */ setCursorStyle(params?: number[]): void; + /** CSI r */ setScrollRegion(params?: number[]): void; + /** CSI s */ saveCursor(params?: number[]): void; + /** CSI u */ restoreCursor(params?: number[]): void; +} + +export interface ILinkMatcher { + id: number; + regex: RegExp; + handler: LinkMatcherHandler; + hoverTooltipCallback?: LinkMatcherHandler; + hoverLeaveCallback?: () => void; + matchIndex?: number; + validationCallback?: LinkMatcherValidationCallback; + priority?: number; +} + +export interface ICharset { + [key: string]: string; +} + +export interface ILinkHoverEvent { + x: number; + y: number; + length: number; +} + +export interface ITerminal extends PublicTerminal, IElementAccessor, IBufferAccessor, ILinkifierAccessor { + selectionManager: ISelectionManager; + charMeasure: ICharMeasure; + renderer: IRenderer; + browser: IBrowser; + writeBuffer: string[]; + cursorHidden: boolean; + cursorState: number; + defAttr: number; + options: ITerminalOptions; + buffer: IBuffer; + buffers: IBufferSet; + isFocused: boolean; + mouseHelper: IMouseHelper; + bracketedPasteMode: boolean; + + /** + * Emit the 'data' event and populate the given data. + * @param data The data to populate in the event. + */ + handler(data: string): void; + scrollLines(disp: number, suppressScrollEvent?: boolean): void; + cancel(ev: Event, force?: boolean): boolean | void; + log(text: string): void; + showCursor(): void; + blankLine(cur?: boolean, isWrapped?: boolean, cols?: number): LineData; +} + +export interface IBufferAccessor { + buffer: IBuffer; +} + +export interface IElementAccessor { + element: HTMLElement; +} + +export interface ILinkifierAccessor { + linkifier: ILinkifier; +} + +export interface IMouseHelper { + getCoords(event: {pageX: number, pageY: number}, element: HTMLElement, charMeasure: ICharMeasure, lineHeight: number, colCount: number, rowCount: number, isSelection?: boolean): [number, number]; + getRawByteCoords(event: MouseEvent, element: HTMLElement, charMeasure: ICharMeasure, lineHeight: number, colCount: number, rowCount: number): { x: number, y: number }; +} + +export interface ICharMeasure { + width: number; + height: number; + measure(options: ITerminalOptions): void; +} + +// TODO: The options that are not in the public API should be reviewed +export interface ITerminalOptions extends IPublicTerminalOptions { + cancelEvents?: boolean; + convertEol?: boolean; + debug?: boolean; + handler?: (data: string) => void; + screenKeys?: boolean; + termName?: string; + useFlowControl?: boolean; +} + +export interface IBuffer { + lines: ICircularList; + ydisp: number; + ybase: number; + y: number; + x: number; + tabs: any; + scrollBottom: number; + scrollTop: number; + savedY: number; + savedX: number; + isCursorInViewport: boolean; + translateBufferLineToString(lineIndex: number, trimRight: boolean, startCol?: number, endCol?: number): string; + nextStop(x?: number): number; + prevStop(x?: number): number; +} + +export interface IBufferSet extends IEventEmitter { + alt: IBuffer; + normal: IBuffer; + active: IBuffer; + + activateNormalBuffer(): void; + activateAltBuffer(): void; +} + +export interface ICircularList extends IEventEmitter { + length: number; + maxLength: number; + forEach: (callbackfn: (value: T, index: number) => void) => void; + + 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; +} + +export interface ISelectionManager { + selectionText: string; + selectionStart: [number, number]; + selectionEnd: [number, number]; + + disable(): void; + enable(): void; + setSelection(row: number, col: number, length: number): void; +} + +export interface ILinkifier extends IEventEmitter { + attachToDom(mouseZoneManager: IMouseZoneManager): void; + linkifyRows(start: number, end: number): void; + setHypertextLinkHandler(handler: LinkMatcherHandler): void; + setHypertextValidationCallback(callback: LinkMatcherValidationCallback): void; + registerLinkMatcher(regex: RegExp, handler: LinkMatcherHandler, options?: ILinkMatcherOptions): number; + deregisterLinkMatcher(matcherId: number): boolean; +} + +export interface ILinkMatcherOptions { + /** + * The index of the link from the regex.match(text) call. This defaults to 0 + * (for regular expressions without capture groups). + */ + matchIndex?: number; + /** + * A callback that validates an individual link, returning true if valid and + * false if invalid. + */ + validationCallback?: LinkMatcherValidationCallback; + /** + * A callback that fires when the mouse hovers over a link. + */ + tooltipCallback?: LinkMatcherHandler; + /** + * A callback that fires when the mouse leaves a link that was hovered. + */ + leaveCallback?: () => void; + /** + * The priority of the link matcher, this defines the order in which the link + * matcher is evaluated relative to others, from highest to lowest. The + * default value is 0. + */ + priority?: number; +} + +export interface IBrowser { + isNode: boolean; + userAgent: string; + platform: string; + isFirefox: boolean; + isMSIE: boolean; + isMac: boolean; + isIpad: boolean; + isIphone: boolean; + isMSWindows: boolean; +} diff --git a/src/Viewport.ts b/src/Viewport.ts index fcac68ad..87ecd69e 100644 --- a/src/Viewport.ts +++ b/src/Viewport.ts @@ -3,9 +3,9 @@ * @license MIT */ -import { ITerminal, IViewport } from './Interfaces'; +import { IColorSet } from './renderer/Types'; +import { ITerminal, IViewport } from './Types'; import { CharMeasure } from './utils/CharMeasure'; -import { IColorSet } from './renderer/Interfaces'; /** * Represents the viewport of a terminal, the visible area within the larger buffer of output. diff --git a/src/handlers/Clipboard.ts b/src/handlers/Clipboard.ts index cf6661fe..fd2b3d77 100644 --- a/src/handlers/Clipboard.ts +++ b/src/handlers/Clipboard.ts @@ -3,7 +3,7 @@ * @license MIT */ -import { ITerminal, ISelectionManager } from '../Interfaces'; +import { ITerminal, ISelectionManager } from '../Types'; interface IWindow extends Window { clipboardData?: { diff --git a/src/input/MouseZoneManager.ts b/src/input/MouseZoneManager.ts index 6fbe1c67..98377f36 100644 --- a/src/input/MouseZoneManager.ts +++ b/src/input/MouseZoneManager.ts @@ -3,8 +3,8 @@ * @license MIT */ -import { IMouseZoneManager, IMouseZone } from './Interfaces'; -import { ITerminal } from '../Interfaces'; +import { ITerminal } from '../Types'; +import { IMouseZoneManager, IMouseZone } from './Types'; const HOVER_DURATION = 500; diff --git a/src/input/Interfaces.ts b/src/input/Types.ts similarity index 100% rename from src/input/Interfaces.ts rename to src/input/Types.ts diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index bf952d06..20a41cfa 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -3,10 +3,9 @@ * @license MIT */ -import { IRenderLayer, IColorSet, IRenderDimensions } from './Interfaces'; -import { ITerminal, ITerminalOptions } from '../Interfaces'; +import { IRenderLayer, IColorSet, IRenderDimensions } from './Types'; +import { CharData, ITerminal, ITerminalOptions } from '../Types'; import { acquireCharAtlas, CHAR_ATLAS_CELL_SPACING } from './CharAtlas'; -import { CharData } from '../Types'; import { CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CHAR_INDEX } from '../Buffer'; export const INVERTED_DEFAULT_COLOR = -1; diff --git a/src/renderer/CharAtlas.ts b/src/renderer/CharAtlas.ts index 2738843c..05cf7201 100644 --- a/src/renderer/CharAtlas.ts +++ b/src/renderer/CharAtlas.ts @@ -3,8 +3,8 @@ * @license MIT */ -import { ITerminal, ITheme } from '../Interfaces'; -import { IColorSet } from '../renderer/Interfaces'; +import { ITerminal } from '../Types'; +import { IColorSet } from './Types'; import { isFirefox } from '../shared/utils/Browser'; import { generateCharAtlas, ICharAtlasRequest } from '../shared/CharAtlasGenerator'; diff --git a/src/renderer/ColorManager.ts b/src/renderer/ColorManager.ts index 6c0d2945..b45c8646 100644 --- a/src/renderer/ColorManager.ts +++ b/src/renderer/ColorManager.ts @@ -3,8 +3,8 @@ * @license MIT */ -import { IColorSet, IColorManager } from './Interfaces'; -import { ITheme } from '../Interfaces'; +import { IColorSet, IColorManager } from './Types'; +import { ITheme } from 'xterm'; const DEFAULT_FOREGROUND = '#ffffff'; const DEFAULT_BACKGROUND = '#000000'; diff --git a/src/renderer/CursorRenderLayer.ts b/src/renderer/CursorRenderLayer.ts index 6ac489fc..d430b81d 100644 --- a/src/renderer/CursorRenderLayer.ts +++ b/src/renderer/CursorRenderLayer.ts @@ -3,13 +3,11 @@ * @license MIT */ -import { IColorSet, IRenderDimensions } from './Interfaces'; -import { IBuffer, ICharMeasure, ITerminal, ITerminalOptions } from '../Interfaces'; import { CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CODE_INDEX, CHAR_DATA_CHAR_INDEX } from '../Buffer'; import { GridCache } from './GridCache'; -import { FLAGS } from './Types'; +import { FLAGS, IColorSet, IRenderDimensions } from './Types'; import { BaseRenderLayer } from './BaseRenderLayer'; -import { CharData } from '../Types'; +import { CharData, IBuffer, ICharMeasure, ITerminal, ITerminalOptions } from '../Types'; interface ICursorState { x: number; diff --git a/src/renderer/Interfaces.ts b/src/renderer/Interfaces.ts deleted file mode 100644 index be1b39dd..00000000 --- a/src/renderer/Interfaces.ts +++ /dev/null @@ -1,99 +0,0 @@ -/** - * Copyright (c) 2017 The xterm.js authors. All rights reserved. - * @license MIT - */ - -import { ITerminal, ITerminalOptions, ITheme, IEventEmitter } from '../Interfaces'; - -export interface IRenderer extends IEventEmitter { - dimensions: IRenderDimensions; - colorManager: IColorManager; - - setTheme(theme: ITheme): IColorSet; - onWindowResize(devicePixelRatio: number): void; - onResize(cols: number, rows: number, didCharSizeChange: boolean): void; - onCharSizeChanged(): void; - onBlur(): void; - onFocus(): void; - onSelectionChanged(start: [number, number], end: [number, number]): void; - onCursorMove(): void; - onOptionsChanged(): void; - clear(): void; - queueRefresh(start: number, end: number): void; -} - -export interface IRenderLayer { - /** - * Called when the terminal loses focus. - */ - onBlur(terminal: ITerminal): void; - - /** - * * Called when the terminal gets focus. - */ - onFocus(terminal: ITerminal): void; - - /** - * Called when the cursor is moved. - */ - onCursorMove(terminal: ITerminal): void; - - /** - * Called when options change. - */ - onOptionsChanged(terminal: ITerminal): void; - - /** - * Called when the theme changes. - */ - onThemeChanged(terminal: ITerminal, colorSet: IColorSet): void; - - /** - * Called when the data in the grid has changed (or needs to be rendered - * again). - */ - onGridChanged(terminal: ITerminal, startRow: number, endRow: number): void; - - /** - * Calls when the selection changes. - */ - onSelectionChanged(terminal: ITerminal, start: [number, number], end: [number, number]): void; - - /** - * Resize the render layer. - */ - resize(terminal: ITerminal, dim: IRenderDimensions, charSizeChanged: boolean): void; - - /** - * Clear the state of the render layer. - */ - reset(terminal: ITerminal): void; -} - -export interface IColorManager { - colors: IColorSet; -} - -export interface IColorSet { - foreground: string; - background: string; - cursor: string; - cursorAccent: string; - selection: string; - ansi: string[]; -} - -export interface IRenderDimensions { - scaledCharWidth: number; - scaledCharHeight: number; - scaledCellWidth: number; - scaledCellHeight: number; - scaledCharLeft: number; - scaledCharTop: number; - scaledCanvasWidth: number; - scaledCanvasHeight: number; - canvasWidth: number; - canvasHeight: number; - actualCellWidth: number; - actualCellHeight: number; -} diff --git a/src/renderer/LinkRenderLayer.ts b/src/renderer/LinkRenderLayer.ts index 87fbddbd..61352f15 100644 --- a/src/renderer/LinkRenderLayer.ts +++ b/src/renderer/LinkRenderLayer.ts @@ -3,13 +3,11 @@ * @license MIT */ -import { IColorSet, IRenderDimensions } from './Interfaces'; -import { IBuffer, ICharMeasure, ILinkHoverEvent, ITerminal, ILinkifierAccessor } from '../Interfaces'; +import { ILinkHoverEvent, ITerminal, ILinkifierAccessor, IBuffer, ICharMeasure, LinkHoverEventTypes } from '../Types'; import { CHAR_DATA_ATTR_INDEX } from '../Buffer'; import { GridCache } from './GridCache'; -import { FLAGS } from './Types'; +import { FLAGS, IColorSet, IRenderDimensions } from './Types'; import { BaseRenderLayer, INVERTED_DEFAULT_COLOR } from './BaseRenderLayer'; -import { LinkHoverEventTypes } from '../Types'; export class LinkRenderLayer extends BaseRenderLayer { private _state: ILinkHoverEvent = null; diff --git a/src/renderer/Renderer.ts b/src/renderer/Renderer.ts index 680d9490..8b9f5006 100644 --- a/src/renderer/Renderer.ts +++ b/src/renderer/Renderer.ts @@ -3,17 +3,18 @@ * @license MIT */ -import { ITerminal, ITheme } from '../Interfaces'; import { CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CHAR_INDEX } from '../Buffer'; import { TextRenderLayer } from './TextRenderLayer'; import { SelectionRenderLayer } from './SelectionRenderLayer'; import { CursorRenderLayer } from './CursorRenderLayer'; import { ColorManager } from './ColorManager'; import { BaseRenderLayer } from './BaseRenderLayer'; -import { IRenderLayer, IColorSet, IRenderer, IRenderDimensions } from './Interfaces'; +import { IRenderLayer, IColorSet, IRenderer, IRenderDimensions } from './Types'; +import { ITerminal } from '../Types'; import { LinkRenderLayer } from './LinkRenderLayer'; import { EventEmitter } from '../EventEmitter'; import { ScreenDprMonitor } from '../utils/ScreenDprMonitor'; +import { ITheme } from 'xterm'; export class Renderer extends EventEmitter implements IRenderer { /** A queue of the rows to be refreshed */ diff --git a/src/renderer/SelectionRenderLayer.ts b/src/renderer/SelectionRenderLayer.ts index 9740bb9a..53fc9b39 100644 --- a/src/renderer/SelectionRenderLayer.ts +++ b/src/renderer/SelectionRenderLayer.ts @@ -3,11 +3,10 @@ * @license MIT */ -import { IColorSet, IRenderDimensions } from './Interfaces'; -import { IBuffer, ICharMeasure, ITerminal } from '../Interfaces'; +import { IBuffer, ICharMeasure, ITerminal } from '../Types'; import { CHAR_DATA_ATTR_INDEX } from '../Buffer'; import { GridCache } from './GridCache'; -import { FLAGS } from './Types'; +import { FLAGS, IColorSet, IRenderDimensions } from './Types'; import { BaseRenderLayer } from './BaseRenderLayer'; export class SelectionRenderLayer extends BaseRenderLayer { diff --git a/src/renderer/TextRenderLayer.ts b/src/renderer/TextRenderLayer.ts index 141d9823..3c01cea3 100644 --- a/src/renderer/TextRenderLayer.ts +++ b/src/renderer/TextRenderLayer.ts @@ -3,12 +3,10 @@ * @license MIT */ -import { IColorSet, IRenderDimensions } from './Interfaces'; -import { IBuffer, ICharMeasure, ITerminal } from '../Interfaces'; import { CHAR_DATA_ATTR_INDEX, CHAR_DATA_CODE_INDEX, CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX } from '../Buffer'; -import { FLAGS } from './Types'; +import { FLAGS, IColorSet, IRenderDimensions } from './Types'; +import { CharData, IBuffer, ICharMeasure, ITerminal } from '../Types'; import { GridCache } from './GridCache'; -import { CharData } from '../Types'; import { BaseRenderLayer, INVERTED_DEFAULT_COLOR } from './BaseRenderLayer'; /** diff --git a/src/renderer/Types.ts b/src/renderer/Types.ts index 834f8813..52c06e04 100644 --- a/src/renderer/Types.ts +++ b/src/renderer/Types.ts @@ -3,7 +3,10 @@ * @license MIT */ - /** +import { ITerminal } from '../Types'; +import { IEventEmitter, ITheme } from 'xterm'; + +/** * Flags used to render terminal text properly. */ export enum FLAGS { @@ -14,3 +17,96 @@ export enum FLAGS { INVISIBLE = 16, DIM = 32 } + +export interface IRenderer extends IEventEmitter { + dimensions: IRenderDimensions; + colorManager: IColorManager; + + setTheme(theme: ITheme): IColorSet; + onWindowResize(devicePixelRatio: number): void; + onResize(cols: number, rows: number, didCharSizeChange: boolean): void; + onCharSizeChanged(): void; + onBlur(): void; + onFocus(): void; + onSelectionChanged(start: [number, number], end: [number, number]): void; + onCursorMove(): void; + onOptionsChanged(): void; + clear(): void; + queueRefresh(start: number, end: number): void; +} + +export interface IColorManager { + colors: IColorSet; +} + +export interface IColorSet { + foreground: string; + background: string; + cursor: string; + cursorAccent: string; + selection: string; + ansi: string[]; +} + +export interface IRenderDimensions { + scaledCharWidth: number; + scaledCharHeight: number; + scaledCellWidth: number; + scaledCellHeight: number; + scaledCharLeft: number; + scaledCharTop: number; + scaledCanvasWidth: number; + scaledCanvasHeight: number; + canvasWidth: number; + canvasHeight: number; + actualCellWidth: number; + actualCellHeight: number; +} + +export interface IRenderLayer { + /** + * Called when the terminal loses focus. + */ + onBlur(terminal: ITerminal): void; + + /** + * * Called when the terminal gets focus. + */ + onFocus(terminal: ITerminal): void; + + /** + * Called when the cursor is moved. + */ + onCursorMove(terminal: ITerminal): void; + + /** + * Called when options change. + */ + onOptionsChanged(terminal: ITerminal): void; + + /** + * Called when the theme changes. + */ + onThemeChanged(terminal: ITerminal, colorSet: IColorSet): void; + + /** + * Called when the data in the grid has changed (or needs to be rendered + * again). + */ + onGridChanged(terminal: ITerminal, startRow: number, endRow: number): void; + + /** + * Calls when the selection changes. + */ + onSelectionChanged(terminal: ITerminal, start: [number, number], end: [number, number]): void; + + /** + * Resize the render layer. + */ + resize(terminal: ITerminal, dim: IRenderDimensions, charSizeChanged: boolean): void; + + /** + * Clear the state of the render layer. + */ + reset(terminal: ITerminal): void; +} diff --git a/src/shared/CharAtlasGenerator.ts b/src/shared/CharAtlasGenerator.ts index 9b895c9c..9ae9f4b3 100644 --- a/src/shared/CharAtlasGenerator.ts +++ b/src/shared/CharAtlasGenerator.ts @@ -3,8 +3,8 @@ * @license MIT */ +import { FontWeight } from 'xterm'; import { isFirefox } from './utils/Browser'; -import { FontWeight } from './Types'; declare const Promise: any; diff --git a/src/shared/Types.ts b/src/shared/Types.ts deleted file mode 100644 index b61525bd..00000000 --- a/src/shared/Types.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Copyright (c) 2018 The xterm.js authors. All rights reserved. - * @license MIT - */ - - export type FontWeight = 'normal' | 'bold' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900'; diff --git a/src/shared/utils/Browser.ts b/src/shared/utils/Browser.ts index 1d4774d2..be71d875 100644 --- a/src/shared/utils/Browser.ts +++ b/src/shared/utils/Browser.ts @@ -24,6 +24,6 @@ export const isLinux = platform.indexOf('Linux') >= 0; * @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): boolean { +function contains(arr: any[], el: any): boolean { return arr.indexOf(el) >= 0; -}; +} diff --git a/src/utils/CharMeasure.test.ts b/src/utils/CharMeasure.test.ts index f50ce96b..e4f4e1d6 100644 --- a/src/utils/CharMeasure.test.ts +++ b/src/utils/CharMeasure.test.ts @@ -4,8 +4,8 @@ */ import jsdom = require('jsdom'); +import { ICharMeasure, ITerminal } from '../Types'; import { assert } from 'chai'; -import { ICharMeasure, ITerminal } from '../Interfaces'; import { CharMeasure } from './CharMeasure'; describe('CharMeasure', () => { diff --git a/src/utils/CharMeasure.ts b/src/utils/CharMeasure.ts index 62291ab2..91cfce5f 100644 --- a/src/utils/CharMeasure.ts +++ b/src/utils/CharMeasure.ts @@ -3,8 +3,8 @@ * @license MIT */ +import { ICharMeasure, ITerminal, ITerminalOptions } from '../Types'; import { EventEmitter } from '../EventEmitter'; -import { ICharMeasure, ITerminal, ITerminalOptions } from '../Interfaces'; /** * Utility class that measures the size of a character. Measurements are done in diff --git a/src/utils/CircularList.ts b/src/utils/CircularList.ts index 97a32b79..6b74971b 100644 --- a/src/utils/CircularList.ts +++ b/src/utils/CircularList.ts @@ -4,7 +4,7 @@ */ import { EventEmitter } from '../EventEmitter'; -import { ICircularList } from '../Interfaces'; +import { ICircularList } from '../Types'; /** * Represents a circular list; a list with a maximum size that wraps around when push is called, diff --git a/src/utils/MouseHelper.ts b/src/utils/MouseHelper.ts index d7d8f698..f62593eb 100644 --- a/src/utils/MouseHelper.ts +++ b/src/utils/MouseHelper.ts @@ -3,8 +3,8 @@ * @license MIT */ -import { ICharMeasure } from '../Interfaces'; -import { IRenderer } from '../renderer/Interfaces'; +import { ICharMeasure } from '../Types'; +import { IRenderer } from '../renderer/Types'; export class MouseHelper { constructor(private _renderer: IRenderer) {} @@ -24,7 +24,7 @@ export class MouseHelper { while (element) { x -= element.offsetLeft; y -= element.offsetTop; - element = 'offsetParent' in element ? element.offsetParent : element.parentElement; + element = element.offsetParent; } element = originalElement; while (element && element !== element.ownerDocument.body) { diff --git a/src/utils/TestUtils.test.ts b/src/utils/TestUtils.test.ts index 8e8900a1..0744cd14 100644 --- a/src/utils/TestUtils.test.ts +++ b/src/utils/TestUtils.test.ts @@ -3,13 +3,73 @@ * @license MIT */ -import { ITerminal, IBuffer, IBufferSet, IBrowser, ICharMeasure, ISelectionManager, ITerminalOptions, IListenerType, IInputHandlingTerminal, IViewport, ICircularList, ICompositionHelper, ITheme, ILinkifier, IMouseHelper } from '../Interfaces'; -import { LineData } from '../Types'; +import { IColorSet, IRenderer, IRenderDimensions, IColorManager } from '../renderer/Types'; +import { LineData, IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminal, IBuffer, IBufferSet, IBrowser, ICharMeasure, ISelectionManager, ITerminalOptions, ICircularList, ILinkifier, IMouseHelper, ILinkMatcherOptions } from '../Types'; import { Buffer } from '../Buffer'; import * as Browser from '../shared/utils/Browser'; -import { IColorSet, IRenderer, IRenderDimensions, IColorManager } from '../renderer/Interfaces'; +import { ITheme } from 'xterm'; export class MockTerminal implements ITerminal { + getOption(key: any): any { + throw new Error('Method not implemented.'); + } + setOption(key: any, value: any): void { + throw new Error('Method not implemented.'); + } + blur(): void { + throw new Error('Method not implemented.'); + } + focus(): void { + throw new Error('Method not implemented.'); + } + resize(columns: number, rows: number): void { + throw new Error('Method not implemented.'); + } + writeln(data: string): void { + throw new Error('Method not implemented.'); + } + open(parent: HTMLElement): void { + throw new Error('Method not implemented.'); + } + attachCustomKeyEventHandler(customKeyEventHandler: (event: KeyboardEvent) => boolean): void { + throw new Error('Method not implemented.'); + } + registerLinkMatcher(regex: RegExp, handler: (event: MouseEvent, uri: string) => boolean | void, options?: ILinkMatcherOptions): number { + throw new Error('Method not implemented.'); + } + deregisterLinkMatcher(matcherId: number): void { + throw new Error('Method not implemented.'); + } + hasSelection(): boolean { + throw new Error('Method not implemented.'); + } + getSelection(): string { + throw new Error('Method not implemented.'); + } + clearSelection(): void { + throw new Error('Method not implemented.'); + } + selectAll(): void { + throw new Error('Method not implemented.'); + } + destroy(): void { + throw new Error('Method not implemented.'); + } + scrollPages(pageCount: number): void { + throw new Error('Method not implemented.'); + } + scrollToTop(): void { + throw new Error('Method not implemented.'); + } + scrollToBottom(): void { + throw new Error('Method not implemented.'); + } + clear(): void { + throw new Error('Method not implemented.'); + } + write(data: string): void { + throw new Error('Method not implemented.'); + } bracketedPasteMode: boolean; mouseHelper: IMouseHelper; renderer: IRenderer; @@ -39,7 +99,7 @@ export class MockTerminal implements ITerminal { on(event: string, callback: () => void): void { throw new Error('Method not implemented.'); } - off(type: string, listener: IListenerType): void { + off(type: string, listener: (...args: any[]) => void): void { throw new Error('Method not implemented.'); } scrollLines(disp: number, suppressScrollEvent: boolean): void { @@ -184,10 +244,10 @@ export class MockInputHandlingTerminal implements IInputHandlingTerminal { setOption(key: string, value: any): void { this.options[key] = value; } - on(type: string, listener: IListenerType): void { + on(type: string, listener: (...args: any[]) => void): void { throw new Error('Method not implemented.'); } - off(type: string, listener: IListenerType): void { + off(type: string, listener: (...args: any[]) => void): void { throw new Error('Method not implemented.'); } emit(type: string, data?: any): void { @@ -220,10 +280,10 @@ export class MockBuffer implements IBuffer { export class MockRenderer implements IRenderer { colorManager: IColorManager; - on(type: string, listener: IListenerType): void { + on(type: string, listener: (...args: any[]) => void): void { throw new Error('Method not implemented.'); } - off(type: string, listener: IListenerType): void { + off(type: string, listener: (...args: any[]) => void): void { throw new Error('Method not implemented.'); } emit(type: string, data?: any): void { diff --git a/tsconfig.json b/tsconfig.json index a3aa790c..38bfd2fa 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,8 +5,7 @@ "rootDir": "src", "outDir": "lib", "sourceMap": true, - "removeComments": true, - "declaration": true + "removeComments": true }, "include": [ "src/**/*" diff --git a/tslint.json b/tslint.json index b5367f6a..f6ad759a 100644 --- a/tslint.json +++ b/tslint.json @@ -24,6 +24,7 @@ "parameter" ], "eofline": true, + "no-duplicate-imports": true, "no-eval": true, "no-internal-module": true, "no-trailing-whitespace": true, diff --git a/typings/xterm.d.ts b/typings/xterm.d.ts index 37f169e8..dbd1eebc 100644 --- a/typings/xterm.d.ts +++ b/typings/xterm.d.ts @@ -192,10 +192,16 @@ declare module 'xterm' { priority?: number; } + export interface IEventEmitter { + on(type: string, listener: (...args: any[]) => void): void; + off(type: string, listener: (...args: any[]) => void): void; + emit(type: string, data?: any): void; + } + /** * The class that represents an xterm.js terminal. */ - export class Terminal { + export class Terminal implements IEventEmitter { /** * The element containing the terminal. */ @@ -244,7 +250,7 @@ declare module 'xterm' { * @param type The type of the event. * @param listener The listener. */ - on(type: 'data', listener: (data?: string) => void): void; + on(type: 'data', listener: (...args: any[]) => void): void; /** * Registers an event listener. * @param type The type of the event. @@ -295,6 +301,8 @@ declare module 'xterm' { */ off(type: 'blur' | 'focus' | 'linefeed' | 'selection' | 'data' | 'key' | 'keypress' | 'keydown' | 'refresh' | 'resize' | 'scroll' | 'title' | string, listener: (...args: any[]) => void): void; + emit(type: string, data?: any): void; + /** * Resizes the terminal. * @param x The number of columns to resize to. @@ -366,22 +374,6 @@ declare module 'xterm' { */ selectAll(): void; - // /** - // * Find the next instance of the term, then scroll to and select it. If it - // * doesn't exist, do nothing. - // * @param term Tne search term. - // * @return Whether a result was found. - // */ - // findNext(term: string): boolean; - - // /** - // * Find the previous instance of the term, then scroll to and select it. If it - // * doesn't exist, do nothing. - // * @param term Tne search term. - // * @return Whether a result was found. - // */ - // findPrevious(term: string): boolean; - /** * Destroys the terminal and detaches it from the DOM. */