Path: blob/main/src/vs/platform/contextview/browser/contextMenuService.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 { IContextMenuDelegate } from '../../../base/browser/contextmenu.js';6import { ModifierKeyEmitter } from '../../../base/browser/dom.js';7import { IAction, Separator } from '../../../base/common/actions.js';8import { Emitter } from '../../../base/common/event.js';9import { Disposable } from '../../../base/common/lifecycle.js';10import { getFlatContextMenuActions } from '../../actions/browser/menuEntryActionViewItem.js';11import { IMenuService, MenuId } from '../../actions/common/actions.js';12import { IContextKeyService } from '../../contextkey/common/contextkey.js';13import { IKeybindingService } from '../../keybinding/common/keybinding.js';14import { INotificationService } from '../../notification/common/notification.js';15import { ITelemetryService } from '../../telemetry/common/telemetry.js';16import { ContextMenuHandler, IContextMenuHandlerOptions } from './contextMenuHandler.js';17import { IContextMenuMenuDelegate, IContextMenuService, IContextViewService } from './contextView.js';1819export class ContextMenuService extends Disposable implements IContextMenuService {2021declare readonly _serviceBrand: undefined;2223private _contextMenuHandler: ContextMenuHandler | undefined = undefined;24private get contextMenuHandler(): ContextMenuHandler {25if (!this._contextMenuHandler) {26this._contextMenuHandler = new ContextMenuHandler(this.contextViewService, this.telemetryService, this.notificationService, this.keybindingService);27}2829return this._contextMenuHandler;30}3132private readonly _onDidShowContextMenu = this._store.add(new Emitter<void>());33readonly onDidShowContextMenu = this._onDidShowContextMenu.event;3435private readonly _onDidHideContextMenu = this._store.add(new Emitter<void>());36readonly onDidHideContextMenu = this._onDidHideContextMenu.event;3738constructor(39@ITelemetryService private readonly telemetryService: ITelemetryService,40@INotificationService private readonly notificationService: INotificationService,41@IContextViewService private readonly contextViewService: IContextViewService,42@IKeybindingService private readonly keybindingService: IKeybindingService,43@IMenuService private readonly menuService: IMenuService,44@IContextKeyService private readonly contextKeyService: IContextKeyService,45) {46super();47}4849configure(options: IContextMenuHandlerOptions): void {50this.contextMenuHandler.configure(options);51}5253// ContextMenu5455showContextMenu(delegate: IContextMenuDelegate | IContextMenuMenuDelegate): void {5657delegate = ContextMenuMenuDelegate.transform(delegate, this.menuService, this.contextKeyService);5859this.contextMenuHandler.showContextMenu({60...delegate,61onHide: (didCancel) => {62delegate.onHide?.(didCancel);6364this._onDidHideContextMenu.fire();65}66});67ModifierKeyEmitter.getInstance().resetKeyStatus();68this._onDidShowContextMenu.fire();69}70}7172export namespace ContextMenuMenuDelegate {7374function is(thing: IContextMenuDelegate | IContextMenuMenuDelegate): thing is IContextMenuMenuDelegate {75return thing && (<IContextMenuMenuDelegate>thing).menuId instanceof MenuId;76}7778export function transform(delegate: IContextMenuDelegate | IContextMenuMenuDelegate, menuService: IMenuService, globalContextKeyService: IContextKeyService): IContextMenuDelegate {79if (!is(delegate)) {80return delegate;81}82const { menuId, menuActionOptions, contextKeyService } = delegate;83return {84...delegate,85getActions: () => {86let target: IAction[] = [];87if (menuId) {88const menu = menuService.getMenuActions(menuId, contextKeyService ?? globalContextKeyService, menuActionOptions);89target = getFlatContextMenuActions(menu);90}91if (!delegate.getActions) {92return target;93} else {94return Separator.join(delegate.getActions(), target);95}96}97};98}99}100101102