/** * Copyright (c) 2017 The xterm.js authors. All rights reserved. * @license MIT */ 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 XtermListener = (...args: any[]) => void; export type CharData = [number, string, number, number]; export type LineData = CharData[]; export type LinkMatcherHandler = (event: MouseEvent, uri: string) => void; export type LinkMatcherValidationCallback = (uri: string, callback: (isValid: boolean) => void) => void; export const 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; tabSet(): void; } export interface IViewport { scrollBarWidth: number; syncScrollArea(): void; getLinesScrolled(ev: WheelEvent): number; 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; willLinkActivate?: (event: MouseEvent, uri: string) => boolean; } export interface ICharset { [key: string]: string; } export interface ILinkHoverEvent { x1: number; y1: number; x2: number; y2: number; cols: number; } export interface ITerminal extends PublicTerminal, IElementAccessor, IBufferAccessor, ILinkifierAccessor { screenElement: HTMLElement; 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; viewport: IViewport; bracketedPasteMode: boolean; applicationCursor: boolean; /** * Emit the 'data' event and populate the given data. * @param data The data to populate in the event. */ handler(data: string): void; send(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 { readonly lines: ICircularList; ydisp: number; ybase: number; y: number; x: number; tabs: any; scrollBottom: number; scrollTop: number; hasScrollback: boolean; 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; 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; isClickInSelection(event: MouseEvent): boolean; selectWordAtCursor(event: MouseEvent): void; } export interface ILinkifier extends IEventEmitter { attachToDom(mouseZoneManager: IMouseZoneManager): void; linkifyRows(start: number, end: number): 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; /** * A callback that fires when the mousedown and click events occur that * determines whether a link will be activated upon click. This enables * only activating a link when a certain modifier is held down, if not the * mouse event will continue propagation (eg. double click to select word). */ willLinkActivate?: (event: MouseEvent, uri: string) => boolean; } export interface IBrowser { isNode: boolean; userAgent: string; platform: string; isFirefox: boolean; isMSIE: boolean; isMac: boolean; isIpad: boolean; isIphone: boolean; isMSWindows: boolean; } export interface ISoundManager { playBellSound(): void; }