Skip to content

Commit

Permalink
resolve accessibility help dialog kbs in accessibleViewService (mic…
Browse files Browse the repository at this point in the history
  • Loading branch information
meganrogge authored and andremmsilva committed May 26, 2024
1 parent 9e7a86c commit 82348ce
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 178 deletions.
15 changes: 5 additions & 10 deletions src/vs/editor/common/standaloneStrings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,14 @@ export namespace AccessibilityHelpNLS {
export const auto_off = nls.localize("auto_off", "The application is configured to never be optimized for usage with a Screen Reader.");
export const screenReaderModeEnabled = nls.localize("screenReaderModeEnabled", "Screen Reader Optimized Mode enabled.");
export const screenReaderModeDisabled = nls.localize("screenReaderModeDisabled", "Screen Reader Optimized Mode disabled.");
export const tabFocusModeOnMsg = nls.localize("tabFocusModeOnMsg", "Pressing Tab in the current editor will move focus to the next focusable element. Toggle this behavior {0}.");
export const tabFocusModeOnMsgNoKb = nls.localize("tabFocusModeOnMsgNoKb", "Pressing Tab in the current editor will move focus to the next focusable element. The command {0} is currently not triggerable by a keybinding.");
export const stickScrollKb = nls.localize("stickScrollKb", "Focus Sticky Scroll ({0}) to focus the currently nested scopes.");
export const stickScrollNoKb = nls.localize("stickScrollNoKb", "Focus Sticky Scroll to focus the currently nested scopes. It is currently not triggerable by a keybinding.");
export const tabFocusModeOffMsg = nls.localize("tabFocusModeOffMsg", "Pressing Tab in the current editor will insert the tab character. Toggle this behavior {0}.");
export const tabFocusModeOffMsgNoKb = nls.localize("tabFocusModeOffMsgNoKb", "Pressing Tab in the current editor will insert the tab character. The command {0} is currently not triggerable by a keybinding.");
export const tabFocusModeOnMsg = nls.localize("tabFocusModeOnMsg", "Pressing Tab in the current editor will move focus to the next focusable element. Toggle this behavior<keybinding:editor.action.toggleTabFocusMode>");
export const tabFocusModeOffMsg = nls.localize("tabFocusModeOffMsg", "Pressing Tab in the current editor will insert the tab character. Toggle this behavior<keybinding:editor.action.toggleTabFocusMode>");
export const stickScroll = nls.localize("stickScrollKb", "Focus Sticky Scroll<keybinding:editor.action.focusStickyScroll> to focus the currently nested scopes.");
export const showAccessibilityHelpAction = nls.localize("showAccessibilityHelpAction", "Show Accessibility Help");
export const listSignalSounds = nls.localize("listSignalSoundsCommand", "Run the command: List Signal Sounds for an overview of all sounds and their current status.");
export const listAlerts = nls.localize("listAnnouncementsCommand", "Run the command: List Signal Announcements for an overview of announcements and their current status.");
export const quickChat = nls.localize("quickChatCommand", "Toggle quick chat ({0}) to open or close a chat session.");
export const quickChatNoKb = nls.localize("quickChatCommandNoKb", "Toggle quick chat is not currently triggerable by a keybinding.");
export const startInlineChat = nls.localize("startInlineChatCommand", "Start inline chat ({0}) to create an in editor chat session.");
export const startInlineChatNoKb = nls.localize("startInlineChatCommandNoKb", "The command: Start inline chat is not currentlyt riggerable by a keybinding.");
export const quickChat = nls.localize("quickChatCommand", "Toggle quick chat<keybinding:workbench.action.quickchat.toggle> to open or close a chat session.",);
export const startInlineChat = nls.localize("startInlineChatCommand", "Start inline chat<keybinding:inlineChat.start> to create an in editor chat session.");
}

export namespace InspectTokensNLS {
Expand Down
13 changes: 12 additions & 1 deletion src/vs/workbench/contrib/accessibility/browser/accessibleView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import { IOpenerService } from 'vs/platform/opener/common/opener';
import { IQuickInputService, IQuickPick, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
import { AccessibilityVerbositySettingId, AccessibilityWorkbenchSettingId, accessibilityHelpIsShown, accessibleViewContainsCodeBlocks, accessibleViewCurrentProviderId, accessibleViewGoToSymbolSupported, accessibleViewInCodeBlock, accessibleViewIsShown, accessibleViewOnLastLine, accessibleViewSupportsNavigation, accessibleViewVerbosityEnabled } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration';
import { resolveContentAndKeybindingItems } from 'vs/workbench/contrib/accessibility/browser/accessibleViewKeybindingResolver';
import { AccessibilityCommandId } from 'vs/workbench/contrib/accessibility/common/accessibilityCommands';
import { IChatCodeBlockContextProviderService } from 'vs/workbench/contrib/chat/browser/chat';
import { ICodeBlockActionContext } from 'vs/workbench/contrib/chat/browser/codeBlockPart';
Expand Down Expand Up @@ -491,7 +492,17 @@ export class AccessibleView extends Disposable {
}
}
const exitThisDialogHint = verbose && !provider.options.position ? localize('exit', '\n\nExit this dialog (Escape).') : '';
const newContent = message + provider.provideContent() + readMoreLink + disableHelpHint + exitThisDialogHint;
let content = provider.provideContent();
if (provider.options.type === AccessibleViewType.Help) {
const resolvedContent = resolveContentAndKeybindingItems(this._keybindingService, content);
if (resolvedContent) {
content = resolvedContent.content.value;
if (resolvedContent.configureKeybindingItems) {
provider.options.configureKeybindingItems = resolvedContent.configureKeybindingItems;
}
}
}
const newContent = message + content + readMoreLink + disableHelpHint + exitThisDialogHint;
this.calculateCodeBlocks(newContent);
this._currentContent = newContent;
this._updateContextKeys(provider, true);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { MarkdownString } from 'vs/base/common/htmlContent';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IPickerQuickAccessItem } from 'vs/platform/quickinput/browser/pickerQuickAccess';
import { AccessibilityCommandId } from 'vs/workbench/contrib/accessibility/common/accessibilityCommands';

export function resolveContentAndKeybindingItems(keybindingService: IKeybindingService, value?: string): { content: MarkdownString; configureKeybindingItems: IPickerQuickAccessItem[] | undefined } | undefined {
if (!value) {
return;
}
const configureKeybindingItems: IPickerQuickAccessItem[] = [];
const matches = value.matchAll(/\<keybinding:(?<commandId>.*)\>/gm);
for (const match of [...matches]) {
const commandId = match?.groups?.commandId;
let kbLabel;
if (match?.length && commandId) {
const keybinding = keybindingService.lookupKeybinding(commandId)?.getAriaLabel();
if (!keybinding) {
const configureKb = keybindingService.lookupKeybinding(AccessibilityCommandId.AccessibilityHelpConfigureKeybindings)?.getAriaLabel();
const keybindingToConfigureQuickPick = configureKb ? '(' + configureKb + ')' : 'by assigning a keybinding to the command Accessibility Help Configure Keybindings.';
kbLabel = `, configure a keybinding ` + keybindingToConfigureQuickPick;
configureKeybindingItems.push({
label: commandId,
id: commandId
});
} else {
kbLabel = ' (' + keybinding + ')';
}
value = value.replace(match[0], kbLabel);
}
}
const content = new MarkdownString(value);
content.isTrusted = true;
return { content, configureKeybindingItems: configureKeybindingItems.length ? configureKeybindingItems : undefined };
}

Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,13 @@ 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 { ICommandService } from 'vs/platform/commands/common/commands';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { descriptionForCommand } from 'vs/workbench/contrib/accessibility/browser/accessibleViewContributions';
import { AccessibilityHelpAction } from 'vs/workbench/contrib/accessibility/browser/accessibleViewActions';
import { CONTEXT_CHAT_ENABLED } from 'vs/workbench/contrib/chat/common/chatContextKeys';
import { CommentAccessibilityHelpNLS } from 'vs/workbench/contrib/comments/browser/commentsAccessibility';
import { CommentCommandId } from 'vs/workbench/contrib/comments/common/commentCommandIds';
import { CommentContextKeys } from 'vs/workbench/contrib/comments/common/commentContextKeys';
import { NEW_UNTITLED_FILE_COMMAND_ID } from 'vs/workbench/contrib/files/browser/fileConstants';
import { IAccessibleViewService, IAccessibleViewContentProvider, AccessibleViewProviderId, IAccessibleViewOptions, AccessibleViewType } from 'vs/platform/accessibility/browser/accessibleView';
Expand Down Expand Up @@ -88,13 +85,13 @@ class EditorAccessibilityHelpProvider implements IAccessibleViewContentProvider
}

