mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Merge branch 'master' into 1473_slow_build
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -77,3 +77,74 @@ export namespace C0 {
|
||||
/** Delete (Caret = ^?) */
|
||||
export const DEL = '\x7f';
|
||||
}
|
||||
|
||||
/**
|
||||
* C1 control codes
|
||||
* See = https://en.wikipedia.org/wiki/C0_and_C1_control_codes
|
||||
*/
|
||||
export namespace C1 {
|
||||
/** padding character */
|
||||
export const PAD = '\x80';
|
||||
/** High Octet Preset */
|
||||
export const HOP = '\x81';
|
||||
/** Break Permitted Here */
|
||||
export const BPH = '\x82';
|
||||
/** No Break Here */
|
||||
export const NBH = '\x83';
|
||||
/** Index */
|
||||
export const IND = '\x84';
|
||||
/** Next Line */
|
||||
export const NEL = '\x85';
|
||||
/** Start of Selected Area */
|
||||
export const SSA = '\x86';
|
||||
/** End of Selected Area */
|
||||
export const ESA = '\x87';
|
||||
/** Horizontal Tabulation Set */
|
||||
export const HTS = '\x88';
|
||||
/** Horizontal Tabulation With Justification */
|
||||
export const HTJ = '\x89';
|
||||
/** Vertical Tabulation Set */
|
||||
export const VTS = '\x8a';
|
||||
/** Partial Line Down */
|
||||
export const PLD = '\x8b';
|
||||
/** Partial Line Up */
|
||||
export const PLU = '\x8c';
|
||||
/** Reverse Index */
|
||||
export const RI = '\x8d';
|
||||
/** Single-Shift 2 */
|
||||
export const SS2 = '\x8e';
|
||||
/** Single-Shift 3 */
|
||||
export const SS3 = '\x8f';
|
||||
/** Device Control String */
|
||||
export const DCS = '\x90';
|
||||
/** Private Use 1 */
|
||||
export const PU1 = '\x91';
|
||||
/** Private Use 2 */
|
||||
export const PU2 = '\x92';
|
||||
/** Set Transmit State */
|
||||
export const STS = '\x93';
|
||||
/** Destructive backspace, intended to eliminate ambiguity about meaning of BS. */
|
||||
export const CCH = '\x94';
|
||||
/** Message Waiting */
|
||||
export const MW = '\x95';
|
||||
/** Start of Protected Area */
|
||||
export const SPA = '\x96';
|
||||
/** End of Protected Area */
|
||||
export const EPA = '\x97';
|
||||
/** Start of String */
|
||||
export const SOS = '\x98';
|
||||
/** Single Graphic Character Introducer */
|
||||
export const SGCI = '\x99';
|
||||
/** Single Character Introducer */
|
||||
export const SCI = '\x9a';
|
||||
/** Control Sequence Introducer */
|
||||
export const CSI = '\x9b';
|
||||
/** String Terminator */
|
||||
export const ST = '\x9c';
|
||||
/** Operating System Command */
|
||||
export const OSC = '\x9d';
|
||||
/** Privacy Message */
|
||||
export const PM = '\x9e';
|
||||
/** Application Program Command */
|
||||
export const APC = '\x9f';
|
||||
}
|
||||
|
||||
+11
-10
@@ -29,38 +29,39 @@ describe('InputHandler', () => {
|
||||
it('should call Terminal.setOption with correct params', () => {
|
||||
let terminal = new MockInputHandlingTerminal();
|
||||
let inputHandler = new InputHandler(terminal);
|
||||
const collect = ' ';
|
||||
|
||||
inputHandler.setCursorStyle([0]);
|
||||
inputHandler.setCursorStyle([0], collect);
|
||||
assert.equal(terminal.options['cursorStyle'], 'block');
|
||||
assert.equal(terminal.options['cursorBlink'], true);
|
||||
|
||||
terminal.options = {};
|
||||
inputHandler.setCursorStyle([1]);
|
||||
inputHandler.setCursorStyle([1], collect);
|
||||
assert.equal(terminal.options['cursorStyle'], 'block');
|
||||
assert.equal(terminal.options['cursorBlink'], true);
|
||||
|
||||
terminal.options = {};
|
||||
inputHandler.setCursorStyle([2]);
|
||||
inputHandler.setCursorStyle([2], collect);
|
||||
assert.equal(terminal.options['cursorStyle'], 'block');
|
||||
assert.equal(terminal.options['cursorBlink'], false);
|
||||
|
||||
terminal.options = {};
|
||||
inputHandler.setCursorStyle([3]);
|
||||
inputHandler.setCursorStyle([3], collect);
|
||||
assert.equal(terminal.options['cursorStyle'], 'underline');
|
||||
assert.equal(terminal.options['cursorBlink'], true);
|
||||
|
||||
terminal.options = {};
|
||||
inputHandler.setCursorStyle([4]);
|
||||
inputHandler.setCursorStyle([4], collect);
|
||||
assert.equal(terminal.options['cursorStyle'], 'underline');
|
||||
assert.equal(terminal.options['cursorBlink'], false);
|
||||
|
||||
terminal.options = {};
|
||||
inputHandler.setCursorStyle([5]);
|
||||
inputHandler.setCursorStyle([5], collect);
|
||||
assert.equal(terminal.options['cursorStyle'], 'bar');
|
||||
assert.equal(terminal.options['cursorBlink'], true);
|
||||
|
||||
terminal.options = {};
|
||||
inputHandler.setCursorStyle([6]);
|
||||
inputHandler.setCursorStyle([6], collect);
|
||||
assert.equal(terminal.options['cursorStyle'], 'bar');
|
||||
assert.equal(terminal.options['cursorBlink'], false);
|
||||
});
|
||||
@@ -68,14 +69,14 @@ describe('InputHandler', () => {
|
||||
describe('setMode', () => {
|
||||
it('should toggle Terminal.bracketedPasteMode', () => {
|
||||
let terminal = new MockInputHandlingTerminal();
|
||||
terminal.prefix = '?';
|
||||
const collect = '?';
|
||||
terminal.bracketedPasteMode = false;
|
||||
let inputHandler = new InputHandler(terminal);
|
||||
// Set bracketed paste mode
|
||||
inputHandler.setMode([2004]);
|
||||
inputHandler.setMode([2004], collect);
|
||||
assert.equal(terminal.bracketedPasteMode, true);
|
||||
// Reset bracketed paste mode
|
||||
inputHandler.resetMode([2004]);
|
||||
inputHandler.resetMode([2004], collect);
|
||||
assert.equal(terminal.bracketedPasteMode, false);
|
||||
});
|
||||
});
|
||||
|
||||
+570
-101
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -232,7 +232,7 @@ export class Parser {
|
||||
if (ch in normalStateHandler) {
|
||||
normalStateHandler[ch](this, this._inputHandler);
|
||||
} else {
|
||||
this._inputHandler.addChar(ch, code);
|
||||
// this._inputHandler.addChar(ch, code);
|
||||
}
|
||||
break;
|
||||
case ParserState.ESCAPED:
|
||||
|
||||
+3
-9
@@ -32,7 +32,7 @@ import { Viewport } from './Viewport';
|
||||
import { rightClickHandler, moveTextAreaUnderMouseCursor, pasteHandler, copyHandler } from './handlers/Clipboard';
|
||||
import { C0 } from './EscapeSequences';
|
||||
import { InputHandler } from './InputHandler';
|
||||
import { Parser } from './Parser';
|
||||
// import { Parser } from './Parser';
|
||||
import { Renderer } from './renderer/Renderer';
|
||||
import { Linkifier } from './Linkifier';
|
||||
import { SelectionManager } from './SelectionManager';
|
||||
@@ -195,8 +195,6 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
|
||||
|
||||
public params: (string | number)[];
|
||||
public currentParam: string | number;
|
||||
public prefix: string;
|
||||
public postfix: string;
|
||||
|
||||
// user input states
|
||||
public writeBuffer: string[];
|
||||
@@ -218,7 +216,6 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
|
||||
|
||||
private _inputHandler: InputHandler;
|
||||
public soundManager: SoundManager;
|
||||
private _parser: Parser;
|
||||
public renderer: IRenderer;
|
||||
public selectionManager: SelectionManager;
|
||||
public linkifier: ILinkifier;
|
||||
@@ -321,8 +318,6 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
|
||||
|
||||
this.params = [];
|
||||
this.currentParam = 0;
|
||||
this.prefix = '';
|
||||
this.postfix = '';
|
||||
|
||||
// user input states
|
||||
this.writeBuffer = [];
|
||||
@@ -333,7 +328,6 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
|
||||
this._userScrolling = false;
|
||||
|
||||
this._inputHandler = new InputHandler(this);
|
||||
this._parser = new Parser(this._inputHandler, this);
|
||||
// Reuse renderer if the Terminal is being recreated via a reset call.
|
||||
this.renderer = this.renderer || null;
|
||||
this.selectionManager = this.selectionManager || null;
|
||||
@@ -1318,8 +1312,8 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
|
||||
// middle of parsing escape sequence in two chunks. For some reason the
|
||||
// state of the parser resets to 0 after exiting parser.parse. This change
|
||||
// just sets the state back based on the correct return statement.
|
||||
const state = this._parser.parse(data);
|
||||
this._parser.setState(state);
|
||||
|
||||
this._inputHandler.parse(data);
|
||||
|
||||
this.updateRange(this.buffer.y);
|
||||
this.refresh(this._refreshStart, this._refreshEnd);
|
||||
|
||||
+166
-12
@@ -45,7 +45,6 @@ export interface IInputHandlingTerminal extends IEventEmitter {
|
||||
bracketedPasteMode: boolean;
|
||||
defAttr: number;
|
||||
curAttr: number;
|
||||
prefix: string;
|
||||
savedCols: number;
|
||||
x10Mouse: boolean;
|
||||
vt200Mouse: boolean;
|
||||
@@ -106,10 +105,11 @@ export interface ICompositionHelper {
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles actions generated by the parser.
|
||||
* Calls the parser and handles actions generated by the parser.
|
||||
*/
|
||||
export interface IInputHandler {
|
||||
addChar(char: string, code: number): void;
|
||||
parse(data: string): void;
|
||||
print(data: string, start: number, end: number): void;
|
||||
|
||||
/** C0 BEL */ bell(): void;
|
||||
/** C0 LF */ lineFeed(): void;
|
||||
@@ -135,26 +135,49 @@ export interface IInputHandler {
|
||||
/** 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 T */ scrollDown(params?: number[], collect?: string): 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 c */ sendDeviceAttributes(params?: number[], collect?: string): 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 h */ setMode(params?: number[], collect?: string): void;
|
||||
/** CSI l */ resetMode(params?: number[], collect?: string): 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 n */ deviceStatus(params?: number[], collect?: string): void;
|
||||
/** CSI p */ softReset(params?: number[], collect?: string): void;
|
||||
/** CSI q */ setCursorStyle(params?: number[], collect?: string): void;
|
||||
/** CSI r */ setScrollRegion(params?: number[], collect?: string): void;
|
||||
/** CSI s */ saveCursor(params?: number[]): void;
|
||||
/** CSI u */ restoreCursor(params?: number[]): void;
|
||||
/** OSC 0
|
||||
OSC 2 */ setTitle(data: string): void;
|
||||
/** ESC E */ nextLine(): void;
|
||||
/** ESC = */ keypadApplicationMode(): void;
|
||||
/** ESC > */ keypadNumericMode(): void;
|
||||
/** ESC % G
|
||||
ESC % @ */ selectDefaultCharset(): void;
|
||||
/** ESC ( C
|
||||
ESC ) C
|
||||
ESC * C
|
||||
ESC + C
|
||||
ESC - C
|
||||
ESC . C
|
||||
ESC / C */ selectCharset(collectAndFlag: string): void;
|
||||
/** ESC D */ index(): void;
|
||||
/** ESC H */ tabSet(): void;
|
||||
/** ESC M */ reverseIndex(): void;
|
||||
/** ESC c */ reset(): void;
|
||||
/** ESC n
|
||||
ESC o
|
||||
ESC |
|
||||
ESC }
|
||||
ESC ~ */ setgLevel(level: number): void;
|
||||
}
|
||||
|
||||
export interface ILinkMatcher {
|
||||
@@ -226,7 +249,7 @@ export interface ILinkifierAccessor {
|
||||
}
|
||||
|
||||
export interface IMouseHelper {
|
||||
getCoords(event: {pageX: number, pageY: number}, element: HTMLElement, charMeasure: ICharMeasure, lineHeight: number, colCount: number, rowCount: number, isSelection?: boolean): [number, number];
|
||||
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 };
|
||||
}
|
||||
|
||||
@@ -355,3 +378,134 @@ export interface IBrowser {
|
||||
export interface ISoundManager {
|
||||
playBellSound(): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal states of EscapeSequenceParser.
|
||||
*/
|
||||
export const enum ParserState {
|
||||
GROUND = 0,
|
||||
ESCAPE = 1,
|
||||
ESCAPE_INTERMEDIATE = 2,
|
||||
CSI_ENTRY = 3,
|
||||
CSI_PARAM = 4,
|
||||
CSI_INTERMEDIATE = 5,
|
||||
CSI_IGNORE = 6,
|
||||
SOS_PM_APC_STRING = 7,
|
||||
OSC_STRING = 8,
|
||||
DCS_ENTRY = 9,
|
||||
DCS_PARAM = 10,
|
||||
DCS_IGNORE = 11,
|
||||
DCS_INTERMEDIATE = 12,
|
||||
DCS_PASSTHROUGH = 13
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal actions of EscapeSequenceParser.
|
||||
*/
|
||||
export const enum ParserAction {
|
||||
IGNORE = 0,
|
||||
ERROR = 1,
|
||||
PRINT = 2,
|
||||
EXECUTE = 3,
|
||||
OSC_START = 4,
|
||||
OSC_PUT = 5,
|
||||
OSC_END = 6,
|
||||
CSI_DISPATCH = 7,
|
||||
PARAM = 8,
|
||||
COLLECT = 9,
|
||||
ESC_DISPATCH = 10,
|
||||
CLEAR = 11,
|
||||
DCS_HOOK = 12,
|
||||
DCS_PUT = 13,
|
||||
DCS_UNHOOK = 14
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal state of EscapeSequenceParser.
|
||||
* Used as argument of the error handler to allow
|
||||
* introspection at runtime on parse errors.
|
||||
* Return it with altered values to recover from
|
||||
* faulty states (not yet supported).
|
||||
* Set `abort` to `true` to abort the current parsing.
|
||||
*/
|
||||
export interface IParsingState {
|
||||
// position in parse string
|
||||
position: number;
|
||||
// actual character code
|
||||
code: number;
|
||||
// current parser state
|
||||
currentState: ParserState;
|
||||
// print buffer start index (-1 for not set)
|
||||
print: number;
|
||||
// dcs buffer start index (-1 for not set)
|
||||
dcs: number;
|
||||
// osc string buffer
|
||||
osc: string;
|
||||
// collect buffer with intermediate characters
|
||||
collect: string;
|
||||
// params buffer
|
||||
params: number[];
|
||||
// should abort (default: false)
|
||||
abort: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* DCS handler signature for EscapeSequenceParser.
|
||||
* EscapeSequenceParser handles DCS commands via separate
|
||||
* subparsers that get hook/unhooked and can handle
|
||||
* arbitrary amount of print data.
|
||||
* On entering a DSC sequence `hook` is called by
|
||||
* `EscapeSequenceParser`. Use it to initialize or reset
|
||||
* states needed to handle the current DCS sequence.
|
||||
* EscapeSequenceParser will call `put` several times if the
|
||||
* parsed string got splitted, therefore you might have to collect
|
||||
* `data` until `unhook` is called. `unhook` marks the end
|
||||
* of the current DCS sequence.
|
||||
*/
|
||||
export interface IDcsHandler {
|
||||
hook(collect: string, params: number[], flag: number): void;
|
||||
put(data: string, start: number, end: number): void;
|
||||
unhook(): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* EscapeSequenceParser interface.
|
||||
*/
|
||||
export interface IEscapeSequenceParser {
|
||||
/**
|
||||
* Reset the parser to its initial state (handlers are kept).
|
||||
*/
|
||||
reset(): void;
|
||||
|
||||
/**
|
||||
* Parse string `data`.
|
||||
* @param data The data to parse.
|
||||
*/
|
||||
parse(data: string): void;
|
||||
|
||||
setPrintHandler(callback: (data: string, start: number, end: number) => void): void;
|
||||
clearPrintHandler(): void;
|
||||
|
||||
setExecuteHandler(flag: string, callback: () => void): void;
|
||||
clearExecuteHandler(flag: string): void;
|
||||
setExecuteHandlerFallback(callback: (code: number) => void): void;
|
||||
|
||||
setCsiHandler(flag: string, callback: (params: number[], collect: string) => void): void;
|
||||
clearCsiHandler(flag: string): void;
|
||||
setCsiHandlerFallback(callback: (collect: string, params: number[], flag: number) => void): void;
|
||||
|
||||
setEscHandler(collectAndFlag: string, callback: () => void): void;
|
||||
clearEscHandler(collectAndFlag: string): void;
|
||||
setEscHandlerFallback(callback: (collect: string, flag: number) => void): void;
|
||||
|
||||
setOscHandler(ident: number, callback: (data: string) => void): void;
|
||||
clearOscHandler(ident: number): void;
|
||||
setOscHandlerFallback(callback: (identifier: number, data: string) => void): void;
|
||||
|
||||
setDcsHandler(collectAndFlag: string, handler: IDcsHandler): void;
|
||||
clearDcsHandler(collectAndFlag: string): void;
|
||||
setDcsHandlerFallback(handler: IDcsHandler): void;
|
||||
|
||||
setErrorHandler(callback: (state: IParsingState) => IParsingState): void;
|
||||
clearErrorHandler(): void;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { FontWeight } from 'xterm';
|
||||
import { CHAR_ATLAS_CELL_SPACING, ICharAtlasConfig } from './Types';
|
||||
import { IColor } from '../Types';
|
||||
import { isFirefox } from '../utils/Browser';
|
||||
import { isFirefox, isSafari } from '../utils/Browser';
|
||||
|
||||
declare const Promise: any;
|
||||
|
||||
@@ -99,7 +99,7 @@ export function generateStaticCharAtlasTexture(context: Window, canvasFactory: (
|
||||
// if support is lacking as drawImage works there too. Firefox is also
|
||||
// included here as ImageBitmap appears both buggy and has horrible
|
||||
// performance (tested on v55).
|
||||
if (!('createImageBitmap' in context) || isFirefox) {
|
||||
if (!('createImageBitmap' in context) || isFirefox || isSafari) {
|
||||
// Don't attempt to clear background colors if createImageBitmap is not supported
|
||||
if (canvas instanceof HTMLCanvasElement) {
|
||||
// Just return the HTMLCanvas if it's a HTMLCanvasElement
|
||||
|
||||
@@ -8,6 +8,7 @@ const userAgent = (isNode) ? 'node' : navigator.userAgent;
|
||||
const platform = (isNode) ? 'node' : navigator.platform;
|
||||
|
||||
export const isFirefox = !!~userAgent.indexOf('Firefox');
|
||||
export const isSafari = /^((?!chrome|android).)*safari/i.test(userAgent);
|
||||
export const isMSIE = !!~userAgent.indexOf('MSIE') || !!~userAgent.indexOf('Trident');
|
||||
|
||||
// Find the users platform. We use this to interpret the meta key
|
||||
|
||||
@@ -184,7 +184,6 @@ export class MockInputHandlingTerminal implements IInputHandlingTerminal {
|
||||
bracketedPasteMode: boolean;
|
||||
defAttr: number;
|
||||
curAttr: number;
|
||||
prefix: string;
|
||||
savedCols: number;
|
||||
x10Mouse: boolean;
|
||||
vt200Mouse: boolean;
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
"parameter"
|
||||
],
|
||||
"eofline": true,
|
||||
"new-parens": true,
|
||||
"no-duplicate-imports": true,
|
||||
"no-eval": true,
|
||||
"no-internal-module": true,
|
||||
|
||||
Reference in New Issue
Block a user