@eclipse-glsp/client 2.5.0-next.426 → 2.5.0-next.428

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 (202) hide show
  1. package/lib/base/auto-complete/auto-complete-widget.d.ts +1 -1
  2. package/lib/base/auto-complete/auto-complete-widget.js +1 -1
  3. package/lib/base/auto-complete/base-autocomplete-palette.d.ts +1 -1
  4. package/lib/base/auto-complete/base-autocomplete-palette.js +1 -1
  5. package/lib/base/command-stack.d.ts +6 -4
  6. package/lib/base/command-stack.d.ts.map +1 -1
  7. package/lib/base/command-stack.js +16 -7
  8. package/lib/base/command-stack.js.map +1 -1
  9. package/lib/base/default.module.d.ts +1 -1
  10. package/lib/base/default.module.d.ts.map +1 -1
  11. package/lib/base/default.module.js +3 -1
  12. package/lib/base/default.module.js.map +1 -1
  13. package/lib/base/editor-context-service.d.ts +10 -13
  14. package/lib/base/editor-context-service.d.ts.map +1 -1
  15. package/lib/base/editor-context-service.js +23 -27
  16. package/lib/base/editor-context-service.js.map +1 -1
  17. package/lib/base/focus/focus-tracker.d.ts +3 -2
  18. package/lib/base/focus/focus-tracker.d.ts.map +1 -1
  19. package/lib/base/focus/focus-tracker.js +9 -0
  20. package/lib/base/focus/focus-tracker.js.map +1 -1
  21. package/lib/base/model/model-change-service.d.ts +65 -0
  22. package/lib/base/model/model-change-service.d.ts.map +1 -0
  23. package/lib/base/model/model-change-service.js +113 -0
  24. package/lib/base/model/model-change-service.js.map +1 -0
  25. package/lib/base/shortcuts/available-shortcuts-extension.d.ts +1 -1
  26. package/lib/base/shortcuts/available-shortcuts-extension.js +1 -1
  27. package/lib/base/shortcuts/available-shortcuts-tool.d.ts +1 -1
  28. package/lib/base/shortcuts/available-shortcuts-tool.js +1 -1
  29. package/lib/base/shortcuts/shortcuts-module.d.ts +1 -1
  30. package/lib/base/shortcuts/shortcuts-module.js +1 -1
  31. package/lib/base/ui-extension/ui-extension.d.ts +1 -1
  32. package/lib/base/ui-extension/ui-extension.js +1 -1
  33. package/lib/default-modules.d.ts +1 -1
  34. package/lib/default-modules.js +1 -1
  35. package/lib/features/accessibility/accessibility-module.d.ts +1 -1
  36. package/lib/features/accessibility/accessibility-module.js +1 -1
  37. package/lib/features/accessibility/edge-autocomplete/edge-autocomplete-palette.d.ts +1 -1
  38. package/lib/features/accessibility/edge-autocomplete/edge-autocomplete-palette.js +1 -1
  39. package/lib/features/accessibility/edge-autocomplete/edge-autocomplete-tool.d.ts +1 -1
  40. package/lib/features/accessibility/edge-autocomplete/edge-autocomplete-tool.js +1 -1
  41. package/lib/features/accessibility/element-navigation/diagram-navigation-tool.d.ts +1 -1
  42. package/lib/features/accessibility/element-navigation/diagram-navigation-tool.js +1 -1
  43. package/lib/features/accessibility/element-navigation/left-right-top-bottom-navigator.d.ts +1 -1
  44. package/lib/features/accessibility/element-navigation/left-right-top-bottom-navigator.js +1 -1
  45. package/lib/features/accessibility/element-navigation/position-navigator.d.ts +1 -1
  46. package/lib/features/accessibility/element-navigation/position-navigator.js +1 -1
  47. package/lib/features/accessibility/focus-tracker/focus-tracker-tool.d.ts +1 -1
  48. package/lib/features/accessibility/focus-tracker/focus-tracker-tool.js +1 -1
  49. package/lib/features/accessibility/global-keylistener-tool.d.ts +1 -1
  50. package/lib/features/accessibility/global-keylistener-tool.js +1 -1
  51. package/lib/features/accessibility/keyboard-grid/keyboard-grid.d.ts +1 -1
  52. package/lib/features/accessibility/keyboard-grid/keyboard-grid.js +1 -1
  53. package/lib/features/accessibility/keyboard-grid/keyboard-node-grid.d.ts +1 -1
  54. package/lib/features/accessibility/keyboard-grid/keyboard-node-grid.js +1 -1
  55. package/lib/features/accessibility/keyboard-tool-palette/keyboard-tool-palette.d.ts +1 -1
  56. package/lib/features/accessibility/keyboard-tool-palette/keyboard-tool-palette.js +1 -1
  57. package/lib/features/accessibility/search/search-palette-module.d.ts +1 -1
  58. package/lib/features/accessibility/search/search-palette-module.js +1 -1
  59. package/lib/features/accessibility/search/search-palette.d.ts +1 -1
  60. package/lib/features/accessibility/search/search-palette.js +1 -1
  61. package/lib/features/accessibility/search/search-tool.d.ts +1 -1
  62. package/lib/features/accessibility/search/search-tool.js +1 -1
  63. package/lib/features/accessibility/view-key-tools/grid-cell-zoom-key-tool.d.ts +1 -1
  64. package/lib/features/accessibility/view-key-tools/grid-cell-zoom-key-tool.js +1 -1
  65. package/lib/features/accessibility/view-key-tools/view-key-tools-module.d.ts +1 -1
  66. package/lib/features/accessibility/view-key-tools/view-key-tools-module.js +1 -1
  67. package/lib/features/bounds/bounds-module.d.ts +1 -1
  68. package/lib/features/bounds/bounds-module.js +1 -1
  69. package/lib/features/bounds/hbox-layout.d.ts +1 -1
  70. package/lib/features/bounds/hbox-layout.js +1 -1
  71. package/lib/features/bounds/vbox-layout.d.ts +1 -1
  72. package/lib/features/bounds/vbox-layout.js +1 -1
  73. package/lib/features/change-bounds/move-element-action.d.ts +1 -1
  74. package/lib/features/change-bounds/move-element-action.js +1 -1
  75. package/lib/features/change-bounds/move-element-handler.d.ts +1 -1
  76. package/lib/features/change-bounds/move-element-handler.js +1 -1
  77. package/lib/features/change-bounds/resize/resize-default-tool.d.ts +1 -1
  78. package/lib/features/change-bounds/resize/resize-default-tool.js +1 -1
  79. package/lib/features/change-bounds/resize/resize-handler.d.ts +1 -1
  80. package/lib/features/change-bounds/resize/resize-handler.js +1 -1
  81. package/lib/features/change-bounds/resize/resize-module.d.ts +1 -1
  82. package/lib/features/change-bounds/resize/resize-module.js +1 -1
  83. package/lib/features/command-palette/server-command-palette-provider.d.ts +1 -1
  84. package/lib/features/command-palette/server-command-palette-provider.js +1 -1
  85. package/lib/features/context-menu/server-context-menu-provider.d.ts +1 -1
  86. package/lib/features/context-menu/server-context-menu-provider.js +1 -1
  87. package/lib/features/copy-paste/copy-paste-handler.d.ts +1 -1
  88. package/lib/features/copy-paste/copy-paste-handler.js +1 -1
  89. package/lib/features/grid/grid-module.d.ts +1 -1
  90. package/lib/features/grid/grid-module.js +1 -1
  91. package/lib/features/grid/grid-snapper.d.ts +1 -1
  92. package/lib/features/grid/grid-snapper.js +1 -1
  93. package/lib/features/grid/grid.d.ts +1 -1
  94. package/lib/features/helper-lines/helper-line-feedback.d.ts +1 -1
  95. package/lib/features/helper-lines/helper-line-feedback.js +1 -1
  96. package/lib/features/hover/hover.d.ts +1 -1
  97. package/lib/features/hover/hover.js +1 -1
  98. package/lib/features/label-edit/edit-label-validator.d.ts +1 -1
  99. package/lib/features/label-edit/edit-label-validator.js +1 -1
  100. package/lib/features/layout/layout-module.d.ts +1 -1
  101. package/lib/features/layout/layout-module.js +1 -1
  102. package/lib/features/navigation/navigation-target-resolver.d.ts +1 -1
  103. package/lib/features/navigation/navigation-target-resolver.js +1 -1
  104. package/lib/features/tool-palette/tool-palette.d.ts +1 -1
  105. package/lib/features/tool-palette/tool-palette.js +1 -1
  106. package/lib/features/tools/base-tools.d.ts +1 -1
  107. package/lib/features/tools/base-tools.js +1 -1
  108. package/lib/features/tools/change-bounds/change-bounds-tool.js +1 -1
  109. package/lib/features/tools/node-creation/container-manager.d.ts +1 -1
  110. package/lib/features/tools/node-creation/container-manager.js +1 -1
  111. package/lib/features/viewport/origin-viewport.d.ts +1 -1
  112. package/lib/features/viewport/origin-viewport.js +1 -1
  113. package/lib/features/viewport/reposition.d.ts +1 -1
  114. package/lib/features/viewport/reposition.js +1 -1
  115. package/lib/features/viewport/viewport-handler.d.ts +1 -1
  116. package/lib/features/viewport/viewport-handler.js +1 -1
  117. package/lib/features/viewport/viewport-key-listener.d.ts +1 -1
  118. package/lib/features/viewport/viewport-key-listener.js +1 -1
  119. package/lib/features/viewport/viewport-modules.d.ts +1 -1
  120. package/lib/features/viewport/viewport-modules.js +1 -1
  121. package/lib/features/viewport/zoom-viewport-action.d.ts +1 -1
  122. package/lib/features/viewport/zoom-viewport-action.js +1 -1
  123. package/lib/index.d.ts +1 -1
  124. package/lib/index.js +1 -1
  125. package/lib/standalone-modules.d.ts +1 -1
  126. package/lib/standalone-modules.js +1 -1
  127. package/lib/utils/viewpoint-util.d.ts +1 -1
  128. package/lib/utils/viewpoint-util.js +1 -1
  129. package/lib/views/base-view-module.d.ts +1 -1
  130. package/lib/views/base-view-module.js +1 -1
  131. package/lib/views/compartments.d.ts +1 -1
  132. package/lib/views/compartments.js +1 -1
  133. package/lib/views/glsp-projection-view.d.ts +1 -1
  134. package/lib/views/glsp-projection-view.js +1 -1
  135. package/lib/views/rounded-corner-view.d.ts +1 -1
  136. package/lib/views/rounded-corner-view.js +1 -1
  137. package/package.json +3 -3
  138. package/src/base/auto-complete/auto-complete-widget.ts +1 -1
  139. package/src/base/auto-complete/base-autocomplete-palette.ts +1 -1
  140. package/src/base/command-stack.ts +19 -13
  141. package/src/base/default.module.ts +3 -1
  142. package/src/base/editor-context-service.ts +23 -30
  143. package/src/base/focus/focus-tracker.ts +8 -3
  144. package/src/base/model/model-change-service.ts +151 -0
  145. package/src/base/shortcuts/available-shortcuts-extension.ts +1 -1
  146. package/src/base/shortcuts/available-shortcuts-tool.ts +1 -1
  147. package/src/base/shortcuts/shortcuts-module.ts +1 -1
  148. package/src/base/ui-extension/ui-extension.ts +1 -1
  149. package/src/default-modules.ts +1 -1
  150. package/src/features/accessibility/accessibility-module.ts +1 -1
  151. package/src/features/accessibility/edge-autocomplete/edge-autocomplete-palette.ts +1 -1
  152. package/src/features/accessibility/edge-autocomplete/edge-autocomplete-tool.ts +1 -1
  153. package/src/features/accessibility/element-navigation/diagram-navigation-tool.ts +1 -1
  154. package/src/features/accessibility/element-navigation/left-right-top-bottom-navigator.ts +1 -1
  155. package/src/features/accessibility/element-navigation/position-navigator.ts +1 -1
  156. package/src/features/accessibility/focus-tracker/focus-tracker-tool.ts +1 -1
  157. package/src/features/accessibility/global-keylistener-tool.ts +1 -1
  158. package/src/features/accessibility/keyboard-grid/keyboard-grid.ts +1 -1
  159. package/src/features/accessibility/keyboard-grid/keyboard-node-grid.ts +1 -1
  160. package/src/features/accessibility/keyboard-tool-palette/keyboard-tool-palette.ts +1 -1
  161. package/src/features/accessibility/search/search-palette-module.ts +1 -1
  162. package/src/features/accessibility/search/search-palette.ts +1 -1
  163. package/src/features/accessibility/search/search-tool.ts +1 -1
  164. package/src/features/accessibility/view-key-tools/grid-cell-zoom-key-tool.ts +1 -1
  165. package/src/features/accessibility/view-key-tools/view-key-tools-module.ts +1 -1
  166. package/src/features/bounds/bounds-module.ts +1 -1
  167. package/src/features/bounds/hbox-layout.ts +1 -1
  168. package/src/features/bounds/vbox-layout.ts +1 -1
  169. package/src/features/change-bounds/move-element-action.ts +1 -1
  170. package/src/features/change-bounds/move-element-handler.ts +1 -1
  171. package/src/features/change-bounds/resize/resize-default-tool.ts +1 -1
  172. package/src/features/change-bounds/resize/resize-handler.ts +1 -1
  173. package/src/features/change-bounds/resize/resize-module.ts +1 -1
  174. package/src/features/command-palette/server-command-palette-provider.ts +1 -1
  175. package/src/features/context-menu/server-context-menu-provider.ts +1 -1
  176. package/src/features/copy-paste/copy-paste-handler.ts +1 -1
  177. package/src/features/grid/grid-module.ts +1 -1
  178. package/src/features/grid/grid-snapper.ts +1 -1
  179. package/src/features/grid/grid.ts +1 -1
  180. package/src/features/helper-lines/helper-line-feedback.ts +1 -1
  181. package/src/features/hover/hover.ts +1 -1
  182. package/src/features/label-edit/edit-label-validator.ts +1 -1
  183. package/src/features/layout/layout-elements-action.spec.ts +1 -1
  184. package/src/features/layout/layout-module.ts +1 -1
  185. package/src/features/navigation/navigation-target-resolver.ts +1 -1
  186. package/src/features/tool-palette/tool-palette.ts +1 -1
  187. package/src/features/tools/base-tools.ts +1 -1
  188. package/src/features/tools/change-bounds/change-bounds-tool.ts +1 -1
  189. package/src/features/tools/node-creation/container-manager.ts +1 -1
  190. package/src/features/viewport/origin-viewport.ts +1 -1
  191. package/src/features/viewport/reposition.ts +1 -1
  192. package/src/features/viewport/viewport-handler.ts +1 -1
  193. package/src/features/viewport/viewport-key-listener.ts +1 -1
  194. package/src/features/viewport/viewport-modules.ts +1 -1
  195. package/src/features/viewport/zoom-viewport-action.ts +1 -1
  196. package/src/index.ts +1 -1
  197. package/src/standalone-modules.ts +1 -1
  198. package/src/utils/viewpoint-util.ts +1 -1
  199. package/src/views/base-view-module.ts +1 -1
  200. package/src/views/compartments.tsx +1 -1
  201. package/src/views/glsp-projection-view.tsx +1 -1
  202. package/src/views/rounded-corner-view.tsx +1 -1
