Skip to content

Commit

Permalink
Ensure we do not return an invalid anchor point during edge routing (#…
Browse files Browse the repository at this point in the history
…325)

* Ensure we do not return an invalid anchor point during edge routing

Fixes eclipse-glsp/glsp#1270
  • Loading branch information
martin-fleck-at committed Mar 10, 2024
1 parent 1f803d1 commit c4764a5
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 4 deletions.
1 change: 1 addition & 0 deletions packages/glsp-sprotty/src/index.ts
Expand Up @@ -16,4 +16,5 @@
export * from './action-override';
export * from './feature-modules';
export * from './re-exports';
export * from './routing-override';
export * from './types';
22 changes: 18 additions & 4 deletions packages/glsp-sprotty/src/re-exports.ts
Expand Up @@ -192,12 +192,26 @@ export * from 'sprotty/lib/features/open/open';
export * from 'sprotty/lib/features/projection/model';
export * from 'sprotty/lib/features/projection/views';

export * from 'sprotty/lib/features/routing/abstract-edge-router';
export {
DefaultAnchors,
LinearRouteOptions,
Side,
AbstractEdgeRouter as SprottyAbstractEdgeRouter
} from 'sprotty/lib/features/routing/abstract-edge-router';
export * from 'sprotty/lib/features/routing/anchor';
export * from 'sprotty/lib/features/routing/bezier-anchors';
export * from 'sprotty/lib/features/routing/bezier-edge-router';
export {
AddRemoveBezierSegmentAction,
AddRemoveBezierSegmentCommand,
BezierMouseListener,
BezierEdgeRouter as SprottyBezierEdgeRouter
} from 'sprotty/lib/features/routing/bezier-edge-router';
export * from 'sprotty/lib/features/routing/manhattan-anchors';
export * from 'sprotty/lib/features/routing/manhattan-edge-router';
export {
ManhattanRouterOptions,
ManhattanEdgeRouter as SprottyManhattanEdgeRouter
} from 'sprotty/lib/features/routing/manhattan-edge-router';

// Alias SModel types
export {
Connectable,
Expand All @@ -214,7 +228,7 @@ export {
isConnectable
} from 'sprotty/lib/features/routing/model';
export * from 'sprotty/lib/features/routing/polyline-anchors';
export * from 'sprotty/lib/features/routing/polyline-edge-router';
export { PolylineRouteOptions, PolylineEdgeRouter as SprottyPolylineEdgeRouter } from 'sprotty/lib/features/routing/polyline-edge-router';
export * from 'sprotty/lib/features/routing/routing';
export * from 'sprotty/lib/features/routing/views';

Expand Down
88 changes: 88 additions & 0 deletions packages/glsp-sprotty/src/routing-override.ts
@@ -0,0 +1,88 @@
/********************************************************************************
* Copyright (c) 2024 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 { Point } from '@eclipse-glsp/protocol';
import { injectable } from 'inversify';
import {
SConnectableElementImpl,
SParentElementImpl,
SRoutableElementImpl,
AbstractEdgeRouter as SprottyAbstractEdgeRouter,
BezierEdgeRouter as SprottyBezierEdgeRouter,
ManhattanEdgeRouter as SprottyManhattanEdgeRouter,
PolylineEdgeRouter as SprottyPolylineEdgeRouter
} from 'sprotty';
import { GConnectableElement, GParentElement, GRoutableElement } from './re-exports';

@injectable()
export abstract class AbstractEdgeRouter extends SprottyAbstractEdgeRouter {
override getTranslatedAnchor(
connectable: SConnectableElementImpl,
refPoint: Point,
refContainer: SParentElementImpl,
edge: SRoutableElementImpl,
anchorCorrection?: number | undefined
): Point {
// users may define all kinds of anchors and anchor computers, we want to make sure we return a valid one in any case
const anchor = super.getTranslatedAnchor(connectable, refPoint, refContainer, edge, anchorCorrection);
return Point.isValid(anchor) ? anchor : refPoint;
}
}

@injectable()
export class PolylineEdgeRouter extends SprottyPolylineEdgeRouter {
override getTranslatedAnchor(
connectable: GConnectableElement,
refPoint: Point,
refContainer: GParentElement,
edge: GRoutableElement,
anchorCorrection?: number | undefined
): Point {
// users may define all kinds of anchors and anchor computers, we want to make sure we return a valid one in any case
const anchor = super.getTranslatedAnchor(connectable, refPoint, refContainer, edge, anchorCorrection);
return Point.isValid(anchor) ? anchor : refPoint;
}
}

@injectable()
export class ManhattanEdgeRouter extends SprottyManhattanEdgeRouter {
override getTranslatedAnchor(
connectable: GConnectableElement,
refPoint: Point,
refContainer: GParentElement,
edge: GRoutableElement,
anchorCorrection?: number | undefined
): Point {
// users may define all kinds of anchors and anchor computers, we want to make sure we return a valid one in any case
const anchor = super.getTranslatedAnchor(connectable, refPoint, refContainer, edge, anchorCorrection);
return Point.isValid(anchor) ? anchor : refPoint;
}
}

@injectable()
export class BezierEdgeRouter extends SprottyBezierEdgeRouter {
override getTranslatedAnchor(
connectable: GConnectableElement,
refPoint: Point,
refContainer: GParentElement,
edge: GRoutableElement,
anchorCorrection?: number | undefined
): Point {
// users may define all kinds of anchors and anchor computers, we want to make sure we return a valid one in any case
const anchor = super.getTranslatedAnchor(connectable, refPoint, refContainer, edge, anchorCorrection);
return Point.isValid(anchor) ? anchor : refPoint;
}
}
1 change: 1 addition & 0 deletions packages/protocol/src/index.ts
Expand Up @@ -18,4 +18,5 @@ export * from './client-server-protocol';
export * from './model';
export * from './re-exports';
export * from './sprotty-actions';
export * from './sprotty-geometry-point';
export * from './utils';
33 changes: 33 additions & 0 deletions packages/protocol/src/sprotty-geometry-point.ts
@@ -0,0 +1,33 @@
/********************************************************************************
* Copyright (c) 2024 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
********************************************************************************/
/* eslint-disable @typescript-eslint/no-shadow */

import { Point } from 'sprotty-protocol/lib/utils/geometry';

declare module 'sprotty-protocol/lib/utils/geometry' {
namespace Point {
/**
* Type guard to check if a point is valid. For a point to be valid it needs to be defined and have valid x and y coordinates.
*
* @param point the point to be checked for validity
*/
function isValid(point?: Point): point is Point;
}
}

Point.isValid = (point?: Point): point is Point => point !== undefined && !isNaN(point.x) && !isNaN(point.y);

export { Point };

0 comments on commit c4764a5

Please sign in to comment.