@eclipse-glsp/client 2.6.0-next.1 → 2.6.0-next.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. package/css/command-palette.css +2 -0
  2. package/css/navigation.css +2 -2
  3. package/css/search.css +12 -3
  4. package/lib/base/action-dispatcher.d.ts +7 -1
  5. package/lib/base/action-dispatcher.d.ts.map +1 -1
  6. package/lib/base/action-dispatcher.js +82 -15
  7. package/lib/base/action-dispatcher.js.map +1 -1
  8. package/lib/base/auto-complete/auto-complete-widget.d.ts +2 -2
  9. package/lib/base/auto-complete/auto-complete-widget.d.ts.map +1 -1
  10. package/lib/base/auto-complete/auto-complete-widget.js +5 -2
  11. package/lib/base/auto-complete/auto-complete-widget.js.map +1 -1
  12. package/lib/base/auto-complete/autocomplete-suggestion-provider.d.ts +56 -0
  13. package/lib/base/auto-complete/autocomplete-suggestion-provider.d.ts.map +1 -0
  14. package/lib/base/auto-complete/autocomplete-suggestion-provider.js +56 -0
  15. package/lib/base/auto-complete/autocomplete-suggestion-provider.js.map +1 -0
  16. package/lib/base/auto-complete/base-autocomplete-palette.d.ts +4 -9
  17. package/lib/base/auto-complete/base-autocomplete-palette.d.ts.map +1 -1
  18. package/lib/base/auto-complete/base-autocomplete-palette.js +2 -2
  19. package/lib/base/auto-complete/base-autocomplete-palette.js.map +1 -1
  20. package/lib/base/default.module.d.ts.map +1 -1
  21. package/lib/base/default.module.js +4 -0
  22. package/lib/base/default.module.js.map +1 -1
  23. package/lib/base/messages.json +68 -57
  24. package/lib/base/tool-manager/tool-manager.d.ts +2 -2
  25. package/lib/base/tool-manager/tool-manager.d.ts.map +1 -1
  26. package/lib/base/tool-manager/tool-manager.js +4 -4
  27. package/lib/base/tool-manager/tool-manager.js.map +1 -1
  28. package/lib/default-modules.d.ts +1 -1
  29. package/lib/default-modules.d.ts.map +1 -1
  30. package/lib/default-modules.js +4 -1
  31. package/lib/default-modules.js.map +1 -1
  32. package/lib/features/accessibility/accessibility-module.d.ts.map +1 -1
  33. package/lib/features/accessibility/accessibility-module.js +2 -4
  34. package/lib/features/accessibility/accessibility-module.js.map +1 -1
  35. package/lib/features/accessibility/edge-autocomplete/edge-autocomplete-palette.d.ts +21 -15
  36. package/lib/features/accessibility/edge-autocomplete/edge-autocomplete-palette.d.ts.map +1 -1
  37. package/lib/features/accessibility/edge-autocomplete/edge-autocomplete-palette.js +59 -45
  38. package/lib/features/accessibility/edge-autocomplete/edge-autocomplete-palette.js.map +1 -1
  39. package/lib/features/accessibility/element-navigation/diagram-navigation-tool.d.ts.map +1 -1
  40. package/lib/features/accessibility/element-navigation/diagram-navigation-tool.js +2 -3
  41. package/lib/features/accessibility/element-navigation/diagram-navigation-tool.js.map +1 -1
  42. package/lib/features/accessibility/{keyboard-pointer/keyboard-pointer-module.d.ts → keyboard/keyboard-module.d.ts} +2 -2
  43. package/lib/features/accessibility/keyboard/keyboard-module.d.ts.map +1 -0
  44. package/lib/features/accessibility/{keyboard-pointer/keyboard-pointer-module.js → keyboard/keyboard-module.js} +7 -4
  45. package/lib/features/accessibility/keyboard/keyboard-module.js.map +1 -0
  46. package/lib/features/accessibility/keyboard-grid/keyboard-grid-search-palette.d.ts +15 -12
  47. package/lib/features/accessibility/keyboard-grid/keyboard-grid-search-palette.d.ts.map +1 -1
  48. package/lib/features/accessibility/keyboard-grid/keyboard-grid-search-palette.js +40 -22
  49. package/lib/features/accessibility/keyboard-grid/keyboard-grid-search-palette.js.map +1 -1
  50. package/lib/features/accessibility/keyboard-grid/keyboard-node-grid.d.ts +1 -1
  51. package/lib/features/accessibility/keyboard-grid/keyboard-node-grid.js +2 -2
  52. package/lib/features/accessibility/keyboard-grid/keyboard-node-grid.js.map +1 -1
  53. package/lib/features/bounds/glsp-hidden-bounds-updater.d.ts +1 -1
  54. package/lib/features/bounds/glsp-hidden-bounds-updater.d.ts.map +1 -1
  55. package/lib/features/bounds/glsp-hidden-bounds-updater.js +4 -1
  56. package/lib/features/bounds/glsp-hidden-bounds-updater.js.map +1 -1
  57. package/lib/features/change-bounds/movement-restrictor.d.ts +12 -4
  58. package/lib/features/change-bounds/movement-restrictor.d.ts.map +1 -1
  59. package/lib/features/change-bounds/movement-restrictor.js +44 -17
  60. package/lib/features/change-bounds/movement-restrictor.js.map +1 -1
  61. package/lib/features/command-palette/command-palette.d.ts +3 -1
  62. package/lib/features/command-palette/command-palette.d.ts.map +1 -1
  63. package/lib/features/command-palette/command-palette.js +37 -0
  64. package/lib/features/command-palette/command-palette.js.map +1 -1
  65. package/lib/features/context-menu/delete-element-context-menu.d.ts +4 -4
  66. package/lib/features/context-menu/delete-element-context-menu.d.ts.map +1 -1
  67. package/lib/features/context-menu/delete-element-context-menu.js +6 -2
  68. package/lib/features/context-menu/delete-element-context-menu.js.map +1 -1
  69. package/lib/features/context-menu/server-context-menu-provider.d.ts +4 -4
  70. package/lib/features/context-menu/server-context-menu-provider.d.ts.map +1 -1
  71. package/lib/features/context-menu/server-context-menu-provider.js +4 -5
  72. package/lib/features/context-menu/server-context-menu-provider.js.map +1 -1
  73. package/lib/features/copy-paste/copy-paste-context-menu.d.ts +22 -5
  74. package/lib/features/copy-paste/copy-paste-context-menu.d.ts.map +1 -1
  75. package/lib/features/copy-paste/copy-paste-context-menu.js +16 -11
  76. package/lib/features/copy-paste/copy-paste-context-menu.js.map +1 -1
  77. package/lib/features/decoration/decoration-module.d.ts +1 -1
  78. package/lib/features/decoration/decoration-module.d.ts.map +1 -1
  79. package/lib/features/decoration/decoration-module.js +2 -1
  80. package/lib/features/decoration/decoration-module.js.map +1 -1
  81. package/lib/features/decoration/decoration-placer.d.ts +9 -3
  82. package/lib/features/decoration/decoration-placer.d.ts.map +1 -1
  83. package/lib/features/decoration/decoration-placer.js +32 -1
  84. package/lib/features/decoration/decoration-placer.js.map +1 -1
  85. package/{src/features/accessibility/edge-autocomplete/edge-autocomplete-context.ts → lib/features/search-palette/search-palette-key-listener.d.ts} +5 -9
  86. package/lib/features/search-palette/search-palette-key-listener.d.ts.map +1 -0
  87. package/lib/features/search-palette/search-palette-key-listener.js +45 -0
  88. package/lib/features/search-palette/search-palette-key-listener.js.map +1 -0
  89. package/lib/features/{accessibility/search → search-palette}/search-palette-module.d.ts +4 -3
  90. package/lib/features/search-palette/search-palette-module.d.ts.map +1 -0
  91. package/lib/features/search-palette/search-palette-module.js +39 -0
  92. package/lib/features/search-palette/search-palette-module.js.map +1 -0
  93. package/lib/features/search-palette/search-palette.d.ts +51 -0
  94. package/lib/features/search-palette/search-palette.d.ts.map +1 -0
  95. package/lib/features/search-palette/search-palette.js +141 -0
  96. package/lib/features/search-palette/search-palette.js.map +1 -0
  97. package/{src/base/auto-complete/autocomplete-suggestion-providers.ts → lib/features/search-palette/suggestions/edge-element-suggestions.d.ts} +11 -22
  98. package/lib/features/search-palette/suggestions/edge-element-suggestions.d.ts.map +1 -0
  99. package/lib/features/search-palette/suggestions/edge-element-suggestions.js +72 -0
  100. package/lib/features/search-palette/suggestions/edge-element-suggestions.js.map +1 -0
  101. package/lib/features/search-palette/suggestions/named-element-suggestions.d.ts +30 -0
  102. package/lib/features/search-palette/suggestions/named-element-suggestions.d.ts.map +1 -0
  103. package/lib/features/search-palette/suggestions/named-element-suggestions.js +83 -0
  104. package/lib/features/search-palette/suggestions/named-element-suggestions.js.map +1 -0
  105. package/lib/features/validation/marker-navigator.d.ts +3 -3
  106. package/lib/features/validation/marker-navigator.d.ts.map +1 -1
  107. package/lib/features/validation/marker-navigator.js +8 -7
  108. package/lib/features/validation/marker-navigator.js.map +1 -1
  109. package/lib/features/viewport/reposition.d.ts.map +1 -1
  110. package/lib/features/viewport/reposition.js +1 -5
  111. package/lib/features/viewport/reposition.js.map +1 -1
  112. package/lib/index.d.ts +7 -6
  113. package/lib/index.d.ts.map +1 -1
  114. package/lib/index.js +7 -6
  115. package/lib/index.js.map +1 -1
  116. package/lib/standalone-modules.d.ts +1 -1
  117. package/lib/standalone-modules.d.ts.map +1 -1
  118. package/lib/standalone-modules.js +2 -0
  119. package/lib/standalone-modules.js.map +1 -1
  120. package/lib/utils/gmodel-util.d.ts +32 -2
  121. package/lib/utils/gmodel-util.d.ts.map +1 -1
  122. package/lib/utils/gmodel-util.js +29 -1
  123. package/lib/utils/gmodel-util.js.map +1 -1
  124. package/package.json +3 -3
  125. package/src/base/action-dispatcher.ts +88 -15
  126. package/src/base/auto-complete/auto-complete-widget.ts +7 -4
  127. package/src/base/auto-complete/autocomplete-suggestion-provider.ts +86 -0
  128. package/src/base/auto-complete/base-autocomplete-palette.ts +6 -6
  129. package/src/base/default.module.ts +5 -0
  130. package/src/base/messages.json +68 -57
  131. package/src/base/tool-manager/tool-manager.ts +4 -4
  132. package/src/default-modules.ts +4 -1
  133. package/src/features/accessibility/accessibility-module.ts +1 -3
  134. package/src/features/accessibility/edge-autocomplete/edge-autocomplete-palette.ts +75 -52
  135. package/src/features/accessibility/element-navigation/diagram-navigation-tool.ts +2 -4
  136. package/src/features/accessibility/{keyboard-pointer/keyboard-pointer-module.ts → keyboard/keyboard-module.ts} +12 -5
  137. package/src/features/accessibility/keyboard-grid/keyboard-grid-search-palette.ts +36 -22
  138. package/src/features/accessibility/keyboard-grid/keyboard-node-grid.ts +3 -3
  139. package/src/features/bounds/glsp-hidden-bounds-updater.ts +5 -1
  140. package/src/features/change-bounds/movement-restrictor.ts +72 -19
  141. package/src/features/command-palette/command-palette.ts +41 -1
  142. package/src/features/context-menu/delete-element-context-menu.ts +9 -5
  143. package/src/features/context-menu/server-context-menu-provider.ts +8 -9
  144. package/src/features/copy-paste/copy-paste-context-menu.ts +21 -17
  145. package/src/features/decoration/decoration-module.ts +2 -1
  146. package/src/features/decoration/decoration-placer.ts +49 -4
  147. package/src/features/{accessibility/search/search-palette-module.ts → search-palette/search-palette-key-listener.ts} +15 -14
  148. package/src/features/search-palette/search-palette-module.ts +48 -0
  149. package/src/features/search-palette/search-palette.ts +164 -0
  150. package/src/features/search-palette/suggestions/edge-element-suggestions.ts +71 -0
  151. package/src/features/search-palette/suggestions/named-element-suggestions.ts +88 -0
  152. package/src/features/validation/marker-navigator.ts +9 -8
  153. package/src/features/viewport/reposition.ts +1 -7
  154. package/src/index.ts +7 -6
  155. package/src/standalone-modules.ts +2 -0
  156. package/src/utils/gmodel-util.ts +59 -1
  157. package/lib/base/auto-complete/autocomplete-suggestion-providers.d.ts +0 -35
  158. package/lib/base/auto-complete/autocomplete-suggestion-providers.d.ts.map +0 -1
  159. package/lib/base/auto-complete/autocomplete-suggestion-providers.js +0 -18
  160. package/lib/base/auto-complete/autocomplete-suggestion-providers.js.map +0 -1
  161. package/lib/features/accessibility/edge-autocomplete/edge-autocomplete-context.d.ts +0 -23
  162. package/lib/features/accessibility/edge-autocomplete/edge-autocomplete-context.d.ts.map +0 -1
  163. package/lib/features/accessibility/edge-autocomplete/edge-autocomplete-context.js +0 -18
  164. package/lib/features/accessibility/edge-autocomplete/edge-autocomplete-context.js.map +0 -1
  165. package/lib/features/accessibility/keyboard-pointer/keyboard-pointer-module.d.ts.map +0 -1
  166. package/lib/features/accessibility/keyboard-pointer/keyboard-pointer-module.js.map +0 -1
  167. package/lib/features/accessibility/search/search-palette-module.d.ts.map +0 -1
  168. package/lib/features/accessibility/search/search-palette-module.js +0 -32
  169. package/lib/features/accessibility/search/search-palette-module.js.map +0 -1
  170. package/lib/features/accessibility/search/search-palette.d.ts +0 -51
  171. package/lib/features/accessibility/search/search-palette.d.ts.map +0 -1
  172. package/lib/features/accessibility/search/search-palette.js +0 -186
  173. package/lib/features/accessibility/search/search-palette.js.map +0 -1
  174. package/lib/features/accessibility/search/search-tool.d.ts +0 -33
  175. package/lib/features/accessibility/search/search-tool.d.ts.map +0 -1
  176. package/lib/features/accessibility/search/search-tool.js +0 -84
  177. package/lib/features/accessibility/search/search-tool.js.map +0 -1
  178. package/src/features/accessibility/search/search-palette.ts +0 -218
  179. package/src/features/accessibility/search/search-tool.ts +0 -74
