From cb93d584a5e1822702c6320b36be7e608bcdbd5b Mon Sep 17 00:00:00 2001 From: Tobias Ortmayr Date: Fri, 21 Jun 2024 12:33:25 +0200 Subject: [PATCH] Minor improvements (#366) - Update example1.wf - Remove projection specific css styles for hiding the projection bars on mouse enter/leave over the diagram. This is not a generic feature only certain integration types support it (Theia//VS Code) so it should be handled in the integration specific code base - Fix timing issue in `GLSPCommandStack` when notifying `GModelRootListeners` after a model change. Properly wait until the listeners a notified before completing the returned promise. This ensures that all model listeners have received the updated model information before the next action is processed by the dispatcher. - Introduce `dispatcherAfterNextUpdate` method in `GLSPActionDispatcher` that allows to delay the dispatching of actions until the next model update is processed from the server. (Now actions can be queued from both client and server) - Update changelog --- CHANGELOG.md | 47 +++++++++++++++++-- examples/workflow-standalone/app/example1.wf | 24 ++++++++++ packages/client/css/glsp-sprotty.css | 9 ---- packages/client/src/base/action-dispatcher.ts | 28 ++++++++++- packages/client/src/base/command-stack.ts | 10 ++-- packages/client/src/base/default.module.ts | 1 + 6 files changed, 99 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 851af523..1cf0f0e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,47 @@ # Eclipse GLSP Client Changelog -## v2.1.0 - active +## v2.2.0 - active + +### Changes + +- [diagram] Fix a bug that prevented proper rendering of templates/ghost elements during node creation in Firefox [#324](https://github.com/eclipse-glsp/glsp-client/pull/324) - Contributed on behalf of Axon Ivy AG +- [routing] Improve anchor point calculation for edge routing [#325](https://github.com/eclipse-glsp/glsp-client/pull/325) +- [validation] Fix a bug that could cause duplicate validation markers after a model update [#329](https://github.com/eclipse-glsp/glsp-client/pull/329) +- [di] Introduce a reusable `LazyInjector` that can be used for deferred retrial of services from the container. [#330](https://github.com/eclipse-glsp/glsp-client/pull/330) + - Introduce `preLoadDiagram` hook for `IDiagramStartup`s. This hook is invoked right before the `DiagramLoader` starts the model loading process +- [launch] Introduce `GLSPWebWorkerProvider` to simply setting up a worker connection to a in-browser GLSP-server [#322](https://github.com/eclipse-glsp/glsp-client/pull/332) +- [diagram] Improve base abstract `UIExtension` to allow more fine-grained definition of container and parent [#333](https://github.com/eclipse-glsp/glsp-client/pull/333) - Contributed on behalf of Axon Ivy AG +- [protocol] Improve Geometry API. Add utility functions to `Bound`,`Dimension` and `Point`. Introduce `Vector` and `Movement` types [#341](https://github.com/eclipse-glsp/glsp-client/pull/341) - Contributed on behalf of Axon Ivy AG +- [features] Introduce optional `gridModule` for managing and rendering grids and `debugModule` that allows do display additional graphical debug information during development [#343](https://github.com/eclipse-glsp/glsp-client/pull/343) [#359](https://github.com/eclipse-glsp/glsp-client/pull/359) +- [diagram] Improve error handling of startup hooks [#346](https://github.com/eclipse-glsp/glsp-client/pull/346) +- [feature] Improve style handling in svg exporter [#354](https://github.com/eclipse-glsp/glsp-client/pull/354) +- [di] Improve `ContainerConfiguration` API and add additional checks to ensure that all ids of `FeatureModules` are unique [#355](https://github.com/eclipse-glsp/glsp-client/pull/355) +- [diagram] Update to sprotty 1.2.0. Non-breaking as all potential API breaks have been mitigated via the glsp-sprotty rexport layer [#357](https://github.com/eclipse-glsp/glsp-client/pull/357) +- [diagram] Fix a bug with the `AutocompleteWidget` that prevented proper application of valid suggestions [#362](https://github.com/eclipse-glsp/glsp-client/pull/362) + +### Potentially breaking changes + +- [protocol] Avoid indirect dependency to `chai` introduce by accidentally exporting testing modules [#321](https://github.com/eclipse-glsp/glsp-client/pull/321) + - `@eclipse-glsp/protocol` no longer exports `test-util.ts` via main index. If needed the module can still be imported via the full path `@eclipse-glsp/protocol/lib/utils/test-util.ts` +- [API] Apply feedback commands already on `SetModelCommand` and unify `rank` and `priority` property [#323](https://github.com/eclipse-glsp/glsp-client/pull/322). + - Method `FeedbackAwareUpdateModelCommand.getFeedbackCommands` moved to `IFeedbackEmitter` for re-use, resulting in two new methods: `getFeedbackCommands` and `applyFeedbackCommands`. + - Method `FeedbackAwareUpdateModelCommand.getPriority` is replaced by a generic `rank` property and the `Ranked` namespace. + - The `priority` property (higher priority equals earlier execution) in `FeedbackCommand` is superseeded by a `rank` property (lower rank equals earlier execution). +- [DI] Introduce deferred injection for multi-injected services (listeners, action handlers etc.). Highly reduces the likelihood of circular dependency issues during container creation.[#330](https://github.com/eclipse-glsp/glsp-client/pull/330)
+ No API breaks in the core API, but it introduces some minor breaks in protected methods/fields of default implementations: + - `GLSPCommandStack` + - Handling of `IGModelRootListeners` has moved to the `EditorContextService`. + - `onModelRootChanged` is no deprecated. Use `EditorContextService.onModelRootChanged` instead + - `EditorContextService`: The `postRequestModel` method has been removed. It was previously unused and effectively a no-op. + - `SelectionService`: Injected `commandStack` property has been removed. +- [diagram] Introduce a reusable `FeedbackEmitter` base implementation that is stable across model updates and allows composing feedback before dispatching it [#342](https://github.com/eclipse-glsp/glsp-client/pull/342)
+ Refactored tool implementations and related services to make use of the new `FeedbackEmitter` API. This can cause potential breaks for adopters that have customized the default tool implementations. + Affected tools and services: `MouseTrackingElementPositionListener`, `HelperLineManager`, `FeedbackMoveMouseListener`, `NodeCreationToolMouseListener`, `EdgeEditListener`, +- [diagram] Refactor and improve `ChangeBounds` API by introducing a centralized `ChangeBoundsManage` and `ChangeBoundsTracker` [#344](https://github.com/eclipse-glsp/glsp-client/pull/344) [#348](https://github.com/eclipse-glsp/glsp-client/pull/348) [#352](https://github.com/eclipse-glsp/glsp-client/pull/352) - Contributed on behalf of Axon Ivy AG + This can cause potential breaks for adopters that have customized the default tool implementations
+ Affected tools and services: `MouseTrackingElementPositionListener`, `FeedbackMoveMouseListener`, `ChangeBoundsTool`, `ChangeBoundsListener`,`FeedbackEdgeRouteMovingMouseListener`, `NodeCreationTool`, + +## [v2.1.0 - 23/01/2024](https://github.com/eclipse-glsp/glsp-client/releases/tag/v2.1.0) ### Changes @@ -15,10 +56,6 @@ - [diagram] Restructure some tools to have a more common infrastructure and support helper lines [#306](https://github.com/eclipse-glsp/glsp-client/pull/306) - [diagram] Fix a bug in `SelectionService` that caused issues with inversify when injecting certain services (e.g. `ActionDispatcher`) in `SelectionChangeListener` implementations [#305](https://github.com/eclipse-glsp/glsp-client/pull/305) - [diagram] Ensure that the `SelectionService` does not trigger a change event if the selection did not change on model update [#313](https://github.com/eclipse-glsp/glsp-client/pull/313) -- [API] Apply feedback commands already on `SetModelCommand` and unify `rank` and `priority` property [#323](https://github.com/eclipse-glsp/glsp-client/pull/322). - - Method `FeedbackAwareUpdateModelCommand.getFeedbackCommands` was move to `IFeedbackEmitter` for re-use, resulting in two new methods: `getFeedbackCommands` and `applyFeedbackCommands`. - - Method `FeedbackAwareUpdateModelCommand.getPriority` was replaced by a generic `rank` property and the `Ranked` namespace. - - The `priority` property (higher priority equals earlier execution) in `FeedbackCommand` was superseeded by a `rank` property (lower rank equals earlier execution). ## [v2.0.0 - 14/10/2023](https://github.com/eclipse-glsp/glsp-client/releases/tag/v2.0.0) diff --git a/examples/workflow-standalone/app/example1.wf b/examples/workflow-standalone/app/example1.wf index 3757ab52..94bb9ff1 100644 --- a/examples/workflow-standalone/app/example1.wf +++ b/examples/workflow-standalone/app/example1.wf @@ -253,6 +253,12 @@ "width": 32, "height": 32 }, + "resizeLocations": [ + "top", + "right", + "bottom", + "left" + ], "children": [] }, { @@ -270,6 +276,12 @@ "width": 32, "height": 32 }, + "resizeLocations": [ + "top", + "right", + "bottom", + "left" + ], "children": [] }, { @@ -704,6 +716,12 @@ "width": 32, "height": 32 }, + "resizeLocations": [ + "top", + "right", + "bottom", + "left" + ], "children": [] }, { @@ -721,6 +739,12 @@ "width": 32, "height": 32 }, + "resizeLocations": [ + "top", + "right", + "bottom", + "left" + ], "children": [] }, { diff --git a/packages/client/css/glsp-sprotty.css b/packages/client/css/glsp-sprotty.css index 7f678a4e..26c76779 100644 --- a/packages/client/css/glsp-sprotty.css +++ b/packages/client/css/glsp-sprotty.css @@ -312,15 +312,6 @@ border-width: 2px; } -.mouse-enter .projection-scroll-bar { - opacity: 0.3; -} - -.mouse-leave .projection-scroll-bar { - opacity: 0; - pointer-events: none; -} - .bordered-projection-bar { border-left: 1px solid rgba(212, 212, 212, 0.2); border-top: 1px solid rgba(212, 212, 212, 0.2); diff --git a/packages/client/src/base/action-dispatcher.ts b/packages/client/src/base/action-dispatcher.ts index c8730582..d45cd3f9 100644 --- a/packages/client/src/base/action-dispatcher.ts +++ b/packages/client/src/base/action-dispatcher.ts @@ -13,20 +13,23 @@ * * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { Action, ActionDispatcher, EMPTY_ROOT, RequestAction, ResponseAction, SetModelAction } from '@eclipse-glsp/sprotty'; +import { Action, ActionDispatcher, EMPTY_ROOT, GModelRoot, RequestAction, ResponseAction, SetModelAction } from '@eclipse-glsp/sprotty'; import { inject, injectable } from 'inversify'; import { GLSPActionHandlerRegistry } from './action-handler-registry'; +import { IGModelRootListener } from './editor-context-service'; import { OptionalAction } from './model/glsp-model-source'; import { ModelInitializationConstraint } from './model/model-initialization-constraint'; @injectable() -export class GLSPActionDispatcher extends ActionDispatcher { +export class GLSPActionDispatcher extends ActionDispatcher implements IGModelRootListener { protected readonly timeouts: Map = new Map(); protected initializedConstraint = false; @inject(ModelInitializationConstraint) protected initializationConstraint: ModelInitializationConstraint; + protected postUpdateQueue: Action[] = []; + override initialize(): Promise { if (!this.initialized) { this.initialized = this.doInitialize(); @@ -71,6 +74,27 @@ export class GLSPActionDispatcher extends ActionDispatcher { this.initializationConstraint.onInitialized(() => this.dispatchAll(actions)); } + /** + * Processes all given actions, by dispatching them to the corresponding handlers, after the next model update. + * The given actions are queued until the next model update cycle has been completed i.e. + * the `EditorContextService.onModelRootChanged` event is triggered. + * + * @param actions The actions that should be dispatched after the next model update + */ + dispatchAfterNextUpdate(...actions: Action[]): void { + this.postUpdateQueue.push(...actions); + } + + modelRootChanged(_root: Readonly): void { + if (this.postUpdateQueue.length === 0) { + return; + } + + const toDispatch = [...this.postUpdateQueue]; + this.postUpdateQueue = []; + this.dispatchAll(toDispatch); + } + override async dispatch(action: Action): Promise { const result = await super.dispatch(action); this.initializationConstraint.notifyDispatched(action); diff --git a/packages/client/src/base/command-stack.ts b/packages/client/src/base/command-stack.ts index 86604fda..ddb0ef34 100644 --- a/packages/client/src/base/command-stack.ts +++ b/packages/client/src/base/command-stack.ts @@ -67,12 +67,14 @@ export class GLSPCommandStack extends CommandStack implements Disposable { return this.currentModel; } - override execute(command: ICommand): Promise { - const result = super.execute(command); + override async execute(command: ICommand): Promise { if (command instanceof SetModelCommand || command instanceof UpdateModelCommand) { - result.then(root => this.notifyListeners(root)); + const result = await super.execute(command); + this.notifyListeners(result); + return result; } - return result; + + return super.execute(command); } protected notifyListeners(root: Readonly): void { diff --git a/packages/client/src/base/default.module.ts b/packages/client/src/base/default.module.ts index f6351b62..0ad81f0a 100644 --- a/packages/client/src/base/default.module.ts +++ b/packages/client/src/base/default.module.ts @@ -99,6 +99,7 @@ export const defaultModule = new FeatureModule( bindAsService(context, TYPES.MouseListener, SelectionClearingMouseListener); bindOrRebind(context, TYPES.ICommandStack).to(GLSPCommandStack).inSingletonScope(); bind(GLSPActionDispatcher).toSelf().inSingletonScope(); + bind(TYPES.IGModelRootListener).toService(GLSPActionDispatcher); bindOrRebind(context, TYPES.IActionDispatcher).toService(GLSPActionDispatcher); bindOrRebind(context, ActionHandlerRegistry).to(GLSPActionHandlerRegistry).inSingletonScope();