@eclipse-glsp/theia-integration
Version:
Glue code to integrate GLSP clients into Eclipse Theia
201 lines • 8.38 kB
JavaScript
"use strict";
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 __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TheiaContextMenuService = exports.TheiaGLSPContextMenu = void 0;
/********************************************************************************
* Copyright (c) 2019-2025 EclipseSource and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
// based on: https://github.com/eclipse-sprotty/sprotty-theia/blob/v0.12.0/src/sprotty/theia-sprotty-context-menu-service.ts
const client_1 = require("@eclipse-glsp/client");
const core_1 = require("@theia/core");
const browser_1 = require("@theia/core/lib/browser");
const inversify_1 = require("inversify");
const glsp_diagram_widget_1 = require("./diagram/glsp-diagram-widget");
var TheiaGLSPContextMenu;
(function (TheiaGLSPContextMenu) {
TheiaGLSPContextMenu.CONTEXT_MENU = ['theia-glsp-context-menu'];
})(TheiaGLSPContextMenu || (exports.TheiaGLSPContextMenu = TheiaGLSPContextMenu = {}));
let TheiaContextMenuService = class TheiaContextMenuService {
constructor() {
this.disposables = [];
}
connect(actionDispatcher) {
this.actionDispatcher = actionDispatcher;
}
get diagramWidget() {
return (0, glsp_diagram_widget_1.getDiagramWidget)(this.shell);
}
show(items, anchor, onHide) {
var _a;
const context = (_a = this.diagramWidget) === null || _a === void 0 ? void 0 : _a.node;
if (!context) {
console.warn('No context available for context menu');
return;
}
this.cleanUpNow();
this.disposables = this.register(TheiaGLSPContextMenu.CONTEXT_MENU, items);
const renderOptions = {
menuPath: TheiaGLSPContextMenu.CONTEXT_MENU,
anchor: anchor,
context,
onHide: () => {
if (onHide) {
onHide();
}
this.scheduleCleanup();
this.restoreFocus();
}
};
this.contextMenuRenderer.render(renderOptions);
}
register(menuPath, items) {
const disposables = [];
for (const item of items) {
if (item.children && item.children.length > 0) {
const menuPathOfItem = item.group ? [...menuPath, item.group] : menuPath;
disposables.push(this.registerSubmenu(menuPathOfItem, item));
disposables.push(...this.register([...menuPathOfItem, item.id], item.children));
}
else {
disposables.push(this.registerCommand(menuPath, item));
disposables.push(this.registerMenuAction(menuPath, item));
}
}
return disposables;
}
registerSubmenu(menuPath, item) {
return this.menuProvider.registerSubmenu([...menuPath, item.id], item.label, { icon: item.icon });
}
registerCommand(menuPath, item) {
const command = { id: commandId(menuPath, item), label: item.label, iconClass: item.icon };
const disposable = this.commandRegistry.registerCommand(command, new GLSPCommandHandler(item, this.actionDispatcher));
return new DisposableCommand(command, disposable);
}
registerMenuAction(menuPath, item) {
const { label, sortString: order, isEnabled, isToggled, isVisible } = item;
const menuAction = { label, order, isEnabled, isToggled, isVisible, commandId: commandId(menuPath, item) };
const menuPathOfItem = item.group ? [...menuPath, item.group] : menuPath;
const disposable = this.menuProvider.registerMenuAction(menuPathOfItem, menuAction);
return new DisposableMenuAction(menuAction, disposable);
}
cleanUpNow() {
window.clearTimeout(this.timeout);
this.cleanUp();
}
scheduleCleanup() {
this.timeout = window.setTimeout(() => {
this.cleanUp();
}, 200);
}
cleanUp() {
this.disposables.forEach(disposable => disposable.dispose(this.menuProvider, this.commandRegistry));
this.disposables = [];
}
restoreFocus() {
const widget = this.diagramWidget;
if (!widget || widget.hasFocus) {
return;
}
widget.actionDispatcher.dispatch(client_1.FocusStateChangedAction.create(true));
}
};
exports.TheiaContextMenuService = TheiaContextMenuService;
__decorate([
(0, inversify_1.inject)(browser_1.ContextMenuRenderer),
__metadata("design:type", browser_1.ContextMenuRenderer)
], TheiaContextMenuService.prototype, "contextMenuRenderer", void 0);
__decorate([
(0, inversify_1.inject)(core_1.MenuModelRegistry),
__metadata("design:type", core_1.MenuModelRegistry)
], TheiaContextMenuService.prototype, "menuProvider", void 0);
__decorate([
(0, inversify_1.inject)(core_1.CommandRegistry),
__metadata("design:type", core_1.CommandRegistry)
], TheiaContextMenuService.prototype, "commandRegistry", void 0);
__decorate([
(0, inversify_1.inject)(browser_1.ApplicationShell),
__metadata("design:type", browser_1.ApplicationShell)
], TheiaContextMenuService.prototype, "shell", void 0);
exports.TheiaContextMenuService = TheiaContextMenuService = __decorate([
(0, inversify_1.injectable)()
], TheiaContextMenuService);
class GLSPCommandHandler {
constructor(menuItem, actionDispatcher) {
this.menuItem = menuItem;
this.actionDispatcher = actionDispatcher;
}
execute(...args) {
if (this.actionDispatcher && this.menuItem.actions) {
this.actionDispatcher.dispatchAll(this.menuItem.actions);
}
}
isEnabled(...args) {
return getBooleanValue(this.menuItem.isEnabled, true);
}
isVisible(...args) {
return getBooleanValue(this.menuItem.isVisible, true);
}
isToggled(...args) {
return getBooleanValue(this.menuItem.isToggled, false);
}
}
class DisposableMenuAction {
constructor(menuAction, disposable) {
this.menuAction = menuAction;
this.disposable = disposable;
}
dispose(menuProvider, commandRegistry) {
menuProvider.unregisterMenuAction(this.menuAction);
this.disposable.dispose();
}
}
class DisposableCommand {
constructor(command, disposable) {
this.command = command;
this.disposable = disposable;
}
dispose(menuProvider, commandRegistry) {
commandRegistry.unregisterCommand(this.command);
this.disposable.dispose();
}
}
function commandId(menuPath, item) {
return menuPath.join('.') + '.' + item.id;
}
function getBooleanValue(value, defaultValue) {
let returnVal = defaultValue;
if (isFunction(value)) {
returnVal = value();
}
else if (isBoolean(value)) {
returnVal = value;
}
return returnVal;
}
function isFunction(value) {
return !!(value && value.constructor && value.apply);
}
function isBoolean(value) {
return typeof value === 'boolean';
}
//# sourceMappingURL=theia-glsp-context-menu-service.js.map