@@ -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
@@ -15,25 +15,37 @@
15
15
  ********************************************************************************/
16
16
  import {
17
17
  CommandExecutionContext,
18
+ CommandExecutionData,
18
19
  CommandStack,
19
20
  Disposable,
20
21
  DisposableCollection,
22
+ Emitter,
21
23
  Event,
22
24
  GModelRoot,
23
25
  ICommand,
24
- LazyInjector,
25
- SetModelCommand,
26
- UpdateModelCommand
26
+ ICommandStack,
27
+ LazyInjector
27
28
  } from '@eclipse-glsp/sprotty';
28
- import { inject, injectable, preDestroy } from 'inversify';
29
+ import { inject, injectable, postConstruct, preDestroy } from 'inversify';
29
30
  import { EditorContextService } from './editor-context-service';
30
31
 
31
32
  @injectable()
32
- export class GLSPCommandStack extends CommandStack implements Disposable {
33
+ export class GLSPCommandStack extends CommandStack implements ICommandStack, Disposable {
33
34
  @inject(LazyInjector)
34
35
  protected lazyInjector: LazyInjector;
35
36
  protected toDispose = new DisposableCollection();
36
37
 
38
+ protected onCommandExecutedEmitter = new Emitter<CommandExecutionData>();
39
+ get onCommandExecuted(): Event<CommandExecutionData> {
40
+ return this.onCommandExecutedEmitter.event;
41
+ }
42
+
43
+ @postConstruct()
44
+ protected override initialize(): void {
45
+ super.initialize();
46
+ this.toDispose.push(this.onCommandExecutedEmitter);
47
+ }
48
+
37
49
  @preDestroy()
38
50
  dispose(): void {
39
51
  this.toDispose.dispose();
@@ -95,13 +107,7 @@ export class GLSPCommandStack extends CommandStack implements Disposable {
95
107
  }
96
108
  override async execute(command: ICommand): Promise<GModelRoot> {
97
109
  const result = await super.execute(command);
98
- if (command instanceof SetModelCommand || command instanceof UpdateModelCommand) {
99
- this.notifyListeners(result);
100
- }
110
+ this.onCommandExecutedEmitter.fire({ command, newRoot: result });
101
111
  return result;
102
112
  }
103
-
104
- protected notifyListeners(root: Readonly<GModelRoot>): void {
105
- this.editorContext.notifyModelRootChanged(root, this);
106
- }
107
113
  }
@@ -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
@@ -46,6 +46,7 @@ import { FocusStateChangedAction } from './focus/focus-state-change-action';
46
46
  import { FocusTracker } from './focus/focus-tracker';
47
47
  import { DiagramLoader } from './model/diagram-loader';
48
48
  import { GLSPModelSource } from './model/glsp-model-source';
49
+ import { ModelChangeService } from './model/model-change-service';
49
50
  import { DefaultModelInitializationConstraint, ModelInitializationConstraint } from './model/model-initialization-constraint';
50
51
  import { GModelRegistry } from './model/model-registry';
51
52
  import { GLSPMousePositionTracker } from './mouse-position-tracker';
@@ -77,6 +78,7 @@ export const defaultModule = new FeatureModule(
77
78
  bind(TYPES.IEditorContextServiceProvider).toProvider<EditorContextService>(
78
79
  ctx => async () => ctx.container.get(EditorContextService)
79
80
  );
81
+ bind(TYPES.IModelChangeService).to(ModelChangeService).inSingletonScope();
80
82
 
81
83
  configureActionHandler(context, SetEditModeAction.KIND, EditorContextService);
82
84
  configureActionHandler(context, SetDirtyStateAction.KIND, EditorContextService);
@@ -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
@@ -15,10 +15,8 @@
15
15
  ********************************************************************************/
16
16
  import {
17
17
  Action,
18
- AnyObject,
19
18
  Args,
20
19
  Bounds,
21
- CommandStack,
22
20
  Disposable,
23
21
  DisposableCollection,
24
22
  EditMode,
@@ -44,6 +42,7 @@ import {
44
42
  import { inject, injectable, postConstruct, preDestroy } from 'inversify';
45
43
  import { FocusChange, FocusTracker } from './focus/focus-tracker';
46
44
  import { IDiagramOptions, IDiagramStartup } from './model/diagram-loader';
45
+ import { IModelChangeService, ViewportChange } from './model/model-change-service';
47
46
  import { SelectionChange, SelectionService } from './selection-service';
48
47
 
49
48
  /**
@@ -85,6 +84,9 @@ export class EditorContextService implements IActionHandler, Disposable, IDiagra
85
84
  @inject(SelectionService)
86
85
  protected selectionService: SelectionService;
87
86
 
87
+ @inject(TYPES.IModelChangeService)
88
+ protected modelChangeService: IModelChangeService;
89
+
88
90
  @inject(MousePositionTracker)
89
91
  protected mousePositionTracker: MousePositionTracker;
90
92
 
@@ -118,13 +120,11 @@ export class EditorContextService implements IActionHandler, Disposable, IDiagra
118
120
  return this.onDirtyStateChangedEmitter.event;
119
121
  }
120
122
 
121
- protected _modelRoot?: Readonly<GModelRoot>;
122
123
  /**
123
124
  * Event that is fired when the model root of the diagram changes i.e. after the `CommandStack` has processed a model update.
124
125
  */
125
- protected onModelRootChangedEmitter = new Emitter<Readonly<GModelRoot>>();
126
126
  get onModelRootChanged(): Event<Readonly<GModelRoot>> {
127
- return this.onModelRootChangedEmitter.event;
127
+ return this.modelChangeService.onModelRootChanged;
128
128
  }
129
129
 
130
130
  /**
@@ -143,6 +143,14 @@ export class EditorContextService implements IActionHandler, Disposable, IDiagra
143
143
  return this.selectionService.onSelectionChanged;
144
144
  }
145
145
 
146
+ /**
147
+ * Event that is fired when the viewport of the diagram changes i.e. after the `CommandStack` has processed a viewport update.
148
+ * By default, this event is only fired if the viewport was changed via a `SetViewportCommand` or `BoundsAwareViewportCommand`
149
+ */
150
+ get onViewportChanged(): Event<ViewportChange> {
151
+ return this.modelChangeService.onViewportChanged;
152
+ }
153
+
146
154
  protected toDispose = new DisposableCollection();
147
155
 
148
156
  @postConstruct()
@@ -151,6 +159,11 @@ export class EditorContextService implements IActionHandler, Disposable, IDiagra
151
159
  this.toDispose.push(this.onEditModeChangedEmitter, this.onDirtyStateChangedEmitter);
152
160
  }
153
161
 
162
+ @preDestroy()
163
+ dispose(): void {
164
+ this.toDispose.dispose();
165
+ }
166
+
154
167
  preLoadDiagram(): MaybePromise<void> {
155
168
  this.lazyInjector.getAll<IGModelRootListener>(TYPES.IGModelRootListener).forEach(listener => {
156
169
  this.onModelRootChanged(event => listener.modelRootChanged(event));
@@ -160,11 +173,6 @@ export class EditorContextService implements IActionHandler, Disposable, IDiagra
160
173
  });
161
174
  }
162
175
 
163
- @preDestroy()
164
- dispose(): void {
165
- this.toDispose.dispose();
166
- }
167
-
168
176
  get(args?: Args): EditorContext {
169
177
  return {
170
178
  selectedElementIds: Array.from(this.selectionService.getSelectedElementIDs()),
@@ -181,21 +189,6 @@ export class EditorContextService implements IActionHandler, Disposable, IDiagra
181
189
  };
182
190
  }
183
191
 
184
- /**
185
- * Notifies the service about a model root change. This method should not be called
186
- * directly. It is called by the `CommandStack` after a model update has been processed.
187
- * @throws an error if the notifier is not a `CommandStack`
188
- * @param root the new model root
189
- * @param notifier the object that triggered the model root change
190
- */
191
- notifyModelRootChanged(root: Readonly<GModelRoot>, notifier: AnyObject): void {
192
- if (!(notifier instanceof CommandStack)) {
193
- throw new Error('Invalid model root change notification. Notifier is not an instance of `CommandStack`.');
194
- }
195
- this._modelRoot = root;
196
- this.onModelRootChangedEmitter.fire(root);
197
- }
198
-
199
192
  handle(action: Action): void {
200
193
  if (SetEditModeAction.is(action)) {
201
194
  this.handleSetEditModeAction(action);
@@ -234,14 +227,14 @@ export class EditorContextService implements IActionHandler, Disposable, IDiagra
234
227
  }
235
228
 
236
229
  get modelRoot(): Readonly<GModelRoot> {
237
- if (!this._modelRoot) {
230
+ if (!this.modelChangeService.currentRoot) {
238
231
  throw new Error('Model root not available yet');
239
232
  }
240
- return this._modelRoot;
233
+ return this.modelChangeService.currentRoot;
241
234
  }
242
235
 
243
236
  get viewport(): Readonly<GModelRoot & Viewport> | undefined {
244
- return this._modelRoot ? findParentByFeature(this._modelRoot, isViewport) : undefined;
237
+ return this.modelRoot ? findParentByFeature(this.modelRoot, isViewport) : undefined;
245
238
  }
246
239
 
247
240
  get viewportData(): Readonly<Viewport> {
@@ -255,7 +248,7 @@ export class EditorContextService implements IActionHandler, Disposable, IDiagra
255
248
 
256
249
  get canvasBounds(): Readonly<Bounds> {
257
250
  // default value aligned with the initialization of canvasBounds in GModelRoot
258
- return this._modelRoot?.canvasBounds ?? Bounds.EMPTY;
251
+ return this.modelRoot?.canvasBounds ?? Bounds.EMPTY;
259
252
  }
260
253
 
261
254
  get selectedElements(): Readonly<GModelElement>[] {
@@ -13,8 +13,8 @@
13
13
  *
14
14
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
15
  ********************************************************************************/
16
- import { Action, Emitter, Event, IActionHandler, ICommand, TYPES, ViewerOptions } from '@eclipse-glsp/sprotty';
17
- import { inject, injectable } from 'inversify';
16
+ import { Action, Disposable, Emitter, Event, IActionHandler, ICommand, TYPES, ViewerOptions } from '@eclipse-glsp/sprotty';
17
+ import { inject, injectable, preDestroy } from 'inversify';
18
18
  import { FocusStateChangedAction } from './focus-state-change-action';
19
19
 
20
20
  export interface FocusChange {
@@ -29,7 +29,7 @@ export interface FocusChange {
29
29
  * Allows querying of the current focus state and the focused root diagram element and the currently focused element within the diagram.
30
30
  */
31
31
  @injectable()
32
- export class FocusTracker implements IActionHandler {
32
+ export class FocusTracker implements IActionHandler, Disposable {
33
33
  protected inActiveCssClass = 'inactive';
34
34
  protected _hasFocus = true;
35
35
  protected _focusElement: HTMLOrSVGElement | null;
@@ -77,4 +77,9 @@ export class FocusTracker implements IActionHandler {
77
77
  }
78
78
  this.onFocusChangedEmitter.fire({ hasFocus: this.hasFocus, focusElement: this.focusElement, diagramElement: this.diagramElement });
79
79
  }
80
+
81
+ @preDestroy()
82
+ dispose(): void {
83
+ this.onFocusChangedEmitter.dispose();
84
+ }
80
85
  }
@@ -0,0 +1,151 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2025 EclipseSource 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
+ import {
17
+ BoundsAwareViewportCommand,
18
+ Disposable,
19
+ DisposableCollection,
20
+ Emitter,
21
+ Event,
22
+ GModelRoot,
23
+ ICommand,
24
+ ICommandStack,
25
+ LazyInjector,
26
+ SetModelCommand,
27
+ SetViewportCommand,
28
+ TYPES,
29
+ UpdateModelCommand,
30
+ Viewport,
31
+ almostEquals,
32
+ isViewport
33
+ } from '@eclipse-glsp/sprotty';
34
+ import { inject, postConstruct, preDestroy } from 'inversify';
35
+
36
+ /**
37
+ * Service that tracks changes to the model root and the viewport.
38
+ * Allows to register listeners that are notified when the model root or the viewport changes.
39
+ * The current model root can be queried at any time.
40
+ */
41
+ export interface IModelChangeService {
42
+ /** The current model root */
43
+ readonly currentRoot: Readonly<GModelRoot> | undefined;
44
+ /**
45
+ * Event that is fired when the model root of the diagram changes i.e. after the `CommandStack` has processed a model update.
46
+ */
47
+ onModelRootChanged: Event<Readonly<GModelRoot>>;
48
+
49
+ /**
50
+ * Event that is fired when the viewport of the diagram changes i.e. after the `CommandStack` has processed a viewport update.
51
+ * By default, this event is only fired if the viewport was changed via a `SetViewportCommand` or `BoundsAwareViewportCommand`
52
+ */
53
+ onViewportChanged: Event<ViewportChange>;
54
+ }
55
+
56
+ /**
57
+ * Event data for the {@link IModelChangeService.onViewportChanged} event.
58
+ */
59
+ export interface ViewportChange {
60
+ /** The new viewport */
61
+ newViewport: Readonly<Viewport>;
62
+ /** The old viewport */
63
+ oldViewport?: Readonly<Viewport>;
64
+ }
65
+
66
+ export class ModelChangeService implements IModelChangeService, Disposable {
67
+ @inject(LazyInjector)
68
+ protected lazyInjector: LazyInjector;
69
+ protected _currentRoot?: Readonly<GModelRoot>;
70
+ protected lastViewport?: Readonly<Viewport>;
71
+ protected toDispose = new DisposableCollection();
72
+
73
+ get currentRoot(): Readonly<GModelRoot> | undefined {
74
+ return this._currentRoot;
75
+ }
76
+
77
+ protected get commandStack(): ICommandStack {
78
+ return this.lazyInjector.get<ICommandStack>(TYPES.ICommandStack);
79
+ }
80
+
81
+ protected onModelRootChangedEmitter = new Emitter<Readonly<GModelRoot>>();
82
+ get onModelRootChanged(): Event<Readonly<GModelRoot>> {
83
+ return this.onModelRootChangedEmitter.event;
84
+ }
85
+
86
+ protected onViewportChangedEmitter = new Emitter<ViewportChange>();
87
+ get onViewportChanged(): Event<ViewportChange> {
88
+ return this.onViewportChangedEmitter.event;
89
+ }
90
+
91
+ @postConstruct()
92
+ protected initialize(): void {
93
+ this.toDispose.push(this.onModelRootChangedEmitter, this.onViewportChangedEmitter);
94
+ this.commandStack.onCommandExecuted(data => this.handleCommandExecution(data.command, data.newRoot));
95
+ }
96
+
97
+ @preDestroy()
98
+ dispose(): void {
99
+ this.toDispose.dispose();
100
+ }
101
+
102
+ protected handleCommandExecution(command: ICommand, newRoot: GModelRoot): void {
103
+ if (this.isModelRootChangeCommand(command)) {
104
+ this.handleModelRootChangeCommand(command, newRoot);
105
+ }
106
+ if (this.isViewportChangeCommand(command)) {
107
+ this.handleViewportChangeCommand(command, newRoot);
108
+ }
109
+ }
110
+
111
+ protected isModelRootChangeCommand(command: ICommand): boolean {
112
+ return command instanceof SetModelCommand || command instanceof UpdateModelCommand;
113
+ }
114
+
115
+ protected isViewportChangeCommand(command: ICommand): boolean {
116
+ return command instanceof SetViewportCommand || command instanceof BoundsAwareViewportCommand;
117
+ }
118
+
119
+ protected handleModelRootChangeCommand(command: ICommand, newRoot: GModelRoot): void {
120
+ this._currentRoot = newRoot;
121
+ this.lastViewport = this.toViewport(newRoot);
122
+ this.onModelRootChangedEmitter.fire(newRoot);
123
+ }
124
+
125
+ protected handleViewportChangeCommand(command: ICommand, newRoot: GModelRoot): void {
126
+ const viewport = this.toViewport(newRoot);
127
+ if (!viewport) {
128
+ return;
129
+ }
130
+
131
+ if (this.hasViewportChanged(viewport)) {
132
+ this.onViewportChangedEmitter.fire({ newViewport: viewport, oldViewport: this.lastViewport });
133
+ this.lastViewport = viewport;
134
+ }
135
+ }
136
+
137
+ protected hasViewportChanged(newViewport: Readonly<Viewport>): boolean {
138
+ if (!this.lastViewport) {
139
+ return true;
140
+ }
141
+ return !(
142
+ almostEquals(newViewport.zoom, this.lastViewport.zoom) &&
143
+ almostEquals(newViewport.scroll.x, this.lastViewport.scroll.x) &&
144
+ almostEquals(newViewport.scroll.y, this.lastViewport.scroll.y)
145
+ );
146
+ }
147
+
148
+ protected toViewport(root: Readonly<GModelRoot>): Readonly<Viewport> | undefined {
149
+ return isViewport(root) ? { scroll: root.scroll, zoom: root.zoom } : undefined;
150
+ }
151
+ }
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2023-2024 Business Informatics Group (TU Wien) and others.
2
+ * Copyright (c) 2023-2025 Business Informatics Group (TU Wien) 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
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2023 Business Informatics Group (TU Wien) and others.
2
+ * Copyright (c) 2023-2025 Business Informatics Group (TU Wien) 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
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2023-2024 Business Informatics Group (TU Wien) and others.
2
+ * Copyright (c) 2023-2025 Business Informatics Group (TU Wien) 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
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2024 EclipseSource and others.
2
+ * Copyright (c) 2024-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
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2021-2024 EclipseSource and others.
2
+ * Copyright (c) 2021-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
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2023-2024 Business Informatics Group (TU Wien) and others.
2
+ * Copyright (c) 2023-2025 Business Informatics Group (TU Wien) 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
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2023 Business Informatics Group (TU Wien) and others.
2
+ * Copyright (c) 2023-2024 Business Informatics Group (TU Wien) 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
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2023 Business Informatics Group (TU Wien) and others.
2
+ * Copyright (c) 2023-2024 Business Informatics Group (TU Wien) 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
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2023 Business Informatics Group (TU Wien) and others.
2
+ * Copyright (c) 2023-2025 Business Informatics Group (TU Wien) 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
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2023 Business Informatics Group (TU Wien) and others.
2
+ * Copyright (c) 2023-2024 Business Informatics Group (TU Wien) 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
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2023 Business Informatics Group (TU Wien) and others.
2
+ * Copyright (c) 2023-2024 Business Informatics Group (TU Wien) 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
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2023 Business Informatics Group (TU Wien) and others.
2
+ * Copyright (c) 2023-2025 Business Informatics Group (TU Wien) 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
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2023 Business Informatics Group (TU Wien) and others.
2
+ * Copyright (c) 2023-2025 Business Informatics Group (TU Wien) 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
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2023-2024 Business Informatics Group (TU Wien) and others.
2
+ * Copyright (c) 2023-2025 Business Informatics Group (TU Wien) 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
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2023 Business Informatics Group (TU Wien) and others.
2
+ * Copyright (c) 2023-2024 Business Informatics Group (TU Wien) 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
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2023-2024 Business Informatics Group (TU Wien) and others.
2
+ * Copyright (c) 2023-2025 Business Informatics Group (TU Wien) 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
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2023-2024 Business Informatics Group (TU Wien) and others.
2
+ * Copyright (c) 2023-2025 Business Informatics Group (TU Wien) 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
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2023 Business Informatics Group (TU Wien) and others.
2
+ * Copyright (c) 2023-2025 Business Informatics Group (TU Wien) 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
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2023 Business Informatics Group (TU Wien) and others.
2
+ * Copyright (c) 2023-2025 Business Informatics Group (TU Wien) 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
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2023 Business Informatics Group (TU Wien) and others.
2
+ * Copyright (c) 2023-2025 Business Informatics Group (TU Wien) 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
@@ -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
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2022-2024 EclipseSource and others.
2
+ * Copyright (c) 2022-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
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2021-2024 EclipseSource and others.
2
+ * Copyright (c) 2021-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
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2021-2024 EclipseSource and others.
2
+ * Copyright (c) 2021-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
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2024 EclipseSource and others.
2
+ * Copyright (c) 2024-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
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2023-2024 Business Informatics Group (TU Wien) and others.
2
+ * Copyright (c) 2023-2025 Business Informatics Group (TU Wien) 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
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2023 Business Informatics Group (TU Wien) and others.
2
+ * Copyright (c) 2023-2025 Business Informatics Group (TU Wien) 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
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2023-2024 Business Informatics Group (TU Wien) and others.
2
+ * Copyright (c) 2023-2025 Business Informatics Group (TU Wien) 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
@@ -1,5 +1,5 @@
1
1
  /********************************************************************************
2
- * Copyright (c) 2023-2024 Business Informatics Group (TU Wien) and others.
2
+ * Copyright (c) 2023-2025 Business Informatics Group (TU Wien) 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