if (options.get(EditorOption.stickyScroll).enabled) {
content.push(descriptionForCommand('editor.action.focusStickyScroll', AccessibilityHelpNLS.stickScrollKb, AccessibilityHelpNLS.stickScrollNoKb, this._keybindingService));
content.push(AccessibilityHelpNLS.stickScroll);
}

if (options.get(EditorOption.tabFocusMode)) {
content.push(descriptionForCommand(ToggleTabFocusModeAction.ID, AccessibilityHelpNLS.tabFocusModeOnMsg, AccessibilityHelpNLS.tabFocusModeOnMsgNoKb, this._keybindingService));
content.push(AccessibilityHelpNLS.tabFocusModeOnMsg);
} else {
content.push(descriptionForCommand(ToggleTabFocusModeAction.ID, AccessibilityHelpNLS.tabFocusModeOffMsg, AccessibilityHelpNLS.tabFocusModeOffMsgNoKb, this._keybindingService));
content.push(AccessibilityHelpNLS.tabFocusModeOffMsg);
}
return content.join('\n\n');
}
Expand All @@ -103,24 +100,14 @@ class EditorAccessibilityHelpProvider implements IAccessibleViewContentProvider
export function getCommentCommandInfo(keybindingService: IKeybindingService, contextKeyService: IContextKeyService, editor: ICodeEditor): string | undefined {
const editorContext = contextKeyService.getContext(editor.getDomNode()!);
if (editorContext.getValue<boolean>(CommentContextKeys.activeEditorHasCommentingRange.key)) {
const commentCommandInfo: string[] = [];
commentCommandInfo.push(CommentAccessibilityHelpNLS.intro);
commentCommandInfo.push(descriptionForCommand(CommentCommandId.Add, CommentAccessibilityHelpNLS.addComment, CommentAccessibilityHelpNLS.addCommentNoKb, keybindingService));
commentCommandInfo.push(descriptionForCommand(CommentCommandId.NextThread, CommentAccessibilityHelpNLS.nextCommentThreadKb, CommentAccessibilityHelpNLS.nextCommentThreadNoKb, keybindingService));
commentCommandInfo.push(descriptionForCommand(CommentCommandId.PreviousThread, CommentAccessibilityHelpNLS.previousCommentThreadKb, CommentAccessibilityHelpNLS.previousCommentThreadNoKb, keybindingService));
commentCommandInfo.push(descriptionForCommand(CommentCommandId.NextRange, CommentAccessibilityHelpNLS.nextRange, CommentAccessibilityHelpNLS.nextRangeNoKb, keybindingService));
commentCommandInfo.push(descriptionForCommand(CommentCommandId.PreviousRange, CommentAccessibilityHelpNLS.previousRange, CommentAccessibilityHelpNLS.previousRangeNoKb, keybindingService));
return commentCommandInfo.join('\n');
return [CommentAccessibilityHelpNLS.intro, CommentAccessibilityHelpNLS.addComment, CommentAccessibilityHelpNLS.nextCommentThread, CommentAccessibilityHelpNLS.previousCommentThread, CommentAccessibilityHelpNLS.nextRange, CommentAccessibilityHelpNLS.previousRange].join('\n');
}
return;
}

