Skip to content

Commit

Permalink
Allow optional actions to avoid console errors (eclipse-glsp#310)
Browse files Browse the repository at this point in the history
  • Loading branch information
martin-fleck-at authored and holkerveen committed Dec 21, 2024
1 parent c24eb23 commit 77e9487
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 6 deletions.
6 changes: 5 additions & 1 deletion packages/client/src/base/action-dispatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
import { inject, injectable } from 'inversify';
import { Action, ActionDispatcher, RequestAction, ResponseAction } from '@eclipse-glsp/sprotty';
import { inject, injectable } from 'inversify';
import { OptionalAction } from './model/glsp-model-source';
import { ModelInitializationConstraint } from './model/model-initialization-constraint';

@injectable()
Expand Down Expand Up @@ -76,6 +77,9 @@ export class GLSPActionDispatcher extends ActionDispatcher {
action.responseId = '';
}
}
if (!this.hasHandler(action) && OptionalAction.is(action)) {
return Promise.resolve();
}
return super.handleAction(action);
}

Expand Down
28 changes: 26 additions & 2 deletions packages/client/src/base/model/glsp-model-source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import { inject, injectable, preDestroy } from 'inversify';
import {
Action,
ActionMessage,
Expand All @@ -29,8 +28,10 @@ import {
ModelSource,
TYPES
} from '@eclipse-glsp/sprotty';
import { inject, injectable, preDestroy } from 'inversify';
import { GLSPActionHandlerRegistry } from '../action-handler-registry';
import { IDiagramOptions } from './diagram-loader';

/**
* A helper interface that allows the client to mark actions that have been received from the server.
*/
Expand All @@ -44,14 +45,37 @@ export namespace ServerAction {
}

/**
* Mark the given action as {@link ServerAction} by attaching the "_receivedFromServer" property
* Mark the given action as {@link ServerAction} by attaching the "__receivedFromServer" property
* @param action The action that should be marked as server action
*/
export function mark(action: Action): void {
(action as ServerAction).__receivedFromServer = true;
}
}

/**
* A helper interface that allows the client to mark actions that can be considered optional and should not throw an error if
* no handler is available.
*/
export interface OptionalAction extends Action {
__skipErrorIfNoHandler: true;
}

export namespace OptionalAction {
export function is(object: unknown): object is ServerAction {
return Action.is(object) && '__skipErrorIfNoHandler' in object && object.__skipErrorIfNoHandler === true;
}

/**
* Mark the given action as {@link OptionalAction} by attaching the "__skipErrorIfNoHandler" property
* @param action The action that should be marked as optional action
*/
export function mark<T extends Action>(action: T): T & OptionalAction {
(action as unknown as OptionalAction).__skipErrorIfNoHandler = true;
return action as T & OptionalAction;
}
}

/**
* Central component for enabling the client-server action flow with the help of an underlying {@link GLSPClient}.
* Handles & forwards actions that are intended for the GLSP server. In addition, it handles {@link ActionMessage}s received
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { DebouncedFunc, debounce } from 'lodash';
import { DragAwareMouseListener } from '../../../base/drag-aware-mouse-listener';
import { CursorCSS, cursorFeedbackAction } from '../../../base/feedback/css-feedback';
import { FeedbackCommand } from '../../../base/feedback/feedback-command';
import { OptionalAction } from '../../../base/model/glsp-model-source';
import { forEachElement } from '../../../utils/gmodel-util';
import { SResizeHandle, addResizeHandles, isResizable, removeResizeHandles } from '../../change-bounds/model';
import { createMovementRestrictionFeedback, removeMovementRestrictionFeedback } from '../../change-bounds/movement-restrictor';
Expand Down Expand Up @@ -125,7 +126,7 @@ export namespace MoveInitializedEventAction {
}

export function create(): MoveInitializedEventAction {
return { kind: KIND };
return OptionalAction.mark({ kind: KIND });
}
}

Expand All @@ -141,7 +142,7 @@ export namespace MoveFinishedEventAction {
}

export function create(): MoveFinishedEventAction {
return { kind: KIND };
return OptionalAction.mark({ kind: KIND });
}
}

Expand All @@ -157,6 +158,7 @@ export class FeedbackMoveMouseListener extends DragAwareMouseListener implements
protected positionUpdater;
protected elementId2startPos = new Map<string, Point>();
protected pendingMoveInitialized?: DebouncedFunc<() => void>;
protected moveInitialized = false;

constructor(protected tool: ChangeBoundsTool) {
super();
Expand All @@ -178,10 +180,12 @@ export class FeedbackMoveMouseListener extends DragAwareMouseListener implements
}

protected scheduleMoveInitialized(): void {
this.moveInitialized = false;
this.pendingMoveInitialized?.cancel();
this.pendingMoveInitialized = debounce(() => {
this.tool.registerFeedback([MoveInitializedEventAction.create()], this);
this.pendingMoveInitialized = undefined;
this.moveInitialized = true;
}, 750);
this.pendingMoveInitialized();
}
Expand Down Expand Up @@ -329,11 +333,12 @@ export class FeedbackMoveMouseListener extends DragAwareMouseListener implements
const moveAction = MoveAction.create(elementMoves, { animate: false, finished: true });
this.tool.deregisterFeedback(this, [moveAction]);
}
} else if (resetFeedback) {
} else if (resetFeedback && this.moveInitialized) {
this.tool.deregisterFeedback(this, [MoveFinishedEventAction.create()]);
}
this.positionUpdater.resetPosition();
this._isMouseDrag = false;
this.moveInitialized = false;
this.rootElement = undefined;
this.elementId2startPos.clear();
}
Expand Down

0 comments on commit 77e9487

Please sign in to comment.