New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@glsp/sprotty-client

Package Overview
Dependencies
Maintainers
2
Versions
57
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@glsp/sprotty-client - npm Package Compare versions

Comparing version 0.1.1 to 0.2.0-next.0185f7f2

lib/base/views/viewer-options.d.ts

27

lib/base/di.config.js

@@ -22,23 +22,6 @@ "use strict";

var types_1 = require("../types");
var command_stack_1 = require("./command-stack");
var diagram_ui_extension_registry_1 = require("./diagram-ui-extension/diagram-ui-extension-registry");
var update_model_command_1 = require("./model/update-model-command");
var tool_manager_action_handler_1 = require("./tool-manager/tool-manager-action-handler");
var viewer_options_1 = require("./views/viewer-options");
var defaultGLSPModule = new inversify_1.ContainerModule(function (bind, unbind, isBound, rebind) {
// GLSP Commandstack initialization ------------------------------------
if (isBound(lib_1.TYPES.ICommandStack)) {
unbind(lib_1.TYPES.ICommandStack);
}
bind(command_stack_1.GLSPCommandStack).toSelf().inSingletonScope();
bind(lib_1.TYPES.ICommandStack).toService(command_stack_1.GLSPCommandStack);
bind(types_1.GLSP_TYPES.IReadonlyModelAccessProvider).toProvider(function (context) {
return function () {
return new Promise(function (resolve) {
resolve(context.container.get(lib_1.TYPES.ICommandStack));
});
};
});
// DiagramUIExtension registry initialization ------------------------------------
bind(types_1.GLSP_TYPES.DiagramUIExtensionRegistry).to(diagram_ui_extension_registry_1.DiagramUIExtensionRegistry).inSingletonScope();
bind(lib_1.TYPES.IActionHandlerInitializer).to(diagram_ui_extension_registry_1.DiagramUIExtensionActionHandlerInitializer);
// Tool manager initialization ------------------------------------

@@ -49,4 +32,12 @@ bind(lib_1.TYPES.IActionHandlerInitializer).to(tool_manager_action_handler_1.ToolManagerActionHandler);

lib_1.configureCommand({ bind: bind, isBound: isBound }, update_model_command_1.FeedbackAwareUpdateModelCommand);
bind(lib_1.TYPES.IActionHandlerInitializer).to(update_model_command_1.SetModelActionHandler);
bind(types_1.GLSP_TYPES.ViewerOptions).toConstantValue(viewer_options_1.defaultGLSPViewerOptions());
if (isBound(lib_1.TYPES.ViewerOptions)) {
rebind(lib_1.TYPES.ViewerOptions).toService(types_1.GLSP_TYPES.ViewerOptions);
}
else {
bind(lib_1.TYPES.ViewerOptions).toService(types_1.GLSP_TYPES.ViewerOptions);
}
});
exports.default = defaultGLSPModule;
//# sourceMappingURL=di.config.js.map

@@ -1,4 +0,13 @@

import { ActionHandlerRegistry, CommandExecutionContext, CommandResult, ILogger, SModelRoot } from "sprotty/lib";
import { Action, ActionHandlerRegistry, CommandExecutionContext, CommandResult, ILogger, SetModelAction, SModelRoot } from "sprotty/lib";
import { UpdateModelAction, UpdateModelCommand } from "sprotty/lib/features/update/update-model";
import { IFeedbackActionDispatcher } from "src/features/tool-feedback/feedback-action-dispatcher";
import { SelfInitializingActionHandler } from "../tool-manager/tool-manager-action-handler";
export declare class SetModelActionHandler extends SelfInitializingActionHandler {
handle(action: Action): Action | void;
handledActionKinds: string[];
}
export declare function isSetModelAction(action: Action): action is SetModelAction;
export interface SModelRootListener {
modelRootChanged(root: Readonly<SModelRoot>): void;
}
/**

@@ -12,3 +21,4 @@ * A special`UpdateModelCommand` that retrieves all registered `actions` from the `IFeedbackActionDispatcher` (if present) and applies their feedback

protected actionHandlerRegistryProvider: () => Promise<ActionHandlerRegistry>;
constructor(action: UpdateModelAction, logger: ILogger, feedbackActionDispatcher: IFeedbackActionDispatcher, actionHandlerRegistryProvider: () => Promise<ActionHandlerRegistry>);
protected modelRootListeners: SModelRootListener[];
constructor(action: UpdateModelAction, logger: ILogger, feedbackActionDispatcher: IFeedbackActionDispatcher, actionHandlerRegistryProvider: () => Promise<ActionHandlerRegistry>, modelRootListeners?: SModelRootListener[]);
protected performUpdate(oldRoot: SModelRoot, newRoot: SModelRoot, context: CommandExecutionContext): CommandResult;

@@ -15,0 +25,0 @@ private getFeedbackCommands;

@@ -48,2 +48,25 @@ "use strict";

var types_1 = require("../../types");
var tool_manager_action_handler_1 = require("../tool-manager/tool-manager-action-handler");
/* ActionHandler that transforms a SetModelAction into an (feedback-aware) UpdateModelAction. This can be done because in sprotty
* UpdateModel behaves the same as SetModel if no model is present yet.*/
var SetModelActionHandler = /** @class */ (function (_super) {
__extends(SetModelActionHandler, _super);
function SetModelActionHandler() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.handledActionKinds = [lib_1.SetModelCommand.KIND];
return _this;
}
SetModelActionHandler.prototype.handle = function (action) {
if (isSetModelAction(action)) {
return new update_model_1.UpdateModelAction(action.newRoot, false);
}
};
return SetModelActionHandler;
}(tool_manager_action_handler_1.SelfInitializingActionHandler));
exports.SetModelActionHandler = SetModelActionHandler;
function isSetModelAction(action) {
return action !== undefined && (action.kind === lib_1.SetModelCommand.KIND)
&& action.newRoot !== undefined;
}
exports.isSetModelAction = isSetModelAction;
/**

@@ -55,3 +78,4 @@ * A special`UpdateModelCommand` that retrieves all registered `actions` from the `IFeedbackActionDispatcher` (if present) and applies their feedback

__extends(FeedbackAwareUpdateModelCommand, _super);
function FeedbackAwareUpdateModelCommand(action, logger, feedbackActionDispatcher, actionHandlerRegistryProvider) {
function FeedbackAwareUpdateModelCommand(action, logger, feedbackActionDispatcher, actionHandlerRegistryProvider, modelRootListeners) {
if (modelRootListeners === void 0) { modelRootListeners = []; }
var _this = _super.call(this, action) || this;

@@ -61,2 +85,3 @@ _this.logger = logger;

_this.actionHandlerRegistryProvider = actionHandlerRegistryProvider;
_this.modelRootListeners = modelRootListeners;
return _this;

@@ -82,2 +107,3 @@ }

}
this.modelRootListeners.forEach(function (listener) { return listener.modelRootChanged(newRoot); });
return _super.prototype.performUpdate.call(this, oldRoot, newRoot, context);

@@ -102,3 +128,4 @@ };

__param(3, inversify_1.inject(lib_1.TYPES.ActionHandlerRegistryProvider)),
__metadata("design:paramtypes", [update_model_1.UpdateModelAction, Object, Object, Function])
__param(4, inversify_1.multiInject(types_1.GLSP_TYPES.SModelRootListener)), __param(4, inversify_1.optional()),
__metadata("design:paramtypes", [update_model_1.UpdateModelAction, Object, Object, Function, Array])
], FeedbackAwareUpdateModelCommand);

@@ -105,0 +132,0 @@ return FeedbackAwareUpdateModelCommand;

@@ -17,5 +17,9 @@ /********************************************************************************

import { interfaces } from "inversify";
import { Action, ICommand, Tool, ToolManager } from "sprotty/lib";
import { Action, ActionHandlerRegistry, IActionHandler, IActionHandlerInitializer, ICommand, Tool, ToolManager } from "sprotty/lib";
import { SetOperationsAction } from "../../features/operation/set-operations";
import { SelfInitializingActionHandler } from "../diagram-ui-extension/diagram-ui-extension-registry";
export declare abstract class SelfInitializingActionHandler implements IActionHandler, IActionHandlerInitializer {
initialize(registry: ActionHandlerRegistry): void;
abstract handle(action: Action): ICommand | Action | void;
abstract handledActionKinds: string[];
}
export declare class ToolManagerActionHandler extends SelfInitializingActionHandler {

@@ -22,0 +26,0 @@ readonly toolFactory: (operationKind: string) => Tool;

@@ -66,3 +66,15 @@ "use strict";

var types_1 = require("../../types");
var diagram_ui_extension_registry_1 = require("../diagram-ui-extension/diagram-ui-extension-registry");
var SelfInitializingActionHandler = /** @class */ (function () {
function SelfInitializingActionHandler() {
}
SelfInitializingActionHandler.prototype.initialize = function (registry) {
var _this = this;
this.handledActionKinds.forEach(function (kind) { return registry.register(kind, _this); });
};
SelfInitializingActionHandler = __decorate([
inversify_1.injectable()
], SelfInitializingActionHandler);
return SelfInitializingActionHandler;
}());
exports.SelfInitializingActionHandler = SelfInitializingActionHandler;
var ToolManagerActionHandler = /** @class */ (function (_super) {

@@ -104,3 +116,3 @@ __extends(ToolManagerActionHandler, _super);

return ToolManagerActionHandler;
}(diagram_ui_extension_registry_1.SelfInitializingActionHandler));
}(SelfInitializingActionHandler));
exports.ToolManagerActionHandler = ToolManagerActionHandler;

