- Trying to get the stories working...

development
Junsik Shim 2021-09-01 23:04:33 +09:00
parent 0adb9fa1d3
commit 4316d4f5e5
50 changed files with 263 additions and 268 deletions

View File

@ -236,7 +236,7 @@ export type ListenerTarget = {
mxListenerList?: Listener[]; mxListenerList?: Listener[];
}; };
export type Listenable = (EventSource | EventTarget) & ListenerTarget; export type Listenable = (EventTarget | (Window & typeof globalThis)) & ListenerTarget;
export type MouseEventListener = (me: MouseEvent) => void; export type MouseEventListener = (me: MouseEvent) => void;
export type KeyboardEventListener = (ke: KeyboardEvent) => void; export type KeyboardEventListener = (ke: KeyboardEvent) => void;

View File

@ -39,10 +39,10 @@ import { getOuterHtml } from './DomUtils';
import CellState from '../view/cell/datatypes/CellState'; import CellState from '../view/cell/datatypes/CellState';
import Cell from '../view/cell/datatypes/Cell'; import Cell from '../view/cell/datatypes/Cell';
import Model from '../view/model/Model'; import Model from '../view/model/Model';
import graph from '../view/Graph'; import CellArray from '../view/cell/datatypes/CellArray';
import type { CellStateStyles, Properties, StyleValue } from '../types'; import type { CellStateStyles, Properties, StyleValue } from '../types';
import CellArray from '../view/cell/datatypes/CellArray'; import type { MaxGraph } from '../view/Graph';
/** /**
* Class: mxUtils * Class: mxUtils
@ -2072,7 +2072,7 @@ export const getSizeForString = (
*/ */
export const getScaleForPageCount = ( export const getScaleForPageCount = (
pageCount: number, pageCount: number,
graph: graph, graph: MaxGraph,
pageFormat?: Rectangle, pageFormat?: Rectangle,
border = 0 border = 0
) => { ) => {
@ -2209,7 +2209,7 @@ export const getScaleForPageCount = (
* h - Optional height of the graph view. * h - Optional height of the graph view.
*/ */
export const show = ( export const show = (
graph: graph, graph: MaxGraph,
doc: Document, doc: Document,
x0 = 0, x0 = 0,
y0 = 0, y0 = 0,
@ -2325,7 +2325,7 @@ export const show = (
* *
* graph - <mxGraph> to be printed. * graph - <mxGraph> to be printed.
*/ */
export const printScreen = (graph: graph) => { export const printScreen = (graph: MaxGraph) => {
const wnd = window.open(); const wnd = window.open();
if (!wnd) return; if (!wnd) return;
@ -2353,19 +2353,52 @@ export const isNullish = (v: string | object | null | undefined | number) =>
export const isNotNullish = (v: string | object | null | undefined | number) => export const isNotNullish = (v: string | object | null | undefined | number) =>
!isNullish(v); !isNullish(v);
// Mixins support export const copyPropertiesToPrototype = (source: any, sourceObj: any, target: any) => {
export const applyMixins = (derivedCtor: any, constructors: any[]) => { Object.getOwnPropertyNames(sourceObj).forEach((name) => {
constructors.forEach((baseCtor) => { try {
Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => { Object.defineProperty(target, name, {
Object.defineProperty( ...(Object.getOwnPropertyDescriptor(source, name) || Object.create(null)),
derivedCtor.prototype, value: sourceObj[name],
name,
Object.getOwnPropertyDescriptor(baseCtor.prototype, name) || Object.create(null)
);
}); });
} catch (e) {
console.error(e);
}
}); });
}; };
export const copyMethodsToPrototype = (source: any, target: any) => {
Object.getOwnPropertyNames(source).forEach((name) => {
try {
if (name !== 'constructor') {
Object.defineProperty(
target,
name,
Object.getOwnPropertyDescriptor(source, name) || Object.create(null)
);
}
} catch (e) {
console.error(e);
}
});
};
// Mixins support
export const applyMixins = (derivedCtor: any, constructors: any[]) => {
constructors.forEach((baseCtor) => {
// Copy variables
copyPropertiesToPrototype(baseCtor.prototype, new baseCtor(), derivedCtor.prototype);
// Copy methods
copyMethodsToPrototype(baseCtor.prototype, derivedCtor.prototype);
});
// Attach the derived prototype to each prototype.
constructors.forEach((baseCtor) => {
Object.setPrototypeOf(baseCtor.prototype, derivedCtor.prototype);
});
};
// Creates a class using a type
export const autoImplement = <T>(): new () => T => class {} as any; export const autoImplement = <T>(): new () => T => class {} as any;
export default utils; export default utils;

View File

@ -17,6 +17,7 @@ import InternalEvent from '../../view/event/InternalEvent';
class mxAnimation extends EventSource { class mxAnimation extends EventSource {
constructor(delay) { constructor(delay) {
super(); super();
this.delay = delay != null ? delay : 20; this.delay = delay != null ? delay : 20;
} }
@ -46,10 +47,7 @@ class mxAnimation extends EventSource {
// startAnimation(): void; // startAnimation(): void;
startAnimation() { startAnimation() {
if (this.thread == null) { if (this.thread == null) {
this.thread = window.setInterval( this.thread = window.setInterval(this.updateAnimation.bind(this), this.delay);
this.updateAnimation.bind(this),
this.delay
);
} }
} }

View File

@ -28,6 +28,7 @@ import { br, write, writeln } from '../DomUtils';
class mxToolbar extends EventSource { class mxToolbar extends EventSource {
constructor(container) { constructor(container) {
super(); super();
this.container = container; this.container = container;
} }

View File

@ -378,10 +378,7 @@ class mxWindow extends EventSource {
// setScrollable(scrollable: boolean): void; // setScrollable(scrollable: boolean): void;
setScrollable(scrollable) { setScrollable(scrollable) {
// Workaround for hang in Presto 2.5.22 (Opera 10.5) // Workaround for hang in Presto 2.5.22 (Opera 10.5)
if ( if (navigator.userAgent == null || navigator.userAgent.indexOf('Presto/2.5') < 0) {
navigator.userAgent == null ||
navigator.userAgent.indexOf('Presto/2.5') < 0
) {
if (scrollable) { if (scrollable) {
this.contentWrapper.style.overflow = 'auto'; this.contentWrapper.style.overflow = 'auto';
} else { } else {
@ -519,12 +516,7 @@ class mxWindow extends EventSource {
} }
}; };
InternalEvent.addGestureListeners( InternalEvent.addGestureListeners(this.resize, start, dragHandler, dropHandler);
this.resize,
start,
dragHandler,
dropHandler
);
this.div.appendChild(this.resize); this.div.appendChild(this.resize);
} else { } else {
this.resize.style.display = 'inline'; this.resize.style.display = 'inline';
@ -550,9 +542,7 @@ class mxWindow extends EventSource {
this.table.style.height = `${height}px`; this.table.style.height = `${height}px`;
this.contentWrapper.style.height = `${ this.contentWrapper.style.height = `${
this.div.offsetHeight - this.div.offsetHeight - this.title.offsetHeight - this.contentHeightCorrection
this.title.offsetHeight -
this.contentHeightCorrection
}px`; }px`;
} }
@ -792,12 +782,7 @@ class mxWindow extends EventSource {
}; };
const dropHandler = (evt) => { const dropHandler = (evt) => {
InternalEvent.removeGestureListeners( InternalEvent.removeGestureListeners(document, null, dragHandler, dropHandler);
document,
null,
dragHandler,
dropHandler
);
this.fireEvent(new EventObject(InternalEvent.MOVE_END, 'event', evt)); this.fireEvent(new EventObject(InternalEvent.MOVE_END, 'event', evt));
InternalEvent.consume(evt); InternalEvent.consume(evt);
}; };
@ -940,9 +925,7 @@ class mxWindow extends EventSource {
this.contentWrapper.style.display != 'none' this.contentWrapper.style.display != 'none'
) { ) {
this.contentWrapper.style.height = `${ this.contentWrapper.style.height = `${
this.div.offsetHeight - this.div.offsetHeight - this.title.offsetHeight - this.contentHeightCorrection
this.title.offsetHeight -
this.contentHeightCorrection
}px`; }px`;
} }
@ -1095,10 +1078,7 @@ export const error = (message, width, close, icon) => {
warn.destroy(); warn.destroy();
}); });
write( write(button, Resources.get(utils.closeResource) || utils.closeResource);
button,
Resources.get(utils.closeResource) || utils.closeResource
);
tmp.appendChild(button); tmp.appendChild(button);
div.appendChild(tmp); div.appendChild(tmp);

View File

@ -76,6 +76,7 @@ import EventSource from '../view/event/EventSource';
class mxUndoManager extends EventSource { class mxUndoManager extends EventSource {
constructor(size) { constructor(size) {
super(); super();
this.size = size != null ? size : 100; this.size = size != null ? size : 100;
this.clear(); this.clear();
} }

View File

@ -147,8 +147,7 @@ class mxAutoSaveManager extends EventSource {
if ( if (
dt > this.autoSaveDelay || dt > this.autoSaveDelay ||
(this.ignoredChanges >= this.autoSaveThreshold && (this.ignoredChanges >= this.autoSaveThreshold && dt > this.autoSaveThrottle)
dt > this.autoSaveThrottle)
) { ) {
this.save(); this.save();
this.reset(); this.reset();

View File

@ -24,6 +24,8 @@ import Point from './geometry/Point';
import { import {
applyMixins, applyMixins,
autoImplement, autoImplement,
copyMethodsToPrototype,
copyPropertiesToPrototype,
getCurrentStyle, getCurrentStyle,
hasScrollbars, hasScrollbars,
parseCssNumber, parseCssNumber,
@ -70,6 +72,7 @@ import GraphTooltip from './tooltip/GraphTooltip';
import GraphTerminal from './terminal/GraphTerminal'; import GraphTerminal from './terminal/GraphTerminal';
import GraphDragDrop from './drag_drop/GraphDragDrop'; import GraphDragDrop from './drag_drop/GraphDragDrop';
import GraphSwimlane from './swimlane/GraphSwimlane'; import GraphSwimlane from './swimlane/GraphSwimlane';
import GraphPageBreaks from './page_breaks/GraphPageBreaks';
type PartialEvents = Pick< type PartialEvents = Pick<
GraphEvents, GraphEvents,
@ -260,14 +263,14 @@ const defaultPlugins: GraphPluginConstructor[] = [
class Graph extends autoImplement<PartialClass>() { class Graph extends autoImplement<PartialClass>() {
constructor( constructor(
container: HTMLElement, container: HTMLElement,
model: Model, model?: Model,
plugins: GraphPluginConstructor[] = defaultPlugins, plugins: GraphPluginConstructor[] = defaultPlugins,
stylesheet: Stylesheet | null = null stylesheet: Stylesheet | null = null
) { ) {
super(); super();
this.container = container; this.container = container;
this.model = model; this.model = model ?? new Model();
this.plugins = plugins; this.plugins = plugins;
this.cellRenderer = this.createCellRenderer(); this.cellRenderer = this.createCellRenderer();
this.setStylesheet(stylesheet != null ? stylesheet : this.createStylesheet()); this.setStylesheet(stylesheet != null ? stylesheet : this.createStylesheet());
@ -570,21 +573,6 @@ class Graph extends autoImplement<PartialClass>() {
*/ */
keepEdgesInBackground: boolean = false; keepEdgesInBackground: boolean = false;
/**
* Specifies if a child should be constrained inside the parent bounds after a
* move or resize of the child.
* @default true
*/
constrainChildren: boolean = true;
/**
* Specifies if child cells with relative geometries should be constrained
* inside the parent bounds, if {@link constrainChildren} is `true`, and/or the
* {@link maximumGraphBounds}.
* @default false
*/
constrainRelativeChildren: boolean = false;
/** /**
* Specifies the return value for {@link isRecursiveResize}. * Specifies the return value for {@link isRecursiveResize}.
* @default false (for backwards compatibility) * @default false (for backwards compatibility)
@ -669,12 +657,13 @@ class Graph extends autoImplement<PartialClass>() {
getContainsValidationErrorsResource = () => this.containsValidationErrorsResource; getContainsValidationErrorsResource = () => this.containsValidationErrorsResource;
// TODO: Document me!! // TODO: Document me!!
batchUpdate(fn: Function): void { batchUpdate(fn: Function) {
(<Model>this.getModel()).beginUpdate(); console.log(this.getModel, this.getModel());
this.getModel().beginUpdate();
try { try {
fn(); fn();
} finally { } finally {
(<Model>this.getModel()).endUpdate(); this.getModel().endUpdate();
} }
} }
@ -775,7 +764,10 @@ class Graph extends autoImplement<PartialClass>() {
const newParent = change.child.getParent(); const newParent = change.child.getParent();
this.view.invalidate(change.child, true, true); this.view.invalidate(change.child, true, true);
if (!this.getModel().contains(newParent) || newParent.isCollapsed()) { if (
newParent &&
(!this.getModel().contains(newParent) || newParent.isCollapsed())
) {
this.view.invalidate(change.child, true, true); this.view.invalidate(change.child, true, true);
this.removeStateForCell(change.child); this.removeStateForCell(change.child);
@ -1669,6 +1661,7 @@ class Graph extends autoImplement<PartialClass>() {
applyMixins(Graph, [ applyMixins(Graph, [
GraphCells, GraphCells,
GraphConnections, GraphConnections,
GraphDragDrop,
GraphEdge, GraphEdge,
GraphEditing, GraphEditing,
GraphEvents, GraphEvents,
@ -1676,11 +1669,20 @@ applyMixins(Graph, [
GraphImage, GraphImage,
GraphLabel, GraphLabel,
GraphOverlays, GraphOverlays,
GraphPageBreaks,
GraphPanning,
GraphPorts,
GraphSelection, GraphSelection,
GraphSnap, GraphSnap,
GraphSwimlane, GraphSwimlane,
GraphTerminal,
GraphTooltip,
GraphValidation, GraphValidation,
GraphVertex, GraphVertex,
GraphZoom,
]); ]);
copyPropertiesToPrototype(EventSource.prototype, new EventSource(), Graph.prototype);
copyMethodsToPrototype(EventSource.prototype, Graph.prototype);
export default Graph; export default Graph;

View File

@ -479,7 +479,7 @@ class GraphHandler implements GraphPlugin {
* selection state to the parent. * selection state to the parent.
*/ */
isPropagateSelectionCell(cell: Cell, immediate: boolean, me: InternalMouseEvent) { isPropagateSelectionCell(cell: Cell, immediate: boolean, me: InternalMouseEvent) {
const parent = cell.getParent(); const parent = cell.getParent() as Cell;
if (immediate) { if (immediate) {
const geo = cell.isEdge() ? null : cell.getGeometry(); const geo = cell.isEdge() ? null : cell.getGeometry();
@ -512,7 +512,8 @@ class GraphHandler implements GraphPlugin {
state && state &&
!this.graph.isCellSelected(state.cell) !this.graph.isCellSelected(state.cell)
) { ) {
let next = this.graph.view.getState(state.cell.getParent()); let parent = state.cell.getParent();
let next = parent ? this.graph.view.getState(parent) : null;
while ( while (
next && next &&
@ -521,7 +522,8 @@ class GraphHandler implements GraphPlugin {
this.isPropagateSelectionCell(state.cell, true, me) this.isPropagateSelectionCell(state.cell, true, me)
) { ) {
state = next; state = next;
next = this.graph.view.getState(state.cell.getParent()); parent = state.cell.getParent();
next = parent ? this.graph.view.getState(parent) : null;
} }
} }
@ -534,17 +536,19 @@ class GraphHandler implements GraphPlugin {
* Hook to return true for delayed selections. * Hook to return true for delayed selections.
*/ */
isDelayedSelection(cell: Cell, me: InternalMouseEvent) { isDelayedSelection(cell: Cell, me: InternalMouseEvent) {
let c: Cell | null = cell;
const selectionCellsHandler = this.graph.getPlugin( const selectionCellsHandler = this.graph.getPlugin(
'SelectionCellsHandler' 'SelectionCellsHandler'
) as SelectionCellsHandler; ) as SelectionCellsHandler;
if (!this.graph.isToggleEvent(me.getEvent()) || !isAltDown(me.getEvent())) { if (!this.graph.isToggleEvent(me.getEvent()) || !isAltDown(me.getEvent())) {
while (cell) { while (c) {
if (selectionCellsHandler.isHandled(cell)) { if (selectionCellsHandler.isHandled(c)) {
return this.graph.cellEditor.getEditingCell() !== cell; return this.graph.cellEditor.getEditingCell() !== c;
} }
cell = cell.getParent(); c = c.getParent();
} }
} }
@ -586,6 +590,7 @@ class GraphHandler implements GraphPlugin {
let parent = cell.getParent(); let parent = cell.getParent();
while ( while (
parent &&
this.graph.view.getState(parent) && this.graph.view.getState(parent) &&
(parent.isVertex() || parent.isEdge()) && (parent.isVertex() || parent.isEdge()) &&
this.isPropagateSelectionCell(cell, false, me) this.isPropagateSelectionCell(cell, false, me)
@ -848,7 +853,7 @@ class GraphHandler implements GraphPlugin {
if (this.guidesEnabled) { if (this.guidesEnabled) {
this.guide = this.createGuide(); this.guide = this.createGuide();
const parent = cell.getParent(); const parent = cell.getParent() as Cell;
const ignore = parent.getChildCount() < 2; const ignore = parent.getChildCount() < 2;
// Uses connected states as guides // Uses connected states as guides
@ -1709,6 +1714,7 @@ class GraphHandler implements GraphPlugin {
if ( if (
target == null && target == null &&
parent &&
this.isRemoveCellsFromParent() && this.isRemoveCellsFromParent() &&
this.shouldRemoveCellsFromParent(parent, cells, evt) this.shouldRemoveCellsFromParent(parent, cells, evt)
) { ) {

View File

@ -631,7 +631,8 @@ class GraphCells extends autoImplement<PartialClass>() {
if (g) { if (g) {
const state = this.getView().getState(cell); const state = this.getView().getState(cell);
const pstate = this.getView().getState(cell.getParent()); const parent = cell.getParent();
const pstate = parent ? this.getView().getState(parent) : null;
if (state && pstate) { if (state && pstate) {
const dx = keepPosition ? 0 : (<Point>pstate.origin).x; const dx = keepPosition ? 0 : (<Point>pstate.origin).x;
@ -785,7 +786,7 @@ class GraphCells extends autoImplement<PartialClass>() {
// Keeps the cell at its absolute location // Keeps the cell at its absolute location
if (o1 && cell !== parent && parent !== previous) { if (o1 && cell !== parent && parent !== previous) {
const oldState = this.getView().getState(previous); const oldState = previous ? this.getView().getState(previous) : null;
const o2 = oldState ? oldState.origin : zero; const o2 = oldState ? oldState.origin : zero;
let geo = cell.getGeometry(); let geo = cell.getGeometry();
@ -1538,7 +1539,7 @@ class GraphCells extends autoImplement<PartialClass>() {
*/ */
extendParent(cell: Cell) { extendParent(cell: Cell) {
const parent = cell.getParent(); const parent = cell.getParent();
let p = parent.getGeometry(); let p = parent ? parent.getGeometry() : null;
if (parent && p && !parent.isCollapsed()) { if (parent && p && !parent.isCollapsed()) {
const geo = cell.getGeometry(); const geo = cell.getGeometry();
@ -1706,6 +1707,7 @@ class GraphCells extends autoImplement<PartialClass>() {
if ( if (
geo && geo &&
geo.relative && geo.relative &&
parent &&
parent.isEdge() && parent.isEdge() &&
this.getModel().contains(parent) this.getModel().contains(parent)
) { ) {
@ -1886,11 +1888,10 @@ class GraphCells extends autoImplement<PartialClass>() {
if (geo && (this.isConstrainRelativeChildren() || !geo.relative)) { if (geo && (this.isConstrainRelativeChildren() || !geo.relative)) {
const parent = cell.getParent(); const parent = cell.getParent();
const pgeo = parent.getGeometry();
let max = this.getMaximumGraphBounds(); let max = this.getMaximumGraphBounds();
// Finds parent offset // Finds parent offset
if (max) { if (max && parent) {
const off = this.getBoundingBoxFromGeometry(new CellArray(parent), false); const off = this.getBoundingBoxFromGeometry(new CellArray(parent), false);
if (off) { if (off) {
@ -2809,7 +2810,7 @@ class GraphCells extends autoImplement<PartialClass>() {
} else { } else {
const parent = cell.getParent(); const parent = cell.getParent();
if (geo.relative) { if (geo.relative && parent) {
if (parent.isVertex() && parent !== this.getView().currentRoot) { if (parent.isVertex() && parent !== this.getView().currentRoot) {
tmp = this.getBoundingBoxFromGeometry(new CellArray(parent), false); tmp = this.getBoundingBoxFromGeometry(new CellArray(parent), false);
@ -2830,7 +2831,7 @@ class GraphCells extends autoImplement<PartialClass>() {
} else { } else {
bbox = Rectangle.fromRectangle(geo); bbox = Rectangle.fromRectangle(geo);
if (parent.isVertex() && cells.indexOf(parent) >= 0) { if (parent && parent.isVertex() && cells.indexOf(parent) >= 0) {
tmp = this.getBoundingBoxFromGeometry(new CellArray(parent), false); tmp = this.getBoundingBoxFromGeometry(new CellArray(parent), false);
if (tmp) { if (tmp) {

View File

@ -343,8 +343,8 @@ class Cell {
/** /**
* Returns the cell's parent. * Returns the cell's parent.
*/ */
getParent(): Cell { getParent() {
return <Cell>this.parent; return this.parent;
} }
/** /**
@ -901,9 +901,9 @@ class Cell {
/** /**
* Returns the root of the model or the topmost parent of the given cell. * Returns the root of the model or the topmost parent of the given cell.
*/ */
getRoot(): Cell { getRoot() {
let root: Cell = this; let root: Cell = this;
let cell: Cell = this; let cell: Cell | null = this;
while (cell) { while (cell) {
root = cell; root = cell;

View File

@ -13,7 +13,7 @@ import Shape from '../../geometry/shape/Shape';
import TextShape from '../../geometry/shape/node/TextShape'; import TextShape from '../../geometry/shape/node/TextShape';
import Dictionary from '../../../util/Dictionary'; import Dictionary from '../../../util/Dictionary';
import { NONE } from '../../../util/Constants'; import { NONE } from '../../../util/Constants';
import { CellStateStyles } from 'core/types'; import { CellStateStyles } from '../../../types';
import RectangleShape from '../../geometry/shape/node/RectangleShape'; import RectangleShape from '../../geometry/shape/node/RectangleShape';
import CellOverlay from '../CellOverlay'; import CellOverlay from '../CellOverlay';

View File

@ -56,10 +56,10 @@ import {
isMouseEvent, isMouseEvent,
isShiftDown, isShiftDown,
} from '../../../util/EventUtils'; } from '../../../util/EventUtils';
import Graph, { MaxGraph } from '../../Graph'; import { MaxGraph } from '../../Graph';
import CellState from '../datatypes/CellState'; import CellState from '../datatypes/CellState';
import Shape from '../../geometry/shape/Shape'; import Shape from '../../geometry/shape/Shape';
import { CellHandle, ColorValue, Listenable } from 'core/types'; import { CellHandle, ColorValue, Listenable } from '../../../types';
import InternalMouseEvent from '../../event/InternalMouseEvent'; import InternalMouseEvent from '../../event/InternalMouseEvent';
import Cell from '../datatypes/Cell'; import Cell from '../datatypes/Cell';
import ImageBox from '../../image/ImageBox'; import ImageBox from '../../image/ImageBox';
@ -400,7 +400,8 @@ class EdgeHandler {
* always returns true. * always returns true.
*/ */
isParentHighlightVisible() { isParentHighlightVisible() {
return !this.graph.isCellSelected(this.state.cell.getParent()); const parent = this.state.cell.getParent();
return parent ? !this.graph.isCellSelected(parent) : null;
} }
/** /**
@ -412,10 +413,10 @@ class EdgeHandler {
if (!this.isDestroyed()) { if (!this.isDestroyed()) {
const visible = this.isParentHighlightVisible(); const visible = this.isParentHighlightVisible();
const parent = this.state.cell.getParent(); const parent = this.state.cell.getParent();
const pstate = this.graph.view.getState(parent); const pstate = parent ? this.graph.view.getState(parent) : null;
if (this.parentHighlight) { if (this.parentHighlight) {
if (parent.isVertex() && visible) { if (parent && parent.isVertex() && visible) {
const b = this.parentHighlight.bounds; const b = this.parentHighlight.bounds;
if ( if (
@ -438,7 +439,7 @@ class EdgeHandler {
this.parentHighlight = null; this.parentHighlight = null;
} }
} else if (this.parentHighlightEnabled && visible) { } else if (this.parentHighlightEnabled && visible) {
if (parent.isVertex() && pstate && !pstate.parentHighlight) { if (parent && parent.isVertex() && pstate && !pstate.parentHighlight) {
this.parentHighlight = this.createParentHighlightShape(pstate); this.parentHighlight = this.createParentHighlightShape(pstate);
// VML dialect required here for event transparency in IE // VML dialect required here for event transparency in IE
this.parentHighlight.dialect = DIALECT_SVG; this.parentHighlight.dialect = DIALECT_SVG;
@ -624,7 +625,7 @@ class EdgeHandler {
if (cell && !cell.isConnectable()) { if (cell && !cell.isConnectable()) {
const parent = cell.getParent(); const parent = cell.getParent();
if (parent.isVertex() && parent.isConnectable()) { if (parent && parent.isVertex() && parent.isConnectable()) {
cell = parent; cell = parent;
} }
} }
@ -1060,7 +1061,7 @@ class EdgeHandler {
* *
* Returns a clone of the current preview state for the given point and terminal. * Returns a clone of the current preview state for the given point and terminal.
*/ */
clonePreviewState(point: Point, terminal: Cell) { clonePreviewState(point: Point, terminal: Cell | null) {
return this.state.clone(); return this.state.clone();
} }
@ -1402,7 +1403,7 @@ class EdgeHandler {
updatePreviewState( updatePreviewState(
edgeState: CellState, edgeState: CellState,
point: Point, point: Point,
terminalState: CellState, terminalState: CellState | null,
me: InternalMouseEvent, me: InternalMouseEvent,
outline = false outline = false
) { ) {
@ -1473,9 +1474,9 @@ class EdgeHandler {
} }
if (this.isSource) { if (this.isSource) {
sourceConstraint = constraint; sourceConstraint = constraint!;
} else if (this.isTarget) { } else if (this.isTarget) {
targetConstraint = constraint; targetConstraint = constraint!;
} }
if (this.isSource || this.isTarget) { if (this.isSource || this.isTarget) {
@ -1713,7 +1714,7 @@ class EdgeHandler {
if (clone) { if (clone) {
let geo = edge.getGeometry(); let geo = edge.getGeometry();
const cloned = this.graph.cloneCell(edge); const cloned = this.graph.cloneCell(edge);
model.add(parent, cloned, parent.getChildCount()); model.add(parent, cloned, parent!.getChildCount());
if (geo != null) { if (geo != null) {
geo = geo.clone(); geo = geo.clone();
@ -1741,7 +1742,8 @@ class EdgeHandler {
pt.y / this.graph.view.scale - this.graph.view.translate.y pt.y / this.graph.view.scale - this.graph.view.translate.y
); );
const pstate = this.graph.getView().getState(edge.getParent()); const parent = edge.getParent();
const pstate = parent ? this.graph.getView().getState(parent) : null;
if (pstate != null) { if (pstate != null) {
pt.x -= pstate.origin.x; pt.x -= pstate.origin.x;
@ -1846,7 +1848,8 @@ class EdgeHandler {
point.x = Math.round(point.x / scale - tr.x); point.x = Math.round(point.x / scale - tr.x);
point.y = Math.round(point.y / scale - tr.y); point.y = Math.round(point.y / scale - tr.y);
const pstate = this.graph.getView().getState(this.state.cell.getParent()); const parent = this.state.cell.getParent();
const pstate = parent ? this.graph.getView().getState(parent) : parent;
if (pstate) { if (pstate) {
point.x -= pstate.origin.x; point.x -= pstate.origin.x;
@ -1967,7 +1970,7 @@ class EdgeHandler {
const parent = edge.getParent(); const parent = edge.getParent();
const terminal = edge.getTerminal(!isSource); const terminal = edge.getTerminal(!isSource);
edge = this.graph.cloneCell(edge); edge = this.graph.cloneCell(edge);
model.add(parent, edge, parent.getChildCount()); model.add(parent, edge, parent!.getChildCount());
model.setTerminal(edge, terminal, !isSource); model.setTerminal(edge, terminal, !isSource);
} }
@ -2000,7 +2003,7 @@ class EdgeHandler {
const source = edge.getTerminal(true); const source = edge.getTerminal(true);
const target = edge.getTerminal(false); const target = edge.getTerminal(false);
edge = this.graph.cloneCell(edge); edge = this.graph.cloneCell(edge);
model.add(parent, edge, parent.getChildCount()); model.add(parent, edge, parent!.getChildCount());
model.setTerminal(edge, source, true); model.setTerminal(edge, source, true);
model.setTerminal(edge, target, false); model.setTerminal(edge, target, false);
} }
@ -2050,7 +2053,7 @@ class EdgeHandler {
const parent = this.state.cell.getParent(); const parent = this.state.cell.getParent();
if (parent.isVertex()) { if (parent && parent.isVertex()) {
const pState = this.graph.view.getState(parent); const pState = this.graph.view.getState(parent);
if (pState) offset = new Point(pState.x, pState.y); if (pState) offset = new Point(pState.x, pState.y);
@ -2478,7 +2481,7 @@ class EdgeHandler {
if (this.parentHighlight) { if (this.parentHighlight) {
const parent = this.state.cell.getParent(); const parent = this.state.cell.getParent();
const pstate = this.graph.view.getState(parent); const pstate = parent ? this.graph.view.getState(parent) : null;
if (pstate && pstate.parentHighlight === this.parentHighlight) { if (pstate && pstate.parentHighlight === this.parentHighlight) {
pstate.parentHighlight = null; pstate.parentHighlight = null;

View File

@ -71,13 +71,6 @@ class GraphEdge extends autoImplement<PartialClass>() {
*/ */
cloneInvalidEdges = false; cloneInvalidEdges = false;
/**
* Specifies if edges should be disconnected from their terminals when they
* are moved.
* @default true
*/
disconnectOnMove = true;
/** /**
* Specifies the alternate edge style to be used if the main control point * Specifies the alternate edge style to be used if the main control point
* on an edge is being double clicked. * on an edge is being double clicked.

View File

@ -1,6 +1,6 @@
import Cell from '../datatypes/Cell'; import Cell from '../datatypes/Cell';
import Geometry from '../../geometry/Geometry'; import Geometry from '../../geometry/Geometry';
import { autoImplement } from 'core/util/Utils'; import { autoImplement } from '../../../util/Utils';
import type GraphCells from '../GraphCells'; import type GraphCells from '../GraphCells';
@ -122,6 +122,7 @@ class GraphVertex extends autoImplement<PartialClass>() {
relative, relative,
geometryClass geometryClass
); );
return this.addCell(vertex, parent); return this.addCell(vertex, parent);
}; };

View File

@ -26,7 +26,7 @@ import CellState from '../datatypes/CellState';
import CellArray from '../datatypes/CellArray'; import CellArray from '../datatypes/CellArray';
import type { MaxGraph } from '../../Graph'; import type { MaxGraph } from '../../Graph';
import type { CellHandle, CellStateStyles } from 'core/types'; import type { CellHandle, CellStateStyles } from '../../../types';
/** /**
* Implements a single custom handle for vertices. * Implements a single custom handle for vertices.

View File

@ -26,20 +26,18 @@ import RectangleShape from '../../geometry/shape/node/RectangleShape';
import ImageShape from '../../geometry/shape/node/ImageShape'; import ImageShape from '../../geometry/shape/node/ImageShape';
import EllipseShape from '../../geometry/shape/node/EllipseShape'; import EllipseShape from '../../geometry/shape/node/EllipseShape';
import Point from '../../geometry/Point'; import Point from '../../geometry/Point';
import utils, { getRotatedPoint, intersects, mod, toRadians } from '../../../util/Utils'; import { getRotatedPoint, intersects, mod, toRadians } from '../../../util/Utils';
import mxClient from '../../../mxClient'; import mxClient from '../../../mxClient';
import { isMouseEvent, isShiftDown } from '../../../util/EventUtils'; import { isMouseEvent, isShiftDown } from '../../../util/EventUtils';
import Graph, { MaxGraph } from '../../Graph'; import { MaxGraph } from '../../Graph';
import CellState from '../datatypes/CellState'; import CellState from '../datatypes/CellState';
import Image from '../../image/ImageBox'; import Image from '../../image/ImageBox';
import Cell from '../datatypes/Cell'; import Cell from '../datatypes/Cell';
import { CellHandle, Listenable } from 'core/types'; import { CellHandle, Listenable } from '../../../types';
import Shape from '../../geometry/shape/Shape'; import Shape from '../../geometry/shape/Shape';
import InternalMouseEvent from '../../event/InternalMouseEvent'; import InternalMouseEvent from '../../event/InternalMouseEvent';
import VertexHandle from './VertexHandle';
import CellArray from '../datatypes/CellArray'; import CellArray from '../datatypes/CellArray';
import EdgeHandler from '../edge/EdgeHandler'; import EdgeHandler from '../edge/EdgeHandler';
import CellHighlight from '../../selection/CellHighlight';
import EventSource from '../../event/EventSource'; import EventSource from '../../event/EventSource';
import GraphHandler from '../../GraphHandler'; import GraphHandler from '../../GraphHandler';
import SelectionCellsHandler from '../../selection/SelectionCellsHandler'; import SelectionCellsHandler from '../../selection/SelectionCellsHandler';
@ -741,6 +739,7 @@ class VertexHandler {
if ( if (
this.state.view.currentRoot !== parent && this.state.view.currentRoot !== parent &&
parent &&
(parent.isVertex() || parent.isEdge()) (parent.isVertex() || parent.isEdge())
) { ) {
this.parentState = this.state.view.graph.view.getState(parent); this.parentState = this.state.view.graph.view.getState(parent);
@ -2048,7 +2047,8 @@ class VertexHandler {
* always returns true. * always returns true.
*/ */
isParentHighlightVisible() { isParentHighlightVisible() {
return !this.graph.isCellSelected(this.state.cell.getParent()); const parent = this.state.cell.getParent();
return parent ? !this.graph.isCellSelected(parent) : false;
} }
/** /**
@ -2060,10 +2060,10 @@ class VertexHandler {
if (!this.isDestroyed()) { if (!this.isDestroyed()) {
const visible = this.isParentHighlightVisible(); const visible = this.isParentHighlightVisible();
const parent = this.state.cell.getParent(); const parent = this.state.cell.getParent();
const pstate = this.graph.view.getState(parent); const pstate = parent ? this.graph.view.getState(parent) : null;
if (this.parentHighlight) { if (this.parentHighlight) {
if (parent.isVertex() && visible) { if (parent && parent.isVertex() && visible) {
const b = this.parentHighlight.bounds; const b = this.parentHighlight.bounds;
if ( if (
@ -2086,7 +2086,12 @@ class VertexHandler {
this.parentHighlight = null; this.parentHighlight = null;
} }
} else if (this.parentHighlightEnabled && visible) { } else if (this.parentHighlightEnabled && visible) {
if (parent.isVertex() && pstate != null && pstate.parentHighlight == null) { if (
parent &&
parent.isVertex() &&
pstate != null &&
pstate.parentHighlight == null
) {
this.parentHighlight = this.createParentHighlightShape(pstate); this.parentHighlight = this.createParentHighlightShape(pstate);
// VML dialect required here for event transparency in IE // VML dialect required here for event transparency in IE
this.parentHighlight.dialect = DIALECT_SVG; this.parentHighlight.dialect = DIALECT_SVG;
@ -2161,7 +2166,7 @@ class VertexHandler {
if (this.parentHighlight) { if (this.parentHighlight) {
const parent = this.state.cell.getParent(); const parent = this.state.cell.getParent();
const pstate = this.graph.view.getState(parent); const pstate = parent ? this.graph.view.getState(parent) : null;
if (pstate && pstate.parentHighlight === this.parentHighlight) { if (pstate && pstate.parentHighlight === this.parentHighlight) {
pstate.parentHighlight = null; pstate.parentHighlight = null;

View File

@ -612,7 +612,7 @@ class ConnectionHandler extends EventSource implements GraphPlugin {
if (cell && !cell.isConnectable() && self.cell) { if (cell && !cell.isConnectable() && self.cell) {
const parent = self.cell.getParent(); const parent = self.cell.getParent();
if (parent.isVertex() && parent.isConnectable()) { if (parent && parent.isVertex() && parent.isConnectable()) {
cell = parent; cell = parent;
} }
} }
@ -1938,13 +1938,13 @@ class ConnectionHandler extends EventSource implements GraphPlugin {
} }
} }
let parent = this.graph.getDefaultParent(); let parent: Cell | null = this.graph.getDefaultParent();
if ( if (
source && source &&
target && target &&
source.getParent() === target.getParent() && source.getParent() === target.getParent() &&
source.getParent().getParent() !== model.getRoot() source.getParent()?.getParent() !== model.getRoot()
) { ) {
parent = source.getParent(); parent = source.getParent();
@ -1954,7 +1954,7 @@ class ConnectionHandler extends EventSource implements GraphPlugin {
target.geometry && target.geometry &&
target.geometry.relative target.geometry.relative
) { ) {
parent = parent.getParent(); parent = parent!.getParent();
} }
} }
@ -1968,7 +1968,7 @@ class ConnectionHandler extends EventSource implements GraphPlugin {
style = this.edgeState.cell.style ?? ''; style = this.edgeState.cell.style ?? '';
} }
edge = this.insertEdge(parent, '', value, source, target, style); edge = this.insertEdge(parent as Cell, '', value, source, target, style);
if (edge && source) { if (edge && source) {
// Updates the connection constraints // Updates the connection constraints
@ -1990,9 +1990,10 @@ class ConnectionHandler extends EventSource implements GraphPlugin {
// Inserts edge before source // Inserts edge before source
if (this.isInsertBefore(edge, source, target, evt, dropTarget)) { if (this.isInsertBefore(edge, source, target, evt, dropTarget)) {
const index = null; const index = null;
let tmp = source; let tmp: Cell | null = source;
while ( while (
tmp &&
tmp.parent != null && tmp.parent != null &&
tmp.geometry != null && tmp.geometry != null &&
tmp.geometry.relative && tmp.geometry.relative &&
@ -2123,7 +2124,7 @@ class ConnectionHandler extends EventSource implements GraphPlugin {
let geo = source.getGeometry(); let geo = source.getGeometry();
while (geo && geo.relative) { while (geo && geo.relative) {
source = source.getParent(); source = source.getParent() as Cell;
geo = source.getGeometry(); geo = source.getGeometry();
} }

View File

@ -233,7 +233,7 @@ class ConstraintHandler {
if (cell != null && !cell.isConnectable()) { if (cell != null && !cell.isConnectable()) {
const parent = cell.getParent(); const parent = cell.getParent();
if (parent.isVertex() && parent.isConnectable()) { if (parent && parent.isVertex() && parent.isConnectable()) {
cell = parent; cell = parent;
} }
} }

View File

@ -51,11 +51,27 @@ class GraphConnections extends autoImplement<PartialClass>() {
this.connectionHandler = connectionHandler; this.connectionHandler = connectionHandler;
} }
constrainChildren = false; /**
* Specifies if a child should be constrained inside the parent bounds after a
* move or resize of the child.
* @default true
*/
constrainChildren = true;
/**
* Specifies if child cells with relative geometries should be constrained
* inside the parent bounds, if {@link constrainChildren} is `true`, and/or the
* {@link maximumGraphBounds}.
* @default false
*/
constrainRelativeChildren = false; constrainRelativeChildren = false;
disconnectOnMove = false; /**
* Specifies if edges should be disconnected from their terminals when they
* are moved.
* @default true
*/
disconnectOnMove = true;
cellsDisconnectable = true; cellsDisconnectable = true;
@ -493,7 +509,8 @@ class GraphConnections extends autoImplement<PartialClass>() {
if (geo) { if (geo) {
const state = this.getView().getState(cell); const state = this.getView().getState(cell);
const pstate = <CellState>this.getView().getState(cell.getParent()); const parent = cell.getParent();
const pstate = parent ? this.getView().getState(parent) : null;
if (state && pstate) { if (state && pstate) {
geo = geo.clone(); geo = geo.clone();

View File

@ -34,9 +34,8 @@ type EventListenerObject = {
* *
* Constructs a new event source. * Constructs a new event source.
*/ */
class EventSource extends EventTarget { class EventSource {
constructor(eventSource: EventSource | null = null) { constructor(eventSource: EventTarget | null = null) {
super();
this.eventSource = eventSource; this.eventSource = eventSource;
} }
@ -61,7 +60,7 @@ class EventSource extends EventTarget {
* *
* Optional source for events. Default is null. * Optional source for events. Default is null.
*/ */
eventSource: EventSource | EventTarget | null; eventSource: EventTarget | null = null;
/** /**
* Function: isEventsEnabled * Function: isEventsEnabled
@ -95,7 +94,7 @@ class EventSource extends EventTarget {
* *
* Sets <eventSource>. * Sets <eventSource>.
*/ */
setEventSource(value: EventSource | EventTarget | null) { setEventSource(value: EventTarget | null) {
this.eventSource = value; this.eventSource = value;
} }
@ -147,7 +146,7 @@ class EventSource extends EventTarget {
* sender - Optional sender to be passed to the listener. Default value is * sender - Optional sender to be passed to the listener. Default value is
* the return value of <getEventSource>. * the return value of <getEventSource>.
*/ */
fireEvent(evt: EventObject, sender: EventSource | EventTarget | null = null) { fireEvent(evt: EventObject, sender: EventTarget | null = null) {
if (this.isEventsEnabled()) { if (this.isEventsEnabled()) {
if (!evt) { if (!evt) {
evt = new EventObject(''); evt = new EventObject('');
@ -157,7 +156,7 @@ class EventSource extends EventTarget {
sender = this.getEventSource(); sender = this.getEventSource();
} }
if (!sender) { if (!sender) {
sender = this; sender = <EventTarget>(<unknown>this);
} }
for (const eventListener of this.eventListeners) { for (const eventListener of this.eventListeners) {

View File

@ -123,7 +123,7 @@ class InternalEvent {
* will be registered as well as the mouse events. * will be registered as well as the mouse events.
*/ */
static addGestureListeners( static addGestureListeners(
node: EventSource | EventTarget, node: Listenable,
startListener: MouseEventListener | null = null, startListener: MouseEventListener | null = null,
moveListener: MouseEventListener | null = null, moveListener: MouseEventListener | null = null,
endListener: MouseEventListener | null = null endListener: MouseEventListener | null = null

View File

@ -7,8 +7,8 @@
import Rectangle from '../Rectangle'; import Rectangle from '../Rectangle';
import Shape from './Shape'; import Shape from './Shape';
import SvgCanvas2D from '../../../util/canvas/SvgCanvas2D'; import SvgCanvas2D from '../../../util/canvas/SvgCanvas2D';
import { ColorValue } from 'core/types'; import { ColorValue } from '../../../types';
import { NONE } from 'core/util/Constants'; import { NONE } from '../../../util/Constants';
/** /**
* Extends {@link Shape} to implement an actor shape. If a custom shape with one * Extends {@link Shape} to implement an actor shape. If a custom shape with one

View File

@ -23,7 +23,7 @@ import {
SHADOW_OFFSET_Y, SHADOW_OFFSET_Y,
} from '../../../util/Constants'; } from '../../../util/Constants';
import Point from '../Point'; import Point from '../Point';
import AbstractCanvas2D from 'core/util/canvas/AbstractCanvas2D'; import AbstractCanvas2D from '../../../util/canvas/AbstractCanvas2D';
import SvgCanvas2D from '../../../util/canvas/SvgCanvas2D'; import SvgCanvas2D from '../../../util/canvas/SvgCanvas2D';
import InternalEvent from '../../event/InternalEvent'; import InternalEvent from '../../event/InternalEvent';
import mxClient from '../../../mxClient'; import mxClient from '../../../mxClient';

View File

@ -9,7 +9,7 @@ import { ARROW_SIZE, ARROW_SPACING, ARROW_WIDTH } from '../../../../util/Constan
import Rectangle from '../../Rectangle'; import Rectangle from '../../Rectangle';
import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D'; import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D';
import Point from '../../Point'; import Point from '../../Point';
import { ColorValue } from 'core/types'; import { ColorValue } from '../../../../types';
/** /**
* Extends {@link Shape} to implement an arrow shape. The shape is used to represent edges, not vertices. * Extends {@link Shape} to implement an arrow shape. The shape is used to represent edges, not vertices.

View File

@ -11,7 +11,7 @@ import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D';
import Point from '../../Point'; import Point from '../../Point';
import Rectangle from '../../Rectangle'; import Rectangle from '../../Rectangle';
import CellState from '../../../cell/datatypes/CellState'; import CellState from '../../../cell/datatypes/CellState';
import { ColorValue } from 'core/types'; import { ColorValue } from '../../../../types';
/** /**
* Extends {@link Shape} to implement an new rounded arrow shape with support for waypoints and double arrows. The * Extends {@link Shape} to implement an new rounded arrow shape with support for waypoints and double arrows. The

View File

@ -11,7 +11,7 @@ import Marker from './Marker';
import Point from '../../Point'; import Point from '../../Point';
import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D'; import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D';
import Rectangle from '../../Rectangle'; import Rectangle from '../../Rectangle';
import { ColorValue } from 'core/types'; import { ColorValue } from '../../../../types';
/** /**
* Extends {@link mxShape} to implement a connector shape. * Extends {@link mxShape} to implement a connector shape.

View File

@ -7,7 +7,7 @@
import Shape from '../Shape'; import Shape from '../Shape';
import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D'; import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D';
import Rectangle from '../../Rectangle'; import Rectangle from '../../Rectangle';
import { ColorValue } from 'core/types'; import { ColorValue } from '../../../../types';
/** /**
* Extends {@link Shape} to implement a horizontal line shape. * Extends {@link Shape} to implement a horizontal line shape.

View File

@ -4,8 +4,8 @@
* Updated to ES9 syntax by David Morrissey 2021 * Updated to ES9 syntax by David Morrissey 2021
* Type definitions from the typed-mxgraph project * Type definitions from the typed-mxgraph project
*/ */
import { ArrowType } from 'core/types'; import { ArrowType } from '../../../../types';
import AbstractCanvas2D from 'core/util/canvas/AbstractCanvas2D'; import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D';
import { import {
ARROW_CLASSIC, ARROW_CLASSIC,
ARROW_CLASSIC_THIN, ARROW_CLASSIC_THIN,

View File

@ -8,7 +8,7 @@ import Shape from '../Shape';
import { LINE_ARCSIZE } from '../../../../util/Constants'; import { LINE_ARCSIZE } from '../../../../util/Constants';
import Point from '../../Point'; import Point from '../../Point';
import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D'; import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D';
import { ColorValue } from 'core/types'; import { ColorValue } from '../../../../types';
/** /**
* Class: mxPolyline * Class: mxPolyline

View File

@ -7,7 +7,7 @@
import Shape from '../Shape'; import Shape from '../Shape';
import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D'; import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D';
import Rectangle from '../../Rectangle'; import Rectangle from '../../Rectangle';
import { NONE } from 'core/util/Constants'; import { NONE } from '../../../../util/Constants';
/** /**
* Extends {@link Shape} to implement an cylinder shape. If a custom shape with one filled area and an overlay path is * Extends {@link Shape} to implement an cylinder shape. If a custom shape with one filled area and an overlay path is

View File

@ -10,7 +10,7 @@ import Rectangle from '../../Rectangle';
import CellState from '../../../cell/datatypes/CellState'; import CellState from '../../../cell/datatypes/CellState';
import AbstractCanvas2D from '../../../../util/canvas/SvgCanvas2D'; import AbstractCanvas2D from '../../../../util/canvas/SvgCanvas2D';
import CellOverlay from '../../../cell/CellOverlay'; import CellOverlay from '../../../cell/CellOverlay';
import { NONE } from 'core/util/Constants'; import { NONE } from '../../../../util/Constants';
/** /**
* Extends {@link mxShape} to implement an image shape. * Extends {@link mxShape} to implement an image shape.

View File

@ -16,8 +16,8 @@ import {
NONE, NONE,
} from '../../../../util/Constants'; } from '../../../../util/Constants';
import RectangleShape from './RectangleShape'; import RectangleShape from './RectangleShape';
import { ColorValue } from 'core/types'; import { ColorValue } from '../../../../types';
import AbstractCanvas2D from 'core/util/canvas/AbstractCanvas2D'; import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D';
/** /**
* Class: mxLabel * Class: mxLabel

View File

@ -13,7 +13,7 @@ import {
import Shape from '../Shape'; import Shape from '../Shape';
import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D'; import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D';
import Rectangle from '../../Rectangle'; import Rectangle from '../../Rectangle';
import { ColorValue } from 'core/types'; import { ColorValue } from '../../../../types';
/** /**
* Extends {@link Shape} to implement a rectangle shape. * Extends {@link Shape} to implement a rectangle shape.

View File

@ -24,7 +24,7 @@ import StencilShapeRegistry from './StencilShapeRegistry';
import { getChildNodes, getTextContent } from '../../../../util/DomUtils'; import { getChildNodes, getTextContent } from '../../../../util/DomUtils';
import Point from '../../Point'; import Point from '../../Point';
import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D'; import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D';
import { AlignValue, ColorValue, VAlignValue } from 'core/types'; import { AlignValue, ColorValue, VAlignValue } from '../../../../types';
/** /**
* Implements a generic shape which is based on a XML node as a description. * Implements a generic shape which is based on a XML node as a description.

View File

@ -15,8 +15,8 @@ import {
NONE, NONE,
RECTANGLE_ROUNDING_FACTOR, RECTANGLE_ROUNDING_FACTOR,
} from '../../../../util/Constants'; } from '../../../../util/Constants';
import { ColorValue } from 'core/types'; import { ColorValue } from '../../../../types';
import AbstractCanvas2D from 'core/util/canvas/AbstractCanvas2D'; import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D';
/** /**
* Extends {@link Shape} to implement a swimlane shape. * Extends {@link Shape} to implement a swimlane shape.

View File

@ -47,8 +47,8 @@ import {
OverflowValue, OverflowValue,
TextDirectionValue, TextDirectionValue,
VAlignValue, VAlignValue,
} from 'core/types'; } from '../../../../types';
import SvgCanvas2D from 'core/util/canvas/SvgCanvas2D'; import SvgCanvas2D from '../../../../util/canvas/SvgCanvas2D';
/** /**
* Extends mxShape to implement a text shape. * Extends mxShape to implement a text shape.

View File

@ -8,7 +8,7 @@
import Point from '../../Point'; import Point from '../../Point';
import Actor from '../Actor'; import Actor from '../Actor';
import { LINE_ARCSIZE } from '../../../../util/Constants'; import { LINE_ARCSIZE } from '../../../../util/Constants';
import AbstractCanvas2D from 'core/util/canvas/AbstractCanvas2D'; import AbstractCanvas2D from '../../../../util/canvas/AbstractCanvas2D';
/** /**
* Implementation of the triangle shape. * Implementation of the triangle shape.

View File

@ -18,9 +18,9 @@ import EventObject from '../event/EventObject';
import Cell from '../cell/datatypes/Cell'; import Cell from '../cell/datatypes/Cell';
import graph from '../Graph'; import graph from '../Graph';
import Rectangle from '../geometry/Rectangle'; import Rectangle from '../geometry/Rectangle';
import InternalMouseEvent from "../event/InternalMouseEvent"; import InternalMouseEvent from '../event/InternalMouseEvent';
import { getClientX, getClientY } from '../../util/EventUtils'; import { getClientX, getClientY } from '../../util/EventUtils';
import CellArray from "../cell/datatypes/CellArray"; import CellArray from '../cell/datatypes/CellArray';
import Graph from '../Graph'; import Graph from '../Graph';
/** /**
@ -219,9 +219,7 @@ class LayoutManager extends EventSource {
* @param cell Array of {@link Cell} that have been moved. * @param cell Array of {@link Cell} that have been moved.
* @param evt Mouse event that represents the mousedown. * @param evt Mouse event that represents the mousedown.
*/ */
cellsMoved(cells: CellArray, cellsMoved(cells: CellArray, evt: InternalMouseEvent): void {
evt: InternalMouseEvent): void {
if (cells != null && evt != null) { if (cells != null && evt != null) {
const point = convertPoint( const point = convertPoint(
(<graph>this.getGraph()).container, (<graph>this.getGraph()).container,
@ -231,10 +229,7 @@ class LayoutManager extends EventSource {
const model = (<graph>this.getGraph()).getModel(); const model = (<graph>this.getGraph()).getModel();
for (let i = 0; i < cells.length; i += 1) { for (let i = 0; i < cells.length; i += 1) {
const layout = this.getLayout( const layout = this.getLayout(cells[i].getParent(), InternalEvent.MOVE_CELLS);
cells[i].getParent(),
InternalEvent.MOVE_CELLS
);
if (layout != null) { if (layout != null) {
layout.moveCell(cells[i], point.x, point.y); layout.moveCell(cells[i], point.x, point.y);
@ -258,10 +253,7 @@ class LayoutManager extends EventSource {
const model = (<graph>this.getGraph()).getModel(); const model = (<graph>this.getGraph()).getModel();
for (let i = 0; i < cells.length; i += 1) { for (let i = 0; i < cells.length; i += 1) {
const layout = this.getLayout( const layout = this.getLayout(cells[i].getParent(), InternalEvent.RESIZE_CELLS);
cells[i].getParent(),
InternalEvent.RESIZE_CELLS
);
if (layout != null) { if (layout != null) {
layout.resizeCell(cells[i], bounds[i], prev?.[i]); layout.resizeCell(cells[i], bounds[i], prev?.[i]);
} }
@ -296,10 +288,7 @@ class LayoutManager extends EventSource {
); );
} }
if ( if (change instanceof TerminalChange || change instanceof GeometryChange) {
change instanceof TerminalChange ||
change instanceof GeometryChange
) {
return this.addCellsWithLayout(change.cell); return this.addCellsWithLayout(change.cell);
} }
@ -313,12 +302,8 @@ class LayoutManager extends EventSource {
/** /**
* Adds all ancestors of the given cell that have a layout. * Adds all ancestors of the given cell that have a layout.
*/ */
addCellsWithLayout(cell: Cell, addCellsWithLayout(cell: Cell, result: CellArray = new CellArray()): CellArray {
result: CellArray = new CellArray()): CellArray { return this.addDescendantsWithLayout(cell, this.addAncestorsWithLayout(cell, result));
return this.addDescendantsWithLayout(
cell,
this.addAncestorsWithLayout(cell, result)
);
} }
/** /**
@ -343,8 +328,7 @@ class LayoutManager extends EventSource {
/** /**
* Adds all descendants of the given cell that have a layout. * Adds all descendants of the given cell that have a layout.
*/ */
addDescendantsWithLayout(cell: Cell, addDescendantsWithLayout(cell: Cell, result: CellArray = new CellArray()): CellArray {
result: CellArray = new CellArray()): CellArray {
if (cell != null && this.hasLayout(cell)) { if (cell != null && this.hasLayout(cell)) {
const model = (<graph>this.getGraph()).getModel(); const model = (<graph>this.getGraph()).getModel();
@ -372,9 +356,7 @@ class LayoutManager extends EventSource {
/** /**
* Executes all layouts which have been scheduled during the changes. * Executes all layouts which have been scheduled during the changes.
*/ */
layoutCells(cells: CellArray, layoutCells(cells: CellArray, bubble: boolean = false): void {
bubble: boolean = false): void {
if (cells.length > 0) { if (cells.length > 0) {
// Invokes the layouts while removing duplicates // Invokes the layouts while removing duplicates
const model = (<graph>this.getGraph()).getModel(); const model = (<graph>this.getGraph()).getModel();
@ -400,8 +382,7 @@ class LayoutManager extends EventSource {
/** /**
* Executes the given layout on the given parent. * Executes the given layout on the given parent.
*/ */
executeLayout(cell: Cell, executeLayout(cell: Cell, bubble: boolean = false): void {
bubble: boolean=false): void {
const layout = this.getLayout( const layout = this.getLayout(
cell, cell,
bubble ? InternalEvent.BEGIN_UPDATE : InternalEvent.END_UPDATE bubble ? InternalEvent.BEGIN_UPDATE : InternalEvent.END_UPDATE

View File

@ -13,7 +13,7 @@ import graph from '../Graph';
import EventObject from '../event/EventObject'; import EventObject from '../event/EventObject';
import Cell from '../cell/datatypes/Cell'; import Cell from '../cell/datatypes/Cell';
import Geometry from '../geometry/Geometry'; import Geometry from '../geometry/Geometry';
import CellArray from "../cell/datatypes/CellArray"; import CellArray from '../cell/datatypes/CellArray';
/** /**
* @class SwimlaneManager * @class SwimlaneManager
@ -282,15 +282,8 @@ class SwimlaneManager extends EventSource {
} }
const parentHorizontal = const parentHorizontal =
current != null current != null ? this.isCellHorizontal(current) : this.horizontal;
? this.isCellHorizontal(current) this.resizeSwimlane(top, size.width, size.height, parentHorizontal);
: this.horizontal;
this.resizeSwimlane(
top,
size.width,
size.height,
parentHorizontal
);
} }
} }
} }
@ -307,12 +300,7 @@ class SwimlaneManager extends EventSource {
* *
* @param swimlane {@link mxCell} whose size has changed. * @param swimlane {@link mxCell} whose size has changed.
*/ */
resizeSwimlane( resizeSwimlane(swimlane: Cell, w: number, h: number, parentHorizontal: boolean): void {
swimlane: Cell,
w: number,
h: number,
parentHorizontal: boolean
): void {
const model = (<graph>this.graph).getModel(); const model = (<graph>this.graph).getModel();
model.beginUpdate(); model.beginUpdate();

View File

@ -4,7 +4,7 @@
* Updated to ES9 syntax by David Morrissey 2021 * Updated to ES9 syntax by David Morrissey 2021
* Type definitions from the typed-mxgraph project * Type definitions from the typed-mxgraph project
*/ */
import CellArray from 'core/view/cell/datatypes/CellArray'; import CellArray from '../../../../../view/cell/datatypes/CellArray';
import Cell from '../../../../cell/datatypes/Cell'; import Cell from '../../../../cell/datatypes/Cell';
class GraphAbstractHierarchyCell extends Cell { class GraphAbstractHierarchyCell extends Cell {

View File

@ -8,10 +8,9 @@ import EventSource from '../event/EventSource';
import UndoableEdit from './UndoableEdit'; import UndoableEdit from './UndoableEdit';
import CellPath from '../cell/datatypes/CellPath'; import CellPath from '../cell/datatypes/CellPath';
import Cell from '../cell/datatypes/Cell'; import Cell from '../cell/datatypes/Cell';
import utils, { isNumeric } from '../../util/Utils'; import { isNumeric } from '../../util/Utils';
import EventObject from '../event/EventObject'; import EventObject from '../event/EventObject';
import InternalEvent from '../event/InternalEvent'; import InternalEvent from '../event/InternalEvent';
import Point from '../geometry/Point';
import ChildChange from './ChildChange'; import ChildChange from './ChildChange';
import CollapseChange from '../folding/CollapseChange'; import CollapseChange from '../folding/CollapseChange';
import GeometryChange from '../geometry/GeometryChange'; import GeometryChange from '../geometry/GeometryChange';
@ -23,7 +22,7 @@ import VisibleChange from '../style/VisibleChange';
import Geometry from '../geometry/Geometry'; import Geometry from '../geometry/Geometry';
import CellArray from '../cell/datatypes/CellArray'; import CellArray from '../cell/datatypes/CellArray';
import type { CellMap, FilterFunction, UndoableChange } from '../../types'; import type { FilterFunction } from '../../types';
/** /**
* Extends {@link EventSource} to implement a graph model. The graph model acts as * Extends {@link EventSource} to implement a graph model. The graph model acts as
@ -209,6 +208,7 @@ import type { CellMap, FilterFunction, UndoableChange } from '../../types';
class Model extends EventSource { class Model extends EventSource {
constructor(root: Cell | null = null) { constructor(root: Cell | null = null) {
super(); super();
this.currentEdit = this.createUndoableEdit(); this.currentEdit = this.createUndoableEdit();
if (root != null) { if (root != null) {
@ -1159,8 +1159,5 @@ class Model extends EventSource {
} }
} }
//
// Atomic changes
//
export default Model; export default Model;
// import('../../serialization/mxModelCodec'); // import('../../serialization/mxModelCodec');

View File

@ -157,8 +157,8 @@ class GraphSelection extends autoImplement<PartialClass>() {
* *
* @param cell {@link mxCell} to add to the selection. * @param cell {@link mxCell} to add to the selection.
*/ */
addCell(cell: Cell) { addCellToSelection(cell: Cell) {
this.addCells(new CellArray(cell)); this.addCellsToSelection(new CellArray(cell));
} }
/** /**
@ -167,7 +167,7 @@ class GraphSelection extends autoImplement<PartialClass>() {
* *
* @param cells Array of {@link Cell} to add to the selection. * @param cells Array of {@link Cell} to add to the selection.
*/ */
addCells(cells: CellArray) { addCellsToSelection(cells: CellArray) {
let remove = null; let remove = null;
if (this.singleSelection) { if (this.singleSelection) {
remove = this.cells; remove = this.cells;
@ -193,8 +193,8 @@ class GraphSelection extends autoImplement<PartialClass>() {
* *
* @param cell {@link mxCell} to remove from the selection. * @param cell {@link mxCell} to remove from the selection.
*/ */
removeCell(cell: Cell) { removeCellFromSelection(cell: Cell) {
this.removeCells(new CellArray(cell)); this.removeCellsFromSelection(new CellArray(cell));
} }
/** /**
@ -203,7 +203,7 @@ class GraphSelection extends autoImplement<PartialClass>() {
* *
* @param cells {@link mxCell}s to remove from the selection. * @param cells {@link mxCell}s to remove from the selection.
*/ */
removeCells(cells: CellArray) { removeCellsFromSelection(cells: CellArray) {
const tmp = new CellArray(); const tmp = new CellArray();
for (let i = 0; i < cells.length; i += 1) { for (let i = 0; i < cells.length; i += 1) {
@ -337,7 +337,7 @@ class GraphSelection extends autoImplement<PartialClass>() {
* @param cell {@link mxCell} to be add to the selection. * @param cell {@link mxCell} to be add to the selection.
*/ */
addSelectionCell(cell: Cell) { addSelectionCell(cell: Cell) {
this.addCell(cell); this.addCellToSelection(cell);
} }
/** /**
@ -346,7 +346,7 @@ class GraphSelection extends autoImplement<PartialClass>() {
* @param cells Array of {@link Cell} to be added to the selection. * @param cells Array of {@link Cell} to be added to the selection.
*/ */
addSelectionCells(cells: CellArray) { addSelectionCells(cells: CellArray) {
this.addCells(cells); this.addCellsToSelection(cells);
} }
/** /**
@ -355,7 +355,7 @@ class GraphSelection extends autoImplement<PartialClass>() {
* @param cell {@link mxCell} to be removed from the selection. * @param cell {@link mxCell} to be removed from the selection.
*/ */
removeSelectionCell(cell: Cell) { removeSelectionCell(cell: Cell) {
this.removeCell(cell); this.removeCellFromSelection(cell);
} }
/** /**
@ -364,7 +364,7 @@ class GraphSelection extends autoImplement<PartialClass>() {
* @param cells Array of {@link Cell} to be removed from the selection. * @param cells Array of {@link Cell} to be removed from the selection.
*/ */
removeSelectionCells(cells: CellArray) { removeSelectionCells(cells: CellArray) {
this.removeCells(cells); this.removeCellsFromSelection(cells);
} }
/** /**
@ -424,7 +424,7 @@ class GraphSelection extends autoImplement<PartialClass>() {
this.clear(); this.clear();
} }
const parent = cell ? cell.getParent() : this.getDefaultParent(); const parent = cell ? (cell.getParent() as Cell) : this.getDefaultParent();
const childCount = parent.getChildCount(); const childCount = parent.getChildCount();
if (!cell && childCount > 0) { if (!cell && childCount > 0) {
@ -516,13 +516,15 @@ class GraphSelection extends autoImplement<PartialClass>() {
selectGroups = false selectGroups = false
) { ) {
const filter = (cell: Cell) => { const filter = (cell: Cell) => {
const p = cell.getParent();
return ( return (
!!this.getView().getState(cell) && !!this.getView().getState(cell) &&
(((selectGroups || cell.getChildCount() === 0) && (((selectGroups || cell.getChildCount() === 0) &&
cell.isVertex() && cell.isVertex() &&
vertices && vertices &&
cell.getParent() && p &&
!cell.getParent().isEdge()) || !p.isEdge()) ||
(cell.isEdge() && edges)) (cell.isEdge() && edges))
); );
}; };
@ -573,7 +575,7 @@ class GraphSelection extends autoImplement<PartialClass>() {
* Returns true if any sibling of the given cell is selected. * Returns true if any sibling of the given cell is selected.
*/ */
isSiblingSelected(cell: Cell) { isSiblingSelected(cell: Cell) {
const parent = cell.getParent(); const parent = cell.getParent() as Cell;
const childCount = parent.getChildCount(); const childCount = parent.getChildCount();
for (let i = 0; i < childCount; i += 1) { for (let i = 0; i < childCount; i += 1) {

View File

@ -9,9 +9,9 @@ type PartialClass = PartialGraph;
class GraphSnap extends autoImplement<PartialClass>() { class GraphSnap extends autoImplement<PartialClass>() {
// TODO: Document me! // TODO: Document me!
tolerance: number = 0; snapTolerance: number = 0;
getSnapTolerance = () => this.tolerance; getSnapTolerance = () => this.snapTolerance;
/** /**
* Specifies the grid size. * Specifies the grid size.
@ -142,14 +142,14 @@ class GraphSnap extends autoImplement<PartialClass>() {
* Returns {@link tolerance}. * Returns {@link tolerance}.
*/ */
getTolerance() { getTolerance() {
return this.tolerance; return this.snapTolerance;
} }
/** /**
* Sets {@link tolerance}. * Sets {@link tolerance}.
*/ */
setTolerance(value: number) { setTolerance(value: number) {
this.tolerance = value; this.snapTolerance = value;
} }
} }

View File

@ -883,7 +883,8 @@ class GraphView extends EventSource {
state.length = 0; state.length = 0;
if (state.cell !== this.currentRoot) { if (state.cell !== this.currentRoot) {
const pState = this.getState(state.cell.getParent()); const parent = state.cell.getParent();
const pState = parent ? this.getState(parent) : null;
if (pState && pState.cell !== this.currentRoot) { if (pState && pState.cell !== this.currentRoot) {
origin.x += pState.origin.x; origin.x += pState.origin.x;
@ -947,7 +948,8 @@ class GraphView extends EventSource {
* Validates the given cell state. * Validates the given cell state.
*/ */
updateVertexState(state: CellState, geo: Geometry) { updateVertexState(state: CellState, geo: Geometry) {
const pState = this.getState(state.cell.getParent()); const parent = state.cell.getParent();
const pState = parent ? this.getState(parent) : null;
if (geo.relative && pState && !pState.cell.isEdge()) { if (geo.relative && pState && !pState.cell.isEdge()) {
const alpha = toRadians(pState.style.rotation); const alpha = toRadians(pState.style.rotation);

View File

@ -6,15 +6,10 @@ const CircularDependencyPlugin = require('circular-dependency-plugin');
module.exports = merge(base, { module.exports = merge(base, {
entry: './src/index.ts', entry: './src/index.ts',
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
},
},
output: { output: {
filename: 'mxgraph.js', filename: 'maxgraph.js',
path: path.resolve(__dirname, 'dist'), path: path.resolve(__dirname, 'dist'),
library: 'mxgraph', library: 'maxgraph',
libraryTarget: 'umd', libraryTarget: 'umd',
}, },
module: { module: {

View File

@ -1,7 +1,6 @@
import maxgraph from '@maxgraph/core'; import maxgraph from '@maxgraph/core';
import { globalTypes } from '../.storybook/preview'; import { globalTypes } from '../.storybook/preview';
import { error } from '@maxgraph/core/util/DomUtils';
import { clone } from '@maxgraph/core/util/CloneUtils'; import { clone } from '@maxgraph/core/util/CloneUtils';
import { button } from '@maxgraph/core/util/dom/mxDomHelpers'; import { button } from '@maxgraph/core/util/dom/mxDomHelpers';
import { load } from '@maxgraph/core/util/network/mxXmlRequest'; import { load } from '@maxgraph/core/util/network/mxXmlRequest';
@ -35,7 +34,7 @@ const Template = ({ label, ...args }) => {
if (!mxClient.isBrowserSupported()) { if (!mxClient.isBrowserSupported()) {
// Displays an error message if the browser is // Displays an error message if the browser is
// not supported. // not supported.
error('Browser is not supported!', 200, false); alert('Browser is not supported!', 200, false);
} else { } else {
// Creates the graph inside the given container // Creates the graph inside the given container
const graph = new Graph(container); const graph = new Graph(container);

View File

@ -1,4 +1,5 @@
import maxgraph from '@maxgraph/core'; import Graph from '@maxgraph/core/view/Graph';
import InternalEvent from '@maxgraph/core/view/event/InternalEvent';
import { globalTypes } from '../.storybook/preview'; import { globalTypes } from '../.storybook/preview';
@ -18,8 +19,6 @@ export default {
}; };
const Template = ({ label, ...args }) => { const Template = ({ label, ...args }) => {
const { Graph, InternalEvent, Rubberband } = maxgraph;
console.log(maxgraph, Graph);
const container = document.createElement('div'); const container = document.createElement('div');
container.style.position = 'relative'; container.style.position = 'relative';
container.style.overflow = 'hidden'; container.style.overflow = 'hidden';
@ -29,10 +28,10 @@ const Template = ({ label, ...args }) => {
container.style.cursor = 'default'; container.style.cursor = 'default';
if (!args.contextMenu) InternalEvent.disableContextMenu(container); if (!args.contextMenu) InternalEvent.disableContextMenu(container);
console.log(Graph, Graph.prototype);
const graph = new Graph(container); const graph = new Graph(container);
if (args.rubberBand) new Rubberband(graph); // if (args.rubberBand) new Rubberband(graph);
const parent = graph.getDefaultParent(); const parent = graph.getDefaultParent();

View File

@ -6,18 +6,15 @@
"esModuleInterop": true, "esModuleInterop": true,
"isolatedModules": true, "isolatedModules": true,
"jsx": "preserve", "jsx": "preserve",
"module": "es2020", "module": "umd",
"lib": ["es2020", "dom"], "lib": ["dom"],
"moduleResolution": "node", "moduleResolution": "node",
"noEmit": true, "noEmit": true,
"strict": true, "strict": true,
"target": "es2020", "target": "es5",
"resolveJsonModule": true, // Required for JSON files "resolveJsonModule": true, // Required for JSON files
"skipLibCheck": true, "skipLibCheck": true,
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true
"paths": {
"core/*": ["./packages/core/src/*"]
}
}, },
"exclude": [ "exclude": [
"node_modules", "node_modules",

View File

@ -1,5 +1,3 @@
const path = require('path');
module.exports = { module.exports = {
devtool: 'eval-source-map', devtool: 'eval-source-map',
module: { module: {
@ -17,9 +15,6 @@ module.exports = {
], ],
}, },
resolve: { resolve: {
alias: {
core: path.resolve(__dirname, 'packages/core/src'),
},
extensions: ['.ts', '.js', '.css'], extensions: ['.ts', '.js', '.css'],
}, },
}; };