Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/browser/parts/dialogs/dialogHandler.ts
5263 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 { localize } from '../../../../nls.js';
7
import { IConfirmation, IConfirmationResult, IInputResult, ICheckbox, IInputElement, ICustomDialogOptions, IInput, AbstractDialogHandler, DialogType, IPrompt, IAsyncPromptResult } from '../../../../platform/dialogs/common/dialogs.js';
8
import { ILayoutService } from '../../../../platform/layout/browser/layoutService.js';
9
import { ILogService } from '../../../../platform/log/common/log.js';
10
import Severity from '../../../../base/common/severity.js';
11
import { Dialog, IDialogResult } from '../../../../base/browser/ui/dialog/dialog.js';
12
import { DisposableStore } from '../../../../base/common/lifecycle.js';
13
import { IKeybindingService } from '../../../../platform/keybinding/common/keybinding.js';
14
import { IClipboardService } from '../../../../platform/clipboard/common/clipboardService.js';
15
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
16
import { IMarkdownRendererService, openLinkFromMarkdown } from '../../../../platform/markdown/browser/markdownRenderer.js';
17
import { IOpenerService } from '../../../../platform/opener/common/opener.js';
18
import { createWorkbenchDialogOptions } from '../../../../platform/dialogs/browser/dialog.js';
19
20
export class BrowserDialogHandler extends AbstractDialogHandler {
21
22
private static readonly ALLOWABLE_COMMANDS = new Set([
23
'copy',
24
'cut',
25
'editor.action.selectAll',
26
'editor.action.clipboardCopyAction',
27
'editor.action.clipboardCutAction',
28
'editor.action.clipboardPasteAction'
29
]);
30
31
constructor(
32
@ILogService private readonly logService: ILogService,
33
@ILayoutService private readonly layoutService: ILayoutService,
34
@IKeybindingService private readonly keybindingService: IKeybindingService,
35
@IInstantiationService instantiationService: IInstantiationService,
36
@IClipboardService private readonly clipboardService: IClipboardService,
37
@IOpenerService private readonly openerService: IOpenerService,
38
@IMarkdownRendererService private readonly markdownRendererService: IMarkdownRendererService,
39
) {
40
super();
41
}
42
43
async prompt<T>(prompt: IPrompt<T>): Promise<IAsyncPromptResult<T>> {
44
this.logService.trace('DialogService#prompt', prompt.message);
45
46
const buttons = this.getPromptButtons(prompt);
47
48
const { button, checkboxChecked } = await this.doShow(prompt.type, prompt.message, buttons, prompt.detail, prompt.cancelButton ? buttons.length - 1 : -1 /* Disabled */, prompt.checkbox, undefined, typeof prompt?.custom === 'object' ? prompt.custom : undefined);
49
50
return this.getPromptResult(prompt, button, checkboxChecked);
51
}
52
53
async confirm(confirmation: IConfirmation): Promise<IConfirmationResult> {
54
this.logService.trace('DialogService#confirm', confirmation.message);
55
56
const buttons = this.getConfirmationButtons(confirmation);
57
58
const { button, checkboxChecked } = await this.doShow(confirmation.type ?? 'question', confirmation.message, buttons, confirmation.detail, buttons.length - 1, confirmation.checkbox, undefined, typeof confirmation?.custom === 'object' ? confirmation.custom : undefined);
59
60
return { confirmed: button === 0, checkboxChecked };
61
}
62
63
async input(input: IInput): Promise<IInputResult> {
64
this.logService.trace('DialogService#input', input.message);
65
66
const buttons = this.getInputButtons(input);
67
68
const { button, checkboxChecked, values } = await this.doShow(input.type ?? 'question', input.message, buttons, input.detail, buttons.length - 1, input?.checkbox, input.inputs, typeof input.custom === 'object' ? input.custom : undefined);
69
70
return { confirmed: button === 0, checkboxChecked, values };
71
}
72
73
async about(title: string, details: string, detailsToCopy: string): Promise<void> {
74
75
const { button } = await this.doShow(
76
Severity.Info,
77
title,
78
[
79
localize({ key: 'copy', comment: ['&& denotes a mnemonic'] }, "&&Copy"),
80
localize('ok', "OK")
81
],
82
details,
83
1
84
);
85
86
if (button === 0) {
87
this.clipboardService.writeText(detailsToCopy);
88
}
89
}
90
91
private async doShow(type: Severity | DialogType | undefined, message: string, buttons?: string[], detail?: string, cancelId?: number, checkbox?: ICheckbox, inputs?: IInputElement[], customOptions?: ICustomDialogOptions): Promise<IDialogResult> {
92
const dialogDisposables = new DisposableStore();
93
94
const renderBody = customOptions ? (parent: HTMLElement) => {
95
parent.classList.add(...(customOptions.classes || []));
96
customOptions.markdownDetails?.forEach(markdownDetail => {
97
const result = dialogDisposables.add(this.markdownRendererService.render(markdownDetail.markdown, {
98
actionHandler: markdownDetail.actionHandler || ((link, mdStr) => {
99
return openLinkFromMarkdown(this.openerService, link, mdStr.isTrusted, true /* skip URL validation to prevent another dialog from showing which is unsupported */);
100
}),
101
}));
102
parent.appendChild(result.element);
103
result.element.classList.add(...(markdownDetail.classes || []));
104
});
105
} : undefined;
106
107
const dialog = new Dialog(
108
this.layoutService.activeContainer,
109
message,
110
buttons,
111
createWorkbenchDialogOptions({
112
detail,
113
cancelId,
114
type: this.getDialogType(type),
115
renderBody,
116
icon: customOptions?.icon,
117
disableCloseAction: customOptions?.disableCloseAction,
118
buttonOptions: customOptions?.buttonDetails?.map(detail => ({ sublabel: detail })),
119
checkboxLabel: checkbox?.label,
120
checkboxChecked: checkbox?.checked,
121
inputs
122
}, this.keybindingService, this.layoutService, BrowserDialogHandler.ALLOWABLE_COMMANDS)
123
);
124
125
dialogDisposables.add(dialog);
126
127
const result = await dialog.show();
128
dialogDisposables.dispose();
129
130
return result;
131
}
132
}
133
134