refactor: abstract classes, empty methods
Add abstract definition to abstract classes Fill empty methods blocks with return Remove unnecessary escapes in regexesdevelopment
parent
5a29d2fa1a
commit
a3102afa74
|
@ -140,7 +140,7 @@ export const htmlEntities = (s: string, newline = true): string => {
|
|||
|
||||
s = s.replace(/&/g, '&'); // 38 26
|
||||
s = s.replace(/"/g, '"'); // 34 22
|
||||
s = s.replace(/\'/g, '''); // 39 27
|
||||
s = s.replace(/'/g, '''); // 39 27
|
||||
s = s.replace(/</g, '<'); // 60 3C
|
||||
s = s.replace(/>/g, '>'); // 62 3E
|
||||
|
||||
|
|
|
@ -2168,8 +2168,12 @@ export class GraphView extends EventSource {
|
|||
|
||||
if (popupMenuHandler) popupMenuHandler.hideMenu();
|
||||
},
|
||||
mouseMove: () => {},
|
||||
mouseUp: () => {},
|
||||
mouseMove: () => {
|
||||
return;
|
||||
},
|
||||
mouseUp: () => {
|
||||
return;
|
||||
},
|
||||
});
|
||||
|
||||
this.moveHandler = (evt: MouseEvent) => {
|
||||
|
|
|
@ -49,7 +49,7 @@ import type {
|
|||
*
|
||||
* Constructs a new abstract canvas.
|
||||
*/
|
||||
class AbstractCanvas2D {
|
||||
abstract class AbstractCanvas2D {
|
||||
constructor() {
|
||||
this.converter = this.createUrlConverter();
|
||||
this.reset();
|
||||
|
@ -525,32 +525,39 @@ class AbstractCanvas2D {
|
|||
/**
|
||||
* Empty implementation for backwards compatibility. This will be removed.
|
||||
*/
|
||||
end() {}
|
||||
abstract end(): void;
|
||||
|
||||
stroke() {}
|
||||
abstract stroke(): void;
|
||||
|
||||
fill() {}
|
||||
abstract fill(): void;
|
||||
|
||||
fillAndStroke() {}
|
||||
abstract fillAndStroke(): void;
|
||||
|
||||
rect(x: number, y: number, w: number, h: number) {}
|
||||
abstract rect(x: number, y: number, w: number, h: number): void;
|
||||
|
||||
roundrect(x: number, y: number, w: number, h: number, r1: number, r2: number) {}
|
||||
abstract roundrect(
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number,
|
||||
r1: number,
|
||||
r2: number
|
||||
): void;
|
||||
|
||||
ellipse(x: number, y: number, w: number, h: number) {}
|
||||
abstract ellipse(x: number, y: number, w: number, h: number): void;
|
||||
|
||||
image(
|
||||
abstract image(
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
h: number,
|
||||
src: string,
|
||||
aspect = true,
|
||||
flipH = false,
|
||||
flipV = false
|
||||
) {}
|
||||
aspect: boolean,
|
||||
flipH: boolean,
|
||||
flipV: boolean
|
||||
): void;
|
||||
|
||||
text(
|
||||
abstract text(
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
|
@ -562,11 +569,11 @@ class AbstractCanvas2D {
|
|||
format: string,
|
||||
overflow: OverflowValue,
|
||||
clip: boolean,
|
||||
rotation = 0,
|
||||
rotation: number,
|
||||
dir: TextDirectionValue
|
||||
) {}
|
||||
): void;
|
||||
|
||||
updateText(
|
||||
abstract updateText(
|
||||
x: number,
|
||||
y: number,
|
||||
w: number,
|
||||
|
@ -576,9 +583,9 @@ class AbstractCanvas2D {
|
|||
wrap: boolean,
|
||||
overflow: OverflowValue,
|
||||
clip: boolean,
|
||||
rotation = 0,
|
||||
rotation: number,
|
||||
node: SVGElement
|
||||
) {}
|
||||
): void;
|
||||
}
|
||||
|
||||
export default AbstractCanvas2D;
|
||||
|
|
|
@ -381,6 +381,10 @@ class SvgCanvas2D extends AbstractCanvas2D {
|
|||
this.gradients = {};
|
||||
}
|
||||
|
||||
end(): void {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the optional style section.
|
||||
*/
|
||||
|
@ -741,7 +745,7 @@ class SvgCanvas2D extends AbstractCanvas2D {
|
|||
|
||||
if (this.root?.ownerDocument === document && useAbsoluteIds) {
|
||||
// Workaround for no fill with base tag in page (escape brackets)
|
||||
const base = this.getBaseUrl().replace(/([\(\)])/g, '\\$1');
|
||||
const base = this.getBaseUrl().replace(/([()])/g, '\\$1');
|
||||
this.node!.setAttribute('fill', `url(${base}#${id})`);
|
||||
} else {
|
||||
this.node!.setAttribute('fill', `url(#${id})`);
|
||||
|
@ -1586,7 +1590,7 @@ class SvgCanvas2D extends AbstractCanvas2D {
|
|||
this.root!.ownerDocument === document
|
||||
) {
|
||||
// Workaround for potential base tag
|
||||
const base = this.getBaseUrl().replace(/([\(\)])/g, '\\$1');
|
||||
const base = this.getBaseUrl().replace(/([()])/g, '\\$1');
|
||||
node.setAttribute('clip-path', `url(${base}#${c.getAttribute('id')})`);
|
||||
} else {
|
||||
node.setAttribute('clip-path', `url(#${c.getAttribute('id')})`);
|
||||
|
|
|
@ -770,9 +770,9 @@ class mxXmlCanvas2D extends AbstractCanvas2D {
|
|||
w: number,
|
||||
h: number,
|
||||
src: string,
|
||||
aspect: boolean,
|
||||
flipH: boolean,
|
||||
flipV: boolean
|
||||
aspect = true,
|
||||
flipH = false,
|
||||
flipV = false
|
||||
) {
|
||||
src = this.converter.convert(src);
|
||||
|
||||
|
@ -789,6 +789,10 @@ class mxXmlCanvas2D extends AbstractCanvas2D {
|
|||
this.root.appendChild(elem);
|
||||
}
|
||||
|
||||
updateText(): void {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a new path and puts it into the drawing buffer.
|
||||
*/
|
||||
|
@ -798,6 +802,10 @@ class mxXmlCanvas2D extends AbstractCanvas2D {
|
|||
this.lastY = 0;
|
||||
}
|
||||
|
||||
end(): void {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the current path the given point.
|
||||
*
|
||||
|
|
|
@ -97,7 +97,9 @@ class CellTracker extends CellMarker {
|
|||
/**
|
||||
* Ignores the event. The event is not consumed.
|
||||
*/
|
||||
mouseDown(sender: EventSource, me: InternalMouseEvent) {}
|
||||
mouseDown(sender: EventSource, me: InternalMouseEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the event by highlighting the cell under the mousepointer if it
|
||||
|
@ -112,7 +114,9 @@ class CellTracker extends CellMarker {
|
|||
/**
|
||||
* Handles the event by resetting the highlight.
|
||||
*/
|
||||
mouseUp(sender: EventSource, me: InternalMouseEvent) {}
|
||||
mouseUp(sender: EventSource, me: InternalMouseEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys the object and all its resources and DOM nodes. This doesn't
|
||||
|
|
|
@ -89,12 +89,16 @@ class VertexHandle implements CellHandle {
|
|||
/**
|
||||
* Hooks for subclassers to update the style in the <state>.
|
||||
*/
|
||||
setPosition(bounds: Rectangle | null, pt: Point, me: InternalMouseEvent) {}
|
||||
setPosition(bounds: Rectangle | null, pt: Point, me: InternalMouseEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for subclassers to execute the handle.
|
||||
*/
|
||||
execute(me: InternalMouseEvent): void {}
|
||||
execute(me: InternalMouseEvent): void {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cell style with the given name to the corresponding value in <state>.
|
||||
|
@ -129,7 +133,6 @@ class VertexHandle implements CellHandle {
|
|||
alpha2
|
||||
)
|
||||
);
|
||||
this.setPosition(this.state.getPaintBounds(), pt, me);
|
||||
this.redraw();
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,9 @@ let supportsPassive = false;
|
|||
try {
|
||||
document.addEventListener(
|
||||
'test',
|
||||
() => {},
|
||||
() => {
|
||||
return;
|
||||
},
|
||||
Object.defineProperty &&
|
||||
Object.defineProperty({}, 'passive', {
|
||||
get: () => {
|
||||
|
|
|
@ -488,12 +488,24 @@ class Shape {
|
|||
canvas.setDashed(this.isDashed);
|
||||
}
|
||||
|
||||
canvas.setStrokeWidth = () => {};
|
||||
canvas.setStrokeColor = () => {};
|
||||
canvas.setFillColor = () => {};
|
||||
canvas.setGradient = () => {};
|
||||
canvas.setDashed = () => {};
|
||||
canvas.text = () => {};
|
||||
canvas.setStrokeWidth = () => {
|
||||
return;
|
||||
};
|
||||
canvas.setStrokeColor = () => {
|
||||
return;
|
||||
};
|
||||
canvas.setFillColor = () => {
|
||||
return;
|
||||
};
|
||||
canvas.setGradient = () => {
|
||||
return;
|
||||
};
|
||||
canvas.setDashed = () => {
|
||||
return;
|
||||
};
|
||||
canvas.text = () => {
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
return canvas;
|
||||
|
@ -553,12 +565,16 @@ class Shape {
|
|||
/**
|
||||
* Invoked before paint is called.
|
||||
*/
|
||||
beforePaint(c: AbstractCanvas2D) {}
|
||||
beforePaint(c: AbstractCanvas2D) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes after paint was called.
|
||||
*/
|
||||
afterPaint(c: AbstractCanvas2D) {}
|
||||
afterPaint(c: AbstractCanvas2D) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic rendering code.
|
||||
|
@ -735,17 +751,23 @@ class Shape {
|
|||
/**
|
||||
* Hook for subclassers. This implementation is empty.
|
||||
*/
|
||||
paintBackground(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {}
|
||||
paintBackground(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for subclassers. This implementation is empty.
|
||||
*/
|
||||
paintForeground(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {}
|
||||
paintForeground(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for subclassers. This implementation is empty.
|
||||
*/
|
||||
paintEdgeShape(c: AbstractCanvas2D, pts: Point[]) {}
|
||||
paintEdgeShape(c: AbstractCanvas2D, pts: Point[]) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the arc size for the given dimension.
|
||||
|
@ -1141,7 +1163,9 @@ class Shape {
|
|||
return rect;
|
||||
}
|
||||
|
||||
redrawHtmlShape() {}
|
||||
redrawHtmlShape() {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a transparent background CSS style to catch all events.
|
||||
|
|
|
@ -23,6 +23,8 @@ import EventObject from '../event/EventObject';
|
|||
import InternalEvent from '../event/InternalEvent';
|
||||
import {
|
||||
CURSOR,
|
||||
DEFAULT_HOTSPOT,
|
||||
DEFAULT_INVALID_COLOR,
|
||||
DEFAULT_VALID_COLOR,
|
||||
DIALECT,
|
||||
HIGHLIGHT_STROKEWIDTH,
|
||||
|
@ -55,7 +57,7 @@ import CellState from '../cell/CellState';
|
|||
import { Graph } from '../Graph';
|
||||
import ConnectionConstraint from '../other/ConnectionConstraint';
|
||||
import Shape from '../geometry/Shape';
|
||||
import { CellStyle, GraphPlugin, Listenable } from '../../types';
|
||||
import { CellStyle, ColorValue, GraphPlugin, Listenable } from '../../types';
|
||||
|
||||
type FactoryMethod = (
|
||||
source: Cell | null,
|
||||
|
@ -526,101 +528,7 @@ class ConnectionHandler extends EventSource implements GraphPlugin {
|
|||
* Creates and returns the {@link CellMarker} used in {@link arker}.
|
||||
*/
|
||||
createMarker() {
|
||||
const self = this;
|
||||
|
||||
class MyCellMarker extends CellMarker {
|
||||
hotspotEnabled = true;
|
||||
|
||||
// Overrides to return cell at location only if valid (so that
|
||||
// there is no highlight for invalid cells)
|
||||
getCell(me: InternalMouseEvent) {
|
||||
let cell = super.getCell(me);
|
||||
self.error = null;
|
||||
|
||||
// Checks for cell at preview point (with grid)
|
||||
if (!cell && self.currentPoint) {
|
||||
cell = self.graph.getCellAt(self.currentPoint.x, self.currentPoint.y);
|
||||
}
|
||||
|
||||
// Uses connectable parent vertex if one exists
|
||||
if (cell && !cell.isConnectable() && self.cell) {
|
||||
const parent = self.cell.getParent();
|
||||
|
||||
if (parent && parent.isVertex() && parent.isConnectable()) {
|
||||
cell = parent;
|
||||
}
|
||||
}
|
||||
|
||||
if (cell) {
|
||||
if (
|
||||
(self.graph.isSwimlane(cell) &&
|
||||
self.currentPoint != null &&
|
||||
self.graph.hitsSwimlaneContent(
|
||||
cell,
|
||||
self.currentPoint.x,
|
||||
self.currentPoint.y
|
||||
)) ||
|
||||
!self.isConnectableCell(cell)
|
||||
) {
|
||||
cell = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (cell) {
|
||||
if (self.isConnecting()) {
|
||||
if (self.previous) {
|
||||
self.error = self.validateConnection(self.previous.cell, cell);
|
||||
|
||||
if (self.error && self.error.length === 0) {
|
||||
cell = null;
|
||||
|
||||
// Enables create target inside groups
|
||||
if (self.isCreateTarget(me.getEvent())) {
|
||||
self.error = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!self.isValidSource(cell, me)) {
|
||||
cell = null;
|
||||
}
|
||||
} else if (
|
||||
self.isConnecting() &&
|
||||
!self.isCreateTarget(me.getEvent()) &&
|
||||
!self.graph.isAllowDanglingEdges()
|
||||
) {
|
||||
self.error = '';
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
// Sets the highlight color according to validateConnection
|
||||
isValidState(state: CellState) {
|
||||
if (self.isConnecting()) {
|
||||
return !self.error;
|
||||
}
|
||||
return super.isValidState(state);
|
||||
}
|
||||
|
||||
// Overrides to use marker color only in highlight mode or for
|
||||
// target selection
|
||||
getMarkerColor(evt: Event, state: CellState, isValid: boolean) {
|
||||
return !self.connectImage || self.isConnecting()
|
||||
? super.getMarkerColor(evt, state, isValid)
|
||||
: NONE;
|
||||
}
|
||||
|
||||
// Overrides to use hotspot only for source selection otherwise
|
||||
// intersects always returns true when over a cell
|
||||
intersects(state: CellState, evt: InternalMouseEvent) {
|
||||
if (self.connectImage || self.isConnecting()) {
|
||||
return true;
|
||||
}
|
||||
return super.intersects(state, evt);
|
||||
}
|
||||
}
|
||||
|
||||
return new MyCellMarker(this.graph) as CellMarker;
|
||||
return new ConnectionHandlerCellMarker(this.graph, this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2078,4 +1986,115 @@ class ConnectionHandler extends EventSource implements GraphPlugin {
|
|||
}
|
||||
}
|
||||
|
||||
class ConnectionHandlerCellMarker extends CellMarker {
|
||||
connectionHandler: ConnectionHandler;
|
||||
|
||||
hotspotEnabled = true;
|
||||
|
||||
constructor(
|
||||
graph: Graph,
|
||||
connectionHandler: ConnectionHandler,
|
||||
validColor: ColorValue = DEFAULT_VALID_COLOR,
|
||||
invalidColor: ColorValue = DEFAULT_INVALID_COLOR,
|
||||
hotspot: number = DEFAULT_HOTSPOT
|
||||
) {
|
||||
super(graph, validColor, invalidColor, hotspot);
|
||||
this.connectionHandler = connectionHandler;
|
||||
}
|
||||
|
||||
// Overrides to return cell at location only if valid (so that
|
||||
// there is no highlight for invalid cells)
|
||||
getCell(me: InternalMouseEvent) {
|
||||
let cell = super.getCell(me);
|
||||
this.connectionHandler.error = null;
|
||||
|
||||
// Checks for cell at preview point (with grid)
|
||||
if (!cell && this.connectionHandler.currentPoint) {
|
||||
cell = this.connectionHandler.graph.getCellAt(
|
||||
this.connectionHandler.currentPoint.x,
|
||||
this.connectionHandler.currentPoint.y
|
||||
);
|
||||
}
|
||||
|
||||
// Uses connectable parent vertex if one exists
|
||||
if (cell && !cell.isConnectable() && this.connectionHandler.cell) {
|
||||
const parent = this.connectionHandler.cell.getParent();
|
||||
|
||||
if (parent && parent.isVertex() && parent.isConnectable()) {
|
||||
cell = parent;
|
||||
}
|
||||
}
|
||||
|
||||
if (cell) {
|
||||
if (
|
||||
(this.connectionHandler.graph.isSwimlane(cell) &&
|
||||
this.connectionHandler.currentPoint != null &&
|
||||
this.connectionHandler.graph.hitsSwimlaneContent(
|
||||
cell,
|
||||
this.connectionHandler.currentPoint.x,
|
||||
this.connectionHandler.currentPoint.y
|
||||
)) ||
|
||||
!this.connectionHandler.isConnectableCell(cell)
|
||||
) {
|
||||
cell = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (cell) {
|
||||
if (this.connectionHandler.isConnecting()) {
|
||||
if (this.connectionHandler.previous) {
|
||||
this.connectionHandler.error = this.connectionHandler.validateConnection(
|
||||
this.connectionHandler.previous.cell,
|
||||
cell
|
||||
);
|
||||
|
||||
if (this.connectionHandler.error && this.connectionHandler.error.length === 0) {
|
||||
cell = null;
|
||||
|
||||
// Enables create target inside groups
|
||||
if (this.connectionHandler.isCreateTarget(me.getEvent())) {
|
||||
this.connectionHandler.error = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!this.connectionHandler.isValidSource(cell, me)) {
|
||||
cell = null;
|
||||
}
|
||||
} else if (
|
||||
this.connectionHandler.isConnecting() &&
|
||||
!this.connectionHandler.isCreateTarget(me.getEvent()) &&
|
||||
!this.connectionHandler.graph.isAllowDanglingEdges()
|
||||
) {
|
||||
this.connectionHandler.error = '';
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
// Sets the highlight color according to validateConnection
|
||||
isValidState(state: CellState) {
|
||||
if (this.connectionHandler.isConnecting()) {
|
||||
return !this.connectionHandler.error;
|
||||
}
|
||||
return super.isValidState(state);
|
||||
}
|
||||
|
||||
// Overrides to use marker color only in highlight mode or for
|
||||
// target selection
|
||||
getMarkerColor(evt: Event, state: CellState, isValid: boolean) {
|
||||
return !this.connectionHandler.connectImage || this.connectionHandler.isConnecting()
|
||||
? super.getMarkerColor(evt, state, isValid)
|
||||
: NONE;
|
||||
}
|
||||
|
||||
// Overrides to use hotspot only for source selection otherwise
|
||||
// intersects always returns true when over a cell
|
||||
intersects(state: CellState, evt: InternalMouseEvent) {
|
||||
if (this.connectionHandler.connectImage || this.connectionHandler.isConnecting()) {
|
||||
return true;
|
||||
}
|
||||
return super.intersects(state, evt);
|
||||
}
|
||||
}
|
||||
|
||||
export default ConnectionHandler;
|
||||
|
|
|
@ -21,6 +21,8 @@ import Point from '../geometry/Point';
|
|||
import {
|
||||
CONNECT_HANDLE_FILLCOLOR,
|
||||
CURSOR,
|
||||
DEFAULT_HOTSPOT,
|
||||
DEFAULT_INVALID_COLOR,
|
||||
DEFAULT_VALID_COLOR,
|
||||
DIALECT,
|
||||
EDGE_SELECTION_COLOR,
|
||||
|
@ -533,70 +535,7 @@ class EdgeHandler {
|
|||
* Creates and returns the {@link CellMarker} used in {@link arker}.
|
||||
*/
|
||||
createMarker() {
|
||||
const self = this; // closure
|
||||
|
||||
class MyMarker extends CellMarker {
|
||||
// Only returns edges if they are connectable and never returns
|
||||
// the edge that is currently being modified
|
||||
getCell = (me: InternalMouseEvent) => {
|
||||
let cell = super.getCell(me);
|
||||
|
||||
// Checks for cell at preview point (with grid)
|
||||
if ((cell === self.state.cell || !cell) && self.currentPoint) {
|
||||
cell = self.graph.getCellAt(self.currentPoint.x, self.currentPoint.y);
|
||||
}
|
||||
|
||||
// Uses connectable parent vertex if one exists
|
||||
if (cell && !cell.isConnectable()) {
|
||||
const parent = cell.getParent();
|
||||
|
||||
if (parent && parent.isVertex() && parent.isConnectable()) {
|
||||
cell = parent;
|
||||
}
|
||||
}
|
||||
|
||||
if (cell) {
|
||||
if (
|
||||
(this.graph.isSwimlane(cell) &&
|
||||
self.currentPoint &&
|
||||
this.graph.hitsSwimlaneContent(
|
||||
cell,
|
||||
self.currentPoint.x,
|
||||
self.currentPoint.y
|
||||
)) ||
|
||||
!self.isConnectableCell(cell) ||
|
||||
cell === self.state.cell ||
|
||||
(cell && !self.graph.connectableEdges && cell.isEdge()) ||
|
||||
self.state.cell.isAncestor(cell)
|
||||
) {
|
||||
cell = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (cell && !cell.isConnectable()) {
|
||||
cell = null;
|
||||
}
|
||||
|
||||
return cell;
|
||||
};
|
||||
|
||||
// Sets the highlight color according to validateConnection
|
||||
isValidState = (state: CellState) => {
|
||||
const cell = self.state.cell.getTerminal(!self.isSource) as Cell;
|
||||
const cellState = self.graph.view.getState(cell) as CellState;
|
||||
const other = self.graph.view.getTerminalPort(state, cellState, !self.isSource);
|
||||
const otherCell = other ? other.cell : null;
|
||||
const source = self.isSource ? state.cell : otherCell;
|
||||
const target = self.isSource ? otherCell : state.cell;
|
||||
|
||||
// Updates the error message of the handler
|
||||
self.error = self.validateConnection(source, target);
|
||||
|
||||
return !self.error;
|
||||
};
|
||||
}
|
||||
|
||||
return new MyMarker(this.graph) as CellMarker;
|
||||
return new EdgeHandlerCellMarker(this.graph, this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -966,12 +905,16 @@ class EdgeHandler {
|
|||
* Hook for subclassers do show details while the handler is active.
|
||||
*/
|
||||
|
||||
updateHint(me: InternalMouseEvent, point: Point) {}
|
||||
updateHint(me: InternalMouseEvent, point: Point) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks for subclassers to hide details when the handler gets inactive.
|
||||
*/
|
||||
removeHint() {}
|
||||
removeHint() {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for rounding the unscaled width or height. This uses Math.round.
|
||||
|
@ -2326,4 +2269,89 @@ class EdgeHandler {
|
|||
}
|
||||
}
|
||||
|
||||
class EdgeHandlerCellMarker extends CellMarker {
|
||||
edgeHandler: EdgeHandler;
|
||||
|
||||
constructor(
|
||||
graph: Graph,
|
||||
edgeHandler: EdgeHandler,
|
||||
validColor: ColorValue = DEFAULT_VALID_COLOR,
|
||||
invalidColor: ColorValue = DEFAULT_INVALID_COLOR,
|
||||
hotspot: number = DEFAULT_HOTSPOT
|
||||
) {
|
||||
super(graph, validColor, invalidColor, hotspot);
|
||||
this.edgeHandler = edgeHandler;
|
||||
}
|
||||
// Only returns edges if they are connectable and never returns
|
||||
// the edge that is currently being modified
|
||||
getCell = (me: InternalMouseEvent) => {
|
||||
let cell = super.getCell(me);
|
||||
|
||||
// Checks for cell at preview point (with grid)
|
||||
if (
|
||||
(cell === this.edgeHandler.state.cell || !cell) &&
|
||||
this.edgeHandler.currentPoint
|
||||
) {
|
||||
cell = this.edgeHandler.graph.getCellAt(
|
||||
this.edgeHandler.currentPoint.x,
|
||||
this.edgeHandler.currentPoint.y
|
||||
);
|
||||
}
|
||||
|
||||
// Uses connectable parent vertex if one exists
|
||||
if (cell && !cell.isConnectable()) {
|
||||
const parent = cell.getParent();
|
||||
|
||||
if (parent && parent.isVertex() && parent.isConnectable()) {
|
||||
cell = parent;
|
||||
}
|
||||
}
|
||||
|
||||
if (cell) {
|
||||
if (
|
||||
(this.graph.isSwimlane(cell) &&
|
||||
this.edgeHandler.currentPoint &&
|
||||
this.graph.hitsSwimlaneContent(
|
||||
cell,
|
||||
this.edgeHandler.currentPoint.x,
|
||||
this.edgeHandler.currentPoint.y
|
||||
)) ||
|
||||
!this.edgeHandler.isConnectableCell(cell) ||
|
||||
cell === this.edgeHandler.state.cell ||
|
||||
(cell && !this.edgeHandler.graph.connectableEdges && cell.isEdge()) ||
|
||||
this.edgeHandler.state.cell.isAncestor(cell)
|
||||
) {
|
||||
cell = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (cell && !cell.isConnectable()) {
|
||||
cell = null;
|
||||
}
|
||||
|
||||
return cell;
|
||||
};
|
||||
|
||||
// Sets the highlight color according to validateConnection
|
||||
isValidState = (state: CellState) => {
|
||||
const cell = this.edgeHandler.state.cell.getTerminal(
|
||||
!this.edgeHandler.isSource
|
||||
) as Cell;
|
||||
const cellState = this.edgeHandler.graph.view.getState(cell) as CellState;
|
||||
const other = this.edgeHandler.graph.view.getTerminalPort(
|
||||
state,
|
||||
cellState,
|
||||
!this.edgeHandler.isSource
|
||||
);
|
||||
const otherCell = other ? other.cell : null;
|
||||
const source = this.edgeHandler.isSource ? state.cell : otherCell;
|
||||
const target = this.edgeHandler.isSource ? otherCell : state.cell;
|
||||
|
||||
// Updates the error message of the handler
|
||||
this.edgeHandler.error = this.edgeHandler.validateConnection(source, target);
|
||||
|
||||
return !this.edgeHandler.error;
|
||||
};
|
||||
}
|
||||
|
||||
export default EdgeHandler;
|
||||
|
|
|
@ -857,12 +857,16 @@ class SelectionHandler implements GraphPlugin {
|
|||
/**
|
||||
* Hook for subclassers do show details while the handler is active.
|
||||
*/
|
||||
updateHint(me?: InternalMouseEvent) {}
|
||||
updateHint(me?: InternalMouseEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks for subclassers to hide details when the handler gets inactive.
|
||||
*/
|
||||
removeHint() {}
|
||||
removeHint() {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for rounding the unscaled vector. This uses Math.round.
|
||||
|
|
|
@ -791,12 +791,16 @@ class VertexHandler {
|
|||
/**
|
||||
* Hook for subclassers do show details while the handler is active.
|
||||
*/
|
||||
updateHint(me: InternalMouseEvent) {}
|
||||
updateHint(me: InternalMouseEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks for subclassers to hide details when the handler gets inactive.
|
||||
*/
|
||||
removeHint() {}
|
||||
removeHint() {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for rounding the angle. This uses Math.round.
|
||||
|
@ -1282,7 +1286,9 @@ class VertexHandler {
|
|||
* This code is executed as part of the model transaction. This implementation
|
||||
* is empty.
|
||||
*/
|
||||
rotateClick() {}
|
||||
rotateClick() {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotates the given cell and its children by the given angle in degrees.
|
||||
|
@ -2016,7 +2022,9 @@ class VertexHandler {
|
|||
*/
|
||||
onDestroy() {
|
||||
(<Graph>this.state.view.graph).removeListener(this.escapeHandler);
|
||||
this.escapeHandler = () => {};
|
||||
this.escapeHandler = () => {
|
||||
return;
|
||||
};
|
||||
|
||||
if (this.preview) {
|
||||
this.preview.destroy();
|
||||
|
|
|
@ -70,7 +70,9 @@ class GraphLayout {
|
|||
* @param x X-coordinate of the new cell location.
|
||||
* @param y Y-coordinate of the new cell location.
|
||||
*/
|
||||
moveCell(cell: Cell, x: number, y: number): void {}
|
||||
moveCell(cell: Cell, x: number, y: number): void {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notified when a cell is being resized in a parent that has automatic
|
||||
|
@ -81,14 +83,18 @@ class GraphLayout {
|
|||
* @param cell <Cell> which has been moved.
|
||||
* @param bounds {@link Rectangle} that represents the new cell bounds.
|
||||
*/
|
||||
resizeCell(cell: Cell, bounds: Rectangle, prev?: Cell) {}
|
||||
resizeCell(cell: Cell, bounds: Rectangle, prev?: Cell) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the layout algorithm for the children of the given parent.
|
||||
*
|
||||
* @param parent {@link mxCell} whose children should be layed out.
|
||||
*/
|
||||
execute(parent: Cell): void {}
|
||||
execute(parent: Cell): void {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the graph that this layout operates on.
|
||||
|
|
|
@ -18,7 +18,7 @@ limitations under the License.
|
|||
|
||||
import Cell from '../../cell/Cell';
|
||||
|
||||
class GraphAbstractHierarchyCell extends Cell {
|
||||
abstract class GraphAbstractHierarchyCell extends Cell {
|
||||
swimlaneIndex: number | null = null;
|
||||
|
||||
/**
|
||||
|
@ -92,16 +92,14 @@ class GraphAbstractHierarchyCell extends Cell {
|
|||
/**
|
||||
* Returns the cells this cell connects to on the next layer up
|
||||
*/
|
||||
getNextLayerConnectedCells(layer: number): GraphAbstractHierarchyCell[] | null {
|
||||
return null;
|
||||
}
|
||||
abstract getNextLayerConnectedCells(layer: number): GraphAbstractHierarchyCell[] | null;
|
||||
|
||||
/**
|
||||
* Returns the cells this cell connects to on the next layer down
|
||||
*/
|
||||
getPreviousLayerConnectedCells(layer: number): GraphAbstractHierarchyCell[] | null {
|
||||
return null;
|
||||
}
|
||||
abstract getPreviousLayerConnectedCells(
|
||||
layer: number
|
||||
): GraphAbstractHierarchyCell[] | null;
|
||||
|
||||
/**
|
||||
* Returns whether or not this cell is an edge
|
||||
|
@ -120,14 +118,12 @@ class GraphAbstractHierarchyCell extends Cell {
|
|||
/**
|
||||
* Gets the value of temp for the specified layer
|
||||
*/
|
||||
getGeneralPurposeVariable(layer: number): number | null {
|
||||
return null;
|
||||
}
|
||||
abstract getGeneralPurposeVariable(layer: number): number | null;
|
||||
|
||||
/**
|
||||
* Set the value of temp for the specified layer
|
||||
*/
|
||||
setGeneralPurposeVariable(layer: number, value: number) {}
|
||||
abstract setGeneralPurposeVariable(layer: number, value: number): void;
|
||||
|
||||
/**
|
||||
* Set the value of x for the specified layer
|
||||
|
|
|
@ -25,15 +25,13 @@ limitations under the License.
|
|||
*
|
||||
* Constructs a new hierarchical layout stage.
|
||||
*/
|
||||
class HierarchicalLayoutStage {
|
||||
constructor() {}
|
||||
|
||||
abstract class HierarchicalLayoutStage {
|
||||
/**
|
||||
* Takes the graph detail and configuration information within the facade
|
||||
* and creates the resulting laid out graph within that facade for further
|
||||
* use.
|
||||
*/
|
||||
execute(parent: any) {}
|
||||
abstract execute(parent: any): void;
|
||||
}
|
||||
|
||||
export default HierarchicalLayoutStage;
|
||||
|
|
|
@ -42,8 +42,12 @@ class PanningManager {
|
|||
this.scrollTop = 0;
|
||||
|
||||
this.mouseListener = {
|
||||
mouseDown: (sender: EventSource, me: InternalMouseEvent) => {},
|
||||
mouseMove: (sender: EventSource, me: InternalMouseEvent) => {},
|
||||
mouseDown: (sender: EventSource, me: InternalMouseEvent) => {
|
||||
return;
|
||||
},
|
||||
mouseMove: (sender: EventSource, me: InternalMouseEvent) => {
|
||||
return;
|
||||
},
|
||||
mouseUp: (sender: EventSource, me: InternalMouseEvent) => {
|
||||
if (this.active) {
|
||||
this.stop();
|
||||
|
|
|
@ -126,13 +126,17 @@ class UndoableEdit {
|
|||
* Hook to notify any listeners of the changes after an <undo> or <redo>
|
||||
* has been carried out. This implementation is empty.
|
||||
*/
|
||||
notify() {}
|
||||
notify(): void {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to free resources after the edit has been removed from the command
|
||||
* history. This implementation is empty.
|
||||
*/
|
||||
die() {}
|
||||
die(): void {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Undoes all changes in this edit.
|
||||
|
|
Loading…
Reference in New Issue