| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- /*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
- import { $, addDisposableListener, append, EventHelper, EventType } from '../../dom.js';
- import { StandardKeyboardEvent } from '../../keyboardEvent.js';
- import { EventType as GestureEventType, Gesture } from '../../touch.js';
- import { ActionRunner } from '../../../common/actions.js';
- import { Emitter } from '../../../common/event.js';
- import './dropdown.css';
- export class BaseDropdown extends ActionRunner {
- constructor(container, options) {
- super();
- this._onDidChangeVisibility = this._register(new Emitter());
- this.onDidChangeVisibility = this._onDidChangeVisibility.event;
- this._element = append(container, $('.monaco-dropdown'));
- this._label = append(this._element, $('.dropdown-label'));
- let labelRenderer = options.labelRenderer;
- if (!labelRenderer) {
- labelRenderer = (container) => {
- container.textContent = options.label || '';
- return null;
- };
- }
- for (const event of [EventType.CLICK, EventType.MOUSE_DOWN, GestureEventType.Tap]) {
- this._register(addDisposableListener(this.element, event, e => EventHelper.stop(e, true))); // prevent default click behaviour to trigger
- }
- for (const event of [EventType.MOUSE_DOWN, GestureEventType.Tap]) {
- this._register(addDisposableListener(this._label, event, e => {
- if (e instanceof MouseEvent && (e.detail > 1 || e.button !== 0)) {
- // prevent right click trigger to allow separate context menu (https://github.com/microsoft/vscode/issues/151064)
- // prevent multiple clicks to open multiple context menus (https://github.com/microsoft/vscode/issues/41363)
- return;
- }
- if (this.visible) {
- this.hide();
- }
- else {
- this.show();
- }
- }));
- }
- this._register(addDisposableListener(this._label, EventType.KEY_UP, e => {
- const event = new StandardKeyboardEvent(e);
- if (event.equals(3 /* KeyCode.Enter */) || event.equals(10 /* KeyCode.Space */)) {
- EventHelper.stop(e, true); // https://github.com/microsoft/vscode/issues/57997
- if (this.visible) {
- this.hide();
- }
- else {
- this.show();
- }
- }
- }));
- const cleanupFn = labelRenderer(this._label);
- if (cleanupFn) {
- this._register(cleanupFn);
- }
- this._register(Gesture.addTarget(this._label));
- }
- get element() {
- return this._element;
- }
- show() {
- if (!this.visible) {
- this.visible = true;
- this._onDidChangeVisibility.fire(true);
- }
- }
- hide() {
- if (this.visible) {
- this.visible = false;
- this._onDidChangeVisibility.fire(false);
- }
- }
- dispose() {
- super.dispose();
- this.hide();
- if (this.boxContainer) {
- this.boxContainer.remove();
- this.boxContainer = undefined;
- }
- if (this.contents) {
- this.contents.remove();
- this.contents = undefined;
- }
- if (this._label) {
- this._label.remove();
- this._label = undefined;
- }
- }
- }
- export class DropdownMenu extends BaseDropdown {
- constructor(container, options) {
- super(container, options);
- this._actions = [];
- this._contextMenuProvider = options.contextMenuProvider;
- this.actions = options.actions || [];
- this.actionProvider = options.actionProvider;
- this.menuClassName = options.menuClassName || '';
- this.menuAsChild = !!options.menuAsChild;
- }
- set menuOptions(options) {
- this._menuOptions = options;
- }
- get menuOptions() {
- return this._menuOptions;
- }
- get actions() {
- if (this.actionProvider) {
- return this.actionProvider.getActions();
- }
- return this._actions;
- }
- set actions(actions) {
- this._actions = actions;
- }
- show() {
- super.show();
- this.element.classList.add('active');
- this._contextMenuProvider.showContextMenu({
- getAnchor: () => this.element,
- getActions: () => this.actions,
- getActionsContext: () => this.menuOptions ? this.menuOptions.context : null,
- getActionViewItem: action => this.menuOptions && this.menuOptions.actionViewItemProvider ? this.menuOptions.actionViewItemProvider(action) : undefined,
- getKeyBinding: action => this.menuOptions && this.menuOptions.getKeyBinding ? this.menuOptions.getKeyBinding(action) : undefined,
- getMenuClassName: () => this.menuClassName,
- onHide: () => this.onHide(),
- actionRunner: this.menuOptions ? this.menuOptions.actionRunner : undefined,
- anchorAlignment: this.menuOptions ? this.menuOptions.anchorAlignment : 0 /* AnchorAlignment.LEFT */,
- domForShadowRoot: this.menuAsChild ? this.element : undefined
- });
- }
- hide() {
- super.hide();
- }
- onHide() {
- this.hide();
- this.element.classList.remove('active');
- }
- }
|