Path: blob/main/src/vs/workbench/browser/parts/notifications/notificationAccessibleView.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { IAction } from '../../../../base/common/actions.js';6import { Codicon } from '../../../../base/common/codicons.js';7import { ThemeIcon } from '../../../../base/common/themables.js';8import { localize } from '../../../../nls.js';9import { IAccessibleViewService, AccessibleViewProviderId, AccessibleViewType, AccessibleContentProvider } from '../../../../platform/accessibility/browser/accessibleView.js';10import { IAccessibleViewImplementation } from '../../../../platform/accessibility/browser/accessibleViewRegistry.js';11import { IAccessibilitySignalService, AccessibilitySignal } from '../../../../platform/accessibilitySignal/browser/accessibilitySignalService.js';12import { ICommandService } from '../../../../platform/commands/common/commands.js';13import { ServicesAccessor } from '../../../../platform/instantiation/common/instantiation.js';14import { IListService, WorkbenchList } from '../../../../platform/list/browser/listService.js';15import { getNotificationFromContext } from './notificationsCommands.js';16import { NotificationFocusedContext } from '../../../common/contextkeys.js';17import { INotificationViewItem } from '../../../common/notifications.js';18import { withSeverityPrefix } from '../../../../platform/notification/common/notification.js';1920export class NotificationAccessibleView implements IAccessibleViewImplementation {21readonly priority = 90;22readonly name = 'notifications';23readonly when = NotificationFocusedContext;24readonly type = AccessibleViewType.View;25getProvider(accessor: ServicesAccessor) {26const accessibleViewService = accessor.get(IAccessibleViewService);27const listService = accessor.get(IListService);28const commandService = accessor.get(ICommandService);29const accessibilitySignalService = accessor.get(IAccessibilitySignalService);3031function getProvider() {32const notification = getNotificationFromContext(listService);33if (!notification) {34return;35}36commandService.executeCommand('notifications.showList');37let notificationIndex: number | undefined;38const list = listService.lastFocusedList;39if (list instanceof WorkbenchList) {40notificationIndex = list.indexOf(notification);41}42if (notificationIndex === undefined) {43return;44}4546function focusList(): void {47commandService.executeCommand('notifications.showList');48if (list && notificationIndex !== undefined) {49list.domFocus();50try {51list.setFocus([notificationIndex]);52} catch { }53}54}5556function getContentForNotification(): string | undefined {57const notification = getNotificationFromContext(listService);58const message = notification?.message.original.toString();59if (!notification || !message) {60return;61}62return withSeverityPrefix(notification.source ? localize('notification.accessibleViewSrc', '{0} Source: {1}', message, notification.source) : message, notification.severity);63}64const content = getContentForNotification();65if (!content) {66return;67}68notification.onDidClose(() => accessibleViewService.next());69return new AccessibleContentProvider(70AccessibleViewProviderId.Notification,71{ type: AccessibleViewType.View },72() => content,73() => focusList(),74'accessibility.verbosity.notification',75undefined,76getActionsFromNotification(notification, accessibilitySignalService),77() => {78if (!list) {79return;80}81focusList();82list.focusNext();83return getContentForNotification();84},85() => {86if (!list) {87return;88}89focusList();90list.focusPrevious();91return getContentForNotification();92},93);94}95return getProvider();96}97}9899100function getActionsFromNotification(notification: INotificationViewItem, accessibilitySignalService: IAccessibilitySignalService): IAction[] | undefined {101let actions = undefined;102if (notification.actions) {103actions = [];104if (notification.actions.primary) {105actions.push(...notification.actions.primary);106}107if (notification.actions.secondary) {108actions.push(...notification.actions.secondary);109}110}111if (actions) {112for (const action of actions) {113action.class = ThemeIcon.asClassName(Codicon.bell);114const initialAction = action.run;115action.run = () => {116initialAction();117notification.close();118};119}120}121const manageExtension = actions?.find(a => a.label.includes('Manage Extension'));122if (manageExtension) {123manageExtension.class = ThemeIcon.asClassName(Codicon.gear);124}125if (actions) {126actions.push({127id: 'clearNotification', label: localize('clearNotification', "Clear Notification"), tooltip: localize('clearNotification', "Clear Notification"), run: () => {128notification.close();129accessibilitySignalService.playSignal(AccessibilitySignal.clear);130}, enabled: true, class: ThemeIcon.asClassName(Codicon.clearAll)131});132}133return actions;134}135136137138