UNPKG

sprotty

Version:

A next-gen framework for graphical views

249 lines 11.2 kB
"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); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var CommandPalette_1; Object.defineProperty(exports, "__esModule", { value: true }); exports.CommandPaletteKeyListener = exports.CommandPalette = void 0; const inversify_1 = require("inversify"); const actions_1 = require("sprotty-protocol/lib/actions"); const action_1 = require("../../base/actions/action"); const types_1 = require("../../base/types"); const ui_extension_1 = require("../../base/ui-extensions/ui-extension"); const ui_extension_registry_1 = require("../../base/ui-extensions/ui-extension-registry"); const dom_helper_1 = require("../../base/views/dom-helper"); const key_tool_1 = require("../../base/views/key-tool"); const codicon_1 = require("../../utils/codicon"); const iterable_1 = require("../../utils/iterable"); const keyboard_1 = require("../../utils/keyboard"); const model_1 = require("../bounds/model"); const model_2 = require("../select/model"); const action_providers_1 = require("./action-providers"); const mouse_tool_1 = require("../../base/views/mouse-tool"); const autocompleter_1 = __importDefault(require("autocompleter")); let CommandPalette = CommandPalette_1 = class CommandPalette extends ui_extension_1.AbstractUIExtension { constructor() { super(...arguments); this.loadingIndicatorClasses = (0, codicon_1.codiconCSSClasses)('loading', false, true, ['loading']); this.xOffset = 20; this.yOffset = 20; this.defaultWidth = 400; this.debounceWaitMs = 100; this.noCommandsMsg = "No commands available"; this.paletteIndex = 0; } id() { return CommandPalette_1.ID; } containerClass() { return "command-palette"; } show(root, ...contextElementIds) { super.show(root, ...contextElementIds); this.paletteIndex = 0; this.contextActions = undefined; this.inputElement.value = ""; this.autoCompleteResult = (0, autocompleter_1.default)(this.autocompleteSettings(root)); this.inputElement.focus(); } initializeContents(containerElement) { containerElement.style.position = "absolute"; this.inputElement = document.createElement('input'); this.inputElement.style.width = '100%'; this.inputElement.addEventListener('keydown', (event) => this.hideIfEscapeEvent(event)); this.inputElement.addEventListener('keydown', (event) => this.cylceIfInvokePaletteKey(event)); this.inputElement.onblur = () => window.setTimeout(() => this.hide(), 200); containerElement.appendChild(this.inputElement); } hideIfEscapeEvent(event) { if ((0, keyboard_1.matchesKeystroke)(event, 'Escape')) { this.hide(); } } cylceIfInvokePaletteKey(event) { if (CommandPalette_1.isInvokePaletteKey(event)) { this.cycle(); } } cycle() { this.contextActions = undefined; this.paletteIndex++; } onBeforeShow(containerElement, root, ...selectedElementIds) { let x = this.xOffset; let y = this.yOffset; const selectedElements = (0, iterable_1.toArray)(root.index.all().filter(e => (0, model_2.isSelectable)(e) && e.selected)); if (selectedElements.length === 1) { const bounds = (0, model_1.getAbsoluteClientBounds)(selectedElements[0], this.domHelper, this.viewerOptions); x += bounds.x + bounds.width; y += bounds.y; } else { const bounds = (0, model_1.getAbsoluteClientBounds)(root, this.domHelper, this.viewerOptions); x += bounds.x; y += bounds.y; } containerElement.style.left = `${x}px`; containerElement.style.top = `${y}px`; containerElement.style.width = `${this.defaultWidth}px`; } autocompleteSettings(root) { return { input: this.inputElement, emptyMsg: this.noCommandsMsg, className: "command-palette-suggestions", debounceWaitMs: this.debounceWaitMs, showOnFocus: true, minLength: -1, fetch: (text, update) => this.updateAutoCompleteActions(update, text, root), onSelect: (item) => this.onSelect(item), render: (item, currentValue) => this.renderLabeledActionSuggestion(item, currentValue), customize: (input, inputRect, container, maxHeight) => { this.customizeSuggestionContainer(container, inputRect, maxHeight); } }; } onSelect(item) { this.executeAction(item); this.hide(); } updateAutoCompleteActions(update, text, root) { this.onLoading(); if (this.contextActions) { update(this.filterActions(text, this.contextActions)); this.onLoaded('success'); } else { this.actionProviderRegistry .getActions(root, text, this.mousePositionTracker.lastPositionOnDiagram, this.paletteIndex) .then(actions => { this.contextActions = actions; update(this.filterActions(text, actions)); this.onLoaded('success'); }) .catch((reason) => { this.logger.error(this, "Failed to obtain actions from command palette action providers", reason); this.onLoaded('error'); }); } } onLoading() { if (this.loadingIndicator && this.containerElement.contains(this.loadingIndicator)) { return; } this.loadingIndicator = document.createElement('span'); this.loadingIndicator.classList.add(...this.loadingIndicatorClasses); this.containerElement.appendChild(this.loadingIndicator); } onLoaded(success) { if (this.containerElement.contains(this.loadingIndicator)) { this.containerElement.removeChild(this.loadingIndicator); } } renderLabeledActionSuggestion(item, value) { const itemElement = document.createElement("div"); const wordMatcher = espaceForRegExp(value).split(" ").join("|"); const regex = new RegExp(wordMatcher, "gi"); if (item.icon) { this.renderIcon(itemElement, item.icon); } if (value.length > 0) { itemElement.innerHTML += item.label.replace(regex, (match) => "<em>" + match + "</em>").replace(/ /g, '&nbsp;'); } else { itemElement.innerHTML += item.label.replace(/ /g, '&nbsp;'); } return itemElement; } renderIcon(itemElement, iconId) { itemElement.innerHTML += `<span class="icon ${this.getCodicon(iconId)}"></span>`; } getFontAwesomeIcon(iconId) { return `fa fa-${iconId}`; } getCodicon(iconId) { return (0, codicon_1.codiconCSSString)(iconId); } filterActions(filterText, actions) { return (0, iterable_1.toArray)(actions.filter(action => { const label = action.label.toLowerCase(); const searchWords = filterText.split(' '); return searchWords.every(word => label.indexOf(word.toLowerCase()) !== -1); })); } customizeSuggestionContainer(container, inputRect, maxHeight) { // move container into our command palette container as this is already positioned correctly container.style.position = "fixed"; if (this.containerElement) { this.containerElement.appendChild(container); } } hide() { super.hide(); if (this.autoCompleteResult) { this.autoCompleteResult.destroy(); } } executeAction(input) { this.actionDispatcherProvider() .then((actionDispatcher) => actionDispatcher.dispatchAll(toActionArray(input))) .catch((reason) => this.logger.error(this, 'No action dispatcher available to execute command palette action', reason)); } }; exports.CommandPalette = CommandPalette; CommandPalette.ID = "command-palette"; CommandPalette.isInvokePaletteKey = (event) => (0, keyboard_1.matchesKeystroke)(event, 'Space', 'ctrl'); __decorate([ (0, inversify_1.inject)(types_1.TYPES.IActionDispatcherProvider), __metadata("design:type", Function) ], CommandPalette.prototype, "actionDispatcherProvider", void 0); __decorate([ (0, inversify_1.inject)(types_1.TYPES.ICommandPaletteActionProviderRegistry), __metadata("design:type", action_providers_1.CommandPaletteActionProviderRegistry) ], CommandPalette.prototype, "actionProviderRegistry", void 0); __decorate([ (0, inversify_1.inject)(types_1.TYPES.ViewerOptions), __metadata("design:type", Object) ], CommandPalette.prototype, "viewerOptions", void 0); __decorate([ (0, inversify_1.inject)(types_1.TYPES.DOMHelper), __metadata("design:type", dom_helper_1.DOMHelper) ], CommandPalette.prototype, "domHelper", void 0); __decorate([ (0, inversify_1.inject)(mouse_tool_1.MousePositionTracker), __metadata("design:type", mouse_tool_1.MousePositionTracker) ], CommandPalette.prototype, "mousePositionTracker", void 0); exports.CommandPalette = CommandPalette = CommandPalette_1 = __decorate([ (0, inversify_1.injectable)() ], CommandPalette); function toActionArray(input) { if ((0, action_1.isLabeledAction)(input)) { return input.actions; } else if ((0, actions_1.isAction)(input)) { return [input]; } return []; } function espaceForRegExp(value) { return value.replace(/([.?*+^$[\]\\(){}|-])/g, '\\$1'); } class CommandPaletteKeyListener extends key_tool_1.KeyListener { keyDown(element, event) { if ((0, keyboard_1.matchesKeystroke)(event, 'Escape')) { return [ui_extension_registry_1.SetUIExtensionVisibilityAction.create({ extensionId: CommandPalette.ID, visible: false, contextElementsId: [] })]; } else if (CommandPalette.isInvokePaletteKey(event)) { const selectedElements = (0, iterable_1.toArray)(element.index.all().filter(e => (0, model_2.isSelectable)(e) && e.selected).map(e => e.id)); return [ui_extension_registry_1.SetUIExtensionVisibilityAction.create({ extensionId: CommandPalette.ID, visible: true, contextElementsId: selectedElements })]; } return []; } } exports.CommandPaletteKeyListener = CommandPaletteKeyListener; //# sourceMappingURL=command-palette.js.map