Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move accessible view hint to the notification list item's aria label #188966

Merged
merged 1 commit into from
Jul 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
46 changes: 30 additions & 16 deletions src/vs/workbench/browser/parts/notifications/notificationsList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { localize } from 'vs/nls';
import { isAncestor, trackFocus } from 'vs/base/browser/dom';
import { WorkbenchList } from 'vs/platform/list/browser/listService';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IListOptions } from 'vs/base/browser/ui/list/listWidget';
import { IListAccessibilityProvider, IListOptions } from 'vs/base/browser/ui/list/listWidget';
import { NOTIFICATIONS_BACKGROUND } from 'vs/workbench/common/theme';
import { INotificationViewItem } from 'vs/workbench/common/notifications';
import { NotificationsListDelegate, NotificationRenderer } from 'vs/workbench/browser/parts/notifications/notificationsViewer';
Expand All @@ -19,6 +19,8 @@ import { NotificationFocusedContext } from 'vs/workbench/common/contextkeys';
import { Disposable } from 'vs/base/common/lifecycle';
import { AriaRole } from 'vs/base/browser/ui/aria/aria';
import { NotificationActionRunner } from 'vs/workbench/browser/parts/notifications/notificationsCommands';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';

export interface INotificationsListOptions extends IListOptions<INotificationViewItem> {
readonly widgetAriaLabel?: string;
Expand Down Expand Up @@ -93,21 +95,7 @@ export class NotificationsList extends Disposable {
overrideStyles: {
listBackground: NOTIFICATIONS_BACKGROUND
},
accessibilityProvider: {
getAriaLabel(element: INotificationViewItem): string {
if (!element.source) {
return localize('notificationAriaLabel', "{0}, notification", element.message.raw);
}

return localize('notificationWithSourceAriaLabel', "{0}, source: {1}, notification", element.message.raw, element.source);
},
getWidgetAriaLabel(): string {
return options.widgetAriaLabel ?? localize('notificationsList', "Notifications List");
},
getRole(): AriaRole {
return 'dialog'; // https://github.com/microsoft/vscode/issues/82728
}
}
accessibilityProvider: this.instantiationService.createInstance(NotificationAccessibilityProvider, options)
}
));

Expand Down Expand Up @@ -267,3 +255,29 @@ export class NotificationsList extends Disposable {
super.dispose();
}
}

class NotificationAccessibilityProvider implements IListAccessibilityProvider<INotificationViewItem> {
constructor(
private readonly _options: INotificationsListOptions,
@IKeybindingService private readonly _keybindingService: IKeybindingService,
@IConfigurationService private readonly _configurationService: IConfigurationService
) { }
getAriaLabel(element: INotificationViewItem): string {
let accessibleViewHint: string | undefined;
const keybinding = this._keybindingService.lookupKeybinding('editor.action.accessibleView')?.getAriaLabel();
if (this._configurationService.getValue('accessibility.verbosity.notification')) {
accessibleViewHint = keybinding ? localize('notificationAccessibleViewHint', "Inspect the response in the accessible view with {0}", keybinding) : localize('notificationAccessibleViewHintNoKb', "Inspect the response in the accessible view via the command Open Accessible View which is currently not triggerable via keybinding");
}
if (!element.source) {
return accessibleViewHint ? localize('notificationAriaLabelHint', "{0}, notification, {1}", element.message.raw, accessibleViewHint) : localize('notificationAriaLabel', "{0}, notification", element.message.raw);
}

return accessibleViewHint ? localize('notificationWithSourceAriaLabelHint', "{0}, source: {1}, notification, {2}", element.message.raw, element.source, accessibleViewHint) : localize('notificationWithSourceAriaLabel', "{0}, source: {1}, notification", element.message.raw, element.source);
}
getWidgetAriaLabel(): string {
return this._options.widgetAriaLabel ?? localize('notificationsList', "Notifications List");
}
getRole(): AriaRole {
return 'dialog'; // https://github.com/microsoft/vscode/issues/82728
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ import { IHostService } from 'vs/workbench/services/host/browser/host';
import { IntervalCounter } from 'vs/base/common/async';
import { assertIsDefined } from 'vs/base/common/types';
import { NotificationsToastsVisibleContext } from 'vs/workbench/common/contextkeys';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';

interface INotificationToast {
readonly item: INotificationViewItem;
Expand Down Expand Up @@ -85,9 +83,7 @@ export class NotificationsToasts extends Themable implements INotificationsToast
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService,
@IContextKeyService private readonly contextKeyService: IContextKeyService,
@ILifecycleService private readonly lifecycleService: ILifecycleService,
@IHostService private readonly hostService: IHostService,
@IKeybindingService private readonly _keybindingService: IKeybindingService,
@IConfigurationService private readonly _configurationService: IConfigurationService
@IHostService private readonly hostService: IHostService
) {
super(themeService);

Expand Down Expand Up @@ -191,24 +187,11 @@ export class NotificationsToasts extends Themable implements INotificationsToast
const notificationList = this.instantiationService.createInstance(NotificationsList, notificationToast, {
verticalScrollMode: ScrollbarVisibility.Hidden,
widgetAriaLabel: (() => {
let accessibleViewHint: string | undefined;
const keybinding = this._keybindingService.lookupKeybinding('editor.action.accessibleView')?.getAriaLabel();
if (this._configurationService.getValue('accessibility.verbosity.notification')) {
accessibleViewHint = keybinding ? localize('chatAccessibleViewHint', "Inspect the response in the accessible view with {0}", keybinding) : localize('chatAccessibleViewHintNoKb', "Inspect the response in the accessible view via the command Open Accessible View which is currently not triggerable via keybinding");
}

if (!item.source) {
if (accessibleViewHint) {
return localize('notificationAriaLabelViewHint', "{0}, notification {1}", item.message.raw, accessibleViewHint);
} else {
return localize('notificationAriaLabel', "{0}, notification", item.message.raw);
}
}
if (accessibleViewHint) {
return localize('notificationWithSourceAriaLabelViewHint', "{0}, source: {1}, notification {2}", item.message.raw, item.source, accessibleViewHint);
} else {
return localize('notificationWithSourceAriaLabel', "{0}, source: {1}, notification", item.message.raw, item.source);
return localize('notificationAriaLabel', "{0}, notification", item.message.raw);
}
return localize('notificationWithSourceAriaLabel', "{0}, source: {1}, notification", item.message.raw, item.source);
})()
});
itemDisposables.add(notificationList);
Expand Down