Merge pull request #190064 from microsoft/merogge/acc-view-symb-polish

apply `when` clauses to accessible view menu, fix some bugs, split code across files
This commit is contained in:
Megan Rogge
2023-08-09 15:25:09 -07:00
committed by GitHub
17 changed files with 507 additions and 497 deletions
@@ -3,256 +3,22 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Disposable } from 'vs/base/common/lifecycle';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
import { AccessibilityHelpNLS } from 'vs/editor/common/standaloneStrings';
import { ToggleTabFocusModeAction } from 'vs/editor/contrib/toggleTabFocusMode/browser/toggleTabFocusMode';
import { localize } from 'vs/nls';
import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { AccessibilityVerbositySettingId, accessibleViewIsShown, registerAccessibilityConfiguration } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration';
import * as strings from 'vs/base/common/strings';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { registerAccessibilityConfiguration } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration';
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
import { Registry } from 'vs/platform/registry/common/platform';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { NEW_UNTITLED_FILE_COMMAND_ID } from 'vs/workbench/contrib/files/browser/fileConstants';
import { ModesHoverController } from 'vs/editor/contrib/hover/browser/hover';
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
import { getNotificationFromContext } from 'vs/workbench/browser/parts/notifications/notificationsCommands';
import { IListService, WorkbenchList } from 'vs/platform/list/browser/listService';
import { NotificationFocusedContext } from 'vs/workbench/common/contextkeys';
import { IAccessibleViewService, AccessibleViewService, IAccessibleContentProvider, IAccessibleViewOptions, AccessibleViewType, AccessibilityHelpAction, AccessibleViewAction } from 'vs/workbench/contrib/accessibility/browser/accessibleView';
import { IHoverService } from 'vs/workbench/services/hover/browser/hover';
import { alert } from 'vs/base/browser/ui/aria/aria';
import { IAccessibleViewService, AccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView';
import { UnfocusedViewDimmingContribution } from 'vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution';
import { EditorAccessibilityHelpContribution, HoverAccessibleViewContribution, NotificationAccessibleViewContribution } from 'vs/workbench/contrib/accessibility/browser/accessibilityContributions';
registerAccessibilityConfiguration();
registerSingleton(IAccessibleViewService, AccessibleViewService, InstantiationType.Delayed);
class AccessibilityHelpProvider implements IAccessibleContentProvider {
onClose() {
this._editor.focus();
}
options: IAccessibleViewOptions = { type: AccessibleViewType.Help, ariaLabel: localize('editor-help', "editor accessibility help"), readMoreUrl: 'https://go.microsoft.com/fwlink/?linkid=851010' };
verbositySettingKey = AccessibilityVerbositySettingId.Editor;
constructor(
private readonly _editor: ICodeEditor,
@IKeybindingService private readonly _keybindingService: IKeybindingService
) {
}
private _descriptionForCommand(commandId: string, msg: string, noKbMsg: string): string {
const kb = this._keybindingService.lookupKeybinding(commandId);
if (kb) {
return strings.format(msg, kb.getAriaLabel());
}
return strings.format(noKbMsg, commandId);
}
provideContent(): string {
const options = this._editor.getOptions();
const content = [];
if (options.get(EditorOption.inDiffEditor)) {
if (options.get(EditorOption.readOnly)) {
content.push(AccessibilityHelpNLS.readonlyDiffEditor);
} else {
content.push(AccessibilityHelpNLS.editableDiffEditor);
}
} else {
if (options.get(EditorOption.readOnly)) {
content.push(AccessibilityHelpNLS.readonlyEditor);
} else {
content.push(AccessibilityHelpNLS.editableEditor);
}
}
if (options.get(EditorOption.tabFocusMode)) {
content.push(this._descriptionForCommand(ToggleTabFocusModeAction.ID, AccessibilityHelpNLS.tabFocusModeOnMsg, AccessibilityHelpNLS.tabFocusModeOnMsgNoKb));
} else {
content.push(this._descriptionForCommand(ToggleTabFocusModeAction.ID, AccessibilityHelpNLS.tabFocusModeOffMsg, AccessibilityHelpNLS.tabFocusModeOffMsgNoKb));
}
return content.join('\n');
}
}
class EditorAccessibilityHelpContribution extends Disposable {
static ID: 'editorAccessibilityHelpContribution';
constructor() {
super();
this._register(AccessibilityHelpAction.addImplementation(95, 'editor', async accessor => {
const codeEditorService = accessor.get(ICodeEditorService);
const accessibleViewService = accessor.get(IAccessibleViewService);
const instantiationService = accessor.get(IInstantiationService);
const commandService = accessor.get(ICommandService);
let codeEditor = codeEditorService.getActiveCodeEditor() || codeEditorService.getFocusedCodeEditor();
if (!codeEditor) {
await commandService.executeCommand(NEW_UNTITLED_FILE_COMMAND_ID);
codeEditor = codeEditorService.getActiveCodeEditor()!;
}
accessibleViewService.show(instantiationService.createInstance(AccessibilityHelpProvider, codeEditor));
}));
}
}
const workbenchRegistry = Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench);
workbenchRegistry.registerWorkbenchContribution(EditorAccessibilityHelpContribution, LifecyclePhase.Eventually);
workbenchRegistry.registerWorkbenchContribution(UnfocusedViewDimmingContribution, LifecyclePhase.Restored);
class HoverAccessibleViewContribution extends Disposable {
static ID: 'hoverAccessibleViewContribution';
private _options: IAccessibleViewOptions = {
ariaLabel: localize('hoverAccessibleView', "Hover Accessible View"), language: 'typescript', type: AccessibleViewType.View
};
constructor() {
super();
this._register(AccessibleViewAction.addImplementation(95, 'hover', accessor => {
const accessibleViewService = accessor.get(IAccessibleViewService);
const codeEditorService = accessor.get(ICodeEditorService);
const editor = codeEditorService.getActiveCodeEditor() || codeEditorService.getFocusedCodeEditor();
const editorHoverContent = editor ? ModesHoverController.get(editor)?.getWidgetContent() ?? undefined : undefined;
if (!editor || !editorHoverContent) {
return false;
}
this._options.language = editor?.getModel()?.getLanguageId() ?? undefined;
accessibleViewService.show({
verbositySettingKey: AccessibilityVerbositySettingId.Hover,
provideContent() { return editorHoverContent; },
onClose() {
ModesHoverController.get(editor)?.focus();
},
options: this._options
});
return true;
}, EditorContextKeys.hoverFocused));
this._register(AccessibleViewAction.addImplementation(90, 'extension-hover', accessor => {
const accessibleViewService = accessor.get(IAccessibleViewService);
const contextViewService = accessor.get(IContextViewService);
const contextViewElement = contextViewService.getContextViewElement();
const extensionHoverContent = contextViewElement?.textContent ?? undefined;
const hoverService = accessor.get(IHoverService);
if (contextViewElement.classList.contains('accessible-view-container') || !extensionHoverContent) {
// The accessible view, itself, uses the context view service to display the text. We don't want to read that.
return false;
}
accessibleViewService.show({
verbositySettingKey: AccessibilityVerbositySettingId.Hover,
provideContent() { return extensionHoverContent; },
onClose() {
hoverService.showAndFocusLastHover();
},
options: this._options
});
return true;
}));
this._register(AccessibilityHelpAction.addImplementation(115, 'accessible-view', accessor => {
accessor.get(IAccessibleViewService).showAccessibleViewHelp();
return true;
}, accessibleViewIsShown));
}
}
const workbenchContributionsRegistry = Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench);
workbenchContributionsRegistry.registerWorkbenchContribution(HoverAccessibleViewContribution, LifecyclePhase.Eventually);
class NotificationAccessibleViewContribution extends Disposable {
static ID: 'notificationAccessibleViewContribution';
constructor() {
super();
this._register(AccessibleViewAction.addImplementation(90, 'notifications', accessor => {
const accessibleViewService = accessor.get(IAccessibleViewService);
const listService = accessor.get(IListService);
const commandService = accessor.get(ICommandService);
function renderAccessibleView(): boolean {
const notification = getNotificationFromContext(listService);
if (!notification) {
return false;
}
commandService.executeCommand('notifications.showList');
let notificationIndex: number | undefined;
let length: number | undefined;
const list = listService.lastFocusedList;
if (list instanceof WorkbenchList) {
notificationIndex = list.indexOf(notification);
length = list.length;
}
if (notificationIndex === undefined) {
return false;
}
function focusList(): void {
commandService.executeCommand('notifications.showList');
if (list && notificationIndex !== undefined) {
list.domFocus();
try {
list.setFocus([notificationIndex]);
} catch { }
}
}
const message = notification.message.original.toString();
if (!message) {
return false;
}
accessibleViewService.show({
provideContent: () => {
return localize('notification.accessibleView', '{0} Source: {1}', message, notification.source);
},
onClose(): void {
focusList();
},
next(): void {
if (!list) {
return;
}
focusList();
list.focusNext();
alertFocusChange(notificationIndex, length, 'next');
renderAccessibleView();
},
previous(): void {
if (!list) {
return;
}
focusList();
list.focusPrevious();
alertFocusChange(notificationIndex, length, 'previous');
renderAccessibleView();
},
verbositySettingKey: AccessibilityVerbositySettingId.Notification,
options: {
ariaLabel: localize('notification', "Notification Accessible View"),
type: AccessibleViewType.View
}
});
return true;
}
return renderAccessibleView();
}, NotificationFocusedContext));
}
}
workbenchContributionsRegistry.registerWorkbenchContribution(NotificationAccessibleViewContribution, LifecyclePhase.Eventually);
export function alertFocusChange(index: number | undefined, length: number | undefined, type: 'next' | 'previous'): void {
if (index === undefined || length === undefined) {
return;
}
const number = index + 1;
if (type === 'next' && number + 1 <= length) {
alert(`Focused ${number + 1} of ${length}`);
} else if (type === 'previous' && number - 1 > 0) {
alert(`Focused ${number - 1} of ${length}`);
}
return;
}
@@ -0,0 +1,245 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Disposable } from 'vs/base/common/lifecycle';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
import { AccessibilityHelpNLS } from 'vs/editor/common/standaloneStrings';
import { ToggleTabFocusModeAction } from 'vs/editor/contrib/toggleTabFocusMode/browser/toggleTabFocusMode';
import { localize } from 'vs/nls';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { AccessibilityVerbositySettingId, accessibleViewIsShown } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration';
import * as strings from 'vs/base/common/strings';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { NEW_UNTITLED_FILE_COMMAND_ID } from 'vs/workbench/contrib/files/browser/fileConstants';
import { ModesHoverController } from 'vs/editor/contrib/hover/browser/hover';
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
import { getNotificationFromContext } from 'vs/workbench/browser/parts/notifications/notificationsCommands';
import { IListService, WorkbenchList } from 'vs/platform/list/browser/listService';
import { NotificationFocusedContext } from 'vs/workbench/common/contextkeys';
import { IAccessibleViewService, IAccessibleContentProvider, IAccessibleViewOptions, AccessibleViewType } from 'vs/workbench/contrib/accessibility/browser/accessibleView';
import { IHoverService } from 'vs/workbench/services/hover/browser/hover';
import { alert } from 'vs/base/browser/ui/aria/aria';
import { AccessibilityHelpAction, AccessibleViewAction } from 'vs/workbench/contrib/accessibility/browser/accessibleViewActions';
export class EditorAccessibilityHelpContribution extends Disposable {
static ID: 'editorAccessibilityHelpContribution';
constructor() {
super();
this._register(AccessibilityHelpAction.addImplementation(95, 'editor', async accessor => {
const codeEditorService = accessor.get(ICodeEditorService);
const accessibleViewService = accessor.get(IAccessibleViewService);
const instantiationService = accessor.get(IInstantiationService);
const commandService = accessor.get(ICommandService);
let codeEditor = codeEditorService.getActiveCodeEditor() || codeEditorService.getFocusedCodeEditor();
if (!codeEditor) {
await commandService.executeCommand(NEW_UNTITLED_FILE_COMMAND_ID);
codeEditor = codeEditorService.getActiveCodeEditor()!;
}
accessibleViewService.show(instantiationService.createInstance(AccessibilityHelpProvider, codeEditor));
}));
}
}
class AccessibilityHelpProvider implements IAccessibleContentProvider {
onClose() {
this._editor.focus();
}
options: IAccessibleViewOptions = { type: AccessibleViewType.Help, ariaLabel: localize('editor-help', "editor accessibility help"), readMoreUrl: 'https://go.microsoft.com/fwlink/?linkid=851010' };
verbositySettingKey = AccessibilityVerbositySettingId.Editor;
constructor(
private readonly _editor: ICodeEditor,
@IKeybindingService private readonly _keybindingService: IKeybindingService
) {
}
private _descriptionForCommand(commandId: string, msg: string, noKbMsg: string): string {
const kb = this._keybindingService.lookupKeybinding(commandId);
if (kb) {
return strings.format(msg, kb.getAriaLabel());
}
return strings.format(noKbMsg, commandId);
}
provideContent(): string {
const options = this._editor.getOptions();
const content = [];
if (options.get(EditorOption.inDiffEditor)) {
if (options.get(EditorOption.readOnly)) {
content.push(AccessibilityHelpNLS.readonlyDiffEditor);
} else {
content.push(AccessibilityHelpNLS.editableDiffEditor);
}
} else {
if (options.get(EditorOption.readOnly)) {
content.push(AccessibilityHelpNLS.readonlyEditor);
} else {
content.push(AccessibilityHelpNLS.editableEditor);
}
}
if (options.get(EditorOption.tabFocusMode)) {
content.push(this._descriptionForCommand(ToggleTabFocusModeAction.ID, AccessibilityHelpNLS.tabFocusModeOnMsg, AccessibilityHelpNLS.tabFocusModeOnMsgNoKb));
} else {
content.push(this._descriptionForCommand(ToggleTabFocusModeAction.ID, AccessibilityHelpNLS.tabFocusModeOffMsg, AccessibilityHelpNLS.tabFocusModeOffMsgNoKb));
}
return content.join('\n');
}
}
export class HoverAccessibleViewContribution extends Disposable {
static ID: 'hoverAccessibleViewContribution';
private _options: IAccessibleViewOptions = {
ariaLabel: localize('hoverAccessibleView', "Hover Accessible View"), language: 'typescript', type: AccessibleViewType.View
};
constructor() {
super();
this._register(AccessibleViewAction.addImplementation(95, 'hover', accessor => {
const accessibleViewService = accessor.get(IAccessibleViewService);
const codeEditorService = accessor.get(ICodeEditorService);
const editor = codeEditorService.getActiveCodeEditor() || codeEditorService.getFocusedCodeEditor();
const editorHoverContent = editor ? ModesHoverController.get(editor)?.getWidgetContent() ?? undefined : undefined;
if (!editor || !editorHoverContent) {
return false;
}
this._options.language = editor?.getModel()?.getLanguageId() ?? undefined;
accessibleViewService.show({
verbositySettingKey: AccessibilityVerbositySettingId.Hover,
provideContent() { return editorHoverContent; },
onClose() {
ModesHoverController.get(editor)?.focus();
},
options: this._options
});
return true;
}, EditorContextKeys.hoverFocused));
this._register(AccessibleViewAction.addImplementation(90, 'extension-hover', accessor => {
const accessibleViewService = accessor.get(IAccessibleViewService);
const contextViewService = accessor.get(IContextViewService);
const contextViewElement = contextViewService.getContextViewElement();
const extensionHoverContent = contextViewElement?.textContent ?? undefined;
const hoverService = accessor.get(IHoverService);
if (contextViewElement.classList.contains('accessible-view-container') || !extensionHoverContent) {
// The accessible view, itself, uses the context view service to display the text. We don't want to read that.
return false;
}
accessibleViewService.show({
verbositySettingKey: AccessibilityVerbositySettingId.Hover,
provideContent() { return extensionHoverContent; },
onClose() {
hoverService.showAndFocusLastHover();
},
options: this._options
});
return true;
}));
this._register(AccessibilityHelpAction.addImplementation(115, 'accessible-view', accessor => {
accessor.get(IAccessibleViewService).showAccessibleViewHelp();
return true;
}, accessibleViewIsShown));
}
}
export class NotificationAccessibleViewContribution extends Disposable {
static ID: 'notificationAccessibleViewContribution';
constructor() {
super();
this._register(AccessibleViewAction.addImplementation(90, 'notifications', accessor => {
const accessibleViewService = accessor.get(IAccessibleViewService);
const listService = accessor.get(IListService);
const commandService = accessor.get(ICommandService);
function renderAccessibleView(): boolean {
const notification = getNotificationFromContext(listService);
if (!notification) {
return false;
}
commandService.executeCommand('notifications.showList');
let notificationIndex: number | undefined;
let length: number | undefined;
const list = listService.lastFocusedList;
if (list instanceof WorkbenchList) {
notificationIndex = list.indexOf(notification);
length = list.length;
}
if (notificationIndex === undefined) {
return false;
}
function focusList(): void {
commandService.executeCommand('notifications.showList');
if (list && notificationIndex !== undefined) {
list.domFocus();
try {
list.setFocus([notificationIndex]);
} catch { }
}
}
const message = notification.message.original.toString();
if (!message) {
return false;
}
accessibleViewService.show({
provideContent: () => {
return localize('notification.accessibleView', '{0} Source: {1}', message, notification.source);
},
onClose(): void {
focusList();
},
next(): void {
if (!list) {
return;
}
focusList();
list.focusNext();
alertFocusChange(notificationIndex, length, 'next');
renderAccessibleView();
},
previous(): void {
if (!list) {
return;
}
focusList();
list.focusPrevious();
alertFocusChange(notificationIndex, length, 'previous');
renderAccessibleView();
},
verbositySettingKey: AccessibilityVerbositySettingId.Notification,
options: {
ariaLabel: localize('notification', "Notification Accessible View"),
type: AccessibleViewType.View
}
});
return true;
}
return renderAccessibleView();
}, NotificationFocusedContext));
}
}
export function alertFocusChange(index: number | undefined, length: number | undefined, type: 'next' | 'previous'): void {
if (index === undefined || length === undefined) {
return;
}
const number = index + 1;
if (type === 'next' && number + 1 <= length) {
alert(`Focused ${number + 1} of ${length}`);
} else if (type === 'previous' && number - 1 > 0) {
alert(`Focused ${number - 1} of ${length}`);
}
return;
}
@@ -6,14 +6,13 @@
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar';
import { alert } from 'vs/base/browser/ui/aria/aria';
import { Codicon } from 'vs/base/common/codicons';
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { KeyCode } from 'vs/base/common/keyCodes';
import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
import { marked } from 'vs/base/common/marked/marked';
import { isMacintosh } from 'vs/base/common/platform';
import { URI } from 'vs/base/common/uri';
import { IEditorConstructionOptions } from 'vs/editor/browser/config/editorConfiguration';
import { Command, EditorExtensionsRegistry, MultiCommand, ServicesAccessor } from 'vs/editor/browser/editorExtensions';
import { EditorExtensionsRegistry } from 'vs/editor/browser/editorExtensions';
import { CodeEditorWidget, ICodeEditorWidgetOptions } from 'vs/editor/browser/widget/codeEditorWidget';
import { ITextModel } from 'vs/editor/common/model';
import { IModelService } from 'vs/editor/common/services/model';
@@ -22,17 +21,17 @@ import { CodeActionController } from 'vs/editor/contrib/codeAction/browser/codeA
import { localize } from 'vs/nls';
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
import { MenuWorkbenchToolBar } from 'vs/platform/actions/browser/toolbar';
import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions';
import { MenuId } from 'vs/platform/actions/common/actions';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ContextKeyExpr, IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IContextViewDelegate, IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { IInstantiationService, createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { ILayoutService } from 'vs/platform/layout/browser/layoutService';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { IPickerQuickAccessItem } from 'vs/platform/quickinput/browser/pickerQuickAccess';
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
import { AccessibilityCommandId } from 'vs/workbench/contrib/accessibility/common/accessibilityCommands';
import { AccessibilityVerbositySettingId, accessibilityHelpIsShown, accessibleViewIsShown } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration';
import { getSimpleEditorOptions } from 'vs/workbench/contrib/codeEditor/browser/simpleEditorOptions';
@@ -143,31 +142,21 @@ class AccessibleView extends Disposable {
}));
}
show(provider?: IAccessibleContentProvider, symbol?: IAccessibleViewSymbol): void {
if (!provider) {
provider = this._currentProvider;
}
show(provider?: IAccessibleContentProvider, symbol?: IAccessibleViewSymbol, showAccessibleViewHelp?: boolean): void {
provider = provider ?? this._currentProvider;
if (!provider) {
return;
}
if (provider.options.type === AccessibleViewType.Help) {
this._accessiblityHelpIsShown.set(true);
} else {
this._accessibleViewIsShown.set(true);
}
const delegate: IContextViewDelegate = {
getAnchor: () => { return { x: (window.innerWidth / 2) - ((Math.min(this._layoutService.dimension.width * 0.62 /* golden cut */, DIMENSIONS.MAX_WIDTH)) / 2), y: this._layoutService.offset.quickPickTop }; },
render: (container) => {
container.classList.add('accessible-view-container');
return this._render(provider!, container);
return this._render(provider!, container, showAccessibleViewHelp);
},
onHide: () => {
if (provider!.options.type === AccessibleViewType.Help) {
this._accessiblityHelpIsShown.reset();
} else {
this._accessibleViewIsShown.reset();
if (!showAccessibleViewHelp) {
this._currentProvider = undefined;
}
this._currentProvider = undefined;
}
};
this._contextViewService.showContextView(delegate);
@@ -206,6 +195,7 @@ class AccessibleView extends Disposable {
return;
}
const symbols: IAccessibleViewSymbol[] = [];
let firstListItem: string | undefined;
for (const token of tokens) {
let label: string | undefined = undefined;
if ('type' in token) {
@@ -215,22 +205,29 @@ class AccessibleView extends Disposable {
case 'code':
label = token.text;
break;
case 'list':
case 'list': {
const firstItem = token.items?.[0];
if (!firstItem) {
break;
}
firstListItem = `- ${firstItem.text}`;
label = token.items?.map(i => i.text).join(', ');
break;
}
}
} else {
label = token.label;
}
if (label) {
symbols.push({ info: label, label: localize('symbolLabel', "({0}) {1}", token.type, label), ariaLabel: localize('symbolLabelAria', "({0}) {1}", token.type, label) });
symbols.push({ info: label, label: localize('symbolLabel', "({0}) {1}", token.type, label), ariaLabel: localize('symbolLabelAria', "({0}) {1}", token.type, label), firstListItem });
firstListItem = undefined;
}
}
return symbols;
}
showSymbol(provider: IAccessibleContentProvider, symbol: IAccessibleViewSymbol): void {
const index = provider.provideContent().split('\n').findIndex(line => line.includes(symbol.info.split('\n')[0])) ?? -1;
const index = provider.provideContent().split('\n').findIndex(line => line.includes(symbol.info.split('\n')[0]) || (symbol.firstListItem && line.includes(symbol.firstListItem))) ?? -1;
if (index >= 0) {
this.show(provider);
this._editorWidget.revealLine(index + 1);
@@ -246,10 +243,22 @@ class AccessibleView extends Disposable {
alert(localize('disableAccessibilityHelp', '{0} accessibility verbosity is now disabled', this._currentProvider.verbositySettingKey));
}
private _render(provider: IAccessibleContentProvider, container: HTMLElement, internal?: boolean): IDisposable {
if (!internal) {
private _updateContextKeys(provider: IAccessibleContentProvider, shown: boolean): void {
if (provider.options.type === AccessibleViewType.Help) {
this._accessiblityHelpIsShown.set(shown);
this._accessibleViewIsShown.set(!shown);
} else {
this._accessibleViewIsShown.set(shown);
this._accessiblityHelpIsShown.set(!shown);
}
}
private _render(provider: IAccessibleContentProvider, container: HTMLElement, showAccessibleViewHelp?: boolean): IDisposable {
if (!showAccessibleViewHelp) {
// don't overwrite the current provider
this._currentProvider = provider;
}
this._updateContextKeys(provider, true);
const value = this._configurationService.getValue(provider.verbositySettingKey);
const readMoreLink = provider.options.readMoreUrl ? localize("openDoc", "\nPress H now to open a browser window with more information related to accessibility.\n") : '';
let disableHelpHint = '';
@@ -290,19 +299,17 @@ class AccessibleView extends Disposable {
let helpHint = '';
const verbose = this._configurationService.getValue(provider.verbositySettingKey);
if (verbose && provider.options.type === AccessibleViewType.View) {
const accessibilityHelpKeybinding = this._keybindingService.lookupKeybinding('editor.action.accessibilityHelp')?.getLabel();
const accessibilityHelpKeybinding = this._keybindingService.lookupKeybinding(AccessibilityCommandId.OpenAccessibilityHelp)?.getLabel();
if (accessibilityHelpKeybinding) {
helpHint = localize('ariaAccessibilityHelp', "Use {0} for accessibility help", accessibilityHelpKeybinding);
}
if (helpHint) {
ariaLabel = provider.options.ariaLabel ? localize('helpAriaKb', "{0}, {1}", provider.options.ariaLabel, helpHint) : localize('accessible-view', "Accessible View, {0}", helpHint);
} else {
ariaLabel = provider.options.ariaLabel ? provider.options.ariaLabel : localize('helpAriaNoKb', "Accessible View");
}
}
if (internal) {
ariaLabel = localize('accessibleViewHelp', "Accessible View Help");
if (helpHint) {
ariaLabel = provider.options.ariaLabel ? localize('helpAriaKb', "{0}, {1}", provider.options.ariaLabel, helpHint) : localize('accessible-view', "Accessible View, {0}", helpHint);
} else {
ariaLabel = provider.options.ariaLabel ? provider.options.ariaLabel : localize('helpAriaNoKb', "Accessible View");
}
this._editorWidget.updateOptions({ ariaLabel });
this._editorWidget.focus();
});
@@ -314,6 +321,7 @@ class AccessibleView extends Disposable {
if (e.keyCode === KeyCode.Escape) {
e.stopPropagation();
this._contextViewService.hideContextView();
this._updateContextKeys(provider, false);
// HACK: Delay to allow the context view to hide #186514
setTimeout(() => provider.onClose(), 100);
} else if (e.keyCode === KeyCode.KeyH && provider.options.readMoreUrl) {
@@ -359,29 +367,28 @@ class AccessibleView extends Disposable {
return;
}
const previousProvider = Object.assign({}, this._currentProvider);
const accessibleViewHelpProvider = Object.assign({}, this._currentProvider);
accessibleViewHelpProvider.options.type = AccessibleViewType.Help;
accessibleViewHelpProvider.provideContent = () => this._getAccessibleViewHelpDialogContent(accessibleViewHelpProvider);
accessibleViewHelpProvider.onClose = () => this.show(previousProvider);
const currentProvider = Object.assign({}, this._currentProvider);
currentProvider.options = Object.assign({}, currentProvider.options);
const currentProviderHasSymbols = this._currentProvider.options.language === 'markdown' || this._currentProvider.options.language === undefined || !!this._currentProvider.getSymbols;
const accessibleViewHelpProvider: IAccessibleContentProvider = {
provideContent: () => this._getAccessibleViewHelpDialogContent(currentProviderHasSymbols),
onClose: () => this.show(currentProvider),
options: {
ariaLabel: localize('accessibleViewHelp', "Accessible View Help"),
type: AccessibleViewType.Help,
},
verbositySettingKey: this._currentProvider.verbositySettingKey
};
this._contextViewService.hideContextView();
// HACK: Delay to allow the context view to hide #186514
setTimeout(() => {
const delegate: IContextViewDelegate = {
getAnchor: () => { return { x: (window.innerWidth / 2) - ((Math.min(this._layoutService.dimension.width * 0.62 /* golden cut */, DIMENSIONS.MAX_WIDTH)) / 2), y: this._layoutService.offset.quickPickTop }; },
render: (container) => {
container.classList.add('accessible-view-container');
return this._render(accessibleViewHelpProvider, container, true);
}
};
this._contextViewService.showContextView(delegate);
}, 100);
setTimeout(() => this.show(accessibleViewHelpProvider, undefined, true), 100);
}
private _getAccessibleViewHelpDialogContent(provider: IAccessibleContentProvider): string {
private _getAccessibleViewHelpDialogContent(providerHasSymbols?: boolean): string {
const navigationHint = this._getNavigationHint();
const goToSymbolHint = this._getGoToSymbolHint(provider);
const toolbarHint = this._getToolbarHint();
const goToSymbolHint = this._getGoToSymbolHint(providerHasSymbols);
const toolbarHint = localize('toolbar', "Navigate to the toolbar ({0} or Shift+Tab)");
let hint = localize('intro', "In the accessible view, you can:\n");
if (navigationHint) {
hint += ' - ' + navigationHint + '\n';
@@ -395,21 +402,10 @@ class AccessibleView extends Disposable {
return hint;
}
private _getToolbarHint(): string {
let toolbarHint = '';
const toolbarKb = this._keybindingService.lookupKeybinding('editor.action.accessibleViewFocusToolbar')?.getLabel();
if (toolbarKb) {
toolbarHint = localize('toolbar', "Navigate to the toolbar ({0} or Shift+Tab)", toolbarKb);
} else {
toolbarHint = localize('toolbarNoKb', "Navigate to the toolbar (Shift+Tab)");
}
return toolbarHint;
}
private _getNavigationHint(): string {
let hint = '';
const nextKeybinding = this._keybindingService.lookupKeybinding('editor.action.accessibleViewNext')?.getAriaLabel();
const previousKeybinding = this._keybindingService.lookupKeybinding('editor.action.accessibleViewPrevious')?.getAriaLabel();
const nextKeybinding = this._keybindingService.lookupKeybinding(AccessibilityCommandId.ShowNext)?.getAriaLabel();
const previousKeybinding = this._keybindingService.lookupKeybinding(AccessibilityCommandId.ShowPrevious)?.getAriaLabel();
if (nextKeybinding && previousKeybinding) {
hint = localize('accessibleViewNextPreviousHint', "Show the next ({0}) or previous ({1}) item", nextKeybinding, previousKeybinding);
} else {
@@ -422,7 +418,7 @@ class AccessibleView extends Disposable {
return '';
}
let hint = '';
const disableKeybinding = this._keybindingService.lookupKeybinding('editor.action.accessibleViewDisableHint', this._contextKeyService)?.getAriaLabel();
const disableKeybinding = this._keybindingService.lookupKeybinding(AccessibilityCommandId.DisableVerbosityHint, this._contextKeyService)?.getAriaLabel();
if (disableKeybinding) {
hint = localize('acessibleViewDisableHint', "Disable the aria label hint to open this ({0})", disableKeybinding);
} else {
@@ -431,11 +427,10 @@ class AccessibleView extends Disposable {
return hint;
}
private _getGoToSymbolHint(provider: IAccessibleContentProvider): string {
const goToSymbolKb = this._keybindingService.lookupKeybinding('editor.action.accessibleViewGoToSymbol')?.getAriaLabel();
const hasSymbolProvider = provider.options.language === 'markdown' || provider.options.language === undefined || !!provider.getSymbols;
private _getGoToSymbolHint(providerHasSymbols?: boolean): string {
const goToSymbolKb = this._keybindingService.lookupKeybinding(AccessibilityCommandId.GoToSymbol)?.getAriaLabel();
let goToSymbolHint = '';
if (hasSymbolProvider) {
if (providerHasSymbols) {
if (goToSymbolKb) {
goToSymbolHint = localize('goToSymbolHint', 'Go to a symbol ({0})', goToSymbolKb);
} else {
@@ -478,7 +473,7 @@ export class AccessibleViewService extends Disposable implements IAccessibleView
if (!this._configurationService.getValue(verbositySettingKey)) {
return null;
}
const keybinding = this._keybindingService.lookupKeybinding(AccessibleViewAction.id)?.getAriaLabel();
const keybinding = this._keybindingService.lookupKeybinding(AccessibilityCommandId.OpenAccessibleView)?.getAriaLabel();
let hint = null;
if (keybinding) {
hint = localize('acessibleViewHint', "Inspect this in the accessible view with {0}", keybinding);
@@ -535,180 +530,5 @@ class AccessibleViewSymbolQuickPick {
interface IAccessibleViewSymbol extends IPickerQuickAccessItem {
info: string;
firstListItem?: string;
}
class AccessibleViewNextAction extends Action2 {
constructor() {
super({
id: 'editor.action.accessibleViewNext',
precondition: ContextKeyExpr.and(accessibleViewIsShown, accessibilityHelpIsShown.negate()),
keybinding: {
primary: KeyMod.Alt | KeyCode.BracketRight,
weight: KeybindingWeight.WorkbenchContrib
},
menu: [{
id: MenuId.CommandPalette,
group: '',
order: 1
},
{ id: MenuId.AccessibleView, group: 'navigation' }],
icon: Codicon.chevronRight,
title: localize('editor.action.accessibleViewNext', "Show Next in Accessible View")
});
}
run(accessor: ServicesAccessor): void {
accessor.get(IAccessibleViewService).next();
}
}
registerAction2(AccessibleViewNextAction);
class AccessibleViewPreviousAction extends Action2 {
constructor() {
super({
id: 'editor.action.accessibleViewPrevious',
precondition: ContextKeyExpr.and(accessibleViewIsShown, accessibilityHelpIsShown.negate()),
keybinding: {
primary: KeyMod.Alt | KeyCode.BracketLeft,
weight: KeybindingWeight.WorkbenchContrib
},
icon: Codicon.chevronLeft,
menu: [{
id: MenuId.CommandPalette,
group: '',
},
{
id: MenuId.AccessibleView,
group: 'navigation'
}],
title: localize('editor.action.accessibleViewPrevious', "Show Previous in Accessible View")
});
}
run(accessor: ServicesAccessor): void {
accessor.get(IAccessibleViewService).previous();
}
}
registerAction2(AccessibleViewPreviousAction);
class AccessibleViewGoToSymbolAction extends Action2 {
constructor() {
super({
id: 'editor.action.accessibleViewGoToSymbol',
precondition: ContextKeyExpr.and(accessibleViewIsShown, accessibilityHelpIsShown.negate()),
keybinding: {
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyO,
weight: KeybindingWeight.WorkbenchContrib + 10
},
icon: Codicon.symbolField,
menu: [{
id: MenuId.CommandPalette,
group: '',
order: 1
}, {
id: MenuId.AccessibleView,
group: 'navigation'
}],
title: localize('editor.action.accessibleViewGoToSymbol', "Go To Symbol in Accessible View")
});
}
run(accessor: ServicesAccessor): void {
accessor.get(IAccessibleViewService).goToSymbol();
}
}
registerAction2(AccessibleViewGoToSymbolAction);
function registerCommand<T extends Command>(command: T): T {
command.register();
return command;
}
export const AccessibilityHelpAction = registerCommand(new MultiCommand({
id: 'editor.action.accessibilityHelp',
precondition: undefined,
kbOpts: {
primary: KeyMod.Alt | KeyCode.F1,
weight: KeybindingWeight.WorkbenchContrib,
linux: {
primary: KeyMod.Alt | KeyMod.Shift | KeyCode.F1,
secondary: [KeyMod.Alt | KeyCode.F1]
}
},
menuOpts: [{
menuId: MenuId.CommandPalette,
group: '',
title: localize('editor.action.accessibilityHelp', "Open Accessibility Help"),
order: 1
}],
}));
export const AccessibleViewAction = registerCommand(new MultiCommand({
id: 'editor.action.accessibleView',
precondition: undefined,
kbOpts: {
primary: KeyMod.Alt | KeyCode.F2,
weight: KeybindingWeight.WorkbenchContrib,
linux: {
primary: KeyMod.Alt | KeyMod.Shift | KeyCode.F2,
secondary: [KeyMod.Alt | KeyCode.F2]
}
},
menuOpts: [{
menuId: MenuId.CommandPalette,
group: '',
title: localize('editor.action.accessibleView', "Open Accessible View"),
order: 1
}],
}));
class AccessibleViewDisableHintAction extends Action2 {
constructor() {
super({
id: 'editor.action.accessibleViewDisableHint',
keybinding: {
when: ContextKeyExpr.or(accessibleViewIsShown, accessibilityHelpIsShown),
primary: KeyMod.Alt | KeyCode.F6,
weight: KeybindingWeight.WorkbenchContrib
},
icon: Codicon.treeFilterClear,
menu: [{
id: MenuId.CommandPalette,
group: '',
order: 1
},
{
id: MenuId.AccessibleView,
group: 'navigation'
}],
title: localize('editor.action.accessibleViewDisableHint', "Disable Accessible View Hint")
});
}
run(accessor: ServicesAccessor): void {
accessor.get(IAccessibleViewService).disableHint();
}
}
registerAction2(AccessibleViewDisableHintAction);
class AccessibleViewFocusToolbarAction extends Action2 {
constructor() {
super({
id: 'editor.action.accessibleViewFocusToolbar',
keybinding: {
when: accessibleViewIsShown,
primary: KeyMod.Alt | KeyCode.F7,
weight: KeybindingWeight.WorkbenchContrib
},
menu: [{
id: MenuId.CommandPalette,
group: '',
order: 1
}],
title: localize('editor.action.accessibleViewFocusToolbar', "Accessible View Focus Toolbar")
});
}
run(accessor: ServicesAccessor): void {
accessor.get(IAccessibleViewService).focusToolbar();
}
}
registerAction2(AccessibleViewFocusToolbarAction);
@@ -0,0 +1,156 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Codicon } from 'vs/base/common/codicons';
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { Command, MultiCommand, ServicesAccessor } from 'vs/editor/browser/editorExtensions';
import { localize } from 'vs/nls';
import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { AccessibilityCommandId } from 'vs/workbench/contrib/accessibility/common/accessibilityCommands';
import { accessibilityHelpIsShown, accessibleViewIsShown } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration';
import { IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView';
const accessibleViewMenu = {
id: MenuId.AccessibleView,
group: 'navigation',
when: accessibleViewIsShown
};
const commandPalette = {
id: MenuId.CommandPalette,
group: '',
order: 1
};
class AccessibleViewNextAction extends Action2 {
constructor() {
super({
id: AccessibilityCommandId.ShowNext,
precondition: accessibleViewIsShown,
keybinding: {
primary: KeyMod.Alt | KeyCode.BracketRight,
weight: KeybindingWeight.WorkbenchContrib
},
menu: [commandPalette, accessibleViewMenu],
icon: Codicon.chevronRight,
title: localize('editor.action.accessibleViewNext', "Show Next in Accessible View")
});
}
run(accessor: ServicesAccessor): void {
accessor.get(IAccessibleViewService).next();
}
}
registerAction2(AccessibleViewNextAction);
class AccessibleViewPreviousAction extends Action2 {
constructor() {
super({
id: AccessibilityCommandId.ShowPrevious,
precondition: accessibleViewIsShown,
keybinding: {
primary: KeyMod.Alt | KeyCode.BracketLeft,
weight: KeybindingWeight.WorkbenchContrib
},
icon: Codicon.chevronLeft,
menu: [commandPalette, accessibleViewMenu],
title: localize('editor.action.accessibleViewPrevious', "Show Previous in Accessible View")
});
}
run(accessor: ServicesAccessor): void {
accessor.get(IAccessibleViewService).previous();
}
}
registerAction2(AccessibleViewPreviousAction);
class AccessibleViewGoToSymbolAction extends Action2 {
constructor() {
super({
id: AccessibilityCommandId.GoToSymbol,
precondition: accessibleViewIsShown,
keybinding: {
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyO,
weight: KeybindingWeight.WorkbenchContrib + 10
},
icon: Codicon.symbolField,
menu: [commandPalette, accessibleViewMenu],
title: localize('editor.action.accessibleViewGoToSymbol', "Go To Symbol in Accessible View")
});
}
run(accessor: ServicesAccessor): void {
accessor.get(IAccessibleViewService).goToSymbol();
}
}
registerAction2(AccessibleViewGoToSymbolAction);
function registerCommand<T extends Command>(command: T): T {
command.register();
return command;
}
export const AccessibilityHelpAction = registerCommand(new MultiCommand({
id: AccessibilityCommandId.OpenAccessibilityHelp,
precondition: undefined,
kbOpts: {
primary: KeyMod.Alt | KeyCode.F1,
weight: KeybindingWeight.WorkbenchContrib,
linux: {
primary: KeyMod.Alt | KeyMod.Shift | KeyCode.F1,
secondary: [KeyMod.Alt | KeyCode.F1]
}
},
menuOpts: [{
menuId: MenuId.CommandPalette,
group: '',
title: localize('editor.action.accessibilityHelp', "Open Accessibility Help"),
order: 1
}],
}));
export const AccessibleViewAction = registerCommand(new MultiCommand({
id: AccessibilityCommandId.OpenAccessibleView,
precondition: undefined,
kbOpts: {
primary: KeyMod.Alt | KeyCode.F2,
weight: KeybindingWeight.WorkbenchContrib,
linux: {
primary: KeyMod.Alt | KeyMod.Shift | KeyCode.F2,
secondary: [KeyMod.Alt | KeyCode.F2]
}
},
menuOpts: [{
menuId: MenuId.CommandPalette,
group: '',
title: localize('editor.action.accessibleView', "Open Accessible View"),
order: 1
}],
}));
class AccessibleViewDisableHintAction extends Action2 {
constructor() {
super({
id: AccessibilityCommandId.DisableVerbosityHint,
keybinding: {
when: ContextKeyExpr.or(accessibleViewIsShown, accessibilityHelpIsShown),
primary: KeyMod.Alt | KeyCode.F6,
weight: KeybindingWeight.WorkbenchContrib
},
icon: Codicon.treeFilterClear,
menu: [commandPalette,
{
id: MenuId.AccessibleView,
group: 'navigation',
when: ContextKeyExpr.or(accessibleViewIsShown, accessibilityHelpIsShown)
}],
title: localize('editor.action.accessibleViewDisableHint', "Disable Accessible View Hint")
});
}
run(accessor: ServicesAccessor): void {
accessor.get(IAccessibleViewService).disableHint();
}
}
registerAction2(AccessibleViewDisableHintAction);
@@ -0,0 +1,13 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export const enum AccessibilityCommandId {
OpenAccessibleView = 'editor.action.accessibleView',
OpenAccessibilityHelp = 'editor.action.accessibilityHelp',
DisableVerbosityHint = 'editor.action.accessibleViewDisableHint',
GoToSymbol = 'editor.action.accessibleViewGoToSymbol',
ShowNext = 'editor.action.accessibleViewNext',
ShowPrevious = 'editor.action.accessibleViewPrevious'
}
@@ -29,7 +29,7 @@ import { IChatWidgetHistoryService } from 'vs/workbench/contrib/chat/common/chat
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { Registry } from 'vs/platform/registry/common/platform';
import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
import { AccessibilityHelpAction } from 'vs/workbench/contrib/accessibility/browser/accessibleView';
import { AccessibilityHelpAction } from 'vs/workbench/contrib/accessibility/browser/accessibleViewActions';
export const CHAT_CATEGORY = { value: localize('chat.category', "Chat"), original: 'Chat' };
@@ -37,17 +37,18 @@ import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle
import '../common/chatColors';
import { registerMoveActions } from 'vs/workbench/contrib/chat/browser/actions/chatMoveActions';
import { ACTION_ID_CLEAR_CHAT, registerClearActions } from 'vs/workbench/contrib/chat/browser/actions/chatClearActions';
import { AccessibleViewAction, AccessibleViewType, IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView';
import { AccessibleViewType, IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView';
import { isResponseVM } from 'vs/workbench/contrib/chat/common/chatViewModel';
import { CONTEXT_IN_CHAT_SESSION } from 'vs/workbench/contrib/chat/common/chatContextKeys';
import { ChatAccessibilityService } from 'vs/workbench/contrib/chat/browser/chatAccessibilityService';
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
import { alertFocusChange } from 'vs/workbench/contrib/accessibility/browser/accessibility.contribution';
import { AccessibilityVerbositySettingId } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration';
import { ChatWelcomeMessageModel } from 'vs/workbench/contrib/chat/common/chatModel';
import { IMarkdownString } from 'vs/base/common/htmlContent';
import { ChatProviderService, IChatProviderService } from 'vs/workbench/contrib/chat/common/chatProvider';
import { ChatSlashCommandService, IChatSlashCommandService } from 'vs/workbench/contrib/chat/common/chatSlashCommands';
import { alertFocusChange } from 'vs/workbench/contrib/accessibility/browser/accessibilityContributions';
import { AccessibleViewAction } from 'vs/workbench/contrib/accessibility/browser/accessibleViewActions';
import { ICommandService } from 'vs/platform/commands/common/commands';
// Register configuration
@@ -33,6 +33,7 @@ import { IChatWidgetHistoryService } from 'vs/workbench/contrib/chat/common/chat
import { AccessibilityVerbositySettingId } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration';
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
import { isMacintosh } from 'vs/base/common/platform';
import { AccessibilityCommandId } from 'vs/workbench/contrib/accessibility/common/accessibilityCommands';
const $ = dom.$;
@@ -101,7 +102,7 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge
private _getAriaLabel(): string {
const verbose = this.configurationService.getValue<boolean>(AccessibilityVerbositySettingId.Chat);
if (verbose) {
const kbLabel = this.keybindingService.lookupKeybinding('editor.action.accessibilityHelp')?.getLabel();
const kbLabel = this.keybindingService.lookupKeybinding(AccessibilityCommandId.OpenAccessibilityHelp)?.getLabel();
return kbLabel ? localize('actions.chat.accessibiltyHelp', "Chat Input, Type to ask questions or type / for topics, press enter to send out the request. Use {0} for Chat Accessibility Help.", kbLabel) : localize('chatInput.accessibilityHelpNoKb', "Chat Input, Type code here and press Enter to run. Use the Chat Accessibility Help command for more information.");
}
return localize('chatInput', "Chat Input");
@@ -20,7 +20,8 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
import { FloatingClickWidget } from 'vs/workbench/browser/codeeditor';
import { AccessibilityVerbositySettingId } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration';
import { AccessibilityHelpAction, AccessibleViewType, IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView';
import { AccessibleViewType, IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView';
import { AccessibilityHelpAction } from 'vs/workbench/contrib/accessibility/browser/accessibleViewActions';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
class DiffEditorHelperContribution extends Disposable implements IDiffEditorContribution {
@@ -15,12 +15,13 @@ import { Registry } from 'vs/platform/registry/common/platform';
import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
import { InlineChatNotebookContribution } from 'vs/workbench/contrib/inlineChat/browser/inlineChatNotebook';
import { AccessibilityVerbositySettingId } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration';
import { AccessibleViewAction, AccessibleViewType, IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView';
import { AccessibleViewType, IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView';
import { Disposable } from 'vs/base/common/lifecycle';
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
import { localize } from 'vs/nls';
import { Extensions, IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { AccessibleViewAction } from 'vs/workbench/contrib/accessibility/browser/accessibleViewActions';
registerSingleton(IInlineChatService, InlineChatServiceImpl, InstantiationType.Delayed);
registerSingleton(IInlineChatSessionService, InlineChatSessionService, InstantiationType.Delayed);
@@ -31,7 +31,7 @@ import { Disposable } from 'vs/base/common/lifecycle';
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
import { Position } from 'vs/editor/common/core/position';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { AccessibilityHelpAction } from 'vs/workbench/contrib/accessibility/browser/accessibleView';
import { AccessibilityHelpAction } from 'vs/workbench/contrib/accessibility/browser/accessibleViewActions';
CommandsRegistry.registerCommandAlias('interactiveEditor.start', 'inlineChat.start');
@@ -53,6 +53,7 @@ import { SlashCommandContentWidget } from 'vs/workbench/contrib/chat/browser/cha
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView';
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
import { AccessibilityCommandId } from 'vs/workbench/contrib/accessibility/common/accessibilityCommands';
const defaultAriaLabel = localize('aria-label', "Inline Chat Input");
@@ -392,7 +393,7 @@ export class InlineChatWidget {
}
let label = defaultAriaLabel;
if (this._configurationService.getValue<boolean>(AccessibilityVerbositySettingId.InlineChat)) {
const kbLabel = this._keybindingService.lookupKeybinding('editor.action.accessibilityHelp')?.getLabel();
const kbLabel = this._keybindingService.lookupKeybinding(AccessibilityCommandId.OpenAccessibilityHelp)?.getLabel();
label = kbLabel ? localize('inlineChat.accessibilityHelp', "Inline Chat Input, Use {0} for Inline Chat Accessibility Help.", kbLabel) : localize('inlineChat.accessibilityHelpNoKb', "Inline Chat Input, Run the Inline Chat Accessibility Help command for more information.");
}
_inputEditorOptions.ariaLabel = label;
@@ -114,8 +114,9 @@ import { NotebookLoggingService } from 'vs/workbench/contrib/notebook/browser/se
import product from 'vs/platform/product/common/product';
import { NOTEBOOK_IS_ACTIVE_EDITOR, NOTEBOOK_OUTPUT_FOCUSED } from 'vs/workbench/contrib/notebook/common/notebookContextKeys';
import { runAccessibilityHelpAction, showAccessibleOutput } from 'vs/workbench/contrib/notebook/browser/notebookAccessibility';
import { AccessibilityHelpAction, AccessibleViewAction, IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView';
import { IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { AccessibilityHelpAction, AccessibleViewAction } from 'vs/workbench/contrib/accessibility/browser/accessibleViewActions';
/*--------------------------------------------------------------------------------------------- */
@@ -99,6 +99,7 @@ import { NotebookCellOutlineProvider } from 'vs/workbench/contrib/notebook/brows
import { AccessibilityVerbositySettingId } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { OutlineTarget } from 'vs/workbench/services/outline/browser/outline';
import { AccessibilityCommandId } from 'vs/workbench/contrib/accessibility/common/accessibilityCommands';
const $ = DOM.$;
@@ -872,7 +873,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD
this._register(this._listDelegate);
const createNotebookAriaLabel = () => {
const keybinding = this.keybindingService.lookupKeybinding('editor.action.accessibilityHelp')?.getLabel();
const keybinding = this.keybindingService.lookupKeybinding(AccessibilityCommandId.OpenAccessibilityHelp)?.getLabel();
if (this.configurationService.getValue(AccessibilityVerbositySettingId.Notebook)) {
return keybinding
@@ -86,6 +86,7 @@ import { IPreferencesService } from 'vs/workbench/services/preferences/common/pr
import { importAMDNodeModule } from 'vs/amdX';
import { ISimpleSelectedSuggestion } from 'vs/workbench/services/suggest/browser/simpleSuggestWidget';
import type { IMarker, Terminal as XTermTerminal } from 'xterm';
import { AccessibilityCommandId } from 'vs/workbench/contrib/accessibility/common/accessibilityCommands';
const enum Constants {
/**
@@ -1886,7 +1887,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
if (!screenReaderOptimized) {
labelParts.push(nls.localize('terminalScreenReaderMode', "Run the command: Toggle Screen Reader Accessibility Mode for an optimized screen reader experience"));
}
const accessibilityHelpKeybinding = this._keybindingService.lookupKeybinding('editor.action.accessibilityHelp')?.getLabel();
const accessibilityHelpKeybinding = this._keybindingService.lookupKeybinding(AccessibilityCommandId.OpenAccessibilityHelp)?.getLabel();
if (this._configurationService.getValue(AccessibilityVerbositySettingId.Terminal) && accessibilityHelpKeybinding) {
labelParts.push(nls.localize('terminalHelpAriaLabel', "Use {0} for terminal accessibility help", accessibilityHelpKeybinding));
}
@@ -14,6 +14,7 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'
import { ISerializedCommandDetectionCapability, ITerminalCapabilityStore } from 'vs/platform/terminal/common/capabilities/capabilities';
import { IMergedEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariable';
import { ICreateContributedTerminalProfileOptions, IExtensionTerminalProfile, IFixedTerminalDimensions, IProcessDataEvent, IProcessProperty, IProcessPropertyMap, IProcessReadyEvent, IProcessReadyWindowsPty, IShellLaunchConfig, ITerminalBackend, ITerminalContributions, ITerminalEnvironment, ITerminalLaunchError, ITerminalProfile, ITerminalProfileObject, ProcessPropertyType, TerminalIcon, TerminalLocationString, TitleEventSource } from 'vs/platform/terminal/common/terminal';
import { AccessibilityCommandId } from 'vs/workbench/contrib/accessibility/common/accessibilityCommands';
import { IEnvironmentVariableInfo } from 'vs/workbench/contrib/terminal/common/environmentVariable';
import { IExtensionPointDescriptor } from 'vs/workbench/services/extensions/common/extensionsRegistry';
@@ -567,7 +568,7 @@ export const DEFAULT_COMMANDS_TO_SKIP_SHELL: string[] = [
TerminalCommandId.AcceptSelectedSuggestion,
TerminalCommandId.HideSuggestWidget,
TerminalCommandId.FocusHover,
'editor.action.accessibilityHelp',
AccessibilityCommandId.OpenAccessibilityHelp,
'editor.action.toggleTabFocusMode',
'notifications.hideList',
'notifications.hideToasts',
@@ -12,7 +12,8 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { IQuickPick, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
import { terminalTabFocusModeContextKey } from 'vs/platform/terminal/common/terminal';
import { AccessibilityHelpAction, IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView';
import { IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView';
import { AccessibilityHelpAction } from 'vs/workbench/contrib/accessibility/browser/accessibleViewActions';
import { ITerminalContribution, ITerminalInstance, ITerminalService, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal';
import { registerTerminalAction } from 'vs/workbench/contrib/terminal/browser/terminalActions';
import { registerTerminalContribution } from 'vs/workbench/contrib/terminal/browser/terminalExtensions';