mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Merge pull request #2239 from Tyriar/charjoiner_layer
Move some parts of renderer to browser
This commit is contained in:
+1
-1
@@ -691,7 +691,7 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp
|
||||
private _createRenderer(): IRenderer {
|
||||
switch (this.options.rendererType) {
|
||||
case 'canvas': return new Renderer(this, this._colorManager.colors, this._charSizeService); break;
|
||||
case 'dom': return new DomRenderer(this, this._colorManager.colors, this._charSizeService); break;
|
||||
case 'dom': return new DomRenderer(this, this._colorManager.colors, this._charSizeService, this.optionsService); break;
|
||||
default: throw new Error(`Unrecognized rendererType "${this.options.rendererType}"`);
|
||||
}
|
||||
}
|
||||
|
||||
+7
-14
@@ -4,24 +4,19 @@
|
||||
*/
|
||||
|
||||
import { assert } from 'chai';
|
||||
|
||||
import { MockTerminal, MockBuffer } from '../TestUtils.test';
|
||||
import { CircularList } from 'common/CircularList';
|
||||
|
||||
import { ICharacterJoinerRegistry } from './Types';
|
||||
import { CharacterJoinerRegistry } from './CharacterJoinerRegistry';
|
||||
import { ICharacterJoinerRegistry } from 'browser/renderer/Types';
|
||||
import { CharacterJoinerRegistry } from 'browser/renderer/CharacterJoinerRegistry';
|
||||
import { BufferLine } from 'common/buffer/BufferLine';
|
||||
import { IBufferLine } from 'common/Types';
|
||||
import { CellData } from 'common/buffer/CellData';
|
||||
import { MockBufferService } from 'common/TestUtils.test';
|
||||
|
||||
describe('CharacterJoinerRegistry', () => {
|
||||
let registry: ICharacterJoinerRegistry;
|
||||
|
||||
beforeEach(() => {
|
||||
const terminal = new MockTerminal();
|
||||
terminal.cols = 16;
|
||||
terminal.buffer = new MockBuffer();
|
||||
const lines = new CircularList<IBufferLine>(7);
|
||||
const bufferService = new MockBufferService(16, 10);
|
||||
const lines = bufferService.buffer.lines;
|
||||
lines.set(0, lineData([['a -> b -> c -> d']]));
|
||||
lines.set(1, lineData([['a -> b => c -> d']]));
|
||||
lines.set(2, lineData([['a -> b -', 0xFFFFFFFF], ['> c -> d', 0]]));
|
||||
@@ -31,7 +26,7 @@ describe('CharacterJoinerRegistry', () => {
|
||||
lines.set(5, lineData([['a', 0x11111111], [' -> b -> c -> '], ['d', 0x22222222]]));
|
||||
const line6 = lineData([['wi']]);
|
||||
line6.resize(line6.length + 1, CellData.fromCharData([0, '¥', 2, '¥'.charCodeAt(0)]));
|
||||
line6.resize(line6.length + 1, CellData.fromCharData([0, '', 0, null]));
|
||||
line6.resize(line6.length + 1, CellData.fromCharData([0, '', 0, 0]));
|
||||
let sub = lineData([['deemo']]);
|
||||
let oldSize = line6.length;
|
||||
line6.resize(oldSize + sub.length, CellData.fromCharData([0, '', 0, 0]));
|
||||
@@ -44,9 +39,7 @@ describe('CharacterJoinerRegistry', () => {
|
||||
for (let i = 0; i < sub.length; ++i) line6.setCell(i + oldSize, sub.loadCell(i, new CellData()));
|
||||
lines.set(6, line6);
|
||||
|
||||
(<MockBuffer>terminal.buffer).setLines(lines);
|
||||
terminal.buffer.ydisp = 0;
|
||||
registry = new CharacterJoinerRegistry(terminal);
|
||||
registry = new CharacterJoinerRegistry(bufferService);
|
||||
});
|
||||
|
||||
it('has no joiners upon creation', () => {
|
||||
+8
-9
@@ -3,12 +3,12 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { ITerminal } from '../Types';
|
||||
import { IBufferLine, ICellData, CharData } from 'common/Types';
|
||||
import { ICharacterJoinerRegistry, ICharacterJoiner } from './Types';
|
||||
import { ICharacterJoinerRegistry, ICharacterJoiner } from 'browser/renderer/Types';
|
||||
import { AttributeData } from 'common/buffer/AttributeData';
|
||||
import { WHITESPACE_CELL_CHAR, Content } from 'common/buffer/Constants';
|
||||
import { CellData } from 'common/buffer/CellData';
|
||||
import { IBufferService } from 'common/services/Services';
|
||||
|
||||
export class JoinedCellData extends AttributeData implements ICellData {
|
||||
private _width: number;
|
||||
@@ -61,8 +61,7 @@ export class CharacterJoinerRegistry implements ICharacterJoinerRegistry {
|
||||
private _nextCharacterJoinerId: number = 0;
|
||||
private _workCell: CellData = new CellData();
|
||||
|
||||
constructor(private _terminal: ITerminal) {
|
||||
}
|
||||
constructor(private _bufferService: IBufferService) { }
|
||||
|
||||
public registerCharacterJoiner(handler: (text: string) => [number, number][]): number {
|
||||
const joiner: ICharacterJoiner = {
|
||||
@@ -90,8 +89,8 @@ export class CharacterJoinerRegistry implements ICharacterJoinerRegistry {
|
||||
return [];
|
||||
}
|
||||
|
||||
const line = this._terminal.buffer.lines.get(row);
|
||||
if (line.length === 0) {
|
||||
const line = this._bufferService.buffer.lines.get(row);
|
||||
if (!line || line.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -144,7 +143,7 @@ export class CharacterJoinerRegistry implements ICharacterJoinerRegistry {
|
||||
}
|
||||
|
||||
// Process any trailing ranges.
|
||||
if (this._terminal.cols - rangeStartColumn > 1) {
|
||||
if (this._bufferService.cols - rangeStartColumn > 1) {
|
||||
const joinedRanges = this._getJoinedRanges(
|
||||
lineStr,
|
||||
rangeStartStringIndex,
|
||||
@@ -204,7 +203,7 @@ export class CharacterJoinerRegistry implements ICharacterJoinerRegistry {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let x = startCol; x < this._terminal.cols; x++) {
|
||||
for (let x = startCol; x < this._bufferService.cols; x++) {
|
||||
const width = line.getWidth(x);
|
||||
const length = line.getString(x).length || WHITESPACE_CELL_CHAR.length;
|
||||
|
||||
@@ -252,7 +251,7 @@ export class CharacterJoinerRegistry implements ICharacterJoinerRegistry {
|
||||
// If there is still a range left at the end, it must extend all the way to
|
||||
// the end of the line.
|
||||
if (currentRange) {
|
||||
currentRange[1] = this._terminal.cols;
|
||||
currentRange[1] = this._bufferService.cols;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
import { assert } from 'chai';
|
||||
import { GridCache } from './GridCache';
|
||||
import { GridCache } from 'browser/renderer/GridCache';
|
||||
|
||||
describe('GridCache', () => {
|
||||
let grid: GridCache<number>;
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
export class GridCache<T> {
|
||||
public cache: T[][];
|
||||
public cache: (T | undefined)[][];
|
||||
|
||||
public constructor() {
|
||||
this.cache = [];
|
||||
@@ -16,7 +16,7 @@ export class GridCache<T> {
|
||||
this.cache.push([]);
|
||||
}
|
||||
for (let y = this.cache[x].length; y < height; y++) {
|
||||
this.cache[x].push(null);
|
||||
this.cache[x].push(undefined);
|
||||
}
|
||||
this.cache[x].length = height;
|
||||
}
|
||||
@@ -26,7 +26,7 @@ export class GridCache<T> {
|
||||
public clear(): void {
|
||||
for (let x = 0; x < this.cache.length; x++) {
|
||||
for (let y = 0; y < this.cache[x].length; y++) {
|
||||
this.cache[x][y] = null;
|
||||
this.cache[x][y] = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
+11
@@ -45,3 +45,14 @@ export interface IRenderer extends IDisposable {
|
||||
registerCharacterJoiner(handler: CharacterJoinerHandler): number;
|
||||
deregisterCharacterJoiner(joinerId: number): boolean;
|
||||
}
|
||||
|
||||
export interface ICharacterJoiner {
|
||||
id: number;
|
||||
handler: CharacterJoinerHandler;
|
||||
}
|
||||
|
||||
export interface ICharacterJoinerRegistry {
|
||||
registerCharacterJoiner(handler: (text: string) => [number, number][]): number;
|
||||
deregisterCharacterJoiner(joinerId: number): boolean;
|
||||
getJoinedCharacters(row: number): [number, number][];
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
import { assert } from 'chai';
|
||||
import { LRUMap } from './LRUMap';
|
||||
import { LRUMap } from 'browser/renderer/atlas/LRUMap';
|
||||
|
||||
describe('LRUMap', () => {
|
||||
it('can be used to store and retrieve values', () => {
|
||||
@@ -4,16 +4,16 @@
|
||||
*/
|
||||
|
||||
interface ILinkedListNode<T> {
|
||||
prev: ILinkedListNode<T>;
|
||||
next: ILinkedListNode<T>;
|
||||
key: number;
|
||||
value: T;
|
||||
prev: ILinkedListNode<T> | null;
|
||||
next: ILinkedListNode<T> | null;
|
||||
key: number | null;
|
||||
value: T | null;
|
||||
}
|
||||
|
||||
export class LRUMap<T> {
|
||||
private _map: { [key: number]: ILinkedListNode<T> } = {};
|
||||
private _head: ILinkedListNode<T> = null;
|
||||
private _tail: ILinkedListNode<T> = null;
|
||||
private _head: ILinkedListNode<T> | null = null;
|
||||
private _tail: ILinkedListNode<T> | null = null;
|
||||
private _nodePool: ILinkedListNode<T>[] = [];
|
||||
public size: number = 0;
|
||||
|
||||
@@ -106,9 +106,9 @@ export class LRUMap<T> {
|
||||
node.value = value;
|
||||
} else if (this.size >= this.capacity) {
|
||||
// we're out of space: recycle the head node, move it to the tail
|
||||
node = this._head;
|
||||
node = this._head!;
|
||||
this._unlinkNode(node);
|
||||
delete this._map[node.key];
|
||||
delete this._map[node.key!];
|
||||
node.key = key;
|
||||
node.value = value;
|
||||
this._map[key] = node;
|
||||
@@ -117,7 +117,7 @@ export class LRUMap<T> {
|
||||
const nodePool = this._nodePool;
|
||||
if (nodePool.length > 0) {
|
||||
// use a preallocated node if we can
|
||||
node = nodePool.pop();
|
||||
node = nodePool.pop()!;
|
||||
node.key = key;
|
||||
node.value = value;
|
||||
} else {
|
||||
+4
-8
@@ -5,25 +5,21 @@
|
||||
|
||||
import jsdom = require('jsdom');
|
||||
import { assert } from 'chai';
|
||||
import { DomRendererRowFactory } from './DomRendererRowFactory';
|
||||
import { DomRendererRowFactory } from 'browser/renderer/dom/DomRendererRowFactory';
|
||||
import { NULL_CELL_CODE, NULL_CELL_WIDTH, NULL_CELL_CHAR, DEFAULT_ATTR, FgFlags, BgFlags, Attributes } from 'common/buffer/Constants';
|
||||
import { BufferLine, DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine';
|
||||
import { ITerminalOptions } from '../../Types';
|
||||
import { IBufferLine } from 'common/Types';
|
||||
import { CellData } from 'common/buffer/CellData';
|
||||
import { MockOptionsService } from 'common/TestUtils.test';
|
||||
|
||||
describe('DomRendererRowFactory', () => {
|
||||
let dom: jsdom.JSDOM;
|
||||
const options: ITerminalOptions = {};
|
||||
let rowFactory: DomRendererRowFactory;
|
||||
let lineData: IBufferLine;
|
||||
|
||||
beforeEach(() => {
|
||||
dom = new jsdom.JSDOM('');
|
||||
|
||||
options.drawBoldTextInBrightColors = true;
|
||||
|
||||
rowFactory = new DomRendererRowFactory(options, dom.window.document);
|
||||
rowFactory = new DomRendererRowFactory(dom.window.document, new MockOptionsService({ drawBoldTextInBrightColors: true }));
|
||||
lineData = createEmptyLineData(2);
|
||||
});
|
||||
|
||||
@@ -38,7 +34,7 @@ describe('DomRendererRowFactory', () => {
|
||||
it('should set correct attributes for double width characters', () => {
|
||||
lineData.setCell(0, CellData.fromCharData([DEFAULT_ATTR, '語', 2, '語'.charCodeAt(0)]));
|
||||
// There should be no element for the following "empty" cell
|
||||
lineData.setCell(1, CellData.fromCharData([DEFAULT_ATTR, '', 0, undefined]));
|
||||
lineData.setCell(1, CellData.fromCharData([DEFAULT_ATTR, '', 0, 0]));
|
||||
const fragment = rowFactory.createRow(lineData, false, undefined, 0, false, 5, 20);
|
||||
assert.equal(getFragmentHtml(fragment),
|
||||
'<span style="width: 10px;">語</span>'
|
||||
+5
-5
@@ -3,12 +3,12 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { ITerminalOptions } from '../../Types';
|
||||
import { IBufferLine } from 'common/Types';
|
||||
import { INVERTED_DEFAULT_COLOR } from '../atlas/Constants';
|
||||
import { INVERTED_DEFAULT_COLOR } from 'browser/renderer/atlas/Constants';
|
||||
import { AttributeData } from 'common/buffer/AttributeData';
|
||||
import { NULL_CELL_CODE, WHITESPACE_CELL_CHAR } from 'common/buffer/Constants';
|
||||
import { CellData } from 'common/buffer/CellData';
|
||||
import { ITerminalOptions, IOptionsService } from 'common/services/Services';
|
||||
|
||||
export const BOLD_CLASS = 'xterm-bold';
|
||||
export const DIM_CLASS = 'xterm-dim';
|
||||
@@ -24,8 +24,8 @@ export class DomRendererRowFactory {
|
||||
private _workCell: CellData = new CellData();
|
||||
|
||||
constructor(
|
||||
private _terminalOptions: ITerminalOptions,
|
||||
private _document: Document
|
||||
private _document: Document,
|
||||
private _optionsService: IOptionsService
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ export class DomRendererRowFactory {
|
||||
charElement.setAttribute('style', style);
|
||||
} else if (this._workCell.isFgPalette()) {
|
||||
let fg = this._workCell.getFgColor();
|
||||
if (this._workCell.isBold() && fg < 8 && !swapColor && this._terminalOptions.drawBoldTextInBrightColors) {
|
||||
if (this._workCell.isBold() && fg < 8 && !swapColor && this._optionsService.options.drawBoldTextInBrightColors) {
|
||||
fg += 8;
|
||||
}
|
||||
charElement.classList.add(`xterm-${swapColor ? 'b' : 'f'}g-${fg}`);
|
||||
@@ -9,7 +9,7 @@ import { ITerminal } from '../Types';
|
||||
import { ICellData } from 'common/Types';
|
||||
import { DEFAULT_COLOR, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_CODE } from 'common/buffer/Constants';
|
||||
import { IGlyphIdentifier } from './atlas/Types';
|
||||
import { DIM_OPACITY, INVERTED_DEFAULT_COLOR } from './atlas/Constants';
|
||||
import { DIM_OPACITY, INVERTED_DEFAULT_COLOR } from 'browser/renderer/atlas/Constants';
|
||||
import { BaseCharAtlas } from './atlas/BaseCharAtlas';
|
||||
import { acquireCharAtlas } from './atlas/CharAtlasCache';
|
||||
import { AttributeData } from 'common/buffer/AttributeData';
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { ILinkifierEvent, ITerminal, ILinkifierAccessor } from '../Types';
|
||||
import { IRenderDimensions } from 'browser/renderer/Types';
|
||||
import { BaseRenderLayer } from './BaseRenderLayer';
|
||||
import { INVERTED_DEFAULT_COLOR } from './atlas/Constants';
|
||||
import { INVERTED_DEFAULT_COLOR } from 'browser/renderer/atlas/Constants';
|
||||
import { is256Color } from './atlas/CharAtlasUtils';
|
||||
import { IColorSet } from 'browser/Types';
|
||||
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
import { TextRenderLayer } from './TextRenderLayer';
|
||||
import { SelectionRenderLayer } from './SelectionRenderLayer';
|
||||
import { CursorRenderLayer } from './CursorRenderLayer';
|
||||
import { IRenderLayer, ICharacterJoinerRegistry } from './Types';
|
||||
import { IRenderer, IRenderDimensions, CharacterJoinerHandler } from 'browser/renderer/Types';
|
||||
import { IRenderLayer } from './Types';
|
||||
import { IRenderer, IRenderDimensions, CharacterJoinerHandler, ICharacterJoinerRegistry } from 'browser/renderer/Types';
|
||||
import { ITerminal } from '../Types';
|
||||
import { LinkRenderLayer } from './LinkRenderLayer';
|
||||
import { CharacterJoinerRegistry } from '../renderer/CharacterJoinerRegistry';
|
||||
import { CharacterJoinerRegistry } from 'browser/renderer/CharacterJoinerRegistry';
|
||||
import { Disposable } from 'common/Lifecycle';
|
||||
import { IColorSet } from 'browser/Types';
|
||||
import { ICharSizeService } from 'browser/services/Services';
|
||||
|
||||
@@ -3,15 +3,14 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { ICharacterJoinerRegistry } from './Types';
|
||||
import { IRenderDimensions } from 'browser/renderer/Types';
|
||||
import { ICharacterJoinerRegistry, IRenderDimensions } from 'browser/renderer/Types';
|
||||
import { ITerminal } from '../Types';
|
||||
import { CharData, ICellData } from 'common/Types';
|
||||
import { GridCache } from './GridCache';
|
||||
import { GridCache } from 'browser/renderer/GridCache';
|
||||
import { BaseRenderLayer } from './BaseRenderLayer';
|
||||
import { AttributeData } from 'common/buffer/AttributeData';
|
||||
import { NULL_CELL_CODE, Content } from 'common/buffer/Constants';
|
||||
import { JoinedCellData } from './CharacterJoinerRegistry';
|
||||
import { JoinedCellData } from 'browser/renderer/CharacterJoinerRegistry';
|
||||
import { IColorSet } from 'browser/Types';
|
||||
import { CellData } from 'common/buffer/CellData';
|
||||
|
||||
|
||||
Vendored
+1
-12
@@ -6,7 +6,7 @@
|
||||
import { ITerminal } from '../Types';
|
||||
import { IDisposable } from 'xterm';
|
||||
import { IColorSet } from 'browser/Types';
|
||||
import { IRenderDimensions, CharacterJoinerHandler } from 'browser/renderer/Types';
|
||||
import { IRenderDimensions, CharacterJoinerHandler, ICharacterJoiner } from 'browser/renderer/Types';
|
||||
|
||||
export interface IRenderLayer extends IDisposable {
|
||||
/**
|
||||
@@ -65,14 +65,3 @@ export interface IRenderLayer extends IDisposable {
|
||||
*/
|
||||
reset(terminal: ITerminal): void;
|
||||
}
|
||||
|
||||
export interface ICharacterJoiner {
|
||||
id: number;
|
||||
handler: CharacterJoinerHandler;
|
||||
}
|
||||
|
||||
export interface ICharacterJoinerRegistry {
|
||||
registerCharacterJoiner(handler: (text: string) => [number, number][]): number;
|
||||
deregisterCharacterJoiner(joinerId: number): boolean;
|
||||
getJoinedCharacters(row: number): [number, number][];
|
||||
}
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
*/
|
||||
|
||||
import { IGlyphIdentifier, ICharAtlasConfig } from './Types';
|
||||
import { DIM_OPACITY, INVERTED_DEFAULT_COLOR } from './Constants';
|
||||
import { DIM_OPACITY, INVERTED_DEFAULT_COLOR } from 'browser/renderer/atlas/Constants';
|
||||
import { BaseCharAtlas } from './BaseCharAtlas';
|
||||
import { DEFAULT_ANSI_COLORS } from 'browser/ColorManager';
|
||||
import { LRUMap } from './LRUMap';
|
||||
import { LRUMap } from 'browser/renderer/atlas/LRUMap';
|
||||
import { isFirefox, isSafari } from 'common/Platform';
|
||||
import { IColor } from 'browser/Types';
|
||||
|
||||
|
||||
@@ -5,11 +5,12 @@
|
||||
|
||||
import { IRenderer, IRenderDimensions, CharacterJoinerHandler } from 'browser/renderer/Types';
|
||||
import { ILinkifierEvent, ITerminal } from '../../Types';
|
||||
import { BOLD_CLASS, ITALIC_CLASS, CURSOR_CLASS, CURSOR_STYLE_BLOCK_CLASS, CURSOR_BLINK_CLASS, CURSOR_STYLE_BAR_CLASS, CURSOR_STYLE_UNDERLINE_CLASS, DomRendererRowFactory } from './DomRendererRowFactory';
|
||||
import { INVERTED_DEFAULT_COLOR } from '../atlas/Constants';
|
||||
import { BOLD_CLASS, ITALIC_CLASS, CURSOR_CLASS, CURSOR_STYLE_BLOCK_CLASS, CURSOR_BLINK_CLASS, CURSOR_STYLE_BAR_CLASS, CURSOR_STYLE_UNDERLINE_CLASS, DomRendererRowFactory } from 'browser/renderer/dom/DomRendererRowFactory';
|
||||
import { INVERTED_DEFAULT_COLOR } from 'browser/renderer/atlas/Constants';
|
||||
import { Disposable } from 'common/Lifecycle';
|
||||
import { IColorSet } from 'browser/Types';
|
||||
import { ICharSizeService } from 'browser/services/Services';
|
||||
import { IOptionsService } from 'common/services/Services';
|
||||
|
||||
const TERMINAL_CLASS_PREFIX = 'xterm-dom-renderer-owner-';
|
||||
const ROW_CONTAINER_CLASS = 'xterm-rows';
|
||||
@@ -43,7 +44,8 @@ export class DomRenderer extends Disposable implements IRenderer {
|
||||
constructor(
|
||||
private _terminal: ITerminal,
|
||||
private _colors: IColorSet,
|
||||
private _charSizeService: ICharSizeService
|
||||
private _charSizeService: ICharSizeService,
|
||||
private _optionsService: IOptionsService
|
||||
) {
|
||||
super();
|
||||
|
||||
@@ -73,7 +75,7 @@ export class DomRenderer extends Disposable implements IRenderer {
|
||||
this._updateDimensions();
|
||||
this._injectCss();
|
||||
|
||||
this._rowFactory = new DomRendererRowFactory(_terminal.options, document);
|
||||
this._rowFactory = new DomRendererRowFactory(document, this._optionsService);
|
||||
|
||||
this._terminal.element.classList.add(TERMINAL_CLASS_PREFIX + this._terminalClass);
|
||||
this._terminal.screenElement.appendChild(this._rowContainer);
|
||||
|
||||
Reference in New Issue
Block a user