From b24bda92ad05c43d80fb5a73ea72071ec850c932 Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Fri, 20 Jan 2023 11:36:25 -0600 Subject: [PATCH] use textbox instead of div for accessibility buffer (#4377) --- src/browser/AccessibilityManager.ts | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/browser/AccessibilityManager.ts b/src/browser/AccessibilityManager.ts index 566439ec..5fbb11dc 100644 --- a/src/browser/AccessibilityManager.ts +++ b/src/browser/AccessibilityManager.ts @@ -28,7 +28,7 @@ export class AccessibilityManager extends Disposable { private _rowElements: HTMLElement[]; private _liveRegion: HTMLElement; private _liveRegionLineCount: number = 0; - private _accessiblityBuffer: HTMLElement; + private _accessiblityBuffer: HTMLTextAreaElement; private _renderRowsDebouncer: IRenderDebouncer; private _screenDprMonitor: ScreenDprMonitor; @@ -89,7 +89,7 @@ export class AccessibilityManager extends Disposable { throw new Error('Cannot enable accessibility before Terminal.open'); } - this._accessiblityBuffer = document.createElement('div'); + this._accessiblityBuffer = document.createElement('textarea'); this._accessiblityBuffer.ariaLabel = Strings.accessibilityBuffer; this._accessiblityBuffer.classList.add('xterm-accessibility-buffer'); this._accessiblityBuffer.contentEditable = 'true'; @@ -323,25 +323,23 @@ export class AccessibilityManager extends Disposable { return; } - const { bufferElements, cursorElement } = this._terminal.viewport.getBufferElements(0); + const { bufferElements } = this._terminal.viewport.getBufferElements(0); + const content = []; for (const element of bufferElements) { if (element.textContent) { - element.textContent = element.textContent.replace(new RegExp(' ', 'g'), '\xA0'); + content.push(element.textContent.replace(new RegExp(' ', 'g'), '\xA0')); } } - this._accessiblityBuffer.ariaRoleDescription = 'document'; - this._accessiblityBuffer.replaceChildren(...bufferElements); + this._accessiblityBuffer.textContent = content.join('\n'); + this._accessiblityBuffer.tabIndex = 0; + this._accessiblityBuffer.ariaRoleDescription = 'textbox'; + this._accessibilityTreeRoot.spellcheck = false; this._accessiblityBuffer.scrollTop = this._accessiblityBuffer.scrollHeight; - const s = document.getSelection(); - if (s && cursorElement) { - s.removeAllRanges(); - const r = document.createRange(); - r.selectNode(bufferElements[bufferElements.length - 1]); - r.setStart(cursorElement, 0); - r.setEnd(cursorElement, 0); - s.addRange(r); - } this._accessiblityBuffer.focus(); + + const end = this._accessiblityBuffer.value.length; + this._accessiblityBuffer.scrollTop = this._accessiblityBuffer.scrollHeight; + this._accessiblityBuffer.setSelectionRange(end, end); } private _handleColorChange(colorSet: ReadonlyColorSet): void {