mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
add registerBufferElementProvider (#4402)
This commit is contained in:
+5
-1
@@ -151,6 +151,10 @@
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.xterm .xterm-accessibility-buffer div {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.xterm .xterm-accessibility-buffer {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
@@ -165,7 +169,7 @@
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.xterm .xterm-accessibility-buffer:focus {
|
||||
.xterm .xterm-accessibility-buffer:focus-within {
|
||||
opacity: 1;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
@@ -4,20 +4,19 @@
|
||||
*/
|
||||
|
||||
import * as Strings from 'browser/LocalizableStrings';
|
||||
import { ITerminal, IRenderDebouncer, ReadonlyColorSet } from 'browser/Types';
|
||||
import { isMac } from 'common/Platform';
|
||||
import { TimeBasedDebouncer } from 'browser/TimeBasedDebouncer';
|
||||
import { IBufferElementProvider, ITerminal, ReadonlyColorSet } from 'browser/Types';
|
||||
import { addDisposableDomListener } from 'browser/Lifecycle';
|
||||
import { Disposable, toDisposable } from 'common/Lifecycle';
|
||||
import { IRenderService, IThemeService } from 'browser/services/Services';
|
||||
import { IOptionsService } from 'common/services/Services';
|
||||
import { ITerminalOptions } from 'xterm';
|
||||
import { IDisposable } from 'common/Types';
|
||||
|
||||
export class AccessibleBuffer extends Disposable {
|
||||
private _accessiblityBuffer: HTMLElement;
|
||||
private _isAccessibilityBufferActive: boolean = false;
|
||||
public get isAccessibilityBufferActive(): boolean { return this._isAccessibilityBufferActive; }
|
||||
|
||||
private _provider: IBufferElementProvider | undefined;
|
||||
constructor(
|
||||
private readonly _terminal: ITerminal,
|
||||
@IOptionsService optionsService: IOptionsService,
|
||||
@@ -26,7 +25,7 @@ export class AccessibleBuffer extends Disposable {
|
||||
) {
|
||||
super();
|
||||
if (!this._terminal.element) {
|
||||
throw new Error('Cannot enable accessibility before Terminal.open');
|
||||
throw new Error('Cannot enable accessibility buffer before Terminal.open');
|
||||
}
|
||||
|
||||
this._accessiblityBuffer = document.createElement('div');
|
||||
@@ -39,10 +38,15 @@ export class AccessibleBuffer extends Disposable {
|
||||
this.register(addDisposableDomListener(this._accessiblityBuffer, 'keydown', (ev: KeyboardEvent) => {
|
||||
if (ev.key === 'Tab') {
|
||||
this._isAccessibilityBufferActive = false;
|
||||
}}
|
||||
}
|
||||
}
|
||||
));
|
||||
this.register(addDisposableDomListener(this._accessiblityBuffer, 'focus',() => this._refreshAccessibilityBuffer()));
|
||||
this.register(addDisposableDomListener(this._accessiblityBuffer, 'focusout',() => this._isAccessibilityBufferActive = false));
|
||||
this.register(addDisposableDomListener(this._accessiblityBuffer, 'focus', () => this._refreshAccessibilityBuffer()));
|
||||
this.register(addDisposableDomListener(this._accessiblityBuffer, 'focusout', (e) => {
|
||||
if (!this._accessiblityBuffer.contains(e.element)) {
|
||||
this._isAccessibilityBufferActive = false;
|
||||
}
|
||||
}));
|
||||
|
||||
this._handleColorChange(themeService.colors);
|
||||
this.register(themeService.onChangeColors(e => this._handleColorChange(e)));
|
||||
@@ -51,19 +55,36 @@ export class AccessibleBuffer extends Disposable {
|
||||
this.register(toDisposable(() => this._accessiblityBuffer.remove()));
|
||||
}
|
||||
|
||||
public registerBufferElementProvider(bufferProvider: IBufferElementProvider): IDisposable {
|
||||
if (this._provider) {
|
||||
throw new Error('Buffer element provider already registered');
|
||||
}
|
||||
this._provider = bufferProvider;
|
||||
return {
|
||||
dispose: () => {
|
||||
this._provider = undefined;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private _refreshAccessibilityBuffer(): void {
|
||||
if (!this._terminal.viewport) {
|
||||
return;
|
||||
}
|
||||
this._isAccessibilityBufferActive = true;
|
||||
const { bufferElements } = this._terminal.viewport.getBufferElements(0);
|
||||
for (const element of bufferElements) {
|
||||
if (element.textContent) {
|
||||
element.textContent = element.textContent.replace(new RegExp(' ', 'g'), '\xA0');
|
||||
}
|
||||
}
|
||||
this._accessiblityBuffer.replaceChildren(...bufferElements);
|
||||
this._accessiblityBuffer.scrollTop = this._accessiblityBuffer.scrollHeight;
|
||||
const bufferElements = this._provider?.provideBufferElements();
|
||||
if (!bufferElements) {
|
||||
const { bufferElements } = this._terminal.viewport.getBufferElements(0);
|
||||
for (const element of bufferElements) {
|
||||
if (element.textContent) {
|
||||
element.textContent = element.textContent.replace(new RegExp(' ', 'g'), '\xA0');
|
||||
}
|
||||
}
|
||||
this._accessiblityBuffer.replaceChildren(...bufferElements);
|
||||
} else {
|
||||
this._accessiblityBuffer.replaceChildren(bufferElements);
|
||||
}
|
||||
}
|
||||
|
||||
private _handleColorChange(colorSet: ReadonlyColorSet): void {
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
* http://linux.die.net/man/7/urxvt
|
||||
*/
|
||||
|
||||
import { ICompositionHelper, ITerminal, IBrowser, CustomKeyEventHandler, IViewport, ILinkifier2, CharacterJoinerHandler, IBufferRange } from 'browser/Types';
|
||||
import { ICompositionHelper, ITerminal, IBrowser, CustomKeyEventHandler, IViewport, ILinkifier2, CharacterJoinerHandler, IBufferRange, IBufferElementProvider } from 'browser/Types';
|
||||
import { IRenderer } from 'browser/renderer/shared/Types';
|
||||
import { CompositionHelper } from 'browser/input/CompositionHelper';
|
||||
import { Viewport } from 'browser/Viewport';
|
||||
@@ -193,6 +193,13 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
||||
}));
|
||||
}
|
||||
|
||||
public registerBufferElementProvider(bufferProvider: IBufferElementProvider): IDisposable {
|
||||
if (!this._accessibleBuffer) {
|
||||
throw new Error ('Cannot register buffer element provider when terminal has not been opened yet');
|
||||
}
|
||||
return this._accessibleBuffer.registerBufferElementProvider(bufferProvider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle color event from inputhandler for OSC 4|104 | 10|110 | 11|111 | 12|112.
|
||||
* An event from OSC 4|104 may contain multiple set or report requests, and multiple
|
||||
|
||||
@@ -7,7 +7,7 @@ import { IDisposable, IMarker, ILinkProvider, IDecorationOptions, IDecoration }
|
||||
import { IEvent, EventEmitter } from 'common/EventEmitter';
|
||||
import { ICharacterJoinerService, ICharSizeService, ICoreBrowserService, IMouseService, IRenderService, ISelectionService, IThemeService } from 'browser/services/Services';
|
||||
import { IRenderDimensions, IRenderer, IRequestRedrawEvent } from 'browser/renderer/shared/Types';
|
||||
import { IColorSet, ITerminal, ILinkifier2, IBrowser, IViewport, ICompositionHelper, CharacterJoinerHandler, IBufferRange, ReadonlyColorSet } from 'browser/Types';
|
||||
import { IColorSet, ITerminal, ILinkifier2, IBrowser, IViewport, ICompositionHelper, CharacterJoinerHandler, IBufferRange, ReadonlyColorSet, IBufferElementProvider } from 'browser/Types';
|
||||
import { IBuffer, IBufferSet } from 'common/buffer/Types';
|
||||
import { IBufferLine, ICellData, IAttributeData, ICircularList, XtermListener, ICharset, ITerminalOptions, ColorIndex } from 'common/Types';
|
||||
import { Buffer } from 'common/buffer/Buffer';
|
||||
@@ -143,6 +143,9 @@ export class MockTerminal implements ITerminal {
|
||||
public getBufferElements(startLine: number, endLine?: number | undefined): { bufferElements: HTMLElement[], cursorElement?: HTMLElement | undefined } {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
public registerBufferElementProvider(bufferProvider: IBufferElementProvider): IDisposable {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
public bracketedPasteMode!: boolean;
|
||||
public renderer!: IRenderer;
|
||||
public linkifier2!: ILinkifier2;
|
||||
|
||||
Vendored
+5
@@ -80,6 +80,7 @@ export interface IPublicTerminal extends IDisposable {
|
||||
refresh(start: number, end: number): void;
|
||||
clearTextureAtlas(): void;
|
||||
reset(): void;
|
||||
registerBufferElementProvider(bufferProvider: IBufferElementProvider): IDisposable;
|
||||
}
|
||||
|
||||
export type CustomKeyEventHandler = (event: KeyboardEvent) => boolean;
|
||||
@@ -220,3 +221,7 @@ export interface IRenderDebouncer extends IDisposable {
|
||||
export interface IRenderDebouncerWithCallback extends IRenderDebouncer {
|
||||
addRefreshCallback(callback: FrameRequestCallback): number;
|
||||
}
|
||||
|
||||
export interface IBufferElementProvider {
|
||||
provideBufferElements(): DocumentFragment;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { Terminal as ITerminalApi, IMarker, IDisposable, ILocalizableStrings, ITerminalAddon, IBufferNamespace as IBufferNamespaceApi, IParser, ILinkProvider, IUnicodeHandling, IModes, IDecorationOptions, IDecoration } from 'xterm';
|
||||
import { Terminal as ITerminalApi, IMarker, IDisposable, ILocalizableStrings, ITerminalAddon, IBufferNamespace as IBufferNamespaceApi, IParser, ILinkProvider, IUnicodeHandling, IModes, IDecorationOptions, IDecoration, IBufferElementProvider } from 'xterm';
|
||||
import { IBufferRange, ITerminal } from 'browser/Types';
|
||||
import { Terminal as TerminalCore } from 'browser/Terminal';
|
||||
import * as Strings from 'browser/LocalizableStrings';
|
||||
@@ -236,6 +236,9 @@ export class Terminal implements ITerminalApi {
|
||||
public loadAddon(addon: ITerminalAddon): void {
|
||||
return this._addonManager.loadAddon(this, addon);
|
||||
}
|
||||
public registerBufferElementProvider(bufferProvider: IBufferElementProvider): IDisposable {
|
||||
return this._core.registerBufferElementProvider(bufferProvider);
|
||||
}
|
||||
public static get strings(): ILocalizableStrings {
|
||||
return Strings;
|
||||
}
|
||||
|
||||
Vendored
+15
@@ -1108,6 +1108,14 @@ declare module 'xterm' {
|
||||
* @param addon The addon to load.
|
||||
*/
|
||||
loadAddon(addon: ITerminalAddon): void;
|
||||
|
||||
/*
|
||||
* Registers a buffer element provider which will provide a custom element to
|
||||
* use in the terminal's accessible buffer. Using this an xterm.js embedder
|
||||
* has full control over how the buffer is represented in the DOM.
|
||||
* @param bufferElementProvider The buffer element provider.
|
||||
*/
|
||||
registerBufferElementProvider(bufferProvider: IBufferElementProvider): IDisposable;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1360,6 +1368,13 @@ declare module 'xterm' {
|
||||
getNullCell(): IBufferCell;
|
||||
}
|
||||
|
||||
export interface IBufferElementProvider {
|
||||
/**
|
||||
* Provides a document fragment containing the buffer elements.
|
||||
*/
|
||||
provideBufferElements(): DocumentFragment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the terminal's set of buffers.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user