@@ -107,0 +119,0 @@ function isTypeAware(tool) {

@@ -16,4 +16,3 @@ /********************************************************************************

********************************************************************************/
import { Action } from "sprotty/lib";
import { LabeledAction } from "../../base/diagram-ui-extension/diagram-ui-extension";
import { Action, LabeledAction } from "sprotty/lib";
export declare class RequestCommandPaletteActions implements Action {

@@ -20,0 +19,0 @@ readonly selectedElementsIDs: string[];

@@ -1,21 +0,7 @@

import { Action, ILogger, SModelElement, SModelRoot } from "sprotty/lib";
import { IReadonlyModelAccessProvider } from "../../base/command-stack";
import { LabeledAction } from "../../base/diagram-ui-extension/diagram-ui-extension";
import { Action, ICommandPaletteActionProvider, ILogger, LabeledAction, SModelElement } from "sprotty/lib";
import { RequestResponseSupport } from "../request-response/support";
export interface ICommandPaletteActionProvider {
getActions(selectedElements: SModelElement[]): Promise<LabeledAction[]>;
}
export declare type ICommandPaletteActionProviderRegistry = () => Promise<ICommandPaletteActionProvider>;
export declare class CommandPaletteActionProviderRegistry implements ICommandPaletteActionProvider {
protected registeredActionProviders: ICommandPaletteActionProvider[];
actionProvider: ICommandPaletteActionProvider[];
constructor(registeredActionProviders?: ICommandPaletteActionProvider[]);
getActions(selectedElements: SModelElement[]): Promise<LabeledAction[]>;
}
export declare class NavigationCommandPaletteActionProvider implements ICommandPaletteActionProvider {
protected modelAccessProvider: IReadonlyModelAccessProvider;
protected logger: ILogger;
constructor(modelAccessProvider: IReadonlyModelAccessProvider, logger: ILogger);
getActions(selectedElements: SModelElement[]): Promise<LabeledAction[]>;
createSelectActions(modelRoot: SModelRoot): LabeledAction[];
constructor(logger: ILogger);
getActions(root: Readonly<SModelElement>): Promise<LabeledAction[]>;
}

@@ -25,5 +11,5 @@ export declare class ServerCommandPaletteActionProvider implements ICommandPaletteActionProvider {

constructor(requestResponseSupport: RequestResponseSupport);
getActions(selectedElements: SModelElement[]): Promise<LabeledAction[]>;
getActions(root: Readonly<SModelElement>): Promise<LabeledAction[]>;
getPaletteActionsFromResponse(action: Action): LabeledAction[];
}
//# sourceMappingURL=action-provider.d.ts.map

@@ -14,12 +14,2 @@ "use strict";

};
var __values = (this && this.__values) || function (o) {
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
if (m) return m.call(o);
return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
};
Object.defineProperty(exports, "__esModule", { value: true });

@@ -44,64 +34,19 @@ /********************************************************************************

var iterable_1 = require("sprotty/lib/utils/iterable");
var diagram_ui_extension_1 = require("../../base/diagram-ui-extension/diagram-ui-extension");
var types_1 = require("../../types");
var model_1 = require("../nameable/model");
var smodel_util_1 = require("../../utils/smodel-util");
var support_1 = require("../request-response/support");
var action_definitions_1 = require("./action-definitions");
var CommandPaletteActionProviderRegistry = /** @class */ (function () {
function CommandPaletteActionProviderRegistry(registeredActionProviders) {
var e_1, _a;
if (registeredActionProviders === void 0) { registeredActionProviders = []; }
this.registeredActionProviders = registeredActionProviders;
this.actionProvider = [];
try {
for (var registeredActionProviders_1 = __values(registeredActionProviders), registeredActionProviders_1_1 = registeredActionProviders_1.next(); !registeredActionProviders_1_1.done; registeredActionProviders_1_1 = registeredActionProviders_1.next()) {
var registeredProvider = registeredActionProviders_1_1.value;
this.actionProvider.push(registeredProvider);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (registeredActionProviders_1_1 && !registeredActionProviders_1_1.done && (_a = registeredActionProviders_1.return)) _a.call(registeredActionProviders_1);
}
finally { if (e_1) throw e_1.error; }
}
}
CommandPaletteActionProviderRegistry.prototype.getActions = function (selectedElements) {
var actionLists = this.actionProvider.map(function (provider) { return provider.getActions(selectedElements); });
return Promise.all(actionLists).then(function (p) { return p.reduce(function (acc, promise) { return promise !== undefined ? acc.concat(promise) : acc; }); });
};
CommandPaletteActionProviderRegistry = __decorate([
inversify_1.injectable(),
__param(0, inversify_1.multiInject(types_1.GLSP_TYPES.ICommandPaletteActionProvider)), __param(0, inversify_1.optional()),
__metadata("design:paramtypes", [Array])
], CommandPaletteActionProviderRegistry);
return CommandPaletteActionProviderRegistry;
}());
exports.CommandPaletteActionProviderRegistry = CommandPaletteActionProviderRegistry;
var NavigationCommandPaletteActionProvider = /** @class */ (function () {
function NavigationCommandPaletteActionProvider(modelAccessProvider, logger) {
this.modelAccessProvider = modelAccessProvider;
function NavigationCommandPaletteActionProvider(logger) {
this.logger = logger;
}
NavigationCommandPaletteActionProvider.prototype.getActions = function (selectedElements) {
var _this = this;
return this.modelAccessProvider()
.then(function (access) { return access.model; })
.then(function (model) { return _this.createSelectActions(model); })
.catch(function (reason) {
_this.logger.error(_this, 'Could not create navigation command palette actions.', reason);
return [];
});
NavigationCommandPaletteActionProvider.prototype.getActions = function (root) {
return Promise.resolve(iterable_1.toArray(root.index.all()
.filter(lib_1.isNameable)
.map(function (nameable) { return new lib_1.LabeledAction("Select " + lib_1.name(nameable), [new lib_1.SelectAction([nameable.id]), new lib_1.CenterAction([nameable.id])]); })));
};
NavigationCommandPaletteActionProvider.prototype.createSelectActions = function (modelRoot) {
return iterable_1.toArray(modelRoot.index.all()
.filter(function (element) { return model_1.isNameable(element); })
.map(function (nameable) { return new diagram_ui_extension_1.LabeledAction("Select " + model_1.name(nameable), [new lib_1.SelectAction([nameable.id]), new lib_1.CenterAction([nameable.id])]); }));
};
NavigationCommandPaletteActionProvider = __decorate([
inversify_1.injectable(),
__param(0, inversify_1.inject(types_1.GLSP_TYPES.IReadonlyModelAccessProvider)),
__param(1, inversify_1.inject(lib_1.TYPES.ILogger)),
__metadata("design:paramtypes", [Function, Object])
__param(0, inversify_1.inject(lib_1.TYPES.ILogger)),
__metadata("design:paramtypes", [Object])
], NavigationCommandPaletteActionProvider);

@@ -115,4 +60,4 @@ return NavigationCommandPaletteActionProvider;

}
ServerCommandPaletteActionProvider.prototype.getActions = function (selectedElements) {
var selectedElementIDs = selectedElements.map(function (e) { return e.id; });
ServerCommandPaletteActionProvider.prototype.getActions = function (root) {
var selectedElementIDs = Array.from(root.index.all().filter(smodel_util_1.isSelected).map(function (e) { return e.id; }));
var requestAction = new action_definitions_1.RequestCommandPaletteActions(selectedElementIDs);

@@ -119,0 +64,0 @@ var responseHandler = this.getPaletteActionsFromResponse;

@@ -18,4 +18,4 @@ /********************************************************************************

import { ContainerModule } from "inversify";
declare const commandPaletteModule: ContainerModule;
export default commandPaletteModule;
declare const glspCommandPaletteModule: ContainerModule;
export default glspCommandPaletteModule;
//# sourceMappingURL=di.config.d.ts.map

@@ -21,22 +21,9 @@ "use strict";

var lib_1 = require("sprotty/lib");
var types_1 = require("../../types");
var action_provider_1 = require("./action-provider");
var command_palette_1 = require("./command-palette");
var commandPaletteModule = new inversify_1.ContainerModule(function (bind, unbind, isBound, rebind) {
bind(command_palette_1.CommandPalette).toSelf().inSingletonScope();
bind(types_1.GLSP_TYPES.IDiagramUIExtension).toService(command_palette_1.CommandPalette);
bind(lib_1.TYPES.KeyListener).to(command_palette_1.CommandPaletteKeyListener);
bind(action_provider_1.CommandPaletteActionProviderRegistry).toSelf().inSingletonScope();
bind(types_1.GLSP_TYPES.ICommandPaletteActionProviderRegistry).toProvider(function (context) {
return function () {
return new Promise(function (resolve) {
resolve(context.container.get(action_provider_1.CommandPaletteActionProviderRegistry));
});
};
});
bind(types_1.GLSP_TYPES.ICommandPaletteActionProvider).to(action_provider_1.NavigationCommandPaletteActionProvider);
var glspCommandPaletteModule = new inversify_1.ContainerModule(function (bind, unbind, isBound, rebind) {
bind(lib_1.TYPES.ICommandPaletteActionProvider).to(action_provider_1.NavigationCommandPaletteActionProvider);
bind(action_provider_1.ServerCommandPaletteActionProvider).toSelf().inSingletonScope();
bind(types_1.GLSP_TYPES.ICommandPaletteActionProvider).to(action_provider_1.ServerCommandPaletteActionProvider);
bind(lib_1.TYPES.ICommandPaletteActionProvider).to(action_provider_1.ServerCommandPaletteActionProvider);
});
exports.default = commandPaletteModule;
exports.default = glspCommandPaletteModule;
//# sourceMappingURL=di.config.js.map

@@ -18,4 +18,6 @@ /********************************************************************************

export declare class RequestTypeHintsAction implements Action {
readonly diagramType?: string | undefined;
static readonly KIND = "requestTypeHints";
kind: string;
constructor(diagramType?: string | undefined);
}

@@ -22,0 +24,0 @@ export declare class SetTypeHintsAction implements Action {

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var RequestTypeHintsAction = /** @class */ (function () {
function RequestTypeHintsAction() {
function RequestTypeHintsAction(diagramType) {
this.diagramType = diagramType;
this.kind = RequestTypeHintsAction.KIND;

@@ -6,0 +7,0 @@ }

import { Action, CommandExecutionContext, CommandResult, ICommand, SModelElement, SModelElementSchema } from "sprotty/lib";
import { SelfInitializingActionHandler } from "../../base/diagram-ui-extension/diagram-ui-extension-registry";
import { EdgeEditConfig, EditConfig, IEditConfigProvider, NodeEditConfig } from "../../base/edit-config/edit-config";
import { SelfInitializingActionHandler } from "../../base/tool-manager/tool-manager-action-handler";
import { IFeedbackActionDispatcher } from "../tool-feedback/feedback-action-dispatcher";

@@ -5,0 +5,0 @@ import { FeedbackCommand } from "../tool-feedback/model";

@@ -45,4 +45,4 @@ "use strict";

var lib_1 = require("sprotty/lib");
var diagram_ui_extension_registry_1 = require("../../base/diagram-ui-extension/diagram-ui-extension-registry");
var edit_config_1 = require("../../base/edit-config/edit-config");
var tool_manager_action_handler_1 = require("../../base/tool-manager/tool-manager-action-handler");
var types_1 = require("../../types");

@@ -136,3 +136,3 @@ var array_utils_1 = require("../../utils/array-utils");

return TypeHintsEditConfigProvider;
}(diagram_ui_extension_registry_1.SelfInitializingActionHandler));
}(tool_manager_action_handler_1.SelfInitializingActionHandler));
exports.TypeHintsEditConfigProvider = TypeHintsEditConfigProvider;

@@ -139,0 +139,0 @@ function createNodeEditConfig(hint) {

import { VNode } from "snabbdom/vnode";
import { Action, CommandExecutionContext, CommandResult, MouseListener, Point, SModelElement } from "sprotty/lib";
import { Action, Bounds, CommandExecutionContext, CommandResult, MouseListener, Point, SModelElement } from "sprotty/lib";
import { GLSPViewerOptions } from "../../base/views/viewer-options";
import { FeedbackCommand } from "./model";

@@ -33,5 +34,12 @@ export declare class ShowChangeBoundsToolResizeFeedbackAction implements Action {

export declare class FeedbackMoveMouseListener extends MouseListener {
protected glspViewerOptions: GLSPViewerOptions;
hasDragged: boolean;
lastDragPosition: Point | undefined;
hasCollided: boolean;
constructor(glspViewerOptions: GLSPViewerOptions);
mouseDown(target: SModelElement, event: MouseEvent): Action[];
/**
* Used to return the collision target(s) or the collision chain in case of multiple selected elements
*/
getCollisionChain(target: SModelElement, element: SModelElement, dx: number, dy: number, collisionChain: SModelElement[]): SModelElement[];
mouseMove(target: SModelElement, event: MouseEvent): Action[];

@@ -42,2 +50,10 @@ mouseEnter(target: SModelElement, event: MouseEvent): Action[];

}
/**
* Used to check if 1D boxes (lines) overlap
*/
export declare function isOverlapping1Dimension(x1: number, width1: number, x2: number, width2: number): boolean;
/**
* Used to check if 2 bounds are overlapping
*/
export declare function isOverlappingBounds(bounds1: Bounds, bounds2: Bounds): boolean;
//# sourceMappingURL=change-bounds-tool-feedback.d.ts.map

@@ -46,3 +46,5 @@ "use strict";

var smodel_util_1 = require("../../utils/smodel-util");
var viewpoint_util_1 = require("../../utils/viewpoint-util");
var model_1 = require("../change-bounds/model");
var cursor_feedback_1 = require("./cursor-feedback");
var model_2 = require("./model");

@@ -121,5 +123,7 @@ var ShowChangeBoundsToolResizeFeedbackAction = /** @class */ (function () {

__extends(FeedbackMoveMouseListener, _super);
function FeedbackMoveMouseListener() {
var _this = _super !== null && _super.apply(this, arguments) || this;
function FeedbackMoveMouseListener(glspViewerOptions) {
var _this = _super.call(this) || this;
_this.glspViewerOptions = glspViewerOptions;
_this.hasDragged = false;
_this.hasCollided = false;
return _this;

@@ -140,3 +144,34 @@ }

};
/**
* Used to return the collision target(s) or the collision chain in case of multiple selected elements
*/
FeedbackMoveMouseListener.prototype.getCollisionChain = function (target, element, dx, dy, collisionChain) {
var _this = this;
if (lib_1.isMoveable(element) && model_1.isResizeable(element)) {
target.root.index.all()
.filter(function (candidate) { return lib_1.isSelectable(candidate) && element.id !== candidate.id && collisionChain.indexOf(candidate) < 0; })
.forEach(function (candidate) {
if (lib_1.isMoveable(element) && lib_1.isMoveable(candidate)) {
if (model_1.isResizeable(element) && model_1.isResizeable(candidate)) {
var futureBounds = {
x: element.position.x + dx,
y: element.position.y + dy,
width: element.size.width,
height: element.size.height
};
if (isOverlappingBounds(futureBounds, candidate.bounds) && !isOverlappingBounds(element.bounds, candidate.bounds)) {
collisionChain.push(candidate);
if (candidate.selected) {
// Check what the selected candidate will collide with and add it to the chain
collisionChain.push.apply(collisionChain, _this.getCollisionChain(target, candidate, dx, dy, collisionChain));
}
}
}
}
});
}
return collisionChain;
};
FeedbackMoveMouseListener.prototype.mouseMove = function (target, event) {
var _this = this;
var result = [];

@@ -149,9 +184,37 @@ if (event.buttons === 0)

var zoom = viewport ? viewport.zoom : 1;
var mousePoint_1 = viewpoint_util_1.getAbsolutePosition(target, event);
var dx_1 = (event.pageX - this.lastDragPosition.x) / zoom;
var dy_1 = (event.pageY - this.lastDragPosition.y) / zoom;
var nodeMoves_1 = [];
var willCollide_1 = false;
var mouseOverElement_1 = false;
var collisionOccured_1 = false;
target.root.index.all()
.filter(function (element) { return lib_1.isSelectable(element) && element.selected; })
.forEach(function (element) {
if (lib_1.isMoveable(element)) {
if (lib_1.isMoveable(element) && model_1.isResizeable(element)) {
// If noElementOverlap Option is set perform collision detection
if (_this.glspViewerOptions.noElementOverlap) {
// After collision the mouse is back inside the element => change cursor back to default
if (_this.hasCollided && lib_1.includes(element.bounds, mousePoint_1)) {
mouseOverElement_1 = true;
result.push(new cursor_feedback_1.ApplyCursorCSSFeedbackAction(cursor_feedback_1.CursorCSS.DEFAULT));
}
// Get only the valid, non-slected collision targets to avoid in-selection collisions
var collisionTargets = _this.getCollisionChain(target, element, dx_1, dy_1, [])
.filter(function (collidingElement) { return lib_1.isSelectable(collidingElement) && !collidingElement.selected; });
if (collisionTargets.length > 0) {
collisionTargets.forEach(function (collisionTarget) {
if (model_1.isResizeable(collisionTarget)) {
willCollide_1 = true;
_this.hasCollided = true;
result.push(new cursor_feedback_1.ApplyCursorCSSFeedbackAction(cursor_feedback_1.CursorCSS.OVERLAP_FORBIDDEN));
}
});
}
}
}
if (lib_1.isMoveable(element) && !collisionOccured_1 && ((!willCollide_1 && !_this.hasCollided) ||
(_this.hasCollided && !willCollide_1 && mouseOverElement_1))) {
_this.hasCollided = false;
nodeMoves_1.push({

@@ -171,4 +234,5 @@ elementId: element.id,

this.lastDragPosition = { x: event.pageX, y: event.pageY };
if (nodeMoves_1.length > 0)
if (nodeMoves_1.length > 0 && !this.hasCollided) {
result.push(new lib_1.MoveAction(nodeMoves_1, false));
}
}

@@ -193,2 +257,17 @@ return result;

exports.FeedbackMoveMouseListener = FeedbackMoveMouseListener;
/**
* Used to check if 1D boxes (lines) overlap
*/
function isOverlapping1Dimension(x1, width1, x2, width2) {
return x1 + width1 >= x2 && x2 + width2 >= x1;
}
exports.isOverlapping1Dimension = isOverlapping1Dimension;
/**
* Used to check if 2 bounds are overlapping
*/
function isOverlappingBounds(bounds1, bounds2) {
return isOverlapping1Dimension(bounds1.x, bounds1.width, bounds2.x, bounds2.width) &&
isOverlapping1Dimension(bounds1.y, bounds1.height, bounds2.y, bounds2.height);
}
exports.isOverlappingBounds = isOverlappingBounds;
//# sourceMappingURL=change-bounds-tool-feedback.js.map
import { Action, CommandExecutionContext, SModelRoot } from "sprotty/lib";
import { FeedbackCommand } from "./model";
export declare enum CursorCSS {
DEFAULT = "default-mode",
OVERLAP_FORBIDDEN = "overlap-forbidden-mode",
NODE_CREATION = "node-creation-mode",

@@ -5,0 +7,0 @@ EDGE_CREATION_SOURCE = "edge-creation-select-source-mode",

@@ -49,2 +49,4 @@ "use strict";

(function (CursorCSS) {
CursorCSS["DEFAULT"] = "default-mode";
CursorCSS["OVERLAP_FORBIDDEN"] = "overlap-forbidden-mode";
CursorCSS["NODE_CREATION"] = "node-creation-mode";

@@ -51,0 +53,0 @@ CursorCSS["EDGE_CREATION_SOURCE"] = "edge-creation-select-source-mode";

@@ -1,8 +0,27 @@

import { Action, IActionDispatcher, ILogger } from "sprotty/lib";
/********************************************************************************
* Copyright (c) 2019 EclipseSource and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
import { Action } from "sprotty/lib";
import { IActionDispatcher } from "sprotty/lib";
import { ILogger } from "sprotty/lib";
export interface IFeedbackEmitter {
}
/**
* Action dispatcher for actions that are meant to show tool feedback.
* Dispatcher for actions that are meant to show visual feedback on
* the diagram that is not part of the diagram sent from the server
* after a model update.
*
* The purpose of this action dispatcher is to re-establish the feedback
* The purpose of this dispatcher is to re-establish the feedback
* after the model has been updated or reset by the server, as this would

@@ -13,3 +32,3 @@ * overwrite the already established feedback, in case it is drawn by

* feedback. This dispatcher will then re-establish all feedback actions
* of the registered tools, whenever the `SModelRoot` has been set.
* of the registered tools, whenever the `SModelRoot` has been set or updated.
*/

@@ -24,9 +43,14 @@ export interface IFeedbackActionDispatcher {

/**
* Deregisters a `feedbackEmitter` from this dispatcher.
* @param feedbackEmitter the emitter sending out feedback actions.
* @param actions the actions to be sent out after deregistration.
* Deregisters a `feedbackEmitter` from this dispatcher and thereafter
* dispatches the provided `actions`.
* @param feedbackEmitter the emitter to be deregistered.
* @param actions the actions to be dispatched right after the deregistration.
* These actions do not have to be related to the actions sent out by the
* deregistered `feedbackEmitter`. The purpose of these actions typically is
* to reset the normal state of the diagram without the feedback (e.g., reset a
* CSS class that was set by a feedbackEmitter).
*/
deregisterFeedback(feedbackEmitter: IFeedbackEmitter, actions: Action[]): void;
/**
* Retrieve all currently registered `actions`
* Retrieve all `actions` sent out by currently registered `feedbackEmitter`.
*/

@@ -44,3 +68,4 @@ getRegisteredFeedback(): Action[];

getRegisteredFeedback(): Action[];
getRegisteredFeedbackEmitters(action: Action): IFeedbackEmitter[];
}
//# sourceMappingURL=feedback-action-dispatcher.d.ts.map

@@ -35,19 +35,5 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
/********************************************************************************
* Copyright (c) 2019 EclipseSource and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
var lib_1 = require("sprotty/lib");
var inversify_1 = require("inversify");
var lib_1 = require("sprotty/lib");
var inversify_2 = require("inversify");
var FeedbackActionDispatcher = /** @class */ (function () {

@@ -79,4 +65,13 @@ function FeedbackActionDispatcher(actionDispatcher, logger) {

};
FeedbackActionDispatcher.prototype.getRegisteredFeedbackEmitters = function (action) {
var result = [];
this.feedbackEmitters.forEach(function (value, key) {
if (value.find(function (a) { return a === action; })) {
result.push(key);
}
});
return result;
};
FeedbackActionDispatcher = __decorate([
inversify_1.injectable(),
inversify_2.injectable(),
__param(0, inversify_1.inject(lib_1.TYPES.IActionDispatcherProvider)),

@@ -83,0 +78,0 @@ __param(1, inversify_1.inject(lib_1.TYPES.ILogger)),

@@ -29,3 +29,4 @@ /********************************************************************************

protected getPosition(handle: SResizeHandle): Point | undefined;
getRadius(): number;
}
//# sourceMappingURL=view.d.ts.map

@@ -52,3 +52,3 @@ "use strict";

if (position !== undefined) {
var node = snabbdom_jsx_1.svg("circle", { "class-sprotty-resize-handle": true, "class-mouseover": handle.hoverFeedback, cx: position.x, cy: position.y }); // Radius must be specified via CSS
var node = snabbdom_jsx_1.svg("circle", { "class-sprotty-resize-handle": true, "class-mouseover": handle.hoverFeedback, cx: position.x, cy: position.y, r: this.getRadius() });
lib_1.setAttr(node, 'data-kind', handle.location);

@@ -78,2 +78,5 @@ return node;

};
SResizeHandleView.prototype.getRadius = function () {
return 7;
};
SResizeHandleView = __decorate([

@@ -80,0 +83,0 @@ inversify_1.injectable()

@@ -21,7 +21,6 @@ "use strict";

var lib_1 = require("sprotty/lib");
var types_1 = require("../../types");
var tool_palette_1 = require("./tool-palette");
var toolPaletteModule = new inversify_1.ContainerModule(function (bind) {
bind(tool_palette_1.ToolPalette).toSelf().inSingletonScope();
bind(types_1.GLSP_TYPES.IDiagramUIExtension).toService(tool_palette_1.ToolPalette);
bind(lib_1.TYPES.IUIExtension).toService(tool_palette_1.ToolPalette);
bind(lib_1.TYPES.IActionHandlerInitializer).to(tool_palette_1.ToolPaletteActionHandler);

@@ -28,0 +27,0 @@ });

@@ -1,9 +0,6 @@

import { Action, IActionDispatcherProvider, ICommand, ILogger, ViewerOptions } from "sprotty/lib";
import { BaseDiagramUIExtension } from "../../base/diagram-ui-extension/diagram-ui-extension";
import { SelfInitializingActionHandler } from "../../base/diagram-ui-extension/diagram-ui-extension-registry";
import { AbstractUIExtension, Action, IActionDispatcher, ICommand, SModelRoot } from "sprotty/lib";
import { SelfInitializingActionHandler } from "../../base/tool-manager/tool-manager-action-handler";
import { Operation } from "../operation/set-operations";
export declare class ToolPalette extends BaseDiagramUIExtension {
protected options: ViewerOptions;
protected actionDispatcherProvider: IActionDispatcherProvider;
protected logger: ILogger;
export declare class ToolPalette extends AbstractUIExtension {
protected readonly actionDispatcher: IActionDispatcher;
static readonly ID = "glsp_tool_palette";

@@ -15,5 +12,6 @@ readonly id = "glsp_tool_palette";

protected defaultToolsButton: HTMLElement;
constructor(options: ViewerOptions, actionDispatcherProvider: IActionDispatcherProvider, logger: ILogger);
modelRootId: string;
initialize(): boolean;
protected createUIElements(): void;
protected initializeContents(containerElement: HTMLElement): void;
protected onBeforeShow(containerElement: HTMLElement, root: Readonly<SModelRoot>): void;
protected createBody(): void;

@@ -20,0 +18,0 @@ protected createHeader(): void;

@@ -24,5 +24,2 @@ "use strict";

};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
var __read = (this && this.__read) || function (o, n) {

@@ -66,4 +63,3 @@ var m = typeof Symbol === "function" && o[Symbol.iterator];

var lib_1 = require("sprotty/lib");
var diagram_ui_extension_1 = require("../../base/diagram-ui-extension/diagram-ui-extension");
var diagram_ui_extension_registry_1 = require("../../base/diagram-ui-extension/diagram-ui-extension-registry");
var tool_manager_action_handler_1 = require("../../base/tool-manager/tool-manager-action-handler");
var set_operations_1 = require("../operation/set-operations");

@@ -76,7 +72,4 @@ var creation_tool_1 = require("../tools/creation-tool");

__extends(ToolPalette, _super);
function ToolPalette(options, actionDispatcherProvider, logger) {
var _this = _super.call(this, options, actionDispatcherProvider, logger) || this;
_this.options = options;
_this.actionDispatcherProvider = actionDispatcherProvider;
_this.logger = logger;
function ToolPalette() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.id = ToolPalette_1.ID;

@@ -93,6 +86,9 @@ _this.containerClass = "tool-palette";

};
ToolPalette.prototype.createUIElements = function () {
ToolPalette.prototype.initializeContents = function (containerElement) {
this.createHeader();
this.createBody();
};
ToolPalette.prototype.onBeforeShow = function (containerElement, root) {
this.modelRootId = root.id;
};
ToolPalette.prototype.createBody = function () {

@@ -148,4 +144,4 @@ var _this = this;

validateActionButton.onclick = function (ev) {
var modelIds = ["sprotty"];
_this.executeAction(new validate_1.RequestMarkersAction(modelIds));
var modelIds = [_this.modelRootId];
_this.actionDispatcher.dispatch(new validate_1.RequestMarkersAction(modelIds));
};

@@ -167,3 +163,3 @@ headerTools.appendChild(validateActionButton);

var action = toolId ? new lib_1.EnableToolsAction([toolId]) : new lib_1.EnableDefaultToolsAction();
_this.executeAction(action);
_this.actionDispatcher.dispatch(action);
_this.changeActiveButton(button);

@@ -191,11 +187,11 @@ _this.restoreFocus();

ToolPalette.ID = "glsp_tool_palette";
__decorate([
inversify_1.inject(lib_1.TYPES.IActionDispatcher),
__metadata("design:type", Object)
], ToolPalette.prototype, "actionDispatcher", void 0);
ToolPalette = ToolPalette_1 = __decorate([
inversify_1.injectable(),
__param(0, inversify_1.inject(lib_1.TYPES.ViewerOptions)),
__param(1, inversify_1.inject(lib_1.TYPES.IActionDispatcherProvider)),
__param(2, inversify_1.inject(lib_1.TYPES.ILogger)),
__metadata("design:paramtypes", [Object, Function, Object])
inversify_1.injectable()
], ToolPalette);
return ToolPalette;
}(diagram_ui_extension_1.BaseDiagramUIExtension));
}(lib_1.AbstractUIExtension));
exports.ToolPalette = ToolPalette;

@@ -239,3 +235,3 @@ function createIcon(cssClasses) {

this.toolPalette.setOperations(action.operations);
return new diagram_ui_extension_registry_1.ShowDiagramUIExtensionAction(ToolPalette.ID, []);
return new lib_1.SetUIExtensionVisibilityAction(ToolPalette.ID, true);
}

@@ -254,4 +250,4 @@ else if (action instanceof lib_1.EnableDefaultToolsAction) {

return ToolPaletteActionHandler;
}(diagram_ui_extension_registry_1.SelfInitializingActionHandler));
}(tool_manager_action_handler_1.SelfInitializingActionHandler));
exports.ToolPaletteActionHandler = ToolPaletteActionHandler;
//# sourceMappingURL=tool-palette.js.map

@@ -1,3 +0,5 @@

import { Action, KeyTool, MouseTool, SModelElement, Tool } from "sprotty/lib";
import { SelectionTracker } from "../select/selection-tracker";
import { Action, KeyTool, MouseListener, SModelElement, SModelRoot, Tool } from "sprotty/lib";
import { GLSPViewerOptions } from "../../base/views/viewer-options";
import { IMouseTool } from "../mouse-tool/mouse-tool";
import { SelectionListener, SelectionService } from "../select/selection-service";
import { FeedbackMoveMouseListener } from "../tool-feedback/change-bounds-tool-feedback";

@@ -19,5 +21,7 @@ import { IFeedbackActionDispatcher } from "../tool-feedback/feedback-action-dispatcher";

export declare class ChangeBoundsTool implements Tool {
protected mouseTool: MouseTool;
protected selectionService: SelectionService;
protected mouseTool: IMouseTool;
protected keyTool: KeyTool;
protected feedbackDispatcher: IFeedbackActionDispatcher;
protected opts: GLSPViewerOptions;
static ID: string;

@@ -27,4 +31,3 @@ readonly id: string;

protected changeBoundsListener: ChangeBoundsListener;
protected selectionTracker: SelectionTracker;
constructor(mouseTool: MouseTool, keyTool: KeyTool, feedbackDispatcher: IFeedbackActionDispatcher);
constructor(selectionService: SelectionService, mouseTool: IMouseTool, keyTool: KeyTool, feedbackDispatcher: IFeedbackActionDispatcher, opts: GLSPViewerOptions);
enable(): void;

@@ -34,3 +37,3 @@ disable(): void;

}
declare class ChangeBoundsListener extends SelectionTracker {
declare class ChangeBoundsListener extends MouseListener implements SelectionListener {
protected tool: ChangeBoundsTool;

@@ -45,6 +48,8 @@ private lastDragPosition;

mouseUp(target: SModelElement, event: MouseEvent): Action[];
keyDown(element: SModelElement, event: KeyboardEvent): Action[];
selectionChanged(root: SModelRoot, selectedElements: string[]): void;
private setActiveResizeElement;
private isActiveResizeElement;
private initPosition;
private updatePosition;
private reset;
private resetPosition;

@@ -51,0 +56,0 @@ private hasPositionDelta;

@@ -27,2 +27,12 @@ "use strict";

};
var __values = (this && this.__values) || function (o) {
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
if (m) return m.call(o);
return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
};
Object.defineProperty(exports, "__esModule", { value: true });

@@ -50,4 +60,3 @@ /********************************************************************************

var operation_actions_1 = require("../operation/operation-actions");
var model_2 = require("../reconnect/model");
var selection_tracker_1 = require("../select/selection-tracker");
var selection_service_1 = require("../select/selection-service");
var change_bounds_tool_feedback_1 = require("../tool-feedback/change-bounds-tool-feedback");

@@ -68,6 +77,8 @@ /**

var ChangeBoundsTool = /** @class */ (function () {
function ChangeBoundsTool(mouseTool, keyTool, feedbackDispatcher) {
function ChangeBoundsTool(selectionService, mouseTool, keyTool, feedbackDispatcher, opts) {
this.selectionService = selectionService;
this.mouseTool = mouseTool;
this.keyTool = keyTool;
this.feedbackDispatcher = feedbackDispatcher;
this.opts = opts;
this.id = ChangeBoundsTool_1.ID;

@@ -78,3 +89,3 @@ }

// install feedback move mouse listener for client-side move updates
this.feedbackMoveMouseListener = new change_bounds_tool_feedback_1.FeedbackMoveMouseListener();
this.feedbackMoveMouseListener = new change_bounds_tool_feedback_1.FeedbackMoveMouseListener(this.opts);
this.mouseTool.register(this.feedbackMoveMouseListener);

@@ -84,3 +95,3 @@ // instlal change bounds listener for client-side resize updates and server-side updates

this.mouseTool.register(this.changeBoundsListener);
this.keyTool.register(this.changeBoundsListener);
this.selectionService.register(this.changeBoundsListener);
this.feedbackDispatcher.registerFeedback(this, [new change_bounds_tool_feedback_1.ShowChangeBoundsToolResizeFeedbackAction]);

@@ -90,3 +101,3 @@ };

this.mouseTool.deregister(this.changeBoundsListener);
this.keyTool.deregister(this.changeBoundsListener);
this.selectionService.deregister(this.changeBoundsListener);
this.mouseTool.deregister(this.feedbackMoveMouseListener);

@@ -102,7 +113,8 @@ this.feedbackDispatcher.deregisterFeedback(this, [new change_bounds_tool_feedback_1.HideChangeBoundsToolResizeFeedbackAction]);

inversify_1.injectable(),
__param(0, inversify_1.inject(lib_1.MouseTool)),
__param(1, inversify_1.inject(lib_1.KeyTool)),
__param(2, inversify_1.inject(types_1.GLSP_TYPES.IFeedbackActionDispatcher)),
__metadata("design:paramtypes", [lib_1.MouseTool,
lib_1.KeyTool, Object])
__param(0, inversify_1.inject(types_1.GLSP_TYPES.SelectionService)),
__param(1, inversify_1.inject(types_1.GLSP_TYPES.MouseTool)),
__param(2, inversify_1.inject(lib_1.KeyTool)),
__param(3, inversify_1.inject(types_1.GLSP_TYPES.IFeedbackActionDispatcher)),
__param(4, inversify_1.inject(types_1.GLSP_TYPES.ViewerOptions)),
__metadata("design:paramtypes", [selection_service_1.SelectionService, Object, lib_1.KeyTool, Object, Object])
], ChangeBoundsTool);

@@ -129,24 +141,14 @@ return ChangeBoundsTool;

if (event.button === 0) {
var active = false;
// check if we have a resize handle (only single-selection)
if (target instanceof model_1.SResizeHandle) {
if (this.activeResizeElementId && target instanceof model_1.SResizeHandle) {
this.activeResizeHandle = target;
active = true;
}
else {
// check if we have a moveable element (multi-selection allowed)
this.tool.dispatchFeedback([new change_bounds_tool_feedback_1.HideChangeBoundsToolResizeFeedbackAction()]);
var moveableElement = lib_1.findParentByFeature(target, model_1.isBoundsAwareMoveable);
if (moveableElement) {
// only allow one element to have the element resize handles
this.activeResizeElementId = moveableElement.id;
this.tool.dispatchFeedback([new change_bounds_tool_feedback_1.ShowChangeBoundsToolResizeFeedbackAction(this.activeResizeElementId)]);
}
active = moveableElement !== undefined || this.activeResizeElementId !== undefined;
this.setActiveResizeElement(target);
}
if (active) {
if (this.activeResizeElementId) {
this.initPosition(event);
}
else {
this.resetPosition();
this.reset();
}

@@ -182,3 +184,3 @@ }

var newBounds_1 = [];
smodel_util_1.forEachElement(target, isNonRoutableSelectedBoundsAware, function (element) {
smodel_util_1.forEachElement(target, smodel_util_1.isNonRoutableSelectedBoundsAware, function (element) {
return createElementAndBounds(element).forEach(function (bounds) { return newBounds_1.push(bounds); });

@@ -193,13 +195,40 @@ });

};
ChangeBoundsListener.prototype.keyDown = function (element, event) {
var actions = [];
ChangeBoundsListener.prototype.selectionChanged = function (root, selectedElements) {
var e_1, _a;
if (this.activeResizeElementId) {
_super.prototype.keyDown.call(this, element, event);
if (this.isMultiSelection()) {
// no element should be in resize mode
this.tool.dispatchFeedback([new change_bounds_tool_feedback_1.HideChangeBoundsToolResizeFeedbackAction()]);
if (selectedElements.indexOf(this.activeResizeElementId) > -1) {
// our active element is still selected, nothing to do
return;
}
try {
// try to find some other selected element and mark that active
for (var _b = __values(selectedElements.reverse()), _c = _b.next(); !_c.done; _c = _b.next()) {
var elementId = _c.value;
var element = root.index.getById(elementId);
if (element && this.setActiveResizeElement(element)) {
return;
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_1) throw e_1.error; }
}
this.reset();
}
return actions;
};
ChangeBoundsListener.prototype.setActiveResizeElement = function (target) {
// check if we have a selected, moveable element (multi-selection allowed)
var moveableElement = lib_1.findParentByFeature(target, model_1.isBoundsAwareMoveable);
if (smodel_util_1.isSelected(moveableElement)) {
// only allow one element to have the element resize handles
this.activeResizeElementId = moveableElement.id;
this.tool.dispatchFeedback([new change_bounds_tool_feedback_1.ShowChangeBoundsToolResizeFeedbackAction(this.activeResizeElementId)]);
return true;
}
return false;
};
ChangeBoundsListener.prototype.isActiveResizeElement = function (element) {

@@ -223,2 +252,6 @@ return element !== undefined && element.id === this.activeResizeElementId;

};
ChangeBoundsListener.prototype.reset = function () {
this.tool.dispatchFeedback([new change_bounds_tool_feedback_1.HideChangeBoundsToolResizeFeedbackAction()]);
this.resetPosition();
};
ChangeBoundsListener.prototype.resetPosition = function () {

@@ -261,3 +294,3 @@ this.activeResizeHandle = undefined;

return ChangeBoundsListener;
}(selection_tracker_1.SelectionTracker));
}(lib_1.MouseListener));
function createChangeBoundsAction(element) {

@@ -293,5 +326,2 @@ if (isValidBoundChange(element, element.bounds)) {

}
function isNonRoutableSelectedBoundsAware(element) {
return lib_1.isBoundsAware(element) && smodel_util_1.isSelected(element) && !model_2.isRoutable(element);
}
//# sourceMappingURL=change-bounds-tool.js.map

@@ -1,4 +0,5 @@

import { Action, AnchorComputerRegistry, MouseTool, SModelElement, Tool } from "sprotty/lib";
import { Action, AnchorComputerRegistry, SModelElement, Tool } from "sprotty/lib";
import { IEditConfigProvider } from "../../base/edit-config/edit-config";
import { TypeAware } from "../../base/tool-manager/tool-manager-action-handler";
import { IMouseTool } from "../mouse-tool/mouse-tool";
import { FeedbackEdgeEndMovingMouseListener } from "../tool-feedback/creation-tool-feedback";

@@ -10,7 +11,7 @@ import { IFeedbackActionDispatcher } from "../tool-feedback/feedback-action-dispatcher";

export declare class NodeCreationTool implements Tool, TypeAware {
protected mouseTool: MouseTool;
protected mouseTool: IMouseTool;
protected feedbackDispatcher: IFeedbackActionDispatcher;
elementTypeId: string;
protected creationToolMouseListener: NodeCreationToolMouseListener;
constructor(mouseTool: MouseTool, feedbackDispatcher: IFeedbackActionDispatcher);
constructor(mouseTool: IMouseTool, feedbackDispatcher: IFeedbackActionDispatcher);
readonly id: string;

@@ -34,3 +35,3 @@ enable(): void;

export declare class EdgeCreationTool implements Tool, TypeAware {
protected mouseTool: MouseTool;
protected mouseTool: IMouseTool;
protected feedbackDispatcher: IFeedbackActionDispatcher;

@@ -42,3 +43,3 @@ protected anchorRegistry: AnchorComputerRegistry;

protected feedbackEndMovingMouseListener: FeedbackEdgeEndMovingMouseListener;
constructor(mouseTool: MouseTool, feedbackDispatcher: IFeedbackActionDispatcher, anchorRegistry: AnchorComputerRegistry, editConfigProvider: IEditConfigProvider);
constructor(mouseTool: IMouseTool, feedbackDispatcher: IFeedbackActionDispatcher, anchorRegistry: AnchorComputerRegistry, editConfigProvider: IEditConfigProvider);
readonly id: string;

@@ -45,0 +46,0 @@ enable(): void;

@@ -85,5 +85,5 @@ "use strict";

inversify_1.injectable(),
__param(0, inversify_1.inject(lib_1.MouseTool)),
__param(0, inversify_1.inject(types_1.GLSP_TYPES.MouseTool)),
__param(1, inversify_1.inject(types_1.GLSP_TYPES.IFeedbackActionDispatcher)),
__metadata("design:paramtypes", [lib_1.MouseTool, Object])
__metadata("design:paramtypes", [Object, Object])
], NodeCreationTool);

@@ -170,7 +170,7 @@ return NodeCreationTool;

inversify_1.injectable(),
__param(0, inversify_1.inject(lib_1.MouseTool)),
__param(0, inversify_1.inject(types_1.GLSP_TYPES.MouseTool)),
__param(1, inversify_1.inject(types_1.GLSP_TYPES.IFeedbackActionDispatcher)),
__param(2, inversify_1.inject(lib_1.AnchorComputerRegistry)),
__param(3, inversify_1.inject(types_1.GLSP_TYPES.IEditConfigProvider)),
__metadata("design:paramtypes", [lib_1.MouseTool, Object, lib_1.AnchorComputerRegistry, Object])
__metadata("design:paramtypes", [Object, Object, lib_1.AnchorComputerRegistry, Object])
], EdgeCreationTool);

@@ -177,0 +177,0 @@ return EdgeCreationTool;

@@ -1,2 +0,3 @@

import { Action, KeyListener, KeyTool, MouseListener, MouseTool, SModelElement, Tool } from "sprotty/lib";
import { Action, KeyListener, KeyTool, MouseListener, SModelElement, Tool } from "sprotty/lib";
import { IMouseTool } from "../mouse-tool/mouse-tool";
import { IFeedbackActionDispatcher } from "../tool-feedback/feedback-action-dispatcher";

@@ -22,3 +23,3 @@ /**

export declare class MouseDeleteTool implements Tool {
protected readonly mouseTool: MouseTool;
protected mouseTool: IMouseTool;
protected readonly feedbackDispatcher: IFeedbackActionDispatcher;

@@ -28,3 +29,3 @@ static ID: string;

protected deleteToolMouseListener: DeleteToolMouseListener;
constructor(mouseTool: MouseTool, feedbackDispatcher: IFeedbackActionDispatcher);
constructor(mouseTool: IMouseTool, feedbackDispatcher: IFeedbackActionDispatcher);
enable(): void;

@@ -31,0 +32,0 @@ disable(): void;

@@ -117,5 +117,5 @@ "use strict";

inversify_1.injectable(),
__param(0, inversify_1.inject(lib_1.MouseTool)),
__param(0, inversify_1.inject(types_1.GLSP_TYPES.MouseTool)),
__param(1, inversify_1.inject(types_1.GLSP_TYPES.IFeedbackActionDispatcher)),
__metadata("design:paramtypes", [lib_1.MouseTool, Object])
__metadata("design:paramtypes", [Object, Object])
], MouseDeleteTool);

@@ -122,0 +122,0 @@ return MouseDeleteTool;

@@ -1,8 +0,9 @@

import { Action, AnchorComputerRegistry, EdgeRouterRegistry, MouseTool, SModelElement, Tool } from "sprotty/lib";
import { SelectionTracker } from "../select/selection-tracker";
import { FeedbackMoveMouseListener } from "../tool-feedback/change-bounds-tool-feedback";
import { FeedbackEdgeSourceMovingMouseListener, FeedbackEdgeTargetMovingMouseListener } from "../tool-feedback/edge-edit-tool-feedback";
import { Action, AnchorComputerRegistry, EdgeRouterRegistry, MouseListener, SModelElement, SModelRoot, Tool } from "sprotty/lib";
import { IMouseTool } from "../mouse-tool/mouse-tool";
import { SelectionListener, SelectionService } from "../select/selection-service";
import { FeedbackEdgeRouteMovingMouseListener, FeedbackEdgeSourceMovingMouseListener, FeedbackEdgeTargetMovingMouseListener } from "../tool-feedback/edge-edit-tool-feedback";
import { IFeedbackActionDispatcher } from "../tool-feedback/feedback-action-dispatcher";
export declare class EdgeEditTool implements Tool {
protected mouseTool: MouseTool;
protected selectionService: SelectionService;
protected mouseTool: IMouseTool;
protected feedbackDispatcher: IFeedbackActionDispatcher;

@@ -15,5 +16,5 @@ protected anchorRegistry: AnchorComputerRegistry;

protected feedbackEdgeTargetMovingListener: FeedbackEdgeTargetMovingMouseListener;
protected feedbackMovingListener: FeedbackMoveMouseListener;
protected feedbackMovingListener: FeedbackEdgeRouteMovingMouseListener;
protected reconnectEdgeListener: ReconnectEdgeListener;
constructor(mouseTool: MouseTool, feedbackDispatcher: IFeedbackActionDispatcher, anchorRegistry: AnchorComputerRegistry, edgeRouterRegistry?: EdgeRouterRegistry | undefined);
constructor(selectionService: SelectionService, mouseTool: IMouseTool, feedbackDispatcher: IFeedbackActionDispatcher, anchorRegistry: AnchorComputerRegistry, edgeRouterRegistry?: EdgeRouterRegistry | undefined);
enable(): void;

@@ -23,3 +24,3 @@ disable(): void;

}
declare class ReconnectEdgeListener extends SelectionTracker {
declare class ReconnectEdgeListener extends MouseListener implements SelectionListener {
protected tool: EdgeEditTool;

@@ -47,2 +48,3 @@ private isMouseDown;

mouseOver(target: SModelElement, event: MouseEvent): Action[];
selectionChanged(root: Readonly<SModelRoot>, selectedElements: string[]): void;
reset(): void;

@@ -49,0 +51,0 @@ private resetData;

@@ -27,2 +27,12 @@ "use strict";

};
var __values = (this && this.__values) || function (o) {
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
if (m) return m.call(o);
return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
};
var __read = (this && this.__read) || function (o, n) {

@@ -68,5 +78,6 @@ var m = typeof Symbol === "function" && o[Symbol.iterator];

var types_1 = require("../../types");
var smodel_util_1 = require("../../utils/smodel-util");
var action_definitions_1 = require("../reconnect/action-definitions");
var model_1 = require("../reconnect/model");
var selection_tracker_1 = require("../select/selection-tracker");
var selection_service_1 = require("../select/selection-service");
var creation_tool_feedback_1 = require("../tool-feedback/creation-tool-feedback");

@@ -76,3 +87,4 @@ var cursor_feedback_1 = require("../tool-feedback/cursor-feedback");

var EdgeEditTool = /** @class */ (function () {
function EdgeEditTool(mouseTool, feedbackDispatcher, anchorRegistry, edgeRouterRegistry) {
function EdgeEditTool(selectionService, mouseTool, feedbackDispatcher, anchorRegistry, edgeRouterRegistry) {
this.selectionService = selectionService;
this.mouseTool = mouseTool;

@@ -88,2 +100,3 @@ this.feedbackDispatcher = feedbackDispatcher;

this.mouseTool.register(this.reconnectEdgeListener);
this.selectionService.register(this.reconnectEdgeListener);
// install feedback move mouse listener for client-side move updates

@@ -99,2 +112,3 @@ this.feedbackEdgeSourceMovingListener = new edge_edit_tool_feedback_1.FeedbackEdgeSourceMovingMouseListener(this.anchorRegistry);

this.reconnectEdgeListener.reset();
this.selectionService.deregister(this.reconnectEdgeListener);
this.mouseTool.deregister(this.feedbackEdgeSourceMovingListener);

@@ -112,7 +126,8 @@ this.mouseTool.deregister(this.feedbackEdgeTargetMovingListener);

inversify_1.injectable(),
__param(0, inversify_1.inject(lib_1.MouseTool)),
__param(1, inversify_1.inject(types_1.GLSP_TYPES.IFeedbackActionDispatcher)),
__param(2, inversify_1.inject(lib_1.AnchorComputerRegistry)),
__param(3, inversify_1.inject(lib_1.EdgeRouterRegistry)), __param(3, inversify_1.optional()),
__metadata("design:paramtypes", [lib_1.MouseTool, Object, lib_1.AnchorComputerRegistry,
__param(0, inversify_1.inject(types_1.GLSP_TYPES.SelectionService)),
__param(1, inversify_1.inject(types_1.GLSP_TYPES.MouseTool)),
__param(2, inversify_1.inject(types_1.GLSP_TYPES.IFeedbackActionDispatcher)),
__param(3, inversify_1.inject(lib_1.AnchorComputerRegistry)),
__param(4, inversify_1.inject(lib_1.EdgeRouterRegistry)), __param(4, inversify_1.optional()),
__metadata("design:paramtypes", [selection_service_1.SelectionService, Object, Object, lib_1.AnchorComputerRegistry,
lib_1.EdgeRouterRegistry])

@@ -131,3 +146,3 @@ ], EdgeEditTool);

ReconnectEdgeListener.prototype.isValidEdge = function (edge) {
return edge !== undefined && edge.id !== creation_tool_feedback_1.feedbackEdgeId(edge.root);
return edge !== undefined && edge.id !== creation_tool_feedback_1.feedbackEdgeId(edge.root) && smodel_util_1.isSelected(edge);
};

@@ -144,3 +159,3 @@ ReconnectEdgeListener.prototype.setEdgeSelected = function (edge) {

ReconnectEdgeListener.prototype.isEdgeSelected = function () {
return this.edge !== undefined;
return this.edge !== undefined && smodel_util_1.isSelected(this.edge);
};

@@ -181,3 +196,3 @@ ReconnectEdgeListener.prototype.setReconnectHandleSelected = function (edge, reconnectHandle) {

ReconnectEdgeListener.prototype.isReadyToReconnect = function () {
return this.isEdgeSelected() && this.isReconnecting() && this.newConnectable !== undefined;
return this.edge && this.isReconnecting() && this.newConnectable !== undefined;
};

@@ -260,2 +275,38 @@ ReconnectEdgeListener.prototype.isReadyToReroute = function () {

};
ReconnectEdgeListener.prototype.selectionChanged = function (root, selectedElements) {
var e_1, _a;
if (this.edge) {
if (selectedElements.indexOf(this.edge.id) > -1) {
// our active edge is still selected, nothing to do
return;
}
if (this.isReconnecting()) {
// we are reconnecting, so we may have clicked on a potential target
return;
}
try {
// try to find some other selected element and mark that active
for (var _b = __values(selectedElements.reverse()), _c = _b.next(); !_c.done; _c = _b.next()) {
var elementId = _c.value;
var element = root.index.getById(elementId);
if (element) {
var edge = lib_1.findParentByFeature(element, model_1.isRoutable);
if (this.isValidEdge(edge)) {
// PHASE 1: Select edge
this.setEdgeSelected(edge);
return;
}
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_1) throw e_1.error; }
}
this.reset();
}
};
ReconnectEdgeListener.prototype.reset = function () {

@@ -282,3 +333,3 @@ this.resetFeedback();

return ReconnectEdgeListener;
}(selection_tracker_1.SelectionTracker));
}(lib_1.MouseListener));
//# sourceMappingURL=edge-edit-tool.js.map

@@ -23,4 +23,7 @@ "use strict";

lib_1.configureCommand({ bind: bind, isBound: isBound }, validate_1.SetMarkersCommand);
lib_1.configureCommand({ bind: bind, isBound: isBound }, validate_1.ApplyMarkersCommand);
lib_1.configureCommand({ bind: bind, isBound: isBound }, validate_1.ClearMarkersCommand);
bind(validate_1.ValidationFeedbackEmitter).toSelf().inSingletonScope();
});
exports.default = validationModule;
//# sourceMappingURL=di.config.js.map

@@ -1,6 +0,8 @@

import { Action, Command, CommandExecutionContext, CommandResult } from "sprotty/lib";
import { Action, Command, CommandExecutionContext, CommandResult, IActionDispatcher } from "sprotty/lib";
import { Marker } from "../../utils/marker";
import { IFeedbackActionDispatcher, IFeedbackEmitter } from "../tool-feedback/feedback-action-dispatcher";
import { FeedbackCommand } from "../tool-feedback/model";
/**
* Action to retrieve markers for a model
*/
* Action to retrieve markers for a model
*/
export declare class RequestMarkersAction implements Action {

@@ -13,5 +15,26 @@ readonly elementsIDs: string[];

/**
* Feedback emitter sending actions for visualizing model validation feedback and
* re-establishing this feedback visualization after the model has been updated.
*/
export declare class ValidationFeedbackEmitter implements IFeedbackEmitter {
protected feedbackActionDispatcher: IFeedbackActionDispatcher;
protected actionDispatcher: () => Promise<IActionDispatcher>;
private registeredAction;
private constructor();
/**
* Register the action that should be emitted for visualizing validation feedback.
* @param action the action that should be emitted when the model is updated and that will visualize the model validation feedback.
*/
registerValidationFeedbackAction(action: MarkersAction): void;
}
/**
* Interface for actions processing markers
*/
export interface MarkersAction extends Action {
readonly markers: Marker[];
}
/**
* Action to set markers for a model
*/
export declare class SetMarkersAction implements Action {
export declare class SetMarkersAction implements MarkersAction {
readonly markers: Marker[];

@@ -22,17 +45,52 @@ readonly kind = "setMarkers";

/**
* Command for handling SetMarkersActions
* Command for handling `SetMarkersAction`
*/
export declare class SetMarkersCommand extends Command {
action: SetMarkersAction;
protected validationFeedbackEmitter: ValidationFeedbackEmitter;
static readonly KIND = "setMarkers";
constructor(action: SetMarkersAction);
/**
* Creates SIssueMarkers for all received markers and adds them to the respective SModelElements
* @param context Context of the command execution
*/
execute(context: CommandExecutionContext): CommandResult;
private getOrCreateSIssueMarker;
undo(context: CommandExecutionContext): CommandResult;
redo(context: CommandExecutionContext): CommandResult;
}
/**
* Action for applying makers to a model
*/
export declare class ApplyMarkersAction implements MarkersAction {
readonly markers: Marker[];
readonly kind: string;
constructor(markers: Marker[]);
}
/**
* Command for handling `ApplyMarkersAction`
*/
export declare class ApplyMarkersCommand extends FeedbackCommand {
protected action: ApplyMarkersAction;
static KIND: string;
readonly priority = 0;
constructor(action: ApplyMarkersAction);
execute(context: CommandExecutionContext): CommandResult;
undo(context: CommandExecutionContext): CommandResult;
redo(context: CommandExecutionContext): CommandResult;
}
/**
* Action for clearing makers of a model
*/
export declare class ClearMarkersAction implements MarkersAction {
readonly markers: Marker[];
readonly kind: string;
constructor(markers: Marker[]);
}
/**
* Command for handling `ClearMarkersAction`
*/
export declare class ClearMarkersCommand extends Command {
protected action: ClearMarkersAction;
static KIND: string;
constructor(action: ClearMarkersAction);
execute(context: CommandExecutionContext): CommandResult;
undo(context: CommandExecutionContext): CommandResult;
redo(context: CommandExecutionContext): CommandResult;
}
//# sourceMappingURL=validate.d.ts.map

@@ -55,6 +55,8 @@ "use strict";

var lib_1 = require("sprotty/lib");
var types_1 = require("../../types");
var marker_1 = require("../../utils/marker");
var model_1 = require("../tool-feedback/model");
/**
* Action to retrieve markers for a model
*/
* Action to retrieve markers for a model
*/
var RequestMarkersAction = /** @class */ (function () {

@@ -71,2 +73,40 @@ function RequestMarkersAction(elementsIDs) {

/**
* Feedback emitter sending actions for visualizing model validation feedback and
* re-establishing this feedback visualization after the model has been updated.
*/
var ValidationFeedbackEmitter = /** @class */ (function () {
function ValidationFeedbackEmitter() {
}
/**
* Register the action that should be emitted for visualizing validation feedback.
* @param action the action that should be emitted when the model is updated and that will visualize the model validation feedback.
*/
ValidationFeedbackEmitter.prototype.registerValidationFeedbackAction = function (action) {
// De-register old action responsible for applying markers and re-applying them when the model is updated
this.feedbackActionDispatcher.deregisterFeedback(this, []);
// Clear existing markers
if (this.registeredAction !== undefined) {
var clearMarkersAction_1 = new ClearMarkersAction(this.registeredAction.markers);
this.actionDispatcher().then(function (dispatcher) { return dispatcher.dispatch(clearMarkersAction_1); });
}
// Register new action responsible for applying markers and re-applying them when the model is updated
this.feedbackActionDispatcher.registerFeedback(this, [action]);
this.registeredAction = action;
};
__decorate([
inversify_1.inject(types_1.GLSP_TYPES.IFeedbackActionDispatcher),
__metadata("design:type", Object)
], ValidationFeedbackEmitter.prototype, "feedbackActionDispatcher", void 0);
__decorate([
inversify_1.inject(lib_1.TYPES.IActionDispatcherProvider),
__metadata("design:type", Function)
], ValidationFeedbackEmitter.prototype, "actionDispatcher", void 0);
ValidationFeedbackEmitter = __decorate([
inversify_1.injectable(),
__metadata("design:paramtypes", [])
], ValidationFeedbackEmitter);
return ValidationFeedbackEmitter;
}());
exports.ValidationFeedbackEmitter = ValidationFeedbackEmitter;
/**
* Action to set markers for a model

@@ -83,3 +123,3 @@ */

/**
* Command for handling SetMarkersActions
* Command for handling `SetMarkersAction`
*/

@@ -93,7 +133,54 @@ var SetMarkersCommand = /** @class */ (function (_super) {

}
/**
* Creates SIssueMarkers for all received markers and adds them to the respective SModelElements
* @param context Context of the command execution
*/
SetMarkersCommand.prototype.execute = function (context) {
var markers = this.action.markers;
var applyMarkersAction = new ApplyMarkersAction(markers);
this.validationFeedbackEmitter.registerValidationFeedbackAction(applyMarkersAction);
return context.root;
};
SetMarkersCommand.prototype.undo = function (context) {
return context.root;
};
SetMarkersCommand.prototype.redo = function (context) {
return this.execute(context);
};
SetMarkersCommand.KIND = 'setMarkers';
__decorate([
inversify_1.inject(ValidationFeedbackEmitter),
__metadata("design:type", ValidationFeedbackEmitter)
], SetMarkersCommand.prototype, "validationFeedbackEmitter", void 0);
SetMarkersCommand = __decorate([
inversify_1.injectable(),
__param(0, inversify_1.inject(lib_1.TYPES.Action)),
__metadata("design:paramtypes", [SetMarkersAction])
], SetMarkersCommand);
return SetMarkersCommand;
}(lib_1.Command));
exports.SetMarkersCommand = SetMarkersCommand;
/**
* Action for applying makers to a model
*/
var ApplyMarkersAction = /** @class */ (function () {
function ApplyMarkersAction(markers) {
this.markers = markers;
this.kind = ApplyMarkersCommand.KIND;
}
ApplyMarkersAction = __decorate([
inversify_1.injectable(),
__metadata("design:paramtypes", [Array])
], ApplyMarkersAction);
return ApplyMarkersAction;
}());
exports.ApplyMarkersAction = ApplyMarkersAction;
/**
* Command for handling `ApplyMarkersAction`
*/
var ApplyMarkersCommand = /** @class */ (function (_super) {
__extends(ApplyMarkersCommand, _super);
function ApplyMarkersCommand(action) {
var _this = _super.call(this) || this;
_this.action = action;
_this.priority = 0;
return _this;
}
ApplyMarkersCommand.prototype.execute = function (context) {
var e_1, _a;

@@ -106,3 +193,3 @@ var markers = this.action.markers;

if (modelElement instanceof lib_1.SParentElement) {
var issueMarker = this.getOrCreateSIssueMarker(modelElement);
var issueMarker = getOrCreateSIssueMarker(modelElement);
var issue = createSIssue(marker);

@@ -122,30 +209,113 @@ issueMarker.issues.push(issue);

};
SetMarkersCommand.prototype.getOrCreateSIssueMarker = function (modelElement) {
var e_2, _a;
var issueMarker;
try {
for (var _b = __values(modelElement.children), _c = _b.next(); !_c.done; _c = _b.next()) {
var child = _c.value;
if (child instanceof lib_1.SIssueMarker) {
issueMarker = child;
}
ApplyMarkersCommand.prototype.undo = function (context) {
return context.root;
};
ApplyMarkersCommand.prototype.redo = function (context) {
return this.execute(context);
};
ApplyMarkersCommand.KIND = "applyMarkers";
ApplyMarkersCommand = __decorate([
inversify_1.injectable(),
__param(0, inversify_1.inject(lib_1.TYPES.Action)),
__metadata("design:paramtypes", [ApplyMarkersAction])
], ApplyMarkersCommand);
return ApplyMarkersCommand;
}(model_1.FeedbackCommand));
exports.ApplyMarkersCommand = ApplyMarkersCommand;
/**
* Retrieves the `SIssueMarker` contained by the provided model element as
* direct child or a newly instantiated `SIssueMarker` if no child
* `SIssueMarker` exists.
* @param modelElement for which the `SIssueMarker` should be retrieved or created.
* @returns the child `SIssueMarker` or a new `SIssueMarker` if no such child exists.
*/
function getOrCreateSIssueMarker(modelElement) {
var issueMarker;
issueMarker = getSIssueMarker(modelElement);
if (issueMarker === undefined) {
issueMarker = new lib_1.SIssueMarker();
issueMarker.type = "marker";
issueMarker.issues = new Array();
modelElement.add(issueMarker);
}
return issueMarker;
}
/**
* Retrieves the `SIssueMarker` contained by the provided model element as
* direct child or `undefined` if such an `SIssueMarker` does not exist.
* @param modelElement for which the `SIssueMarker` should be retrieved.
* @returns the child `SIssueMarker` or `undefined` if no such child exists.
*/
function getSIssueMarker(modelElement) {
var e_2, _a;
var issueMarker;
try {
for (var _b = __values(modelElement.children), _c = _b.next(); !_c.done; _c = _b.next()) {
var child = _c.value;
if (child instanceof lib_1.SIssueMarker) {
issueMarker = child;
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_2) throw e_2.error; }
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
if (issueMarker === undefined) {
issueMarker = new lib_1.SIssueMarker();
issueMarker.type = "marker";
issueMarker.issues = new Array();
modelElement.add(issueMarker);
finally { if (e_2) throw e_2.error; }
}
return issueMarker;
}
/**
* Creates an `SIssue` with `severity` and `message` set according to
* the `kind` and `description` of the provided `Marker`.
* @param marker `Marker` for that an `SIssue` should be created.
* @returns the created `SIssue`.
*/
function createSIssue(marker) {
var issue = new lib_1.SIssue();
issue.message = marker.description;
switch (marker.kind) {
case marker_1.MarkerKind.ERROR: {
issue.severity = 'error';
break;
}
return issueMarker;
};
SetMarkersCommand.prototype.undo = function (context) {
var e_3, _a, e_4, _b;
case marker_1.MarkerKind.INFO: {
issue.severity = 'info';
break;
}
case marker_1.MarkerKind.WARNING: {
issue.severity = 'warning';
break;
}
}
return issue;
}
/**
* Action for clearing makers of a model
*/
var ClearMarkersAction = /** @class */ (function () {
function ClearMarkersAction(markers) {
this.markers = markers;
this.kind = ClearMarkersCommand.KIND;
}
ClearMarkersAction = __decorate([
inversify_1.injectable(),
__metadata("design:paramtypes", [Array])
], ClearMarkersAction);
return ClearMarkersAction;
}());
exports.ClearMarkersAction = ClearMarkersAction;
/**
* Command for handling `ClearMarkersAction`
*/
var ClearMarkersCommand = /** @class */ (function (_super) {
__extends(ClearMarkersCommand, _super);
function ClearMarkersCommand(action) {
var _this = _super.call(this) || this;
_this.action = action;
return _this;
}
ClearMarkersCommand.prototype.execute = function (context) {
var e_3, _a;
var markers = this.action.markers;

@@ -157,24 +327,13 @@ try {

if (modelElement instanceof lib_1.SParentElement) {
try {
for (var _c = __values(modelElement.children), _d = _c.next(); !_d.done; _d = _c.next()) {
var child = _d.value;
if (child instanceof lib_1.SIssueMarker) {
for (var index = 0; index < child.issues.length; ++index) {
var issue = child.issues[index];
if (issue.message === marker.description) {
child.issues.splice(index--, 1);
}
}
if (child.issues.length === 0) {
modelElement.remove(child);
}
var issueMarker = getSIssueMarker(modelElement);
if (issueMarker !== undefined) {
for (var index = 0; index < issueMarker.issues.length; ++index) {
var issue = issueMarker.issues[index];
if (issue.message === marker.description) {
issueMarker.issues.splice(index--, 1);
}
}
}
catch (e_4_1) { e_4 = { error: e_4_1 }; }
finally {
try {
if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
if (issueMarker.issues.length === 0) {
modelElement.remove(issueMarker);
}
finally { if (e_4) throw e_4.error; }
}

@@ -193,33 +352,17 @@ }

};
SetMarkersCommand.prototype.redo = function (context) {
ClearMarkersCommand.prototype.undo = function (context) {
return context.root;
};
ClearMarkersCommand.prototype.redo = function (context) {
return this.execute(context);
};
SetMarkersCommand.KIND = 'setMarkers';
SetMarkersCommand = __decorate([
ClearMarkersCommand.KIND = "clearMarkers";
ClearMarkersCommand = __decorate([
inversify_1.injectable(),
__param(0, inversify_1.inject(lib_1.TYPES.Action)),
__metadata("design:paramtypes", [SetMarkersAction])
], SetMarkersCommand);
return SetMarkersCommand;
__metadata("design:paramtypes", [ClearMarkersAction])
], ClearMarkersCommand);
return ClearMarkersCommand;
}(lib_1.Command));
exports.SetMarkersCommand = SetMarkersCommand;
function createSIssue(marker) {
var issue = new lib_1.SIssue();
issue.message = marker.description;
switch (marker.kind) {
case marker_1.MarkerKind.ERROR: {
issue.severity = 'error';
break;
}
case marker_1.MarkerKind.INFO: {
issue.severity = 'info';
break;
}
case marker_1.MarkerKind.WARNING: {
issue.severity = 'warning';
break;
}
}
return issue;
}
exports.ClearMarkersCommand = ClearMarkersCommand;
//# sourceMappingURL=validate.js.map

@@ -17,7 +17,11 @@ /********************************************************************************

import defaultGLSPModule from "./base/di.config";
import commandPaletteModule from "./features/command-palette/di.config";
import glspCommandPaletteModule from "./features/command-palette/di.config";
import glspEditLabelValidationModule from "./features/edit-label-validation/di.config";
import executeModule from "./features/execute/di.config";
import modelHintsModule from "./features/hints/di.config";
import layoutCommandsModule from "./features/layout/di.config";
import glspMouseToolModule from "./features/mouse-tool/di.config";
import requestResponseModule from "./features/request-response/di.config";
import saveModule from "./features/save/di.config";
import glspSelectModule from "./features/select/di.config";
import toolFeedbackModule from "./features/tool-feedback/di.config";

@@ -27,11 +31,10 @@ import paletteModule from "./features/tool-palette/di.config";

export * from 'sprotty/lib';
export * from './base/command-stack';
export * from './base/diagram-ui-extension/diagram-ui-extension';
export * from './base/edit-config/edit-config';
export * from './model-source/websocket-diagram-server';
export * from './base/model/update-model-command';
export * from './base/tool-manager/tool-manager-action-handler';
export * from './base/views/viewer-options';
export * from './features/change-bounds/model';
export * from './features/command-palette/action-definitions';
export * from './features/command-palette/action-provider';
export * from './features/command-palette/command-palette';
export * from './features/execute/execute-command';

@@ -41,3 +44,3 @@ export * from './features/execute/model';

export * from './features/hints/type-hints-action-initializer';
export * from './features/nameable/model';
export * from './features/mouse-tool/di.config';
export * from './features/operation/operation-actions';

@@ -49,2 +52,3 @@ export * from './features/operation/set-operations';

export * from './features/save/save';
export * from './features/select/di.config';
export * from './features/tool-feedback/creation-tool-feedback';

@@ -58,2 +62,3 @@ export * from './features/tool-feedback/model';

export * from './features/validation/validate';
export * from './features/layout/layout-commands';
export * from './lib/model';

@@ -65,3 +70,4 @@ export * from './types';

export * from './utils/viewpoint-util';
export { validationModule, saveModule, executeModule, paletteModule, toolFeedbackModule, defaultGLSPModule, modelHintsModule, commandPaletteModule, requestResponseModule };
export { validationModule, saveModule, executeModule, paletteModule, toolFeedbackModule, defaultGLSPModule, modelHintsModule, glspCommandPaletteModule, requestResponseModule, //
glspSelectModule, glspMouseToolModule, layoutCommandsModule, glspEditLabelValidationModule };
//# sourceMappingURL=index.d.ts.map

@@ -24,27 +24,34 @@ "use strict";

var di_config_2 = require("./features/command-palette/di.config");
exports.commandPaletteModule = di_config_2.default;
var di_config_3 = require("./features/execute/di.config");
exports.executeModule = di_config_3.default;
var di_config_4 = require("./features/hints/di.config");
exports.modelHintsModule = di_config_4.default;
var di_config_5 = require("./features/request-response/di.config");
exports.requestResponseModule = di_config_5.default;
var di_config_6 = require("./features/save/di.config");
exports.saveModule = di_config_6.default;
var di_config_7 = require("./features/tool-feedback/di.config");
exports.toolFeedbackModule = di_config_7.default;
var di_config_8 = require("./features/tool-palette/di.config");
exports.paletteModule = di_config_8.default;
var di_config_9 = require("./features/validation/di.config");
exports.validationModule = di_config_9.default;
exports.glspCommandPaletteModule = di_config_2.default;
var di_config_3 = require("./features/edit-label-validation/di.config");
exports.glspEditLabelValidationModule = di_config_3.default;
var di_config_4 = require("./features/execute/di.config");
exports.executeModule = di_config_4.default;
var di_config_5 = require("./features/hints/di.config");
exports.modelHintsModule = di_config_5.default;
var di_config_6 = require("./features/layout/di.config");
exports.layoutCommandsModule = di_config_6.default;
var di_config_7 = require("./features/mouse-tool/di.config");
exports.glspMouseToolModule = di_config_7.default;
var di_config_8 = require("./features/request-response/di.config");
exports.requestResponseModule = di_config_8.default;
var di_config_9 = require("./features/save/di.config");
exports.saveModule = di_config_9.default;
var di_config_10 = require("./features/select/di.config");
exports.glspSelectModule = di_config_10.default;
var di_config_11 = require("./features/tool-feedback/di.config");
exports.toolFeedbackModule = di_config_11.default;
var di_config_12 = require("./features/tool-palette/di.config");
exports.paletteModule = di_config_12.default;
var di_config_13 = require("./features/validation/di.config");
exports.validationModule = di_config_13.default;
__export(require("sprotty/lib"));
__export(require("./base/command-stack"));
__export(require("./base/diagram-ui-extension/diagram-ui-extension"));
__export(require("./base/edit-config/edit-config"));
__export(require("./model-source/websocket-diagram-server"));
__export(require("./base/model/update-model-command"));
__export(require("./base/tool-manager/tool-manager-action-handler"));
__export(require("./base/views/viewer-options"));
__export(require("./features/change-bounds/model"));
__export(require("./features/command-palette/action-definitions"));
__export(require("./features/command-palette/action-provider"));
__export(require("./features/command-palette/command-palette"));
__export(require("./features/execute/execute-command"));

@@ -54,3 +61,3 @@ __export(require("./features/execute/model"));

__export(require("./features/hints/type-hints-action-initializer"));
__export(require("./features/nameable/model"));
__export(require("./features/mouse-tool/di.config"));
__export(require("./features/operation/operation-actions"));

@@ -62,2 +69,3 @@ __export(require("./features/operation/set-operations"));

__export(require("./features/save/save"));
__export(require("./features/select/di.config"));
__export(require("./features/tool-feedback/creation-tool-feedback"));

@@ -71,2 +79,3 @@ __export(require("./features/tool-feedback/model"));

__export(require("./features/validation/validate"));
__export(require("./features/layout/layout-commands"));
__export(require("./lib/model"));

@@ -73,0 +82,0 @@ __export(require("./types"));

@@ -17,12 +17,13 @@ /********************************************************************************

export declare const GLSP_TYPES: {
ICommandPaletteActionProvider: symbol;
ICommandPaletteActionProviderRegistry: symbol;
IFeedbackActionDispatcher: symbol;
IToolFactory: symbol;
IReadonlyModelAccessProvider: symbol;
IDiagramUIExtension: symbol;
DiagramUIExtensionRegistry: symbol;
IEditConfigProvider: symbol;
RequestResponseSupport: symbol;
SelectionService: symbol;
SelectionListener: symbol;
SModelRootListener: symbol;
MouseTool: symbol;
ViewerOptions: symbol;
};
//# sourceMappingURL=types.d.ts.map

@@ -19,12 +19,13 @@ "use strict";

exports.GLSP_TYPES = {
ICommandPaletteActionProvider: Symbol.for("ICommandPaletteActionProvider"),
ICommandPaletteActionProviderRegistry: Symbol.for("ICommandPaletteActionProviderRegistry"),
IFeedbackActionDispatcher: Symbol.for("IFeedbackActionDispatcher"),
IToolFactory: Symbol.for("Factory<Tool>"),
IReadonlyModelAccessProvider: Symbol.for("IReadonlyModelAccessProvider"),
IDiagramUIExtension: Symbol.for("IDiagramUIExtension"),
DiagramUIExtensionRegistry: Symbol.for("DiagramUIExtensionRegistry"),
IEditConfigProvider: Symbol.for("IEditConfigProvider"),
RequestResponseSupport: Symbol.for("RequestResponseSupport")
RequestResponseSupport: Symbol.for("RequestResponseSupport"),
SelectionService: Symbol.for("SelectionService"),
SelectionListener: Symbol.for("SelectionListener"),
SModelRootListener: Symbol.for("SModelRootListener"),
MouseTool: Symbol.for("MouseTool"),
ViewerOptions: Symbol.for("ViewerOptions")
};
//# sourceMappingURL=types.js.map

@@ -16,11 +16,10 @@ /********************************************************************************

********************************************************************************/
import { BoundsAware, Selectable, SModelElement, SParentElement } from "sprotty/lib";
import { NodeEditConfig } from "../base/edit-config/edit-config";
import { Selectable } from "sprotty/lib";
import { SModelElement } from "sprotty/lib";
import { SParentElement } from "sprotty/lib";
export declare function getIndex(element: SModelElement): import("sprotty").SModelIndex<SModelElement>;
export declare function forEachElement<T>(element: SModelElement, predicate: (element: SModelElement) => element is SModelElement & T, runnable: (element: SModelElement & T) => void): void;
export declare function getMatchingElements<T>(element: SModelElement, predicate: (element: SModelElement) => element is SModelElement & T): (SModelElement & T)[];
export declare function hasSelectedElements(element: SModelElement): boolean;
export declare function getSelectedElementCount(element: SModelElement): number;
export declare function isSelected(element: SModelElement): element is SModelElement & Selectable;
export declare function isSelected(element: SModelElement | undefined): element is SModelElement & Selectable;
export declare function isNotUndefined<T>(element: T | undefined): element is T;

@@ -30,2 +29,4 @@ export declare function addCssClasses(root: SModelElement, cssClasses: string[]): void;

export declare function isContainmentAllowed(element: SModelElement, containableElementTypeId: string): element is SParentElement & NodeEditConfig;
export declare function isNonRoutableSelectedBoundsAware(element: SModelElement): element is SelectableBoundsAware;
export declare type SelectableBoundsAware = SModelElement & BoundsAware & Selectable;
//# sourceMappingURL=smodel-util.d.ts.map

@@ -13,4 +13,20 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
/********************************************************************************
* Copyright (c) 2019 EclipseSource and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
var lib_1 = require("sprotty/lib");
var edit_config_1 = require("../base/edit-config/edit-config");
var lib_1 = require("sprotty/lib");
var model_1 = require("../features/reconnect/model");
function getIndex(element) {

@@ -26,2 +42,8 @@ return element.root.index;

exports.forEachElement = forEachElement;
function getMatchingElements(element, predicate) {
var matching = [];
forEachElement(element, predicate, function (item) { return matching.push(item); });
return matching;
}
exports.getMatchingElements = getMatchingElements;
function hasSelectedElements(element) {

@@ -40,3 +62,3 @@ return getSelectedElementCount(element) > 0;

function isSelected(element) {
return lib_1.isSelectable(element) && element.selected;
return isNotUndefined(element) && lib_1.isSelectable(element) && element.selected;
}

@@ -97,2 +119,6 @@ exports.isSelected = isSelected;

exports.isContainmentAllowed = isContainmentAllowed;
function isNonRoutableSelectedBoundsAware(element) {
return lib_1.isBoundsAware(element) && isSelected(element) && !model_1.isRoutable(element);
}
exports.isNonRoutableSelectedBoundsAware = isNonRoutableSelectedBoundsAware;
//# sourceMappingURL=smodel-util.js.map
{
"name": "@glsp/sprotty-client",
"version": "0.1.1",
"version": "0.2.0-next.0185f7f2",
"description": "A sprotty-based client for GLSP",

@@ -31,3 +31,3 @@ "license": "(EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0)",

"autocompleter": "^4.0.2",
"sprotty": "^0.6.0"
"sprotty": "0.7.0-next.cea0e2b"
},

@@ -34,0 +34,0 @@ "devDependencies": {

@@ -22,31 +22,8 @@ /********************************************************************************

import { GLSP_TYPES } from "../types";
import { GLSPCommandStack, IReadonlyModelAccess } from "./command-stack";
import {
DiagramUIExtensionActionHandlerInitializer,
DiagramUIExtensionRegistry
} from "./diagram-ui-extension/diagram-ui-extension-registry";
import { FeedbackAwareUpdateModelCommand } from "./model/update-model-command";
import { FeedbackAwareUpdateModelCommand, SetModelActionHandler } from "./model/update-model-command";
import { createToolFactory, ToolManagerActionHandler } from "./tool-manager/tool-manager-action-handler";
import { defaultGLSPViewerOptions, GLSPViewerOptions } from "./views/viewer-options";
const defaultGLSPModule = new ContainerModule((bind, unbind, isBound, rebind) => {
// GLSP Commandstack initialization ------------------------------------
if (isBound(TYPES.ICommandStack)) {
unbind(TYPES.ICommandStack);
}
bind(GLSPCommandStack).toSelf().inSingletonScope();
bind(TYPES.ICommandStack).toService(GLSPCommandStack);
bind(GLSP_TYPES.IReadonlyModelAccessProvider).toProvider<IReadonlyModelAccess>((context) => {
return () => {
return new Promise<IReadonlyModelAccess>((resolve) => {
resolve(context.container.get<IReadonlyModelAccess>(TYPES.ICommandStack));
});
};
});
// DiagramUIExtension registry initialization ------------------------------------
bind(GLSP_TYPES.DiagramUIExtensionRegistry).to(DiagramUIExtensionRegistry).inSingletonScope();
bind(TYPES.IActionHandlerInitializer).to(DiagramUIExtensionActionHandlerInitializer);
// Tool manager initialization ------------------------------------
bind(TYPES.IActionHandlerInitializer).to(ToolManagerActionHandler);

@@ -57,4 +34,13 @@ bind(GLSP_TYPES.IToolFactory).toFactory<Tool>((createToolFactory()));

configureCommand({ bind, isBound }, FeedbackAwareUpdateModelCommand);
bind(TYPES.IActionHandlerInitializer).to(SetModelActionHandler);
bind<GLSPViewerOptions>(GLSP_TYPES.ViewerOptions).toConstantValue(defaultGLSPViewerOptions());
if (isBound(TYPES.ViewerOptions)) {
rebind(TYPES.ViewerOptions).toService(GLSP_TYPES.ViewerOptions);
} else {
bind(TYPES.ViewerOptions).toService(GLSP_TYPES.ViewerOptions);
}
});
export default defaultGLSPModule;

@@ -16,4 +16,5 @@ /********************************************************************************

********************************************************************************/
import { inject, injectable, optional } from "inversify";
import { inject, injectable, multiInject, optional } from "inversify";
import {
Action,
ActionHandlerRegistry,

@@ -25,2 +26,4 @@ Command,

ILogger,
SetModelAction,
SetModelCommand,
SModelRoot,

@@ -34,3 +37,25 @@ TYPES

import { GLSP_TYPES } from "../../types";
import { SelfInitializingActionHandler } from "../tool-manager/tool-manager-action-handler";
/* ActionHandler that transforms a SetModelAction into an (feedback-aware) UpdateModelAction. This can be done because in sprotty
* UpdateModel behaves the same as SetModel if no model is present yet.*/
export class SetModelActionHandler extends SelfInitializingActionHandler {
handle(action: Action): Action | void {
if (isSetModelAction(action)) {
return new UpdateModelAction(action.newRoot, false);
}
}
handledActionKinds = [SetModelCommand.KIND];
}
export function isSetModelAction(action: Action): action is SetModelAction {
return action !== undefined && (action.kind === SetModelCommand.KIND)
&& (<SetModelAction>action).newRoot !== undefined;
}
export interface SModelRootListener {
modelRootChanged(root: Readonly<SModelRoot>): void
}
/**

@@ -45,3 +70,4 @@ * A special`UpdateModelCommand` that retrieves all registered `actions` from the `IFeedbackActionDispatcher` (if present) and applies their feedback

@inject(GLSP_TYPES.IFeedbackActionDispatcher) @optional() protected readonly feedbackActionDispatcher: IFeedbackActionDispatcher,
@inject(TYPES.ActionHandlerRegistryProvider) protected actionHandlerRegistryProvider: () => Promise<ActionHandlerRegistry>) {
@inject(TYPES.ActionHandlerRegistryProvider) protected actionHandlerRegistryProvider: () => Promise<ActionHandlerRegistry>,
@multiInject(GLSP_TYPES.SModelRootListener) @optional() protected modelRootListeners: SModelRootListener[] = []) {
super(action);

@@ -67,2 +93,3 @@ }

}
this.modelRootListeners.forEach(listener => listener.modelRootChanged(newRoot));
return super.performUpdate(oldRoot, newRoot, context);

@@ -69,0 +96,0 @@

@@ -17,3 +17,12 @@ /********************************************************************************

import { inject, injectable, interfaces } from "inversify";
import { Action, ICommand, Tool, ToolManager, TYPES } from "sprotty/lib";
import {
Action,
ActionHandlerRegistry,
IActionHandler,
IActionHandlerInitializer,
ICommand,
Tool,
ToolManager,
TYPES,
} from "sprotty/lib";

@@ -24,5 +33,14 @@ import { isSetOperationsAction, OperationKind, SetOperationsAction } from "../../features/operation/set-operations";

import { GLSP_TYPES } from "../../types";
import { SelfInitializingActionHandler } from "../diagram-ui-extension/diagram-ui-extension-registry";
@injectable()
export abstract class SelfInitializingActionHandler implements IActionHandler, IActionHandlerInitializer {
initialize(registry: ActionHandlerRegistry) {
this.handledActionKinds.forEach(kind => registry.register(kind, this));
}
abstract handle(action: Action): ICommand | Action | void;
abstract handledActionKinds: string[];
}
@injectable()

@@ -29,0 +47,0 @@ export class ToolManagerActionHandler extends SelfInitializingActionHandler {

@@ -16,6 +16,4 @@ /********************************************************************************

********************************************************************************/
import { Action } from "sprotty/lib";
import { Action, LabeledAction } from "sprotty/lib";
import { LabeledAction } from "../../base/diagram-ui-extension/diagram-ui-extension";
export class RequestCommandPaletteActions implements Action {

@@ -22,0 +20,0 @@ static readonly KIND = "requestCommandPaletteActions";

@@ -16,58 +16,34 @@ /********************************************************************************

********************************************************************************/
import { inject, injectable, multiInject, optional } from "inversify";
import { Action, CenterAction, ILogger, SelectAction, SModelElement, SModelRoot, TYPES } from "sprotty/lib";
import { inject, injectable } from "inversify";
import {
Action,
CenterAction,
ICommandPaletteActionProvider,
ILogger,
isNameable,
LabeledAction,
name,
SelectAction,
SModelElement,
TYPES,
} from "sprotty/lib";
import { toArray } from "sprotty/lib/utils/iterable";
import { IReadonlyModelAccessProvider } from "../../base/command-stack";
import { LabeledAction } from "../../base/diagram-ui-extension/diagram-ui-extension";
import { GLSP_TYPES } from "../../types";
import { isNameable, name } from "../nameable/model";
import { isSelected } from "../../utils/smodel-util";
import { RequestResponseSupport } from "../request-response/support";
import { isSetCommandPaletteActionsAction, RequestCommandPaletteActions } from "./action-definitions";
export interface ICommandPaletteActionProvider {
getActions(selectedElements: SModelElement[]): Promise<LabeledAction[]>;
}
export type ICommandPaletteActionProviderRegistry = () => Promise<ICommandPaletteActionProvider>;
@injectable()
export class CommandPaletteActionProviderRegistry implements ICommandPaletteActionProvider {
public actionProvider: ICommandPaletteActionProvider[] = [];
constructor(@multiInject(GLSP_TYPES.ICommandPaletteActionProvider) @optional() protected registeredActionProviders: ICommandPaletteActionProvider[] = []) {
for (const registeredProvider of registeredActionProviders) {
this.actionProvider.push(registeredProvider);
}
}
getActions(selectedElements: SModelElement[]): Promise<LabeledAction[]> {
const actionLists = this.actionProvider.map(provider => provider.getActions(selectedElements));
return Promise.all(actionLists).then(p => p.reduce((acc, promise) => promise !== undefined ? acc.concat(promise) : acc));
}
}
@injectable()
export class NavigationCommandPaletteActionProvider implements ICommandPaletteActionProvider {
constructor(
@inject(GLSP_TYPES.IReadonlyModelAccessProvider) protected modelAccessProvider: IReadonlyModelAccessProvider,
@inject(TYPES.ILogger) protected logger: ILogger) { }
getActions(selectedElements: SModelElement[]): Promise<LabeledAction[]> {
return this.modelAccessProvider()
.then(access => access.model)
.then(model => this.createSelectActions(model))
.catch(reason => {
this.logger.error(this, 'Could not create navigation command palette actions.', reason);
return [];
});
getActions(root: Readonly<SModelElement>): Promise<LabeledAction[]> {
return Promise.resolve(toArray(root.index.all()
.filter(isNameable)
.map(nameable => new LabeledAction(`Select ${name(nameable)}`, [new SelectAction([nameable.id]), new CenterAction([nameable.id])]))));
}
createSelectActions(modelRoot: SModelRoot): LabeledAction[] {
return toArray(modelRoot.index.all()
.filter(element => isNameable(element))
.map(nameable => new LabeledAction(`Select ${name(nameable)}`, [new SelectAction([nameable.id]), new CenterAction([nameable.id])])));
}
}

@@ -80,4 +56,4 @@

getActions(selectedElements: SModelElement[]): Promise<LabeledAction[]> {
const selectedElementIDs = selectedElements.map(e => e.id);
getActions(root: Readonly<SModelElement>): Promise<LabeledAction[]> {
const selectedElementIDs = Array.from(root.index.all().filter(isSelected).map(e => e.id));
const requestAction = new RequestCommandPaletteActions(selectedElementIDs);

@@ -84,0 +60,0 @@ const responseHandler = this.getPaletteActionsFromResponse;

@@ -21,31 +21,10 @@ /********************************************************************************

import { GLSP_TYPES } from "../../types";
import {
CommandPaletteActionProviderRegistry,
ICommandPaletteActionProvider,
NavigationCommandPaletteActionProvider,
ServerCommandPaletteActionProvider
} from "./action-provider";
import { CommandPalette, CommandPaletteKeyListener } from "./command-palette";
import { NavigationCommandPaletteActionProvider, ServerCommandPaletteActionProvider } from "./action-provider";
const commandPaletteModule = new ContainerModule((bind, unbind, isBound, rebind) => {
bind(CommandPalette).toSelf().inSingletonScope();
bind(GLSP_TYPES.IDiagramUIExtension).toService(CommandPalette);
bind(TYPES.KeyListener).to(CommandPaletteKeyListener);
bind(CommandPaletteActionProviderRegistry).toSelf().inSingletonScope();
bind(GLSP_TYPES.ICommandPaletteActionProviderRegistry).toProvider<ICommandPaletteActionProvider>((context) => {
return () => {
return new Promise<ICommandPaletteActionProvider>((resolve) => {
resolve(context.container.get<ICommandPaletteActionProvider>(CommandPaletteActionProviderRegistry));
});
};
});
bind(GLSP_TYPES.ICommandPaletteActionProvider).to(NavigationCommandPaletteActionProvider);
const glspCommandPaletteModule = new ContainerModule((bind, unbind, isBound, rebind) => {
bind(TYPES.ICommandPaletteActionProvider).to(NavigationCommandPaletteActionProvider);
bind(ServerCommandPaletteActionProvider).toSelf().inSingletonScope();
bind(GLSP_TYPES.ICommandPaletteActionProvider).to(ServerCommandPaletteActionProvider);
bind(TYPES.ICommandPaletteActionProvider).to(ServerCommandPaletteActionProvider);
});
export default commandPaletteModule;
export default glspCommandPaletteModule;

@@ -21,2 +21,3 @@ /********************************************************************************

kind = RequestTypeHintsAction.KIND;
constructor(public readonly diagramType?: string) { }
}

@@ -23,0 +24,0 @@

@@ -24,6 +24,5 @@ /********************************************************************************

SModelElementSchema,
TYPES
TYPES,
} from "sprotty/lib";
import { SelfInitializingActionHandler } from "../../base/diagram-ui-extension/diagram-ui-extension-registry";
import {

@@ -37,4 +36,5 @@ EdgeEditConfig,

NodeEditConfig,
nodeEditConfig
nodeEditConfig,
} from "../../base/edit-config/edit-config";
import { SelfInitializingActionHandler } from "../../base/tool-manager/tool-manager-action-handler";
import { GLSP_TYPES } from "../../types";

@@ -41,0 +41,0 @@ import { contains } from "../../utils/array-utils";

@@ -20,2 +20,3 @@ /********************************************************************************

Action,
Bounds,
CommandExecutionContext,

@@ -25,2 +26,3 @@ CommandResult,

findParentByFeature,
includes,
isMoveable,

@@ -37,4 +39,7 @@ isSelectable,

import { GLSPViewerOptions } from "../../base/views/viewer-options";
import { isNotUndefined } from "../../utils/smodel-util";
import { getAbsolutePosition } from "../../utils/viewpoint-util";
import { addResizeHandles, isResizeable, removeResizeHandles } from "../change-bounds/model";
import { ApplyCursorCSSFeedbackAction, CursorCSS } from "./cursor-feedback";
import { FeedbackCommand } from "./model";

@@ -99,3 +104,4 @@

lastDragPosition: Point | undefined;
hasCollided = false;
constructor(protected glspViewerOptions: GLSPViewerOptions) { super(); }
mouseDown(target: SModelElement, event: MouseEvent): Action[] {

@@ -114,2 +120,37 @@ if (event.button === 0) {

/**
* Used to return the collision target(s) or the collision chain in case of multiple selected elements
*/
getCollisionChain(target: SModelElement, element: SModelElement, dx: number, dy: number, collisionChain: SModelElement[]): SModelElement[] {
if (isMoveable(element) && isResizeable(element)) {
target.root.index.all()
.filter(candidate => isSelectable(candidate) && element.id !== candidate.id && collisionChain.indexOf(candidate) < 0)
.forEach(candidate => {
if (isMoveable(element) && isMoveable(candidate)) {
if (isResizeable(element) && isResizeable(candidate)) {
const futureBounds: Bounds = {
x: element.position.x + dx,
y: element.position.y + dy,
width: element.size.width,
height: element.size.height
};
if (isOverlappingBounds(futureBounds, candidate.bounds) && !isOverlappingBounds(element.bounds, candidate.bounds)) {
collisionChain.push(candidate);
if (candidate.selected) {
// Check what the selected candidate will collide with and add it to the chain
collisionChain.push.apply(collisionChain, this.getCollisionChain(target, candidate, dx, dy, collisionChain));
}
}
}
}
});
}
return collisionChain;
}
mouseMove(target: SModelElement, event: MouseEvent): Action[] {

@@ -123,9 +164,39 @@ const result: Action[] = [];

const zoom = viewport ? viewport.zoom : 1;
const mousePoint: Point = getAbsolutePosition(target, event);
const dx = (event.pageX - this.lastDragPosition.x) / zoom;
const dy = (event.pageY - this.lastDragPosition.y) / zoom;
const nodeMoves: ElementMove[] = [];
let willCollide: boolean = false;
let mouseOverElement: boolean = false;
const collisionOccured: boolean = false;
target.root.index.all()
.filter(element => isSelectable(element) && element.selected)
.forEach(element => {
if (isMoveable(element)) {
if (isMoveable(element) && isResizeable(element)) {
// If noElementOverlap Option is set perform collision detection
if (this.glspViewerOptions.noElementOverlap) {
// After collision the mouse is back inside the element => change cursor back to default
if (this.hasCollided && includes(element.bounds, mousePoint)) {
mouseOverElement = true;
result.push(new ApplyCursorCSSFeedbackAction(CursorCSS.DEFAULT));
}
// Get only the valid, non-slected collision targets to avoid in-selection collisions
const collisionTargets: SModelElement[] = this.getCollisionChain(target, element, dx, dy, [])
.filter(collidingElement => isSelectable(collidingElement) && !collidingElement.selected);
if (collisionTargets.length > 0) {
collisionTargets.forEach(collisionTarget => {
if (isResizeable(collisionTarget)) {
willCollide = true;
this.hasCollided = true;
result.push(new ApplyCursorCSSFeedbackAction(CursorCSS.OVERLAP_FORBIDDEN));
}
});
}
}
}
if (isMoveable(element) && !collisionOccured && ((!willCollide && !this.hasCollided) ||
(this.hasCollided && !willCollide && mouseOverElement))) {
this.hasCollided = false;
nodeMoves.push({

@@ -145,5 +216,7 @@ elementId: element.id,

this.lastDragPosition = { x: event.pageX, y: event.pageY };
if (nodeMoves.length > 0)
if (nodeMoves.length > 0 && !this.hasCollided) {
result.push(new MoveAction(nodeMoves, false));
}
}
return result;

@@ -168,1 +241,18 @@ }

}
/**
* Used to check if 1D boxes (lines) overlap
*/
export function isOverlapping1Dimension(x1: number, width1: number, x2: number, width2: number): boolean {
return x1 + width1 >= x2 && x2 + width2 >= x1;
}
/**
* Used to check if 2 bounds are overlapping
*/
export function isOverlappingBounds(bounds1: Bounds, bounds2: Bounds): boolean {
return isOverlapping1Dimension(bounds1.x, bounds1.width, bounds2.x, bounds2.width) &&
isOverlapping1Dimension(bounds1.y, bounds1.height, bounds2.y, bounds2.height);
}

@@ -23,2 +23,4 @@ /********************************************************************************

export enum CursorCSS {
DEFAULT = 'default-mode',
OVERLAP_FORBIDDEN = 'overlap-forbidden-mode',
NODE_CREATION = 'node-creation-mode',

@@ -25,0 +27,0 @@ EDGE_CREATION_SOURCE = 'edge-creation-select-source-mode',

@@ -16,10 +16,18 @@ /********************************************************************************

********************************************************************************/
import { inject, injectable } from "inversify";
import { Action, IActionDispatcher, ILogger, TYPES } from "sprotty/lib";
import { Action } from "sprotty/lib";
import { IActionDispatcher } from "sprotty/lib";
import { ILogger } from "sprotty/lib";
import { TYPES } from "sprotty/lib";
import { inject } from "inversify";
import { injectable } from "inversify";
export interface IFeedbackEmitter { }
/**
* Action dispatcher for actions that are meant to show tool feedback.
* Dispatcher for actions that are meant to show visual feedback on
* the diagram that is not part of the diagram sent from the server
* after a model update.
*
* The purpose of this action dispatcher is to re-establish the feedback
* The purpose of this dispatcher is to re-establish the feedback
* after the model has been updated or reset by the server, as this would

@@ -30,3 +38,3 @@ * overwrite the already established feedback, in case it is drawn by

* feedback. This dispatcher will then re-establish all feedback actions
* of the registered tools, whenever the `SModelRoot` has been set.
* of the registered tools, whenever the `SModelRoot` has been set or updated.
*/

@@ -40,6 +48,12 @@ export interface IFeedbackActionDispatcher {

registerFeedback(feedbackEmitter: IFeedbackEmitter, actions: Action[]): void;
/**
* Deregisters a `feedbackEmitter` from this dispatcher.
* @param feedbackEmitter the emitter sending out feedback actions.
* @param actions the actions to be sent out after deregistration.
* Deregisters a `feedbackEmitter` from this dispatcher and thereafter
* dispatches the provided `actions`.
* @param feedbackEmitter the emitter to be deregistered.
* @param actions the actions to be dispatched right after the deregistration.
* These actions do not have to be related to the actions sent out by the
* deregistered `feedbackEmitter`. The purpose of these actions typically is
* to reset the normal state of the diagram without the feedback (e.g., reset a
* CSS class that was set by a feedbackEmitter).
*/

@@ -49,3 +63,3 @@ deregisterFeedback(feedbackEmitter: IFeedbackEmitter, actions: Action[]): void;

/**
* Retrieve all currently registered `actions`
* Retrieve all `actions` sent out by currently registered `feedbackEmitter`.
*/

@@ -87,3 +101,13 @@ getRegisteredFeedback(): Action[]

getRegisteredFeedbackEmitters(action: Action) {
const result: IFeedbackEmitter[] = [];
this.feedbackEmitters.forEach((value, key) => {
if (value.find(a => a === action)) {
result.push(key);
}
}
);
return result;
}
}

@@ -21,3 +21,2 @@ /********************************************************************************

import { GLSP_TYPES } from "../../types";
import { ToolPalette, ToolPaletteActionHandler } from "./tool-palette";

@@ -27,3 +26,3 @@

bind(ToolPalette).toSelf().inSingletonScope();
bind(GLSP_TYPES.IDiagramUIExtension).toService(ToolPalette);
bind(TYPES.IUIExtension).toService(ToolPalette);
bind(TYPES.IActionHandlerInitializer).to(ToolPaletteActionHandler);

@@ -30,0 +29,0 @@ });

@@ -18,17 +18,14 @@ /********************************************************************************

import {
AbstractUIExtension,
Action,
EnableDefaultToolsAction,
EnableToolsAction,
IActionDispatcherProvider,
IActionDispatcher,
ICommand,
ILogger,
TYPES,
ViewerOptions
SetUIExtensionVisibilityAction,
SModelRoot,
TYPES
} from "sprotty/lib";
import { BaseDiagramUIExtension } from "../../base/diagram-ui-extension/diagram-ui-extension";
import {
SelfInitializingActionHandler,
ShowDiagramUIExtensionAction
} from "../../base/diagram-ui-extension/diagram-ui-extension-registry";
import { SelfInitializingActionHandler } from "../../base/tool-manager/tool-manager-action-handler";
import { isSetOperationsAction, Operation, parentGroup, SetOperationsAction } from "../operation/set-operations";

@@ -41,3 +38,4 @@ import { deriveToolId } from "../tools/creation-tool";

@injectable()
export class ToolPalette extends BaseDiagramUIExtension {
export class ToolPalette extends AbstractUIExtension {
@inject(TYPES.IActionDispatcher) protected readonly actionDispatcher: IActionDispatcher;
static readonly ID = "glsp_tool_palette";

@@ -50,9 +48,4 @@

protected defaultToolsButton: HTMLElement;
modelRootId: string;
constructor(
@inject(TYPES.ViewerOptions) protected options: ViewerOptions,
@inject(TYPES.IActionDispatcherProvider) protected actionDispatcherProvider: IActionDispatcherProvider,
@inject(TYPES.ILogger) protected logger: ILogger) {
super(options, actionDispatcherProvider, logger);
}

@@ -66,3 +59,3 @@ initialize() {

protected createUIElements(): void {
protected initializeContents(containerElement: HTMLElement): void {
this.createHeader();

@@ -72,2 +65,6 @@ this.createBody();

protected onBeforeShow(containerElement: HTMLElement, root: Readonly<SModelRoot>) {
this.modelRootId = root.id;
}
protected createBody(): void {

@@ -127,4 +124,4 @@ const bodyDiv = document.createElement("div");

validateActionButton.onclick = (ev: MouseEvent) => {
const modelIds: string[] = ["sprotty"];
this.executeAction(new RequestMarkersAction(modelIds));
const modelIds: string[] = [this.modelRootId];
this.actionDispatcher.dispatch(new RequestMarkersAction(modelIds));
};

@@ -148,3 +145,3 @@ headerTools.appendChild(validateActionButton);

const action = toolId ? new EnableToolsAction([toolId]) : new EnableDefaultToolsAction();
this.executeAction(action);
this.actionDispatcher.dispatch(action);
this.changeActiveButton(button);

@@ -211,3 +208,3 @@ this.restoreFocus();

this.toolPalette.setOperations(action.operations);
return new ShowDiagramUIExtensionAction(ToolPalette.ID, []);
return new SetUIExtensionVisibilityAction(ToolPalette.ID, true);
} else if (action instanceof EnableDefaultToolsAction) {

@@ -214,0 +211,0 @@ this.toolPalette.changeActiveButton();

@@ -23,10 +23,9 @@ /********************************************************************************

findParentByFeature,
isBoundsAware,
isViewport,
KeyTool,
MouseTool,
MouseListener,
Point,
Selectable,
SetBoundsAction,
SModelElement,
SModelRoot,
SParentElement,

@@ -36,8 +35,9 @@ Tool

import { GLSPViewerOptions } from "../../base/views/viewer-options";
import { GLSP_TYPES } from "../../types";
import { forEachElement, isSelected } from "../../utils/smodel-util";
import { forEachElement, isNonRoutableSelectedBoundsAware, isSelected } from "../../utils/smodel-util";
import { isBoundsAwareMoveable, isResizeable, ResizeHandleLocation, SResizeHandle } from "../change-bounds/model";
import { IMouseTool } from "../mouse-tool/mouse-tool";
import { ChangeBoundsOperationAction } from "../operation/operation-actions";
import { isRoutable } from "../reconnect/model";
import { SelectionTracker } from "../select/selection-tracker";
import { SelectionListener, SelectionService } from "../select/selection-service";
import {

@@ -70,11 +70,12 @@ FeedbackMoveMouseListener,

protected changeBoundsListener: ChangeBoundsListener;
protected selectionTracker: SelectionTracker;
constructor(@inject(MouseTool) protected mouseTool: MouseTool,
constructor(@inject(GLSP_TYPES.SelectionService) protected selectionService: SelectionService,
@inject(GLSP_TYPES.MouseTool) protected mouseTool: IMouseTool,
@inject(KeyTool) protected keyTool: KeyTool,
@inject(GLSP_TYPES.IFeedbackActionDispatcher) protected feedbackDispatcher: IFeedbackActionDispatcher) { }
@inject(GLSP_TYPES.IFeedbackActionDispatcher) protected feedbackDispatcher: IFeedbackActionDispatcher,
@inject(GLSP_TYPES.ViewerOptions) protected opts: GLSPViewerOptions) { }
enable() {
// install feedback move mouse listener for client-side move updates
this.feedbackMoveMouseListener = new FeedbackMoveMouseListener();
this.feedbackMoveMouseListener = new FeedbackMoveMouseListener(this.opts);
this.mouseTool.register(this.feedbackMoveMouseListener);

@@ -85,3 +86,3 @@

this.mouseTool.register(this.changeBoundsListener);
this.keyTool.register(this.changeBoundsListener);
this.selectionService.register(this.changeBoundsListener);
this.feedbackDispatcher.registerFeedback(this, [new ShowChangeBoundsToolResizeFeedbackAction]);

@@ -92,3 +93,3 @@ }

this.mouseTool.deregister(this.changeBoundsListener);
this.keyTool.deregister(this.changeBoundsListener);
this.selectionService.deregister(this.changeBoundsListener);
this.mouseTool.deregister(this.feedbackMoveMouseListener);

@@ -103,3 +104,3 @@ this.feedbackDispatcher.deregisterFeedback(this, [new HideChangeBoundsToolResizeFeedbackAction]);

class ChangeBoundsListener extends SelectionTracker {
class ChangeBoundsListener extends MouseListener implements SelectionListener {
// members for calculating the correct position change

@@ -121,22 +122,12 @@ private lastDragPosition: Point | undefined = undefined;

if (event.button === 0) {
let active: boolean = false;
// check if we have a resize handle (only single-selection)
if (target instanceof SResizeHandle) {
if (this.activeResizeElementId && target instanceof SResizeHandle) {
this.activeResizeHandle = target;
active = true;
} else {
// check if we have a moveable element (multi-selection allowed)
this.tool.dispatchFeedback([new HideChangeBoundsToolResizeFeedbackAction()]);
const moveableElement = findParentByFeature(target, isBoundsAwareMoveable);
if (moveableElement) {
// only allow one element to have the element resize handles
this.activeResizeElementId = moveableElement.id;
this.tool.dispatchFeedback([new ShowChangeBoundsToolResizeFeedbackAction(this.activeResizeElementId)]);
}
active = moveableElement !== undefined || this.activeResizeElementId !== undefined;
this.setActiveResizeElement(target);
}
if (active) {
if (this.activeResizeElementId) {
this.initPosition(event);
} else {
this.resetPosition();
this.reset();
}

@@ -184,14 +175,32 @@ }

keyDown(element: SModelElement, event: KeyboardEvent): Action[] {
const actions: Action[] = [];
selectionChanged(root: SModelRoot, selectedElements: string[]): void {
if (this.activeResizeElementId) {
super.keyDown(element, event);
if (this.isMultiSelection()) {
// no element should be in resize mode
this.tool.dispatchFeedback([new HideChangeBoundsToolResizeFeedbackAction()]);
if (selectedElements.indexOf(this.activeResizeElementId) > -1) {
// our active element is still selected, nothing to do
return;
}
// try to find some other selected element and mark that active
for (const elementId of selectedElements.reverse()) {
const element = root.index.getById(elementId);
if (element && this.setActiveResizeElement(element)) {
return;
}
}
this.reset();
}
return actions;
}
private setActiveResizeElement(target: SModelElement): boolean {
// check if we have a selected, moveable element (multi-selection allowed)
const moveableElement = findParentByFeature(target, isBoundsAwareMoveable);
if (isSelected(moveableElement)) {
// only allow one element to have the element resize handles
this.activeResizeElementId = moveableElement.id;
this.tool.dispatchFeedback([new ShowChangeBoundsToolResizeFeedbackAction(this.activeResizeElementId)]);
return true;
}
return false;
}
private isActiveResizeElement(element: SModelElement | undefined): element is SParentElement & BoundsAware {

@@ -219,2 +228,7 @@ return element !== undefined && element.id === this.activeResizeElementId;

private reset() {
this.tool.dispatchFeedback([new HideChangeBoundsToolResizeFeedbackAction()]);
this.resetPosition();
}
private resetPosition() {

@@ -312,5 +326,1 @@ this.activeResizeHandle = undefined;

}
function isNonRoutableSelectedBoundsAware(element: SModelElement): element is SModelElement & BoundsAware & Selectable {
return isBoundsAware(element) && isSelected(element) && !isRoutable(element);
}

@@ -25,3 +25,2 @@ /********************************************************************************

isCtrlOrCmd,
MouseTool,
SModelElement,

@@ -36,2 +35,3 @@ SModelRoot,

import { getAbsolutePosition } from "../../utils/viewpoint-util";
import { IMouseTool } from "../mouse-tool/mouse-tool";
import { CreateConnectionOperationAction, CreateNodeOperationAction } from "../operation/operation-actions";

@@ -60,3 +60,3 @@ import { deriveOperationId, OperationKind } from "../operation/set-operations";

constructor(@inject(MouseTool) protected mouseTool: MouseTool,
constructor(@inject(GLSP_TYPES.MouseTool) protected mouseTool: IMouseTool,
@inject(GLSP_TYPES.IFeedbackActionDispatcher) protected feedbackDispatcher: IFeedbackActionDispatcher) { }

@@ -133,3 +133,3 @@

constructor(@inject(MouseTool) protected mouseTool: MouseTool,
constructor(@inject(GLSP_TYPES.MouseTool) protected mouseTool: IMouseTool,
@inject(GLSP_TYPES.IFeedbackActionDispatcher) protected feedbackDispatcher: IFeedbackActionDispatcher,

@@ -136,0 +136,0 @@ @inject(AnchorComputerRegistry) protected anchorRegistry: AnchorComputerRegistry,

@@ -25,3 +25,2 @@ /********************************************************************************

MouseListener,
MouseTool,
SModelElement,

@@ -34,2 +33,3 @@ SModelRoot,

import { GLSP_TYPES } from "../../types";
import { IMouseTool } from "../mouse-tool/mouse-tool";
import { DeleteElementOperationAction } from "../operation/operation-actions";

@@ -83,3 +83,3 @@ import { ApplyCursorCSSFeedbackAction, CursorCSS } from "../tool-feedback/cursor-feedback";

constructor(@inject(MouseTool) protected readonly mouseTool: MouseTool,
constructor(@inject(GLSP_TYPES.MouseTool) protected mouseTool: IMouseTool,
@inject(GLSP_TYPES.IFeedbackActionDispatcher) protected readonly feedbackDispatcher: IFeedbackActionDispatcher) { }

@@ -86,0 +86,0 @@

@@ -24,4 +24,5 @@ /********************************************************************************

isConnectable,
MouseTool,
MouseListener,
SModelElement,
SModelRoot,
SRoutableElement,

@@ -34,2 +35,4 @@ SRoutingHandle,

import { GLSP_TYPES } from "../../types";
import { isSelected } from "../../utils/smodel-util";
import { IMouseTool } from "../mouse-tool/mouse-tool";
import { ReconnectConnectionOperationAction, RerouteConnectionOperationAction } from "../reconnect/action-definitions";

@@ -44,4 +47,3 @@ import {

} from "../reconnect/model";
import { SelectionTracker } from "../select/selection-tracker";
import { FeedbackMoveMouseListener } from "../tool-feedback/change-bounds-tool-feedback";
import { SelectionListener, SelectionService } from "../select/selection-service";
import { DrawFeedbackEdgeAction, feedbackEdgeId, RemoveFeedbackEdgeAction } from "../tool-feedback/creation-tool-feedback";

@@ -67,6 +69,7 @@ import { ApplyCursorCSSFeedbackAction, CursorCSS } from "../tool-feedback/cursor-feedback";

protected feedbackEdgeTargetMovingListener: FeedbackEdgeTargetMovingMouseListener;
protected feedbackMovingListener: FeedbackMoveMouseListener;
protected feedbackMovingListener: FeedbackEdgeRouteMovingMouseListener;
protected reconnectEdgeListener: ReconnectEdgeListener;
constructor(@inject(MouseTool) protected mouseTool: MouseTool,
constructor(@inject(GLSP_TYPES.SelectionService) protected selectionService: SelectionService,
@inject(GLSP_TYPES.MouseTool) protected mouseTool: IMouseTool,
@inject(GLSP_TYPES.IFeedbackActionDispatcher) protected feedbackDispatcher: IFeedbackActionDispatcher,

@@ -80,2 +83,3 @@ @inject(AnchorComputerRegistry) protected anchorRegistry: AnchorComputerRegistry,

this.mouseTool.register(this.reconnectEdgeListener);
this.selectionService.register(this.reconnectEdgeListener);

@@ -93,2 +97,3 @@ // install feedback move mouse listener for client-side move updates

this.reconnectEdgeListener.reset();
this.selectionService.deregister(this.reconnectEdgeListener);
this.mouseTool.deregister(this.feedbackEdgeSourceMovingListener);

@@ -105,3 +110,3 @@ this.mouseTool.deregister(this.feedbackEdgeTargetMovingListener);

class ReconnectEdgeListener extends SelectionTracker {
class ReconnectEdgeListener extends MouseListener implements SelectionListener {
private isMouseDown: boolean;

@@ -124,3 +129,3 @@

private isValidEdge(edge?: SRoutableElement): edge is SRoutableElement {
return edge !== undefined && edge.id !== feedbackEdgeId(edge.root);
return edge !== undefined && edge.id !== feedbackEdgeId(edge.root) && isSelected(edge);
}

@@ -140,3 +145,3 @@

private isEdgeSelected(): boolean {
return this.edge !== undefined;
return this.edge !== undefined && isSelected(this.edge);
}

@@ -183,3 +188,3 @@

private isReadyToReconnect() {
return this.isEdgeSelected() && this.isReconnecting() && this.newConnectable !== undefined;
return this.edge && this.isReconnecting() && this.newConnectable !== undefined;
}

@@ -266,2 +271,31 @@

selectionChanged(root: Readonly<SModelRoot>, selectedElements: string[]): void {
if (this.edge) {
if (selectedElements.indexOf(this.edge.id) > -1) {
// our active edge is still selected, nothing to do
return;
}
if (this.isReconnecting()) {
// we are reconnecting, so we may have clicked on a potential target
return;
}
// try to find some other selected element and mark that active
for (const elementId of selectedElements.reverse()) {
const element = root.index.getById(elementId);
if (element) {
const edge = findParentByFeature(element, isRoutable);
if (this.isValidEdge(edge)) {
// PHASE 1: Select edge
this.setEdgeSelected(edge);
return;
}
}
}
this.reset();
}
}
public reset() {

@@ -288,4 +322,3 @@ this.resetFeedback();

this.tool.dispatchFeedback(result);
}
}

@@ -19,8 +19,11 @@ /********************************************************************************

import { SetMarkersCommand } from "./validate";
import { ApplyMarkersCommand, ClearMarkersCommand, SetMarkersCommand, ValidationFeedbackEmitter } from "./validate";
const validationModule = new ContainerModule((bind, _unbind, isBound) => {
configureCommand({ bind, isBound }, SetMarkersCommand);
configureCommand({ bind, isBound }, ApplyMarkersCommand);
configureCommand({ bind, isBound }, ClearMarkersCommand);
bind(ValidationFeedbackEmitter).toSelf().inSingletonScope();
});
export default validationModule;

@@ -22,2 +22,3 @@ /********************************************************************************

CommandResult,
IActionDispatcher,
SIssue,

@@ -30,7 +31,10 @@ SIssueMarker,

import { GLSP_TYPES } from "../../types";
import { Marker, MarkerKind } from "../../utils/marker";
import { IFeedbackActionDispatcher, IFeedbackEmitter } from "../tool-feedback/feedback-action-dispatcher";
import { FeedbackCommand } from "../tool-feedback/model";
/**
* Action to retrieve markers for a model
*/
* Action to retrieve markers for a model
*/
export class RequestMarkersAction implements Action {

@@ -45,5 +49,48 @@

/**
* Feedback emitter sending actions for visualizing model validation feedback and
* re-establishing this feedback visualization after the model has been updated.
*/
@injectable()
export class ValidationFeedbackEmitter implements IFeedbackEmitter {
@inject(GLSP_TYPES.IFeedbackActionDispatcher) protected feedbackActionDispatcher: IFeedbackActionDispatcher;
@inject(TYPES.IActionDispatcherProvider) protected actionDispatcher: () => Promise<IActionDispatcher>;
private registeredAction: MarkersAction;
private constructor() { }
/**
* Register the action that should be emitted for visualizing validation feedback.
* @param action the action that should be emitted when the model is updated and that will visualize the model validation feedback.
*/
registerValidationFeedbackAction(action: MarkersAction) {
// De-register old action responsible for applying markers and re-applying them when the model is updated
this.feedbackActionDispatcher.deregisterFeedback(this, []);
// Clear existing markers
if (this.registeredAction !== undefined) {
const clearMarkersAction = new ClearMarkersAction(this.registeredAction.markers);
this.actionDispatcher().then(dispatcher => dispatcher.dispatch(clearMarkersAction));
}
// Register new action responsible for applying markers and re-applying them when the model is updated
this.feedbackActionDispatcher.registerFeedback(this, [action]);
this.registeredAction = action;
}
}
/**
* Interface for actions processing markers
*/
export interface MarkersAction extends Action {
readonly markers: Marker[];
}
/**
* Action to set markers for a model
*/
export class SetMarkersAction implements Action {
export class SetMarkersAction implements MarkersAction {
readonly kind = SetMarkersCommand.KIND;

@@ -54,3 +101,3 @@ constructor(public readonly markers: Marker[]) { }

/**
* Command for handling SetMarkersActions
* Command for handling `SetMarkersAction`
*/

@@ -60,2 +107,4 @@ @injectable()

@inject(ValidationFeedbackEmitter) protected validationFeedbackEmitter: ValidationFeedbackEmitter;
static readonly KIND = 'setMarkers';

@@ -67,39 +116,41 @@

/**
* Creates SIssueMarkers for all received markers and adds them to the respective SModelElements
* @param context Context of the command execution
*/
execute(context: CommandExecutionContext): CommandResult {
const markers: Marker[] = this.action.markers;
for (const marker of markers) {
const modelElement: SModelElement | undefined = context.root.index.getById(marker.elementId);
if (modelElement instanceof SParentElement) {
const issueMarker: SIssueMarker = this.getOrCreateSIssueMarker(modelElement);
const issue: SIssue = createSIssue(marker);
issueMarker.issues.push(issue);
}
}
const applyMarkersAction: ApplyMarkersAction = new ApplyMarkersAction(markers);
this.validationFeedbackEmitter.registerValidationFeedbackAction(applyMarkersAction);
return context.root;
}
private getOrCreateSIssueMarker(modelElement: SParentElement): SIssueMarker {
let issueMarker: SIssueMarker | undefined;
undo(context: CommandExecutionContext): CommandResult {
return context.root;
}
for (const child of modelElement.children) {
if (child instanceof SIssueMarker) {
issueMarker = child;
}
}
redo(context: CommandExecutionContext): CommandResult {
return this.execute(context);
}
}
if (issueMarker === undefined) {
issueMarker = new SIssueMarker();
issueMarker.type = "marker";
issueMarker.issues = new Array<SIssue>();
modelElement.add(issueMarker);
}
/**
* Action for applying makers to a model
*/
@injectable()
export class ApplyMarkersAction implements MarkersAction {
readonly kind = ApplyMarkersCommand.KIND;
constructor(public readonly markers: Marker[]) { }
}
return issueMarker;
/**
* Command for handling `ApplyMarkersAction`
*/
@injectable()
export class ApplyMarkersCommand extends FeedbackCommand {
static KIND = "applyMarkers";
readonly priority = 0;
constructor(@inject(TYPES.Action) protected action: ApplyMarkersAction) {
super();
}
undo(context: CommandExecutionContext): CommandResult {
execute(context: CommandExecutionContext): CommandResult {
const markers: Marker[] = this.action.markers;

@@ -109,15 +160,5 @@ for (const marker of markers) {

if (modelElement instanceof SParentElement) {
for (const child of modelElement.children) {
if (child instanceof SIssueMarker) {
for (let index = 0; index < child.issues.length; ++index) {
const issue = child.issues[index];
if (issue.message === marker.description) {
child.issues.splice(index--, 1);
}
}
if (child.issues.length === 0) {
modelElement.remove(child);
}
}
}
const issueMarker: SIssueMarker = getOrCreateSIssueMarker(modelElement);
const issue: SIssue = createSIssue(marker);
issueMarker.issues.push(issue);
}

@@ -128,2 +169,6 @@ }

undo(context: CommandExecutionContext): CommandResult {
return context.root;
}
redo(context: CommandExecutionContext): CommandResult {

@@ -134,2 +179,48 @@ return this.execute(context);

/**
* Retrieves the `SIssueMarker` contained by the provided model element as
* direct child or a newly instantiated `SIssueMarker` if no child
* `SIssueMarker` exists.
* @param modelElement for which the `SIssueMarker` should be retrieved or created.
* @returns the child `SIssueMarker` or a new `SIssueMarker` if no such child exists.
*/
function getOrCreateSIssueMarker(modelElement: SParentElement): SIssueMarker {
let issueMarker: SIssueMarker | undefined;
issueMarker = getSIssueMarker(modelElement);
if (issueMarker === undefined) {
issueMarker = new SIssueMarker();
issueMarker.type = "marker";
issueMarker.issues = new Array<SIssue>();
modelElement.add(issueMarker);
}
return issueMarker;
}
/**
* Retrieves the `SIssueMarker` contained by the provided model element as
* direct child or `undefined` if such an `SIssueMarker` does not exist.
* @param modelElement for which the `SIssueMarker` should be retrieved.
* @returns the child `SIssueMarker` or `undefined` if no such child exists.
*/
function getSIssueMarker(modelElement: SParentElement): SIssueMarker | undefined {
let issueMarker: SIssueMarker | undefined;
for (const child of modelElement.children) {
if (child instanceof SIssueMarker) {
issueMarker = child;
}
}
return issueMarker;
}
/**
* Creates an `SIssue` with `severity` and `message` set according to
* the `kind` and `description` of the provided `Marker`.
* @param marker `Marker` for that an `SIssue` should be created.
* @returns the created `SIssue`.
*/
function createSIssue(marker: Marker): SIssue {

@@ -156,1 +247,52 @@ const issue: SIssue = new SIssue();

}
/**
* Action for clearing makers of a model
*/
@injectable()
export class ClearMarkersAction implements MarkersAction {
readonly kind = ClearMarkersCommand.KIND;
constructor(public readonly markers: Marker[]) { }
}
/**
* Command for handling `ClearMarkersAction`
*/
@injectable()
export class ClearMarkersCommand extends Command {
static KIND = "clearMarkers";
constructor(@inject(TYPES.Action) protected action: ClearMarkersAction) {
super();
}
execute(context: CommandExecutionContext): CommandResult {
const markers: Marker[] = this.action.markers;
for (const marker of markers) {
const modelElement: SModelElement | undefined = context.root.index.getById(marker.elementId);
if (modelElement instanceof SParentElement) {
const issueMarker: SIssueMarker | undefined = getSIssueMarker(modelElement);
if (issueMarker !== undefined) {
for (let index = 0; index < issueMarker.issues.length; ++index) {
const issue: SIssue = issueMarker.issues[index];
if (issue.message === marker.description) {
issueMarker.issues.splice(index--, 1);
}
}
if (issueMarker.issues.length === 0) {
modelElement.remove(issueMarker);
}
}
}
}
return context.root;
}
undo(context: CommandExecutionContext): CommandResult {
return context.root;
}
redo(context: CommandExecutionContext): CommandResult {
return this.execute(context);
}
}

@@ -17,7 +17,11 @@ /********************************************************************************

import defaultGLSPModule from "./base/di.config";
import commandPaletteModule from "./features/command-palette/di.config";
import glspCommandPaletteModule from "./features/command-palette/di.config";
import glspEditLabelValidationModule from "./features/edit-label-validation/di.config";
import executeModule from "./features/execute/di.config";
import modelHintsModule from "./features/hints/di.config";
import layoutCommandsModule from "./features/layout/di.config";
import glspMouseToolModule from "./features/mouse-tool/di.config";
import requestResponseModule from "./features/request-response/di.config";
import saveModule from "./features/save/di.config";
import glspSelectModule from "./features/select/di.config";
import toolFeedbackModule from "./features/tool-feedback/di.config";

@@ -28,11 +32,10 @@ import paletteModule from "./features/tool-palette/di.config";

export * from 'sprotty/lib';
export * from './base/command-stack';
export * from './base/diagram-ui-extension/diagram-ui-extension';
export * from './base/edit-config/edit-config';
export * from './model-source/websocket-diagram-server';
export * from './base/model/update-model-command';
export * from './base/tool-manager/tool-manager-action-handler';
export * from './base/views/viewer-options';
export * from './features/change-bounds/model';
export * from './features/command-palette/action-definitions';
export * from './features/command-palette/action-provider';
export * from './features/command-palette/command-palette';
export * from './features/execute/execute-command';

@@ -42,3 +45,3 @@ export * from './features/execute/model';

export * from './features/hints/type-hints-action-initializer';
export * from './features/nameable/model';
export * from './features/mouse-tool/di.config';
export * from './features/operation/operation-actions';

@@ -50,2 +53,3 @@ export * from './features/operation/set-operations';

export * from './features/save/save';
export * from './features/select/di.config';
export * from './features/tool-feedback/creation-tool-feedback';

@@ -59,2 +63,3 @@ export * from './features/tool-feedback/model';

export * from './features/validation/validate';
export * from './features/layout/layout-commands';
export * from './lib/model';

@@ -66,3 +71,7 @@ export * from './types';

export * from './utils/viewpoint-util';
export { validationModule, saveModule, executeModule, paletteModule, toolFeedbackModule, defaultGLSPModule, modelHintsModule, commandPaletteModule, requestResponseModule };
export {
validationModule, saveModule, executeModule, paletteModule, toolFeedbackModule, defaultGLSPModule, modelHintsModule, glspCommandPaletteModule, requestResponseModule, //
glspSelectModule, glspMouseToolModule, layoutCommandsModule, glspEditLabelValidationModule
};

@@ -17,11 +17,12 @@ /********************************************************************************

export const GLSP_TYPES = {
ICommandPaletteActionProvider: Symbol.for("ICommandPaletteActionProvider"),
ICommandPaletteActionProviderRegistry: Symbol.for("ICommandPaletteActionProviderRegistry"),
IFeedbackActionDispatcher: Symbol.for("IFeedbackActionDispatcher"),
IToolFactory: Symbol.for("Factory<Tool>"),
IReadonlyModelAccessProvider: Symbol.for("IReadonlyModelAccessProvider"),
IDiagramUIExtension: Symbol.for("IDiagramUIExtension"),
DiagramUIExtensionRegistry: Symbol.for("DiagramUIExtensionRegistry"),
IEditConfigProvider: Symbol.for("IEditConfigProvider"),
RequestResponseSupport: Symbol.for("RequestResponseSupport")
RequestResponseSupport: Symbol.for("RequestResponseSupport"),
SelectionService: Symbol.for("SelectionService"),
SelectionListener: Symbol.for("SelectionListener"),
SModelRootListener: Symbol.for("SModelRootListener"),
MouseTool: Symbol.for("MouseTool"),
ViewerOptions: Symbol.for("ViewerOptions")
};

@@ -16,9 +16,6 @@ /********************************************************************************

********************************************************************************/
import { NodeEditConfig } from "../base/edit-config/edit-config";
import { Selectable } from "sprotty/lib";
import { SModelElement } from "sprotty/lib";
import { SParentElement } from "sprotty/lib";
import { BoundsAware, isBoundsAware, isSelectable, Selectable, SModelElement, SParentElement } from "sprotty/lib";
import { isConfigurableNode } from "../base/edit-config/edit-config";
import { isSelectable } from "sprotty/lib";
import { isConfigurableNode, NodeEditConfig } from "../base/edit-config/edit-config";
import { isRoutable } from "../features/reconnect/model";

@@ -35,2 +32,8 @@ export function getIndex(element: SModelElement) {

export function getMatchingElements<T>(element: SModelElement, predicate: (element: SModelElement) => element is SModelElement & T): (SModelElement & T)[] {
const matching: (SModelElement & T)[] = [];
forEachElement(element, predicate, item => matching.push(item));
return matching;
}
export function hasSelectedElements(element: SModelElement) {

@@ -48,4 +51,4 @@ return getSelectedElementCount(element) > 0;

export function isSelected(element: SModelElement): element is SModelElement & Selectable {
return isSelectable(element) && element.selected;
export function isSelected(element: SModelElement | undefined): element is SModelElement & Selectable {
return isNotUndefined(element) && isSelectable(element) && element.selected;
}

@@ -84,1 +87,7 @@

}
export function isNonRoutableSelectedBoundsAware(element: SModelElement): element is SelectableBoundsAware {
return isBoundsAware(element) && isSelected(element) && !isRoutable(element);
}
export type SelectableBoundsAware = SModelElement & BoundsAware & Selectable;

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc