/* eslint-disable @typescript-eslint/no-explicit-any */ import { inject, injectable, optional } from 'inversify'; import { Command, CommandHandler, CommandRegistry } from '@gedit/command'; import { Keybinding, KeybindingRegistry } from '@gedit/layout'; import { Disposable, MenuAction, MenuModelRegistry, MenuPath, SubMenuOptions } from '@gedit/application-common'; import { AbleManager, EntityManager } from '../common'; import { PlaygroundConfig } from './playground-config'; export const PLAYGROUND_ID_PREFIX = '__PG'; export const PlaygroundId = Symbol('PlaygroundId'); export type PlaygroundId = string; export const toCommandId = (playgroundId: string, cmdId: string) => playgroundId + '_' + cmdId; export const toContextMenuPath = (playgroundId: string): MenuPath => ([playgroundId, 'contextmenu']); export interface PlaygroundCommandHandler extends CommandHandler { /** * Execute this handler. */ execute(...args: any[]): any; /** * Test whether this handler is enabled (active). */ isEnabled?(...args: any[]): boolean; /** * Test whether menu items for this handler should be visible. */ isVisible?(...args: any[]): boolean; /** * Test whether menu items for this handler should be toggled. */ isToggled?(...args: any[]): boolean; } @injectable() export class PlaygroundCommandRegistry { @inject(CommandRegistry) @optional() private readonly commands?: CommandRegistry; @inject(AbleManager) readonly ableManager: AbleManager; @inject(EntityManager) readonly entityManager: EntityManager; @inject(PlaygroundId) readonly playgroundId: PlaygroundId; toCommandId(id: string): string { return toCommandId(this.playgroundId, id); } /** * 注册命令 * @param command * @param handler */ registerCommand(command: Command, handler: PlaygroundCommandHandler): Disposable { if (!this.commands) { console.error('Miss command registry'); return Disposable.NULL; } return this.commands.registerCommand({ ...command, id: toCommandId(this.playgroundId, command.id) }, handler); } async executeCommand(commandId: string, ...args: any[]): Promise { if (!this.commands) { console.error('Miss command registry'); return undefined; } return this.commands.executeCommand(toCommandId(this.playgroundId, commandId), ...args); } unregisterCommand(command: Command): void { if (!this.commands) { console.error('Miss command registry'); return; } this.commands.unregisterCommand({ ...command, id: toCommandId(this.playgroundId, command.id) }); } } @injectable() export class PlaygroundMenuRegistry { @inject(MenuModelRegistry) @optional() private readonly menus?: MenuModelRegistry; @inject(PlaygroundId) readonly playgroundId: PlaygroundId; @inject(PlaygroundConfig) readonly playgroundConfig: PlaygroundConfig; toMenuPath(menuPath: MenuPath): MenuPath { if (this.playgroundConfig.contextMenuPath) { return this.playgroundConfig.contextMenuPath.concat(menuPath); } return toContextMenuPath(this.playgroundId).concat(menuPath); } toMenuAction(menuAction: MenuAction): MenuAction { return { ...menuAction, commandId: toCommandId(this.playgroundId, menuAction.commandId) }; } toCommands(commands: Command[]): Command[] { return commands.map(cmd => ({ ...cmd, id: toCommandId(this.playgroundId, cmd.id)})); } /** * 注册右键菜单 */ registerMenuAction(menuPath: MenuPath, menuAction: MenuAction): Disposable { if (!this.menus) { console.error('Miss menu registry'); return Disposable.NULL; } return this.menus.registerMenuAction(this.toMenuPath(menuPath), this.toMenuAction(menuAction)); } registerMenus(menuPath: MenuPath, commands: Command[]): Disposable { if (!this.menus) { console.error('Miss menu registry'); return Disposable.NULL; } return this.menus.registerMenusByCommands(this.toMenuPath(menuPath), this.toCommands(commands)); } registerSubmenus(menuPath: MenuPath, label: string, commands: Command[] = [], options?: SubMenuOptions): Disposable { if (!this.menus) { console.error('Miss menu registry'); return Disposable.NULL; } return this.menus.registerSubmenusByCommands(this.toMenuPath(menuPath), label, this.toCommands(commands), options); } /** * 注册子菜单 */ registerSubmenuAction(menuPath: MenuPath, label: string, options?: SubMenuOptions): Disposable { if (!this.menus) { console.error('Miss menu registry'); return Disposable.NULL; } return this.menus.registerSubmenu(this.toMenuPath(menuPath), label, options); } unregisterMenuAction(item: MenuAction, menuPath?: MenuPath): void { if (!this.menus) { console.error('Miss menu registry'); return; } this.menus.unregisterMenuAction(item, menuPath ? this.toMenuPath(menuPath) : undefined); } } @injectable() export class PlaygroundKeybindingRegistry { @inject(PlaygroundId) readonly playgroundId: PlaygroundId; @inject(KeybindingRegistry) @optional() private readonly keybindings?: KeybindingRegistry; private toKeybinding(keybinding: Keybinding): Keybinding { return { ...keybinding, command: toCommandId(this.playgroundId, keybinding.command) }; } /** * 注册快捷键 */ registerKeybindings(...keybindings: Keybinding[]): Disposable { if (!this.keybindings) { console.error('Miss keybinding registry'); return Disposable.NULL; } return this.keybindings.registerKeybindings(...keybindings.map(k => this.toKeybinding(k))); } unregisterKeybinding(keybinding: Keybinding): void { if (!this.keybindings) { console.error('Miss keybinding registry'); return; } this.keybindings.unregisterKeybinding(this.toKeybinding(keybinding)); } }