| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338 |
- /*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
- 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); }
- };
- import * as dom from '../../../../base/browser/dom.js';
- import { ActionViewItem } from '../../../../base/browser/ui/actionbar/actionViewItems.js';
- import { Separator, SubmenuAction } from '../../../../base/common/actions.js';
- import { DisposableStore } from '../../../../base/common/lifecycle.js';
- import { isIOS } from '../../../../base/common/platform.js';
- import { EditorAction, registerEditorAction, registerEditorContribution } from '../../../browser/editorExtensions.js';
- import { EditorContextKeys } from '../../../common/editorContextKeys.js';
- import * as nls from '../../../../nls.js';
- import { IMenuService, MenuId, SubmenuItemAction } from '../../../../platform/actions/common/actions.js';
- import { IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js';
- import { IContextMenuService, IContextViewService } from '../../../../platform/contextview/browser/contextView.js';
- import { IKeybindingService } from '../../../../platform/keybinding/common/keybinding.js';
- import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js';
- let ContextMenuController = class ContextMenuController {
- constructor(editor, _contextMenuService, _contextViewService, _contextKeyService, _keybindingService, _menuService, _configurationService) {
- this._contextMenuService = _contextMenuService;
- this._contextViewService = _contextViewService;
- this._contextKeyService = _contextKeyService;
- this._keybindingService = _keybindingService;
- this._menuService = _menuService;
- this._configurationService = _configurationService;
- this._toDispose = new DisposableStore();
- this._contextMenuIsBeingShownCount = 0;
- this._editor = editor;
- this._toDispose.add(this._editor.onContextMenu((e) => this._onContextMenu(e)));
- this._toDispose.add(this._editor.onMouseWheel((e) => {
- if (this._contextMenuIsBeingShownCount > 0) {
- const view = this._contextViewService.getContextViewElement();
- const target = e.srcElement;
- // Event triggers on shadow root host first
- // Check if the context view is under this host before hiding it #103169
- if (!(target.shadowRoot && dom.getShadowRoot(view) === target.shadowRoot)) {
- this._contextViewService.hideContextView();
- }
- }
- }));
- this._toDispose.add(this._editor.onKeyDown((e) => {
- if (!this._editor.getOption(20 /* EditorOption.contextmenu */)) {
- return; // Context menu is turned off through configuration
- }
- if (e.keyCode === 58 /* KeyCode.ContextMenu */) {
- // Chrome is funny like that
- e.preventDefault();
- e.stopPropagation();
- this.showContextMenu();
- }
- }));
- }
- static get(editor) {
- return editor.getContribution(ContextMenuController.ID);
- }
- _onContextMenu(e) {
- if (!this._editor.hasModel()) {
- return;
- }
- if (!this._editor.getOption(20 /* EditorOption.contextmenu */)) {
- this._editor.focus();
- // Ensure the cursor is at the position of the mouse click
- if (e.target.position && !this._editor.getSelection().containsPosition(e.target.position)) {
- this._editor.setPosition(e.target.position);
- }
- return; // Context menu is turned off through configuration
- }
- if (e.target.type === 12 /* MouseTargetType.OVERLAY_WIDGET */) {
- return; // allow native menu on widgets to support right click on input field for example in find
- }
- if (e.target.type === 6 /* MouseTargetType.CONTENT_TEXT */ && e.target.detail.injectedText) {
- return; // allow native menu on injected text
- }
- e.event.preventDefault();
- e.event.stopPropagation();
- if (e.target.type === 11 /* MouseTargetType.SCROLLBAR */) {
- return this._showScrollbarContextMenu({ x: e.event.posx - 1, width: 2, y: e.event.posy - 1, height: 2 });
- }
- if (e.target.type !== 6 /* MouseTargetType.CONTENT_TEXT */ && e.target.type !== 7 /* MouseTargetType.CONTENT_EMPTY */ && e.target.type !== 1 /* MouseTargetType.TEXTAREA */) {
- return; // only support mouse click into text or native context menu key for now
- }
- // Ensure the editor gets focus if it hasn't, so the right events are being sent to other contributions
- this._editor.focus();
- // Ensure the cursor is at the position of the mouse click
- if (e.target.position) {
- let hasSelectionAtPosition = false;
- for (const selection of this._editor.getSelections()) {
- if (selection.containsPosition(e.target.position)) {
- hasSelectionAtPosition = true;
- break;
- }
- }
- if (!hasSelectionAtPosition) {
- this._editor.setPosition(e.target.position);
- }
- }
- // Unless the user triggerd the context menu through Shift+F10, use the mouse position as menu position
- let anchor = null;
- if (e.target.type !== 1 /* MouseTargetType.TEXTAREA */) {
- anchor = { x: e.event.posx - 1, width: 2, y: e.event.posy - 1, height: 2 };
- }
- // Show the context menu
- this.showContextMenu(anchor);
- }
- showContextMenu(anchor) {
- if (!this._editor.getOption(20 /* EditorOption.contextmenu */)) {
- return; // Context menu is turned off through configuration
- }
- if (!this._editor.hasModel()) {
- return;
- }
- // Find actions available for menu
- const menuActions = this._getMenuActions(this._editor.getModel(), this._editor.isSimpleWidget ? MenuId.SimpleEditorContext : MenuId.EditorContext);
- // Show menu if we have actions to show
- if (menuActions.length > 0) {
- this._doShowContextMenu(menuActions, anchor);
- }
- }
- _getMenuActions(model, menuId) {
- const result = [];
- // get menu groups
- const menu = this._menuService.createMenu(menuId, this._contextKeyService);
- const groups = menu.getActions({ arg: model.uri });
- menu.dispose();
- // translate them into other actions
- for (const group of groups) {
- const [, actions] = group;
- let addedItems = 0;
- for (const action of actions) {
- if (action instanceof SubmenuItemAction) {
- const subActions = this._getMenuActions(model, action.item.submenu);
- if (subActions.length > 0) {
- result.push(new SubmenuAction(action.id, action.label, subActions));
- addedItems++;
- }
- }
- else {
- result.push(action);
- addedItems++;
- }
- }
- if (addedItems) {
- result.push(new Separator());
- }
- }
- if (result.length) {
- result.pop(); // remove last separator
- }
- return result;
- }
- _doShowContextMenu(actions, anchor = null) {
- if (!this._editor.hasModel()) {
- return;
- }
- // Disable hover
- const oldHoverSetting = this._editor.getOption(55 /* EditorOption.hover */);
- this._editor.updateOptions({
- hover: {
- enabled: false
- }
- });
- if (!anchor) {
- // Ensure selection is visible
- this._editor.revealPosition(this._editor.getPosition(), 1 /* ScrollType.Immediate */);
- this._editor.render();
- const cursorCoords = this._editor.getScrolledVisiblePosition(this._editor.getPosition());
- // Translate to absolute editor position
- const editorCoords = dom.getDomNodePagePosition(this._editor.getDomNode());
- const posx = editorCoords.left + cursorCoords.left;
- const posy = editorCoords.top + cursorCoords.top + cursorCoords.height;
- anchor = { x: posx, y: posy };
- }
- const useShadowDOM = this._editor.getOption(117 /* EditorOption.useShadowDOM */) && !isIOS; // Do not use shadow dom on IOS #122035
- // Show menu
- this._contextMenuIsBeingShownCount++;
- this._contextMenuService.showContextMenu({
- domForShadowRoot: useShadowDOM ? this._editor.getDomNode() : undefined,
- getAnchor: () => anchor,
- getActions: () => actions,
- getActionViewItem: (action) => {
- const keybinding = this._keybindingFor(action);
- if (keybinding) {
- return new ActionViewItem(action, action, { label: true, keybinding: keybinding.getLabel(), isMenu: true });
- }
- const customActionViewItem = action;
- if (typeof customActionViewItem.getActionViewItem === 'function') {
- return customActionViewItem.getActionViewItem();
- }
- return new ActionViewItem(action, action, { icon: true, label: true, isMenu: true });
- },
- getKeyBinding: (action) => {
- return this._keybindingFor(action);
- },
- onHide: (wasCancelled) => {
- this._contextMenuIsBeingShownCount--;
- this._editor.focus();
- this._editor.updateOptions({
- hover: oldHoverSetting
- });
- }
- });
- }
- _showScrollbarContextMenu(anchor) {
- if (!this._editor.hasModel()) {
- return;
- }
- const minimapOptions = this._editor.getOption(67 /* EditorOption.minimap */);
- let lastId = 0;
- const createAction = (opts) => {
- return {
- id: `menu-action-${++lastId}`,
- label: opts.label,
- tooltip: '',
- class: undefined,
- enabled: (typeof opts.enabled === 'undefined' ? true : opts.enabled),
- checked: opts.checked,
- run: opts.run,
- dispose: () => null
- };
- };
- const createSubmenuAction = (label, actions) => {
- return new SubmenuAction(`menu-action-${++lastId}`, label, actions, undefined);
- };
- const createEnumAction = (label, enabled, configName, configuredValue, options) => {
- if (!enabled) {
- return createAction({ label, enabled, run: () => { } });
- }
- const createRunner = (value) => {
- return () => {
- this._configurationService.updateValue(configName, value);
- };
- };
- const actions = [];
- for (const option of options) {
- actions.push(createAction({
- label: option.label,
- checked: configuredValue === option.value,
- run: createRunner(option.value)
- }));
- }
- return createSubmenuAction(label, actions);
- };
- const actions = [];
- actions.push(createAction({
- label: nls.localize('context.minimap.minimap', "Minimap"),
- checked: minimapOptions.enabled,
- run: () => {
- this._configurationService.updateValue(`editor.minimap.enabled`, !minimapOptions.enabled);
- }
- }));
- actions.push(new Separator());
- actions.push(createAction({
- label: nls.localize('context.minimap.renderCharacters', "Render Characters"),
- enabled: minimapOptions.enabled,
- checked: minimapOptions.renderCharacters,
- run: () => {
- this._configurationService.updateValue(`editor.minimap.renderCharacters`, !minimapOptions.renderCharacters);
- }
- }));
- actions.push(createEnumAction(nls.localize('context.minimap.size', "Vertical size"), minimapOptions.enabled, 'editor.minimap.size', minimapOptions.size, [{
- label: nls.localize('context.minimap.size.proportional', "Proportional"),
- value: 'proportional'
- }, {
- label: nls.localize('context.minimap.size.fill', "Fill"),
- value: 'fill'
- }, {
- label: nls.localize('context.minimap.size.fit', "Fit"),
- value: 'fit'
- }]));
- actions.push(createEnumAction(nls.localize('context.minimap.slider', "Slider"), minimapOptions.enabled, 'editor.minimap.showSlider', minimapOptions.showSlider, [{
- label: nls.localize('context.minimap.slider.mouseover', "Mouse Over"),
- value: 'mouseover'
- }, {
- label: nls.localize('context.minimap.slider.always', "Always"),
- value: 'always'
- }]));
- const useShadowDOM = this._editor.getOption(117 /* EditorOption.useShadowDOM */) && !isIOS; // Do not use shadow dom on IOS #122035
- this._contextMenuIsBeingShownCount++;
- this._contextMenuService.showContextMenu({
- domForShadowRoot: useShadowDOM ? this._editor.getDomNode() : undefined,
- getAnchor: () => anchor,
- getActions: () => actions,
- onHide: (wasCancelled) => {
- this._contextMenuIsBeingShownCount--;
- this._editor.focus();
- }
- });
- }
- _keybindingFor(action) {
- return this._keybindingService.lookupKeybinding(action.id);
- }
- dispose() {
- if (this._contextMenuIsBeingShownCount > 0) {
- this._contextViewService.hideContextView();
- }
- this._toDispose.dispose();
- }
- };
- ContextMenuController.ID = 'editor.contrib.contextmenu';
- ContextMenuController = __decorate([
- __param(1, IContextMenuService),
- __param(2, IContextViewService),
- __param(3, IContextKeyService),
- __param(4, IKeybindingService),
- __param(5, IMenuService),
- __param(6, IConfigurationService)
- ], ContextMenuController);
- export { ContextMenuController };
- class ShowContextMenu extends EditorAction {
- constructor() {
- super({
- id: 'editor.action.showContextMenu',
- label: nls.localize('action.showContextMenu.label', "Show Editor Context Menu"),
- alias: 'Show Editor Context Menu',
- precondition: undefined,
- kbOpts: {
- kbExpr: EditorContextKeys.textInputFocus,
- primary: 1024 /* KeyMod.Shift */ | 68 /* KeyCode.F10 */,
- weight: 100 /* KeybindingWeight.EditorContrib */
- }
- });
- }
- run(accessor, editor) {
- var _a;
- (_a = ContextMenuController.get(editor)) === null || _a === void 0 ? void 0 : _a.showContextMenu();
- }
- }
- registerEditorContribution(ContextMenuController.ID, ContextMenuController);
- registerEditorAction(ShowContextMenu);
|