Skip to content

Commit 367eb45

Browse files
authored
Merge pull request #3284 from Tyriar/tyriar/charJoinerService
Convert CharacterJoinerRegistry to a service
2 parents 233b78d + 1124f8b commit 367eb45

14 files changed

+145
-173
lines changed

src/browser/Terminal.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
* http://linux.die.net/man/7/urxvt
2222
*/
2323

24-
import { ICompositionHelper, ITerminal, IBrowser, CustomKeyEventHandler, ILinkifier, IMouseZoneManager, LinkMatcherHandler, ILinkMatcherOptions, IViewport, ILinkifier2 } from 'browser/Types';
25-
import { IRenderer, CharacterJoinerHandler } from 'browser/renderer/Types';
24+
import { ICompositionHelper, ITerminal, IBrowser, CustomKeyEventHandler, ILinkifier, IMouseZoneManager, LinkMatcherHandler, ILinkMatcherOptions, IViewport, ILinkifier2, CharacterJoinerHandler } from 'browser/Types';
25+
import { IRenderer } from 'browser/renderer/Types';
2626
import { CompositionHelper } from 'browser/input/CompositionHelper';
2727
import { Viewport } from 'browser/Viewport';
2828
import { rightClickHandler, moveTextAreaUnderMouseCursor, handlePasteEvent, copyHandler, paste } from 'browser/Clipboard';
@@ -45,7 +45,7 @@ import { EventEmitter, IEvent, forwardEvent } from 'common/EventEmitter';
4545
import { DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine';
4646
import { ColorManager } from 'browser/ColorManager';
4747
import { RenderService } from 'browser/services/RenderService';
48-
import { ICharSizeService, IRenderService, IMouseService, ISelectionService, ISoundService, ICoreBrowserService } from 'browser/services/Services';
48+
import { ICharSizeService, IRenderService, IMouseService, ISelectionService, ISoundService, ICoreBrowserService, ICharacterJoinerService } from 'browser/services/Services';
4949
import { CharSizeService } from 'browser/services/CharSizeService';
5050
import { IBuffer } from 'common/buffer/Types';
5151
import { MouseService } from 'browser/services/MouseService';
@@ -54,6 +54,7 @@ import { CoreBrowserService } from 'browser/services/CoreBrowserService';
5454
import { CoreTerminal } from 'common/CoreTerminal';
5555
import { ITerminalOptions as IInitializedTerminalOptions } from 'common/services/Services';
5656
import { rgba } from 'browser/Color';
57+
import { CharacterJoinerService } from 'browser/services/CharacterJoinerService';
5758

5859
// Let it work inside Node.js for automated testing purposes.
5960
const document: Document = (typeof window !== 'undefined') ? window.document : null as any;
@@ -82,6 +83,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
8283
private _charSizeService: ICharSizeService | undefined;
8384
private _mouseService: IMouseService | undefined;
8485
private _renderService: IRenderService | undefined;
86+
private _characterJoinerService: ICharacterJoinerService | undefined;
8587
private _selectionService: ISelectionService | undefined;
8688
private _soundService: ISoundService | undefined;
8789

@@ -449,6 +451,9 @@ export class Terminal extends CoreTerminal implements ITerminal {
449451
this.register(this.optionsService.onOptionChange(e => this._colorManager!.onOptionsChange(e)));
450452
this._colorManager.setTheme(this._theme);
451453

454+
this._characterJoinerService = this._instantiationService.createInstance(CharacterJoinerService);
455+
this._instantiationService.setService(ICharacterJoinerService, this._characterJoinerService);
456+
452457
const renderer = this._createRenderer();
453458
this._renderService = this.register(this._instantiationService.createInstance(RenderService, renderer, this.rows, this.screenElement));
454459
this._instantiationService.setService(IRenderService, this._renderService);
@@ -550,7 +555,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
550555

551556
private _createRenderer(): IRenderer {
552557
switch (this.options.rendererType) {
553-
case 'canvas': return this._instantiationService.createInstance(Renderer, this._colorManager!.colors, this.screenElement!, this.linkifier, this.linkifier2);
558+
case 'canvas': return this._instantiationService.createInstance(Renderer, this._colorManager!.colors, this.screenElement!, this.linkifier, this.linkifier2, this._instantiationService);
554559
case 'dom': return this._instantiationService.createInstance(DomRenderer, this._colorManager!.colors, this.element!, this.screenElement!, this._viewportElement!, this.linkifier, this.linkifier2);
555560
default: throw new Error(`Unrecognized rendererType "${this.options.rendererType}"`);
556561
}
@@ -914,13 +919,19 @@ export class Terminal extends CoreTerminal implements ITerminal {
914919
}
915920

916921
public registerCharacterJoiner(handler: CharacterJoinerHandler): number {
917-
const joinerId = this._renderService!.registerCharacterJoiner(handler);
922+
if (!this._characterJoinerService) {
923+
throw new Error('Terminal must be opened first');
924+
}
925+
const joinerId = this._characterJoinerService.register(handler);
918926
this.refresh(0, this.rows - 1);
919927
return joinerId;
920928
}
921929

922930
public deregisterCharacterJoiner(joinerId: number): void {
923-
if (this._renderService!.deregisterCharacterJoiner(joinerId)) {
931+
if (!this._characterJoinerService) {
932+
throw new Error('Terminal must be opened first');
933+
}
934+
if (this._characterJoinerService.deregister(joinerId)) {
924935
this.refresh(0, this.rows - 1);
925936
}
926937
}

src/browser/TestUtils.test.ts

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
import { IDisposable, IMarker, ISelectionPosition, ILinkProvider } from 'xterm';
77
import { IEvent, EventEmitter } from 'common/EventEmitter';
88
import { ICharSizeService, IMouseService, IRenderService, ISelectionService } from 'browser/services/Services';
9-
import { IRenderDimensions, IRenderer, CharacterJoinerHandler, IRequestRedrawEvent } from 'browser/renderer/Types';
10-
import { IColorSet, ILinkMatcherOptions, ITerminal, ILinkifier, ILinkifier2, IBrowser, IViewport, IColorManager, ICompositionHelper } from 'browser/Types';
9+
import { IRenderDimensions, IRenderer, IRequestRedrawEvent } from 'browser/renderer/Types';
10+
import { IColorSet, ILinkMatcherOptions, ITerminal, ILinkifier, ILinkifier2, IBrowser, IViewport, IColorManager, ICompositionHelper, CharacterJoinerHandler } from 'browser/Types';
1111
import { IBuffer, IBufferStringIterator, IBufferSet } from 'common/buffer/Types';
1212
import { IBufferLine, ICellData, IAttributeData, ICircularList, XtermListener, ICharset, ITerminalOptions } from 'common/Types';
1313
import { Buffer } from 'common/buffer/Buffer';
@@ -284,8 +284,6 @@ export class MockRenderer implements IRenderer {
284284
public onDevicePixelRatioChange(): void { }
285285
public clear(): void { }
286286
public renderRows(start: number, end: number): void { }
287-
public registerCharacterJoiner(handler: CharacterJoinerHandler): number { return 0; }
288-
public deregisterCharacterJoiner(): boolean { return true; }
289287
}
290288

291289
export class MockViewport implements IViewport {
@@ -409,12 +407,6 @@ export class MockRenderService implements IRenderService {
409407
public clear(): void {
410408
throw new Error('Method not implemented.');
411409
}
412-
public registerCharacterJoiner(handler: CharacterJoinerHandler): number {
413-
throw new Error('Method not implemented.');
414-
}
415-
public deregisterCharacterJoiner(joinerId: number): boolean {
416-
throw new Error('Method not implemented.');
417-
}
418410
public dispose(): void {
419411
throw new Error('Method not implemented.');
420412
}

src/browser/Types.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,3 +302,10 @@ interface IBufferCellPosition {
302302
x: number;
303303
y: number;
304304
}
305+
306+
export type CharacterJoinerHandler = (text: string) => [number, number][];
307+
308+
export interface ICharacterJoiner {
309+
id: number;
310+
handler: CharacterJoinerHandler;
311+
}

src/browser/renderer/CursorRenderLayer.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@ export class CursorRenderLayer extends BaseRenderLayer {
3737
colors: IColorSet,
3838
rendererId: number,
3939
private _onRequestRedraw: IEventEmitter<IRequestRedrawEvent>,
40-
bufferService: IBufferService,
41-
optionsService: IOptionsService,
42-
private readonly _coreService: ICoreService,
43-
private readonly _coreBrowserService: ICoreBrowserService
40+
@IBufferService bufferService: IBufferService,
41+
@IOptionsService optionsService: IOptionsService,
42+
@ICoreService private readonly _coreService: ICoreService,
43+
@ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService
4444
) {
4545
super(container, 'cursor', zIndex, true, colors, rendererId, bufferService, optionsService);
4646
this._state = {

src/browser/renderer/LinkRenderLayer.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ export class LinkRenderLayer extends BaseRenderLayer {
2020
rendererId: number,
2121
linkifier: ILinkifier,
2222
linkifier2: ILinkifier2,
23-
bufferService: IBufferService,
24-
optionsService: IOptionsService
23+
@IBufferService bufferService: IBufferService,
24+
@IOptionsService optionsService: IOptionsService
2525
) {
2626
super(container, 'link', zIndex, true, colors, rendererId, bufferService, optionsService);
2727
linkifier.onShowLinkUnderline(e => this._onShowLinkUnderline(e));

src/browser/renderer/Renderer.ts

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,12 @@
66
import { TextRenderLayer } from 'browser/renderer/TextRenderLayer';
77
import { SelectionRenderLayer } from 'browser/renderer/SelectionRenderLayer';
88
import { CursorRenderLayer } from 'browser/renderer/CursorRenderLayer';
9-
import { IRenderLayer, IRenderer, IRenderDimensions, CharacterJoinerHandler, ICharacterJoinerRegistry, IRequestRedrawEvent } from 'browser/renderer/Types';
9+
import { IRenderLayer, IRenderer, IRenderDimensions, IRequestRedrawEvent } from 'browser/renderer/Types';
1010
import { LinkRenderLayer } from 'browser/renderer/LinkRenderLayer';
11-
import { CharacterJoinerRegistry } from 'browser/renderer/CharacterJoinerRegistry';
1211
import { Disposable } from 'common/Lifecycle';
1312
import { IColorSet, ILinkifier, ILinkifier2 } from 'browser/Types';
1413
import { ICharSizeService, ICoreBrowserService } from 'browser/services/Services';
15-
import { IBufferService, IOptionsService, ICoreService } from 'common/services/Services';
14+
import { IBufferService, IOptionsService, ICoreService, IInstantiationService } from 'common/services/Services';
1615
import { removeTerminalFromCache } from 'browser/renderer/atlas/CharAtlasCache';
1716
import { EventEmitter, IEvent } from 'common/EventEmitter';
1817

@@ -23,7 +22,6 @@ export class Renderer extends Disposable implements IRenderer {
2322

2423
private _renderLayers: IRenderLayer[];
2524
private _devicePixelRatio: number;
26-
private _characterJoinerRegistry: ICharacterJoinerRegistry;
2725

2826
public dimensions: IRenderDimensions;
2927

@@ -35,20 +33,18 @@ export class Renderer extends Disposable implements IRenderer {
3533
private readonly _screenElement: HTMLElement,
3634
linkifier: ILinkifier,
3735
linkifier2: ILinkifier2,
36+
instantiationService: IInstantiationService,
3837
@IBufferService private readonly _bufferService: IBufferService,
3938
@ICharSizeService private readonly _charSizeService: ICharSizeService,
40-
@IOptionsService private readonly _optionsService: IOptionsService,
41-
@ICoreService coreService: ICoreService,
42-
@ICoreBrowserService coreBrowserService: ICoreBrowserService
39+
@IOptionsService private readonly _optionsService: IOptionsService
4340
) {
4441
super();
4542
const allowTransparency = this._optionsService.options.allowTransparency;
46-
this._characterJoinerRegistry = new CharacterJoinerRegistry(this._bufferService);
4743
this._renderLayers = [
48-
new TextRenderLayer(this._screenElement, 0, this._colors, this._characterJoinerRegistry, allowTransparency, this._id, this._bufferService, _optionsService),
49-
new SelectionRenderLayer(this._screenElement, 1, this._colors, this._id, this._bufferService, _optionsService),
50-
new LinkRenderLayer(this._screenElement, 2, this._colors, this._id, linkifier, linkifier2, this._bufferService, _optionsService),
51-
new CursorRenderLayer(this._screenElement, 3, this._colors, this._id, this._onRequestRedraw, this._bufferService, _optionsService, coreService, coreBrowserService)
44+
instantiationService.createInstance(TextRenderLayer, this._screenElement, 0, this._colors, allowTransparency, this._id),
45+
instantiationService.createInstance(SelectionRenderLayer, this._screenElement, 1, this._colors, this._id),
46+
instantiationService.createInstance(LinkRenderLayer, this._screenElement, 2, this._colors, this._id, linkifier, linkifier2),
47+
instantiationService.createInstance(CursorRenderLayer, this._screenElement, 3, this._colors, this._id, this._onRequestRedraw)
5248
];
5349
this.dimensions = {
5450
scaledCharWidth: 0,
@@ -210,12 +206,4 @@ export class Renderer extends Disposable implements IRenderer {
210206
this.dimensions.actualCellHeight = this.dimensions.canvasHeight / this._bufferService.rows;
211207
this.dimensions.actualCellWidth = this.dimensions.canvasWidth / this._bufferService.cols;
212208
}
213-
214-
public registerCharacterJoiner(handler: CharacterJoinerHandler): number {
215-
return this._characterJoinerRegistry.registerCharacterJoiner(handler);
216-
}
217-
218-
public deregisterCharacterJoiner(joinerId: number): boolean {
219-
return this._characterJoinerRegistry.deregisterCharacterJoiner(joinerId);
220-
}
221209
}

src/browser/renderer/SelectionRenderLayer.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ export class SelectionRenderLayer extends BaseRenderLayer {
2323
zIndex: number,
2424
colors: IColorSet,
2525
rendererId: number,
26-
bufferService: IBufferService,
27-
optionsService: IOptionsService
26+
@IBufferService bufferService: IBufferService,
27+
@IOptionsService optionsService: IOptionsService
2828
) {
2929
super(container, 'selection', zIndex, true, colors, rendererId, bufferService, optionsService);
3030
this._clearState();

src/browser/renderer/TextRenderLayer.ts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,17 @@
33
* @license MIT
44
*/
55

6-
import { ICharacterJoinerRegistry, IRenderDimensions } from 'browser/renderer/Types';
6+
import { IRenderDimensions } from 'browser/renderer/Types';
77
import { CharData, ICellData } from 'common/Types';
88
import { GridCache } from 'browser/renderer/GridCache';
99
import { BaseRenderLayer } from 'browser/renderer/BaseRenderLayer';
1010
import { AttributeData } from 'common/buffer/AttributeData';
1111
import { NULL_CELL_CODE, Content } from 'common/buffer/Constants';
12-
import { JoinedCellData } from 'browser/renderer/CharacterJoinerRegistry';
1312
import { IColorSet } from 'browser/Types';
1413
import { CellData } from 'common/buffer/CellData';
1514
import { IOptionsService, IBufferService } from 'common/services/Services';
15+
import { ICharacterJoinerService } from 'browser/services/Services';
16+
import { JoinedCellData } from 'browser/services/CharacterJoinerService';
1617

1718
/**
1819
* This CharData looks like a null character, which will forc a clear and render
@@ -26,22 +27,20 @@ export class TextRenderLayer extends BaseRenderLayer {
2627
private _characterWidth: number = 0;
2728
private _characterFont: string = '';
2829
private _characterOverlapCache: { [key: string]: boolean } = {};
29-
private _characterJoinerRegistry: ICharacterJoinerRegistry;
3030
private _workCell = new CellData();
3131

3232
constructor(
3333
container: HTMLElement,
3434
zIndex: number,
3535
colors: IColorSet,
36-
characterJoinerRegistry: ICharacterJoinerRegistry,
3736
alpha: boolean,
3837
rendererId: number,
39-
bufferService: IBufferService,
40-
optionsService: IOptionsService
38+
@IBufferService bufferService: IBufferService,
39+
@IOptionsService optionsService: IOptionsService,
40+
@ICharacterJoinerService private readonly _characterJoinerService: ICharacterJoinerService
4141
) {
4242
super(container, 'text', zIndex, alpha, colors, rendererId, bufferService, optionsService);
4343
this._state = new GridCache<CharData>();
44-
this._characterJoinerRegistry = characterJoinerRegistry;
4544
}
4645

4746
public resize(dim: IRenderDimensions): void {
@@ -67,7 +66,6 @@ export class TextRenderLayer extends BaseRenderLayer {
6766
private _forEachCell(
6867
firstRow: number,
6968
lastRow: number,
70-
joinerRegistry: ICharacterJoinerRegistry | null,
7169
callback: (
7270
cell: ICellData,
7371
x: number,
@@ -77,7 +75,7 @@ export class TextRenderLayer extends BaseRenderLayer {
7775
for (let y = firstRow; y <= lastRow; y++) {
7876
const row = y + this._bufferService.buffer.ydisp;
7977
const line = this._bufferService.buffer.lines.get(row);
80-
const joinedRanges = joinerRegistry ? joinerRegistry.getJoinedCharacters(row) : [];
78+
const joinedRanges = this._characterJoinerService.getJoinedCharacters(row);
8179
for (let x = 0; x < this._bufferService.cols; x++) {
8280
line!.loadCell(x, this._workCell);
8381
let cell = this._workCell;
@@ -160,7 +158,7 @@ export class TextRenderLayer extends BaseRenderLayer {
160158

161159
ctx.save();
162160

163-
this._forEachCell(firstRow, lastRow, null, (cell, x, y) => {
161+
this._forEachCell(firstRow, lastRow, (cell, x, y) => {
164162
// libvte and xterm both draw the background (but not foreground) of invisible characters,
165163
// so we should too.
166164
let nextFillStyle = null; // null represents default background color
@@ -213,7 +211,7 @@ export class TextRenderLayer extends BaseRenderLayer {
213211
}
214212

215213
private _drawForeground(firstRow: number, lastRow: number): void {
216-
this._forEachCell(firstRow, lastRow, this._characterJoinerRegistry, (cell, x, y) => {
214+
this._forEachCell(firstRow, lastRow, (cell, x, y) => {
217215
if (cell.isInvisible()) {
218216
return;
219217
}

src/browser/renderer/Types.d.ts

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ import { IDisposable } from 'common/Types';
77
import { IColorSet } from 'browser/Types';
88
import { IEvent } from 'common/EventEmitter';
99

10-
export type CharacterJoinerHandler = (text: string) => [number, number][];
11-
1210
export interface IRenderDimensions {
1311
scaledCharWidth: number;
1412
scaledCharHeight: number;
@@ -54,19 +52,6 @@ export interface IRenderer extends IDisposable {
5452
onOptionsChanged(): void;
5553
clear(): void;
5654
renderRows(start: number, end: number): void;
57-
registerCharacterJoiner(handler: CharacterJoinerHandler): number;
58-
deregisterCharacterJoiner(joinerId: number): boolean;
59-
}
60-
61-
export interface ICharacterJoiner {
62-
id: number;
63-
handler: CharacterJoinerHandler;
64-
}
65-
66-
export interface ICharacterJoinerRegistry {
67-
registerCharacterJoiner(handler: (text: string) => [number, number][]): number;
68-
deregisterCharacterJoiner(joinerId: number): boolean;
69-
getJoinedCharacters(row: number): [number, number][];
7055
}
7156

7257
export interface IRenderLayer extends IDisposable {
@@ -106,16 +91,6 @@ export interface IRenderLayer extends IDisposable {
10691
*/
10792
onSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void;
10893

109-
/**
110-
* Registers a handler to join characters to render as a group
111-
*/
112-
registerCharacterJoiner?(joiner: ICharacterJoiner): void;
113-
114-
/**
115-
* Deregisters the specified character joiner handler
116-
*/
117-
deregisterCharacterJoiner?(joinerId: number): void;
118-
11994
/**
12095
* Resize the render layer.
12196
*/

src/browser/renderer/dom/DomRenderer.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* @license MIT
44
*/
55

6-
import { IRenderer, IRenderDimensions, CharacterJoinerHandler, IRequestRedrawEvent } from 'browser/renderer/Types';
6+
import { IRenderer, IRenderDimensions, IRequestRedrawEvent } from 'browser/renderer/Types';
77
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';
88
import { INVERTED_DEFAULT_COLOR } from 'browser/renderer/atlas/Constants';
99
import { Disposable } from 'common/Lifecycle';
@@ -372,9 +372,6 @@ export class DomRenderer extends Disposable implements IRenderer {
372372
return `.${TERMINAL_CLASS_PREFIX}${this._terminalClass}`;
373373
}
374374

375-
public registerCharacterJoiner(handler: CharacterJoinerHandler): number { return -1; }
376-
public deregisterCharacterJoiner(joinerId: number): boolean { return false; }
377-
378375
private _onLinkHover(e: ILinkifierEvent): void {
379376
this._setCellUnderline(e.x1, e.x2, e.y1, e.y2, e.cols, true);
380377
}

0 commit comments

Comments
 (0)