mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Merge branch 'master' into trim_behavior
This commit is contained in:
@@ -172,6 +172,7 @@ computational environment for Jupyter, supporting interactive data science and s
|
||||
- [**Shellvault**](https://www.shellvault.io): The cloud-based SSH terminal you can access from anywhere.
|
||||
- [**Juno**](http://junolab.org/): A flexible Julia IDE, based on Atom.
|
||||
- [**webssh**](https://github.com/huashengdun/webssh): Web based ssh client.
|
||||
- [**info-beamer hosted**](https://info-beamer.com): Uses Xterm.js to manage digital signage devices from the web dashboard.
|
||||
|
||||
[And much more...](https://github.com/xtermjs/xterm.js/network/dependents)
|
||||
|
||||
|
||||
+2
-2
@@ -235,7 +235,7 @@ function initOptions(term: TerminalType): void {
|
||||
});
|
||||
html += '</div><div class="option-group">';
|
||||
numberOptions.forEach(o => {
|
||||
html += `<div class="option"><label>${o} <input id="opt-${o}" type="number" value="${term.getOption(o)}"/></label></div>`;
|
||||
html += `<div class="option"><label>${o} <input id="opt-${o}" type="number" value="${term.getOption(o)}" step="${o === 'lineHeight' ? '0.1' : '1'}"/></label></div>`;
|
||||
});
|
||||
html += '</div><div class="option-group">';
|
||||
Object.keys(stringOptions).forEach(o => {
|
||||
@@ -265,7 +265,7 @@ function initOptions(term: TerminalType): void {
|
||||
if (o === 'cols' || o === 'rows') {
|
||||
updateTerminalSize();
|
||||
} else {
|
||||
term.setOption(o, parseInt(input.value, 10));
|
||||
term.setOption(o, o === 'lineHeight' ? parseFloat(input.value) : parseInt(input.value, 10));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "xterm",
|
||||
"description": "Full xterm terminal, in your browser",
|
||||
"version": "3.8.0",
|
||||
"version": "3.9.0",
|
||||
"main": "lib/public/Terminal.js",
|
||||
"types": "typings/xterm.d.ts",
|
||||
"repository": "https://github.com/xtermjs/xterm.js",
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import * as Strings from './Strings';
|
||||
import { ITerminal, IBuffer } from './Types';
|
||||
import { isMac } from './shared/utils/Browser';
|
||||
import { isMac } from './core/Platform';
|
||||
import { RenderDebouncer } from './ui/RenderDebouncer';
|
||||
import { addDisposableDomListener } from './ui/Lifecycle';
|
||||
import { Disposable } from './common/Lifecycle';
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import { assert, expect } from 'chai';
|
||||
import { ITerminal } from './Types';
|
||||
import { Buffer, DEFAULT_ATTR, CHAR_DATA_CHAR_INDEX } from './Buffer';
|
||||
import { CircularList } from './common/CircularList';
|
||||
import { MockTerminal, TestTerminal } from './utils/TestUtils.test';
|
||||
import { MockTerminal, TestTerminal } from './ui/TestUtils.test';
|
||||
import { BufferLine } from './BufferLine';
|
||||
|
||||
const INIT_COLS = 80;
|
||||
|
||||
+4
-4
@@ -7,7 +7,7 @@ import { CircularList } from './common/CircularList';
|
||||
import { CharData, ITerminal, IBuffer, IBufferLine, BufferIndex, IBufferStringIterator, IBufferStringIteratorResult, IBufferLineConstructor } from './Types';
|
||||
import { EventEmitter } from './common/EventEmitter';
|
||||
import { IMarker } from 'xterm';
|
||||
import { BufferLine, BufferLineTypedArray } from './BufferLine';
|
||||
import { BufferLine, BufferLineJSArray } from './BufferLine';
|
||||
import { DEFAULT_COLOR } from './renderer/atlas/Types';
|
||||
|
||||
export const DEFAULT_ATTR = (0 << 18) | (DEFAULT_COLOR << 9) | (256 << 0);
|
||||
@@ -61,9 +61,9 @@ export class Buffer implements IBuffer {
|
||||
}
|
||||
|
||||
public setBufferLineFactory(type: string): void {
|
||||
if (type === 'TypedArray') {
|
||||
if (this._bufferLineConstructor !== BufferLineTypedArray) {
|
||||
this._bufferLineConstructor = BufferLineTypedArray;
|
||||
if (type === 'JsArray') {
|
||||
if (this._bufferLineConstructor !== BufferLineJSArray) {
|
||||
this._bufferLineConstructor = BufferLineJSArray;
|
||||
this._recreateLines();
|
||||
}
|
||||
} else {
|
||||
|
||||
+8
-15
@@ -7,8 +7,10 @@ import { NULL_CELL_CODE, NULL_CELL_WIDTH, NULL_CELL_CHAR, CHAR_DATA_CHAR_INDEX,
|
||||
|
||||
/**
|
||||
* Class representing a terminal line.
|
||||
*
|
||||
* @deprecated to be removed with one of the next releases
|
||||
*/
|
||||
export class BufferLine implements IBufferLine {
|
||||
export class BufferLineJSArray implements IBufferLine {
|
||||
protected _data: CharData[];
|
||||
public isWrapped = false;
|
||||
public length: number;
|
||||
@@ -94,14 +96,14 @@ export class BufferLine implements IBufferLine {
|
||||
}
|
||||
}
|
||||
|
||||
public copyFrom(line: BufferLine): void {
|
||||
public copyFrom(line: BufferLineJSArray): void {
|
||||
this._data = line._data.slice(0);
|
||||
this.length = line.length;
|
||||
this.isWrapped = line.isWrapped;
|
||||
}
|
||||
|
||||
public clone(): IBufferLine {
|
||||
const newLine = new BufferLine(0);
|
||||
const newLine = new BufferLineJSArray(0);
|
||||
newLine.copyFrom(this);
|
||||
return newLine;
|
||||
}
|
||||
@@ -145,17 +147,8 @@ const IS_COMBINED_BIT_MASK = 0x80000000;
|
||||
|
||||
/**
|
||||
* Typed array based bufferline implementation.
|
||||
* Note: Unlike the JS variant the access to the data
|
||||
* via set/get is always a copy action.
|
||||
* Sloppy ref style coding will not work anymore:
|
||||
* line = new BufferLine(10);
|
||||
* char = line.get(0); // char is a copy
|
||||
* char[some_index] = 123; // will not update the line
|
||||
* line.set(0, ch); // do this to update line data
|
||||
* TODO:
|
||||
* - provide getData/setData to directly access the data
|
||||
*/
|
||||
export class BufferLineTypedArray implements IBufferLine {
|
||||
export class BufferLine implements IBufferLine {
|
||||
protected _data: Uint32Array | null = null;
|
||||
protected _combined: {[index: number]: string} = {};
|
||||
public length: number;
|
||||
@@ -274,7 +267,7 @@ export class BufferLineTypedArray implements IBufferLine {
|
||||
}
|
||||
|
||||
/** alter to a full copy of line */
|
||||
public copyFrom(line: BufferLineTypedArray): void {
|
||||
public copyFrom(line: BufferLine): void {
|
||||
if (this.length !== line.length) {
|
||||
this._data = new Uint32Array(line._data);
|
||||
} else {
|
||||
@@ -291,7 +284,7 @@ export class BufferLineTypedArray implements IBufferLine {
|
||||
|
||||
/** create a new clone */
|
||||
public clone(): IBufferLine {
|
||||
const newLine = new BufferLineTypedArray(0);
|
||||
const newLine = new BufferLine(0);
|
||||
// creation of new typed array from another is actually pretty slow :(
|
||||
// still faster than copying values one by one
|
||||
newLine._data = new Uint32Array(this._data);
|
||||
|
||||
@@ -7,7 +7,7 @@ import { assert } from 'chai';
|
||||
import { ITerminal } from './Types';
|
||||
import { BufferSet } from './BufferSet';
|
||||
import { Buffer } from './Buffer';
|
||||
import { MockTerminal } from './utils/TestUtils.test';
|
||||
import { MockTerminal } from './ui/TestUtils.test';
|
||||
|
||||
describe('BufferSet', () => {
|
||||
let terminal: ITerminal;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { TestTerminal } from './utils/TestUtils.test';
|
||||
import { TestTerminal } from './ui/TestUtils.test';
|
||||
import { assert } from 'chai';
|
||||
import { getStringCellWidth, wcwidth } from './CharWidth';
|
||||
import { IBuffer } from './Types';
|
||||
|
||||
@@ -67,7 +67,8 @@ const PRINTABLES = r(0x20, 0x7f);
|
||||
const EXECUTABLES = r(0x00, 0x18);
|
||||
EXECUTABLES.push(0x19);
|
||||
EXECUTABLES.push.apply(EXECUTABLES, r(0x1c, 0x20));
|
||||
const DEFAULT_TRANSITION = ParserAction.ERROR << 4 | ParserState.GROUND;
|
||||
// Pseudo-character placeholder for printable non-ascii characters.
|
||||
const NON_ASCII_PRINTABLE = 0xA0;
|
||||
|
||||
/**
|
||||
* VT500 compatible transition table.
|
||||
@@ -79,10 +80,10 @@ export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
|
||||
const states: number[] = r(ParserState.GROUND, ParserState.DCS_PASSTHROUGH + 1);
|
||||
let state: any;
|
||||
|
||||
// table with default transition [any] --> DEFAULT_TRANSITION
|
||||
// table with default transition
|
||||
for (state in states) {
|
||||
// NOTE: table lookup is capped at 0xa0 in parse to keep the table small
|
||||
for (let code = 0; code < 160; ++code) {
|
||||
for (let code = 0; code <= NON_ASCII_PRINTABLE; ++code) {
|
||||
table.add(code, state, ParserAction.ERROR, ParserState.GROUND);
|
||||
}
|
||||
}
|
||||
@@ -184,6 +185,7 @@ export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
|
||||
table.addMany(PRINTABLES, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);
|
||||
table.add(0x7f, ParserState.DCS_PASSTHROUGH, ParserAction.IGNORE, ParserState.DCS_PASSTHROUGH);
|
||||
table.addMany([0x1b, 0x9c], ParserState.DCS_PASSTHROUGH, ParserAction.DCS_UNHOOK, ParserState.GROUND);
|
||||
table.add(NON_ASCII_PRINTABLE, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);
|
||||
return table;
|
||||
})();
|
||||
|
||||
@@ -391,7 +393,7 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
|
||||
}
|
||||
|
||||
// normal transition & action lookup
|
||||
transition = (code < 0xa0) ? (table[currentState << 8 | code]) : DEFAULT_TRANSITION;
|
||||
transition = table[currentState << 8 | (code < 0xa0 ? code : NON_ASCII_PRINTABLE)];
|
||||
switch (transition >> 4) {
|
||||
case ParserAction.PRINT:
|
||||
print = (~print) ? print : i;
|
||||
@@ -423,10 +425,6 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
|
||||
case ParserState.GROUND:
|
||||
print = (~print) ? print : i;
|
||||
break;
|
||||
case ParserState.OSC_STRING:
|
||||
osc += String.fromCharCode(code);
|
||||
transition |= ParserState.OSC_STRING;
|
||||
break;
|
||||
case ParserState.CSI_IGNORE:
|
||||
transition |= ParserState.CSI_IGNORE;
|
||||
break;
|
||||
@@ -517,7 +515,15 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
|
||||
osc = '';
|
||||
break;
|
||||
case ParserAction.OSC_PUT:
|
||||
osc += data.charAt(i);
|
||||
for (let j = i + 1; ; j++) {
|
||||
if (j >= l
|
||||
|| (code = data.charCodeAt(j)) < 0x20
|
||||
|| (code > 0x7f && code <= 0x9f)) {
|
||||
osc += data.substring(i, j);
|
||||
i = j - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ParserAction.OSC_END:
|
||||
if (osc && code !== 0x18 && code !== 0x1a) {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { assert, expect } from 'chai';
|
||||
import { InputHandler } from './InputHandler';
|
||||
import { MockInputHandlingTerminal } from './utils/TestUtils.test';
|
||||
import { MockInputHandlingTerminal } from './ui/TestUtils.test';
|
||||
import { CHAR_DATA_ATTR_INDEX, DEFAULT_ATTR } from './Buffer';
|
||||
import { Terminal } from './Terminal';
|
||||
import { IBufferLine } from './Types';
|
||||
|
||||
@@ -7,7 +7,7 @@ import { assert } from 'chai';
|
||||
import { IMouseZoneManager, IMouseZone } from './ui/Types';
|
||||
import { ILinkMatcher, ITerminal, IBufferLine } from './Types';
|
||||
import { Linkifier } from './Linkifier';
|
||||
import { MockBuffer, MockTerminal, TestTerminal } from './utils/TestUtils.test';
|
||||
import { MockBuffer, MockTerminal, TestTerminal } from './ui/TestUtils.test';
|
||||
import { CircularList } from './common/CircularList';
|
||||
import { BufferLine } from './BufferLine';
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import { SelectionManager, SelectionMode } from './SelectionManager';
|
||||
import { SelectionModel } from './SelectionModel';
|
||||
import { BufferSet } from './BufferSet';
|
||||
import { ITerminal, IBuffer, IBufferLine } from './Types';
|
||||
import { MockTerminal } from './utils/TestUtils.test';
|
||||
import { MockTerminal } from './ui/TestUtils.test';
|
||||
import { BufferLine } from './BufferLine';
|
||||
|
||||
class TestMockTerminal extends MockTerminal {
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
import { ITerminal, ISelectionManager, IBuffer, CharData, IBufferLine } from './Types';
|
||||
import { XtermListener } from './common/Types';
|
||||
import { MouseHelper } from './utils/MouseHelper';
|
||||
import * as Browser from './shared/utils/Browser';
|
||||
import { MouseHelper } from './ui/MouseHelper';
|
||||
import * as Browser from './core/Platform';
|
||||
import { CharMeasure } from './ui/CharMeasure';
|
||||
import { EventEmitter } from './common/EventEmitter';
|
||||
import { SelectionModel } from './SelectionModel';
|
||||
|
||||
@@ -7,7 +7,7 @@ import { assert } from 'chai';
|
||||
import { ITerminal } from './Types';
|
||||
import { SelectionModel } from './SelectionModel';
|
||||
import { BufferSet } from './BufferSet';
|
||||
import { MockTerminal } from './utils/TestUtils.test';
|
||||
import { MockTerminal } from './ui/TestUtils.test';
|
||||
|
||||
class TestSelectionModel extends SelectionModel {
|
||||
constructor(
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { assert, expect } from 'chai';
|
||||
import { Terminal } from './Terminal';
|
||||
import { MockViewport, MockCompositionHelper, MockRenderer } from './utils/TestUtils.test';
|
||||
import { MockViewport, MockCompositionHelper, MockRenderer } from './ui/TestUtils.test';
|
||||
import { CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, DEFAULT_ATTR } from './Buffer';
|
||||
|
||||
const INIT_COLS = 80;
|
||||
|
||||
+6
-5
@@ -36,11 +36,10 @@ import { Renderer } from './renderer/Renderer';
|
||||
import { Linkifier } from './Linkifier';
|
||||
import { SelectionManager } from './SelectionManager';
|
||||
import { CharMeasure } from './ui/CharMeasure';
|
||||
import * as Browser from './shared/utils/Browser';
|
||||
import * as Browser from './core/Platform';
|
||||
import { addDisposableDomListener } from './ui/Lifecycle';
|
||||
import * as Strings from './Strings';
|
||||
import { MouseHelper } from './utils/MouseHelper';
|
||||
import { clone } from './utils/Clone';
|
||||
import { MouseHelper } from './ui/MouseHelper';
|
||||
import { DEFAULT_BELL_SOUND, SoundManager } from './SoundManager';
|
||||
import { DEFAULT_ANSI_COLORS } from './renderer/ColorManager';
|
||||
import { MouseZoneManager } from './ui/MouseZoneManager';
|
||||
@@ -52,6 +51,7 @@ import { DomRenderer } from './renderer/dom/DomRenderer';
|
||||
import { IKeyboardEvent } from './common/Types';
|
||||
import { evaluateKeyboardEvent } from './core/input/Keyboard';
|
||||
import { KeyboardResultType, ICharset } from './core/Types';
|
||||
import { clone } from './common/Clone';
|
||||
|
||||
// Let it work inside Node.js for automated testing purposes.
|
||||
const document = (typeof window !== 'undefined') ? window.document : null;
|
||||
@@ -106,7 +106,7 @@ const DEFAULT_OPTIONS: ITerminalOptions = {
|
||||
theme: null,
|
||||
rightClickSelectsWord: Browser.isMac,
|
||||
rendererType: 'canvas',
|
||||
experimentalBufferLineImpl: 'JsArray'
|
||||
experimentalBufferLineImpl: 'TypedArray'
|
||||
};
|
||||
|
||||
export class Terminal extends EventEmitter implements ITerminal, IDisposable, IInputHandlingTerminal {
|
||||
@@ -464,6 +464,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
|
||||
this.renderer.onResize(this.cols, this.rows);
|
||||
this.refresh(0, this.rows - 1);
|
||||
}
|
||||
break;
|
||||
case 'rendererType':
|
||||
if (this.renderer) {
|
||||
this.unregister(this.renderer);
|
||||
@@ -1179,7 +1180,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
|
||||
*/
|
||||
public scroll(isWrapped: boolean = false): void {
|
||||
let newLine: IBufferLine;
|
||||
const useRecycling = this.options.experimentalBufferLineImpl === 'TypedArray';
|
||||
const useRecycling = this.options.experimentalBufferLineImpl !== 'JsArray';
|
||||
if (useRecycling) {
|
||||
newLine = this._blankLine;
|
||||
if (!newLine || newLine.length !== this.cols || newLine.get(0)[CHAR_DATA_ATTR_INDEX] !== this.eraseAttr()) {
|
||||
|
||||
+1
-1
@@ -245,7 +245,7 @@ export interface ILinkifierAccessor {
|
||||
}
|
||||
|
||||
export interface IMouseHelper {
|
||||
getCoords(event: { pageX: number, pageY: number }, element: HTMLElement, charMeasure: ICharMeasure, colCount: number, rowCount: number, isSelection?: boolean): [number, number];
|
||||
getCoords(event: { clientX: number, clientY: number }, element: HTMLElement, charMeasure: ICharMeasure, colCount: number, rowCount: number, isSelection?: boolean): [number, number];
|
||||
getRawByteCoords(event: MouseEvent, element: HTMLElement, charMeasure: ICharMeasure, colCount: number, rowCount: number): { x: number, y: number };
|
||||
}
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ describe('clone', () => {
|
||||
test.a.b.c.d.e.f = 'bar';
|
||||
|
||||
// The values at a greater depth then 5 should not be cloned
|
||||
assert.equal(cloned.a.b.c.d.e.f, 'bar');
|
||||
assert.equal((cloned as any).a.b.c.d.e.f, 'bar');
|
||||
});
|
||||
|
||||
it('should allow an optional maximum depth to be set', () => {
|
||||
@@ -118,7 +118,7 @@ describe('clone', () => {
|
||||
test.a.b.c = 'bar';
|
||||
|
||||
// The values at a greater depth then 2 should not be cloned
|
||||
assert.equal(cloned.a.b.c, 'bar');
|
||||
assert.equal((cloned as any).a.b.c, 'bar');
|
||||
});
|
||||
|
||||
it('should not throw when cloning a recursive reference', () => {
|
||||
@@ -6,7 +6,7 @@
|
||||
/*
|
||||
* A simple utility for cloning values
|
||||
*/
|
||||
export const clone = <T>(val: T, depth: number = 5): T => {
|
||||
export function clone<T>(val: T, depth: number = 5): T | null {
|
||||
if (typeof val !== 'object') {
|
||||
return val;
|
||||
}
|
||||
@@ -25,4 +25,4 @@ export const clone = <T>(val: T, depth: number = 5): T => {
|
||||
}
|
||||
|
||||
return clonedObject as T;
|
||||
};
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user