Path: blob/main/src/vs/workbench/browser/parts/dialogs/dialogHandler.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 { localize } from '../../../../nls.js';6import { IConfirmation, IConfirmationResult, IInputResult, ICheckbox, IInputElement, ICustomDialogOptions, IInput, AbstractDialogHandler, DialogType, IPrompt, IAsyncPromptResult } from '../../../../platform/dialogs/common/dialogs.js';7import { ILayoutService } from '../../../../platform/layout/browser/layoutService.js';8import { ILogService } from '../../../../platform/log/common/log.js';9import Severity from '../../../../base/common/severity.js';10import { Dialog, IDialogResult } from '../../../../base/browser/ui/dialog/dialog.js';11import { DisposableStore } from '../../../../base/common/lifecycle.js';12import { IKeybindingService } from '../../../../platform/keybinding/common/keybinding.js';13import { IClipboardService } from '../../../../platform/clipboard/common/clipboardService.js';14import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';15import { MarkdownRenderer, openLinkFromMarkdown } from '../../../../editor/browser/widget/markdownRenderer/browser/markdownRenderer.js';16import { IOpenerService } from '../../../../platform/opener/common/opener.js';17import { createWorkbenchDialogOptions } from '../../../../platform/dialogs/browser/dialog.js';1819export class BrowserDialogHandler extends AbstractDialogHandler {2021private static readonly ALLOWABLE_COMMANDS = [22'copy',23'cut',24'editor.action.selectAll',25'editor.action.clipboardCopyAction',26'editor.action.clipboardCutAction',27'editor.action.clipboardPasteAction'28];2930private readonly markdownRenderer: MarkdownRenderer;3132constructor(33@ILogService private readonly logService: ILogService,34@ILayoutService private readonly layoutService: ILayoutService,35@IKeybindingService private readonly keybindingService: IKeybindingService,36@IInstantiationService instantiationService: IInstantiationService,37@IClipboardService private readonly clipboardService: IClipboardService,38@IOpenerService private readonly openerService: IOpenerService39) {40super();4142this.markdownRenderer = instantiationService.createInstance(MarkdownRenderer, {});43}4445async prompt<T>(prompt: IPrompt<T>): Promise<IAsyncPromptResult<T>> {46this.logService.trace('DialogService#prompt', prompt.message);4748const buttons = this.getPromptButtons(prompt);4950const { 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);5152return this.getPromptResult(prompt, button, checkboxChecked);53}5455async confirm(confirmation: IConfirmation): Promise<IConfirmationResult> {56this.logService.trace('DialogService#confirm', confirmation.message);5758const buttons = this.getConfirmationButtons(confirmation);5960const { 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);6162return { confirmed: button === 0, checkboxChecked };63}6465async input(input: IInput): Promise<IInputResult> {66this.logService.trace('DialogService#input', input.message);6768const buttons = this.getInputButtons(input);6970const { 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);7172return { confirmed: button === 0, checkboxChecked, values };73}7475async about(title: string, details: string, detailsToCopy: string): Promise<void> {7677const { button } = await this.doShow(78Severity.Info,79title,80[81localize({ key: 'copy', comment: ['&& denotes a mnemonic'] }, "&&Copy"),82localize('ok', "OK")83],84details,85186);8788if (button === 0) {89this.clipboardService.writeText(detailsToCopy);90}91}9293private async doShow(type: Severity | DialogType | undefined, message: string, buttons?: string[], detail?: string, cancelId?: number, checkbox?: ICheckbox, inputs?: IInputElement[], customOptions?: ICustomDialogOptions): Promise<IDialogResult> {94const dialogDisposables = new DisposableStore();9596const renderBody = customOptions ? (parent: HTMLElement) => {97parent.classList.add(...(customOptions.classes || []));98customOptions.markdownDetails?.forEach(markdownDetail => {99const result = dialogDisposables.add(this.markdownRenderer.render(markdownDetail.markdown, {100actionHandler: markdownDetail.actionHandler || ((link, mdStr) => {101return openLinkFromMarkdown(this.openerService, link, mdStr.isTrusted, true /* skip URL validation to prevent another dialog from showing which is unsupported */);102}),103}));104parent.appendChild(result.element);105result.element.classList.add(...(markdownDetail.classes || []));106});107} : undefined;108109const dialog = new Dialog(110this.layoutService.activeContainer,111message,112buttons,113createWorkbenchDialogOptions({114detail,115cancelId,116type: this.getDialogType(type),117renderBody,118icon: customOptions?.icon,119disableCloseAction: customOptions?.disableCloseAction,120buttonOptions: customOptions?.buttonDetails?.map(detail => ({ sublabel: detail })),121checkboxLabel: checkbox?.label,122checkboxChecked: checkbox?.checked,123inputs124}, this.keybindingService, this.layoutService, BrowserDialogHandler.ALLOWABLE_COMMANDS)125);126127dialogDisposables.add(dialog);128129const result = await dialog.show();130dialogDisposables.dispose();131132return result;133}134}135136137