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