aria alert for cell index changes.

This commit is contained in:
rebornix 2021-03-16 10:10:06 -07:00
parent 5f4e9a55f5
commit 8303d03545
No known key found for this signature in database
GPG key ID: 181FC90D15393C20
2 changed files with 55 additions and 4 deletions

View file

@ -5,6 +5,7 @@
import { getPixelRatio, getZoomLevel } from 'vs/base/browser/browser';
import * as DOM from 'vs/base/browser/dom';
import * as aria from 'vs/base/browser/ui/aria/aria';
import { IMouseWheelEvent, StandardMouseEvent } from 'vs/base/browser/mouseEvent';
import { IListContextMenuEvent } from 'vs/base/browser/ui/list/list';
import { IAction } from 'vs/base/common/actions';
@ -560,7 +561,18 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
listInactiveFocusOutline: editorBackground,
},
accessibilityProvider: {
getAriaLabel() { return null; },
getAriaLabel: (element) => {
if (!this.viewModel) {
return '';
}
const index = this.viewModel.getCellIndex(element);
if (index >= 0) {
return `Cell ${index}, ${element.cellKind === CellKind.Markdown ? 'markdown' : 'code'} cell`;
}
return '';
},
getWidgetAriaLabel() {
return nls.localize('notebookTreeAriaLabel', "Notebook");
}
@ -1790,6 +1802,27 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
return undefined;
}
private _cellFocusAria(cell: ICellViewModel, focusItem: 'editor' | 'container' | 'output') {
const index = this._notebookViewModel?.getCellIndex(cell);
if (index !== undefined && index >= 0) {
let position = '';
switch (focusItem) {
case 'editor':
position = `the inner ${cell.cellKind === CellKind.Markdown ? 'markdown' : 'code'} editor is focused, press escape to focus the cell container`;
break;
case 'output':
position = `the cell output is focused, press escape to focus the cell container`;
break;
case 'container':
position = `the ${cell.cellKind === CellKind.Markdown ? 'markdown preview' : 'cell container'} is focused, press enter to focus the inner ${cell.cellKind === CellKind.Markdown ? 'markdown' : 'code'} editor`;
break;
default:
break;
}
aria.alert(`Cell ${this._notebookViewModel?.getCellIndex(cell)}, ${position} `);
}
}
focusNotebookCell(cell: ICellViewModel, focusItem: 'editor' | 'container' | 'output', options?: IFocusNotebookCellOptions) {
if (this._isDisposed) {
return;
@ -1797,6 +1830,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
if (focusItem === 'editor') {
this.focusElement(cell);
this._cellFocusAria(cell, focusItem);
this._list.focusView();
cell.editState = CellEditState.Editing;
@ -1806,6 +1840,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
}
} else if (focusItem === 'output') {
this.focusElement(cell);
this._cellFocusAria(cell, focusItem);
this._list.focusView();
if (!this._webview) {
@ -1828,6 +1863,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
cell.focusMode = CellFocusMode.Container;
this.focusElement(cell);
this._cellFocusAria(cell, focusItem);
if (!options?.skipReveal) {
this.revealInCenterIfOutsideViewport(cell);
}

View file

@ -5,6 +5,7 @@
import { getPixelRatio, getZoomLevel } from 'vs/base/browser/browser';
import * as DOM from 'vs/base/browser/dom';
import * as aria from 'vs/base/browser/ui/aria/aria';
import { domEvent } from 'vs/base/browser/event';
import { renderIcon } from 'vs/base/browser/ui/iconLabel/iconLabels';
import { IListRenderer, IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
@ -880,7 +881,13 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
this.updateExecutionOrder(metadata, templateData);
templateData.statusBar.cellStatusMessageContainer.textContent = metadata?.statusMessage || '';
templateData.cellRunState.renderState(element.metadata?.runState);
templateData.cellRunState.renderState(element.metadata?.runState, () => {
if (!this.notebookEditor.viewModel) {
return -1;
}
return this.notebookEditor.viewModel.getCellIndex(element);
});
if (metadata.runState === NotebookCellRunState.Running) {
if (metadata.runStartTime) {
@ -1095,6 +1102,7 @@ export class RunStateRenderer {
private spinnerTimer: any | undefined;
private pendingNewState: NotebookCellRunState | undefined;
private lastRunState: NotebookCellRunState | undefined;
constructor(private readonly element: HTMLElement) {
DOM.hide(element);
@ -1107,23 +1115,28 @@ export class RunStateRenderer {
}
}
renderState(runState: NotebookCellRunState = NotebookCellRunState.Idle) {
renderState(runState: NotebookCellRunState = NotebookCellRunState.Idle, getCellIndex: () => number) {
if (this.spinnerTimer) {
this.pendingNewState = runState;
return;
}
if (runState === NotebookCellRunState.Success) {
aria.alert(`Code cell at ${getCellIndex()} finishes running successfully`);
DOM.reset(this.element, renderIcon(successStateIcon));
} else if (runState === NotebookCellRunState.Error) {
aria.alert(`Code cell at ${getCellIndex()} finishes running with errors`);
DOM.reset(this.element, renderIcon(errorStateIcon));
} else if (runState === NotebookCellRunState.Running) {
if (this.lastRunState !== NotebookCellRunState.Running) {
aria.alert(`Code cell at ${getCellIndex()} starts running`);
}
DOM.reset(this.element, renderIcon(syncing));
this.spinnerTimer = setTimeout(() => {
this.spinnerTimer = undefined;
if (this.pendingNewState) {
this.renderState(this.pendingNewState);
this.renderState(this.pendingNewState, getCellIndex);
this.pendingNewState = undefined;
}
}, RunStateRenderer.MIN_SPINNER_TIME);
@ -1136,6 +1149,8 @@ export class RunStateRenderer {
} else {
this.element.style.display = 'flex';
}
this.lastRunState = runState;
}
}