check if screen reader optimized, support for right prompts

This commit is contained in:
meganrogge
2023-08-11 15:05:46 -07:00
parent ea912c1b39
commit bb9d98b82e
10 changed files with 33 additions and 18 deletions
@@ -115,6 +115,7 @@ export class CommandDetectionCapability extends Disposable implements ICommandDe
constructor(
private readonly _terminal: Terminal,
private readonly _isScreenReaderOptimized: boolean,
private readonly _logService: ILogService
) {
super();
@@ -137,6 +138,24 @@ export class CommandDetectionCapability extends Disposable implements ICommandDe
@debounce(500)
private _handleCursorMove() {
// Sync the textarea with the terminal contents so screen readers can read it
if (this._isScreenReaderOptimized) {
const buffer = this._terminal.buffer.active;
const line = buffer.getLine(buffer.cursorY)?.translateToString(true);
let commandText: string | undefined;
if (line) {
if (this._currentCommand.commandStartX) {
// Left prompt
commandText = line.substring(this._currentCommand.commandStartX);
} else if (this._currentCommand.commandRightPromptStartX) {
// Right prompt
commandText = line.substring(0, this._currentCommand.commandRightPromptStartX).trimStart();
}
if (commandText?.length) {
this._onRequestWriteToTextArea.fire(commandText);
}
}
}
// Early versions of conpty do not have real support for an alt buffer, in addition certain
// commands such as tsc watch will write to the top of the normal buffer. The following
// checks when the cursor has moved while the normal buffer is empty and if it is above the
@@ -147,14 +166,7 @@ export class CommandDetectionCapability extends Disposable implements ICommandDe
//
// This is mostly a workaround for Windows but applies to all OS' because of the tsc watch
// case.
let line = this._terminal.buffer.active.getLine(this._terminal.buffer.active.cursorY)?.translateToString(true);
if (this._currentCommand.commandStartX) {
line = line?.substring(this._currentCommand.commandStartX).trimEnd();
}
if (line) {
console.log(line);
this._onRequestWriteToTextArea.fire(line);
}
if (this._terminal.buffer.active === this._terminal.buffer.normal && this._currentCommand.commandStartMarker) {
if (this._terminal.buffer.active.baseY + this._terminal.buffer.active.cursorY < this._currentCommand.commandStartMarker.line) {
this._clearCommandsInViewport();
@@ -207,6 +207,7 @@ export class ShellIntegrationAddon extends Disposable implements IShellIntegrati
constructor(
private _nonce: string,
private readonly _isScreenReaderOptimized: boolean,
private readonly _disableTelemetry: boolean | undefined,
private readonly _telemetryService: ITelemetryService | undefined,
private readonly _logService: ILogService
@@ -513,7 +514,7 @@ export class ShellIntegrationAddon extends Disposable implements IShellIntegrati
protected _createOrGetCommandDetection(terminal: Terminal): ICommandDetectionCapability {
let commandDetection = this.capabilities.get(TerminalCapability.CommandDetection);
if (!commandDetection) {
commandDetection = this._register(new CommandDetectionCapability(terminal, this._logService));
commandDetection = this._register(new CommandDetectionCapability(terminal, this._isScreenReaderOptimized, this._logService));
this.capabilities.add(TerminalCapability.CommandDetection, commandDetection);
}
return commandDetection;
+1 -1
View File
@@ -1000,7 +1000,7 @@ class XtermSerializer implements ITerminalSerializer {
this._xterm.writeln(reviveBufferWithRestoreMessage);
}
this.setUnicodeVersion(unicodeVersion);
this._shellIntegrationAddon = new ShellIntegrationAddon(shellIntegrationNonce, true, undefined, logService);
this._shellIntegrationAddon = new ShellIntegrationAddon(shellIntegrationNonce, false, true, undefined, logService);
this._xterm.loadAddon(this._shellIntegrationAddon);
}
@@ -425,9 +425,9 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
commandCapability?.onRequestWriteToTextArea(text => {
const textArea = this.xterm?.raw.textarea;
if (textArea) {
// Sync the textarea using shell integration so screen
// readers can read the command
textArea.textContent = text;
console.log('content is');
console.log(textArea.textContent);
}
});
commandCapability?.onCommandFinished(e => {
@@ -43,6 +43,7 @@ import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService
import { debounce } from 'vs/base/common/decorators';
import { MouseWheelClassifier } from 'vs/base/browser/ui/scrollbar/scrollableElement';
import { IMouseWheelEvent, StandardWheelEvent } from 'vs/base/browser/mouseEvent';
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
const enum RenderConstants {
/**
@@ -202,6 +203,7 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, ID
@ITelemetryService private readonly _telemetryService: ITelemetryService,
@IClipboardService private readonly _clipboardService: IClipboardService,
@IContextKeyService contextKeyService: IContextKeyService,
@IAccessibilityService private readonly _accessiblityService: IAccessibilityService
) {
super();
const font = this._configHelper.getFont(undefined, true);
@@ -272,7 +274,7 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, ID
this._decorationAddon = this._instantiationService.createInstance(DecorationAddon, this._capabilities);
this._decorationAddon.onDidRequestRunCommand(e => this._onDidRequestRunCommand.fire(e));
this.raw.loadAddon(this._decorationAddon);
this._shellIntegrationAddon = new ShellIntegrationAddon(shellIntegrationNonce, disableShellIntegrationReporting, this._telemetryService, this._logService);
this._shellIntegrationAddon = new ShellIntegrationAddon(shellIntegrationNonce, this._accessiblityService.isScreenReaderOptimized(), disableShellIntegrationReporting, this._telemetryService, this._logService);
this.raw.loadAddon(this._shellIntegrationAddon);
this._anyTerminalFocusContextKey = TerminalContextKeys.focusInAny.bindTo(contextKeyService);
@@ -62,7 +62,7 @@ suite('CommandDetectionCapability', () => {
xterm = new TerminalCtor({ allowProposedApi: true, cols: 80 });
instantiationService = new TestInstantiationService();
instantiationService.stub(IContextMenuService, { showContextMenu(delegate: IContextMenuDelegate): void { } } as Partial<IContextMenuService>);
capability = new TestCommandDetectionCapability(xterm, new NullLogService());
capability = new TestCommandDetectionCapability(xterm, false, new NullLogService());
addEvents = [];
capability.onCommandFinished(e => addEvents.push(e));
assertCommands([]);
@@ -61,7 +61,7 @@ suite('DecorationAddon', () => {
instantiationService.stub(IContextMenuService, instantiationService.createInstance(ContextMenuService));
instantiationService.stub(ILogService, NullLogService);
const capabilities = new TerminalCapabilityStore();
capabilities.add(TerminalCapability.CommandDetection, instantiationService.createInstance(CommandDetectionCapability, xterm));
capabilities.add(TerminalCapability.CommandDetection, instantiationService.createInstance(CommandDetectionCapability, xterm, false));
instantiationService.stub(ILifecycleService, new TestLifecycleService());
decorationAddon = instantiationService.createInstance(DecorationAddon, capabilities);
xterm.loadAddon(decorationAddon);
@@ -34,7 +34,7 @@ suite('ShellIntegrationAddon', () => {
const TerminalCtor = (await importAMDNodeModule<typeof import('xterm')>('xterm', 'lib/xterm.js')).Terminal;
xterm = new TerminalCtor({ allowProposedApi: true, cols: 80, rows: 30 });
shellIntegrationAddon = new TestShellIntegrationAddon('', true, undefined, new NullLogService());
shellIntegrationAddon = new TestShellIntegrationAddon('', false, true, undefined, new NullLogService());
xterm.loadAddon(shellIntegrationAddon);
capabilities = shellIntegrationAddon.capabilities;
});
@@ -125,7 +125,7 @@ suite('Workbench - TerminalLinkOpeners', () => {
setup(() => {
capabilities = new TerminalCapabilityStore();
commandDetection = instantiationService.createInstance(TestCommandDetectionCapability, xterm);
commandDetection = instantiationService.createInstance(TestCommandDetectionCapability, xterm, false);
capabilities.add(TerminalCapability.CommandDetection, commandDetection);
});
@@ -58,7 +58,7 @@ suite('QuickFixAddon', () => {
instantiationService.stub(ILabelService, {} as Partial<ILabelService>);
const capabilities = new TerminalCapabilityStore();
instantiationService.stub(ILogService, new NullLogService());
commandDetection = instantiationService.createInstance(CommandDetectionCapability, terminal);
commandDetection = instantiationService.createInstance(CommandDetectionCapability, terminal, false);
capabilities.add(TerminalCapability.CommandDetection, commandDetection);
instantiationService.stub(IContextMenuService, instantiationService.createInstance(ContextMenuService));
instantiationService.stub(IOpenerService, {} as Partial<IOpenerService>);