export function getChatCommandInfo(keybindingService: IKeybindingService, contextKeyService: IContextKeyService): string | undefined {
if (CONTEXT_CHAT_ENABLED.getValue(contextKeyService)) {
const commentCommandInfo: string[] = [];
commentCommandInfo.push(descriptionForCommand('workbench.action.quickchat.toggle', AccessibilityHelpNLS.quickChat, AccessibilityHelpNLS.quickChatNoKb, keybindingService));
commentCommandInfo.push(descriptionForCommand('inlineChat.start', AccessibilityHelpNLS.startInlineChat, AccessibilityHelpNLS.startInlineChatNoKb, keybindingService));
return commentCommandInfo.join('\n');
return [AccessibilityHelpNLS.quickChat, AccessibilityHelpNLS.startInlineChat].join('\n');
}
return;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,14 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { MarkdownString } from 'vs/base/common/htmlContent';
import { DisposableMap, IDisposable, DisposableStore, Disposable } from 'vs/base/common/lifecycle';
import { ServicesAccessor } from 'vs/editor/browser/editorExtensions';
import { AccessibleViewType, ExtensionContentProvider } from 'vs/platform/accessibility/browser/accessibleView';
import { AccessibleViewRegistry } from 'vs/platform/accessibility/browser/accessibleViewRegistry';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IPickerQuickAccessItem } from 'vs/platform/quickinput/browser/pickerQuickAccess';
import { Registry } from 'vs/platform/registry/common/platform';
import { FocusedViewContext } from 'vs/workbench/common/contextkeys';
import { IViewsRegistry, Extensions, IViewDescriptor } from 'vs/workbench/common/views';
import { AccessibilityCommandId } from 'vs/workbench/contrib/accessibility/common/accessibilityCommands';
import { IViewsService } from 'vs/workbench/services/views/common/viewsService';

