Skip to content

Commit 3a74930

Browse files
committed
Cap output element to prevent screen reader freezing
1 parent a15df82 commit 3a74930

File tree

3 files changed

+8
-7
lines changed

3 files changed

+8
-7
lines changed

css/xterm.css

+1
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@
160160
background: #000;
161161
color: #fff;
162162
opacity: 0;
163+
overflow: scroll;
163164
}
164165
.xterm .xterm-accessibility-full-output:focus {
165166
opacity: 1;

src/browser/AccessibilityManager.ts

+7-6
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ export class AccessibilityManager extends Disposable {
8989
if (!this._terminal.element) {
9090
throw new Error('Cannot enable accessibility before Terminal.open');
9191
}
92-
this._terminal.element.insertAdjacentElement('afterbegin', this._accessibilityTreeRoot);
92+
// this._terminal.element.insertAdjacentElement('afterbegin', this._accessibilityTreeRoot);
9393

9494
this._fullOutputElement = document.createElement('section');
9595
// TODO: Add to strings
@@ -324,7 +324,10 @@ export class AccessibilityManager extends Disposable {
324324
const outputLines: HTMLElement[] = [];
325325
let currentLine: string = '';
326326
let lastContentfulElement: HTMLElement | undefined;
327-
for (let i = 0; i < this._terminal.buffer.lines.length; i++) {
327+
// Cap the number of items in full output, without this screen reader can easily lock up for 20+
328+
// seconds, probably due to refreshing their a11y tree
329+
const start = Math.max(this._terminal.buffer.lines.length - 100, 0);
330+
for (let i = start; i < this._terminal.buffer.lines.length; i++) {
328331
const line = this._terminal.buffer.lines.get(i);
329332
if (!line) {
330333
continue;
@@ -341,10 +344,7 @@ export class AccessibilityManager extends Disposable {
341344
currentLine = '';
342345
}
343346
}
344-
while (this._fullOutputElement.children.length > 0) {
345-
this._fullOutputElement.removeChild(this._fullOutputElement.children[0]);
346-
}
347-
this._fullOutputElement.append(...outputLines);
347+
this._fullOutputElement.replaceChildren(...outputLines);
348348
const s = document.getSelection();
349349
if (s && lastContentfulElement) {
350350
s.removeAllRanges();
@@ -354,6 +354,7 @@ export class AccessibilityManager extends Disposable {
354354
r.setEnd(lastContentfulElement, 0);
355355
s.addRange(r);
356356
}
357+
this._fullOutputElement.scrollTop = this._fullOutputElement.scrollHeight;
357358
// TODO: Delegate API for translating lines into elements
358359
}
359360

src/browser/Terminal.ts

-1
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,6 @@ export class Terminal extends CoreTerminal implements ITerminal {
419419
this.element.dir = 'ltr'; // xterm.css assumes LTR
420420
this.element.classList.add('terminal');
421421
this.element.classList.add('xterm');
422-
this.element.setAttribute('tabindex', '0');
423422
parent.appendChild(this.element);
424423

425424
// Performance: Use a document fragment to build the terminal

0 commit comments

Comments
 (0)