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

@eclipse-glsp/client

Package Overview
Dependencies
Maintainers
5
Versions
378
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@eclipse-glsp/client - npm Package Compare versions

Comparing version 0.8.0-next.b2224cc to 0.8.0-next.bddae4a

lib/base/editor-context.d.ts

2

lib/base/di.config.js

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

var command_stack_1 = require("./command-stack");
var editor_context_1 = require("./editor-context");
var update_model_command_1 = require("./model/update-model-command");

@@ -32,2 +33,3 @@ var tool_manager_action_handler_1 = require("./tool-manager/tool-manager-action-handler");

bind(types_1.GLSP_TYPES.IToolFactory).toFactory((tool_manager_action_handler_1.createToolFactory()));
bind(editor_context_1.EditorContextService).toSelf().inSingletonScope();
// Model update initialization ------------------------------------

@@ -34,0 +36,0 @@ lib_1.configureCommand(context, update_model_command_1.FeedbackAwareUpdateModelCommand);

5

lib/base/model/update-model-command.d.ts
import { Action, ActionHandlerRegistry, CommandExecutionContext, CommandReturn, IActionHandler, 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 { IFeedbackActionDispatcher } from "../../features/tool-feedback/feedback-action-dispatcher";
export declare class SetModelActionHandler implements IActionHandler {
handle(action: Action): Action | void;
handledActionKinds: string[];
}

@@ -19,4 +18,4 @@ export declare function isSetModelAction(action: Action): action is SetModelAction;

protected readonly feedbackActionDispatcher: IFeedbackActionDispatcher;
protected actionHandlerRegistryProvider: () => Promise<ActionHandlerRegistry>;
protected modelRootListeners: SModelRootListener[];
protected actionHandlerRegistry?: ActionHandlerRegistry;
constructor(action: UpdateModelAction, logger: ILogger, feedbackActionDispatcher: IFeedbackActionDispatcher, actionHandlerRegistryProvider: () => Promise<ActionHandlerRegistry>, modelRootListeners?: SModelRootListener[]);

@@ -23,0 +22,0 @@ protected performUpdate(oldRoot: SModelRoot, newRoot: SModelRoot, context: CommandExecutionContext): CommandReturn;

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

function SetModelActionHandler() {
this.handledActionKinds = [lib_1.SetModelCommand.KIND];
}

@@ -82,9 +81,8 @@ SetModelActionHandler.prototype.handle = function (action) {

_this.feedbackActionDispatcher = feedbackActionDispatcher;
_this.actionHandlerRegistryProvider = actionHandlerRegistryProvider;
_this.modelRootListeners = modelRootListeners;
actionHandlerRegistryProvider().then(function (registry) { return _this.actionHandlerRegistry = registry; });
return _this;
}
FeedbackAwareUpdateModelCommand.prototype.performUpdate = function (oldRoot, newRoot, context) {
var _this = this;
if (this.feedbackActionDispatcher) {
if (this.feedbackActionDispatcher && this.actionHandlerRegistry) {
// Create a temporary context wich defines the `newRoot` as `root`

@@ -100,6 +98,4 @@ // This way we do not corrupt the redo/undo behavior of the super class

};
this.actionHandlerRegistryProvider().then(function (registry) {
var feedbackCommands = _this.getFeedbackCommands(registry);
feedbackCommands.forEach(function (command) { return command.execute(tempContext_1); });
});
var feedbackCommands = this.getFeedbackCommands(this.actionHandlerRegistry);
feedbackCommands.forEach(function (command) { return command.execute(tempContext_1); });
}

@@ -106,0 +102,0 @@ this.modelRootListeners.forEach(function (listener) { return listener.modelRootChanged(newRoot); });

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

********************************************************************************/
import { BoundsAware, Hoverable, Locateable, SChildElement, Selectable, SModelElement, SNode, SParentElement } from "sprotty/lib";
import { NodeEditConfig } from "../../base/edit-config/edit-config";
import { BoundsAware, Hoverable, Locateable, SChildElement, Selectable, SModelElement, SParentElement } from "sprotty/lib";
export declare const resizeFeature: unique symbol;
export interface Resizable extends BoundsAware, Selectable {
}
export declare function isResizable(element: SModelElement): element is SParentElement & Resizable;
export declare enum ResizeHandleLocation {

@@ -25,3 +28,2 @@ TopLeft = "top-left",

}
export declare function isResizeable(element: SModelElement): element is SNode & SParentElement & BoundsAware & Selectable & NodeEditConfig;
export declare function isBoundsAwareMoveable(element: SModelElement): element is SModelElement & Locateable & BoundsAware;

@@ -28,0 +30,0 @@ export declare class SResizeHandle extends SChildElement implements Hoverable {

@@ -32,3 +32,7 @@ "use strict";

var lib_1 = require("sprotty/lib");
var edit_config_1 = require("../../base/edit-config/edit-config");
exports.resizeFeature = Symbol("resizeFeature");
function isResizable(element) {
return lib_1.isBoundsAware(element) && lib_1.isSelectable(element) && element instanceof lib_1.SParentElement && element.hasFeature(exports.resizeFeature);
}
exports.isResizable = isResizable;
var ResizeHandleLocation;

@@ -41,6 +45,2 @@ (function (ResizeHandleLocation) {

})(ResizeHandleLocation = exports.ResizeHandleLocation || (exports.ResizeHandleLocation = {}));
function isResizeable(element) {
return edit_config_1.isConfigurableNode(element) && element.resizable && lib_1.isBoundsAware(element) && lib_1.isSelectable(element) && element instanceof lib_1.SParentElement;
}
exports.isResizeable = isResizeable;
function isBoundsAwareMoveable(element) {

@@ -47,0 +47,0 @@ return lib_1.isMoveable(element) && lib_1.isBoundsAware(element);

@@ -1,30 +0,13 @@

import { Action, Bounds, BoundsAware, Point, PointToPointLine, SModelElement } from "sprotty/lib";
import { Action, BoundsAware, Point, SModelElement } from "sprotty/lib";
export interface IMovementRestrictor {
attemptMove(element: SModelElement, mousePoint: Point, target: SModelElement, delta: Point, result: Action[]): boolean;
validate(newLocation: Point, element: SModelElement): boolean;
cssClasses?: string[];
}
export declare class NoCollisionMovementRestrictor {
hasCollided: boolean;
attemptMove(element: SModelElement, mousePoint: Point, target: SModelElement, delta: Point, result: Action[]): boolean;
/**
* Used to return the collision target(s) or the collision chain in case of multiple selected elements
*/
getCollisionChain(target: SModelElement, element: SModelElement, delta: Point, collisionChain: SModelElement[]): SModelElement[];
/**
* Returns bounds centered around the point
*/
getCenteredBoundsToPointer(mousePoint: Point, bounds: Bounds): Bounds;
getDistanceBetweenParallelLines(p1: Point, p2: Point, secondLine: PointToPointLine): Number;
/**
* Snaps the element to the target in case of a collision
*/
getSnappedBounds(element: SModelElement & BoundsAware, target: SModelElement & BoundsAware): Bounds;
export declare function createMovementRestrictionFeedback(element: SModelElement, movementRestrictor: IMovementRestrictor): Action[];
export declare function removeMovementRestrictionFeedback(element: SModelElement, movementRestrictor: IMovementRestrictor): Action[];
export declare class NoOverlapMovmentRestrictor implements IMovementRestrictor {
validate(newLocation: Point, element: SModelElement): boolean;
cssClasses: string[];
}
/**
* 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;
export declare function areOverlapping(element1: SModelElement & BoundsAware, element2: SModelElement & BoundsAware): boolean;
//# sourceMappingURL=movement-restrictor.d.ts.map

@@ -26,242 +26,63 @@ "use strict";

var lib_1 = require("sprotty/lib");
var iterable_1 = require("sprotty/lib/utils/iterable");
var cursor_feedback_1 = require("../tool-feedback/cursor-feedback");
var viewpoint_util_1 = require("../../utils/viewpoint-util");
var css_feedback_1 = require("../tool-feedback/css-feedback");
var model_1 = require("./model");
var NoCollisionMovementRestrictor = /** @class */ (function () {
function NoCollisionMovementRestrictor() {
this.hasCollided = false;
function createMovementRestrictionFeedback(element, movementRestrictor) {
var result = [];
result.push(new css_feedback_1.ModifyCSSFeedbackAction(element, movementRestrictor.cssClasses));
if (element instanceof lib_1.SParentElement) {
element.children.filter(function (child) { return child instanceof model_1.SResizeHandle; }).forEach(function (child) { return result.push(new css_feedback_1.ModifyCSSFeedbackAction(child, movementRestrictor.cssClasses)); });
}
/*
* Attempt to perform an element move. Returns true if the move is not restricted anc can be applied successfull and false otherwise
*/
NoCollisionMovementRestrictor.prototype.attemptMove = function (element, mousePoint, target, delta, result) {
var _this = this;
return result;
}
exports.createMovementRestrictionFeedback = createMovementRestrictionFeedback;
function removeMovementRestrictionFeedback(element, movementRestrictor) {
var result = [];
result.push(new css_feedback_1.ModifyCSSFeedbackAction(element, undefined, movementRestrictor.cssClasses));
if (element instanceof lib_1.SParentElement) {
element.children.filter(function (child) { return child instanceof model_1.SResizeHandle; }).
forEach(function (child) { return result.push(new css_feedback_1.ModifyCSSFeedbackAction(child, undefined, movementRestrictor.cssClasses)); });
}
return result;
}
exports.removeMovementRestrictionFeedback = removeMovementRestrictionFeedback;
var NoOverlapMovmentRestrictor = /** @class */ (function () {
function NoOverlapMovmentRestrictor() {
this.cssClasses = ["movement-not-allowed"];
}
NoOverlapMovmentRestrictor.prototype.validate = function (newLocation, element) {
if (!model_1.isBoundsAwareMoveable(element)) {
return false;
}
var mouseOverElement = false;
var willOverlap = false;
// Create ghost element to check possible bounds
// Create ghost element at the newLocation;
var ghostElement = Object.create(element);
ghostElement.bounds = this.getCenteredBoundsToPointer(mousePoint, element.bounds);
// Set type to Ghost to keep tracking it through elements
ghostElement.bounds.x = newLocation.x - element.bounds.width / 2;
ghostElement.bounds.y = newLocation.y - element.bounds.height / 2;
ghostElement.type = "Ghost";
ghostElement.id = element.id;
// Check collision for gost element (to see when it has passed beyond obstacle)
var collisionTargetsGhost = this.getCollisionChain(target, ghostElement, delta, [])
.filter(function (collidingElement) { return lib_1.isSelectable(collidingElement) && !collidingElement.selected; });
// After collision the mouse is back inside the element => change cursor back to default
if (this.hasCollided && lib_1.includes(element.bounds, mousePoint)) {
mouseOverElement = true;
result.push(new cursor_feedback_1.ApplyCursorCSSFeedbackAction(cursor_feedback_1.CursorCSS.DEFAULT));
}
var selectedElements = target.root.index.all()
.filter(function (selected) { return lib_1.isSelectable(selected) && selected.selected; });
// If the ghost element has moved beyond the obstacle move the actual element there aswell
// But only if a single element is selected (multi-selection jumps are not supported)
if (this.hasCollided && collisionTargetsGhost.length === 0 && iterable_1.toArray(selectedElements).length === 1) {
mouseOverElement = true;
result.push(new cursor_feedback_1.ApplyCursorCSSFeedbackAction(cursor_feedback_1.CursorCSS.DEFAULT));
if (element.id === ghostElement.id) {
element.bounds = ghostElement.bounds;
}
}
// Get only the valid, non-slected collision targets to avoid in-selection collisions
var collisionTargets = this.getCollisionChain(target, element, delta, [])
.filter(function (collidingElement) { return lib_1.isSelectable(collidingElement) && !collidingElement.selected; });
if (collisionTargets.length > 0) {
collisionTargets.forEach(function (collisionTarget) {
if (lib_1.isBoundsAware(collisionTarget)) {
// Only snap on first collision to avoid erratic jumps
if (!_this.hasCollided) {
var snappedBounds = _this.getSnappedBounds(element, collisionTarget);
var snapMoves = [];
snapMoves.push({
elementId: element.id,
fromPosition: {
x: element.position.x,
y: element.position.y
},
toPosition: {
x: snappedBounds.x,
y: snappedBounds.y
}
});
result.push(new lib_1.MoveAction(snapMoves, false));
}
willOverlap = true;
_this.hasCollided = true;
result.push(new cursor_feedback_1.ApplyCursorCSSFeedbackAction(cursor_feedback_1.CursorCSS.OVERLAP_FORBIDDEN));
}
});
}
if ((!willOverlap && !this.hasCollided) ||
(this.hasCollided && !willOverlap && mouseOverElement)) {
this.hasCollided = false;
return true;
}
return false;
return !Array.from(element.root.index.all().filter(function (e) { return e.id !== ghostElement.id && e !== ghostElement.root && (e instanceof lib_1.SNode); })
.map(function (e) { return e; })).some(function (e) { return areOverlapping(e, ghostElement); });
};
/**
* Used to return the collision target(s) or the collision chain in case of multiple selected elements
*/
NoCollisionMovementRestrictor.prototype.getCollisionChain = function (target, element, delta, collisionChain) {
var _this = this;
if (model_1.isBoundsAwareMoveable(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 (lib_1.isBoundsAware(element) && lib_1.isBoundsAware(candidate)) {
var futureBounds = {
x: element.position.x + delta.x,
y: element.position.y + delta.y,
width: element.bounds.width,
height: element.bounds.height
};
if (isOverlappingBounds(futureBounds, candidate.bounds) && (!isOverlappingBounds(element.bounds, candidate.bounds) || element.type === "Ghost")) {
collisionChain.push(candidate);
if (lib_1.isSelectable(candidate) && candidate.selected) {
// Check what the selected candidate will collide with and add it to the chain
collisionChain.push.apply(collisionChain, _this.getCollisionChain(target, candidate, delta, collisionChain));
}
}
}
}
});
}
return collisionChain;
};
/**
* Returns bounds centered around the point
*/
NoCollisionMovementRestrictor.prototype.getCenteredBoundsToPointer = function (mousePoint, bounds) {
var middleX = mousePoint.x - bounds.width / 2;
var middleY = mousePoint.y - bounds.height / 2;
var shiftedBounds = { x: middleX, y: middleY, width: bounds.width, height: bounds.height };
return shiftedBounds;
};
// Remove this and use the one from the improved routing branch
NoCollisionMovementRestrictor.prototype.getDistanceBetweenParallelLines = function (p1, p2, secondLine) {
var numerator = Math.abs((secondLine.a * p1.x) + (secondLine.b * p1.y) - secondLine.c);
var denominator = Math.sqrt(Math.pow(secondLine.a, 2) + Math.pow(secondLine.b, 2));
return numerator / denominator;
};
/**
* Snaps the element to the target in case of a collision
*/
NoCollisionMovementRestrictor.prototype.getSnappedBounds = function (element, target) {
var snappedBounds = element.bounds;
// Build corner points
var elementTopLeft = {
x: element.bounds.x,
y: element.bounds.y
};
var elementTopRight = {
x: element.bounds.x + element.bounds.width,
y: element.bounds.y
};
var elementBottomLeft = {
x: element.bounds.x,
y: element.bounds.y + element.bounds.height
};
var elementBottomRight = {
x: element.bounds.x + element.bounds.width,
y: element.bounds.y + element.bounds.height
};
var targetTopLeft = {
x: target.bounds.x,
y: target.bounds.y
};
var targetTopRight = {
x: target.bounds.x + target.bounds.width,
y: target.bounds.y
};
var targetBottomLeft = {
x: target.bounds.x,
y: target.bounds.y + target.bounds.height
};
var targetBottomRight = {
x: target.bounds.x + target.bounds.width,
y: target.bounds.y + target.bounds.height
};
// Build lines
var targetTopLine = new lib_1.PointToPointLine(targetTopLeft, targetTopRight);
var targetBottomLine = new lib_1.PointToPointLine(targetBottomLeft, targetBottomRight);
var targetLeftLine = new lib_1.PointToPointLine(targetTopLeft, targetBottomLeft);
var targetRightLine = new lib_1.PointToPointLine(targetTopRight, targetBottomRight);
// Compute distances
var distanceTop = this.getDistanceBetweenParallelLines(elementBottomLeft, elementBottomRight, targetTopLine);
var distanceBottom = this.getDistanceBetweenParallelLines(elementTopLeft, elementTopRight, targetBottomLine);
var distanceLeft = this.getDistanceBetweenParallelLines(elementTopLeft, elementBottomLeft, targetRightLine);
var distanceRight = this.getDistanceBetweenParallelLines(elementTopRight, elementBottomRight, targetLeftLine);
var minimumCandidates = [];
// Overlap on the horizontal lines
if (isOverlapping1Dimension(element.bounds.x, element.bounds.width, target.bounds.x, target.bounds.width)) {
minimumCandidates.push(distanceTop.valueOf());
minimumCandidates.push(distanceBottom.valueOf());
}
// Overlap on the horizontal lines
if (isOverlapping1Dimension(element.bounds.y, element.bounds.height, target.bounds.y, target.bounds.height)) {
minimumCandidates.push(distanceLeft.valueOf());
minimumCandidates.push(distanceRight.valueOf());
}
// Get minimum distance and then snap accordingly
minimumCandidates.sort(function (a, b) { return a - b; });
var minimumDistance = minimumCandidates[0];
if (minimumDistance === distanceTop) {
snappedBounds = {
x: element.bounds.x,
y: target.bounds.y - 1 - element.bounds.height,
width: element.bounds.width,
height: element.bounds.height
};
}
if (minimumDistance === distanceBottom) {
snappedBounds = {
x: element.bounds.x,
y: target.bounds.y + target.bounds.height + 1,
width: element.bounds.width,
height: element.bounds.height
};
}
if (minimumDistance === distanceLeft) {
snappedBounds = {
x: target.bounds.x + target.bounds.width + 1,
y: element.bounds.y,
width: element.bounds.width,
height: element.bounds.height
};
}
if (minimumDistance === distanceRight) {
snappedBounds = {
x: target.bounds.x - 1 - element.bounds.width,
y: element.bounds.y,
width: element.bounds.width,
height: element.bounds.height
};
}
return snappedBounds;
};
NoCollisionMovementRestrictor = __decorate([
NoOverlapMovmentRestrictor = __decorate([
inversify_1.injectable()
], NoCollisionMovementRestrictor);
return NoCollisionMovementRestrictor;
], NoOverlapMovmentRestrictor);
return NoOverlapMovmentRestrictor;
}());
exports.NoCollisionMovementRestrictor = NoCollisionMovementRestrictor;
/**
* Used to check if 1D boxes (lines) overlap
*/
function isOverlapping1Dimension(x1, width1, x2, width2) {
return x1 + width1 >= x2 && x2 + width2 >= x1;
exports.NoOverlapMovmentRestrictor = NoOverlapMovmentRestrictor;
function areOverlapping(element1, element2) {
var b1 = viewpoint_util_1.toAbsoluteBounds(element1);
var b2 = viewpoint_util_1.toAbsoluteBounds(element2);
var r1TopLeft = b1;
var r1BottomRight = { x: b1.x + b1.width, y: b1.y + b1.height };
var r2TopLeft = b2;
var r2BottomRight = { x: b2.x + b2.width, y: b2.y + b2.height };
// If one rectangle is on left side of other
if (r1TopLeft.x > r2BottomRight.x || r2TopLeft.x > r1BottomRight.x)
return false;
// If one rectangle is above other
if (r1BottomRight.y < r2TopLeft.y || r2BottomRight.y < r1TopLeft.y)
return false;
return true;
}
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;
exports.areOverlapping = areOverlapping;
//# sourceMappingURL=movement-restrictor.js.map

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

var lib_1 = require("sprotty/lib");
var action_provider_1 = require("./action-provider");
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(lib_1.TYPES.ICommandPaletteActionProvider).to(action_provider_1.ServerCommandPaletteActionProvider);
var server_command_palette_provider_1 = require("./server-command-palette-provider");
var glspCommandPaletteModule = new inversify_1.ContainerModule(function (bind) {
bind(lib_1.TYPES.ICommandPaletteActionProvider).to(server_command_palette_provider_1.ServerCommandPaletteActionProvider);
});
exports.default = glspCommandPaletteModule;
//# sourceMappingURL=di.config.js.map

@@ -1,19 +0,21 @@

import { Action, EditableLabel, EditLabelValidationResult, IEditLabelValidationDecorator, IEditLabelValidator, SModelElement } from "sprotty";
import { RequestResponseSupport } from "../request-response/support";
export declare class ValidateLabelEditAction implements Action {
import { Action, EditableLabel, EditLabelValidationResult, IEditLabelValidationDecorator, IEditLabelValidator, RequestAction, ResponseAction, SModelElement } from "sprotty";
import { GLSPActionDispatcher } from "../request-response/glsp-action-dispatcher";
export declare class ValidateLabelEditAction implements RequestAction<SetLabelEditValidationResultAction> {
readonly value: string;
readonly labelId: string;
readonly requestId: string;
static readonly KIND = "validateLabelEdit";
kind: string;
constructor(value: string, labelId: string);
constructor(value: string, labelId: string, requestId?: string);
}
export declare class SetLabelEditValidationResultAction implements Action {
export declare class SetLabelEditValidationResultAction implements ResponseAction {
readonly result: EditLabelValidationResult;
readonly responseId: string;
static readonly KIND = "setLabelEditValidationResult";
kind: string;
constructor(result: EditLabelValidationResult);
constructor(result: EditLabelValidationResult, responseId?: string);
}
export declare function isSetLabelEditValidationResultAction(action: Action): action is SetLabelEditValidationResultAction;
export declare class ServerEditLabelValidator implements IEditLabelValidator {
protected requestResponseSupport: RequestResponseSupport;
protected actionDispatcher: GLSPActionDispatcher;
validate(value: string, label: EditableLabel & SModelElement): Promise<EditLabelValidationResult>;

@@ -20,0 +22,0 @@ getValidationResultFromResponse(action: Action): EditLabelValidationResult;

@@ -28,8 +28,10 @@ "use strict";

var inversify_1 = require("inversify");
var types_1 = require("../../types");
var support_1 = require("../request-response/support");
var sprotty_1 = require("sprotty");
var glsp_action_dispatcher_1 = require("../request-response/glsp-action-dispatcher");
var ValidateLabelEditAction = /** @class */ (function () {
function ValidateLabelEditAction(value, labelId) {
function ValidateLabelEditAction(value, labelId, requestId) {
if (requestId === void 0) { requestId = sprotty_1.generateRequestId(); }
this.value = value;
this.labelId = labelId;
this.requestId = requestId;
this.kind = ValidateLabelEditAction.KIND;

@@ -42,4 +44,6 @@ }

var SetLabelEditValidationResultAction = /** @class */ (function () {
function SetLabelEditValidationResultAction(result) {
function SetLabelEditValidationResultAction(result, responseId) {
if (responseId === void 0) { responseId = ''; }
this.result = result;
this.responseId = responseId;
this.kind = SetLabelEditValidationResultAction.KIND;

@@ -60,4 +64,5 @@ }

ServerEditLabelValidator.prototype.validate = function (value, label) {
var _this = this;
var action = new ValidateLabelEditAction(value, label.id);
return this.requestResponseSupport.dispatchRequest(action, this.getValidationResultFromResponse);
return this.actionDispatcher.requestUntil(action).then(function (response) { return _this.getValidationResultFromResponse(response); });
};

@@ -71,5 +76,5 @@ ServerEditLabelValidator.prototype.getValidationResultFromResponse = function (action) {

__decorate([
inversify_1.inject(types_1.GLSP_TYPES.RequestResponseSupport),
__metadata("design:type", support_1.RequestResponseSupport)
], ServerEditLabelValidator.prototype, "requestResponseSupport", void 0);
inversify_1.inject(sprotty_1.TYPES.IActionDispatcher),
__metadata("design:type", glsp_action_dispatcher_1.GLSPActionDispatcher)
], ServerEditLabelValidator.prototype, "actionDispatcher", void 0);
ServerEditLabelValidator = __decorate([

@@ -76,0 +81,0 @@ inversify_1.injectable()

@@ -21,11 +21,11 @@ "use strict";

var types_1 = require("../../types");
var action_definition_1 = require("./action-definition");
var type_hints_action_initializer_1 = require("./type-hints-action-initializer");
var request_type_hints_action_1 = require("./request-type-hints-action");
var type_hints_1 = require("./type-hints");
var modelHintsModule = new inversify_1.ContainerModule(function (bind, _unbind, isBound) {
bind(type_hints_action_initializer_1.TypeHintsEditConfigProvider).toSelf().inSingletonScope();
lib_1.configureActionHandler({ bind: bind, isBound: isBound }, action_definition_1.SetTypeHintsAction.KIND, type_hints_action_initializer_1.TypeHintsEditConfigProvider);
bind(types_1.GLSP_TYPES.IEditConfigProvider).toService(type_hints_action_initializer_1.TypeHintsEditConfigProvider);
lib_1.configureCommand({ bind: bind, isBound: isBound }, type_hints_action_initializer_1.ApplyEditConfigCommand);
bind(type_hints_1.TypeHintProvider).toSelf().inSingletonScope();
bind(types_1.GLSP_TYPES.ITypeHintProvider).toService(type_hints_1.TypeHintProvider);
lib_1.configureActionHandler({ bind: bind, isBound: isBound }, request_type_hints_action_1.SetTypeHintsAction.KIND, type_hints_1.TypeHintProvider);
lib_1.configureCommand({ bind: bind, isBound: isBound }, type_hints_1.ApplyTypeHintsCommand);
});
exports.default = modelHintsModule;
//# sourceMappingURL=di.config.js.map

@@ -53,5 +53,5 @@ import { Action, Command, CommandExecutionContext, CommandReturn, Dimension, ElementAndBounds, ElementMove, IActionDispatcher, KeyListener, Point, SModelElement } from "sprotty";

export declare namespace Select {
function all(elements: SelectableBoundsAware[]): SelectableBoundsAware[];
function first(elements: SelectableBoundsAware[]): SelectableBoundsAware[];
function last(elements: SelectableBoundsAware[]): SelectableBoundsAware[];
function all(elements: SelectableBoundsAware[]): (SModelElement & import("sprotty").BoundsAware & import("sprotty").Selectable)[];
function first(elements: SelectableBoundsAware[]): (SModelElement & import("sprotty").BoundsAware & import("sprotty").Selectable)[];
function last(elements: SelectableBoundsAware[]): (SModelElement & import("sprotty").BoundsAware & import("sprotty").Selectable)[];
}

@@ -58,0 +58,0 @@ export declare class AlignElementsAction implements Action {

@@ -38,3 +38,3 @@ /********************************************************************************

newBounds: ElementAndBounds[];
readonly kind = "changeBoundsOperation";
readonly kind = "changeBounds";
constructor(newBounds: ElementAndBounds[]);

@@ -49,2 +49,14 @@ }

}
export declare class ReconnectConnectionOperationAction implements Action {
readonly connectionElementId: string;
readonly sourceElementId: string;
readonly targetElementId: string;
readonly kind = "reconnectConnection";
constructor(connectionElementId: string, sourceElementId: string, targetElementId: string);
}
export declare class ChangeRoutingPointsOperation implements Action {
newRoutingPoints: ElementAndRoutingPoints[];
readonly kind = "changeRoutingPoints";
constructor(newRoutingPoints: ElementAndRoutingPoints[]);
}
export declare class GenericOperationAction implements Action {

@@ -57,2 +69,6 @@ readonly id: string;

}
export interface ElementAndRoutingPoints {
elementId: string;
newRoutingPoints?: Point[];
}
//# sourceMappingURL=operation-actions.d.ts.map

@@ -50,2 +50,20 @@ "use strict";

exports.ChangeContainerOperation = ChangeContainerOperation;
var ReconnectConnectionOperationAction = /** @class */ (function () {
function ReconnectConnectionOperationAction(connectionElementId, sourceElementId, targetElementId) {
this.connectionElementId = connectionElementId;
this.sourceElementId = sourceElementId;
this.targetElementId = targetElementId;
this.kind = set_operations_1.OperationKind.RECONNECT_CONNECTION;
}
return ReconnectConnectionOperationAction;
}());
exports.ReconnectConnectionOperationAction = ReconnectConnectionOperationAction;
var ChangeRoutingPointsOperation = /** @class */ (function () {
function ChangeRoutingPointsOperation(newRoutingPoints) {
this.newRoutingPoints = newRoutingPoints;
this.kind = set_operations_1.OperationKind.CHANGE_ROUTING_POINTS;
}
return ChangeRoutingPointsOperation;
}());
exports.ChangeRoutingPointsOperation = ChangeRoutingPointsOperation;
var GenericOperationAction = /** @class */ (function () {

@@ -52,0 +70,0 @@ function GenericOperationAction(id, elementId, location) {

@@ -21,5 +21,5 @@ /********************************************************************************

const RECONNECT_CONNECTION = "reconnectConnection";
const REROUTE_CONNECTION = "rerouteConnection";
const DELETE_ELEMENT = "delete";
const CHANGE_BOUNDS = "changeBoundsOperation";
const CHANGE_ROUTING_POINTS = "changeRoutingPoints";
const DELETE_ELEMENT = "deleteElement";
const CHANGE_BOUNDS = "changeBounds";
const CHANGE_CONTAINER = "changeContainer";

@@ -26,0 +26,0 @@ const GENERIC = "generic";

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

OperationKind.RECONNECT_CONNECTION = "reconnectConnection";
OperationKind.REROUTE_CONNECTION = "rerouteConnection";
OperationKind.DELETE_ELEMENT = "delete";
OperationKind.CHANGE_BOUNDS = "changeBoundsOperation";
OperationKind.CHANGE_ROUTING_POINTS = "changeRoutingPoints";
OperationKind.DELETE_ELEMENT = "deleteElement";
OperationKind.CHANGE_BOUNDS = "changeBounds";
OperationKind.CHANGE_CONTAINER = "changeContainer";

@@ -13,0 +13,0 @@ OperationKind.GENERIC = "generic";

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

********************************************************************************/
import { RoutingHandleKind, SModelElement, SRoutableElement, SRoutingHandle } from "sprotty/lib";
export declare function isRoutable<T extends SModelElement>(element: T): element is T & SRoutableElement;
import { RoutingHandleKind, SModelElement, SModelExtension, SRoutableElement, SRoutingHandle } from "sprotty/lib";
export declare const reconnectFeature: unique symbol;
export interface Reconnectable extends SModelExtension {
}
export declare function isReconnectable(element: SModelElement): element is SRoutableElement & Reconnectable;
export declare function isReconnectHandle(element: SModelElement | undefined): element is SReconnectHandle;
export declare function isRoutingHandle(element: SModelElement | undefined): element is SRoutingHandle;
export declare function addReconnectHandles(element: SRoutableElement): void;

@@ -22,0 +24,0 @@ export declare function removeReconnectHandles(element: SRoutableElement): void;

@@ -32,7 +32,8 @@ "use strict";

var lib_1 = require("sprotty/lib");
exports.reconnectFeature = Symbol("reconnectFeature");
function isReconnectable(element) {
return element instanceof lib_1.SRoutableElement && element.hasFeature(exports.reconnectFeature);
}
exports.isReconnectable = isReconnectable;
var ROUTING_HANDLE_SOURCE_INDEX = -2;
function isRoutable(element) {
return element instanceof lib_1.SRoutableElement && element.routingPoints !== undefined;
}
exports.isRoutable = isRoutable;
function isReconnectHandle(element) {

@@ -42,6 +43,2 @@ return element !== undefined && element instanceof SReconnectHandle;

exports.isReconnectHandle = isReconnectHandle;
function isRoutingHandle(element) {
return element !== undefined && element instanceof lib_1.SRoutingHandle;
}
exports.isRoutingHandle = isRoutingHandle;
function addReconnectHandles(element) {

@@ -48,0 +45,0 @@ removeReconnectHandles(element);

@@ -20,10 +20,7 @@ "use strict";

var sprotty_1 = require("sprotty");
var types_1 = require("../../types");
var support_1 = require("./support");
var glsp_action_dispatcher_1 = require("./glsp-action-dispatcher");
var requestResponseModule = new inversify_1.ContainerModule(function (bind, unbind, isBound, rebind) {
bind(support_1.RequestResponseSupport).toSelf().inSingletonScope();
bind(types_1.GLSP_TYPES.RequestResponseSupport).toService(support_1.RequestResponseSupport);
bind(sprotty_1.TYPES.IActionHandlerInitializer).toService(support_1.RequestResponseSupport);
rebind(sprotty_1.TYPES.IActionDispatcher).to(glsp_action_dispatcher_1.GLSPActionDispatcher).inSingletonScope();
});
exports.default = requestResponseModule;
//# sourceMappingURL=di.config.js.map
import { VNode } from "snabbdom/vnode";
import { Action, CommandExecutionContext, CommandReturn, MouseListener, Point, SModelElement } from "sprotty/lib";
import { IMovementRestrictor } from "../change-bounds/movement-restrictor";
import { Action, CommandExecutionContext, CommandReturn, MouseListener, MoveAction, Point, SModelElement, SModelRoot } from "sprotty/lib";
import { ChangeBoundsTool } from "../tools/change-bounds-tool";
import { FeedbackCommand } from "./model";

@@ -34,8 +34,13 @@ export declare class ShowChangeBoundsToolResizeFeedbackAction implements Action {

export declare class FeedbackMoveMouseListener extends MouseListener {
protected movementRestrictor?: IMovementRestrictor | undefined;
protected tool: ChangeBoundsTool;
hasDragged: boolean;
lastDragPosition: Point | undefined;
constructor(movementRestrictor?: IMovementRestrictor | undefined);
startDragPosition: Point | undefined;
elementId2startPos: Map<string, Point>;
constructor(tool: ChangeBoundsTool);
mouseDown(target: SModelElement, event: MouseEvent): Action[];
mouseMove(target: SModelElement, event: MouseEvent): Action[];
protected collectStartPositions(root: SModelRoot): void;
protected getElementMoves(target: SModelElement, event: MouseEvent, isFinished: boolean): MoveAction | undefined;
protected validateMove(startPostion: Point, toPosition: Point, element: SModelElement, isFinished: boolean): Point;
protected snap(position: Point, element: SModelElement, isSnap: boolean): Point;
mouseEnter(target: SModelElement, event: MouseEvent): Action[];

@@ -42,0 +47,0 @@ mouseUp(target: SModelElement, event: MouseEvent): Action[];

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

};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spread = (this && this.__spread) || function () {
for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
return ar;
};
Object.defineProperty(exports, "__esModule", { value: true });

@@ -47,4 +67,4 @@ /********************************************************************************

var smodel_util_1 = require("../../utils/smodel-util");
var viewpoint_util_1 = require("../../utils/viewpoint-util");
var model_1 = require("../change-bounds/model");
var movement_restrictor_1 = require("../change-bounds/movement-restrictor");
var model_2 = require("./model");

@@ -75,6 +95,9 @@ var ShowChangeBoundsToolResizeFeedbackAction = /** @class */ (function () {

var index = context.root.index;
index.all().filter(model_1.isResizeable).forEach(model_1.removeResizeHandles);
index
.all()
.filter(model_1.isResizable)
.forEach(model_1.removeResizeHandles);
if (smodel_util_1.isNotUndefined(this.action.elementId)) {
var resizeElement = index.getById(this.action.elementId);
if (smodel_util_1.isNotUndefined(resizeElement) && model_1.isResizeable(resizeElement)) {
if (smodel_util_1.isNotUndefined(resizeElement) && model_1.isResizable(resizeElement)) {
model_1.addResizeHandles(resizeElement);

@@ -85,3 +108,3 @@ }

};
ShowChangeBoundsToolResizeFeedbackCommand.KIND = 'showChangeBoundsToolResizeFeedback';
ShowChangeBoundsToolResizeFeedbackCommand.KIND = "showChangeBoundsToolResizeFeedback";
ShowChangeBoundsToolResizeFeedbackCommand = __decorate([

@@ -104,6 +127,9 @@ inversify_1.injectable(),

var index = context.root.index;
index.all().filter(model_1.isResizeable).forEach(model_1.removeResizeHandles);
index
.all()
.filter(model_1.isResizable)
.forEach(model_1.removeResizeHandles);
return context.root;
};
HideChangeBoundsToolResizeFeedbackCommand.KIND = 'hideChangeBoundsToolResizeFeedback';
HideChangeBoundsToolResizeFeedbackCommand.KIND = "hideChangeBoundsToolResizeFeedback";
HideChangeBoundsToolResizeFeedbackCommand = __decorate([

@@ -126,16 +152,17 @@ inversify_1.injectable(),

__extends(FeedbackMoveMouseListener, _super);
function FeedbackMoveMouseListener(movementRestrictor) {
function FeedbackMoveMouseListener(tool) {
var _this = _super.call(this) || this;
_this.movementRestrictor = movementRestrictor;
_this.tool = tool;
_this.hasDragged = false;
_this.elementId2startPos = new Map();
return _this;
}
FeedbackMoveMouseListener.prototype.mouseDown = function (target, event) {
if (event.button === 0) {
if (event.button === 0 && !(target instanceof model_1.SResizeHandle)) {
var moveable = lib_1.findParentByFeature(target, lib_1.isMoveable);
if (moveable !== undefined) {
this.lastDragPosition = { x: event.pageX, y: event.pageY };
this.startDragPosition = { x: event.pageX, y: event.pageY };
}
else {
this.lastDragPosition = undefined;
this.startDragPosition = undefined;
}

@@ -147,26 +174,48 @@ this.hasDragged = false;

FeedbackMoveMouseListener.prototype.mouseMove = function (target, event) {
var _this = this;
var result = [];
if (event.buttons === 0)
this.mouseUp(target, event);
else if (this.lastDragPosition) {
var viewport = lib_1.findParentByFeature(target, lib_1.isViewport);
else if (this.startDragPosition) {
if (this.elementId2startPos.size === 0) {
this.collectStartPositions(target.root);
}
this.hasDragged = true;
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 isValidMove_1 = true;
target.root.index.all()
.filter(function (element) { return lib_1.isSelectable(element) && element.selected; })
.forEach(function (element) {
if (model_1.isBoundsAwareMoveable(element)) {
// If a movement restrictor is bound attemt a non restricted move
if (_this.movementRestrictor) {
isValidMove_1 = _this.movementRestrictor.attemptMove(element, mousePoint_1, target, { x: dx_1, y: dy_1 }, result);
}
}
if (lib_1.isMoveable(element) && isValidMove_1) {
nodeMoves_1.push({
var moveAction = this.getElementMoves(target, event, false);
if (moveAction)
result.push(moveAction);
}
return result;
};
FeedbackMoveMouseListener.prototype.collectStartPositions = function (root) {
var _this = this;
root.index
.all()
.filter(function (element) { return lib_1.isSelectable(element) && element.selected; })
.forEach(function (element) {
if (lib_1.isMoveable(element)) {
_this.elementId2startPos.set(element.id, element.position);
}
});
};
FeedbackMoveMouseListener.prototype.getElementMoves = function (target, event, isFinished) {
var _this = this;
if (!this.startDragPosition)
return undefined;
var elementMoves = [];
var viewport = lib_1.findParentByFeature(target, lib_1.isViewport);
var zoom = viewport ? viewport.zoom : 1;
var delta = {
x: (event.pageX - this.startDragPosition.x) / zoom,
y: (event.pageY - this.startDragPosition.y) / zoom
};
this.elementId2startPos.forEach(function (startPosition, elementId) {
var element = target.root.index.getById(elementId);
if (element) {
var toPosition = _this.snap({
x: startPosition.x + delta.x,
y: startPosition.y + delta.y
}, element, !event.shiftKey);
if (lib_1.isMoveable(element)) {
toPosition = _this.validateMove(startPosition, toPosition, element, isFinished);
elementMoves.push({
elementId: element.id,

@@ -177,16 +226,36 @@ fromPosition: {

},
toPosition: {
x: element.position.x + dx_1,
y: element.position.y + dy_1
}
toPosition: toPosition
});
}
});
this.lastDragPosition = { x: event.pageX, y: event.pageY };
if (nodeMoves_1.length > 0 && isValidMove_1) {
result.push(new lib_1.MoveAction(nodeMoves_1, false));
}
});
if (elementMoves.length > 0)
return new lib_1.MoveAction(elementMoves, false, isFinished);
else
return undefined;
};
FeedbackMoveMouseListener.prototype.validateMove = function (startPostion, toPosition, element, isFinished) {
var newPosition = toPosition;
if (this.tool.movementRestrictor) {
var valid = this.tool.movementRestrictor.validate(toPosition, element);
var actions = void 0;
if (!valid) {
actions = movement_restrictor_1.createMovementRestrictionFeedback(element, this.tool.movementRestrictor);
if (isFinished) {
newPosition = startPostion;
}
}
else {
actions = movement_restrictor_1.removeMovementRestrictionFeedback(element, this.tool.movementRestrictor);
}
this.tool.dispatchFeedback(this, actions);
}
return result;
return newPosition;
};
FeedbackMoveMouseListener.prototype.snap = function (position, element, isSnap) {
if (isSnap && this.tool.snapper)
return this.tool.snapper.snap(position, element);
else
return position;
};
FeedbackMoveMouseListener.prototype.mouseEnter = function (target, event) {

@@ -198,5 +267,16 @@ if (target instanceof lib_1.SModelRoot && event.buttons === 0)

FeedbackMoveMouseListener.prototype.mouseUp = function (target, event) {
var result = [];
if (this.startDragPosition) {
var moveAction = this.getElementMoves(target, event, true);
if (moveAction) {
result.push(moveAction);
}
if (this.tool.movementRestrictor) {
result.push.apply(result, __spread(movement_restrictor_1.removeMovementRestrictionFeedback(target, this.tool.movementRestrictor)));
}
}
this.hasDragged = false;
this.lastDragPosition = undefined;
return [];
this.startDragPosition = undefined;
this.elementId2startPos.clear();
return result;
};

@@ -203,0 +283,0 @@ FeedbackMoveMouseListener.prototype.decorate = function (vnode, element) {

@@ -6,4 +6,5 @@ import { Action, AnchorComputerRegistry, CommandExecutionContext, CommandReturn, MouseListener, SDanglingAnchor, SModelElement, SModelRoot, SRoutableElement } from "sprotty/lib";

readonly sourceId: string;
readonly routerKind?: string | undefined;
kind: string;
constructor(elementTypeId: string, sourceId: string);
constructor(elementTypeId: string, sourceId: string, routerKind?: string | undefined);
}

@@ -10,0 +11,0 @@ export declare class DrawFeedbackEdgeCommand extends FeedbackCommand {

@@ -45,9 +45,10 @@ "use strict";

var lib_1 = require("sprotty/lib");
var smodel_util_1 = require("../../utils/smodel-util");
var viewpoint_util_1 = require("../../utils/viewpoint-util");
var model_1 = require("../reconnect/model");
var model_2 = require("./model");
var model_1 = require("./model");
var DrawFeedbackEdgeAction = /** @class */ (function () {
function DrawFeedbackEdgeAction(elementTypeId, sourceId) {
function DrawFeedbackEdgeAction(elementTypeId, sourceId, routerKind) {
this.elementTypeId = elementTypeId;
this.sourceId = sourceId;
this.routerKind = routerKind;
this.kind = DrawFeedbackEdgeCommand.KIND;

@@ -66,3 +67,3 @@ }

DrawFeedbackEdgeCommand.prototype.execute = function (context) {
drawFeedbackEdge(context, this.action.sourceId, this.action.elementTypeId);
drawFeedbackEdge(context, this.action.sourceId, this.action.elementTypeId, this.action.routerKind);
return context.root;

@@ -77,3 +78,3 @@ };

return DrawFeedbackEdgeCommand;
}(model_2.FeedbackCommand));
}(model_1.FeedbackCommand));
exports.DrawFeedbackEdgeCommand = DrawFeedbackEdgeCommand;

@@ -101,3 +102,3 @@ var RemoveFeedbackEdgeAction = /** @class */ (function () {

return RemoveFeedbackEdgeCommand;
}(model_2.FeedbackCommand));
}(model_1.FeedbackCommand));
exports.RemoveFeedbackEdgeCommand = RemoveFeedbackEdgeCommand;

@@ -159,3 +160,3 @@ var FeedbackEdgeEnd = /** @class */ (function (_super) {

exports.feedbackEdgeEndId = feedbackEdgeEndId;
function drawFeedbackEdge(context, sourceId, elementTypeId) {
function drawFeedbackEdge(context, sourceId, elementTypeId, routerKind) {
var root = context.root;

@@ -172,12 +173,14 @@ var sourceChild = root.index.getById(sourceId);

edgeEnd.id = feedbackEdgeEndId(root);
edgeEnd.position = { x: source.bounds.x, y: source.bounds.y };
edgeEnd.position = viewpoint_util_1.toAbsolutePosition(source);
var feedbackEdgeSchema = {
type: 'edge',
type: elementTypeId,
id: feedbackEdgeId(root),
sourceId: source.id,
targetId: edgeEnd.id,
cssClasses: ["feedback-edge"],
routerKind: routerKind,
opacity: 0.3
};
var feedbackEdge = context.modelFactory.createElement(feedbackEdgeSchema);
if (model_1.isRoutable(feedbackEdge)) {
if (smodel_util_1.isRoutable(feedbackEdge)) {
edgeEnd.feedbackEdge = feedbackEdge;

@@ -184,0 +187,0 @@ root.add(edgeEnd);

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

var creation_tool_feedback_1 = require("./creation-tool-feedback");
var cursor_feedback_1 = require("./cursor-feedback");
var css_feedback_1 = require("./css-feedback");
var edge_edit_tool_feedback_1 = require("./edge-edit-tool-feedback");

@@ -31,4 +31,4 @@ var feedback_action_dispatcher_1 = require("./feedback-action-dispatcher");

bind(types_1.GLSP_TYPES.IFeedbackActionDispatcher).to(feedback_action_dispatcher_1.FeedbackActionDispatcher).inSingletonScope();
lib_1.configureCommand({ bind: bind, isBound: isBound }, css_feedback_1.ModifyCssFeedbackCommand);
// create node and edge tool feedback
lib_1.configureCommand({ bind: bind, isBound: isBound }, cursor_feedback_1.ApplyCursorCSSFeedbackActionCommand);
lib_1.configureCommand({ bind: bind, isBound: isBound }, creation_tool_feedback_1.DrawFeedbackEdgeCommand);

@@ -35,0 +35,0 @@ lib_1.configureCommand({ bind: bind, isBound: isBound }, creation_tool_feedback_1.RemoveFeedbackEdgeCommand);

@@ -77,6 +77,6 @@ "use strict";

var index = context.root.index;
index.all().filter(model_1.isRoutable).forEach(model_1.removeReconnectHandles);
index.all().filter(smodel_util_1.isRoutable).forEach(model_1.removeReconnectHandles);
if (smodel_util_1.isNotUndefined(this.action.elementId)) {
var routableElement = index.getById(this.action.elementId);
if (smodel_util_1.isNotUndefined(routableElement) && model_1.isRoutable(routableElement)) {
if (smodel_util_1.isNotUndefined(routableElement) && smodel_util_1.isRoutable(routableElement)) {
model_1.addReconnectHandles(routableElement);

@@ -105,3 +105,3 @@ }

var index = context.root.index;
index.all().filter(model_1.isRoutable).forEach(model_1.removeReconnectHandles);
index.all().filter(smodel_util_1.isRoutable).forEach(model_1.removeReconnectHandles);
return context.root;

@@ -233,3 +233,3 @@ };

if (event.button === 0) {
var routingHandle = lib_1.findParentByFeature(target, model_1.isRoutingHandle);
var routingHandle = lib_1.findParentByFeature(target, smodel_util_1.isRoutingHandle);
if (routingHandle !== undefined) {

@@ -259,5 +259,5 @@ result.push(new SwitchRoutingModeAction([target.id], []));

target.root.index.all()
.filter(function (element) { return smodel_util_1.isSelected(element); })
.filter(function (element) { return lib_1.isSelected(element); })
.forEach(function (element) {
if (model_1.isRoutingHandle(element)) {
if (smodel_util_1.isRoutingHandle(element)) {
var point = _this.getHandlePosition(element);

@@ -285,3 +285,3 @@ if (point !== undefined) {

var parent_1 = handle.parent;
if (!model_1.isRoutable(parent_1))
if (!smodel_util_1.isRoutable(parent_1))
return undefined;

@@ -334,3 +334,3 @@ var router = this.edgeRouterRegistry.get(parent_1.routerKind);

var feedbackEdge = context.modelFactory.createElement(feedbackEdgeSchema);
if (model_1.isRoutable(feedbackEdge)) {
if (smodel_util_1.isRoutable(feedbackEdge)) {
edgeEnd.feedbackEdge = feedbackEdge;

@@ -337,0 +337,0 @@ root.add(edgeEnd);

@@ -1,19 +0,4 @@

/********************************************************************************
* 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 { VNode } from "snabbdom/vnode";
import { IView, Point, RenderingContext, SModelElement } from "sprotty/lib";
import { SResizeHandle } from '../change-bounds/model';
import { SResizeHandle } from "../change-bounds/model";
/**

@@ -20,0 +5,0 @@ * This view is used for the invisible end of the feedback edge.

"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
/********************************************************************************

@@ -17,14 +24,7 @@ * Copyright (c) 2019 EclipseSource and others.

********************************************************************************/
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
/** @jsx svg */
var inversify_1 = require("inversify");
var snabbdom_jsx_1 = require("snabbdom-jsx");
var snabbdom = require("snabbdom-jsx");
var lib_1 = require("sprotty/lib");
var model_1 = require("../change-bounds/model");
var JSX = { createElement: snabbdom.svg };
/**

@@ -39,3 +39,3 @@ * This view is used for the invisible end of the feedback edge.

var position = model.position || lib_1.ORIGIN_POINT;
return snabbdom_jsx_1.svg("g", { x: position.x, y: position.y });
return JSX.createElement("g", { x: position.x, y: position.y });
};

@@ -54,3 +54,3 @@ FeedbackEdgeEndView = __decorate([

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, r: this.getRadius() });
var node = JSX.createElement("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);

@@ -60,7 +60,7 @@ return node;

// Fallback: Create an empty group
return snabbdom_jsx_1.svg("g", null);
return JSX.createElement("g", null);
};
SResizeHandleView.prototype.getPosition = function (handle) {
var parent = handle.parent;
if (model_1.isResizeable(parent)) {
if (model_1.isResizable(parent)) {
if (handle.location === model_1.ResizeHandleLocation.TopLeft) {

@@ -67,0 +67,0 @@ return { x: 0, y: 0 };

@@ -1,7 +0,8 @@

import { Action, KeyTool, MouseListener, SModelElement, SModelRoot, Tool } from "sprotty/lib";
import { Action, Bounds, BoundsAware, Dimension, EdgeRouterRegistry, ElementAndBounds, ISnapper, KeyTool, ModelLayoutOptions, MouseListener, Point, SModelElement, SModelRoot, SParentElement, Tool } from "sprotty/lib";
import { Resizable, SResizeHandle } from "../change-bounds/model";
import { IMovementRestrictor } from "../change-bounds/movement-restrictor";
import { IMouseTool } from "../mouse-tool/mouse-tool";
import { SelectionListener, SelectionService } from "../select/selection-service";
import { FeedbackMoveMouseListener } from "../tool-feedback/change-bounds-tool-feedback";
import { IFeedbackActionDispatcher } from "../tool-feedback/feedback-action-dispatcher";
import { IFeedbackActionDispatcher, IFeedbackEmitter } from "../tool-feedback/feedback-action-dispatcher";
import { DragAwareMouseListener } from "./drag-aware-mouse-listener";
/**

@@ -25,33 +26,49 @@ * The change bounds tool has the license to move multiple elements or resize a single element by implementing the ChangeBounds operation.

protected feedbackDispatcher: IFeedbackActionDispatcher;
protected movementRestrictor?: IMovementRestrictor | undefined;
readonly edgeRouterRegistry?: EdgeRouterRegistry | undefined;
readonly snapper?: ISnapper | undefined;
readonly movementRestrictor?: IMovementRestrictor | undefined;
static ID: string;
readonly id: string;
protected feedbackMoveMouseListener: FeedbackMoveMouseListener;
protected changeBoundsListener: ChangeBoundsListener;
constructor(selectionService: SelectionService, mouseTool: IMouseTool, keyTool: KeyTool, feedbackDispatcher: IFeedbackActionDispatcher, movementRestrictor?: IMovementRestrictor | undefined);
protected feedbackMoveMouseListener: MouseListener;
protected changeBoundsListener: MouseListener & SelectionListener;
constructor(selectionService: SelectionService, mouseTool: IMouseTool, keyTool: KeyTool, feedbackDispatcher: IFeedbackActionDispatcher, edgeRouterRegistry?: EdgeRouterRegistry | undefined, snapper?: ISnapper | undefined, movementRestrictor?: IMovementRestrictor | undefined);
enable(): void;
protected createMoveMouseListener(): MouseListener;
protected createChangeBoundsListener(): MouseListener & SelectionListener;
disable(): void;
dispatchFeedback(actions: Action[]): void;
dispatchFeedback(feedbackEmmmiter: IFeedbackEmitter, actions: Action[]): void;
}
declare class ChangeBoundsListener extends MouseListener implements SelectionListener {
export declare class ChangeBoundsListener extends DragAwareMouseListener implements SelectionListener {
protected tool: ChangeBoundsTool;
private lastDragPosition;
private positionDelta;
private activeResizeElementId;
private activeResizeHandle;
protected lastDragPosition?: Point;
protected positionDelta: Point;
protected initialPositon: Point | undefined;
protected initialBounds: Bounds | undefined;
protected activeResizeElementId?: string;
protected activeResizeHandle?: SResizeHandle;
constructor(tool: ChangeBoundsTool);
mouseDown(target: SModelElement, event: MouseEvent): Action[];
mouseMove(target: SModelElement, event: MouseEvent): Action[];
mouseUp(target: SModelElement, event: MouseEvent): Action[];
draggingMouseUp(target: SModelElement, event: MouseEvent): Action[];
selectionChanged(root: SModelRoot, selectedElements: string[]): void;
private setActiveResizeElement;
private isActiveResizeElement;
private initPosition;
private updatePosition;
private reset;
private resetPosition;
private hasPositionDelta;
private handleElementResize;
protected setActiveResizeElement(target: SModelElement): boolean;
protected isActiveResizeElement(element?: SModelElement): element is SParentElement & BoundsAware;
protected initPosition(event: MouseEvent): void;
protected updatePosition(target: SModelElement, event: MouseEvent): boolean;
protected reset(): void;
protected resetPosition(): void;
protected handleElementResize(): Action[];
protected handleTopLeftResize(resizeElement: SParentElement & Resizable): Action[];
protected handleTopRightResize(resizeElement: SParentElement & Resizable): Action[];
protected handleBottomLeftResize(resizeElement: SParentElement & Resizable): Action[];
protected handleBottomRightResize(resizeElement: SParentElement & Resizable): Action[];
protected createChangeBoundsAction(element: SModelElement & BoundsAware): Action[];
protected createElementAndBounds(element: SModelElement & BoundsAware): ElementAndBounds[];
protected createSetBoundsAction(element: SModelElement & BoundsAware, x: number, y: number, width: number, height: number): Action[];
protected isValidBoundChange(element: SModelElement & BoundsAware, newPosition: Point, newSize: Dimension): boolean;
protected isValidSize(element: SModelElement & BoundsAware, size: Dimension): boolean;
protected minWidth(element: SModelElement & BoundsAware): number;
protected minHeight(element: SModelElement & BoundsAware): number;
protected getLayoutOptions(element: SModelElement): ModelLayoutOptions | undefined;
}
export {};
//# sourceMappingURL=change-bounds-tool.d.ts.map

@@ -38,2 +38,22 @@ "use strict";

};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spread = (this && this.__spread) || function () {
for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
return ar;
};
Object.defineProperty(exports, "__esModule", { value: true });

@@ -60,5 +80,7 @@ /********************************************************************************

var model_1 = require("../change-bounds/model");
var movement_restrictor_1 = require("../change-bounds/movement-restrictor");
var operation_actions_1 = require("../operation/operation-actions");
var selection_service_1 = require("../select/selection-service");
var change_bounds_tool_feedback_1 = require("../tool-feedback/change-bounds-tool-feedback");
var drag_aware_mouse_listener_1 = require("./drag-aware-mouse-listener");
/**

@@ -78,3 +100,3 @@ * The change bounds tool has the license to move multiple elements or resize a single element by implementing the ChangeBounds operation.

var ChangeBoundsTool = /** @class */ (function () {
function ChangeBoundsTool(selectionService, mouseTool, keyTool, feedbackDispatcher, movementRestrictor) {
function ChangeBoundsTool(selectionService, mouseTool, keyTool, feedbackDispatcher, edgeRouterRegistry, snapper, movementRestrictor) {
this.selectionService = selectionService;

@@ -84,2 +106,4 @@ this.mouseTool = mouseTool;

this.feedbackDispatcher = feedbackDispatcher;
this.edgeRouterRegistry = edgeRouterRegistry;
this.snapper = snapper;
this.movementRestrictor = movementRestrictor;

@@ -91,10 +115,17 @@ this.id = ChangeBoundsTool_1.ID;

// install feedback move mouse listener for client-side move updates
this.feedbackMoveMouseListener = new change_bounds_tool_feedback_1.FeedbackMoveMouseListener(this.movementRestrictor);
this.feedbackMoveMouseListener = this.createMoveMouseListener();
this.mouseTool.register(this.feedbackMoveMouseListener);
// instlal change bounds listener for client-side resize updates and server-side updates
this.changeBoundsListener = new ChangeBoundsListener(this);
// install change bounds listener for client-side resize updates and server-side updates
this.changeBoundsListener = this.createChangeBoundsListener();
this.mouseTool.register(this.changeBoundsListener);
this.selectionService.register(this.changeBoundsListener);
// register feedback
this.feedbackDispatcher.registerFeedback(this, [new change_bounds_tool_feedback_1.ShowChangeBoundsToolResizeFeedbackAction]);
};
ChangeBoundsTool.prototype.createMoveMouseListener = function () {
return new change_bounds_tool_feedback_1.FeedbackMoveMouseListener(this);
};
ChangeBoundsTool.prototype.createChangeBoundsListener = function () {
return new ChangeBoundsListener(this);
};
ChangeBoundsTool.prototype.disable = function () {

@@ -104,6 +135,7 @@ this.mouseTool.deregister(this.changeBoundsListener);

this.mouseTool.deregister(this.feedbackMoveMouseListener);
this.feedbackDispatcher.deregisterFeedback(this, [new change_bounds_tool_feedback_1.HideChangeBoundsToolResizeFeedbackAction]);
this.feedbackDispatcher.deregisterFeedback(this.feedbackMoveMouseListener, []);
this.feedbackDispatcher.deregisterFeedback(this.changeBoundsListener, [new change_bounds_tool_feedback_1.HideChangeBoundsToolResizeFeedbackAction]);
};
ChangeBoundsTool.prototype.dispatchFeedback = function (actions) {
this.feedbackDispatcher.registerFeedback(this, actions);
ChangeBoundsTool.prototype.dispatchFeedback = function (feedbackEmmmiter, actions) {
this.feedbackDispatcher.registerFeedback(feedbackEmmmiter, actions);
};

@@ -118,4 +150,6 @@ var ChangeBoundsTool_1;

__param(3, inversify_1.inject(types_1.GLSP_TYPES.IFeedbackActionDispatcher)),
__param(4, inversify_1.inject(types_1.GLSP_TYPES.IMovementRestrictor)), __param(4, inversify_1.optional()),
__metadata("design:paramtypes", [selection_service_1.SelectionService, Object, lib_1.KeyTool, Object, Object])
__param(4, inversify_1.inject(lib_1.EdgeRouterRegistry)), __param(4, inversify_1.optional()),
__param(5, inversify_1.inject(lib_1.TYPES.ISnapper)), __param(5, inversify_1.optional()),
__param(6, inversify_1.inject(types_1.GLSP_TYPES.IMovementRestrictor)), __param(6, inversify_1.optional()),
__metadata("design:paramtypes", [selection_service_1.SelectionService, Object, lib_1.KeyTool, Object, lib_1.EdgeRouterRegistry, Object, Object])
], ChangeBoundsTool);

@@ -130,8 +164,4 @@ return ChangeBoundsTool;

_this.tool = tool;
// members for calculating the correct position change
_this.lastDragPosition = undefined;
_this.positionDelta = { x: 0, y: 0 };
// members for resize mode
_this.activeResizeElementId = undefined;
_this.activeResizeHandle = undefined;
_this.initialPositon = undefined;
return _this;

@@ -141,22 +171,23 @@ }

_super.prototype.mouseDown.call(this, target, event);
var actions = [];
if (event.button === 0) {
// check if we have a resize handle (only single-selection)
if (this.activeResizeElementId && target instanceof model_1.SResizeHandle) {
this.activeResizeHandle = target;
}
else {
this.setActiveResizeElement(target);
}
if (this.activeResizeElementId) {
this.initPosition(event);
}
else {
this.reset();
}
if (event.button !== 0) {
return [];
}
return actions;
// check if we have a resize handle (only single-selection)
if (this.activeResizeElementId && target instanceof model_1.SResizeHandle) {
this.activeResizeHandle = target;
}
else {
this.setActiveResizeElement(target);
}
if (this.activeResizeElementId) {
this.initPosition(event);
}
else {
this.reset();
}
return [];
};
ChangeBoundsListener.prototype.mouseMove = function (target, event) {
if (this.updatePosition(target, event)) {
_super.prototype.mouseMove.call(this, target, event);
if (this.updatePosition(target, event) && this.activeResizeHandle) {
// rely on the FeedbackMoveMouseListener to update the element bounds of selected elements

@@ -168,22 +199,27 @@ // consider resize handles ourselves

};
ChangeBoundsListener.prototype.mouseUp = function (target, event) {
_super.prototype.mouseUp.call(this, target, event);
if (!this.hasPositionDelta()) {
ChangeBoundsListener.prototype.draggingMouseUp = function (target, event) {
var _this = this;
if (this.lastDragPosition === undefined) {
this.resetPosition();
return [];
}
// no further bound changing, simply send the latest data to the server using a single change bounds action for all relevant elements
var actions = [];
if (this.activeResizeHandle) {
// An action. Resize, not move.
var resizeElement = lib_1.findParentByFeature(this.activeResizeHandle, model_1.isResizeable);
// Resize, not move
var resizeElement = lib_1.findParentByFeature(this.activeResizeHandle, model_1.isResizable);
if (this.isActiveResizeElement(resizeElement)) {
createChangeBoundsAction(resizeElement).forEach(function (action) { return actions.push(action); });
this.createChangeBoundsAction(resizeElement).forEach(function (action) { return actions.push(action); });
}
}
else {
// Bounds... Change Bounds.
// Move
var newBounds_1 = [];
smodel_util_1.forEachElement(target, smodel_util_1.isNonRoutableSelectedBoundsAware, function (element) {
return createElementAndBounds(element).forEach(function (bounds) { return newBounds_1.push(bounds); });
var newRoutingPoints_1 = [];
smodel_util_1.forEachElement(target, smodel_util_1.isNonRoutableSelectedMovableBoundsAware, function (element) {
_this.createElementAndBounds(element).forEach(function (bounds) { return newBounds_1.push(bounds); });
// If client routing is enabled -> delegate routingpoints of connected edges to server
if (_this.tool.edgeRouterRegistry && element instanceof lib_1.SConnectableElement) {
element.incomingEdges.map(smodel_util_1.toElementAndRoutingPoints).forEach(function (ear) { return newRoutingPoints_1.push(ear); });
element.outgoingEdges.map(smodel_util_1.toElementAndRoutingPoints).forEach(function (ear) { return newRoutingPoints_1.push(ear); });
}
});

@@ -193,2 +229,5 @@ if (newBounds_1.length > 0) {

}
if (newRoutingPoints_1.length > 0) {
actions.push(new operation_actions_1.ChangeRoutingPointsOperation(newRoutingPoints_1));
}
}

@@ -201,3 +240,3 @@ this.resetPosition();

if (this.activeResizeElementId) {
if (selectedElements.indexOf(this.activeResizeElementId) > -1) {
if (selectedElements.includes(this.activeResizeElementId)) {
// our active element is still selected, nothing to do

@@ -229,6 +268,6 @@ return;

var moveableElement = lib_1.findParentByFeature(target, model_1.isBoundsAwareMoveable);
if (smodel_util_1.isSelected(moveableElement)) {
if (lib_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)]);
this.tool.dispatchFeedback(this, [new change_bounds_tool_feedback_1.ShowChangeBoundsToolResizeFeedbackAction(this.activeResizeElementId)]);
return true;

@@ -242,3 +281,8 @@ }

ChangeBoundsListener.prototype.initPosition = function (event) {
this.initialPositon = { x: event.pageX, y: event.pageY };
this.lastDragPosition = { x: event.pageX, y: event.pageY };
if (this.activeResizeHandle) {
var resizeElement = lib_1.findParentByFeature(this.activeResizeHandle, model_1.isResizable);
this.initialBounds = { x: resizeElement.bounds.x, y: resizeElement.bounds.y, width: resizeElement.bounds.width, height: resizeElement.bounds.height };
}
};

@@ -258,3 +302,3 @@ ChangeBoundsListener.prototype.updatePosition = function (target, event) {

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

@@ -265,7 +309,5 @@ };

this.lastDragPosition = undefined;
this.initialPositon = undefined;
this.positionDelta = { x: 0, y: 0 };
};
ChangeBoundsListener.prototype.hasPositionDelta = function () {
return this.positionDelta.x !== 0 || this.positionDelta.y !== 0;
};
ChangeBoundsListener.prototype.handleElementResize = function () {

@@ -275,59 +317,101 @@ if (!this.activeResizeHandle) {

}
var actions = [];
var resizeElement = lib_1.findParentByFeature(this.activeResizeHandle, model_1.isResizeable);
var resizeElement = lib_1.findParentByFeature(this.activeResizeHandle, model_1.isResizable);
if (this.isActiveResizeElement(resizeElement)) {
switch (this.activeResizeHandle.location) {
case model_1.ResizeHandleLocation.TopLeft:
createSetBoundsAction(resizeElement, resizeElement.bounds.x + this.positionDelta.x, resizeElement.bounds.y + this.positionDelta.y, resizeElement.bounds.width - this.positionDelta.x, resizeElement.bounds.height - this.positionDelta.y)
.forEach(function (action) { return actions.push(action); });
break;
return this.handleTopLeftResize(resizeElement);
case model_1.ResizeHandleLocation.TopRight:
createSetBoundsAction(resizeElement, resizeElement.bounds.x, resizeElement.bounds.y + this.positionDelta.y, resizeElement.bounds.width + this.positionDelta.x, resizeElement.bounds.height - this.positionDelta.y)
.forEach(function (action) { return actions.push(action); });
break;
return this.handleTopRightResize(resizeElement);
case model_1.ResizeHandleLocation.BottomLeft:
createSetBoundsAction(resizeElement, resizeElement.bounds.x + this.positionDelta.x, resizeElement.bounds.y, resizeElement.bounds.width - this.positionDelta.x, resizeElement.bounds.height + this.positionDelta.y)
.forEach(function (action) { return actions.push(action); });
break;
return this.handleBottomLeftResize(resizeElement);
case model_1.ResizeHandleLocation.BottomRight:
createSetBoundsAction(resizeElement, resizeElement.bounds.x, resizeElement.bounds.y, resizeElement.bounds.width + this.positionDelta.x, resizeElement.bounds.height + this.positionDelta.y)
.forEach(function (action) { return actions.push(action); });
break;
return this.handleBottomRightResize(resizeElement);
}
}
return actions;
return [];
};
ChangeBoundsListener.prototype.handleTopLeftResize = function (resizeElement) {
return this.createSetBoundsAction(resizeElement, resizeElement.bounds.x + this.positionDelta.x, resizeElement.bounds.y + this.positionDelta.y, resizeElement.bounds.width - this.positionDelta.x, resizeElement.bounds.height - this.positionDelta.y);
};
ChangeBoundsListener.prototype.handleTopRightResize = function (resizeElement) {
return this.createSetBoundsAction(resizeElement, resizeElement.bounds.x, resizeElement.bounds.y + this.positionDelta.y, resizeElement.bounds.width + this.positionDelta.x, resizeElement.bounds.height - this.positionDelta.y);
};
ChangeBoundsListener.prototype.handleBottomLeftResize = function (resizeElement) {
return this.createSetBoundsAction(resizeElement, resizeElement.bounds.x + this.positionDelta.x, resizeElement.bounds.y, resizeElement.bounds.width - this.positionDelta.x, resizeElement.bounds.height + this.positionDelta.y);
};
ChangeBoundsListener.prototype.handleBottomRightResize = function (resizeElement) {
return this.createSetBoundsAction(resizeElement, resizeElement.bounds.x, resizeElement.bounds.y, resizeElement.bounds.width + this.positionDelta.x, resizeElement.bounds.height + this.positionDelta.y);
};
ChangeBoundsListener.prototype.createChangeBoundsAction = function (element) {
if (this.isValidBoundChange(element, element.bounds, element.bounds)) {
return [new operation_actions_1.ChangeBoundsOperationAction([smodel_util_1.toElementAndBounds(element)])];
}
else if (this.initialBounds) {
var actions = [];
if (this.tool.movementRestrictor) {
actions.push.apply(actions, __spread(movement_restrictor_1.removeMovementRestrictionFeedback(element, this.tool.movementRestrictor)));
}
actions.push(new lib_1.SetBoundsAction([{ elementId: element.id, newPosition: this.initialBounds, newSize: this.initialBounds }]));
return actions;
}
return [];
};
ChangeBoundsListener.prototype.createElementAndBounds = function (element) {
if (this.isValidBoundChange(element, element.bounds, element.bounds)) {
return [smodel_util_1.toElementAndBounds(element)];
}
return [];
};
ChangeBoundsListener.prototype.createSetBoundsAction = function (element, x, y, width, height) {
var newPosition = { x: x, y: y };
var newSize = { width: width, height: height };
var result = [];
if (this.isValidBoundChange(element, newPosition, newSize)) {
if (this.tool.movementRestrictor) {
result.push.apply(result, __spread(movement_restrictor_1.removeMovementRestrictionFeedback(element, this.tool.movementRestrictor)));
}
result.push(new lib_1.SetBoundsAction([{ elementId: element.id, newPosition: newPosition, newSize: newSize }]));
}
else if (this.isValidSize(element, newSize)) {
if (this.tool.movementRestrictor) {
result.push.apply(result, __spread(movement_restrictor_1.createMovementRestrictionFeedback(element, this.tool.movementRestrictor)));
}
result.push(new lib_1.SetBoundsAction([{ elementId: element.id, newPosition: newPosition, newSize: newSize }]));
}
return result;
};
ChangeBoundsListener.prototype.isValidBoundChange = function (element, newPosition, newSize) {
var valid = this.isValidSize(element, newSize);
if (this.tool.movementRestrictor) {
return valid && this.tool.movementRestrictor.validate(newPosition, element);
}
return valid;
};
ChangeBoundsListener.prototype.isValidSize = function (element, size) {
return size.width >= this.minWidth(element) && size.height >= this.minHeight(element);
};
ChangeBoundsListener.prototype.minWidth = function (element) {
var layoutOptions = this.getLayoutOptions(element);
if (layoutOptions !== undefined && typeof layoutOptions.minWidth === 'number') {
return layoutOptions.minWidth;
}
return 1;
};
ChangeBoundsListener.prototype.minHeight = function (element) {
var layoutOptions = this.getLayoutOptions(element);
if (layoutOptions !== undefined && typeof layoutOptions.minHeight === 'number') {
return layoutOptions.minHeight;
}
return 1;
};
ChangeBoundsListener.prototype.getLayoutOptions = function (element) {
var layoutOptions = element.layoutOptions;
if (layoutOptions !== undefined) {
return layoutOptions;
}
return undefined;
};
return ChangeBoundsListener;
}(lib_1.MouseListener));
function createChangeBoundsAction(element) {
if (isValidBoundChange(element, element.bounds, element.bounds)) {
return [new operation_actions_1.ChangeBoundsOperationAction([smodel_util_1.toElementAndBounds(element)])];
}
return [];
}
function createElementAndBounds(element) {
if (isValidBoundChange(element, element.bounds, element.bounds)) {
return [smodel_util_1.toElementAndBounds(element)];
}
return [];
}
function createSetBoundsAction(element, x, y, width, height) {
var newPosition = { x: x, y: y };
var newSize = { width: width, height: height };
if (isValidBoundChange(element, newPosition, newSize)) {
return [new lib_1.SetBoundsAction([{ elementId: element.id, newPosition: newPosition, newSize: newSize }])];
}
return [];
}
function isValidBoundChange(element, newPosition, newSize) {
return newSize.width >= minWidth(element) && newSize.height >= minHeight(element);
}
function minWidth(element) {
// currently there are no element-specific constraints
return 1;
}
function minHeight(element) {
// currently there are no element-specific constraints
return 1;
}
}(drag_aware_mouse_listener_1.DragAwareMouseListener));
exports.ChangeBoundsListener = ChangeBoundsListener;
//# sourceMappingURL=change-bounds-tool.js.map

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

import { Action, AnchorComputerRegistry, SModelElement, Tool } from "sprotty/lib";
import { IEditConfigProvider } from "../../base/edit-config/edit-config";
import { Action, AnchorComputerRegistry, SEdge, SModelElement, Tool } from "sprotty/lib";
import { TypeAware } from "../../base/tool-manager/tool-manager-action-handler";
import { Containable } from "../hints/model";
import { ITypeHintProvider } from "../hints/type-hints";
import { IMouseTool } from "../mouse-tool/mouse-tool";

@@ -24,5 +25,5 @@ import { FeedbackEdgeEndMovingMouseListener } from "../tool-feedback/creation-tool-feedback";

protected tool: NodeCreationTool;
private container?;
protected container?: SModelElement & Containable;
constructor(elementTypeId: string, tool: NodeCreationTool);
private creationAllowed;
protected creationAllowed(elementTypeId: string): boolean | undefined;
nonDraggingMouseUp(target: SModelElement, event: MouseEvent): Action[];

@@ -38,7 +39,7 @@ mouseOver(target: SModelElement, event: MouseEvent): Action[];

protected anchorRegistry: AnchorComputerRegistry;
readonly editConfigProvider: IEditConfigProvider;
readonly typeHintProvider: ITypeHintProvider;
elementTypeId: string;
protected creationToolMouseListener: EdgeCreationToolMouseListener;
protected feedbackEndMovingMouseListener: FeedbackEdgeEndMovingMouseListener;
constructor(mouseTool: IMouseTool, feedbackDispatcher: IFeedbackActionDispatcher, anchorRegistry: AnchorComputerRegistry, editConfigProvider: IEditConfigProvider);
constructor(mouseTool: IMouseTool, feedbackDispatcher: IFeedbackActionDispatcher, anchorRegistry: AnchorComputerRegistry, typeHintProvider: ITypeHintProvider);
readonly id: string;

@@ -52,16 +53,16 @@ enable(): void;

protected tool: EdgeCreationTool;
private source?;
private target?;
private currentTarget?;
private allowedTarget;
private edgeEditConfig?;
protected source?: string;
protected target?: string;
protected currentTarget?: SModelElement;
protected allowedTarget: boolean;
protected proxyEdge: SEdge;
constructor(elementTypeId: string, tool: EdgeCreationTool);
private reinitialize;
protected reinitialize(): void;
nonDraggingMouseUp(element: SModelElement, event: MouseEvent): Action[];
private isSourceSelected;
private isTargetSelected;
protected isSourceSelected(): boolean;
protected isTargetSelected(): boolean;
mouseOver(target: SModelElement, event: MouseEvent): Action[];
private isAllowedSource;
private isAllowedTarget;
protected isAllowedSource(element: SModelElement | undefined): boolean;
protected isAllowedTarget(element: SModelElement | undefined): boolean;
}
//# sourceMappingURL=creation-tool.d.ts.map

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

var lib_1 = require("sprotty/lib");
var edit_config_1 = require("../../base/edit-config/edit-config");
var types_1 = require("../../types");
var viewpoint_util_1 = require("../../utils/viewpoint-util");
var model_1 = require("../hints/model");
var operation_actions_1 = require("../operation/operation-actions");
var set_operations_1 = require("../operation/set-operations");
var creation_tool_feedback_1 = require("../tool-feedback/creation-tool-feedback");
var cursor_feedback_1 = require("../tool-feedback/cursor-feedback");
var css_feedback_1 = require("../tool-feedback/css-feedback");
var drag_aware_mouse_listener_1 = require("./drag-aware-mouse-listener");

@@ -75,7 +75,7 @@ exports.TOOL_ID_PREFIX = "tool";

this.mouseTool.register(this.creationToolMouseListener);
this.feedbackDispatcher.registerFeedback(this, [new cursor_feedback_1.ApplyCursorCSSFeedbackAction(cursor_feedback_1.CursorCSS.NODE_CREATION)]);
this.feedbackDispatcher.registerFeedback(this, [css_feedback_1.cursorFeedbackAction(css_feedback_1.CursorCSS.NODE_CREATION)]);
};
NodeCreationTool.prototype.disable = function () {
this.mouseTool.deregister(this.creationToolMouseListener);
this.feedbackDispatcher.deregisterFeedback(this, [new cursor_feedback_1.ApplyCursorCSSFeedbackAction()]);
this.feedbackDispatcher.deregisterFeedback(this, [css_feedback_1.cursorFeedbackAction()]);
};

@@ -102,8 +102,8 @@ NodeCreationTool.prototype.dispatchFeedback = function (actions) {

}
NodeCreationToolMouseListener.prototype.creationAllowed = function (target) {
return this.container || target instanceof lib_1.SModelRoot;
NodeCreationToolMouseListener.prototype.creationAllowed = function (elementTypeId) {
return this.container && this.container.isContainableElement(elementTypeId);
};
NodeCreationToolMouseListener.prototype.nonDraggingMouseUp = function (target, event) {
var result = [];
if (this.creationAllowed(target)) {
if (this.creationAllowed(this.elementTypeId)) {
var containerId = this.container ? this.container.id : undefined;

@@ -119,9 +119,8 @@ var location_1 = viewpoint_util_1.getAbsolutePosition(target, event);

NodeCreationToolMouseListener.prototype.mouseOver = function (target, event) {
var _this = this;
var currentContainer = lib_1.findParent(target, function (e) { return edit_config_1.containmentAllowed(e, _this.elementTypeId); });
var currentContainer = lib_1.findParentByFeature(target, model_1.isContainable);
if (!this.container || currentContainer !== this.container) {
this.container = currentContainer;
var feedback = this.creationAllowed(target)
? new cursor_feedback_1.ApplyCursorCSSFeedbackAction(cursor_feedback_1.CursorCSS.NODE_CREATION) :
new cursor_feedback_1.ApplyCursorCSSFeedbackAction(cursor_feedback_1.CursorCSS.OPERATION_NOT_ALLOWED);
var feedback = this.creationAllowed(this.elementTypeId)
? css_feedback_1.cursorFeedbackAction(css_feedback_1.CursorCSS.NODE_CREATION) :
css_feedback_1.cursorFeedbackAction(css_feedback_1.CursorCSS.OPERATION_NOT_ALLOWED);
this.tool.dispatchFeedback([feedback]);

@@ -142,7 +141,7 @@ }

var EdgeCreationTool = /** @class */ (function () {
function EdgeCreationTool(mouseTool, feedbackDispatcher, anchorRegistry, editConfigProvider) {
function EdgeCreationTool(mouseTool, feedbackDispatcher, anchorRegistry, typeHintProvider) {
this.mouseTool = mouseTool;
this.feedbackDispatcher = feedbackDispatcher;
this.anchorRegistry = anchorRegistry;
this.editConfigProvider = editConfigProvider;
this.typeHintProvider = typeHintProvider;
this.elementTypeId = "unknown";

@@ -162,3 +161,3 @@ }

this.mouseTool.register(this.feedbackEndMovingMouseListener);
this.dispatchFeedback([new cursor_feedback_1.ApplyCursorCSSFeedbackAction(cursor_feedback_1.CursorCSS.OPERATION_NOT_ALLOWED)]);
this.dispatchFeedback([css_feedback_1.cursorFeedbackAction(css_feedback_1.CursorCSS.OPERATION_NOT_ALLOWED)]);
};

@@ -168,3 +167,3 @@ EdgeCreationTool.prototype.disable = function () {

this.mouseTool.deregister(this.feedbackEndMovingMouseListener);
this.feedbackDispatcher.deregisterFeedback(this, [new creation_tool_feedback_1.RemoveFeedbackEdgeAction(), new cursor_feedback_1.ApplyCursorCSSFeedbackAction()]);
this.feedbackDispatcher.deregisterFeedback(this, [new creation_tool_feedback_1.RemoveFeedbackEdgeAction(), css_feedback_1.cursorFeedbackAction()]);
};

@@ -179,3 +178,3 @@ EdgeCreationTool.prototype.dispatchFeedback = function (actions) {

__param(2, inversify_1.inject(lib_1.AnchorComputerRegistry)),
__param(3, inversify_1.inject(types_1.GLSP_TYPES.IEditConfigProvider)),
__param(3, inversify_1.inject(types_1.GLSP_TYPES.ITypeHintProvider)),
__metadata("design:paramtypes", [Object, Object, lib_1.AnchorComputerRegistry, Object])

@@ -193,6 +192,4 @@ ], EdgeCreationTool);

_this.allowedTarget = false;
var config = tool.editConfigProvider.getEditConfig(_this.elementTypeId);
if (config && config.configType === edit_config_1.edgeEditConfig) {
_this.edgeEditConfig = config;
}
_this.proxyEdge = new lib_1.SEdge();
_this.proxyEdge.type = elementTypeId;
return _this;

@@ -254,8 +251,8 @@ }

if (this.allowedTarget) {
var action = !this.isSourceSelected() ? new cursor_feedback_1.ApplyCursorCSSFeedbackAction(cursor_feedback_1.CursorCSS.EDGE_CREATION_SOURCE) :
new cursor_feedback_1.ApplyCursorCSSFeedbackAction(cursor_feedback_1.CursorCSS.EDGE_CREATION_TARGET);
var action = !this.isSourceSelected() ? css_feedback_1.cursorFeedbackAction(css_feedback_1.CursorCSS.EDGE_CREATION_SOURCE) :
css_feedback_1.cursorFeedbackAction(css_feedback_1.CursorCSS.EDGE_CREATION_TARGET);
return [action];
}
}
return [new cursor_feedback_1.ApplyCursorCSSFeedbackAction(cursor_feedback_1.CursorCSS.OPERATION_NOT_ALLOWED)];
return [css_feedback_1.cursorFeedbackAction(css_feedback_1.CursorCSS.OPERATION_NOT_ALLOWED)];
}

@@ -265,6 +262,6 @@ return [];

EdgeCreationToolMouseListener.prototype.isAllowedSource = function (element) {
return element !== undefined && this.edgeEditConfig ? this.edgeEditConfig.isAllowedSource(element) : false;
return element !== undefined && lib_1.isConnectable(element) && element.canConnect(this.proxyEdge, "source");
};
EdgeCreationToolMouseListener.prototype.isAllowedTarget = function (element) {
return element !== undefined && this.edgeEditConfig ? this.edgeEditConfig.isAllowedTarget(element) : false;
return element !== undefined && lib_1.isConnectable(element) && element.canConnect(this.proxyEdge, "target");
};

@@ -271,0 +268,0 @@ EdgeCreationToolMouseListener = __decorate([

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

var operation_actions_1 = require("../operation/operation-actions");
var cursor_feedback_1 = require("../tool-feedback/cursor-feedback");
var css_feedback_1 = require("../tool-feedback/css-feedback");
/**

@@ -83,3 +83,3 @@ * Deletes selected elements when hitting the `Del` key.

if (keyboard_1.matchesKeystroke(event, 'Delete')) {
var deleteElementIds = Array.from(element.root.index.all().filter(function (e) { return lib_1.isSelectable(e) && e.selected; })
var deleteElementIds = Array.from(element.root.index.all().filter(function (e) { return lib_1.isDeletable(e) && lib_1.isSelectable(e) && e.selected; })
.filter(function (e) { return e.id !== e.root.id; }).map(function (e) { return e.id; }));

@@ -109,7 +109,7 @@ return [new operation_actions_1.DeleteElementOperationAction(deleteElementIds)];

this.mouseTool.register(this.deleteToolMouseListener);
this.feedbackDispatcher.registerFeedback(this, [new cursor_feedback_1.ApplyCursorCSSFeedbackAction(cursor_feedback_1.CursorCSS.ELEMENT_DELETION)]);
this.feedbackDispatcher.registerFeedback(this, [css_feedback_1.cursorFeedbackAction(css_feedback_1.CursorCSS.ELEMENT_DELETION)]);
};
MouseDeleteTool.prototype.disable = function () {
this.mouseTool.deregister(this.deleteToolMouseListener);
this.feedbackDispatcher.registerFeedback(this, [new cursor_feedback_1.ApplyCursorCSSFeedbackAction()]);
this.feedbackDispatcher.registerFeedback(this, [css_feedback_1.cursorFeedbackAction()]);
};

@@ -133,3 +133,3 @@ var MouseDeleteTool_1;

DeleteToolMouseListener.prototype.mouseUp = function (target, event) {
if (target instanceof lib_1.SModelRoot) {
if (!lib_1.isDeletable(target)) {
return [];

@@ -136,0 +136,0 @@ }

@@ -26,4 +26,4 @@ /********************************************************************************

export declare class DragAwareMouseListener extends MouseListener {
private isMouseDown;
private isMouseDrag;
private _isMouseDown;
private _isMouseDrag;
mouseDown(target: SModelElement, event: MouseEvent): Action[];

@@ -34,3 +34,5 @@ mouseMove(target: SModelElement, event: MouseEvent): Action[];

draggingMouseUp(element: SModelElement, event: MouseEvent): Action[];
readonly isMouseDrag: boolean;
readonly isMouseDown: boolean;
}
//# sourceMappingURL=drag-aware-mouse-listener.d.ts.map

@@ -44,13 +44,13 @@ "use strict";

var _this = _super !== null && _super.apply(this, arguments) || this;
_this.isMouseDown = false;
_this.isMouseDrag = false;
_this._isMouseDown = false;
_this._isMouseDrag = false;
return _this;
}
DragAwareMouseListener.prototype.mouseDown = function (target, event) {
this.isMouseDown = true;
this._isMouseDown = true;
return [];
};
DragAwareMouseListener.prototype.mouseMove = function (target, event) {
if (this.isMouseDown) {
this.isMouseDrag = true;
if (this._isMouseDown) {
this._isMouseDrag = true;
}

@@ -60,5 +60,5 @@ return [];

DragAwareMouseListener.prototype.mouseUp = function (element, event) {
this.isMouseDown = false;
if (this.isMouseDrag) {
this.isMouseDrag = false;
this._isMouseDown = false;
if (this._isMouseDrag) {
this._isMouseDrag = false;
return this.draggingMouseUp(element, event);

@@ -74,2 +74,16 @@ }

};
Object.defineProperty(DragAwareMouseListener.prototype, "isMouseDrag", {
get: function () {
return this._isMouseDrag;
},
enumerable: true,
configurable: true
});
Object.defineProperty(DragAwareMouseListener.prototype, "isMouseDown", {
get: function () {
return this._isMouseDown;
},
enumerable: true,
configurable: true
});
return DragAwareMouseListener;

@@ -76,0 +90,0 @@ }(lib_1.MouseListener));

@@ -1,3 +0,4 @@

import { Action, AnchorComputerRegistry, EdgeRouterRegistry, MouseListener, SModelElement, SModelRoot, Tool } from "sprotty/lib";
import { Action, AnchorComputerRegistry, Connectable, EdgeRouterRegistry, MouseListener, SModelElement, SModelRoot, SRoutableElement, SRoutingHandle, Tool } from "sprotty/lib";
import { IMouseTool } from "../mouse-tool/mouse-tool";
import { SReconnectHandle } from "../reconnect/model";
import { SelectionListener, SelectionService } from "../select/selection-service";

@@ -25,19 +26,19 @@ import { FeedbackEdgeRouteMovingMouseListener, FeedbackEdgeSourceMovingMouseListener, FeedbackEdgeTargetMovingMouseListener } from "../tool-feedback/edge-edit-tool-feedback";

protected tool: EdgeEditTool;
private isMouseDown;
private edge?;
private routingHandle?;
private newConnectable?;
private reconnectMode?;
protected isMouseDown: boolean;
protected edge?: SRoutableElement;
protected routingHandle?: SRoutingHandle;
protected newConnectable?: SModelElement & Connectable;
protected reconnectMode?: 'NEW_SOURCE' | 'NEW_TARGET';
constructor(tool: EdgeEditTool);
private isValidEdge;
private setEdgeSelected;
private isEdgeSelected;
private setReconnectHandleSelected;
private isReconnecting;
private isReconnectingNewSource;
private setRoutingHandleSelected;
private requiresReconnect;
private setNewConnectable;
private isReadyToReconnect;
private isReadyToReroute;
protected isValidEdge(edge?: SRoutableElement): edge is SRoutableElement;
protected setEdgeSelected(edge: SRoutableElement): void;
protected isEdgeSelected(): boolean;
protected setReconnectHandleSelected(edge: SRoutableElement, reconnectHandle: SReconnectHandle): void;
protected isReconnecting(): boolean;
protected isReconnectingNewSource(): boolean;
protected setRoutingHandleSelected(edge: SRoutableElement, routingHandle: SRoutingHandle): void;
protected requiresReconnect(sourceId: string, targetId: string): boolean;
protected setNewConnectable(connectable?: SModelElement & Connectable): void;
protected isReadyToReconnect(): boolean | undefined;
protected isReadyToReroute(): boolean;
mouseDown(target: SModelElement, event: MouseEvent): Action[];

@@ -49,6 +50,6 @@ mouseMove(target: SModelElement, event: MouseEvent): Action[];

reset(): void;
private resetData;
private resetFeedback;
protected resetData(): void;
protected resetFeedback(): void;
}
export {};
//# sourceMappingURL=edge-edit-tool.d.ts.map

@@ -76,10 +76,9 @@ "use strict";

var lib_1 = require("sprotty/lib");
var edit_config_1 = require("../../base/edit-config/edit-config");
var types_1 = require("../../types");
var smodel_util_1 = require("../../utils/smodel-util");
var action_definitions_1 = require("../reconnect/action-definitions");
var operation_actions_1 = require("../operation/operation-actions");
var model_1 = require("../reconnect/model");
var selection_service_1 = require("../select/selection-service");
var creation_tool_feedback_1 = require("../tool-feedback/creation-tool-feedback");
var cursor_feedback_1 = require("../tool-feedback/cursor-feedback");
var css_feedback_1 = require("../tool-feedback/css-feedback");
var edge_edit_tool_feedback_1 = require("../tool-feedback/edge-edit-tool-feedback");

@@ -142,3 +141,3 @@ var EdgeEditTool = /** @class */ (function () {

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

@@ -152,6 +151,13 @@ ReconnectEdgeListener.prototype.setEdgeSelected = function (edge) {

// note: order is important here as we want the reconnect handles to cover the routing handles
this.tool.dispatchFeedback([new edge_edit_tool_feedback_1.SwitchRoutingModeAction([this.edge.id], []), new edge_edit_tool_feedback_1.ShowEdgeReconnectHandlesFeedbackAction(this.edge.id)]);
var feedbackActions = [];
if (lib_1.canEditRouting(edge)) {
feedbackActions.push(new edge_edit_tool_feedback_1.SwitchRoutingModeAction([this.edge.id], []));
}
if (model_1.isReconnectable(edge)) {
feedbackActions.push(new edge_edit_tool_feedback_1.ShowEdgeReconnectHandlesFeedbackAction(this.edge.id));
}
this.tool.dispatchFeedback(feedbackActions);
};
ReconnectEdgeListener.prototype.isEdgeSelected = function () {
return this.edge !== undefined && smodel_util_1.isSelected(this.edge);
return this.edge !== undefined && lib_1.isSelected(this.edge);
};

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

this.tool.dispatchFeedback([new edge_edit_tool_feedback_1.HideEdgeReconnectHandlesFeedbackAction(),
new cursor_feedback_1.ApplyCursorCSSFeedbackAction(cursor_feedback_1.CursorCSS.EDGE_RECONNECT),
css_feedback_1.cursorFeedbackAction(css_feedback_1.CursorCSS.EDGE_RECONNECT),
new edge_edit_tool_feedback_1.DrawFeedbackEdgeSourceAction(this.edge.type, this.edge.targetId)]);

@@ -169,3 +175,3 @@ this.reconnectMode = "NEW_SOURCE";

this.tool.dispatchFeedback([new edge_edit_tool_feedback_1.HideEdgeReconnectHandlesFeedbackAction(),
new cursor_feedback_1.ApplyCursorCSSFeedbackAction(cursor_feedback_1.CursorCSS.EDGE_CREATION_TARGET),
css_feedback_1.cursorFeedbackAction(css_feedback_1.CursorCSS.EDGE_CREATION_TARGET),
new creation_tool_feedback_1.DrawFeedbackEdgeAction(this.edge.type, this.edge.sourceId)]);

@@ -204,4 +210,4 @@ this.reconnectMode = "NEW_TARGET";

var reconnectHandle = lib_1.findParentByFeature(target, model_1.isReconnectHandle);
var routingHandle = !reconnectHandle ? lib_1.findParentByFeature(target, model_1.isRoutingHandle) : undefined;
var edge = lib_1.findParentByFeature(target, model_1.isRoutable);
var routingHandle = !reconnectHandle ? lib_1.findParentByFeature(target, smodel_util_1.isRoutingHandle) : undefined;
var edge = lib_1.findParentByFeature(target, smodel_util_1.isRoutable);
if (this.isEdgeSelected() && edge && reconnectHandle) {

@@ -242,3 +248,3 @@ // PHASE 2 Reconnect: Select reconnect handle on selected edge

if (this.requiresReconnect(sourceId, targetId)) {
result.push(new action_definitions_1.ReconnectConnectionOperationAction(this.edge.id, sourceId, targetId));
result.push(new operation_actions_1.ReconnectConnectionOperationAction(this.edge.id, sourceId, targetId));
}

@@ -250,4 +256,4 @@ this.reset();

var latestEdge = target.index.getById(this.edge.id);
if (latestEdge && model_1.isRoutable(latestEdge)) {
result.push(new action_definitions_1.RerouteConnectionOperationAction(latestEdge.id, latestEdge.routingPoints));
if (latestEdge && smodel_util_1.isRoutable(latestEdge)) {
result.push(new operation_actions_1.ChangeRoutingPointsOperation([{ elementId: latestEdge.id, newRoutingPoints: latestEdge.routingPoints }]));
this.routingHandle = undefined;

@@ -263,10 +269,10 @@ }

this.setNewConnectable(currentTarget);
if (currentTarget && edit_config_1.isConfigurableEdge(this.edge)) {
if ((this.reconnectMode === 'NEW_SOURCE' && this.edge.isAllowedSource(currentTarget.type)) ||
(this.reconnectMode === 'NEW_TARGET' && this.edge.isAllowedTarget(currentTarget.type))) {
this.tool.dispatchFeedback([new cursor_feedback_1.ApplyCursorCSSFeedbackAction(cursor_feedback_1.CursorCSS.EDGE_RECONNECT)]);
if (currentTarget) {
if ((this.reconnectMode === 'NEW_SOURCE' && currentTarget.canConnect(this.edge, "source")) ||
(this.reconnectMode === 'NEW_TARGET' && currentTarget.canConnect(this.edge, "target"))) {
this.tool.dispatchFeedback([css_feedback_1.cursorFeedbackAction(css_feedback_1.CursorCSS.EDGE_RECONNECT)]);
return [];
}
}
this.tool.dispatchFeedback([new cursor_feedback_1.ApplyCursorCSSFeedbackAction(cursor_feedback_1.CursorCSS.OPERATION_NOT_ALLOWED)]);
this.tool.dispatchFeedback([css_feedback_1.cursorFeedbackAction(css_feedback_1.CursorCSS.OPERATION_NOT_ALLOWED)]);
}

@@ -293,3 +299,3 @@ }

if (element) {
var edge = lib_1.findParentByFeature(element, model_1.isRoutable);
var edge = lib_1.findParentByFeature(element, smodel_util_1.isRoutable);
if (this.isValidEdge(edge)) {

@@ -330,3 +336,3 @@ // PHASE 1: Select edge

result.push.apply(result, __spread([new edge_edit_tool_feedback_1.HideEdgeReconnectHandlesFeedbackAction(),
new cursor_feedback_1.ApplyCursorCSSFeedbackAction(), new creation_tool_feedback_1.RemoveFeedbackEdgeAction()]));
css_feedback_1.cursorFeedbackAction(), new creation_tool_feedback_1.RemoveFeedbackEdgeAction()]));
this.tool.dispatchFeedback(result);

@@ -333,0 +339,0 @@ };

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

import { Action, Command, CommandExecutionContext, CommandReturn, IActionDispatcher } from "sprotty/lib";
import { Action, Command, CommandExecutionContext, CommandReturn, IActionDispatcher, SIssueMarker } from "sprotty/lib";
import { Marker } from "../../utils/marker";

@@ -94,2 +94,5 @@ import { IFeedbackActionDispatcher, IFeedbackEmitter } from "../tool-feedback/feedback-action-dispatcher";

}
export declare class GIssueMarker extends SIssueMarker {
constructor();
}
//# sourceMappingURL=validate.d.ts.map

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

var marker_1 = require("../../utils/marker");
var smodel_util_1 = require("../../utils/smodel-util");
var hover_1 = require("../hover/hover");
var model_1 = require("../tool-feedback/model");

@@ -194,2 +196,3 @@ /**

issueMarker.issues.push(issue);
addCSSClassToIssueParent(modelElement, issueMarker);
}

@@ -222,2 +225,8 @@ }

exports.ApplyMarkersCommand = ApplyMarkersCommand;
function addCSSClassToIssueParent(modelElement, issueMarker) {
smodel_util_1.addCssClasses(modelElement, [hover_1.getSeverity(issueMarker)]);
}
function removeCSSClassFromIssueParent(modelElement, issueMarker) {
smodel_util_1.removeCssClasses(modelElement, [hover_1.getSeverity(issueMarker)]);
}
/**

@@ -234,3 +243,3 @@ * Retrieves the `SIssueMarker` contained by the provided model element as

if (issueMarker === undefined) {
issueMarker = new lib_1.SIssueMarker();
issueMarker = new GIssueMarker();
issueMarker.type = "marker";

@@ -328,2 +337,3 @@ issueMarker.issues = new Array();

if (issueMarker !== undefined) {
removeCSSClassFromIssueParent(modelElement, issueMarker);
for (var index = 0; index < issueMarker.issues.length; ++index) {

@@ -338,2 +348,5 @@ var issue = issueMarker.issues[index];

}
else {
addCSSClassToIssueParent(modelElement, issueMarker);
}
}

@@ -367,2 +380,12 @@ }

exports.ClearMarkersCommand = ClearMarkersCommand;
var GIssueMarker = /** @class */ (function (_super) {
__extends(GIssueMarker, _super);
function GIssueMarker() {
var _this = _super.call(this) || this;
_this.features = new Set(lib_1.SDecoration.DEFAULT_FEATURES);
return _this;
}
return GIssueMarker;
}(lib_1.SIssueMarker));
exports.GIssueMarker = GIssueMarker;
//# sourceMappingURL=validate.js.map

@@ -18,5 +18,8 @@ /********************************************************************************

import glspCommandPaletteModule from "./features/command-palette/di.config";
import glspContextMenuModule from "./features/context-menu/di.config";
import glspServerCopyPasteModule from "./features/copy-paste/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 glspHoverModule from "./features/hover/di.config";
import layoutCommandsModule from "./features/layout/di.config";

@@ -31,24 +34,36 @@ import glspMouseToolModule from "./features/mouse-tool/di.config";

export * from 'sprotty/lib';
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/command-stack';
export * from './base/editor-context';
export * from './features/change-bounds/model';
export * from './features/change-bounds/movement-restrictor';
export * from './features/command-palette/action-definitions';
export * from './features/command-palette/action-provider';
export * from './features/change-bounds/snap';
export * from './features/context-actions/action-definitions';
export * from './features/context-menu/delete-element-context-menu';
export * from './features/command-palette/server-command-palette-provider';
export * from './features/copy-paste/copy-paste-handler';
export * from './features/edit-label-validation/edit-label-validator';
export * from './features/execute/execute-command';
export * from './features/execute/model';
export * from './features/hints/action-definition';
export * from './features/hints/type-hints-action-initializer';
export * from './features/mouse-tool/di.config';
export * from './features/hints/request-type-hints-action';
export * from './features/hints/type-hints';
export * from './features/hints/model';
export * from "./features/hover/hover";
export * from './features/layout/layout-commands';
export * from './features/mouse-tool/mouse-tool';
export * from './features/operation/operation-actions';
export * from './features/operation/set-operations';
export * from './features/request-response/action-definitions';
export * from './features/request-response/support';
export * from './features/rank/model';
export * from './features/reconnect/model';
export * from './features/request-response/glsp-action-dispatcher';
export * from './features/save/model';
export * from './features/save/save';
export * from './features/select/di.config';
export * from './features/tool-feedback/change-bounds-tool-feedback';
export * from './features/tool-feedback/creation-tool-feedback';
export * from './features/tool-feedback/css-feedback';
export * from './features/tool-feedback/edge-edit-tool-feedback';
export * from './features/tool-feedback/feedback-action-dispatcher';
export * from './features/tool-feedback/model';
export * from './features/tool-feedback/model';
export * from './features/tool-palette/tool-palette';

@@ -59,5 +74,6 @@ export * from './features/tools/change-bounds-tool';

export * from './features/tools/delete-tool';
export * from './features/tools/drag-aware-mouse-listener';
export * from './features/tools/edge-edit-tool';
export * from './features/undo-redo/model';
export * from './features/validation/validate';
export * from './features/layout/layout-commands';
export * from './lib/model';

@@ -69,5 +85,6 @@ export * from './types';

export * from './utils/viewpoint-util';
export * from './model-source/websocket-diagram-server';
export * from "./model-source/glsp-server-status";
export { validationModule, saveModule, executeModule, paletteModule, toolFeedbackModule, defaultGLSPModule, modelHintsModule, glspCommandPaletteModule, requestResponseModule, //
glspSelectModule, glspMouseToolModule, layoutCommandsModule, glspEditLabelValidationModule };
glspContextMenuModule, glspServerCopyPasteModule, glspSelectModule, glspMouseToolModule, layoutCommandsModule, glspEditLabelValidationModule, glspHoverModule };
//# sourceMappingURL=index.d.ts.map

@@ -25,47 +25,65 @@ "use strict";

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;
var di_config_3 = require("./features/context-menu/di.config");
exports.glspContextMenuModule = di_config_3.default;
var di_config_4 = require("./features/copy-paste/di.config");
exports.glspServerCopyPasteModule = di_config_4.default;
var di_config_5 = require("./features/edit-label-validation/di.config");
exports.glspEditLabelValidationModule = di_config_5.default;
var di_config_6 = require("./features/execute/di.config");
exports.executeModule = di_config_6.default;
var di_config_7 = require("./features/hints/di.config");
exports.modelHintsModule = di_config_7.default;
var di_config_8 = require("./features/hover/di.config");
exports.glspHoverModule = di_config_8.default;
var di_config_9 = require("./features/layout/di.config");
exports.layoutCommandsModule = di_config_9.default;
var di_config_10 = require("./features/mouse-tool/di.config");
exports.glspMouseToolModule = di_config_10.default;
var di_config_11 = require("./features/request-response/di.config");
exports.requestResponseModule = di_config_11.default;
var di_config_12 = require("./features/save/di.config");
exports.saveModule = di_config_12.default;
var di_config_13 = require("./features/select/di.config");
exports.glspSelectModule = di_config_13.default;
var di_config_14 = require("./features/tool-feedback/di.config");
exports.toolFeedbackModule = di_config_14.default;
var di_config_15 = require("./features/tool-palette/di.config");
exports.paletteModule = di_config_15.default;
var di_config_16 = require("./features/validation/di.config");
exports.validationModule = di_config_16.default;
__export(require("sprotty/lib"));
__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/command-stack"));
__export(require("./base/editor-context"));
__export(require("./features/change-bounds/model"));
__export(require("./features/change-bounds/movement-restrictor"));
__export(require("./features/command-palette/action-definitions"));
__export(require("./features/command-palette/action-provider"));
__export(require("./features/change-bounds/snap"));
__export(require("./features/context-actions/action-definitions"));
__export(require("./features/context-menu/delete-element-context-menu"));
__export(require("./features/command-palette/server-command-palette-provider"));
__export(require("./features/copy-paste/copy-paste-handler"));
__export(require("./features/edit-label-validation/edit-label-validator"));
__export(require("./features/execute/execute-command"));
__export(require("./features/execute/model"));
__export(require("./features/hints/action-definition"));
__export(require("./features/hints/type-hints-action-initializer"));
__export(require("./features/mouse-tool/di.config"));
__export(require("./features/hints/request-type-hints-action"));
__export(require("./features/hints/type-hints"));
__export(require("./features/hints/model"));
__export(require("./features/hover/hover"));
__export(require("./features/layout/layout-commands"));
__export(require("./features/mouse-tool/mouse-tool"));
__export(require("./features/operation/operation-actions"));
__export(require("./features/operation/set-operations"));
__export(require("./features/request-response/action-definitions"));
__export(require("./features/request-response/support"));
__export(require("./features/rank/model"));
__export(require("./features/reconnect/model"));
__export(require("./features/request-response/glsp-action-dispatcher"));
__export(require("./features/save/model"));
__export(require("./features/save/save"));
__export(require("./features/select/di.config"));
__export(require("./features/tool-feedback/change-bounds-tool-feedback"));
__export(require("./features/tool-feedback/creation-tool-feedback"));
__export(require("./features/tool-feedback/css-feedback"));
__export(require("./features/tool-feedback/edge-edit-tool-feedback"));
__export(require("./features/tool-feedback/feedback-action-dispatcher"));
__export(require("./features/tool-feedback/model"));
__export(require("./features/tool-feedback/model"));
__export(require("./features/tool-palette/tool-palette"));

@@ -76,5 +94,6 @@ __export(require("./features/tools/change-bounds-tool"));

__export(require("./features/tools/delete-tool"));
__export(require("./features/tools/drag-aware-mouse-listener"));
__export(require("./features/tools/edge-edit-tool"));
__export(require("./features/undo-redo/model"));
__export(require("./features/validation/validate"));
__export(require("./features/layout/layout-commands"));
__export(require("./lib/model"));

@@ -86,3 +105,4 @@ __export(require("./types"));

__export(require("./utils/viewpoint-util"));
__export(require("./model-source/websocket-diagram-server"));
__export(require("./model-source/glsp-server-status"));
//# sourceMappingURL=index.js.map

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

********************************************************************************/
import { SGraph } from "sprotty/lib";
import { SGraph, SModelElement, SModelElementSchema } from "sprotty/lib";
import { Containable } from "../features/hints/model";
import { Saveable } from "../features/save/model";
export declare class GLSPGraph extends SGraph implements Saveable {
export declare class GLSPGraph extends SGraph implements Saveable, Containable {
static readonly DEFAULT_FEATURES: symbol[];
dirty: boolean;
hasFeature(feature: symbol): boolean;
isContainableElement(input: string | SModelElement | SModelElementSchema): boolean;
}
//# sourceMappingURL=model.d.ts.map

@@ -32,11 +32,15 @@ "use strict";

var lib_1 = require("sprotty/lib");
var model_1 = require("../features/save/model");
var model_1 = require("../features/hints/model");
var model_2 = require("../features/save/model");
var GLSPGraph = /** @class */ (function (_super) {
__extends(GLSPGraph, _super);
function GLSPGraph() {
return _super !== null && _super.apply(this, arguments) || this;
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.dirty = false;
return _this;
}
GLSPGraph.prototype.hasFeature = function (feature) {
return feature === model_1.saveFeature || _super.prototype.hasFeature.call(this, feature);
GLSPGraph.prototype.isContainableElement = function (input) {
return true;
};
GLSPGraph.DEFAULT_FEATURES = [lib_1.viewportFeature, lib_1.exportFeature, model_2.saveFeature, model_1.containerFeature];
return GLSPGraph;

@@ -43,0 +47,0 @@ }(lib_1.SGraph));

@@ -41,10 +41,11 @@ "use strict";

var vscode_ws_jsonrpc_1 = require("vscode-ws-jsonrpc");
var action_definitions_1 = require("../features/command-palette/action-definitions");
var action_definitions_1 = require("../features/context-actions/action-definitions");
var execute_command_1 = require("../features/execute/execute-command");
var action_definition_1 = require("../features/hints/action-definition");
var request_type_hints_action_1 = require("../features/hints/request-type-hints-action");
var set_operations_1 = require("../features/operation/set-operations");
var action_definitions_2 = require("../features/request-response/action-definitions");
var save_1 = require("../features/save/save");
var model_1 = require("../features/undo-redo/model");
var validate_1 = require("../features/validation/validate");
var edit_label_validator_1 = require("../features/edit-label-validation/edit-label-validator");
var copy_paste_actions_1 = require("../features/copy-paste/copy-paste-actions");
var GLSPWebsocketDiagramServer = /** @class */ (function (_super) {

@@ -102,3 +103,3 @@ __extends(GLSPWebsocketDiagramServer, _super);

registry.register(set_operations_1.OperationKind.RECONNECT_CONNECTION, diagramServer);
registry.register(set_operations_1.OperationKind.REROUTE_CONNECTION, diagramServer);
registry.register(set_operations_1.OperationKind.CHANGE_ROUTING_POINTS, diagramServer);
registry.register(set_operations_1.OperationKind.CREATE_NODE, diagramServer);

@@ -108,3 +109,3 @@ registry.register(set_operations_1.OperationKind.CHANGE_BOUNDS, diagramServer);

registry.register(execute_command_1.ExecuteServerCommandAction.KIND, diagramServer);
registry.register(action_definition_1.RequestTypeHintsAction.KIND, diagramServer);
registry.register(request_type_hints_action_1.RequestTypeHintsAction.KIND, diagramServer);
registry.register(sprotty_1.ComputedBoundsAction.KIND, diagramServer);

@@ -119,7 +120,10 @@ registry.register(sprotty_1.RequestBoundsCommand.KIND, diagramServer);

registry.register(sprotty_1.ExportSvgAction.KIND, diagramServer);
registry.register(action_definitions_1.RequestCommandPaletteActions.KIND, diagramServer);
registry.register(action_definitions_2.IdentifiableRequestAction.KIND, diagramServer);
registry.register(action_definitions_1.RequestContextActions.KIND, diagramServer);
registry.register(edit_label_validator_1.ValidateLabelEditAction.KIND, diagramServer);
registry.register(validate_1.RequestMarkersAction.KIND, diagramServer);
registry.register(sprotty_1.LayoutAction.KIND, diagramServer);
registry.register(sprotty_1.ApplyLabelEditAction.KIND, diagramServer);
registry.register(copy_paste_actions_1.RequestClipboardDataAction.KIND, diagramServer);
registry.register(copy_paste_actions_1.PasteOperationAction.KIND, diagramServer);
registry.register(copy_paste_actions_1.CutOperationAction.KIND, diagramServer);
// Register an empty handler for SwitchEditMode, to avoid runtime exceptions.

@@ -126,0 +130,0 @@ // We don't want to support SwitchEditMode, but sprotty still sends some corresponding

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

IToolFactory: symbol;
IEditConfigProvider: symbol;
ITypeHintProvider: symbol;
IMovementRestrictor: symbol;
RequestResponseSupport: symbol;
SelectionService: symbol;

@@ -28,3 +27,8 @@ SelectionListener: symbol;

MouseTool: symbol;
IContextMenuService: symbol;
IContextMenuServiceProvider: symbol;
IContextMenuProviderRegistry: symbol;
IContextMenuProvider: symbol;
ICopyPasteHandler: symbol;
};
//# sourceMappingURL=types.d.ts.map

@@ -22,10 +22,14 @@ "use strict";

IToolFactory: Symbol.for("Factory<Tool>"),
IEditConfigProvider: Symbol.for("IEditConfigProvider"),
ITypeHintProvider: Symbol.for("ITypeHintProvider"),
IMovementRestrictor: Symbol.for("IMovmementRestrictor"),
RequestResponseSupport: Symbol.for("RequestResponseSupport"),
SelectionService: Symbol.for("SelectionService"),
SelectionListener: Symbol.for("SelectionListener"),
SModelRootListener: Symbol.for("SModelRootListener"),
MouseTool: Symbol.for("MouseTool")
MouseTool: Symbol.for("MouseTool"),
IContextMenuService: Symbol.for("IContextMenuService"),
IContextMenuServiceProvider: Symbol.for("IContextMenuServiceProvider"),
IContextMenuProviderRegistry: Symbol.for("IContextMenuProviderRegistry"),
IContextMenuProvider: Symbol.for("IContextMenuProvider"),
ICopyPasteHandler: Symbol.for("ICopyPasteHandler")
};
//# sourceMappingURL=types.js.map

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

********************************************************************************/
export declare function contains<T>(array: T[], value: T): boolean;
export declare function remove<T>(array: T[], value: T): boolean;
export declare function distinctAdd<T>(array: T[], value: T): boolean;
//# sourceMappingURL=array-utils.d.ts.map

@@ -18,8 +18,2 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
function contains(array, value) {
if (value === undefined)
return false;
return array.indexOf(value) >= 0;
}
exports.contains = contains;
function remove(array, value) {

@@ -35,3 +29,3 @@ var index = array.indexOf(value);

function distinctAdd(array, value) {
if (!contains(array, value)) {
if (!array.includes(value)) {
array.push(value);

@@ -38,0 +32,0 @@ return true;

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

********************************************************************************/
import { BoundsAware, Selectable, SModelElement, SParentElement } from "sprotty/lib";
import { NodeEditConfig } from "../base/edit-config/edit-config";
import { BoundsAware, Selectable, SModelElement, SRoutableElement, SRoutingHandle } from "sprotty/lib";
import { ElementAndRoutingPoints } from "src/features/operation/operation-actions";
export declare function getIndex(element: SModelElement): import("sprotty").SModelIndex<SModelElement>;

@@ -24,8 +24,9 @@ export declare function forEachElement<T>(element: SModelElement, predicate: (element: SModelElement) => element is SModelElement & T, runnable: (element: SModelElement & T) => void): void;

export declare function getSelectedElementCount(element: SModelElement): number;
export declare function isSelected(element: SModelElement | undefined): element is SModelElement & Selectable;
export declare function isNotUndefined<T>(element: T | undefined): element is T;
export declare function addCssClasses(root: SModelElement, cssClasses: string[]): void;
export declare function removeCssClasses(root: SModelElement, cssClasses: string[]): void;
export declare function isContainmentAllowed(element: SModelElement, containableElementTypeId: string): element is SParentElement & NodeEditConfig;
export declare function isNonRoutableSelectedMovableBoundsAware(element: SModelElement): element is SelectableBoundsAware;
export declare function isNonRoutableSelectedBoundsAware(element: SModelElement): element is SelectableBoundsAware;
export declare function isRoutable<T extends SModelElement>(element: T): element is T & SRoutableElement;
export declare function isRoutingHandle(element: SModelElement | undefined): element is SRoutingHandle;
export declare type SelectableBoundsAware = SModelElement & BoundsAware & Selectable;

@@ -43,2 +44,3 @@ export declare function toElementAndBounds(element: SModelElement & BoundsAware): {

};
export declare function toElementAndRoutingPoints(element: SRoutableElement): ElementAndRoutingPoints;
//# sourceMappingURL=smodel-util.d.ts.map

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

var lib_1 = require("sprotty/lib");
var edit_config_1 = require("../base/edit-config/edit-config");
var model_1 = require("../features/reconnect/model");
function getIndex(element) {

@@ -56,3 +54,3 @@ return element.root.index;

getIndex(element).all()
.filter(isSelected)
.filter(lib_1.isSelected)
.forEach(function (e) { return selected = selected + 1; });

@@ -62,6 +60,2 @@ return selected;

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

@@ -116,10 +110,18 @@ return element !== undefined;

exports.removeCssClasses = removeCssClasses;
function isContainmentAllowed(element, containableElementTypeId) {
return edit_config_1.isConfigurableNode(element) && element.isContainableElement(containableElementTypeId);
function isNonRoutableSelectedMovableBoundsAware(element) {
return isNonRoutableSelectedBoundsAware(element) && lib_1.isMoveable(element);
}
exports.isContainmentAllowed = isContainmentAllowed;
exports.isNonRoutableSelectedMovableBoundsAware = isNonRoutableSelectedMovableBoundsAware;
function isNonRoutableSelectedBoundsAware(element) {
return lib_1.isBoundsAware(element) && isSelected(element) && !model_1.isRoutable(element);
return lib_1.isBoundsAware(element) && lib_1.isSelected(element) && !isRoutable(element);
}
exports.isNonRoutableSelectedBoundsAware = isNonRoutableSelectedBoundsAware;
function isRoutable(element) {
return element instanceof lib_1.SRoutableElement && element.routingPoints !== undefined;
}
exports.isRoutable = isRoutable;
function isRoutingHandle(element) {
return element !== undefined && element instanceof lib_1.SRoutingHandle;
}
exports.isRoutingHandle = isRoutingHandle;
function toElementAndBounds(element) {

@@ -139,2 +141,9 @@ return {

exports.toElementAndBounds = toElementAndBounds;
function toElementAndRoutingPoints(element) {
return {
elementId: element.id,
newRoutingPoints: element.routingPoints
};
}
exports.toElementAndRoutingPoints = toElementAndRoutingPoints;
//# sourceMappingURL=smodel-util.js.map

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

********************************************************************************/
import { Point } from "sprotty/lib";
import { SModelElement } from "sprotty/lib";
import { Bounds, BoundsAware, Dimension, Point, SModelElement } from "sprotty/lib";
/**

@@ -33,2 +32,23 @@ * Return the position corresponding to this mouse event (Browser coordinates)

export declare function getAbsolutePosition(target: SModelElement, mouseEvent: MouseEvent): Point;
/**
* Translates the bounds of the diagram element (local coordinates) into the diagram coordinates system
* (i.e. relative to the Diagram's 0;0 point)
*
* @param target A bounds-aware element from the diagram
*/
export declare function toAbsoluteBounds(element: SModelElement & BoundsAware): Bounds;
/**
* Translates the position of the diagram element (local coordinates) into the diagram coordinates system
* (i.e. relative to the Diagram's 0;0 point)
*
* @param target A bounds-aware element from the diagram
*/
export declare function toAbsolutePosition(target: SModelElement & BoundsAware): Point;
/**
* Translates the size of the diagram element (local coordinates) into the diagram coordinates system
* (i.e. relative to the Diagram's 0;0 point)
*
* @param target A bounds-aware element from the diagram
*/
export declare function toAbsoluteSize(target: SModelElement & BoundsAware): Dimension;
//# sourceMappingURL=viewpoint-util.d.ts.map
"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 lib_2 = require("sprotty/lib");
/**

@@ -23,3 +37,3 @@ * Return the position corresponding to this mouse event (Browser coordinates)

yPos -= canvasBounds.y;
var viewport = lib_1.findParentByFeature(target, lib_2.isViewport);
var viewport = lib_1.findParentByFeature(target, lib_1.isViewport);
var zoom = viewport ? viewport.zoom : 1;

@@ -40,2 +54,37 @@ if (viewport) {

exports.getAbsolutePosition = getAbsolutePosition;
/**
* Translates the bounds of the diagram element (local coordinates) into the diagram coordinates system
* (i.e. relative to the Diagram's 0;0 point)
*
* @param target A bounds-aware element from the diagram
*/
function toAbsoluteBounds(element) {
var location = lib_1.isAlignable(element) ? element.alignment : lib_1.ORIGIN_POINT;
var x = location.x;
var y = location.y;
var width = element.bounds.width;
var height = element.bounds.height;
return lib_1.translateBounds({ x: x, y: y, width: width, height: height }, element, element.root);
}
exports.toAbsoluteBounds = toAbsoluteBounds;
/**
* Translates the position of the diagram element (local coordinates) into the diagram coordinates system
* (i.e. relative to the Diagram's 0;0 point)
*
* @param target A bounds-aware element from the diagram
*/
function toAbsolutePosition(target) {
return toAbsoluteBounds(target);
}
exports.toAbsolutePosition = toAbsolutePosition;
/**
* Translates the size of the diagram element (local coordinates) into the diagram coordinates system
* (i.e. relative to the Diagram's 0;0 point)
*
* @param target A bounds-aware element from the diagram
*/
function toAbsoluteSize(target) {
return toAbsoluteBounds(target);
}
exports.toAbsoluteSize = toAbsoluteSize;
//# sourceMappingURL=viewpoint-util.js.map
{
"name": "@eclipse-glsp/client",
"version": "0.8.0-next.b2224cc",
"version": "0.8.0-next.bddae4a",
"description": "A sprotty-based client for GLSP",

@@ -36,5 +36,13 @@ "license": "(EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0)",

"devDependencies": {
"@types/chai": "4.1.3",
"@types/mocha": "^5.2.7",
"@types/node": "10.14.18",
"@types/uuid": "3.4.5",
"chai": "^4.2.0",
"jenkins-mocha": "^8.0.0",
"mocha": "^6.2.0",
"reflect-metadata": "^0.1.13",
"rimraf": "^2.6.1",
"semver": "6.3.0",
"ts-node": "^8.3.0",
"tslint": "^5.5.0",

@@ -49,2 +57,3 @@ "typescript": "3.6.4"

"watch": "tsc -w",
"test": "jenkins-mocha --opts ./configs/mocha.opts \"./src/**/*.spec.?(ts|tsx)\"",
"publish:latest": "yarn publish --tag latest",

@@ -51,0 +60,0 @@ "publish:next": "yarn publish --new-version \"$(semver $npm_package_version -i minor)-next.$(git rev-parse --short HEAD)\" --tag next"

@@ -1,3 +0,9 @@

# Eclipse GLSP - Client
# Eclipse GLSP - Client [![build-status](https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fci.eclipse.org%2Fglsp%2Fjob%2Feclipse-glsp%2Fjob%2Fglsp-client%2Fjob%2Fmaster%2F)](https://ci.eclipse.org/glsp/job/eclipse-glsp/job/glsp-client/job/master) ![build-status-server](https://img.shields.io/jenkins/build?jobUrl=https://ci.eclipse.org/glsp/job/deploy-npm-glsp-client/&label=publish)
This package contains a client for the [Graphical Language Server Protocol (GLSP)](https://github.com/eclipse-glsp/glsp) based on [Eclipse Sprotty](https://github.com/eclipse/sprotty).
A web-based diagram client framework for the [Graphical Language Server Protocol (GLSP)](https://github.com/eclipse-glsp/glsp) based on [Eclipse Sprotty](https://github.com/eclipse/sprotty).
This project is built with `yarn` and is available from npm via [@eclipse-glsp/client](https://www.npmjs.com/package/@eclipse-glsp/client).
For more information, please visit the [Eclipse GLSP Umbrella repository](https://github.com/eclipse-glsp/glsp) and the [Eclipse GLSP Website](https://www.eclipse.org/glsp/). If you have questions, contact us on our [spectrum chat](https://spectrum.chat/glsp/) and have a look at our [communication and support options](https://www.eclipse.org/glsp/contact/).
![alt](https://www.eclipse.org/glsp/images/diagramanimated.gif)

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

import { GLSPCommandStack } from "./command-stack";
import { EditorContextService } from "./editor-context";
import { FeedbackAwareUpdateModelCommand, SetModelActionHandler } from "./model/update-model-command";
import { createToolFactory, GLSPToolManagerActionHandler } from "./tool-manager/tool-manager-action-handler";
const defaultGLSPModule = new ContainerModule((bind, _unbind, isBound, rebind) => {

@@ -34,2 +34,3 @@ const context = { bind, _unbind, isBound, rebind };

bind(GLSP_TYPES.IToolFactory).toFactory<Tool>((createToolFactory()));
bind(EditorContextService).toSelf().inSingletonScope();

@@ -36,0 +37,0 @@ // Model update initialization ------------------------------------

@@ -32,4 +32,4 @@ /********************************************************************************

import { UpdateModelAction, UpdateModelCommand } from "sprotty/lib/features/update/update-model";
import { IFeedbackActionDispatcher } from "src/features/tool-feedback/feedback-action-dispatcher";
import { IFeedbackActionDispatcher } from "../../features/tool-feedback/feedback-action-dispatcher";
import { FeedbackCommand } from "../../features/tool-feedback/model";

@@ -47,4 +47,2 @@ import { GLSP_TYPES } from "../../types";

}
handledActionKinds = [SetModelCommand.KIND];
}

@@ -67,12 +65,14 @@

export class FeedbackAwareUpdateModelCommand extends UpdateModelCommand {
protected actionHandlerRegistry?: ActionHandlerRegistry;
constructor(@inject(TYPES.Action) action: UpdateModelAction,
@inject(TYPES.ILogger) protected logger: ILogger,
@inject(GLSP_TYPES.IFeedbackActionDispatcher) @optional() protected readonly feedbackActionDispatcher: IFeedbackActionDispatcher,
@inject(TYPES.ActionHandlerRegistryProvider) protected actionHandlerRegistryProvider: () => Promise<ActionHandlerRegistry>,
@inject(TYPES.ActionHandlerRegistryProvider) actionHandlerRegistryProvider: () => Promise<ActionHandlerRegistry>,
@multiInject(GLSP_TYPES.SModelRootListener) @optional() protected modelRootListeners: SModelRootListener[] = []) {
super(action);
actionHandlerRegistryProvider().then(registry => this.actionHandlerRegistry = registry);
}
protected performUpdate(oldRoot: SModelRoot, newRoot: SModelRoot, context: CommandExecutionContext): CommandReturn {
if (this.feedbackActionDispatcher) {
if (this.feedbackActionDispatcher && this.actionHandlerRegistry) {
// Create a temporary context wich defines the `newRoot` as `root`

@@ -88,10 +88,9 @@ // This way we do not corrupt the redo/undo behavior of the super class

};
this.actionHandlerRegistryProvider().then(registry => {
const feedbackCommands = this.getFeedbackCommands(registry);
feedbackCommands.forEach(command => command.execute(tempContext));
});
const feedbackCommands = this.getFeedbackCommands(this.actionHandlerRegistry);
feedbackCommands.forEach(command => command.execute(tempContext));
}
this.modelRootListeners.forEach(listener => listener.modelRootChanged(newRoot));
return super.performUpdate(oldRoot, newRoot, context);
}

@@ -98,0 +97,0 @@

@@ -27,8 +27,14 @@ /********************************************************************************

SModelElement,
SNode,
SParentElement
} from "sprotty/lib";
import { isConfigurableNode, NodeEditConfig } from "../../base/edit-config/edit-config";
export const resizeFeature = Symbol("resizeFeature");
export interface Resizable extends BoundsAware, Selectable {
}
export function isResizable(element: SModelElement): element is SParentElement & Resizable {
return isBoundsAware(element) && isSelectable(element) && element instanceof SParentElement && element.hasFeature(resizeFeature);
}
export enum ResizeHandleLocation {

@@ -41,6 +47,2 @@ TopLeft = "top-left",

export function isResizeable(element: SModelElement): element is SNode & SParentElement & BoundsAware & Selectable & NodeEditConfig {
return isConfigurableNode(element) && element.resizable && isBoundsAware(element) && isSelectable(element) && element instanceof SParentElement;
}
export function isBoundsAwareMoveable(element: SModelElement): element is SModelElement & Locateable & BoundsAware {

@@ -47,0 +49,0 @@ return isMoveable(element) && isBoundsAware(element);

@@ -17,274 +17,70 @@ /********************************************************************************

import { injectable } from "inversify";
import {
Action,
Bounds,
BoundsAware,
ElementMove,
includes,
isBoundsAware,
isMoveable,
isSelectable,
MoveAction,
Point,
PointToPointLine,
SModelElement
} from "sprotty/lib";
import { FluentIterable, toArray } from "sprotty/lib/utils/iterable";
import { Action, BoundsAware, Point, SModelElement, SNode, SParentElement } from "sprotty/lib";
import { ApplyCursorCSSFeedbackAction, CursorCSS } from "../tool-feedback/cursor-feedback";
import { isBoundsAwareMoveable } from "./model";
import { toAbsoluteBounds } from "../../utils/viewpoint-util";
import { ModifyCSSFeedbackAction } from "../tool-feedback/css-feedback";
import { isBoundsAwareMoveable, SResizeHandle } from "./model";
export interface IMovementRestrictor {
attemptMove(element: SModelElement, mousePoint: Point, target: SModelElement, delta: Point, result: Action[]): boolean
validate(newLocation: Point, element: SModelElement): boolean;
cssClasses?: string[];
}
export function createMovementRestrictionFeedback(element: SModelElement, movementRestrictor: IMovementRestrictor): Action[] {
const result: Action[] = [];
result.push(new ModifyCSSFeedbackAction(element, movementRestrictor.cssClasses));
if (element instanceof SParentElement) {
element.children.filter(child => child instanceof SResizeHandle).forEach(child => result.push(new ModifyCSSFeedbackAction(child, movementRestrictor.cssClasses)));
}
return result;
}
export function removeMovementRestrictionFeedback(element: SModelElement, movementRestrictor: IMovementRestrictor): Action[] {
const result: Action[] = [];
result.push(new ModifyCSSFeedbackAction(element, undefined, movementRestrictor.cssClasses));
if (element instanceof SParentElement) {
element.children.filter(child => child instanceof SResizeHandle).
forEach(child => result.push(new ModifyCSSFeedbackAction(child, undefined, movementRestrictor.cssClasses)));
}
return result;
}
@injectable()
export class NoCollisionMovementRestrictor {
hasCollided = false;
/*
* Attempt to perform an element move. Returns true if the move is not restricted anc can be applied successfull and false otherwise
*/
attemptMove(element: SModelElement, mousePoint: Point, target: SModelElement, delta: Point, result: Action[]): boolean {
export class NoOverlapMovmentRestrictor implements IMovementRestrictor {
validate(newLocation: Point, element: SModelElement): boolean {
if (!isBoundsAwareMoveable(element)) {
return false;
}
let mouseOverElement: boolean = false;
let willOverlap: boolean = false;
// Create ghost element to check possible bounds
// Create ghost element at the newLocation;
const ghostElement = Object.create(element);
ghostElement.bounds = this.getCenteredBoundsToPointer(mousePoint, element.bounds);
// Set type to Ghost to keep tracking it through elements
ghostElement.bounds.x = newLocation.x - element.bounds.width / 2;
ghostElement.bounds.y = newLocation.y - element.bounds.height / 2;
ghostElement.type = "Ghost";
ghostElement.id = element.id;
// Check collision for gost element (to see when it has passed beyond obstacle)
const collisionTargetsGhost: SModelElement[] = this.getCollisionChain(target, ghostElement, delta, [])
.filter(collidingElement => isSelectable(collidingElement) && !collidingElement.selected);
return !Array.from(element.root.index.all().filter(e => e.id !== ghostElement.id && e !== ghostElement.root && (e instanceof SNode))
.map(e => e as SModelElement & BoundsAware)).some(e => areOverlapping(e, ghostElement));
}
// 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));
}
cssClasses = ["movement-not-allowed"];
}
const selectedElements: FluentIterable<SModelElement> = target.root.index.all()
.filter(selected => isSelectable(selected) && selected.selected);
export function areOverlapping(element1: SModelElement & BoundsAware, element2: SModelElement & BoundsAware) {
const b1 = toAbsoluteBounds(element1);
const b2 = toAbsoluteBounds(element2);
const r1TopLeft: Point = b1;
const r1BottomRight = { x: b1.x + b1.width, y: b1.y + b1.height };
const r2TopLeft: Point = b2;
const r2BottomRight = { x: b2.x + b2.width, y: b2.y + b2.height };
// If the ghost element has moved beyond the obstacle move the actual element there aswell
// But only if a single element is selected (multi-selection jumps are not supported)
if (this.hasCollided && collisionTargetsGhost.length === 0 && toArray(selectedElements).length === 1) {
mouseOverElement = true;
result.push(new ApplyCursorCSSFeedbackAction(CursorCSS.DEFAULT));
// If one rectangle is on left side of other
if (r1TopLeft.x > r2BottomRight.x || r2TopLeft.x > r1BottomRight.x)
return false;
if (element.id === ghostElement.id) {
element.bounds = ghostElement.bounds;
}
}
// Get only the valid, non-slected collision targets to avoid in-selection collisions
const collisionTargets: SModelElement[] = this.getCollisionChain(target, element, delta, [])
.filter(collidingElement => isSelectable(collidingElement) && !collidingElement.selected);
if (collisionTargets.length > 0) {
collisionTargets.forEach(collisionTarget => {
if (isBoundsAware(collisionTarget)) {
// Only snap on first collision to avoid erratic jumps
if (!this.hasCollided) {
const snappedBounds = this.getSnappedBounds(element, collisionTarget);
const snapMoves: ElementMove[] = [];
snapMoves.push({
elementId: element.id,
fromPosition: {
x: element.position.x,
y: element.position.y
},
toPosition: {
x: snappedBounds.x,
y: snappedBounds.y
}
});
result.push(new MoveAction(snapMoves, false));
}
willOverlap = true;
this.hasCollided = true;
result.push(new ApplyCursorCSSFeedbackAction(CursorCSS.OVERLAP_FORBIDDEN));
}
});
}
if ((!willOverlap && !this.hasCollided) ||
(this.hasCollided && !willOverlap && mouseOverElement)) {
this.hasCollided = false;
return true;
}
// If one rectangle is above other
if (r1BottomRight.y < r2TopLeft.y || r2BottomRight.y < r1TopLeft.y)
return false;
}
/**
* Used to return the collision target(s) or the collision chain in case of multiple selected elements
*/
getCollisionChain(target: SModelElement, element: SModelElement, delta: Point, collisionChain: SModelElement[]): SModelElement[] {
if (isBoundsAwareMoveable(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 (isBoundsAware(element) && isBoundsAware(candidate)) {
const futureBounds: Bounds = {
x: element.position.x + delta.x,
y: element.position.y + delta.y,
width: element.bounds.width,
height: element.bounds.height
};
if (isOverlappingBounds(futureBounds, candidate.bounds) && (!isOverlappingBounds(element.bounds, candidate.bounds) || element.type === "Ghost")) {
collisionChain.push(candidate);
if (isSelectable(candidate) && candidate.selected) {
// Check what the selected candidate will collide with and add it to the chain
collisionChain.push.apply(collisionChain, this.getCollisionChain(target, candidate, delta, collisionChain));
}
}
}
}
});
}
return collisionChain;
}
return true;
/**
* Returns bounds centered around the point
*/
getCenteredBoundsToPointer(mousePoint: Point, bounds: Bounds): Bounds {
const middleX = mousePoint.x - bounds.width / 2;
const middleY = mousePoint.y - bounds.height / 2;
const shiftedBounds: Bounds = { x: middleX, y: middleY, width: bounds.width, height: bounds.height };
return shiftedBounds;
}
// Remove this and use the one from the improved routing branch
getDistanceBetweenParallelLines(p1: Point, p2: Point, secondLine: PointToPointLine): Number {
const numerator: number = Math.abs((secondLine.a * p1.x) + (secondLine.b * p1.y) - secondLine.c);
const denominator: number = Math.sqrt(Math.pow(secondLine.a, 2) + Math.pow(secondLine.b, 2));
return numerator / denominator;
}
/**
* Snaps the element to the target in case of a collision
*/
getSnappedBounds(element: SModelElement & BoundsAware, target: SModelElement & BoundsAware): Bounds {
let snappedBounds = element.bounds;
// Build corner points
const elementTopLeft = {
x: element.bounds.x,
y: element.bounds.y
};
const elementTopRight = {
x: element.bounds.x + element.bounds.width,
y: element.bounds.y
};
const elementBottomLeft = {
x: element.bounds.x,
y: element.bounds.y + element.bounds.height
};
const elementBottomRight = {
x: element.bounds.x + element.bounds.width,
y: element.bounds.y + element.bounds.height
};
const targetTopLeft = {
x: target.bounds.x,
y: target.bounds.y
};
const targetTopRight = {
x: target.bounds.x + target.bounds.width,
y: target.bounds.y
};
const targetBottomLeft = {
x: target.bounds.x,
y: target.bounds.y + target.bounds.height
};
const targetBottomRight = {
x: target.bounds.x + target.bounds.width,
y: target.bounds.y + target.bounds.height
};
// Build lines
const targetTopLine = new PointToPointLine(targetTopLeft, targetTopRight);
const targetBottomLine = new PointToPointLine(targetBottomLeft, targetBottomRight);
const targetLeftLine = new PointToPointLine(targetTopLeft, targetBottomLeft);
const targetRightLine = new PointToPointLine(targetTopRight, targetBottomRight);
// Compute distances
const distanceTop = this.getDistanceBetweenParallelLines(elementBottomLeft, elementBottomRight, targetTopLine);
const distanceBottom = this.getDistanceBetweenParallelLines(elementTopLeft, elementTopRight, targetBottomLine);
const distanceLeft = this.getDistanceBetweenParallelLines(elementTopLeft, elementBottomLeft, targetRightLine);
const distanceRight = this.getDistanceBetweenParallelLines(elementTopRight, elementBottomRight, targetLeftLine);
const minimumCandidates: number[] = [];
// Overlap on the horizontal lines
if (isOverlapping1Dimension(element.bounds.x, element.bounds.width, target.bounds.x, target.bounds.width)) {
minimumCandidates.push(distanceTop.valueOf());
minimumCandidates.push(distanceBottom.valueOf());
}
// Overlap on the horizontal lines
if (isOverlapping1Dimension(element.bounds.y, element.bounds.height, target.bounds.y, target.bounds.height)) {
minimumCandidates.push(distanceLeft.valueOf());
minimumCandidates.push(distanceRight.valueOf());
}
// Get minimum distance and then snap accordingly
minimumCandidates.sort((a, b) => a - b);
const minimumDistance = minimumCandidates[0];
if (minimumDistance === distanceTop) {
snappedBounds = {
x: element.bounds.x,
y: target.bounds.y - 1 - element.bounds.height,
width: element.bounds.width,
height: element.bounds.height
};
}
if (minimumDistance === distanceBottom) {
snappedBounds = {
x: element.bounds.x,
y: target.bounds.y + target.bounds.height + 1,
width: element.bounds.width,
height: element.bounds.height
};
}
if (minimumDistance === distanceLeft) {
snappedBounds = {
x: target.bounds.x + target.bounds.width + 1,
y: element.bounds.y,
width: element.bounds.width,
height: element.bounds.height
};
}
if (minimumDistance === distanceRight) {
snappedBounds = {
x: target.bounds.x - 1 - element.bounds.width,
y: element.bounds.y,
width: element.bounds.width,
height: element.bounds.height
};
}
return snappedBounds;
}
}
/**
* 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);
}

@@ -21,7 +21,5 @@ /********************************************************************************

import { NavigationCommandPaletteActionProvider, ServerCommandPaletteActionProvider } from "./action-provider";
import { ServerCommandPaletteActionProvider } from "./server-command-palette-provider";
const glspCommandPaletteModule = new ContainerModule((bind, unbind, isBound, rebind) => {
bind(TYPES.ICommandPaletteActionProvider).to(NavigationCommandPaletteActionProvider);
bind(ServerCommandPaletteActionProvider).toSelf().inSingletonScope();
const glspCommandPaletteModule = new ContainerModule((bind) => {
bind(TYPES.ICommandPaletteActionProvider).to(ServerCommandPaletteActionProvider);

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

@@ -21,21 +21,29 @@ /********************************************************************************

EditLabelValidationResult,
generateRequestId,
IEditLabelValidationDecorator,
IEditLabelValidator,
RequestAction,
ResponseAction,
Severity,
SModelElement
SModelElement,
TYPES
} from "sprotty";
import { GLSP_TYPES } from "../../types";
import { RequestResponseSupport } from "../request-response/support";
import { GLSPActionDispatcher } from "../request-response/glsp-action-dispatcher";
export class ValidateLabelEditAction implements Action {
export class ValidateLabelEditAction implements RequestAction<SetLabelEditValidationResultAction> {
static readonly KIND = "validateLabelEdit";
kind = ValidateLabelEditAction.KIND;
constructor(public readonly value: string, public readonly labelId: string) { }
constructor(
public readonly value: string,
public readonly labelId: string,
public readonly requestId: string = generateRequestId()) { }
}
export class SetLabelEditValidationResultAction implements Action {
export class SetLabelEditValidationResultAction implements ResponseAction {
static readonly KIND = "setLabelEditValidationResult";
kind = SetLabelEditValidationResultAction.KIND;
constructor(public readonly result: EditLabelValidationResult) { }
constructor(
public readonly result: EditLabelValidationResult,
public readonly responseId: string = '') { }
}

@@ -51,7 +59,7 @@

@inject(GLSP_TYPES.RequestResponseSupport) protected requestResponseSupport: RequestResponseSupport;
@inject(TYPES.IActionDispatcher) protected actionDispatcher: GLSPActionDispatcher;
validate(value: string, label: EditableLabel & SModelElement): Promise<EditLabelValidationResult> {
const action = new ValidateLabelEditAction(value, label.id);
return this.requestResponseSupport.dispatchRequest(action, this.getValidationResultFromResponse);
return this.actionDispatcher.requestUntil(action).then(response => this.getValidationResultFromResponse(response));
}

@@ -58,0 +66,0 @@

@@ -20,12 +20,12 @@ /********************************************************************************

import { GLSP_TYPES } from "../../types";
import { SetTypeHintsAction } from "./action-definition";
import { ApplyEditConfigCommand, TypeHintsEditConfigProvider } from "./type-hints-action-initializer";
import { SetTypeHintsAction } from "./request-type-hints-action";
import { ApplyTypeHintsCommand, TypeHintProvider } from "./type-hints";
const modelHintsModule = new ContainerModule((bind, _unbind, isBound) => {
bind(TypeHintsEditConfigProvider).toSelf().inSingletonScope();
configureActionHandler({ bind, isBound }, SetTypeHintsAction.KIND, TypeHintsEditConfigProvider);
bind(GLSP_TYPES.IEditConfigProvider).toService(TypeHintsEditConfigProvider);
configureCommand({ bind, isBound }, ApplyEditConfigCommand);
bind(TypeHintProvider).toSelf().inSingletonScope();
bind(GLSP_TYPES.ITypeHintProvider).toService(TypeHintProvider);
configureActionHandler({ bind, isBound }, SetTypeHintsAction.KIND, TypeHintProvider);
configureCommand({ bind, isBound }, ApplyTypeHintsCommand);
});
export default modelHintsModule;

@@ -56,2 +56,15 @@ /********************************************************************************

export class ReconnectConnectionOperationAction implements Action {
readonly kind = OperationKind.RECONNECT_CONNECTION;
constructor(public readonly connectionElementId: string,
public readonly sourceElementId: string,
public readonly targetElementId: string) { }
}
export class ChangeRoutingPointsOperation implements Action {
readonly kind = OperationKind.CHANGE_ROUTING_POINTS;
constructor(public newRoutingPoints: ElementAndRoutingPoints[]) { }
}
export class GenericOperationAction implements Action {

@@ -65,1 +78,5 @@ readonly kind = OperationKind.GENERIC;

export interface ElementAndRoutingPoints {
elementId: string
newRoutingPoints?: Point[];
}

@@ -22,5 +22,5 @@ /********************************************************************************

export const RECONNECT_CONNECTION = "reconnectConnection";
export const REROUTE_CONNECTION = "rerouteConnection";
export const DELETE_ELEMENT = "delete";
export const CHANGE_BOUNDS = "changeBoundsOperation";
export const CHANGE_ROUTING_POINTS = "changeRoutingPoints";
export const DELETE_ELEMENT = "deleteElement";
export const CHANGE_BOUNDS = "changeBounds";
export const CHANGE_CONTAINER = "changeContainer";

@@ -27,0 +27,0 @@ export const GENERIC = "generic";

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

SModelElement,
SModelExtension,
SRoutableElement,

@@ -27,8 +28,12 @@ SRoutingHandle

const ROUTING_HANDLE_SOURCE_INDEX: number = -2;
export const reconnectFeature = Symbol("reconnectFeature");
export interface Reconnectable extends SModelExtension {
}
export function isRoutable<T extends SModelElement>(element: T): element is T & SRoutableElement {
return element instanceof SRoutableElement && (element as any).routingPoints !== undefined;
export function isReconnectable(element: SModelElement): element is SRoutableElement & Reconnectable {
return element instanceof SRoutableElement && element.hasFeature(reconnectFeature);
}
const ROUTING_HANDLE_SOURCE_INDEX: number = -2;
export function isReconnectHandle(element: SModelElement | undefined): element is SReconnectHandle {

@@ -38,5 +43,2 @@ return element !== undefined && element instanceof SReconnectHandle;

export function isRoutingHandle(element: SModelElement | undefined): element is SRoutingHandle {
return element !== undefined && element instanceof SRoutingHandle;
}

@@ -43,0 +45,0 @@ export function addReconnectHandles(element: SRoutableElement) {

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

import { GLSP_TYPES } from "../../types";
import { RequestResponseSupport } from "./support";
import { GLSPActionDispatcher } from "./glsp-action-dispatcher";
const requestResponseModule = new ContainerModule((bind, unbind, isBound, rebind) => {
bind(RequestResponseSupport).toSelf().inSingletonScope();
bind(GLSP_TYPES.RequestResponseSupport).toService(RequestResponseSupport);
bind(TYPES.IActionHandlerInitializer).toService(RequestResponseSupport);
rebind(TYPES.IActionDispatcher).to(GLSPActionDispatcher).inSingletonScope();
});
export default requestResponseModule;

@@ -36,5 +36,5 @@ /********************************************************************************

import { isNotUndefined } from "../../utils/smodel-util";
import { getAbsolutePosition } from "../../utils/viewpoint-util";
import { addResizeHandles, isBoundsAwareMoveable, isResizeable, removeResizeHandles } from "../change-bounds/model";
import { IMovementRestrictor } from "../change-bounds/movement-restrictor";
import { addResizeHandles, isResizable, removeResizeHandles, SResizeHandle } from "../change-bounds/model";
import { createMovementRestrictionFeedback, removeMovementRestrictionFeedback } from "../change-bounds/movement-restrictor";
import { ChangeBoundsTool } from "../tools/change-bounds-tool";
import { FeedbackCommand } from "./model";

@@ -54,5 +54,8 @@

export class ShowChangeBoundsToolResizeFeedbackCommand extends FeedbackCommand {
static readonly KIND = 'showChangeBoundsToolResizeFeedback';
static readonly KIND = "showChangeBoundsToolResizeFeedback";
constructor(@inject(TYPES.Action) protected action: ShowChangeBoundsToolResizeFeedbackAction) {
constructor(
@inject(TYPES.Action)
protected action: ShowChangeBoundsToolResizeFeedbackAction
) {
super();

@@ -63,7 +66,10 @@ }

const index = context.root.index;
index.all().filter(isResizeable).forEach(removeResizeHandles);
index
.all()
.filter(isResizable)
.forEach(removeResizeHandles);
if (isNotUndefined(this.action.elementId)) {
const resizeElement = index.getById(this.action.elementId);
if (isNotUndefined(resizeElement) && isResizeable(resizeElement)) {
if (isNotUndefined(resizeElement) && isResizable(resizeElement)) {
addResizeHandles(resizeElement);

@@ -78,5 +84,8 @@ }

export class HideChangeBoundsToolResizeFeedbackCommand extends FeedbackCommand {
static readonly KIND = 'hideChangeBoundsToolResizeFeedback';
static readonly KIND = "hideChangeBoundsToolResizeFeedback";
constructor(@inject(TYPES.Action) protected action: HideChangeBoundsToolResizeFeedbackAction) {
constructor(
@inject(TYPES.Action)
protected action: HideChangeBoundsToolResizeFeedbackAction
) {
super();

@@ -87,3 +96,6 @@ }

const index = context.root.index;
index.all().filter(isResizeable).forEach(removeResizeHandles);
index
.all()
.filter(isResizable)
.forEach(removeResizeHandles);
return context.root;

@@ -102,11 +114,15 @@ }

hasDragged = false;
lastDragPosition: Point | undefined;
constructor(protected movementRestrictor?: IMovementRestrictor) { super(); }
startDragPosition: Point | undefined;
elementId2startPos = new Map<string, Point>();
constructor(protected tool: ChangeBoundsTool) {
super();
}
mouseDown(target: SModelElement, event: MouseEvent): Action[] {
if (event.button === 0) {
if (event.button === 0 && !(target instanceof SResizeHandle)) {
const moveable = findParentByFeature(target, isMoveable);
if (moveable !== undefined) {
this.lastDragPosition = { x: event.pageX, y: event.pageY };
this.startDragPosition = { x: event.pageX, y: event.pageY };
} else {
this.lastDragPosition = undefined;
this.startDragPosition = undefined;
}

@@ -118,48 +134,89 @@ this.hasDragged = false;

mouseMove(target: SModelElement, event: MouseEvent): Action[] {
const result: Action[] = [];
if (event.buttons === 0)
this.mouseUp(target, event);
else if (this.lastDragPosition) {
const viewport = findParentByFeature(target, isViewport);
if (event.buttons === 0) this.mouseUp(target, event);
else if (this.startDragPosition) {
if (this.elementId2startPos.size === 0) {
this.collectStartPositions(target.root);
}
this.hasDragged = true;
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 isValidMove: boolean = true;
const moveAction = this.getElementMoves(target, event, false);
if (moveAction) result.push(moveAction);
}
return result;
}
target.root.index.all()
.filter(element => isSelectable(element) && element.selected)
.forEach(element => {
if (isBoundsAwareMoveable(element)) {
// If a movement restrictor is bound attemt a non restricted move
if (this.movementRestrictor) {
isValidMove = this.movementRestrictor.attemptMove(element, mousePoint, target, { x: dx, y: dy }, result);
}
}
if (isMoveable(element) && isValidMove) {
nodeMoves.push({
elementId: element.id,
fromPosition: {
x: element.position.x,
y: element.position.y
},
toPosition: {
x: element.position.x + dx,
y: element.position.y + dy
}
});
}
});
this.lastDragPosition = { x: event.pageX, y: event.pageY };
if (nodeMoves.length > 0 && isValidMove) {
result.push(new MoveAction(nodeMoves, false));
protected collectStartPositions(root: SModelRoot) {
root.index
.all()
.filter(element => isSelectable(element) && element.selected)
.forEach(element => {
if (isMoveable(element)) {
this.elementId2startPos.set(element.id, element.position);
}
});
}
protected getElementMoves(target: SModelElement, event: MouseEvent, isFinished: boolean): MoveAction | undefined {
if (!this.startDragPosition) return undefined;
const elementMoves: ElementMove[] = [];
const viewport = findParentByFeature(target, isViewport);
const zoom = viewport ? viewport.zoom : 1;
const delta = {
x: (event.pageX - this.startDragPosition.x) / zoom,
y: (event.pageY - this.startDragPosition.y) / zoom
};
this.elementId2startPos.forEach((startPosition, elementId) => {
const element = target.root.index.getById(elementId);
if (element) {
let toPosition = this.snap(
{
x: startPosition.x + delta.x,
y: startPosition.y + delta.y
},
element,
!event.shiftKey
);
if (isMoveable(element)) {
toPosition = this.validateMove(startPosition, toPosition, element, isFinished);
elementMoves.push({
elementId: element.id,
fromPosition: {
x: element.position.x,
y: element.position.y
},
toPosition
});
}
}
});
if (elementMoves.length > 0)
return new MoveAction(elementMoves, false, isFinished);
else return undefined;
}
protected validateMove(startPostion: Point, toPosition: Point, element: SModelElement, isFinished: boolean) {
let newPosition = toPosition;
if (this.tool.movementRestrictor) {
const valid = this.tool.movementRestrictor.validate(toPosition, element);
let actions;
if (!valid) {
actions = createMovementRestrictionFeedback(element, this.tool.movementRestrictor);
if (isFinished) {
newPosition = startPostion;
}
} else {
actions = removeMovementRestrictionFeedback(element, this.tool.movementRestrictor);
}
this.tool.dispatchFeedback(this, actions);
}
return result;
return newPosition;
}
protected snap(position: Point, element: SModelElement, isSnap: boolean): Point {
if (isSnap && this.tool.snapper) return this.tool.snapper.snap(position, element);
else return position;
}

@@ -173,5 +230,17 @@ mouseEnter(target: SModelElement, event: MouseEvent): Action[] {

mouseUp(target: SModelElement, event: MouseEvent): Action[] {
const result: Action[] = [];
if (this.startDragPosition) {
const moveAction = this.getElementMoves(target, event, true);
if (moveAction) {
result.push(moveAction);
}
if (this.tool.movementRestrictor) {
result.push(...removeMovementRestrictionFeedback(target, this.tool.movementRestrictor));
}
}
this.hasDragged = false;
this.lastDragPosition = undefined;
return [];
this.startDragPosition = undefined;
this.elementId2startPos.clear();
return result;
}

@@ -182,4 +251,2 @@

}
}

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

SDanglingAnchor,
SEdgeSchema,
SModelElement,

@@ -41,13 +42,11 @@ SModelRoot,

import { getAbsolutePosition } from "../../utils/viewpoint-util";
import { isRoutable } from "../reconnect/model";
import { isRoutable } from "../../utils/smodel-util";
import { getAbsolutePosition, toAbsolutePosition } from "../../utils/viewpoint-util";
import { FeedbackCommand } from "./model";
export class DrawFeedbackEdgeAction implements Action {
kind = DrawFeedbackEdgeCommand.KIND;
constructor(readonly elementTypeId: string, readonly sourceId: string) { }
constructor(readonly elementTypeId: string, readonly sourceId: string, readonly routerKind?: string) { }
}
@injectable()

@@ -62,3 +61,3 @@ export class DrawFeedbackEdgeCommand extends FeedbackCommand {

execute(context: CommandExecutionContext): CommandReturn {
drawFeedbackEdge(context, this.action.sourceId, this.action.elementTypeId);
drawFeedbackEdge(context, this.action.sourceId, this.action.elementTypeId, this.action.routerKind);
return context.root;

@@ -132,3 +131,3 @@ }

function drawFeedbackEdge(context: CommandExecutionContext, sourceId: string, elementTypeId: string) {
function drawFeedbackEdge(context: CommandExecutionContext, sourceId: string, elementTypeId: string, routerKind?: string) {
const root = context.root;

@@ -147,9 +146,11 @@ const sourceChild = root.index.getById(sourceId);

edgeEnd.id = feedbackEdgeEndId(root);
edgeEnd.position = { x: source.bounds.x, y: source.bounds.y };
edgeEnd.position = toAbsolutePosition(source);
const feedbackEdgeSchema = {
type: 'edge',
const feedbackEdgeSchema = <SEdgeSchema>{
type: elementTypeId,
id: feedbackEdgeId(root),
sourceId: source.id,
targetId: edgeEnd.id,
cssClasses: ["feedback-edge"],
routerKind,
opacity: 0.3

@@ -156,0 +157,0 @@ };

@@ -26,3 +26,3 @@ /********************************************************************************

import { DrawFeedbackEdgeCommand, FeedbackEdgeEnd, RemoveFeedbackEdgeCommand } from "./creation-tool-feedback";
import { ApplyCursorCSSFeedbackActionCommand } from "./cursor-feedback";
import { ModifyCssFeedbackCommand } from "./css-feedback";
import {

@@ -40,4 +40,5 @@ DrawFeedbackEdgeSourceCommand,

configureCommand({ bind, isBound }, ModifyCssFeedbackCommand);
// create node and edge tool feedback
configureCommand({ bind, isBound }, ApplyCursorCSSFeedbackActionCommand);
configureCommand({ bind, isBound }, DrawFeedbackEdgeCommand);

@@ -44,0 +45,0 @@ configureCommand({ bind, isBound }, RemoveFeedbackEdgeCommand);

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

isConnectable,
isSelected,
isViewport,

@@ -46,5 +47,5 @@ MouseListener,

import { isNotUndefined, isSelected } from "../../utils/smodel-util";
import { isNotUndefined, isRoutable, isRoutingHandle } from "../../utils/smodel-util";
import { getAbsolutePosition } from "../../utils/viewpoint-util";
import { addReconnectHandles, isRoutable, isRoutingHandle, removeReconnectHandles } from "../reconnect/model";
import { addReconnectHandles, removeReconnectHandles } from "../reconnect/model";
import {

@@ -186,3 +187,2 @@ FeedbackEdgeEnd,

export class FeedbackEdgeRouteMovingMouseListener extends MouseListener {

@@ -189,0 +189,0 @@ hasDragged = false;

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

Action,
Bounds,
BoundsAware,
Dimension,
EdgeRouterRegistry,
ElementAndBounds,
findParentByFeature,
ISnapper,
isSelected,
isViewport,
KeyTool,
ModelLayoutOptions,
MouseListener,
Point,
SConnectableElement,
SetBoundsAction,

@@ -32,11 +38,25 @@ SModelElement,

SParentElement,
Tool
Tool,
TYPES
} from "sprotty/lib";
import { GLSP_TYPES } from "../../types";
import { forEachElement, isNonRoutableSelectedBoundsAware, isSelected, toElementAndBounds } from "../../utils/smodel-util";
import { isBoundsAwareMoveable, isResizeable, ResizeHandleLocation, SResizeHandle } from "../change-bounds/model";
import { IMovementRestrictor } from "../change-bounds/movement-restrictor";
import {
forEachElement,
isNonRoutableSelectedMovableBoundsAware,
toElementAndBounds,
toElementAndRoutingPoints
} from "../../utils/smodel-util";
import { isBoundsAwareMoveable, isResizable, Resizable, ResizeHandleLocation, SResizeHandle } from "../change-bounds/model";
import {
createMovementRestrictionFeedback,
IMovementRestrictor,
removeMovementRestrictionFeedback
} from "../change-bounds/movement-restrictor";
import { IMouseTool } from "../mouse-tool/mouse-tool";
import { ChangeBoundsOperationAction } from "../operation/operation-actions";
import {
ChangeBoundsOperationAction,
ChangeRoutingPointsOperation,
ElementAndRoutingPoints
} from "../operation/operation-actions";
import { SelectionListener, SelectionService } from "../select/selection-service";

@@ -48,3 +68,4 @@ import {

} from "../tool-feedback/change-bounds-tool-feedback";
import { IFeedbackActionDispatcher } from "../tool-feedback/feedback-action-dispatcher";
import { IFeedbackActionDispatcher, IFeedbackEmitter } from "../tool-feedback/feedback-action-dispatcher";
import { DragAwareMouseListener } from "./drag-aware-mouse-listener";

@@ -69,4 +90,4 @@ /**

protected feedbackMoveMouseListener: FeedbackMoveMouseListener;
protected changeBoundsListener: ChangeBoundsListener;
protected feedbackMoveMouseListener: MouseListener;
protected changeBoundsListener: MouseListener & SelectionListener;

@@ -77,16 +98,28 @@ constructor(@inject(GLSP_TYPES.SelectionService) protected selectionService: SelectionService,

@inject(GLSP_TYPES.IFeedbackActionDispatcher) protected feedbackDispatcher: IFeedbackActionDispatcher,
@inject(GLSP_TYPES.IMovementRestrictor) @optional() protected movementRestrictor?: IMovementRestrictor) { }
@inject(EdgeRouterRegistry) @optional() readonly edgeRouterRegistry?: EdgeRouterRegistry,
@inject(TYPES.ISnapper) @optional() readonly snapper?: ISnapper,
@inject(GLSP_TYPES.IMovementRestrictor) @optional() readonly movementRestrictor?: IMovementRestrictor) { }
enable() {
// install feedback move mouse listener for client-side move updates
this.feedbackMoveMouseListener = new FeedbackMoveMouseListener(this.movementRestrictor);
this.feedbackMoveMouseListener = this.createMoveMouseListener();
this.mouseTool.register(this.feedbackMoveMouseListener);
// instlal change bounds listener for client-side resize updates and server-side updates
this.changeBoundsListener = new ChangeBoundsListener(this);
// install change bounds listener for client-side resize updates and server-side updates
this.changeBoundsListener = this.createChangeBoundsListener();
this.mouseTool.register(this.changeBoundsListener);
this.selectionService.register(this.changeBoundsListener);
// register feedback
this.feedbackDispatcher.registerFeedback(this, [new ShowChangeBoundsToolResizeFeedbackAction]);
}
protected createMoveMouseListener(): MouseListener {
return new FeedbackMoveMouseListener(this);
}
protected createChangeBoundsListener(): MouseListener & SelectionListener {
return new ChangeBoundsListener(this);
}
disable() {

@@ -96,18 +129,21 @@ this.mouseTool.deregister(this.changeBoundsListener);

this.mouseTool.deregister(this.feedbackMoveMouseListener);
this.feedbackDispatcher.deregisterFeedback(this, [new HideChangeBoundsToolResizeFeedbackAction]);
this.feedbackDispatcher.deregisterFeedback(this.feedbackMoveMouseListener, []);
this.feedbackDispatcher.deregisterFeedback(this.changeBoundsListener, [new HideChangeBoundsToolResizeFeedbackAction]);
}
dispatchFeedback(actions: Action[]) {
this.feedbackDispatcher.registerFeedback(this, actions);
dispatchFeedback(feedbackEmmmiter: IFeedbackEmitter, actions: Action[]) {
this.feedbackDispatcher.registerFeedback(feedbackEmmmiter, actions);
}
}
class ChangeBoundsListener extends MouseListener implements SelectionListener {
export class ChangeBoundsListener extends DragAwareMouseListener implements SelectionListener {
// members for calculating the correct position change
private lastDragPosition: Point | undefined = undefined;
private positionDelta: Point = { x: 0, y: 0 };
protected lastDragPosition?: Point;
protected positionDelta: Point = { x: 0, y: 0 };
protected initialPositon: Point | undefined = undefined;
protected initialBounds: Bounds | undefined;
// members for resize mode
private activeResizeElementId: string | undefined = undefined;
private activeResizeHandle: SResizeHandle | undefined = undefined;
protected activeResizeElementId?: string;
protected activeResizeHandle?: SResizeHandle;

@@ -120,21 +156,22 @@ constructor(protected tool: ChangeBoundsTool) {

super.mouseDown(target, event);
const actions: Action[] = [];
if (event.button === 0) {
// check if we have a resize handle (only single-selection)
if (this.activeResizeElementId && target instanceof SResizeHandle) {
this.activeResizeHandle = target;
} else {
this.setActiveResizeElement(target);
}
if (this.activeResizeElementId) {
this.initPosition(event);
} else {
this.reset();
}
if (event.button !== 0) {
return [];
}
return actions;
// check if we have a resize handle (only single-selection)
if (this.activeResizeElementId && target instanceof SResizeHandle) {
this.activeResizeHandle = target;
} else {
this.setActiveResizeElement(target);
}
if (this.activeResizeElementId) {
this.initPosition(event);
} else {
this.reset();
}
return [];
}
mouseMove(target: SModelElement, event: MouseEvent): Action[] {
if (this.updatePosition(target, event)) {
super.mouseMove(target, event);
if (this.updatePosition(target, event) && this.activeResizeHandle) {
// rely on the FeedbackMoveMouseListener to update the element bounds of selected elements

@@ -147,5 +184,4 @@ // consider resize handles ourselves

mouseUp(target: SModelElement, event: MouseEvent): Action[] {
super.mouseUp(target, event);
if (!this.hasPositionDelta()) {
draggingMouseUp(target: SModelElement, event: MouseEvent): Action[] {
if (this.lastDragPosition === undefined) {
this.resetPosition();

@@ -155,18 +191,28 @@ return [];

// no further bound changing, simply send the latest data to the server using a single change bounds action for all relevant elements
const actions: Action[] = [];
if (this.activeResizeHandle) {
// An action. Resize, not move.
const resizeElement = findParentByFeature(this.activeResizeHandle, isResizeable);
// Resize, not move
const resizeElement = findParentByFeature(this.activeResizeHandle, isResizable);
if (this.isActiveResizeElement(resizeElement)) {
createChangeBoundsAction(resizeElement).forEach(action => actions.push(action));
this.createChangeBoundsAction(resizeElement).forEach(action => actions.push(action));
}
} else {
// Bounds... Change Bounds.
// Move
const newBounds: ElementAndBounds[] = [];
forEachElement(target, isNonRoutableSelectedBoundsAware, element =>
createElementAndBounds(element).forEach(bounds => newBounds.push(bounds)));
const newRoutingPoints: ElementAndRoutingPoints[] = [];
forEachElement(target, isNonRoutableSelectedMovableBoundsAware, element => {
this.createElementAndBounds(element).forEach(bounds => newBounds.push(bounds));
// If client routing is enabled -> delegate routingpoints of connected edges to server
if (this.tool.edgeRouterRegistry && element instanceof SConnectableElement) {
element.incomingEdges.map(toElementAndRoutingPoints).forEach(ear => newRoutingPoints.push(ear));
element.outgoingEdges.map(toElementAndRoutingPoints).forEach(ear => newRoutingPoints.push(ear));
}
});
if (newBounds.length > 0) {
actions.push(new ChangeBoundsOperationAction(newBounds));
}
if (newRoutingPoints.length > 0) {
actions.push(new ChangeRoutingPointsOperation(newRoutingPoints));
}
}

@@ -179,3 +225,3 @@ this.resetPosition();

if (this.activeResizeElementId) {
if (selectedElements.indexOf(this.activeResizeElementId) > -1) {
if (selectedElements.includes(this.activeResizeElementId)) {
// our active element is still selected, nothing to do

@@ -196,3 +242,3 @@ return;

private setActiveResizeElement(target: SModelElement): boolean {
protected setActiveResizeElement(target: SModelElement): boolean {
// check if we have a selected, moveable element (multi-selection allowed)

@@ -203,3 +249,3 @@ const moveableElement = findParentByFeature(target, isBoundsAwareMoveable);

this.activeResizeElementId = moveableElement.id;
this.tool.dispatchFeedback([new ShowChangeBoundsToolResizeFeedbackAction(this.activeResizeElementId)]);
this.tool.dispatchFeedback(this, [new ShowChangeBoundsToolResizeFeedbackAction(this.activeResizeElementId)]);
return true;

@@ -210,11 +256,17 @@ }

private isActiveResizeElement(element: SModelElement | undefined): element is SParentElement & BoundsAware {
protected isActiveResizeElement(element?: SModelElement): element is SParentElement & BoundsAware {
return element !== undefined && element.id === this.activeResizeElementId;
}
private initPosition(event: MouseEvent) {
protected initPosition(event: MouseEvent) {
this.initialPositon = { x: event.pageX, y: event.pageY };
this.lastDragPosition = { x: event.pageX, y: event.pageY };
if (this.activeResizeHandle) {
const resizeElement = findParentByFeature(this.activeResizeHandle, isResizable);
this.initialBounds = { x: resizeElement!.bounds.x, y: resizeElement!.bounds.y, width: resizeElement!.bounds.width, height: resizeElement!.bounds.height };
}
}
private updatePosition(target: SModelElement, event: MouseEvent): boolean {
protected updatePosition(target: SModelElement, event: MouseEvent): boolean {
if (this.lastDragPosition) {

@@ -233,18 +285,15 @@ const viewport = findParentByFeature(target, isViewport);

private reset() {
this.tool.dispatchFeedback([new HideChangeBoundsToolResizeFeedbackAction()]);
protected reset() {
this.tool.dispatchFeedback(this, [new HideChangeBoundsToolResizeFeedbackAction()]);
this.resetPosition();
}
private resetPosition() {
protected resetPosition() {
this.activeResizeHandle = undefined;
this.lastDragPosition = undefined;
this.initialPositon = undefined;
this.positionDelta = { x: 0, y: 0 };
}
private hasPositionDelta(): boolean {
return this.positionDelta.x !== 0 || this.positionDelta.y !== 0;
}
private handleElementResize(): Action[] {
protected handleElementResize(): Action[] {
if (!this.activeResizeHandle) {

@@ -254,83 +303,127 @@ return [];

const actions: Action[] = [];
const resizeElement = findParentByFeature(this.activeResizeHandle, isResizeable);
const resizeElement = findParentByFeature(this.activeResizeHandle, isResizable);
if (this.isActiveResizeElement(resizeElement)) {
switch (this.activeResizeHandle.location) {
case ResizeHandleLocation.TopLeft:
createSetBoundsAction(resizeElement,
resizeElement.bounds.x + this.positionDelta.x,
resizeElement.bounds.y + this.positionDelta.y,
resizeElement.bounds.width - this.positionDelta.x,
resizeElement.bounds.height - this.positionDelta.y)
.forEach(action => actions.push(action));
break;
return this.handleTopLeftResize(resizeElement);
case ResizeHandleLocation.TopRight:
createSetBoundsAction(resizeElement,
resizeElement.bounds.x,
resizeElement.bounds.y + this.positionDelta.y,
resizeElement.bounds.width + this.positionDelta.x,
resizeElement.bounds.height - this.positionDelta.y)
.forEach(action => actions.push(action));
break;
return this.handleTopRightResize(resizeElement);
case ResizeHandleLocation.BottomLeft:
createSetBoundsAction(resizeElement,
resizeElement.bounds.x + this.positionDelta.x,
resizeElement.bounds.y,
resizeElement.bounds.width - this.positionDelta.x,
resizeElement.bounds.height + this.positionDelta.y)
.forEach(action => actions.push(action));
break;
return this.handleBottomLeftResize(resizeElement);
case ResizeHandleLocation.BottomRight:
createSetBoundsAction(resizeElement,
resizeElement.bounds.x,
resizeElement.bounds.y,
resizeElement.bounds.width + this.positionDelta.x,
resizeElement.bounds.height + this.positionDelta.y)
.forEach(action => actions.push(action));
break;
return this.handleBottomRightResize(resizeElement);
}
}
return actions;
return [];
}
}
function createChangeBoundsAction(element: SModelElement & BoundsAware): Action[] {
if (isValidBoundChange(element, element.bounds, element.bounds)) {
return [new ChangeBoundsOperationAction([toElementAndBounds(element)])];
protected handleTopLeftResize(resizeElement: SParentElement & Resizable): Action[] {
return this.createSetBoundsAction(resizeElement,
resizeElement.bounds.x + this.positionDelta.x,
resizeElement.bounds.y + this.positionDelta.y,
resizeElement.bounds.width - this.positionDelta.x,
resizeElement.bounds.height - this.positionDelta.y);
}
return [];
}
function createElementAndBounds(element: SModelElement & BoundsAware): ElementAndBounds[] {
if (isValidBoundChange(element, element.bounds, element.bounds)) {
return [toElementAndBounds(element)];
protected handleTopRightResize(resizeElement: SParentElement & Resizable): Action[] {
return this.createSetBoundsAction(resizeElement,
resizeElement.bounds.x,
resizeElement.bounds.y + this.positionDelta.y,
resizeElement.bounds.width + this.positionDelta.x,
resizeElement.bounds.height - this.positionDelta.y);
}
return [];
}
function createSetBoundsAction(element: SModelElement & BoundsAware, x: number, y: number, width: number, height: number): Action[] {
const newPosition = { x, y };
const newSize = { width, height };
if (isValidBoundChange(element, newPosition, newSize)) {
return [new SetBoundsAction([{ elementId: element.id, newPosition, newSize }])];
protected handleBottomLeftResize(resizeElement: SParentElement & Resizable): Action[] {
return this.createSetBoundsAction(resizeElement,
resizeElement.bounds.x + this.positionDelta.x,
resizeElement.bounds.y,
resizeElement.bounds.width - this.positionDelta.x,
resizeElement.bounds.height + this.positionDelta.y);
}
protected handleBottomRightResize(resizeElement: SParentElement & Resizable): Action[] {
return this.createSetBoundsAction(resizeElement,
resizeElement.bounds.x,
resizeElement.bounds.y,
resizeElement.bounds.width + this.positionDelta.x,
resizeElement.bounds.height + this.positionDelta.y);
}
return [];
}
protected createChangeBoundsAction(element: SModelElement & BoundsAware): Action[] {
if (this.isValidBoundChange(element, element.bounds, element.bounds)) {
return [new ChangeBoundsOperationAction([toElementAndBounds(element)])];
} else if (this.initialBounds) {
const actions: Action[] = [];
if (this.tool.movementRestrictor) {
actions.push(...removeMovementRestrictionFeedback(element, this.tool.movementRestrictor));
}
actions.push(new SetBoundsAction([{ elementId: element.id, newPosition: this.initialBounds, newSize: this.initialBounds }]));
return actions;
}
return [];
}
function isValidBoundChange(element: SModelElement & BoundsAware, newPosition: Point, newSize: Dimension): boolean {
return newSize.width >= minWidth(element) && newSize.height >= minHeight(element);
}
protected createElementAndBounds(element: SModelElement & BoundsAware): ElementAndBounds[] {
if (this.isValidBoundChange(element, element.bounds, element.bounds)) {
return [toElementAndBounds(element)];
}
return [];
}
function minWidth(element: SModelElement & BoundsAware): number {
// currently there are no element-specific constraints
return 1;
}
protected createSetBoundsAction(element: SModelElement & BoundsAware, x: number, y: number, width: number, height: number): Action[] {
const newPosition = { x, y };
const newSize = { width, height };
const result: Action[] = [];
if (this.isValidBoundChange(element, newPosition, newSize)) {
if (this.tool.movementRestrictor) {
result.push(...removeMovementRestrictionFeedback(element, this.tool.movementRestrictor));
}
function minHeight(element: SModelElement & BoundsAware): number {
// currently there are no element-specific constraints
return 1;
}
result.push(new SetBoundsAction([{ elementId: element.id, newPosition, newSize }]));
} else if (this.isValidSize(element, newSize)) {
if (this.tool.movementRestrictor) {
result.push(...createMovementRestrictionFeedback(element, this.tool.movementRestrictor));
}
result.push(new SetBoundsAction([{ elementId: element.id, newPosition, newSize }]));
}
return result;
}
protected isValidBoundChange(element: SModelElement & BoundsAware, newPosition: Point, newSize: Dimension): boolean {
const valid = this.isValidSize(element, newSize);
if (this.tool.movementRestrictor) {
return valid && this.tool.movementRestrictor.validate(newPosition, element);
}
return valid;
}
protected isValidSize(element: SModelElement & BoundsAware, size: Dimension) {
return size.width >= this.minWidth(element) && size.height >= this.minHeight(element);
}
protected minWidth(element: SModelElement & BoundsAware): number {
const layoutOptions = this.getLayoutOptions(element);
if (layoutOptions !== undefined && typeof layoutOptions.minWidth === 'number') {
return layoutOptions.minWidth;
}
return 1;
}
protected minHeight(element: SModelElement & BoundsAware): number {
const layoutOptions = this.getLayoutOptions(element);
if (layoutOptions !== undefined && typeof layoutOptions.minHeight === 'number') {
return layoutOptions.minHeight;
}
return 1;
}
protected getLayoutOptions(element: SModelElement): ModelLayoutOptions | undefined {
const layoutOptions = (element as any).layoutOptions;
if (layoutOptions !== undefined) {
return layoutOptions as ModelLayoutOptions;
}
return undefined;
}
}

@@ -21,15 +21,15 @@ /********************************************************************************

EnableDefaultToolsAction,
findParent,
findParentByFeature,
isConnectable,
isCtrlOrCmd,
SEdge,
SModelElement,
SModelRoot,
Tool
} from "sprotty/lib";
import { containmentAllowed, EdgeEditConfig, edgeEditConfig, IEditConfigProvider } from "../../base/edit-config/edit-config";
import { TypeAware } from "../../base/tool-manager/tool-manager-action-handler";
import { GLSP_TYPES } from "../../types";
import { getAbsolutePosition } from "../../utils/viewpoint-util";
import { Containable, isContainable } from "../hints/model";
import { ITypeHintProvider } from "../hints/type-hints";
import { IMouseTool } from "../mouse-tool/mouse-tool";

@@ -43,7 +43,6 @@ import { CreateConnectionOperationAction, CreateNodeOperationAction } from "../operation/operation-actions";

} from "../tool-feedback/creation-tool-feedback";
import { ApplyCursorCSSFeedbackAction, CursorCSS } from "../tool-feedback/cursor-feedback";
import { CursorCSS, cursorFeedbackAction } from "../tool-feedback/css-feedback";
import { IFeedbackActionDispatcher } from "../tool-feedback/feedback-action-dispatcher";
import { DragAwareMouseListener } from "./drag-aware-mouse-listener";
export const TOOL_ID_PREFIX = "tool";

@@ -70,3 +69,3 @@

this.mouseTool.register(this.creationToolMouseListener);
this.feedbackDispatcher.registerFeedback(this, [new ApplyCursorCSSFeedbackAction(CursorCSS.NODE_CREATION)]);
this.feedbackDispatcher.registerFeedback(this, [cursorFeedbackAction(CursorCSS.NODE_CREATION)]);
}

@@ -76,3 +75,3 @@

this.mouseTool.deregister(this.creationToolMouseListener);
this.feedbackDispatcher.deregisterFeedback(this, [new ApplyCursorCSSFeedbackAction()]);
this.feedbackDispatcher.deregisterFeedback(this, [cursorFeedbackAction()]);
}

@@ -87,3 +86,3 @@

export class NodeCreationToolMouseListener extends DragAwareMouseListener {
private container?: SModelElement;
protected container?: SModelElement & Containable;
constructor(protected elementTypeId: string, protected tool: NodeCreationTool) {

@@ -93,4 +92,4 @@ super();

private creationAllowed(target: SModelElement) {
return this.container || target instanceof SModelRoot;
protected creationAllowed(elementTypeId: string) {
return this.container && this.container.isContainableElement(elementTypeId);
}

@@ -100,3 +99,3 @@

const result: Action[] = [];
if (this.creationAllowed(target)) {
if (this.creationAllowed(this.elementTypeId)) {
const containerId = this.container ? this.container.id : undefined;

@@ -113,8 +112,8 @@ const location = getAbsolutePosition(target, event);

mouseOver(target: SModelElement, event: MouseEvent): Action[] {
const currentContainer = findParent(target, e => containmentAllowed(e, this.elementTypeId));
const currentContainer = findParentByFeature(target, isContainable);
if (!this.container || currentContainer !== this.container) {
this.container = currentContainer;
const feedback = this.creationAllowed(target)
? new ApplyCursorCSSFeedbackAction(CursorCSS.NODE_CREATION) :
new ApplyCursorCSSFeedbackAction(CursorCSS.OPERATION_NOT_ALLOWED);
const feedback = this.creationAllowed(this.elementTypeId)
? cursorFeedbackAction(CursorCSS.NODE_CREATION) :
cursorFeedbackAction(CursorCSS.OPERATION_NOT_ALLOWED);
this.tool.dispatchFeedback([feedback]);

@@ -139,3 +138,3 @@ }

@inject(AnchorComputerRegistry) protected anchorRegistry: AnchorComputerRegistry,
@inject(GLSP_TYPES.IEditConfigProvider) public readonly editConfigProvider: IEditConfigProvider) { }
@inject(GLSP_TYPES.ITypeHintProvider) public readonly typeHintProvider: ITypeHintProvider) { }

@@ -151,3 +150,3 @@ get id() {

this.mouseTool.register(this.feedbackEndMovingMouseListener);
this.dispatchFeedback([new ApplyCursorCSSFeedbackAction(CursorCSS.OPERATION_NOT_ALLOWED)]);
this.dispatchFeedback([cursorFeedbackAction(CursorCSS.OPERATION_NOT_ALLOWED)]);
}

@@ -158,3 +157,3 @@

this.mouseTool.deregister(this.feedbackEndMovingMouseListener);
this.feedbackDispatcher.deregisterFeedback(this, [new RemoveFeedbackEdgeAction(), new ApplyCursorCSSFeedbackAction()]);
this.feedbackDispatcher.deregisterFeedback(this, [new RemoveFeedbackEdgeAction(), cursorFeedbackAction()]);
}

@@ -170,17 +169,14 @@

export class EdgeCreationToolMouseListener extends DragAwareMouseListener {
private source?: string;
private target?: string;
private currentTarget?: SModelElement;
private allowedTarget: boolean = false;
private edgeEditConfig?: EdgeEditConfig;
protected source?: string;
protected target?: string;
protected currentTarget?: SModelElement;
protected allowedTarget: boolean = false;
protected proxyEdge: SEdge;
constructor(protected elementTypeId: string, protected tool: EdgeCreationTool) {
super();
const config = tool.editConfigProvider.getEditConfig(this.elementTypeId);
if (config && config.configType === edgeEditConfig) {
this.edgeEditConfig = config as EdgeEditConfig;
}
this.proxyEdge = new SEdge();
this.proxyEdge.type = elementTypeId;
}
private reinitialize() {
protected reinitialize() {
this.source = undefined;

@@ -220,7 +216,7 @@ this.target = undefined;

private isSourceSelected() {
protected isSourceSelected() {
return this.source !== undefined;
}
private isTargetSelected() {
protected isTargetSelected() {
return this.target !== undefined;

@@ -241,8 +237,8 @@ }

if (this.allowedTarget) {
const action = !this.isSourceSelected() ? new ApplyCursorCSSFeedbackAction(CursorCSS.EDGE_CREATION_SOURCE) :
new ApplyCursorCSSFeedbackAction(CursorCSS.EDGE_CREATION_TARGET);
const action = !this.isSourceSelected() ? cursorFeedbackAction(CursorCSS.EDGE_CREATION_SOURCE) :
cursorFeedbackAction(CursorCSS.EDGE_CREATION_TARGET);
return [action];
}
}
return [new ApplyCursorCSSFeedbackAction(CursorCSS.OPERATION_NOT_ALLOWED)];
return [cursorFeedbackAction(CursorCSS.OPERATION_NOT_ALLOWED)];
}

@@ -252,9 +248,10 @@ return [];

private isAllowedSource(element: SModelElement | undefined): boolean {
return element !== undefined && this.edgeEditConfig ? this.edgeEditConfig.isAllowedSource(element) : false;
protected isAllowedSource(element: SModelElement | undefined): boolean {
return element !== undefined && isConnectable(element) && element.canConnect(this.proxyEdge, "source");
}
private isAllowedTarget(element: SModelElement | undefined): boolean {
return element !== undefined && this.edgeEditConfig ? this.edgeEditConfig.isAllowedTarget(element) : false;
protected isAllowedTarget(element: SModelElement | undefined): boolean {
return element !== undefined && isConnectable(element) && element.canConnect(this.proxyEdge, "target");
}
}

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

isCtrlOrCmd,
isDeletable,
isSelectable,

@@ -27,3 +28,2 @@ KeyListener,

SModelElement,
SModelRoot,
Tool

@@ -36,3 +36,3 @@ } from "sprotty/lib";

import { DeleteElementOperationAction } from "../operation/operation-actions";
import { ApplyCursorCSSFeedbackAction, CursorCSS } from "../tool-feedback/cursor-feedback";
import { CursorCSS, cursorFeedbackAction } from "../tool-feedback/css-feedback";
import { IFeedbackActionDispatcher } from "../tool-feedback/feedback-action-dispatcher";

@@ -65,3 +65,3 @@

if (matchesKeystroke(event, 'Delete')) {
const deleteElementIds = Array.from(element.root.index.all().filter(e => isSelectable(e) && e.selected)
const deleteElementIds = Array.from(element.root.index.all().filter(e => isDeletable(e) && isSelectable(e) && e.selected)
.filter(e => e.id !== e.root.id).map(e => e.id));

@@ -90,3 +90,3 @@ return [new DeleteElementOperationAction(deleteElementIds)];

this.mouseTool.register(this.deleteToolMouseListener);
this.feedbackDispatcher.registerFeedback(this, [new ApplyCursorCSSFeedbackAction(CursorCSS.ELEMENT_DELETION)]);
this.feedbackDispatcher.registerFeedback(this, [cursorFeedbackAction(CursorCSS.ELEMENT_DELETION)]);
}

@@ -96,6 +96,4 @@

this.mouseTool.deregister(this.deleteToolMouseListener);
this.feedbackDispatcher.registerFeedback(this, [new ApplyCursorCSSFeedbackAction()]);
this.feedbackDispatcher.registerFeedback(this, [cursorFeedbackAction()]);
}
}

@@ -106,3 +104,3 @@

mouseUp(target: SModelElement, event: MouseEvent): Action[] {
if (target instanceof SModelRoot) {
if (!isDeletable(target)) {
return [];

@@ -109,0 +107,0 @@ }

@@ -28,7 +28,7 @@ /********************************************************************************

private isMouseDown: boolean = false;
private isMouseDrag: boolean = false;
private _isMouseDown: boolean = false;
private _isMouseDrag: boolean = false;
mouseDown(target: SModelElement, event: MouseEvent): Action[] {
this.isMouseDown = true;
this._isMouseDown = true;
return [];

@@ -38,4 +38,4 @@ }

mouseMove(target: SModelElement, event: MouseEvent): Action[] {
if (this.isMouseDown) {
this.isMouseDrag = true;
if (this._isMouseDown) {
this._isMouseDrag = true;
}

@@ -46,5 +46,5 @@ return [];

mouseUp(element: SModelElement, event: MouseEvent): Action[] {
this.isMouseDown = false;
if (this.isMouseDrag) {
this.isMouseDrag = false;
this._isMouseDown = false;
if (this._isMouseDrag) {
this._isMouseDrag = false;
return this.draggingMouseUp(element, event);

@@ -64,2 +64,10 @@ }

get isMouseDrag() {
return this._isMouseDrag;
}
get isMouseDown() {
return this._isMouseDown;
}
}

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

AnchorComputerRegistry,
canEditRouting,
Connectable,

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

isConnectable,
isSelected,
MouseListener,

@@ -34,11 +36,9 @@ SModelElement,

import { isConfigurableEdge } from "../../base/edit-config/edit-config";
import { GLSP_TYPES } from "../../types";
import { isSelected } from "../../utils/smodel-util";
import { isRoutable, isRoutingHandle } from "../../utils/smodel-util";
import { IMouseTool } from "../mouse-tool/mouse-tool";
import { ReconnectConnectionOperationAction, RerouteConnectionOperationAction } from "../reconnect/action-definitions";
import { ChangeRoutingPointsOperation, ReconnectConnectionOperationAction } from "../operation/operation-actions";
import {
isReconnectable,
isReconnectHandle,
isRoutable,
isRoutingHandle,
isSourceRoutingHandle,

@@ -50,3 +50,3 @@ isTargetRoutingHandle,

import { DrawFeedbackEdgeAction, feedbackEdgeId, RemoveFeedbackEdgeAction } from "../tool-feedback/creation-tool-feedback";
import { ApplyCursorCSSFeedbackAction, CursorCSS } from "../tool-feedback/cursor-feedback";
import { CursorCSS, cursorFeedbackAction } from "../tool-feedback/css-feedback";
import {

@@ -109,13 +109,13 @@ DrawFeedbackEdgeSourceAction,

class ReconnectEdgeListener extends MouseListener implements SelectionListener {
private isMouseDown: boolean;
protected isMouseDown: boolean;
// active selection data
private edge?: SRoutableElement;
private routingHandle?: SRoutingHandle;
protected edge?: SRoutableElement;
protected routingHandle?: SRoutingHandle;
// new connectable (source or target) for edge
private newConnectable?: SModelElement & Connectable;
protected newConnectable?: SModelElement & Connectable;
// active reconnect handle data
private reconnectMode?: 'NEW_SOURCE' | 'NEW_TARGET';
protected reconnectMode?: 'NEW_SOURCE' | 'NEW_TARGET';

@@ -126,7 +126,7 @@ constructor(protected tool: EdgeEditTool) {

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

@@ -139,14 +139,21 @@ // reset from a previously selected edge

// note: order is important here as we want the reconnect handles to cover the routing handles
this.tool.dispatchFeedback([new SwitchRoutingModeAction([this.edge.id], []), new ShowEdgeReconnectHandlesFeedbackAction(this.edge.id)]);
const feedbackActions = [];
if (canEditRouting(edge)) {
feedbackActions.push(new SwitchRoutingModeAction([this.edge.id], []));
}
if (isReconnectable(edge)) {
feedbackActions.push(new ShowEdgeReconnectHandlesFeedbackAction(this.edge.id));
}
this.tool.dispatchFeedback(feedbackActions);
}
private isEdgeSelected(): boolean {
protected isEdgeSelected(): boolean {
return this.edge !== undefined && isSelected(this.edge);
}
private setReconnectHandleSelected(edge: SRoutableElement, reconnectHandle: SReconnectHandle) {
protected setReconnectHandleSelected(edge: SRoutableElement, reconnectHandle: SReconnectHandle) {
if (this.edge && this.edge.target && this.edge.source) {
if (isSourceRoutingHandle(edge, reconnectHandle)) {
this.tool.dispatchFeedback([new HideEdgeReconnectHandlesFeedbackAction(),
new ApplyCursorCSSFeedbackAction(CursorCSS.EDGE_RECONNECT),
cursorFeedbackAction(CursorCSS.EDGE_RECONNECT),
new DrawFeedbackEdgeSourceAction(this.edge.type, this.edge.targetId)]);

@@ -156,3 +163,3 @@ this.reconnectMode = "NEW_SOURCE";

this.tool.dispatchFeedback([new HideEdgeReconnectHandlesFeedbackAction(),
new ApplyCursorCSSFeedbackAction(CursorCSS.EDGE_CREATION_TARGET),
cursorFeedbackAction(CursorCSS.EDGE_CREATION_TARGET),
new DrawFeedbackEdgeAction(this.edge.type, this.edge.sourceId)]);

@@ -164,11 +171,11 @@ this.reconnectMode = "NEW_TARGET";

private isReconnecting(): boolean {
protected isReconnecting(): boolean {
return this.reconnectMode !== undefined;
}
private isReconnectingNewSource(): boolean {
protected isReconnectingNewSource(): boolean {
return this.reconnectMode === "NEW_SOURCE";
}
private setRoutingHandleSelected(edge: SRoutableElement, routingHandle: SRoutingHandle) {
protected setRoutingHandleSelected(edge: SRoutableElement, routingHandle: SRoutingHandle) {
if (this.edge && this.edge.target && this.edge.source) {

@@ -179,15 +186,15 @@ this.routingHandle = routingHandle;

private requiresReconnect(sourceId: string, targetId: string): boolean {
protected requiresReconnect(sourceId: string, targetId: string): boolean {
return this.edge !== undefined && (this.edge.sourceId !== sourceId || this.edge.targetId !== targetId);
}
private setNewConnectable(connectable?: SModelElement & Connectable) {
protected setNewConnectable(connectable?: SModelElement & Connectable) {
this.newConnectable = connectable;
}
private isReadyToReconnect() {
protected isReadyToReconnect() {
return this.edge && this.isReconnecting() && this.newConnectable !== undefined;
}
private isReadyToReroute() {
protected isReadyToReroute() {
return this.routingHandle !== undefined;

@@ -245,3 +252,3 @@ }

if (latestEdge && isRoutable(latestEdge)) {
result.push(new RerouteConnectionOperationAction(latestEdge.id, latestEdge.routingPoints));
result.push(new ChangeRoutingPointsOperation([{ elementId: latestEdge.id, newRoutingPoints: latestEdge.routingPoints }]));
this.routingHandle = undefined;

@@ -258,11 +265,11 @@ }

this.setNewConnectable(currentTarget);
if (currentTarget && isConfigurableEdge(this.edge)) {
if ((this.reconnectMode === 'NEW_SOURCE' && this.edge.isAllowedSource(currentTarget.type)) ||
(this.reconnectMode === 'NEW_TARGET' && this.edge.isAllowedTarget(currentTarget.type))) {
if (currentTarget) {
if ((this.reconnectMode === 'NEW_SOURCE' && currentTarget.canConnect(this.edge, "source")) ||
(this.reconnectMode === 'NEW_TARGET' && currentTarget.canConnect(this.edge, "target"))) {
this.tool.dispatchFeedback([new ApplyCursorCSSFeedbackAction(CursorCSS.EDGE_RECONNECT)]);
this.tool.dispatchFeedback([cursorFeedbackAction(CursorCSS.EDGE_RECONNECT)]);
return [];
}
}
this.tool.dispatchFeedback([new ApplyCursorCSSFeedbackAction(CursorCSS.OPERATION_NOT_ALLOWED)]);
this.tool.dispatchFeedback([cursorFeedbackAction(CursorCSS.OPERATION_NOT_ALLOWED)]);
}

@@ -307,3 +314,3 @@ }

private resetData() {
protected resetData() {
this.isMouseDown = false;

@@ -316,3 +323,3 @@ this.edge = undefined;

private resetFeedback() {
protected resetFeedback() {
const result: Action[] = [];

@@ -323,5 +330,5 @@ if (this.edge) {

result.push(...[new HideEdgeReconnectHandlesFeedbackAction(),
new ApplyCursorCSSFeedbackAction(), new RemoveFeedbackEdgeAction()]);
cursorFeedbackAction(), new RemoveFeedbackEdgeAction()]);
this.tool.dispatchFeedback(result);
}
}

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

IActionDispatcher,
SDecoration,
SIssue,

@@ -33,2 +34,4 @@ SIssueMarker,

import { Marker, MarkerKind } from "../../utils/marker";
import { addCssClasses, removeCssClasses } from "../../utils/smodel-util";
import { getSeverity } from "../hover/hover";
import { IFeedbackActionDispatcher, IFeedbackEmitter } from "../tool-feedback/feedback-action-dispatcher";

@@ -159,2 +162,3 @@ import { FeedbackCommand } from "../tool-feedback/model";

issueMarker.issues.push(issue);
addCSSClassToIssueParent(modelElement, issueMarker);
}

@@ -174,2 +178,10 @@ }

function addCSSClassToIssueParent(modelElement: SParentElement, issueMarker: SIssueMarker) {
addCssClasses(modelElement, [getSeverity(issueMarker)]);
}
function removeCSSClassFromIssueParent(modelElement: SParentElement, issueMarker: SIssueMarker) {
removeCssClasses(modelElement, [getSeverity(issueMarker)]);
}
/**

@@ -188,3 +200,3 @@ * Retrieves the `SIssueMarker` contained by the provided model element as

if (issueMarker === undefined) {
issueMarker = new SIssueMarker();
issueMarker = new GIssueMarker();
issueMarker.type = "marker";

@@ -271,2 +283,3 @@ issueMarker.issues = new Array<SIssue>();

if (issueMarker !== undefined) {
removeCSSClassFromIssueParent(modelElement, issueMarker);
for (let index = 0; index < issueMarker.issues.length; ++index) {

@@ -280,2 +293,4 @@ const issue: SIssue = issueMarker.issues[index];

modelElement.remove(issueMarker);
} else {
addCSSClassToIssueParent(modelElement, issueMarker);
}

@@ -296,1 +311,9 @@ }

}
export class GIssueMarker extends SIssueMarker {
constructor() {
super();
this.features = new Set<symbol>(SDecoration.DEFAULT_FEATURES);
}
}

@@ -18,5 +18,8 @@ /********************************************************************************

import glspCommandPaletteModule from "./features/command-palette/di.config";
import glspContextMenuModule from "./features/context-menu/di.config";
import glspServerCopyPasteModule from "./features/copy-paste/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 glspHoverModule from "./features/hover/di.config";
import layoutCommandsModule from "./features/layout/di.config";

@@ -32,24 +35,37 @@ import glspMouseToolModule from "./features/mouse-tool/di.config";

export * from 'sprotty/lib';
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/command-stack';
export * from './base/editor-context';
export * from './features/change-bounds/model';
export * from './features/change-bounds/movement-restrictor';
export * from './features/command-palette/action-definitions';
export * from './features/command-palette/action-provider';
export * from './features/change-bounds/snap';
export * from './features/context-actions/action-definitions';
export * from './features/context-menu/delete-element-context-menu';
export * from './features/command-palette/server-command-palette-provider';
export * from './features/copy-paste/copy-paste-handler';
export * from './features/edit-label-validation/edit-label-validator';
export * from './features/execute/execute-command';
export * from './features/execute/model';
export * from './features/hints/action-definition';
export * from './features/hints/type-hints-action-initializer';
export * from './features/mouse-tool/di.config';
export * from './features/hints/request-type-hints-action';
export * from './features/hints/type-hints';
export * from './features/hints/model';
export * from "./features/hover/hover";
export * from './features/layout/layout-commands';
export * from './features/mouse-tool/mouse-tool';
export * from './features/operation/operation-actions';
export * from './features/operation/set-operations';
export * from './features/request-response/action-definitions';
export * from './features/request-response/support';
export * from './features/rank/model';
export * from './features/reconnect/model';
export * from './features/request-response/glsp-action-dispatcher';
export * from './features/save/model';
export * from './features/save/save';
export * from './features/select/di.config';
export * from './features/tool-feedback/change-bounds-tool-feedback';
export * from './features/tool-feedback/creation-tool-feedback';
export * from './features/tool-feedback/css-feedback';
export * from './features/tool-feedback/edge-edit-tool-feedback';
export * from './features/tool-feedback/feedback-action-dispatcher';
export * from './features/tool-feedback/model';
export * from './features/tool-feedback/model';
export * from './features/tool-palette/tool-palette';

@@ -60,5 +76,7 @@ export * from './features/tools/change-bounds-tool';

export * from './features/tools/delete-tool';
export * from './features/tools/drag-aware-mouse-listener';
export * from './features/tools/edge-edit-tool';
export * from './features/undo-redo/model';
export * from './features/validation/validate';
export * from './features/layout/layout-commands';
export * from './lib/model';

@@ -70,9 +88,9 @@ export * from './types';

export * from './utils/viewpoint-util';
export * from './model-source/websocket-diagram-server';
export * from "./model-source/glsp-server-status";
export {
validationModule, saveModule, executeModule, paletteModule, toolFeedbackModule, defaultGLSPModule, modelHintsModule, glspCommandPaletteModule, requestResponseModule, //
glspSelectModule, glspMouseToolModule, layoutCommandsModule, glspEditLabelValidationModule
glspContextMenuModule, glspServerCopyPasteModule, glspSelectModule, glspMouseToolModule, layoutCommandsModule, glspEditLabelValidationModule, glspHoverModule
};

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

********************************************************************************/
import { SGraph } from "sprotty/lib";
import { exportFeature, SGraph, SModelElement, SModelElementSchema, viewportFeature } from "sprotty/lib";
import { Containable, containerFeature } from "../features/hints/model";
import { Saveable, saveFeature } from "../features/save/model";
export class GLSPGraph extends SGraph implements Saveable {
dirty: boolean;
hasFeature(feature: symbol) {
return feature === saveFeature || super.hasFeature(feature);
export class GLSPGraph extends SGraph implements Saveable, Containable {
static readonly DEFAULT_FEATURES = [viewportFeature, exportFeature, saveFeature, containerFeature];
dirty: boolean = false;
isContainableElement(input: string | SModelElement | SModelElementSchema): boolean {
return true;
}
}

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

import { NotificationType } from "vscode-ws-jsonrpc";
import { RequestCommandPaletteActions } from "../features/command-palette/action-definitions";
import { RequestContextActions } from "../features/context-actions/action-definitions";
import { ExecuteServerCommandAction } from "../features/execute/execute-command";
import { RequestTypeHintsAction } from "../features/hints/action-definition";
import { RequestTypeHintsAction } from "../features/hints/request-type-hints-action";
import { OperationKind, RequestOperationsAction } from "../features/operation/set-operations";
import { IdentifiableRequestAction } from "../features/request-response/action-definitions";
import { SaveModelAction } from "../features/save/save";
import { GlspRedoAction, GlspUndoAction } from "../features/undo-redo/model";
import { RequestMarkersAction } from "../features/validation/validate";
import { ValidateLabelEditAction } from "../features/edit-label-validation/edit-label-validator";
import { RequestClipboardDataAction, PasteOperationAction, CutOperationAction } from "../features/copy-paste/copy-paste-actions";

@@ -50,3 +51,2 @@ @injectable()

});
}

@@ -89,3 +89,3 @@

registry.register(OperationKind.RECONNECT_CONNECTION, diagramServer);
registry.register(OperationKind.REROUTE_CONNECTION, diagramServer);
registry.register(OperationKind.CHANGE_ROUTING_POINTS, diagramServer);
registry.register(OperationKind.CREATE_NODE, diagramServer);

@@ -105,7 +105,10 @@ registry.register(OperationKind.CHANGE_BOUNDS, diagramServer);

registry.register(ExportSvgAction.KIND, diagramServer);
registry.register(RequestCommandPaletteActions.KIND, diagramServer);
registry.register(IdentifiableRequestAction.KIND, diagramServer);
registry.register(RequestContextActions.KIND, diagramServer);
registry.register(ValidateLabelEditAction.KIND, diagramServer);
registry.register(RequestMarkersAction.KIND, diagramServer);
registry.register(LayoutAction.KIND, diagramServer);
registry.register(ApplyLabelEditAction.KIND, diagramServer);
registry.register(RequestClipboardDataAction.KIND, diagramServer);
registry.register(PasteOperationAction.KIND, diagramServer);
registry.register(CutOperationAction.KIND, diagramServer);

@@ -112,0 +115,0 @@ // Register an empty handler for SwitchEditMode, to avoid runtime exceptions.

@@ -20,9 +20,13 @@ /********************************************************************************

IToolFactory: Symbol.for("Factory<Tool>"),
IEditConfigProvider: Symbol.for("IEditConfigProvider"),
ITypeHintProvider: Symbol.for("ITypeHintProvider"),
IMovementRestrictor: Symbol.for("IMovmementRestrictor"),
RequestResponseSupport: Symbol.for("RequestResponseSupport"),
SelectionService: Symbol.for("SelectionService"),
SelectionListener: Symbol.for("SelectionListener"),
SModelRootListener: Symbol.for("SModelRootListener"),
MouseTool: Symbol.for("MouseTool")
MouseTool: Symbol.for("MouseTool"),
IContextMenuService: Symbol.for("IContextMenuService"),
IContextMenuServiceProvider: Symbol.for("IContextMenuServiceProvider"),
IContextMenuProviderRegistry: Symbol.for("IContextMenuProviderRegistry"),
IContextMenuProvider: Symbol.for("IContextMenuProvider"),
ICopyPasteHandler: Symbol.for("ICopyPasteHandler")
};

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

export function contains<T>(array: T[], value: T): boolean {
if (value === undefined) return false;
return array.indexOf(value) >= 0;
}
export function remove<T>(array: T[], value: T): boolean {

@@ -33,3 +28,3 @@ const index = array.indexOf(value);

export function distinctAdd<T>(array: T[], value: T): boolean {
if (!contains(array, value)) {
if (!array.includes(value)) {
array.push(value);

@@ -36,0 +31,0 @@ return true;

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

********************************************************************************/
import { BoundsAware, isBoundsAware, isSelectable, Selectable, SModelElement, SParentElement } from "sprotty/lib";
import {
BoundsAware,
isBoundsAware,
isMoveable,
isSelected,
Selectable,
SModelElement,
SRoutableElement,
SRoutingHandle
} from "sprotty/lib";
import { ElementAndRoutingPoints } from "src/features/operation/operation-actions";
import { isConfigurableNode, NodeEditConfig } from "../base/edit-config/edit-config";
import { isRoutable } from "../features/reconnect/model";

@@ -50,6 +58,2 @@ export function getIndex(element: SModelElement) {

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

@@ -82,5 +86,4 @@ return element !== undefined;

export function isContainmentAllowed(element: SModelElement, containableElementTypeId: string)
: element is SParentElement & NodeEditConfig {
return isConfigurableNode(element) && element.isContainableElement(containableElementTypeId);
export function isNonRoutableSelectedMovableBoundsAware(element: SModelElement): element is SelectableBoundsAware {
return isNonRoutableSelectedBoundsAware(element) && isMoveable(element);
}

@@ -92,2 +95,10 @@

export function isRoutable<T extends SModelElement>(element: T): element is T & SRoutableElement {
return element instanceof SRoutableElement && (element as any).routingPoints !== undefined;
}
export function isRoutingHandle(element: SModelElement | undefined): element is SRoutingHandle {
return element !== undefined && element instanceof SRoutingHandle;
}
export type SelectableBoundsAware = SModelElement & BoundsAware & Selectable;

@@ -108,1 +119,8 @@

}
export function toElementAndRoutingPoints(element: SRoutableElement): ElementAndRoutingPoints {
return {
elementId: element.id,
newRoutingPoints: element.routingPoints
};
}

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

********************************************************************************/
import { Point } from "sprotty/lib";
import { SModelElement } from "sprotty/lib";
import { Viewport } from "sprotty/lib";
import {
Bounds,
BoundsAware,
Dimension,
findParentByFeature,
isAlignable,
isViewport,
ORIGIN_POINT,
Point,
SModelElement,
translateBounds,
Viewport
} from "sprotty/lib";
import { findParentByFeature } from "sprotty/lib";
import { isViewport } from "sprotty/lib";
/**

@@ -60,1 +67,36 @@ * Return the position corresponding to this mouse event (Browser coordinates)

}
/**
* Translates the bounds of the diagram element (local coordinates) into the diagram coordinates system
* (i.e. relative to the Diagram's 0;0 point)
*
* @param target A bounds-aware element from the diagram
*/
export function toAbsoluteBounds(element: SModelElement & BoundsAware): Bounds {
const location = isAlignable(element) ? element.alignment : ORIGIN_POINT;
const x = location.x;
const y = location.y;
const width = element.bounds.width;
const height = element.bounds.height;
return translateBounds({ x, y, width, height }, element, element.root);
}
/**
* Translates the position of the diagram element (local coordinates) into the diagram coordinates system
* (i.e. relative to the Diagram's 0;0 point)
*
* @param target A bounds-aware element from the diagram
*/
export function toAbsolutePosition(target: SModelElement & BoundsAware): Point {
return toAbsoluteBounds(target);
}
/**
* Translates the size of the diagram element (local coordinates) into the diagram coordinates system
* (i.e. relative to the Diagram's 0;0 point)
*
* @param target A bounds-aware element from the diagram
*/
export function toAbsoluteSize(target: SModelElement & BoundsAware): Dimension {
return toAbsoluteBounds(target);
}

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

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