UNPKG

monaco-editor-core

Version:

A browser based code editor

228 lines (227 loc) • 10.5 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as dom from '../../../base/browser/dom.js'; import { ActionBar } from '../../../base/browser/ui/actionbar/actionbar.js'; import { Disposable, DisposableStore, MutableDisposable } from '../../../base/common/lifecycle.js'; import './actionWidget.css'; import { localize, localize2 } from '../../../nls.js'; import { acceptSelectedActionCommand, ActionList, previewSelectedActionCommand } from './actionList.js'; import { Action2, registerAction2 } from '../../actions/common/actions.js'; import { IContextKeyService, RawContextKey } from '../../contextkey/common/contextkey.js'; import { IContextViewService } from '../../contextview/browser/contextView.js'; import { registerSingleton } from '../../instantiation/common/extensions.js'; import { createDecorator, IInstantiationService } from '../../instantiation/common/instantiation.js'; import { inputActiveOptionBackground, registerColor } from '../../theme/common/colorRegistry.js'; registerColor('actionBar.toggledBackground', inputActiveOptionBackground, localize('actionBar.toggledBackground', 'Background color for toggled action items in action bar.')); const ActionWidgetContextKeys = { Visible: new RawContextKey('codeActionMenuVisible', false, localize('codeActionMenuVisible', "Whether the action widget list is visible")) }; export const IActionWidgetService = createDecorator('actionWidgetService'); let ActionWidgetService = class ActionWidgetService extends Disposable { get isVisible() { return ActionWidgetContextKeys.Visible.getValue(this._contextKeyService) || false; } constructor(_contextViewService, _contextKeyService, _instantiationService) { super(); this._contextViewService = _contextViewService; this._contextKeyService = _contextKeyService; this._instantiationService = _instantiationService; this._list = this._register(new MutableDisposable()); } show(user, supportsPreview, items, delegate, anchor, container, actionBarActions) { const visibleContext = ActionWidgetContextKeys.Visible.bindTo(this._contextKeyService); const list = this._instantiationService.createInstance(ActionList, user, supportsPreview, items, delegate); this._contextViewService.showContextView({ getAnchor: () => anchor, render: (container) => { visibleContext.set(true); return this._renderWidget(container, list, actionBarActions ?? []); }, onHide: (didCancel) => { visibleContext.reset(); this._onWidgetClosed(didCancel); }, }, container, false); } acceptSelected(preview) { this._list.value?.acceptSelected(preview); } focusPrevious() { this._list?.value?.focusPrevious(); } focusNext() { this._list?.value?.focusNext(); } hide(didCancel) { this._list.value?.hide(didCancel); this._list.clear(); } _renderWidget(element, list, actionBarActions) { const widget = document.createElement('div'); widget.classList.add('action-widget'); element.appendChild(widget); this._list.value = list; if (this._list.value) { widget.appendChild(this._list.value.domNode); } else { throw new Error('List has no value'); } const renderDisposables = new DisposableStore(); // Invisible div to block mouse interaction in the rest of the UI const menuBlock = document.createElement('div'); const block = element.appendChild(menuBlock); block.classList.add('context-view-block'); renderDisposables.add(dom.addDisposableListener(block, dom.EventType.MOUSE_DOWN, e => e.stopPropagation())); // Invisible div to block mouse interaction with the menu const pointerBlockDiv = document.createElement('div'); const pointerBlock = element.appendChild(pointerBlockDiv); pointerBlock.classList.add('context-view-pointerBlock'); // Removes block on click INSIDE widget or ANY mouse movement renderDisposables.add(dom.addDisposableListener(pointerBlock, dom.EventType.POINTER_MOVE, () => pointerBlock.remove())); renderDisposables.add(dom.addDisposableListener(pointerBlock, dom.EventType.MOUSE_DOWN, () => pointerBlock.remove())); // Action bar let actionBarWidth = 0; if (actionBarActions.length) { const actionBar = this._createActionBar('.action-widget-action-bar', actionBarActions); if (actionBar) { widget.appendChild(actionBar.getContainer().parentElement); renderDisposables.add(actionBar); actionBarWidth = actionBar.getContainer().offsetWidth; } } const width = this._list.value?.layout(actionBarWidth); widget.style.width = `${width}px`; const focusTracker = renderDisposables.add(dom.trackFocus(element)); renderDisposables.add(focusTracker.onDidBlur(() => this.hide(true))); return renderDisposables; } _createActionBar(className, actions) { if (!actions.length) { return undefined; } const container = dom.$(className); const actionBar = new ActionBar(container); actionBar.push(actions, { icon: false, label: true }); return actionBar; } _onWidgetClosed(didCancel) { this._list.value?.hide(didCancel); } }; ActionWidgetService = __decorate([ __param(0, IContextViewService), __param(1, IContextKeyService), __param(2, IInstantiationService) ], ActionWidgetService); registerSingleton(IActionWidgetService, ActionWidgetService, 1 /* InstantiationType.Delayed */); const weight = 100 /* KeybindingWeight.EditorContrib */ + 1000; registerAction2(class extends Action2 { constructor() { super({ id: 'hideCodeActionWidget', title: localize2('hideCodeActionWidget.title', "Hide action widget"), precondition: ActionWidgetContextKeys.Visible, keybinding: { weight, primary: 9 /* KeyCode.Escape */, secondary: [1024 /* KeyMod.Shift */ | 9 /* KeyCode.Escape */] }, }); } run(accessor) { accessor.get(IActionWidgetService).hide(true); } }); registerAction2(class extends Action2 { constructor() { super({ id: 'selectPrevCodeAction', title: localize2('selectPrevCodeAction.title', "Select previous action"), precondition: ActionWidgetContextKeys.Visible, keybinding: { weight, primary: 16 /* KeyCode.UpArrow */, secondary: [2048 /* KeyMod.CtrlCmd */ | 16 /* KeyCode.UpArrow */], mac: { primary: 16 /* KeyCode.UpArrow */, secondary: [2048 /* KeyMod.CtrlCmd */ | 16 /* KeyCode.UpArrow */, 256 /* KeyMod.WinCtrl */ | 46 /* KeyCode.KeyP */] }, } }); } run(accessor) { const widgetService = accessor.get(IActionWidgetService); if (widgetService instanceof ActionWidgetService) { widgetService.focusPrevious(); } } }); registerAction2(class extends Action2 { constructor() { super({ id: 'selectNextCodeAction', title: localize2('selectNextCodeAction.title', "Select next action"), precondition: ActionWidgetContextKeys.Visible, keybinding: { weight, primary: 18 /* KeyCode.DownArrow */, secondary: [2048 /* KeyMod.CtrlCmd */ | 18 /* KeyCode.DownArrow */], mac: { primary: 18 /* KeyCode.DownArrow */, secondary: [2048 /* KeyMod.CtrlCmd */ | 18 /* KeyCode.DownArrow */, 256 /* KeyMod.WinCtrl */ | 44 /* KeyCode.KeyN */] } } }); } run(accessor) { const widgetService = accessor.get(IActionWidgetService); if (widgetService instanceof ActionWidgetService) { widgetService.focusNext(); } } }); registerAction2(class extends Action2 { constructor() { super({ id: acceptSelectedActionCommand, title: localize2('acceptSelected.title', "Accept selected action"), precondition: ActionWidgetContextKeys.Visible, keybinding: { weight, primary: 3 /* KeyCode.Enter */, secondary: [2048 /* KeyMod.CtrlCmd */ | 89 /* KeyCode.Period */], } }); } run(accessor) { const widgetService = accessor.get(IActionWidgetService); if (widgetService instanceof ActionWidgetService) { widgetService.acceptSelected(); } } }); registerAction2(class extends Action2 { constructor() { super({ id: previewSelectedActionCommand, title: localize2('previewSelected.title', "Preview selected action"), precondition: ActionWidgetContextKeys.Visible, keybinding: { weight, primary: 2048 /* KeyMod.CtrlCmd */ | 3 /* KeyCode.Enter */, } }); } run(accessor) { const widgetService = accessor.get(IActionWidgetService); if (widgetService instanceof ActionWidgetService) { widgetService.acceptSelected(true); } } });