Socket
Socket
Sign inDemoInstall

sprotty

Package Overview
Dependencies
6
Maintainers
4
Versions
236
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.1.1 to 1.2.0

lib/features/edge-junction/di.config.d.ts

6

lib/base/animations/animation.d.ts

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

constructor(context: CommandExecutionContext, ease?: (x: number) => number);
protected stopped: boolean;
start(): Promise<SModelRootImpl>;
/**
* Stop the animation at the current state.
* The promise returned by start() will be resolved with the current state after the next tweening step.
*/
stop(): void;
/**
* This method called by the animation at each rendering pass until

@@ -30,0 +36,0 @@ * the duration is reached. Implement it to interpolate the state.

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

this.ease = ease;
this.stopped = false;
}
start() {
// in case start() is called multiple times, we need to reset the stopped flag
this.stopped = false;
return new Promise((resolve, reject) => {

@@ -51,2 +54,6 @@ let start = undefined;

}
else if (this.stopped) {
this.context.logger.log(this, 'Animation stopped at ' + (t * 100) + '%');
resolve(current);
}
else {

@@ -65,2 +72,9 @@ this.context.syncer.onNextFrame(lambda);

}
/**
* Stop the animation at the current state.
* The promise returned by start() will be resolved with the current state after the next tweening step.
*/
stop() {
this.stopped = true;
}
}

@@ -67,0 +81,0 @@ exports.Animation = Animation;

15

lib/base/commands/command-stack-options.d.ts

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

********************************************************************************/
import { Container } from "inversify";
import { Container, interfaces } from 'inversify';
/**

@@ -35,3 +35,16 @@ * Options for the command execution

}
export declare const defaultCommandStackOptions: () => CommandStackOptions;
/**
* Utility function to partially set command stack options. Default values (from `defaultViewerOptions`) are used for
* options that are not specified.
*/
export declare function configureCommandStackOptions(context: {
bind: interfaces.Bind;
isBound: interfaces.IsBound;
rebind: interfaces.Rebind;
}, options: Partial<CommandStackOptions>): void;
/**
* Utility function to partially override the currently configured command stack options in a DI container.
*/
export declare function overrideCommandStackOptions(container: Container, options: Partial<CommandStackOptions>): CommandStackOptions;
//# sourceMappingURL=command-stack-options.d.ts.map