@@ -14,20 +14,21 @@
14
14
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
15
  ********************************************************************************/
16
16
 
17
- import { bindAsService, BindingContext, FeatureModule, TYPES } from '@eclipse-glsp/sprotty';
18
- import '../../../../css/search.css';
17
+ import { Action, GModelElement, KeyListener, matchesKeystroke, SetUIExtensionVisibilityAction } from '@eclipse-glsp/sprotty';
18
+ import { injectable } from 'inversify';
19
19
  import { SearchAutocompletePalette } from './search-palette';
20
- import { SearchAutocompletePaletteTool } from './search-tool';
21
20
 
22
- export const searchPaletteModule = new FeatureModule(
23
- (bind, _unbind, isBound, rebind) => {
24
- const context = { bind, isBound, rebind };
25
- configureSearchPaletteModule(context);
26
- },
27
- { featureId: Symbol('searchPalette') }
28
- );
29
-
30
- export function configureSearchPaletteModule(context: Pick<BindingContext, 'bind'>): void {
31
- bindAsService(context, TYPES.IUIExtension, SearchAutocompletePalette);
32
- bindAsService(context, TYPES.IDefaultTool, SearchAutocompletePaletteTool);
21
+ @injectable()
22
+ export class SearchPaletteKeyListener extends KeyListener {
23
+ override keyDown(element: GModelElement, event: KeyboardEvent): Action[] {
24
+ if (matchesKeystroke(event, 'KeyF', 'ctrlCmd')) {
25
+ return [
26
+ SetUIExtensionVisibilityAction.create({
27
+ extensionId: SearchAutocompletePalette.ID,
28
+ visible: true
29
+ })
30
+ ];
31
+ }
32
+ return [];
33
+ }
33
34
  }
@@ -0,0 +1,48 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2023-2025 Business Informatics Group (TU Wien) and others.
3
+ *
4
+ * This program and the accompanying materials are made available under the
5
+ * terms of the Eclipse Public License v. 2.0 which is available at
6
+ * http://www.eclipse.org/legal/epl-2.0.
7
+ *
8
+ * This Source Code may also be made available under the following Secondary
9
+ * Licenses when the conditions for such availability set forth in the Eclipse
10
+ * Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ * with the GNU Classpath Exception which is available at
12
+ * https://www.gnu.org/software/classpath/license.html.
13
+ *
14
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
+ ********************************************************************************/
16
+
17
+ import { bindAsService, FeatureModule, TYPES } from '@eclipse-glsp/sprotty';
18
+ import '../../../css/search.css';
19
+ import { SearchAutocompletePalette } from './search-palette';
20
+ import { SearchPaletteKeyListener } from './search-palette-key-listener';
21
+ import { RevealEdgeElementSuggestionProvider } from './suggestions/edge-element-suggestions';
22
+ import { NodesWithoutNameSuggestionProvider, RevealNamedElementSuggestionProvider } from './suggestions/named-element-suggestions';
23
+
24
+ export const searchPaletteModule = new FeatureModule(
25
+ (bind, _unbind, isBound, rebind) => {
26
+ const context = { bind, isBound, rebind };
27
+ bindAsService(context, TYPES.IUIExtension, SearchAutocompletePalette);
28
+ },
29
+ { featureId: Symbol('searchPalette') }
30
+ );
31
+
32
+ export const searchPaletteDefaultSuggestionsModule = new FeatureModule(
33
+ (bind, _unbind, isBound, rebind) => {
34
+ const context = { bind, isBound, rebind };
35
+ bindAsService(context, TYPES.IAutocompleteSuggestionProvider, RevealNamedElementSuggestionProvider);
36
+ bindAsService(context, TYPES.IAutocompleteSuggestionProvider, NodesWithoutNameSuggestionProvider);
37
+ bindAsService(context, TYPES.IAutocompleteSuggestionProvider, RevealEdgeElementSuggestionProvider);
38
+ },
39
+ { featureId: Symbol('searchPaletteDefaultSuggestions'), requires: searchPaletteModule }
40
+ );
41
+
42
+ export const standaloneSearchPaletteModule = new FeatureModule(
43
+ (bind, _unbind, isBound) => {
44
+ const context = { bind, isBound };
45
+ bindAsService(context, TYPES.KeyListener, SearchPaletteKeyListener);
46
+ },
47
+ { featureId: Symbol('standaloneSearchPalette'), requires: searchPaletteModule }
48
+ );
@@ -0,0 +1,164 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2023-2025 Business Informatics Group (TU Wien) and others.
3
+ *
4
+ * This program and the accompanying materials are made available under the
5
+ * terms of the Eclipse Public License v. 2.0 which is available at
6
+ * http://www.eclipse.org/legal/epl-2.0.
7
+ *
8
+ * This Source Code may also be made available under the following Secondary
9
+ * Licenses when the conditions for such availability set forth in the Eclipse
10
+ * Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ * with the GNU Classpath Exception which is available at
12
+ * https://www.gnu.org/software/classpath/license.html.
13
+ *
14
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
+ ********************************************************************************/
16
+
17
+ import { GModelElement, GModelRoot, GNode, LabeledAction, SelectAllAction, toArray, TYPES } from '@eclipse-glsp/sprotty';
18
+ import { inject, injectable } from 'inversify';
19
+ import { debounce, isEqual } from 'lodash';
20
+ import {
21
+ AutocompleteSuggestionProviderContext,
22
+ type AutocompleteSuggestion,
23
+ type AutocompleteSuggestionRegistry
24
+ } from '../../base/auto-complete/autocomplete-suggestion-provider';
25
+ import { BaseAutocompletePalette } from '../../base/auto-complete/base-autocomplete-palette';
26
+ import { applyCssClasses, deleteCssClasses } from '../../base/feedback/css-feedback';
27
+ import { messages } from '../../base/messages';
28
+ import { GEdge } from '../../model';
29
+ import { RepositionAction } from '../viewport/reposition';
30
+
31
+ const CSS_SEARCH_HIDDEN = 'search-hidden';
32
+ const CSS_SEARCH_HIGHLIGHTED = 'search-highlighted';
33
+
34
+ export interface SearchAutocompleteSuggestion extends Required<AutocompleteSuggestion> {}
35
+
36
+ export namespace SearchAutocompleteSuggestion {
37
+ export function is(suggestion: AutocompleteSuggestion): suggestion is SearchAutocompleteSuggestion {
38
+ return suggestion.element !== undefined;
39
+ }
40
+ }
41
+
42
+ @injectable()
43
+ export class SearchAutocompletePalette extends BaseAutocompletePalette {
44
+ static readonly ID: string = 'glsp.search-autocomplete-palette';
45
+
46
+ @inject(TYPES.IAutocompleteSuggestionProviderRegistry)
47
+ protected readonly suggestionRegistry: AutocompleteSuggestionRegistry;
48
+
49
+ /**
50
+ * Cache the suggestions so that we don't have to retrieve them again for CSS manipulation.
51
+ */
52
+ protected cachedSuggestions: SearchAutocompleteSuggestion[] = [];
53
+
54
+ id(): string {
55
+ return SearchAutocompletePalette.ID;
56
+ }
57
+
58
+ /**
59
+ * The search context for the search palette. This is used to filter the suggestions
60
+ */
61
+ get searchContext(): string[] {
62
+ return [AutocompleteSuggestionProviderContext.CANVAS];
63
+ }
64
+
65
+ protected override initializeContents(containerElement: HTMLElement): void {
66
+ super.initializeContents(containerElement);
67
+
68
+ this.autocompleteWidget.inputField.placeholder = messages.search.placeholder;
69
+ containerElement.setAttribute('aria-label', messages.search.label);
70
+ }
71
+
72
+ protected async retrieveSuggestions(root: Readonly<GModelRoot>, input: string): Promise<LabeledAction[]> {
73
+ const suggestions = await this.provideSearchSuggestions(root, input);
74
+ this.cachedSuggestions = suggestions;
75
+ return suggestions.map(s => s.action);
76
+ }
77
+
78
+ protected async provideSearchSuggestions(root: Readonly<GModelRoot>, input: string): Promise<SearchAutocompleteSuggestion[]> {
79
+ return (
80
+ await Promise.all(
81
+ this.suggestionRegistry.providersForContext(this.searchContext).flatMap(provider => provider.getSuggestions(root, input))
82
+ )
83
+ )
84
+ .flat(1)
85
+ .filter(SearchAutocompleteSuggestion.is);
86
+ }
87
+
88
+ protected override async visibleSuggestionsChanged(root: Readonly<GModelRoot>, labeledActions: LabeledAction[]): Promise<void> {
89
+ await this.applyCSS(this.getHiddenElements(root, this.getSuggestionsFromLabeledActions(labeledActions)), CSS_SEARCH_HIDDEN);
90
+ await this.deleteCSS(
91
+ this.getSuggestionsFromLabeledActions(labeledActions)
92
+ .filter(s => s.element)
93
+ .map(s => s.element!),
94
+ CSS_SEARCH_HIDDEN
95
+ );
96
+ }
97
+
98
+ protected override async selectedSuggestionChanged(
99
+ root: Readonly<GModelRoot>,
100
+ labeledAction?: LabeledAction | undefined
101
+ ): Promise<void> {
102
+ await this.handleSuggestionChanged(root, labeledAction);
103
+ }
104
+
105
+ protected readonly handleSuggestionChanged = debounce(this.doHandleSuggestionChanged, 300, { trailing: true });
106
+ protected async doHandleSuggestionChanged(root: Readonly<GModelRoot>, labeledAction?: LabeledAction | undefined): Promise<void> {
107
+ await this.deleteAllCSS(root, CSS_SEARCH_HIGHLIGHTED);
108
+ if (labeledAction !== undefined) {
109
+ const suggestions = this.getSuggestionsFromLabeledActions([labeledAction]);
110
+
111
+ const actions: RepositionAction[] = [];
112
+ suggestions.map(currElem => actions.push(RepositionAction.create([currElem.element.id])));
113
+
114
+ this.actionDispatcher.dispatchAll(actions);
115
+ await this.applyCSS(
116
+ suggestions.map(s => s.element),
117
+ CSS_SEARCH_HIGHLIGHTED
118
+ );
119
+ }
120
+ }
121
+
122
+ override show(root: Readonly<GModelRoot>, ...contextElementIds: string[]): void {
123
+ this.actionDispatcher.dispatch(SelectAllAction.create(false));
124
+
125
+ super.show(root, ...contextElementIds);
126
+ }
127
+
128
+ override hide(): void {
129
+ if (this.root !== undefined) {
130
+ this.deleteAllCSS(this.root, CSS_SEARCH_HIDDEN, CSS_SEARCH_HIGHLIGHTED);
131
+ this.autocompleteWidget.inputField.value = '';
132
+ }
133
+
134
+ super.hide();
135
+ }
136
+
137
+ protected applyCSS(elements: GModelElement[], ...add: string[]): Promise<void> {
138
+ const actions = elements.map(element => applyCssClasses(element, ...add));
139
+ return this.actionDispatcher.dispatchAll(actions);
140
+ }
141
+
142
+ protected deleteCSS(elements: GModelElement[], ...remove: string[]): Promise<void> {
143
+ const actions = elements.map(element => deleteCssClasses(element, ...remove));
144
+ return this.actionDispatcher.dispatchAll(actions);
145
+ }
146
+
147
+ protected deleteAllCSS(root: Readonly<GModelRoot>, ...remove: string[]): Promise<void> {
148
+ const actions = toArray(root.index.all().map(element => deleteCssClasses(element, ...remove)));
149
+ return this.actionDispatcher.dispatchAll(actions);
150
+ }
151
+
152
+ protected getSuggestionsFromLabeledActions(labeledActions: LabeledAction[]): SearchAutocompleteSuggestion[] {
153
+ return this.cachedSuggestions.filter(c => labeledActions.find(s => isEqual(s, c.action)));
154
+ }
155
+
156
+ protected getHiddenElements(root: Readonly<GModelRoot>, suggestions: SearchAutocompleteSuggestion[]): GModelElement[] {
157
+ return toArray(
158
+ root.index
159
+ .all()
160
+ .filter(element => element instanceof GNode || element instanceof GEdge)
161
+ .filter(element => suggestions.find(suggestion => suggestion.element.id === element.id) === undefined)
162
+ );
163
+ }
164
+ }
@@ -0,0 +1,71 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2023-2025 Business Informatics Group (TU Wien) and others.
3
+ *
4
+ * This program and the accompanying materials are made available under the
5
+ * terms of the Eclipse Public License v. 2.0 which is available at
6
+ * http://www.eclipse.org/legal/epl-2.0.
7
+ *
8
+ * This Source Code may also be made available under the following Secondary
9
+ * Licenses when the conditions for such availability set forth in the Eclipse
10
+ * Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ * with the GNU Classpath Exception which is available at
12
+ * https://www.gnu.org/software/classpath/license.html.
13
+ *
14
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
+ ********************************************************************************/
16
+
17
+ import { Action, CenterAction, GModelRoot, SelectAction, codiconCSSString, name, toArray } from '@eclipse-glsp/sprotty';
18
+ import { injectable } from 'inversify';
19
+ import {
20
+ AutocompleteSuggestionProviderContext,
21
+ IAutocompleteSuggestionProvider,
22
+ type AutocompleteSuggestion
23
+ } from '../../../base/auto-complete/autocomplete-suggestion-provider';
24
+ import { GEdge } from '../../../model';
25
+
26
+ @injectable()
27
+ export class RevealEdgeElementSuggestionProvider implements IAutocompleteSuggestionProvider {
28
+ get id(): string {
29
+ return 'glsp.reveal-edge-element-suggestion';
30
+ }
31
+
32
+ canHandle(context: string): boolean {
33
+ return context === AutocompleteSuggestionProviderContext.CANVAS;
34
+ }
35
+
36
+ async getSuggestions(root: Readonly<GModelRoot>, text: string): Promise<AutocompleteSuggestion[]> {
37
+ const edges = toArray(root.index.all().filter(element => element instanceof GEdge)) as GEdge[];
38
+ return edges.map(edge => ({
39
+ element: edge,
40
+ action: {
41
+ label: `[${edge.type}] ${this.getEdgeLabel(root, edge)}`,
42
+ actions: this.createActions(edge),
43
+ icon: codiconCSSString('arrow-both')
44
+ }
45
+ }));
46
+ }
47
+
48
+ protected createActions(edge: GEdge): Action[] {
49
+ return [
50
+ SelectAction.create({ selectedElementsIDs: [edge.id] }),
51
+ CenterAction.create([edge.sourceId, edge.targetId], { retainZoom: true })
52
+ ];
53
+ }
54
+
55
+ protected getEdgeLabel(root: Readonly<GModelRoot>, edge: GEdge): string {
56
+ let sourceName = '';
57
+ let targetName = '';
58
+
59
+ const sourceNode = root.index.getById(edge.sourceId);
60
+ const targetNode = root.index.getById(edge.targetId);
61
+
62
+ if (sourceNode !== undefined) {
63
+ sourceName = name(sourceNode) ?? sourceNode.type;
64
+ }
65
+ if (targetNode !== undefined) {
66
+ targetName = name(targetNode) ?? targetNode.type;
67
+ }
68
+
69
+ return sourceName + ' -> ' + targetName;
70
+ }
71
+ }
@@ -0,0 +1,88 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2023-2025 Business Informatics Group (TU Wien) and others.
3
+ *
4
+ * This program and the accompanying materials are made available under the
5
+ * terms of the Eclipse Public License v. 2.0 which is available at
6
+ * http://www.eclipse.org/legal/epl-2.0.
7
+ *
8
+ * This Source Code may also be made available under the following Secondary
9
+ * Licenses when the conditions for such availability set forth in the Eclipse
10
+ * Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ * with the GNU Classpath Exception which is available at
12
+ * https://www.gnu.org/software/classpath/license.html.
13
+ *
14
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
+ ********************************************************************************/
16
+
17
+ import {
18
+ Action,
19
+ CenterAction,
20
+ codiconCSSString,
21
+ GModelElement,
22
+ GModelRoot,
23
+ GNode,
24
+ isNameable,
25
+ name,
26
+ SelectAction,
27
+ toArray
28
+ } from '@eclipse-glsp/sprotty';
29
+ import { injectable } from 'inversify';
30
+ import {
31
+ AutocompleteSuggestionProviderContext,
32
+ IAutocompleteSuggestionProvider,
33
+ type AutocompleteSuggestion
34
+ } from '../../../base/auto-complete/autocomplete-suggestion-provider';
35
+
36
+ @injectable()
37
+ export class RevealNamedElementSuggestionProvider implements IAutocompleteSuggestionProvider {
38
+ get id(): string {
39
+ return 'glsp.reveal-named-element-suggestion';
40
+ }
41
+
42
+ canHandle(context: string): boolean {
43
+ return context === AutocompleteSuggestionProviderContext.CANVAS;
44
+ }
45
+
46
+ async getSuggestions(root: Readonly<GModelRoot>, text: string): Promise<AutocompleteSuggestion[]> {
47
+ const nameables = toArray(root.index.all().filter(element => isNameable(element)));
48
+ return nameables.map(nameable => ({
49
+ element: nameable,
50
+ action: {
51
+ label: `[${nameable.type}] ${name(nameable) ?? '<no-name>'}`,
52
+ actions: this.createActions(nameable),
53
+ icon: codiconCSSString('eye')
54
+ }
55
+ }));
56
+ }
57
+
58
+ protected createActions(nameable: GModelElement): Action[] {
59
+ return [SelectAction.create({ selectedElementsIDs: [nameable.id] }), CenterAction.create([nameable.id], { retainZoom: true })];
60
+ }
61
+ }
62
+
63
+ @injectable()
64
+ export class NodesWithoutNameSuggestionProvider implements IAutocompleteSuggestionProvider {
65
+ get id(): string {
66
+ return 'glsp.reveal-nodes-without-name-suggestion';
67
+ }
68
+
69
+ canHandle(searchContext: string): boolean {
70
+ return searchContext === AutocompleteSuggestionProviderContext.CANVAS;
71
+ }
72
+
73
+ async getSuggestions(root: Readonly<GModelRoot>, text: string): Promise<AutocompleteSuggestion[]> {
74
+ const nodes = toArray(root.index.all().filter(element => !isNameable(element) && element instanceof GNode));
75
+ return nodes.map(node => ({
76
+ element: node,
77
+ action: {
78
+ label: `[${node.type}]`,
79
+ actions: this.createActions(node),
80
+ icon: codiconCSSString('symbol-namespace')
81
+ }
82
+ }));
83
+ }
84
+
85
+ protected createActions(nameable: GModelElement): Action[] {
86
+ return [SelectAction.create({ selectedElementsIDs: [nameable.id] }), CenterAction.create([nameable.id], { retainZoom: true })];
87
+ }
88
+ }
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2020-2024 EclipseSource and others.
2
+ * Copyright (c) 2020-2025 EclipseSource and others.
3
3
  *
4
4
  * This program and the accompanying materials are made available under the
5
5
  * terms of the Eclipse Public License v. 2.0 which is available at
@@ -16,6 +16,7 @@
16
16
  import {
17
17
  Action,
18
18
  CenterAction,
19
+ ClientMenuItem,
19
20
  GIssueSeverity,
20
21
  GModelElement,
21
22
  GModelRoot,
@@ -23,7 +24,6 @@ import {
23
24
  IActionHandler,
24
25
  IContextMenuItemProvider,
25
26
  KeyListener,
26
- MenuItem,
27
27
  Point,
28
28
  SelectAction,
29
29
  TYPES,
@@ -35,6 +35,7 @@ import {
35
35
  matchesKeystroke
36
36
  } from '@eclipse-glsp/sprotty';
37
37
  import { inject, injectable } from 'inversify';
38
+ import { messages } from '../../base/messages';
38
39
  import { SelectionService } from '../../base/selection-service';
39
40
  import { BoundsAwareModelElement, SelectableElement, getElements, isSelectableAndBoundsAware } from '../../utils/gmodel-util';
40
41
  import { MarkerPredicates, collectIssueMarkers } from '../../utils/marker';
@@ -206,33 +207,33 @@ export class NavigateToMarkerActionHandler implements IActionHandler {
206
207
  export class MarkerNavigatorContextMenuItemProvider implements IContextMenuItemProvider {
207
208
  @inject(SelectionService) protected selectionService: SelectionService;
208
209
 
209
- getItems(root: Readonly<GModelRoot>, lastMousePosition?: Point): Promise<MenuItem[]> {
210
+ async getItems(root: Readonly<GModelRoot>, lastMousePosition?: Point): Promise<ClientMenuItem[]> {
210
211
  const selectedElementIds = Array.from(this.selectionService.getSelectedElementIDs());
211
212
  const hasMarkers = collectIssueMarkers(root).length > 0;
212
- return Promise.resolve([
213
+ return [
213
214
  {
214
215
  id: 'navigate',
215
- label: 'Go to',
216
+ label: messages.context_menu.marker.navigation,
216
217
  group: 'navigate',
217
218
  actions: [],
218
219
  children: [
219
220
  {
220
221
  id: 'next-marker',
221
- label: 'Next marker',
222
+ label: messages.context_menu.marker.next,
222
223
  group: 'marker',
223
224
  actions: [NavigateToMarkerAction.create({ direction: 'next', selectedElementIds })],
224
225
  isEnabled: () => hasMarkers
225
226
  },
226
227
  {
227
228
  id: 'previous-marker',
228
- label: 'Previous marker',
229
+ label: messages.context_menu.marker.previous,
229
230
  group: 'marker',
230
231
  actions: [NavigateToMarkerAction.create({ direction: 'previous', selectedElementIds })],
231
232
  isEnabled: () => hasMarkers
232
233
  }
233
234
  ]
234
235
  }
235
- ]);
236
+ ];
236
237
  }
237
238
  }
238
239
 
@@ -70,13 +70,7 @@ export class RepositionCommand extends BoundsAwareViewportCommand {
70
70
  if (element instanceof GChildElement && element.parent !== viewport) {
71
71
  return this.boundsInViewport(element.parent, element.parent.localToParent(bounds) as Bounds, viewport);
72
72
  } else if (element instanceof GEdge) {
73
- const edgeBounds = getRouteBounds(calcElementAndRoute(element).newRoutingPoints ?? []);
74
-
75
- if (element instanceof GChildElement && element.parent !== viewport) {
76
- return this.boundsInViewport(element.parent, element.parent.localToParent(edgeBounds), viewport);
77
- }
78
-
79
- return edgeBounds;
73
+ return getRouteBounds(calcElementAndRoute(element).newRoutingPoints ?? []);
80
74
  }
81
75
 
82
76
  return bounds;
package/src/index.ts CHANGED
@@ -18,7 +18,7 @@ export * from './base/action-handler-registry';
18
18
  export * from './base/args-feature';
19
19
  export * from './base/auto-complete/auto-complete-actions';
20
20
  export * from './base/auto-complete/auto-complete-widget';
21
- export * from './base/auto-complete/autocomplete-suggestion-providers';
21
+ export * from './base/auto-complete/autocomplete-suggestion-provider';
22
22
  export * from './base/auto-complete/base-autocomplete-palette';
23
23
  export * from './base/auto-complete/validation-decorator';
24
24
  export * from './base/command-stack';
@@ -58,7 +58,6 @@ export * from './default-modules';
58
58
  export * from './features/accessibility/accessibility-module';
59
59
  export * from './features/accessibility/actions';
60
60
  export * from './features/accessibility/edge-autocomplete/action';
61
- export * from './features/accessibility/edge-autocomplete/edge-autocomplete-context';
62
61
  export * from './features/accessibility/edge-autocomplete/edge-autocomplete-palette';
63
62
  export * from './features/accessibility/edge-autocomplete/edge-autocomplete-tool';
64
63
  export * from './features/accessibility/element-navigation/diagram-navigation-tool';
@@ -79,13 +78,10 @@ export * from './features/accessibility/keyboard-pointer/actions';
79
78
  export * from './features/accessibility/keyboard-pointer/constants';
80
79
  export * from './features/accessibility/keyboard-pointer/keyboard-pointer';
81
80
  export * from './features/accessibility/keyboard-pointer/keyboard-pointer-listener';
82
- export * from './features/accessibility/keyboard-pointer/keyboard-pointer-module';
83
81
  export * from './features/accessibility/keyboard-pointer/keyboard-pointer-position';
84
82
  export * from './features/accessibility/keyboard-tool-palette/keyboard-tool-palette';
85
83
  export * from './features/accessibility/keyboard-tool-palette/keyboard-tool-palette-module';
86
- export * from './features/accessibility/search/search-palette';
87
- export * from './features/accessibility/search/search-palette-module';
88
- export * from './features/accessibility/search/search-tool';
84
+ export * from './features/accessibility/keyboard/keyboard-module';
89
85
  export * from './features/accessibility/toast/toast-handler';
90
86
  export * from './features/accessibility/toast/toast-module';
91
87
  export * from './features/accessibility/toast/toast-tool';
@@ -171,6 +167,11 @@ export * from './features/routing/edge-router';
171
167
  export * from './features/routing/routing-module';
172
168
  export * from './features/save/save-keylistener';
173
169
  export * from './features/save/save-module';
170
+ export * from './features/search-palette/search-palette';
171
+ export * from './features/search-palette/search-palette-key-listener';
172
+ export * from './features/search-palette/search-palette-module';
173
+ export * from './features/search-palette/suggestions/edge-element-suggestions';
174
+ export * from './features/search-palette/suggestions/named-element-suggestions';
174
175
  export * from './features/select/select-feedback-command';
175
176
  export * from './features/select/select-module';
176
177
  export * from './features/select/select-mouse-listener';
@@ -39,6 +39,7 @@ import { standaloneResizeModule } from './features/change-bounds/resize/resize-m
39
39
  import { standaloneCopyPasteModule } from './features/copy-paste/copy-paste-modules';
40
40
  import { standaloneExportModule } from './features/export/export-modules';
41
41
  import { saveModule } from './features/save/save-module';
42
+ import { standaloneSearchPaletteModule } from './features/search-palette/search-palette-module';
42
43
  import { standaloneSelectModule } from './features/select/select-module';
43
44
  import { undoRedoModule } from './features/undo-redo/undo-redo-module';
44
45
  import { standaloneMarkerNavigatorModule } from './features/validation/validation-modules';
@@ -101,6 +102,7 @@ export const STANDALONE_MODULES = [
101
102
  standaloneDefaultModule,
102
103
  standaloneShortcutsModule,
103
104
  standaloneResizeModule,
105
+ standaloneSearchPaletteModule,
104
106
  saveModule,
105
107
  undoRedoModule
106
108
  ] as const;
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2019-2024 EclipseSource and others.
2
+ * Copyright (c) 2019-2025 EclipseSource and others.
3
3
  *
4
4
  * This program and the accompanying materials are made available under the
5
5
  * terms of the Eclipse Public License v. 2.0 which is available at
@@ -86,6 +86,63 @@ export function getMatchingElements<T>(index: ModelIndexImpl, predicate: ModelFi
86
86
  return Array.from(filter(index, predicate));
87
87
  }
88
88
 
89
+ /**
90
+ * Retrieves an array of all parent elements for the given element that match the given type guard.
91
+ * @param element The {@link GModelElement} for which the parent elements should be retrieved.
92
+ * @param guard The type guard that should be used.
93
+ * @returns An array of all parent elements that match the type guard
94
+ * (correctly casted to also include the additional type of the guard).
95
+ */
96
+ export function getParents<T extends GParentElement>(element: GModelElement, guard: TypeGuard<T>): T[];
97
+ /**
98
+ * Retrieves an array of all parent elements for the given element that match the given {@link ModelFilterPredicate}.
99
+ * @param element The {@link GModelElement} for which the parent elements should be retrieved.
100
+ * @param predicate The filter predicate that should be used.
101
+ * @returns An array of all parent elements that match the filter predicate
102
+ * (correctly casted to also include the additional type of the predicate).
103
+ */
104
+ export function getParents<T>(element: GModelElement, predicate: ModelFilterPredicate<T>): (GParentElement & T)[];
105
+ export function getParents(element: GModelElement, filterPredicate: (parent: GParentElement) => boolean): GParentElement[] {
106
+ const parents: GParentElement[] = [];
107
+ let current: GModelElement | undefined = element;
108
+ while (current instanceof GChildElement) {
109
+ const parent: GParentElement = current.parent;
110
+ if (filterPredicate(parent)) {
111
+ parents.push(parent);
112
+ }
113
+ current = parent;
114
+ }
115
+ return parents;
116
+ }
117
+
118
+ /** * Retrieves an array of all child elements for the given element that match the given type guard.
119
+ * @param element The {@link GModelElement} for which the child elements should be retrieved.
120
+ * @param guard The type guard that should be used.
121
+ * @returns An array of all child elements that match the type guard
122
+ * (correctly casted to also include the additional type of the guard).
123
+ */
124
+ export function getChildren<T extends GChildElement>(element: GModelElement, guard: TypeGuard<T>): T[];
125
+ /** * Retrieves an array of all child elements for the given element that match the given {@link ModelFilterPredicate}.
126
+ * @param element The {@link GModelElement} for which the child elements should be retrieved.
127
+ * @param predicate The filter predicate that should be used.
128
+ * @returns An array of all child elements that match the filter predicate
129
+ * (correctly casted to also include the additional type of the predicate).
130
+ */
131
+ export function getChildren<T>(element: GModelElement, predicate: ModelFilterPredicate<T>): (GChildElement & T)[];
132
+ export function getChildren(element: GModelElement, filterPredicate: (parent: GChildElement) => boolean): GChildElement[] {
133
+ const children: GChildElement[] = [];
134
+ if (element instanceof GParentElement) {
135
+ for (const child of element.children) {
136
+ if (filterPredicate(child)) {
137
+ children.push(child);
138
+ }
139
+ if (child instanceof GParentElement) {
140
+ children.push(...getChildren(child, filterPredicate as any));
141
+ }
142
+ }
143
+ }
144
+ return children;
145
+ }
89
146
  /**
90
147
  * Invokes the given model index to retrieve the corresponding model elements for the given set of ids. Ids that
91
148
  * have no corresponding element in the index will be ignored.
@@ -104,6 +161,7 @@ export function getElements<S extends GModelElement>(index: ModelIndexImpl, elem
104
161
  };
105
162
  return elementsIDs.map(id => index.getById(id)).filter(filterFn);
106
163
  }
164
+
107
165
  /**
108
166
  * Retrieves the amount of currently selected elements in the given {@link ModelIndexImpl}.
109
167
  * @param index The {@link ModelIndexImpl}.