export class ExtensionAccessibilityHelpDialogContribution extends Disposable {
Expand Down Expand Up @@ -42,9 +39,9 @@ export class ExtensionAccessibilityHelpDialogContribution extends Disposable {

function registerAccessibilityHelpAction(keybindingService: IKeybindingService, viewDescriptor: IViewDescriptor): IDisposable {
const disposableStore = new DisposableStore();
const helpContent = resolveExtensionHelpContent(keybindingService, viewDescriptor.accessibilityHelpContent);
if (!helpContent) {
throw new Error('No help content for view');
const content = viewDescriptor.accessibilityHelpContent?.value;
if (!content) {
throw new Error('No content provided for the accessibility help dialog');
}
disposableStore.add(AccessibleViewRegistry.register({
priority: 95,
Expand All @@ -55,8 +52,8 @@ function registerAccessibilityHelpAction(keybindingService: IKeybindingService,
const viewsService = accessor.get(IViewsService);
return new ExtensionContentProvider(
viewDescriptor.id,
{ type: AccessibleViewType.Help, configureKeybindingItems: helpContent.configureKeybindingItems },
() => helpContent.value.value,
{ type: AccessibleViewType.Help },
() => content,
() => viewsService.openView(viewDescriptor.id, true),
);
}
Expand All @@ -68,35 +65,3 @@ function registerAccessibilityHelpAction(keybindingService: IKeybindingService,
}));
return disposableStore;
}

function resolveExtensionHelpContent(keybindingService: IKeybindingService, content?: MarkdownString): { value: MarkdownString; configureKeybindingItems: IPickerQuickAccessItem[] | undefined } | undefined {
if (!content) {
return;
}
const configureKeybindingItems: IPickerQuickAccessItem[] = [];
let resolvedContent = typeof content === 'string' ? content : content.value;
const matches = resolvedContent.matchAll(/\<keybinding:(?<commandId>.*)\>/gm);
for (const match of [...matches]) {
const commandId = match?.groups?.commandId;
let kbLabel;
if (match?.length && commandId) {
const keybinding = keybindingService.lookupKeybinding(commandId)?.getAriaLabel();
if (!keybinding) {
const configureKb = keybindingService.lookupKeybinding(AccessibilityCommandId.AccessibilityHelpConfigureKeybindings)?.getAriaLabel();
const keybindingToConfigureQuickPick = configureKb ? '(' + configureKb + ')' : 'by assigning a keybinding to the command accessibility.openQuickPick.';
kbLabel = `, configure a keybinding ` + keybindingToConfigureQuickPick;
configureKeybindingItems.push({
label: commandId,
id: commandId
});
} else {
kbLabel = ' (' + keybinding + ')';
}
resolvedContent = resolvedContent.replace(match[0], kbLabel);
}
}
const value = new MarkdownString(resolvedContent);
value.isTrusted = true;
return { value, configureKeybindingItems: configureKeybindingItems.length ? configureKeybindingItems : undefined };
}

Loading

0 comments on commit 82348ce

Please sign in to comment.