@@ -18,5 +18,27 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.overrideCommandStackOptions = void 0;
exports.overrideCommandStackOptions = exports.configureCommandStackOptions = exports.defaultCommandStackOptions = void 0;
const object_1 = require("sprotty-protocol/lib/utils/object");
const types_1 = require("../types");
const defaultCommandStackOptions = () => ({
defaultDuration: 250,
undoHistoryLimit: 50
});
exports.defaultCommandStackOptions = defaultCommandStackOptions;
/**
* Utility function to partially set command stack options. Default values (from `defaultViewerOptions`) are used for
* options that are not specified.
*/
function configureCommandStackOptions(context, options) {
const opt = Object.assign(Object.assign({}, (0, exports.defaultCommandStackOptions)()), options);
if (context.isBound(types_1.TYPES.CommandStackOptions)) {
context.rebind(types_1.TYPES.CommandStackOptions).toConstantValue(opt);
}
else {
context.bind(types_1.TYPES.CommandStackOptions).toConstantValue(opt);
}
}
exports.configureCommandStackOptions = configureCommandStackOptions;
/**
* Utility function to partially override the currently configured command stack options in a DI container.
*/
function overrideCommandStackOptions(container, options) {

@@ -23,0 +45,0 @@ const defaultOptions = container.get(types_1.TYPES.CommandStackOptions);

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

import { CommandStackOptions } from './command-stack-options';
import { ICommand, CommandExecutionContext, CommandReturn, CommandResult } from './command';
import { ICommand, CommandExecutionContext, CommandReturn, CommandResult, IStoppableCommand } from './command';
/**

@@ -105,2 +105,6 @@ * The component that holds the current model and applies the commands

/**
* Map which holds the last stoppable command for certain action kinds.
*/
protected stoppableCommands: Map<string, IStoppableCommand>;
/**
* System commands should be transparent to the user in undo/redo

@@ -107,0 +111,0 @@ * operations. When a system command is executed when the redo

@@ -65,2 +65,6 @@ "use strict";

/**
* Map which holds the last stoppable command for certain action kinds.
*/
this.stoppableCommands = new Map();
/**
* System commands should be transparent to the user in undo/redo

@@ -144,2 +148,11 @@ * operations. When a system command is executed when the redo

handleCommand(command, operation, beforeResolve) {
// If the command implements the IStoppableCommand interface, we first need to stop the execution of the
// previous command with the same action kind and then store the new command as the last stoppable command.
if ((0, command_1.isStoppableCommand)(command)) {
const stoppableCommand = this.stoppableCommands.get(command.stoppableCommandKey);
if (stoppableCommand) {
stoppableCommand.stopExecution();
}
this.stoppableCommands.set(command.stoppableCommandKey, command);
}
this.currentPromise = this.currentPromise.then(state => new Promise(resolve => {

@@ -146,0 +159,0 @@ let target;

@@ -49,2 +49,10 @@ /********************************************************************************

/**
* A stoppable commands execution (e.g. one that starts an animation) can be interrupted.
*/
export interface IStoppableCommand extends ICommand {
stopExecution(): void;
stoppableCommandKey: string;
}
export declare function isStoppableCommand(command: any): command is IStoppableCommand;
/**
* Commands return the changed model or a Promise for it. Promises

@@ -51,0 +59,0 @@ * serve animating commands to render some intermediate states before

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

Object.defineProperty(exports, "__esModule", { value: true });
exports.ResetCommand = exports.SystemCommand = exports.PopupCommand = exports.HiddenCommand = exports.MergeableCommand = exports.Command = void 0;
exports.ResetCommand = exports.SystemCommand = exports.PopupCommand = exports.HiddenCommand = exports.MergeableCommand = exports.Command = exports.isStoppableCommand = void 0;
require("reflect-metadata");
const inversify_1 = require("inversify");
const sprotty_protocol_1 = require("sprotty-protocol");
function isStoppableCommand(command) {
return command && (0, sprotty_protocol_1.hasOwnProperty)(command, 'stoppableCommandKey') && 'stopExecution' in command && typeof command.stopExecution === 'function';
}
exports.isStoppableCommand = isStoppableCommand;
/**

@@ -29,0 +34,0 @@ * Base class for all commands.

6

lib/base/di.config.js

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

const command_stack_1 = require("./commands/command-stack");
const command_stack_options_1 = require("./commands/command-stack-options");
const smodel_factory_1 = require("./model/smodel-factory");

@@ -80,6 +81,3 @@ const animation_frame_syncer_1 = require("./animations/animation-frame-syncer");

});
bind(types_1.TYPES.CommandStackOptions).toConstantValue({
defaultDuration: 250,
undoHistoryLimit: 50
});
bind(types_1.TYPES.CommandStackOptions).toConstantValue((0, command_stack_options_1.defaultCommandStackOptions)());
// Viewer ---------------------------------------------

@@ -86,0 +84,0 @@ bind(viewer_1.ModelViewer).toSelf().inSingletonScope();

/********************************************************************************
* Copyright (c) 2017-2018 TypeFox and others.
* Copyright (c) 2017-2024 TypeFox and others.
*

@@ -58,2 +58,3 @@ * This program and the accompanying materials are made available under the

features?: CustomFeatures;
isOverride?: boolean;
}

@@ -60,0 +61,0 @@ export interface SModelElementConstructor {

"use strict";
/********************************************************************************
* Copyright (c) 2017-2018 TypeFox and others.
* Copyright (c) 2017-2024 TypeFox and others.
*

@@ -47,10 +47,24 @@ * This program and the accompanying materials are made available under the

const featureSet = createFeatureSet(defaultFeatures, registration.features);
this.register(registration.type, () => {
const element = new registration.constr();
element.features = featureSet;
return element;
});
if (registration.isOverride) {
this.override(registration.type, () => {
const element = new registration.constr();
element.features = featureSet;
return element;
});
}
else {
this.register(registration.type, () => {
const element = new registration.constr();
element.features = featureSet;
return element;
});
}
}
else {
this.register(registration.type, () => new registration.constr());
if (registration.isOverride) {
this.override(registration.type, () => new registration.constr());
}
else {
this.register(registration.type, () => new registration.constr());
}
}

@@ -57,0 +71,0 @@ });

/********************************************************************************
* Copyright (c) 2017-2018 TypeFox and others.
* Copyright (c) 2017-2024 TypeFox and others.
*

@@ -26,3 +26,3 @@ * This program and the accompanying materials are made available under the

isBound: interfaces.IsBound;
}, type: string, constr: new () => SModelElementImpl, features?: CustomFeatures): void;
}, type: string, constr: new () => SModelElementImpl, features?: CustomFeatures, isOverride?: boolean): void;
/**

@@ -29,0 +29,0 @@ * Find a parent element that satisfies the given predicate.

"use strict";
/********************************************************************************
* Copyright (c) 2017-2018 TypeFox and others.
* Copyright (c) 2017-2024 TypeFox and others.
*

@@ -24,5 +24,5 @@ * This program and the accompanying materials are made available under the

*/
function registerModelElement(context, type, constr, features) {
function registerModelElement(context, type, constr, features, isOverride) {
context.bind(types_1.TYPES.SModelElementRegistration).toConstantValue({
type, constr, features
type, constr, features, isOverride
});

@@ -29,0 +29,0 @@ }

/********************************************************************************
* Copyright (c) 2017-2018 TypeFox and others.
* Copyright (c) 2017-2024 TypeFox and others.
*

@@ -68,2 +68,3 @@ * This program and the accompanying materials are made available under the

factory: () => IView;
isOverride?: boolean;
}

@@ -87,2 +88,6 @@ export type ViewRegistrationFactory = () => ViewRegistration;

}, type: string, modelConstr: new () => SModelElementImpl, viewConstr: interfaces.ServiceIdentifier<IView>, features?: CustomFeatures): void;
export declare function overrideModelElement(context: {
bind: interfaces.Bind;
isBound: interfaces.IsBound;
}, type: string, modelConstr: new () => SModelElementImpl, viewConstr: interfaces.ServiceIdentifier<IView>, features?: CustomFeatures): void;
/**

@@ -94,3 +99,3 @@ * Utility function to register a view for a model element type.

isBound: interfaces.IsBound;
}, type: string, constr: interfaces.ServiceIdentifier<IView>): void;
}, type: string, constr: interfaces.ServiceIdentifier<IView>, isOverride?: boolean): void;
/**

@@ -97,0 +102,0 @@ * This view is used when the model is the EMPTY_ROOT.

"use strict";
/********************************************************************************
* Copyright (c) 2017-2018 TypeFox and others.
* Copyright (c) 2017-2024 TypeFox and others.
*

@@ -31,3 +31,3 @@ * This program and the accompanying materials are made available under the

Object.defineProperty(exports, "__esModule", { value: true });
exports.MissingView = exports.EmptyView = exports.configureView = exports.configureModelElement = exports.ViewRegistry = exports.findArgValue = void 0;
exports.MissingView = exports.EmptyView = exports.configureView = exports.overrideModelElement = exports.configureModelElement = exports.ViewRegistry = exports.findArgValue = void 0;
/** @jsx svg */

@@ -64,3 +64,10 @@ const jsx_1 = require("../../lib/jsx");

this.registerDefaults();
registrations.forEach(registration => this.register(registration.type, registration.factory()));
registrations.forEach(registration => {
if (registration.isOverride) {
this.override(registration.type, registration.factory());
}
else {
this.register(registration.type, registration.factory());
}
});
}

@@ -94,6 +101,11 @@ registerDefaults() {

exports.configureModelElement = configureModelElement;
function overrideModelElement(context, type, modelConstr, viewConstr, features) {
(0, smodel_utils_1.registerModelElement)(context, type, modelConstr, features, true);
configureView(context, type, viewConstr, true);
}
exports.overrideModelElement = overrideModelElement;
/**
* Utility function to register a view for a model element type.
*/
function configureView(context, type, constr) {
function configureView(context, type, constr, isOverride) {
if (typeof constr === 'function') {

@@ -109,3 +121,4 @@ if (!(0, inversify_2.isInjectable)(constr)) {

type,
factory: () => ctx.container.get(constr)
factory: () => ctx.container.get(constr),
isOverride
}));

@@ -112,0 +125,0 @@ }

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

hiddenClass: string;
/** ID of the HTML element holding the shadow root. */
shadowRoot?: string;
/** ID of the HTML element into which hover popup boxes are rendered. */

@@ -29,0 +31,0 @@ popupDiv: string;

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

const opt = Object.assign(Object.assign({}, (0, exports.defaultViewerOptions)()), options);
if (context.isBound(types_1.TYPES.ViewerOptions))
if (context.isBound(types_1.TYPES.ViewerOptions)) {
context.rebind(types_1.TYPES.ViewerOptions).toConstantValue(opt);
else
}
else {
context.bind(types_1.TYPES.ViewerOptions).toConstantValue(opt);
}
}

@@ -50,0 +52,0 @@ exports.configureViewerOptions = configureViewerOptions;

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

update(model, cause) {
var _a;
this.logger.log(this, 'rendering', model);

@@ -115,3 +116,12 @@ const newVDOM = (0, jsx_1.html)("div", { id: this.options.baseDiv }, this.renderer.renderElement(model));

else if (typeof document !== 'undefined') {
const placeholder = document.getElementById(this.options.baseDiv);
let placeholder = null;
if (this.options.shadowRoot) {
const shadowRoot = (_a = document.getElementById(this.options.shadowRoot)) === null || _a === void 0 ? void 0 : _a.shadowRoot;
if (shadowRoot) {
placeholder = shadowRoot.getElementById(this.options.baseDiv);
}
}
else {
placeholder = document.getElementById(this.options.baseDiv);
}
if (placeholder !== null) {

@@ -118,0 +128,0 @@ if (typeof window !== 'undefined') {

/********************************************************************************
* Copyright (c) 2017-2018 TypeFox and others.
* Copyright (c) 2017-2024 TypeFox and others.
*

@@ -20,4 +20,5 @@ * This program and the accompanying materials are made available under the

import { ILayout, StatefulLayouter } from './layout';
import { AbstractLayoutOptions, HAlignment, VAlignment } from './layout-options';
import { AbstractLayoutOptions } from './layout-options';
import { BoundsData } from './hidden-bounds-updater';
import { HAlignment, VAlignment } from 'sprotty-protocol/lib/model';
export declare abstract class AbstractLayout<T extends AbstractLayoutOptions> implements ILayout {

@@ -24,0 +25,0 @@ layout(container: SParentElementImpl & InternalLayoutContainer, layouter: StatefulLayouter): void;

"use strict";
/********************************************************************************
* Copyright (c) 2017-2018 TypeFox and others.
* Copyright (c) 2017-2024 TypeFox and others.
*

@@ -5,0 +5,0 @@ * This program and the accompanying materials are made available under the

/********************************************************************************
* Copyright (c) 2017-2018 TypeFox and others.
* Copyright (c) 2017-2024 TypeFox and others.
*

@@ -19,6 +19,7 @@ * This program and the accompanying materials are made available under the

import { AbstractLayout } from './abstract-layout';
import { AbstractLayoutOptions, VAlignment } from './layout-options';
import { AbstractLayoutOptions } from './layout-options';
import { BoundsData } from './hidden-bounds-updater';
import { InternalLayoutContainer } from './model';
import { StatefulLayouter } from './layout';
import { VAlignment } from 'sprotty-protocol/lib/model';
export interface HBoxLayoutOptions extends AbstractLayoutOptions {

@@ -25,0 +26,0 @@ hGap: number;

"use strict";
/********************************************************************************
* Copyright (c) 2017-2018 TypeFox and others.
* Copyright (c) 2017-2024 TypeFox and others.
*

@@ -5,0 +5,0 @@ * This program and the accompanying materials are made available under the

/********************************************************************************
* Copyright (c) 2017-2018 TypeFox and others.
* Copyright (c) 2017-2024 TypeFox and others.
*

@@ -17,3 +17,5 @@ * This program and the accompanying materials are made available under the

import { JsonMap } from 'sprotty-protocol/lib/utils/json';
/** @deprecated Use HAlignment from `sprotty-protocol` instead */
export type HAlignment = 'left' | 'center' | 'right';
/** @deprecated Use VAlignment from `sprotty-protocol` instead */
export type VAlignment = 'top' | 'center' | 'bottom';

@@ -20,0 +22,0 @@ export interface AbstractLayoutOptions extends JsonMap {

"use strict";
/********************************************************************************
* Copyright (c) 2017-2018 TypeFox and others.
* Copyright (c) 2017-2024 TypeFox and others.
*

@@ -5,0 +5,0 @@ * This program and the accompanying materials are made available under the

/********************************************************************************
* Copyright (c) 2017-2018 TypeFox and others.
* Copyright (c) 2017-2024 TypeFox and others.
*

@@ -19,6 +19,7 @@ * This program and the accompanying materials are made available under the

import { AbstractLayout } from './abstract-layout';
import { AbstractLayoutOptions, HAlignment, VAlignment } from './layout-options';
import { AbstractLayoutOptions } from './layout-options';
import { BoundsData } from './hidden-bounds-updater';
import { InternalLayoutContainer } from './model';
import { StatefulLayouter } from './layout';
import { VAlignment, HAlignment } from 'sprotty-protocol/lib/model';
export interface StackLayoutOptions extends AbstractLayoutOptions {

@@ -25,0 +26,0 @@ paddingFactor: number;

"use strict";
/********************************************************************************
* Copyright (c) 2017-2018 TypeFox and others.
* Copyright (c) 2017-2024 TypeFox and others.
*

@@ -5,0 +5,0 @@ * This program and the accompanying materials are made available under the

/********************************************************************************
* Copyright (c) 2017-2018 TypeFox and others.
* Copyright (c) 2017-2024 TypeFox and others.
*

@@ -19,6 +19,7 @@ * This program and the accompanying materials are made available under the

import { AbstractLayout } from './abstract-layout';
import { AbstractLayoutOptions, HAlignment } from './layout-options';
import { AbstractLayoutOptions } from './layout-options';
import { BoundsData } from './hidden-bounds-updater';
import { InternalLayoutContainer } from './model';
import { StatefulLayouter } from './layout';
import { HAlignment } from 'sprotty-protocol/lib/model';
export interface VBoxLayoutOptions extends AbstractLayoutOptions {

@@ -25,0 +26,0 @@ vGap: number;

"use strict";
/********************************************************************************
* Copyright (c) 2017-2018 TypeFox and others.
* Copyright (c) 2017-2024 TypeFox and others.
*

@@ -5,0 +5,0 @@ * This program and the accompanying materials are made available under the

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

import { Animation } from '../../base/animations/animation';
import { CommandExecutionContext, ICommand, MergeableCommand, CommandReturn } from '../../base/commands/command';
import { CommandExecutionContext, ICommand, MergeableCommand, CommandReturn, IStoppableCommand } from '../../base/commands/command';
import { SChildElementImpl, SModelElementImpl, SModelRootImpl } from '../../base/model/smodel';

@@ -46,3 +46,3 @@ import { MouseListener } from '../../base/views/mouse-tool';

}
export declare class MoveCommand extends MergeableCommand {
export declare class MoveCommand extends MergeableCommand implements IStoppableCommand {
protected readonly action: MoveAction;

@@ -53,3 +53,6 @@ static readonly KIND = "move";

protected edgeMementi: EdgeMemento[];
protected animation: Animation | undefined;
stoppableCommandKey: string;
constructor(action: MoveAction);
stopExecution(): void;
execute(context: CommandExecutionContext): CommandReturn;

@@ -59,2 +62,4 @@ protected resolveHandleMove(handle: SRoutingHandleImpl, edge: SRoutableElementImpl, move: ElementMove): ResolvedHandleMove | undefined;

protected doMove(edge2move: Map<SRoutableElementImpl, ResolvedHandleMove[]>, attachedEdgeShifts: Map<SRoutableElementImpl, Point>): void;
protected isChildOfMovedElements(el: SChildElementImpl): boolean;
protected isAttachedEdge(edge: SRoutableElementImpl): boolean;
protected undoMove(): void;

@@ -61,0 +66,0 @@ undo(context: CommandExecutionContext): Promise<SModelRootImpl>;

@@ -60,3 +60,11 @@ "use strict";

this.edgeMementi = [];
this.stoppableCommandKey = MoveCommand_1.KIND;
}
// stop the execution of the CompoundAnimation started below
stopExecution() {
if (this.animation) {
this.animation.stop();
this.animation = undefined;
}
}
execute(context) {

@@ -87,12 +95,28 @@ const index = context.root.index;

if (this.edgeRouterRegistry) {
index.getAttachedElements(element).forEach(edge => {
if (edge instanceof model_2.SRoutableElementImpl) {
const existingDelta = attachedEdgeShifts.get(edge);
const newDelta = geometry_1.Point.subtract(resolvedMove.toPosition, resolvedMove.fromPosition);
const delta = (existingDelta)
? geometry_1.Point.linear(existingDelta, newDelta, 0.5)
: newDelta;
attachedEdgeShifts.set(edge, delta);
const handleEdges = (el) => {
index.getAttachedElements(el).forEach(edge => {
if (edge instanceof model_2.SRoutableElementImpl && !this.isChildOfMovedElements(edge)) {
const existingDelta = attachedEdgeShifts.get(edge);
const newDelta = geometry_1.Point.subtract(resolvedMove.toPosition, resolvedMove.fromPosition);
const delta = (existingDelta)
? geometry_1.Point.linear(existingDelta, newDelta, 0.5)
: newDelta;
attachedEdgeShifts.set(edge, delta);
}
});
};
const handleEdgesForChildren = (el) => {
if ((0, smodel_1.isParent)(el)) {
el.children.forEach(childEl => {
if (childEl instanceof smodel_1.SModelElementImpl) {
if (childEl instanceof model_2.SConnectableElementImpl) {
handleEdges(childEl);
}
handleEdgesForChildren(childEl);
}
});
}
});
};
handleEdgesForChildren(element);
handleEdges(element);
}

@@ -105,6 +129,6 @@ }

this.undoMove();
return new animation_1.CompoundAnimation(context.root, context, [
return (this.animation = new animation_1.CompoundAnimation(context.root, context, [
new MoveAnimation(context.root, this.resolvedMoves, context, false),
new MorphEdgesAnimation(context.root, this.edgeMementi, context, false)
]).start();
])).start();
}

@@ -152,6 +176,3 @@ return context.root;

const before = router.takeSnapshot(edge);
if (edge.source
&& edge.target
&& this.resolvedMoves.get(edge.source.id)
&& this.resolvedMoves.get(edge.target.id)) {
if (this.isAttachedEdge(edge)) {
// move the entire edge when both source and target are moved

@@ -170,2 +191,25 @@ edge.routingPoints = edge.routingPoints.map(rp => geometry_1.Point.add(rp, delta));

}
isChildOfMovedElements(el) {
const parent = el.parent;
if (Array.from(this.resolvedMoves.values()).map(rm => rm.element.id).includes(parent.id)) {
return true;
}
if (parent instanceof smodel_1.SChildElementImpl) {
return this.isChildOfMovedElements(parent);
}
return false;
}
;
// tests if the edge is attached to the moved element directly or to on of their children
isAttachedEdge(edge) {
const source = edge.source;
const target = edge.target;
const checkMovedElementsAndChildren = (sourceOrTarget) => {
return Boolean(this.resolvedMoves.get(sourceOrTarget.id)) || this.isChildOfMovedElements(sourceOrTarget);
};
return Boolean(source &&
target &&
checkMovedElementsAndChildren(source) &&
checkMovedElementsAndChildren(target));
}
undoMove() {

@@ -172,0 +216,0 @@ this.resolvedMoves.forEach(res => {

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

pointIndex?: number;
isJunction?: boolean;
}

@@ -124,3 +125,3 @@ /**

export interface IEdgeRoutePostprocessor {
apply(routing: EdgeRouting): void;
apply(routing: EdgeRouting, parent: SParentElementImpl): void;
}

@@ -127,0 +128,0 @@ export declare class EdgeRouterRegistry extends InstanceRegistry<IEdgeRouter> {

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

for (const postProcessor of this.postProcessors) {
postProcessor.apply(routing);
postProcessor.apply(routing, parent);
}

@@ -64,0 +64,0 @@ return routing;

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

const model_1 = require("./model");
const geometry_2 = require("../../utils/geometry");
function getZoom(label) {

@@ -76,3 +77,5 @@ let zoom = 1;

}
const zoom = viewport.zoom * zoomFactor;
// 'limitViewport' used by 'SetViewportCommand' will set the zoom to the min max level
// so we need to do this here to to avoid 'jumps' of the diagram based on the viewport.scroll
const zoom = (0, geometry_2.limit)(viewport.zoom * zoomFactor, this.viewerOptions.zoomLimits);
const viewportOffset = this.getViewportOffset(target.root, event);

@@ -79,0 +82,0 @@ const offsetFactor = 1.0 / zoom - 1.0 / viewport.zoom;

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

render(edge: Readonly<SEdgeImpl>, context: RenderingContext, args?: IViewArgs): VNode | undefined;
protected renderJunctionPoints(edge: Readonly<SEdgeImpl>, route: RoutedPoint[], context: RenderingContext, args: IViewArgs | undefined): any;
protected renderLine(edge: SEdgeImpl, segments: Point[], context: RenderingContext, args?: IViewArgs): VNode;

@@ -38,0 +39,0 @@ protected renderAdditionals(edge: SEdgeImpl, segments: Point[], context: RenderingContext): VNode[];

@@ -77,4 +77,18 @@ "use strict";

this.renderAdditionals(edge, route, context),
this.renderJunctionPoints(edge, route, context, args),
context.renderChildren(edge, { route }));
}
renderJunctionPoints(edge, route, context, args) {
const radius = 5;
const junctionPoints = [];
for (let i = 1; i < route.length; i++) {
if (route[i].isJunction) {
junctionPoints.push((0, jsx_1.svg)("circle", { cx: route[i].x, cy: route[i].y, r: radius }));
}
}
if (junctionPoints.length > 0) {
return (0, jsx_1.svg)("g", { "class-sprotty-junction": true }, junctionPoints);
}
return undefined;
}
renderLine(edge, segments, context, args) {

@@ -81,0 +95,0 @@ const firstPoint = segments[0];

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

export * from './features/edge-intersection/sweepline';
export * from './features/edge-junction/junction-finder';
export * from './features/move/model';

@@ -126,2 +127,3 @@ export * from './features/move/move';

import edgeIntersectionModule from './features/edge-intersection/di.config';
import edgeJunctionModule from './features/edge-junction/di.config';
import edgeLayoutModule from './features/edge-layout/di.config';

@@ -140,3 +142,3 @@ import expandModule from './features/expand/di.config';

import zorderModule from './features/zorder/di.config';
export { boundsModule, buttonModule, commandPaletteModule, contextMenuModule, decorationModule, edgeIntersectionModule, edgeLayoutModule, expandModule, exportModule, fadeModule, hoverModule, moveModule, openModule, routingModule, selectModule, undoRedoModule, updateModule, viewportModule, zorderModule };
export { boundsModule, buttonModule, commandPaletteModule, contextMenuModule, decorationModule, edgeIntersectionModule, edgeJunctionModule, edgeLayoutModule, expandModule, exportModule, fadeModule, hoverModule, moveModule, openModule, routingModule, selectModule, undoRedoModule, updateModule, viewportModule, zorderModule };
export * from './graph/sgraph';

@@ -143,0 +145,0 @@ export * from './graph/views';

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

Object.defineProperty(exports, "__esModule", { value: true });
exports.modelSourceModule = exports.zorderModule = exports.viewportModule = exports.updateModule = exports.undoRedoModule = exports.selectModule = exports.routingModule = exports.openModule = exports.moveModule = exports.hoverModule = exports.fadeModule = exports.exportModule = exports.expandModule = exports.edgeLayoutModule = exports.edgeIntersectionModule = exports.decorationModule = exports.contextMenuModule = exports.commandPaletteModule = exports.buttonModule = exports.boundsModule = exports.defaultModule = void 0;
exports.modelSourceModule = exports.zorderModule = exports.viewportModule = exports.updateModule = exports.undoRedoModule = exports.selectModule = exports.routingModule = exports.openModule = exports.moveModule = exports.hoverModule = exports.fadeModule = exports.exportModule = exports.expandModule = exports.edgeLayoutModule = exports.edgeJunctionModule = exports.edgeIntersectionModule = exports.decorationModule = exports.contextMenuModule = exports.commandPaletteModule = exports.buttonModule = exports.boundsModule = exports.defaultModule = void 0;
// ------------------ Base ------------------

@@ -111,2 +111,3 @@ __exportStar(require("./base/actions/action"), exports);

__exportStar(require("./features/edge-intersection/sweepline"), exports);
__exportStar(require("./features/edge-junction/junction-finder"), exports);
__exportStar(require("./features/move/model"), exports);

@@ -155,28 +156,30 @@ __exportStar(require("./features/move/move"), exports);

exports.edgeIntersectionModule = di_config_7.default;
const di_config_8 = __importDefault(require("./features/edge-layout/di.config"));
exports.edgeLayoutModule = di_config_8.default;
const di_config_9 = __importDefault(require("./features/expand/di.config"));
exports.expandModule = di_config_9.default;
const di_config_10 = __importDefault(require("./features/export/di.config"));
exports.exportModule = di_config_10.default;
const di_config_11 = __importDefault(require("./features/fade/di.config"));
exports.fadeModule = di_config_11.default;
const di_config_12 = __importDefault(require("./features/hover/di.config"));
exports.hoverModule = di_config_12.default;
const di_config_13 = __importDefault(require("./features/move/di.config"));
exports.moveModule = di_config_13.default;
const di_config_14 = __importDefault(require("./features/open/di.config"));
exports.openModule = di_config_14.default;
const di_config_15 = __importDefault(require("./features/routing/di.config"));
exports.routingModule = di_config_15.default;
const di_config_16 = __importDefault(require("./features/select/di.config"));
exports.selectModule = di_config_16.default;
const di_config_17 = __importDefault(require("./features/undo-redo/di.config"));
exports.undoRedoModule = di_config_17.default;
const di_config_18 = __importDefault(require("./features/update/di.config"));
exports.updateModule = di_config_18.default;
const di_config_19 = __importDefault(require("./features/viewport/di.config"));
exports.viewportModule = di_config_19.default;
const di_config_20 = __importDefault(require("./features/zorder/di.config"));
exports.zorderModule = di_config_20.default;
const di_config_8 = __importDefault(require("./features/edge-junction/di.config"));
exports.edgeJunctionModule = di_config_8.default;
const di_config_9 = __importDefault(require("./features/edge-layout/di.config"));
exports.edgeLayoutModule = di_config_9.default;
const di_config_10 = __importDefault(require("./features/expand/di.config"));
exports.expandModule = di_config_10.default;
const di_config_11 = __importDefault(require("./features/export/di.config"));
exports.exportModule = di_config_11.default;
const di_config_12 = __importDefault(require("./features/fade/di.config"));
exports.fadeModule = di_config_12.default;
const di_config_13 = __importDefault(require("./features/hover/di.config"));
exports.hoverModule = di_config_13.default;
const di_config_14 = __importDefault(require("./features/move/di.config"));
exports.moveModule = di_config_14.default;
const di_config_15 = __importDefault(require("./features/open/di.config"));
exports.openModule = di_config_15.default;
const di_config_16 = __importDefault(require("./features/routing/di.config"));
exports.routingModule = di_config_16.default;
const di_config_17 = __importDefault(require("./features/select/di.config"));
exports.selectModule = di_config_17.default;
const di_config_18 = __importDefault(require("./features/undo-redo/di.config"));
exports.undoRedoModule = di_config_18.default;
const di_config_19 = __importDefault(require("./features/update/di.config"));
exports.updateModule = di_config_19.default;
const di_config_20 = __importDefault(require("./features/viewport/di.config"));
exports.viewportModule = di_config_20.default;
const di_config_21 = __importDefault(require("./features/zorder/di.config"));
exports.zorderModule = di_config_21.default;
// ------------------ Graph ------------------

@@ -199,4 +202,4 @@ __exportStar(require("./graph/sgraph"), exports);

__exportStar(require("./model-source/websocket"), exports);
const di_config_21 = __importDefault(require("./model-source/di.config"));
exports.modelSourceModule = di_config_21.default;
const di_config_22 = __importDefault(require("./model-source/di.config"));
exports.modelSourceModule = di_config_22.default;
// ------------------ Utilities ------------------

@@ -203,0 +206,0 @@ __exportStar(require("./utils/browser"), exports);

@@ -39,4 +39,11 @@ "use strict";

const idx = key.indexOf('-');
if (idx > 0)
addAttr(key.slice(0, idx), key.slice(idx + 1), source[key]);
if (idx > 0) {
const modname = key.slice(0, idx);
if (modulesNS.includes(modname)) {
addAttr(modname, key.slice(idx + 1), source[key]);
}
else {
addAttr(defNS, key, source[key]);
}
}
else if (!data[key])

@@ -53,3 +60,6 @@ addAttr(defNS, key, source[key]);

function JSX(namespace, defNS = 'props') {
return (tag, attrs, ...children) => (0, snabbdom_1.jsx)(tag, normalizeAttrs(attrs, defNS, namespace), children);
return (tag, attrs, ...children) => {
const isComponent = typeof tag === 'function';
return (0, snabbdom_1.jsx)(tag, (isComponent ? attrs : normalizeAttrs(attrs, defNS, namespace)), children);
};
}

@@ -56,0 +66,0 @@ exports.JSX = JSX;

/********************************************************************************
* Copyright (c) 2017-2018 TypeFox and others.
* Copyright (c) 2017-2024 TypeFox and others.
*

@@ -27,2 +27,3 @@ * This program and the accompanying materials are made available under the

register(key: string, factory: (u: U) => T): void;
override(key: string, factory: (u: U) => T): void;
deregister(key: string): void;

@@ -36,2 +37,3 @@ hasKey(key: string): boolean;

register(key: string, instance: T): void;
override(key: string, instance: T): void;
deregister(key: string): void;

@@ -38,0 +40,0 @@ hasKey(key: string): boolean;

"use strict";
/********************************************************************************
* Copyright (c) 2017-2018 TypeFox and others.
* Copyright (c) 2017-2024 TypeFox and others.
*

@@ -69,6 +69,15 @@ * This program and the accompanying materials are made available under the

if (this.hasKey(key)) {
throw new Error('Key is already registered: ' + key);
throw new Error(`Key is already registered: ${key}. Use \`overrideModelElement\` instead.`);
}
this.elements.set(key, factory);
}
override(key, factory) {
if (key === undefined) {
throw new Error('Key is undefined');
}
else if (!this.hasKey(key)) {
throw new Error(`Key is not registered: ${key}. Use \`configureModelElement\` instead.`);
}
this.elements.set(key, factory);
}
deregister(key) {

@@ -109,6 +118,15 @@ if (key === undefined) {

if (this.hasKey(key)) {
throw new Error('Key is already registered: ' + key);
throw new Error(`Key is already registered: ${key}. Use \`overrideModelElement\` instead.`);
}
this.elements.set(key, instance);
}
override(key, instance) {
if (key === undefined) {
throw new Error('Key is undefined');
}
else if (!this.hasKey(key)) {
throw new Error(`Key is not registered: ${key}. Use \`configureModelElement\` instead.`);
}
this.elements.set(key, instance);
}
deregister(key) {

@@ -115,0 +133,0 @@ if (key === undefined) {

{
"name": "sprotty",
"version": "1.1.1",
"version": "1.2.0",
"description": "A next-gen framework for graphical views",

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

"snabbdom": "~3.5.1",
"sprotty-protocol": "^1.1.0",
"sprotty-protocol": "^1.2.0",
"tinyqueue": "^2.0.3"

@@ -54,3 +54,4 @@ },

"main": "lib/index",
"types": "lib/index"
"types": "lib/index",
"gitHead": "0c679d4bdabcf0d9da8d25a8cc9f650a679b54df"
}

@@ -30,3 +30,7 @@ /********************************************************************************

protected stopped = false;
start(): Promise<SModelRootImpl> {
// in case start() is called multiple times, we need to reset the stopped flag
this.stopped = false;
return new Promise<SModelRootImpl>(

@@ -51,2 +55,5 @@ (resolve: (model: SModelRootImpl) => void, reject: (model: SModelRootImpl) => void) => {

resolve(current);
} else if (this.stopped) {
this.context.logger.log(this, 'Animation stopped at ' + (t * 100) + '%');
resolve(current);
} else {

@@ -66,2 +73,10 @@ this.context.syncer.onNextFrame(lambda);

/**
* Stop the animation at the current state.
* The promise returned by start() will be resolved with the current state after the next tweening step.
*/
stop(): void {
this.stopped = true;
}
/**
* This method called by the animation at each rendering pass until

@@ -68,0 +83,0 @@ * the duration is reached. Implement it to interpolate the state.

@@ -17,4 +17,4 @@ /********************************************************************************

import { Container } from "inversify";
import { safeAssign } from "sprotty-protocol/lib/utils/object";
import { Container, interfaces } from 'inversify';
import { safeAssign } from 'sprotty-protocol/lib/utils/object';
import { TYPES } from '../types';

@@ -41,2 +41,27 @@

export const defaultCommandStackOptions: () => CommandStackOptions = () => ({
defaultDuration: 250,
undoHistoryLimit: 50
});
/**
* Utility function to partially set command stack options. Default values (from `defaultViewerOptions`) are used for
* options that are not specified.
*/
export function configureCommandStackOptions(context: { bind: interfaces.Bind, isBound: interfaces.IsBound, rebind: interfaces.Rebind },
options: Partial<CommandStackOptions>): void {
const opt: CommandStackOptions = {
...defaultCommandStackOptions(),
...options
};
if (context.isBound(TYPES.CommandStackOptions)) {
context.rebind(TYPES.CommandStackOptions).toConstantValue(opt);
} else {
context.bind(TYPES.CommandStackOptions).toConstantValue(opt);
}
}
/**
* Utility function to partially override the currently configured command stack options in a DI container.
*/
export function overrideCommandStackOptions(container: Container, options: Partial<CommandStackOptions>): CommandStackOptions {

@@ -43,0 +68,0 @@ const defaultOptions = container.get<CommandStackOptions>(TYPES.CommandStackOptions);

@@ -28,3 +28,3 @@ /********************************************************************************

HiddenCommand, ICommand, CommandExecutionContext, CommandReturn, SystemCommand,
MergeableCommand, PopupCommand, ResetCommand, CommandResult
MergeableCommand, PopupCommand, ResetCommand, CommandResult, isStoppableCommand, IStoppableCommand
} from './command';

@@ -123,2 +123,7 @@

/**
* Map which holds the last stoppable command for certain action kinds.
*/
protected stoppableCommands: Map<string, IStoppableCommand> = new Map();
/**
* System commands should be transparent to the user in undo/redo

@@ -215,2 +220,12 @@ * operations. When a system command is executed when the redo

beforeResolve: (command: ICommand, context: CommandExecutionContext) => void) {
// If the command implements the IStoppableCommand interface, we first need to stop the execution of the
// previous command with the same action kind and then store the new command as the last stoppable command.
if (isStoppableCommand(command)) {
const stoppableCommand = this.stoppableCommands.get(command.stoppableCommandKey);
if (stoppableCommand) {
stoppableCommand.stopExecution();
}
this.stoppableCommands.set(command.stoppableCommandKey, command);
}
this.currentPromise = this.currentPromise.then(state =>

@@ -217,0 +232,0 @@ new Promise<CommandStackState>(resolve => {

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

import { IViewer } from "../views/viewer";
import { hasOwnProperty } from 'sprotty-protocol';

@@ -57,2 +58,14 @@ /**

/**
* A stoppable commands execution (e.g. one that starts an animation) can be interrupted.
*/
export interface IStoppableCommand extends ICommand {
stopExecution(): void
stoppableCommandKey: string
}
export function isStoppableCommand(command: any): command is IStoppableCommand {
return command && hasOwnProperty(command, 'stoppableCommandKey') && 'stopExecution' in command && typeof command.stopExecution === 'function';
}
/**
* Commands return the changed model or a Promise for it. Promises

@@ -59,0 +72,0 @@ * serve animating commands to render some intermediate states before

@@ -24,3 +24,3 @@ /********************************************************************************

import { CommandStack, ICommandStack } from "./commands/command-stack";
import { CommandStackOptions } from "./commands/command-stack-options";
import { CommandStackOptions, defaultCommandStackOptions } from "./commands/command-stack-options";
import { SModelFactory, SModelRegistry } from './model/smodel-factory';

@@ -86,6 +86,3 @@ import { AnimationFrameSyncer } from "./animations/animation-frame-syncer";

});
bind<CommandStackOptions>(TYPES.CommandStackOptions).toConstantValue({
defaultDuration: 250,
undoHistoryLimit: 50
});
bind<CommandStackOptions>(TYPES.CommandStackOptions).toConstantValue(defaultCommandStackOptions());

@@ -92,0 +89,0 @@ // Viewer ---------------------------------------------

/********************************************************************************
* Copyright (c) 2017-2018 TypeFox and others.
* Copyright (c) 2017-2024 TypeFox and others.
*

@@ -37,9 +37,21 @@ * This program and the accompanying materials are made available under the

const featureSet = createFeatureSet(defaultFeatures, registration.features);
this.register(registration.type, () => {
const element = new registration.constr();
element.features = featureSet;
return element;
});
if (registration.isOverride) {
this.override(registration.type, () => {
const element = new registration.constr();
element.features = featureSet;
return element;
});
} else {
this.register(registration.type, () => {
const element = new registration.constr();
element.features = featureSet;
return element;
});
}
} else {
this.register(registration.type, () => new registration.constr());
if (registration.isOverride) {
this.override(registration.type, () => new registration.constr());
} else {
this.register(registration.type, () => new registration.constr());
}
}

@@ -181,2 +193,3 @@ });

features?: CustomFeatures
isOverride?: boolean
}

@@ -183,0 +196,0 @@

/********************************************************************************
* Copyright (c) 2017-2018 TypeFox and others.
* Copyright (c) 2017-2024 TypeFox and others.
*

@@ -27,5 +27,5 @@ * This program and the accompanying materials are made available under the

export function registerModelElement(context: { bind: interfaces.Bind, isBound: interfaces.IsBound },
type: string, constr: new () => SModelElementImpl, features?: CustomFeatures): void {
type: string, constr: new () => SModelElementImpl, features?: CustomFeatures, isOverride?: boolean): void {
context.bind<SModelElementRegistration>(TYPES.SModelElementRegistration).toConstantValue({
type, constr, features
type, constr, features, isOverride
});

@@ -32,0 +32,0 @@ }

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

hiddenClass: string
/** ID of the HTML element holding the shadow root. */
shadowRoot?: string
/** ID of the HTML element into which hover popup boxes are rendered. */

@@ -81,6 +83,7 @@ popupDiv: string

};
if (context.isBound(TYPES.ViewerOptions))
if (context.isBound(TYPES.ViewerOptions)) {
context.rebind(TYPES.ViewerOptions).toConstantValue(opt);
else
} else {
context.bind(TYPES.ViewerOptions).toConstantValue(opt);
}
}

@@ -87,0 +90,0 @@

/********************************************************************************
* Copyright (c) 2017-2018 TypeFox and others.
* Copyright (c) 2017-2024 TypeFox and others.
*

@@ -21,5 +21,6 @@ * This program and the accompanying materials are made available under the

import { ILayout, StatefulLayouter } from './layout';
import { AbstractLayoutOptions, HAlignment, VAlignment } from './layout-options';
import { AbstractLayoutOptions } from './layout-options';
import { BoundsData } from './hidden-bounds-updater';
import { injectable } from 'inversify';
import { HAlignment, VAlignment } from 'sprotty-protocol/lib/model';

@@ -26,0 +27,0 @@ @injectable()

/********************************************************************************
* Copyright (c) 2017-2018 TypeFox and others.
* Copyright (c) 2017-2024 TypeFox and others.
*

@@ -21,6 +21,7 @@ * This program and the accompanying materials are made available under the

import { AbstractLayout } from './abstract-layout';
import { AbstractLayoutOptions, VAlignment } from './layout-options';
import { AbstractLayoutOptions } from './layout-options';
import { BoundsData } from './hidden-bounds-updater';
import { InternalLayoutContainer, isLayoutableChild } from './model';
import { StatefulLayouter } from './layout';
import { VAlignment } from 'sprotty-protocol/lib/model';

@@ -27,0 +28,0 @@ export interface HBoxLayoutOptions extends AbstractLayoutOptions {

/********************************************************************************
* Copyright (c) 2017-2018 TypeFox and others.
* Copyright (c) 2017-2024 TypeFox and others.
*

@@ -19,4 +19,6 @@ * This program and the accompanying materials are made available under the

/** @deprecated Use HAlignment from `sprotty-protocol` instead */
export type HAlignment = 'left' | 'center' | 'right';
/** @deprecated Use VAlignment from `sprotty-protocol` instead */
export type VAlignment = 'top' | 'center' | 'bottom';

@@ -23,0 +25,0 @@

/********************************************************************************
* Copyright (c) 2017-2018 TypeFox and others.
* Copyright (c) 2017-2024 TypeFox and others.
*

@@ -21,6 +21,7 @@ * This program and the accompanying materials are made available under the

import { AbstractLayout } from './abstract-layout';
import { AbstractLayoutOptions, HAlignment, VAlignment } from './layout-options';
import { AbstractLayoutOptions } from './layout-options';
import { BoundsData } from './hidden-bounds-updater';
import { InternalLayoutContainer, isLayoutableChild } from './model';
import { StatefulLayouter } from './layout';
import { VAlignment, HAlignment } from 'sprotty-protocol/lib/model';

@@ -27,0 +28,0 @@ export interface StackLayoutOptions extends AbstractLayoutOptions {

/********************************************************************************
* Copyright (c) 2017-2018 TypeFox and others.
* Copyright (c) 2017-2024 TypeFox and others.
*

@@ -21,6 +21,7 @@ * This program and the accompanying materials are made available under the

import { AbstractLayout } from './abstract-layout';
import { AbstractLayoutOptions, HAlignment } from './layout-options';
import { AbstractLayoutOptions } from './layout-options';
import { BoundsData } from './hidden-bounds-updater';
import { InternalLayoutContainer, isLayoutableChild } from './model';
import { StatefulLayouter } from './layout';
import { HAlignment } from 'sprotty-protocol/lib/model';

@@ -27,0 +28,0 @@ export interface VBoxLayoutOptions extends AbstractLayoutOptions {

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

import { Animation, CompoundAnimation } from '../../base/animations/animation';
import { CommandExecutionContext, ICommand, MergeableCommand, CommandReturn } from '../../base/commands/command';
import { SChildElementImpl, SModelElementImpl, SModelRootImpl } from '../../base/model/smodel';
import { CommandExecutionContext, ICommand, MergeableCommand, CommandReturn, IStoppableCommand } from '../../base/commands/command';
import { SChildElementImpl, SModelElementImpl, SModelRootImpl, isParent } from '../../base/model/smodel';
import { findParentByFeature, translatePoint } from '../../base/model/smodel-utils';

@@ -37,3 +37,3 @@ import { TYPES } from '../../base/types';

import { ReconnectCommand } from '../edit/reconnect';
import { edgeInProgressID, edgeInProgressTargetHandleID, isConnectable, SRoutableElementImpl, SRoutingHandleImpl } from '../routing/model';
import { edgeInProgressID, edgeInProgressTargetHandleID, isConnectable, SConnectableElementImpl, SRoutableElementImpl, SRoutingHandleImpl } from '../routing/model';
import { EdgeMemento, EdgeRouterRegistry, EdgeSnapshot, RoutedPoint } from '../routing/routing';

@@ -66,3 +66,3 @@ import { isEdgeLayoutable } from '../edge-layout/model';

@injectable()
export class MoveCommand extends MergeableCommand {
export class MoveCommand extends MergeableCommand implements IStoppableCommand {
static readonly KIND = MoveAction.KIND;

@@ -74,7 +74,20 @@

protected edgeMementi: EdgeMemento[] = [];
protected animation: Animation | undefined;
stoppableCommandKey: string;
constructor(@inject(TYPES.Action) protected readonly action: MoveAction) {
super();
this.stoppableCommandKey = MoveCommand.KIND;
}
// stop the execution of the CompoundAnimation started below
stopExecution(): void {
if (this.animation) {
this.animation.stop();
this.animation = undefined;
}
}
execute(context: CommandExecutionContext): CommandReturn {

@@ -104,12 +117,28 @@ const index = context.root.index;

if (this.edgeRouterRegistry) {
index.getAttachedElements(element).forEach(edge => {
if (edge instanceof SRoutableElementImpl) {
const existingDelta = attachedEdgeShifts.get(edge);
const newDelta = Point.subtract(resolvedMove.toPosition, resolvedMove.fromPosition);
const delta = (existingDelta)
? Point.linear(existingDelta, newDelta, 0.5)
: newDelta;
attachedEdgeShifts.set(edge, delta);
const handleEdges = (el: SModelElementImpl) => {
index.getAttachedElements(el).forEach(edge => {
if (edge instanceof SRoutableElementImpl && !this.isChildOfMovedElements(edge as SRoutableElementImpl)) {
const existingDelta = attachedEdgeShifts.get(edge);
const newDelta = Point.subtract(resolvedMove.toPosition, resolvedMove.fromPosition);
const delta = (existingDelta)
? Point.linear(existingDelta, newDelta, 0.5)
: newDelta;
attachedEdgeShifts.set(edge, delta);
}
});
};
const handleEdgesForChildren = (el: SModelElementImpl) => {
if (isParent(el)) {
el.children.forEach(childEl => {
if (childEl instanceof SModelElementImpl) {
if (childEl instanceof SConnectableElementImpl) {
handleEdges(childEl);
}
handleEdgesForChildren(childEl);
}
});
}
});
};
handleEdgesForChildren(element);
handleEdges(element);
}

@@ -122,6 +151,6 @@ }

this.undoMove();
return new CompoundAnimation(context.root, context, [
return (this.animation = new CompoundAnimation(context.root, context, [
new MoveAnimation(context.root, this.resolvedMoves, context, false),
new MorphEdgesAnimation(context.root, this.edgeMementi, context, false)
]).start();
])).start();
}

@@ -172,6 +201,3 @@ return context.root;

const before = router.takeSnapshot(edge);
if (edge.source
&& edge.target
&& this.resolvedMoves.get(edge.source.id)
&& this.resolvedMoves.get(edge.target.id)) {
if (this.isAttachedEdge(edge)) {
// move the entire edge when both source and target are moved

@@ -190,2 +216,29 @@ edge.routingPoints = edge.routingPoints.map(rp => Point.add(rp, delta));

protected isChildOfMovedElements(el: SChildElementImpl): boolean {
const parent = el.parent;
if (Array.from(this.resolvedMoves.values()).map(rm => rm.element.id).includes(parent.id)) {
return true;
}
if (parent instanceof SChildElementImpl) {
return this.isChildOfMovedElements(parent);
}
return false;
};
// tests if the edge is attached to the moved element directly or to on of their children
protected isAttachedEdge(edge: SRoutableElementImpl): boolean {
const source = edge.source;
const target = edge.target;
const checkMovedElementsAndChildren = (sourceOrTarget: SConnectableElementImpl): boolean => {
return Boolean(this.resolvedMoves.get(sourceOrTarget.id)) || this.isChildOfMovedElements(sourceOrTarget);
};
return Boolean(
source &&
target &&
checkMovedElementsAndChildren(source) &&
checkMovedElementsAndChildren(target)
);
}
protected undoMove() {

@@ -192,0 +245,0 @@ this.resolvedMoves.forEach(res => {

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

pointIndex?: number
isJunction?: boolean
}

@@ -151,3 +152,3 @@

export interface IEdgeRoutePostprocessor {
apply(routing: EdgeRouting): void;
apply(routing: EdgeRouting, parent: SParentElementImpl): void;
}

@@ -183,3 +184,3 @@

for (const postProcessor of this.postProcessors) {
postProcessor.apply(routing);
postProcessor.apply(routing, parent);
}

@@ -186,0 +187,0 @@ return routing;

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

import { isViewport } from './model';
import { limit } from '../../utils/geometry';

@@ -75,3 +76,6 @@ export function getZoom(label: SModelElementImpl) {

}
const zoom = viewport.zoom * zoomFactor;
// 'limitViewport' used by 'SetViewportCommand' will set the zoom to the min max level
// so we need to do this here to to avoid 'jumps' of the diagram based on the viewport.scroll
const zoom = limit(viewport.zoom * zoomFactor, this.viewerOptions.zoomLimits);
const viewportOffset = this.getViewportOffset(target.root, event);

@@ -78,0 +82,0 @@ const offsetFactor = 1.0 / zoom - 1.0 / viewport.zoom;

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

export * from './features/edge-junction/junction-finder';
export * from './features/move/model';

@@ -163,2 +165,3 @@ export * from './features/move/move';

import edgeIntersectionModule from './features/edge-intersection/di.config';
import edgeJunctionModule from './features/edge-junction/di.config';
import edgeLayoutModule from './features/edge-layout/di.config';

@@ -180,3 +183,3 @@ import expandModule from './features/expand/di.config';

boundsModule, buttonModule, commandPaletteModule, contextMenuModule, decorationModule,
edgeIntersectionModule, edgeLayoutModule, expandModule, exportModule, fadeModule, hoverModule, moveModule,
edgeIntersectionModule, edgeJunctionModule, edgeLayoutModule, expandModule, exportModule, fadeModule, hoverModule, moveModule,
openModule, routingModule, selectModule, undoRedoModule, updateModule, viewportModule, zorderModule

@@ -183,0 +186,0 @@ };

@@ -51,5 +51,10 @@ /********************************************************************************

const idx = key.indexOf('-');
if (idx > 0)
addAttr(key.slice(0, idx), key.slice(idx + 1), source[key]);
else if (!data[key])
if (idx > 0) {
const modname = key.slice(0, idx);
if (modulesNS.includes(modname)) {
addAttr(modname, key.slice(idx + 1), source[key]);
} else {
addAttr(defNS, key, source[key]);
}
} else if (!data[key])
addAttr(defNS, key, source[key]);

@@ -67,3 +72,6 @@ });

function JSX(namespace?: string, defNS: string = 'props') {
return (tag: FunctionComponent | string, attrs: VNodeData | null, ...children: JsxVNodeChild[]) => jsx(tag, normalizeAttrs(attrs, defNS, namespace), children);
return (tag: FunctionComponent | string, attrs: VNodeData | null, ...children: JsxVNodeChild[]) => {
const isComponent = typeof tag === 'function';
return jsx(tag, (isComponent ? attrs : normalizeAttrs(attrs, defNS, namespace)), children);
};
}

@@ -70,0 +78,0 @@

/********************************************************************************
* Copyright (c) 2017-2018 TypeFox and others.
* Copyright (c) 2017-2024 TypeFox and others.
*

@@ -63,3 +63,3 @@ * This program and the accompanying materials are made available under the

if (this.hasKey(key)) {
throw new Error('Key is already registered: ' + key);
throw new Error(`Key is already registered: ${key}. Use \`overrideModelElement\` instead.`);
}

@@ -69,2 +69,11 @@ this.elements.set(key, factory);

override(key: string, factory: (u: U) => T) {
if (key === undefined) {
throw new Error('Key is undefined');
} else if (!this.hasKey(key)) {
throw new Error(`Key is not registered: ${key}. Use \`configureModelElement\` instead.`);
}
this.elements.set(key, factory);
}
deregister(key: string) {

@@ -104,3 +113,3 @@ if (key === undefined) {

if (this.hasKey(key)) {
throw new Error('Key is already registered: ' + key);
throw new Error(`Key is already registered: ${key}. Use \`overrideModelElement\` instead.`);
}

@@ -110,2 +119,11 @@ this.elements.set(key, instance);

override(key: string, instance: T) {
if (key === undefined) {
throw new Error('Key is undefined');
} else if (!this.hasKey(key)) {
throw new Error(`Key is not registered: ${key}. Use \`configureModelElement\` instead.`);
}
this.elements.set(key, instance);
}
deregister(key: string) {

@@ -112,0 +130,0 @@ if (key === undefined) {

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

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc