Merge pull request #2239 from Tyriar/charjoiner_layer

Move some parts of renderer to browser
This commit is contained in:
Daniel Imms
2019-06-16 00:12:55 -07:00
committed by GitHub
18 changed files with 67 additions and 78 deletions
+1 -1
View File
@@ -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}"`);
}
}
@@ -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', () => {
@@ -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;
}
}
}
+11
View File
@@ -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 {
@@ -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>'
@@ -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}`);
+1 -1
View File
@@ -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';
+1 -1
View File
@@ -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';
+3 -3
View File
@@ -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 -4
View File
@@ -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';
+1 -12
View File
@@ -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][];
}
+2 -2
View File
@@ -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';
+6 -4
View File
@@ -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);