enable registering a decoration before attach to dom has happened
This commit is contained in:
@@ -473,7 +473,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
|||||||
this._viewportElement.classList.add('xterm-viewport');
|
this._viewportElement.classList.add('xterm-viewport');
|
||||||
fragment.appendChild(this._viewportElement);
|
fragment.appendChild(this._viewportElement);
|
||||||
|
|
||||||
//TODO: make this opt in, must be done before the scroll area in order to show up
|
// TODO: make this opt in, must be done before the scroll area in order to show up
|
||||||
this._scrollbarDecorationNode = document.createElement('canvas');
|
this._scrollbarDecorationNode = document.createElement('canvas');
|
||||||
this._scrollbarDecorationNode.classList.add('xterm-decoration-scrollbar');
|
this._scrollbarDecorationNode.classList.add('xterm-decoration-scrollbar');
|
||||||
this._viewportElement?.appendChild(this._scrollbarDecorationNode);
|
this._viewportElement?.appendChild(this._scrollbarDecorationNode);
|
||||||
@@ -584,7 +584,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
|||||||
this.linkifier.attachToDom(this.element, this._mouseZoneManager);
|
this.linkifier.attachToDom(this.element, this._mouseZoneManager);
|
||||||
this.linkifier2.attachToDom(this.screenElement, this._mouseService, this._renderService);
|
this.linkifier2.attachToDom(this.screenElement, this._mouseService, this._renderService);
|
||||||
|
|
||||||
this.decorationService.attachToDom(this._scrollbarDecorationNode, this.screenElement, this._viewportElement, this._renderService);
|
this.decorationService.attachToDom(this._renderService, this.screenElement, this._viewportElement, this._scrollbarDecorationNode);
|
||||||
// This event listener must be registered aftre MouseZoneManager is created
|
// This event listener must be registered aftre MouseZoneManager is created
|
||||||
this.register(addDisposableDomListener(this.element, 'mousedown', (e: MouseEvent) => this._selectionService!.onMouseDown(e)));
|
this.register(addDisposableDomListener(this.element, 'mousedown', (e: MouseEvent) => this._selectionService!.onMouseDown(e)));
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { addDisposableDomListener } from 'browser/Lifecycle';
|
|||||||
import { IDecorationService, IRenderService } from 'browser/services/Services';
|
import { IDecorationService, IRenderService } from 'browser/services/Services';
|
||||||
import { EventEmitter, IEvent } from 'common/EventEmitter';
|
import { EventEmitter, IEvent } from 'common/EventEmitter';
|
||||||
import { Disposable } from 'common/Lifecycle';
|
import { Disposable } from 'common/Lifecycle';
|
||||||
|
import { BufferService } from 'common/services/BufferService';
|
||||||
import { IBufferService, IInstantiationService } from 'common/services/Services';
|
import { IBufferService, IInstantiationService } from 'common/services/Services';
|
||||||
import { IDecorationOptions, IDecoration, IMarker } from 'xterm';
|
import { IDecorationOptions, IDecoration, IMarker } from 'xterm';
|
||||||
|
|
||||||
@@ -16,35 +17,33 @@ const enum ScrollbarConstants {
|
|||||||
|
|
||||||
export class DecorationService extends Disposable implements IDecorationService {
|
export class DecorationService extends Disposable implements IDecorationService {
|
||||||
|
|
||||||
private _container: HTMLElement | undefined;
|
|
||||||
private _screenElement: HTMLElement | undefined;
|
|
||||||
private _viewportElement: HTMLElement | undefined;
|
|
||||||
private _renderService: IRenderService | undefined;
|
private _renderService: IRenderService | undefined;
|
||||||
private _animationFrame: number | undefined;
|
private _animationFrame: number | undefined;
|
||||||
|
|
||||||
|
private _screenElement: HTMLElement | undefined;
|
||||||
|
private _viewportElement: HTMLElement | undefined;
|
||||||
|
private _bufferDecorationContainer: HTMLElement | undefined;
|
||||||
|
private _scrollbarDecorationCanvas: CanvasRenderingContext2D | null = null;
|
||||||
|
private _scrollbarDecorationNode: HTMLCanvasElement | undefined;
|
||||||
|
|
||||||
private readonly _bufferDecorations: BufferDecoration[] = [];
|
private readonly _bufferDecorations: BufferDecoration[] = [];
|
||||||
private _scrollbarDecorations: ScrollbarDecoration[] = [];
|
private _scrollbarDecorations: ScrollbarDecoration[] = [];
|
||||||
|
|
||||||
private _scrollbarDecorationCanvas: CanvasRenderingContext2D | null = null;
|
constructor(@IInstantiationService private readonly _instantiationService: IInstantiationService) { super(); }
|
||||||
private _scrollbarDecorationNode: HTMLCanvasElement | undefined;
|
|
||||||
|
|
||||||
constructor(@IInstantiationService private readonly _instantiationService: IInstantiationService, @IBufferService private readonly _bufferService: IBufferService) { super(); }
|
public attachToDom(renderService: IRenderService, screenElement: HTMLElement, viewportElement: HTMLElement, scrollbarDecorationNode: HTMLCanvasElement): void {
|
||||||
|
|
||||||
public attachToDom(scrollbarDecorationNode: HTMLCanvasElement, screenElement: HTMLElement, viewportElement: HTMLElement, renderService: IRenderService): void {
|
|
||||||
this._renderService = renderService;
|
this._renderService = renderService;
|
||||||
this._screenElement = screenElement;
|
this._screenElement = screenElement;
|
||||||
this._viewportElement = viewportElement;
|
this._viewportElement = viewportElement;
|
||||||
this._scrollbarDecorationNode = scrollbarDecorationNode;
|
this._scrollbarDecorationNode = scrollbarDecorationNode;
|
||||||
this._container = document.createElement('div');
|
|
||||||
this._container.classList.add('xterm-decoration-container');
|
|
||||||
screenElement.appendChild(this._container);
|
|
||||||
this.register(this._renderService.onRenderedBufferChange(() => this._refresh()));
|
this.register(this._renderService.onRenderedBufferChange(() => this._refresh()));
|
||||||
this.register(this._renderService.onDimensionsChange(() => this._refresh(true)));
|
this.register(this._renderService.onDimensionsChange(() => this._refresh(true)));
|
||||||
this.register(addDisposableDomListener(window, 'resize', () => this._refreshScollbarDecorations()));
|
this.register(addDisposableDomListener(window, 'resize', () => this._refreshScollbarDecorations()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined {
|
public registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined {
|
||||||
if (decorationOptions.marker.isDisposed || !this._container || !this._scrollbarDecorationNode) {
|
if (decorationOptions.marker.isDisposed) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
if (decorationOptions.scrollbarDecorationColor) {
|
if (decorationOptions.scrollbarDecorationColor) {
|
||||||
@@ -57,12 +56,12 @@ export class DecorationService extends Disposable implements IDecorationService
|
|||||||
for (const bufferDecoration of this._bufferDecorations) {
|
for (const bufferDecoration of this._bufferDecorations) {
|
||||||
bufferDecoration.dispose();
|
bufferDecoration.dispose();
|
||||||
}
|
}
|
||||||
if (this._screenElement && this._container && this._screenElement.contains(this._container)) {
|
|
||||||
this._screenElement.removeChild(this._container);
|
|
||||||
}
|
|
||||||
for (const scrollbarDecoration of this._scrollbarDecorations) {
|
for (const scrollbarDecoration of this._scrollbarDecorations) {
|
||||||
scrollbarDecoration.dispose();
|
scrollbarDecoration.dispose();
|
||||||
}
|
}
|
||||||
|
if (this._screenElement && this._bufferDecorationContainer && this._screenElement.contains(this._bufferDecorationContainer)) {
|
||||||
|
this._screenElement.removeChild(this._bufferDecorationContainer);
|
||||||
|
}
|
||||||
this._scrollbarDecorations = [];
|
this._scrollbarDecorations = [];
|
||||||
this._scrollbarDecorationNode?.remove();
|
this._scrollbarDecorationNode?.remove();
|
||||||
}
|
}
|
||||||
@@ -83,10 +82,12 @@ export class DecorationService extends Disposable implements IDecorationService
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _registerBufferDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined {
|
private _registerBufferDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined {
|
||||||
if (!this._container) {
|
if (this._screenElement && !this._bufferDecorationContainer) {
|
||||||
return;
|
this._bufferDecorationContainer = document.createElement('div');
|
||||||
|
this._bufferDecorationContainer.classList.add('xterm-decoration-container');
|
||||||
|
this._screenElement.appendChild(this._bufferDecorationContainer);
|
||||||
}
|
}
|
||||||
const decoration = this._instantiationService.createInstance(BufferDecoration, decorationOptions, this._container);
|
const decoration = new BufferDecoration(this._instantiationService.createInstance(BufferService), decorationOptions, this._bufferDecorationContainer);
|
||||||
this._bufferDecorations.push(decoration);
|
this._bufferDecorations.push(decoration);
|
||||||
decoration.onDispose(() => this._bufferDecorations.splice(this._bufferDecorations.indexOf(decoration), 1));
|
decoration.onDispose(() => this._bufferDecorations.splice(this._bufferDecorations.indexOf(decoration), 1));
|
||||||
this._queueRefresh();
|
this._queueRefresh();
|
||||||
@@ -101,7 +102,7 @@ export class DecorationService extends Disposable implements IDecorationService
|
|||||||
this._scrollbarDecorationCanvas = this._scrollbarDecorationNode.getContext('2d');
|
this._scrollbarDecorationCanvas = this._scrollbarDecorationNode.getContext('2d');
|
||||||
this._refreshScollbarDecorations();
|
this._refreshScollbarDecorations();
|
||||||
}
|
}
|
||||||
const decoration = new ScrollbarDecoration({ marker, scrollbarDecorationColor: color }, this._scrollbarDecorationNode, this._scrollbarDecorationCanvas!, this._bufferService);
|
const decoration = this._instantiationService.createInstance(ScrollbarDecoration, { marker, scrollbarDecorationColor: color }, this._scrollbarDecorationNode, this._scrollbarDecorationCanvas!);
|
||||||
decoration.onDispose(() => this._scrollbarDecorations.splice(this._scrollbarDecorations.indexOf(decoration), 1));
|
decoration.onDispose(() => this._scrollbarDecorations.splice(this._scrollbarDecorations.indexOf(decoration), 1));
|
||||||
this._scrollbarDecorations.push(decoration);
|
this._scrollbarDecorations.push(decoration);
|
||||||
return decoration;
|
return decoration;
|
||||||
@@ -129,8 +130,8 @@ export class DecorationService extends Disposable implements IDecorationService
|
|||||||
decoration.render();
|
decoration.render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ScrollbarDecoration extends Disposable implements IDecoration {
|
export class ScrollbarDecoration extends Disposable implements IDecoration {
|
||||||
private readonly _marker: IMarker;
|
private readonly _marker: IMarker;
|
||||||
private _canvas: HTMLCanvasElement | undefined;
|
private _canvas: HTMLCanvasElement | undefined;
|
||||||
@@ -152,7 +153,7 @@ export class ScrollbarDecoration extends Disposable implements IDecoration {
|
|||||||
options: IDecorationOptions,
|
options: IDecorationOptions,
|
||||||
canvas: HTMLCanvasElement,
|
canvas: HTMLCanvasElement,
|
||||||
private readonly _ctx: CanvasRenderingContext2D,
|
private readonly _ctx: CanvasRenderingContext2D,
|
||||||
private readonly _bufferService: IBufferService
|
@IBufferService private readonly _bufferService: IBufferService
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
this._marker = options.marker;
|
this._marker = options.marker;
|
||||||
@@ -209,9 +210,9 @@ export class BufferDecoration extends Disposable implements IDecoration {
|
|||||||
public height: number;
|
public height: number;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
private readonly _bufferService: IBufferService,
|
||||||
options: IDecorationOptions,
|
options: IDecorationOptions,
|
||||||
private readonly _container: HTMLElement,
|
private readonly _container?: HTMLElement
|
||||||
@IBufferService private readonly _bufferService: IBufferService
|
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
this.x = options.x ?? 0;
|
this.x = options.x ?? 0;
|
||||||
@@ -236,7 +237,7 @@ export class BufferDecoration extends Disposable implements IDecoration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _createElement(renderService: IRenderService, shouldRecreate?: boolean): void {
|
private _createElement(renderService: IRenderService, shouldRecreate?: boolean): void {
|
||||||
if (shouldRecreate && this._element && this._container.contains(this._element)) {
|
if (shouldRecreate && this._element && this._container && this._container.contains(this._element)) {
|
||||||
this._container.removeChild(this._element);
|
this._container.removeChild(this._element);
|
||||||
}
|
}
|
||||||
this._element = document.createElement('div');
|
this._element = document.createElement('div');
|
||||||
@@ -272,7 +273,7 @@ export class BufferDecoration extends Disposable implements IDecoration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override dispose(): void {
|
public override dispose(): void {
|
||||||
if (this.isDisposed) {
|
if (this.isDisposed || !this._container) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this._element && this._container.contains(this._element)) {
|
if (this._element && this._container.contains(this._element)) {
|
||||||
|
|||||||
@@ -119,6 +119,6 @@ export interface ICharacterJoinerService {
|
|||||||
|
|
||||||
export const IDecorationService = createDecorator<IDecorationService>('DecorationService');
|
export const IDecorationService = createDecorator<IDecorationService>('DecorationService');
|
||||||
export interface IDecorationService extends IDisposable {
|
export interface IDecorationService extends IDisposable {
|
||||||
attachToDom(scrollbarDecorationNode: HTMLCanvasElement, screenElement: HTMLElement, viewportElement: HTMLElement, renderService: IRenderService): void;
|
attachToDom(renderService: IRenderService, screenElement: HTMLElement, viewportElement: HTMLElement, scrollbarDecorationNode: HTMLCanvasElement): void;
|
||||||
registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined;
|
registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user