@html-graph/html-graph 8.15.1 → 8.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -619,6 +619,7 @@ const canvasErrorText = Object.freeze({
619
619
  removeNonexistentPort: (portId) => `Failed to remove port with ID ${JSON.stringify(portId)} because it does not exist`,
620
620
  accessNonexistentEdge: (edgeId) => `Failed to access edge with ID ${JSON.stringify(edgeId)} because it does not exist`,
621
621
  addEdgeWithExistingId: (edgeId) => `Failed to add edge with ID ${JSON.stringify(edgeId)} because an edge with this ID already exists`,
622
+ addEdgeWithElementInUse: (edgeId, useEdgeId) => `Failed to add edge with ID ${JSON.stringify(edgeId)} because its SVG element is already attached to edge with ID ${JSON.stringify(useEdgeId)}`,
622
623
  addEdgeFromNonexistentPort: (edgeId, portId) => `Failed to add edge with ID ${JSON.stringify(edgeId)} from port with ID ${JSON.stringify(portId)} because the port does not exist`,
623
624
  addEdgeToNonexistentPort: (edgeId, portId) => `Failed to add edge with ID ${JSON.stringify(edgeId)} to port with ID ${JSON.stringify(portId)} because the port does not exist`,
624
625
  updateNonexistentEdge: (edgeId) => `Failed to update edge with ID ${JSON.stringify(edgeId)} because it does not exist`,
@@ -637,6 +638,7 @@ class GraphStore {
637
638
  __publicField(this, "portOutgoingEdges", /* @__PURE__ */ new Map());
638
639
  __publicField(this, "portCycleEdges", /* @__PURE__ */ new Map());
639
640
  __publicField(this, "elementPorts", new OneToManyCollection());
641
+ __publicField(this, "edgesElementsMap", /* @__PURE__ */ new Map());
640
642
  __publicField(this, "afterNodeAddedEmitter");
641
643
  __publicField(this, "onAfterNodeAdded");
642
644
  __publicField(this, "afterNodeUpdatedEmitter");
@@ -817,6 +819,9 @@ class GraphStore {
817
819
  }
818
820
  return edge;
819
821
  }
822
+ findEdgeIdByElement(element) {
823
+ return this.edgesElementsMap.get(element);
824
+ }
820
825
  addEdge(request) {
821
826
  if (this.hasEdge(request.id)) {
822
827
  throw new CanvasError(canvasErrorText.addEdgeWithExistingId(request.id));
@@ -831,6 +836,12 @@ class GraphStore {
831
836
  canvasErrorText.addEdgeToNonexistentPort(request.id, request.to)
832
837
  );
833
838
  }
839
+ const useEdgeId = this.findEdgeIdByElement(request.shape.svg);
840
+ if (useEdgeId !== void 0) {
841
+ throw new CanvasError(
842
+ canvasErrorText.addEdgeWithElementInUse(request.id, useEdgeId)
843
+ );
844
+ }
834
845
  this.addEdgeInternal(request);
835
846
  this.afterEdgeAddedEmitter.emit(request.id);
836
847
  }
@@ -888,6 +899,7 @@ class GraphStore {
888
899
  this.portCycleEdges.clear();
889
900
  this.elementPorts.clear();
890
901
  this.nodesElementsMap.clear();
902
+ this.edgesElementsMap.clear();
891
903
  this.edges.clear();
892
904
  this.ports.clear();
893
905
  this.nodes.clear();
@@ -996,6 +1008,7 @@ class GraphStore {
996
1008
  priority: request.priority
997
1009
  }
998
1010
  });
1011
+ this.edgesElementsMap.set(request.shape.svg, request.id);
999
1012
  if (request.from !== request.to) {
1000
1013
  this.portOutgoingEdges.get(request.from).add(request.id);
1001
1014
  this.portIncomingEdges.get(request.to).add(request.id);
@@ -1004,7 +1017,7 @@ class GraphStore {
1004
1017
  }
1005
1018
  }
1006
1019
  removeEdgeInternal(edgeId) {
1007
- const { from, to } = this.getEdge(edgeId);
1020
+ const { from, to, payload } = this.getEdge(edgeId);
1008
1021
  this.portCycleEdges.get(from).delete(edgeId);
1009
1022
  this.portCycleEdges.get(to).delete(edgeId);
1010
1023
  this.portIncomingEdges.get(from).delete(edgeId);
@@ -1012,6 +1025,7 @@ class GraphStore {
1012
1025
  this.portOutgoingEdges.get(from).delete(edgeId);
1013
1026
  this.portOutgoingEdges.get(to).delete(edgeId);
1014
1027
  this.edges.delete(edgeId);
1028
+ this.edgesElementsMap.delete(payload.shape.svg);
1015
1029
  }
1016
1030
  }
1017
1031
  const calculateReverseMatrix = (matrix) => {
@@ -2673,6 +2687,11 @@ class InteractiveEdgeShape {
2673
2687
  __publicField(this, "line");
2674
2688
  __publicField(this, "sourceArrow");
2675
2689
  __publicField(this, "targetArrow");
2690
+ // TODO: make private
2691
+ /**
2692
+ * @deprecated
2693
+ * do use shape.svg instead
2694
+ */
2676
2695
  __publicField(this, "handle", createEdgeGroup());
2677
2696
  __publicField(this, "onAfterRender");
2678
2697
  __publicField(this, "interactiveLine");
@@ -2829,6 +2848,9 @@ class Graph {
2829
2848
  shape: payload.shape
2830
2849
  };
2831
2850
  }
2851
+ findEdgeIdByElement(element) {
2852
+ return this.graphStore.findEdgeIdByElement(element);
2853
+ }
2832
2854
  getPortIncomingEdgeIds(portId) {
2833
2855
  return this.graphStore.getPortIncomingEdgeIds(portId);
2834
2856
  }
@@ -3283,11 +3305,11 @@ class DraggablePortsConfigurator {
3283
3305
  }
3284
3306
  const target = event.currentTarget;
3285
3307
  const portId = this.canvas.graph.findPortIdsByElement(target)[0];
3286
- const accepted = this.params.onPortPointerDown(portId, {
3308
+ const dragAllowed = this.params.portDragAllowedVerifier(portId, {
3287
3309
  x: mouseEvent.clientX,
3288
3310
  y: mouseEvent.clientY
3289
3311
  });
3290
- if (!accepted) {
3312
+ if (!dragAllowed) {
3291
3313
  return;
3292
3314
  }
3293
3315
  event.stopPropagation();
@@ -3304,8 +3326,8 @@ class DraggablePortsConfigurator {
3304
3326
  event.clientY
3305
3327
  );
3306
3328
  if (!isInside) {
3307
- this.params.onPointerMoveOutside();
3308
- this.stopMouseDrag();
3329
+ this.removeWindowMouseListeners();
3330
+ this.params.onPointerOutside();
3309
3331
  return;
3310
3332
  }
3311
3333
  this.params.onPointerMove({ x: event.clientX, y: event.clientY });
@@ -3314,8 +3336,8 @@ class DraggablePortsConfigurator {
3314
3336
  if (!this.params.mouseUpEventVerifier(event)) {
3315
3337
  return;
3316
3338
  }
3339
+ this.removeWindowMouseListeners();
3317
3340
  this.params.onPointerUp({ x: event.clientX, y: event.clientY });
3318
- this.stopMouseDrag();
3319
3341
  });
3320
3342
  __publicField(this, "onPortTouchStart", (event) => {
3321
3343
  const touchEvent = event;
@@ -3325,11 +3347,11 @@ class DraggablePortsConfigurator {
3325
3347
  const touch = touchEvent.touches[0];
3326
3348
  const target = event.currentTarget;
3327
3349
  const portId = this.canvas.graph.findPortIdsByElement(target)[0];
3328
- const accepted = this.params.onPortPointerDown(portId, {
3350
+ const dragAllowed = this.params.portDragAllowedVerifier(portId, {
3329
3351
  x: touch.clientX,
3330
3352
  y: touch.clientY
3331
3353
  });
3332
- if (!accepted) {
3354
+ if (!dragAllowed) {
3333
3355
  return;
3334
3356
  }
3335
3357
  event.stopPropagation();
@@ -3350,16 +3372,16 @@ class DraggablePortsConfigurator {
3350
3372
  touch.clientY
3351
3373
  );
3352
3374
  if (!isInside) {
3353
- this.params.onPointerMoveOutside();
3354
- this.stopTouchDrag();
3375
+ this.removeWindowTouchListeners();
3376
+ this.params.onPointerOutside();
3355
3377
  return;
3356
3378
  }
3357
3379
  this.params.onPointerMove({ x: touch.clientX, y: touch.clientY });
3358
3380
  });
3359
3381
  __publicField(this, "onWindowTouchFinish", (event) => {
3382
+ this.removeWindowTouchListeners();
3360
3383
  const touch = event.changedTouches[0];
3361
3384
  this.params.onPointerUp({ x: touch.clientX, y: touch.clientY });
3362
- this.stopTouchDrag();
3363
3385
  });
3364
3386
  __publicField(this, "reset", () => {
3365
3387
  this.canvas.graph.getAllPortIds().forEach((portId) => {
@@ -3368,10 +3390,9 @@ class DraggablePortsConfigurator {
3368
3390
  });
3369
3391
  });
3370
3392
  __publicField(this, "revert", () => {
3371
- this.params.onStopDrag();
3372
- this.reset();
3373
3393
  this.removeWindowMouseListeners();
3374
3394
  this.removeWindowTouchListeners();
3395
+ this.reset();
3375
3396
  });
3376
3397
  this.canvas = canvas;
3377
3398
  this.window = window2;
@@ -3397,14 +3418,6 @@ class DraggablePortsConfigurator {
3397
3418
  element.removeEventListener("mousedown", this.onPortMouseDown);
3398
3419
  element.removeEventListener("touchstart", this.onPortTouchStart);
3399
3420
  }
3400
- stopMouseDrag() {
3401
- this.params.onStopDrag();
3402
- this.removeWindowMouseListeners();
3403
- }
3404
- stopTouchDrag() {
3405
- this.params.onStopDrag();
3406
- this.removeWindowTouchListeners();
3407
- }
3408
3421
  removeWindowMouseListeners() {
3409
3422
  this.window.removeEventListener("mousemove", this.onWindowMouseMove);
3410
3423
  this.window.removeEventListener("mouseup", this.onWindowMouseUp);
@@ -3415,45 +3428,161 @@ class DraggablePortsConfigurator {
3415
3428
  this.window.removeEventListener("touchcancel", this.onWindowTouchFinish);
3416
3429
  }
3417
3430
  }
3418
- class LayoutApplier {
3419
- constructor(canvas, layoutAlgorithm, params) {
3420
- this.canvas = canvas;
3421
- this.layoutAlgorithm = layoutAlgorithm;
3422
- this.params = params;
3431
+ class EventTagger {
3432
+ constructor() {
3433
+ __publicField(this, "field", "_htmlGraphTags");
3434
+ }
3435
+ has(event, tag) {
3436
+ const e = event;
3437
+ const tags = e[this.field];
3438
+ return tags !== void 0 && tags.has(tag);
3439
+ }
3440
+ tag(event, tag) {
3441
+ const e = event;
3442
+ const tags = e[this.field];
3443
+ if (tags === void 0) {
3444
+ e[this.field] = /* @__PURE__ */ new Set([tag]);
3445
+ } else {
3446
+ tags.add(tag);
3447
+ }
3423
3448
  }
3424
- apply() {
3425
- const coords = this.layoutAlgorithm.calculateCoordinates({
3426
- graph: this.canvas.graph,
3427
- viewport: this.canvas.viewport
3449
+ }
3450
+ const selectionHandled = Symbol();
3451
+ class UserSelectableElementsConfigurator {
3452
+ constructor(window2, pointInsideVerifier, params) {
3453
+ __publicField(this, "onSelected");
3454
+ __publicField(this, "mouseDownEventVerifier");
3455
+ __publicField(this, "mouseUpEventVerifier");
3456
+ __publicField(this, "movementThreshold");
3457
+ __publicField(this, "selectionCandidate", null);
3458
+ __publicField(this, "previousMouse", null);
3459
+ __publicField(this, "previousTouch", null);
3460
+ __publicField(this, "movedDistance", 0);
3461
+ __publicField(this, "onElementMouseDown", (event) => {
3462
+ const mouseEvent = event;
3463
+ if (!this.mouseDownEventVerifier(mouseEvent)) {
3464
+ return;
3465
+ }
3466
+ this.selectionCandidate = mouseEvent.currentTarget;
3467
+ this.previousMouse = { x: mouseEvent.clientX, y: mouseEvent.clientY };
3468
+ this.movedDistance = 0;
3469
+ this.window.addEventListener("mousemove", this.onWindowMouseMove, {
3470
+ passive: true
3471
+ });
3472
+ this.window.addEventListener("mouseup", this.onWindowMouseUp, {
3473
+ passive: true
3474
+ });
3428
3475
  });
3429
- this.params.onBeforeApplied();
3430
- coords.forEach((point, nodeId) => {
3431
- if (!this.params.staticNodeResolver(nodeId)) {
3432
- this.canvas.updateNode(nodeId, point);
3476
+ __publicField(this, "onElementTouchStart", (event) => {
3477
+ const touchEvent = event;
3478
+ const touches = touchEvent.touches;
3479
+ if (touches.length !== 1) {
3480
+ return;
3481
+ }
3482
+ this.selectionCandidate = touchEvent.currentTarget;
3483
+ this.previousTouch = touches[0];
3484
+ this.movedDistance = 0;
3485
+ this.window.addEventListener("touchmove", this.onWindowTouchMove, {
3486
+ passive: true
3487
+ });
3488
+ this.window.addEventListener("touchend", this.onWindowTouchEnd, {
3489
+ passive: true
3490
+ });
3491
+ this.window.addEventListener("touchcancel", this.onWindowTouchCancel, {
3492
+ passive: true
3493
+ });
3494
+ });
3495
+ __publicField(this, "onWindowMouseMove", (event) => {
3496
+ const mouseEvent = event;
3497
+ const inside = this.pointInsideVerifier.verify(
3498
+ mouseEvent.clientX,
3499
+ mouseEvent.clientY
3500
+ );
3501
+ if (!inside) {
3502
+ this.removeWindowMouseListeners();
3503
+ return;
3433
3504
  }
3505
+ const previousMouse = this.previousMouse;
3506
+ const x = mouseEvent.clientX - previousMouse.x;
3507
+ const y = mouseEvent.clientY - previousMouse.y;
3508
+ this.previousMouse = { x: mouseEvent.clientX, y: mouseEvent.clientY };
3509
+ this.processMoveThresholdVerification(x, y, () => {
3510
+ this.removeWindowMouseListeners();
3511
+ });
3434
3512
  });
3435
- this.params.onAfterApplied();
3436
- }
3437
- }
3438
- class AnimatedLayoutApplier {
3439
- constructor(canvas, layoutAlgorithm, params) {
3440
- this.canvas = canvas;
3441
- this.layoutAlgorithm = layoutAlgorithm;
3442
- this.params = params;
3443
- }
3444
- apply(dt) {
3445
- const coords = this.layoutAlgorithm.calculateNextCoordinates({
3446
- graph: this.canvas.graph,
3447
- viewport: this.canvas.viewport,
3448
- dt
3513
+ __publicField(this, "onWindowMouseUp", (event) => {
3514
+ const mouseEvent = event;
3515
+ if (!this.mouseUpEventVerifier(mouseEvent)) {
3516
+ return;
3517
+ }
3518
+ this.removeWindowMouseListeners();
3519
+ this.onSelected(this.selectionCandidate, event);
3449
3520
  });
3450
- this.params.onBeforeApplied();
3451
- coords.forEach((point, nodeId) => {
3452
- if (!this.params.staticNodeResolver(nodeId)) {
3453
- this.canvas.updateNode(nodeId, point);
3521
+ __publicField(this, "onWindowTouchMove", (event) => {
3522
+ const touchEvent = event;
3523
+ const touches = touchEvent.touches;
3524
+ if (touches.length !== 1) {
3525
+ this.removeWindowTouchListeners();
3526
+ return;
3527
+ }
3528
+ const touch = touches[0];
3529
+ const inside = this.pointInsideVerifier.verify(
3530
+ touch.clientX,
3531
+ touch.clientY
3532
+ );
3533
+ if (!inside) {
3534
+ this.removeWindowTouchListeners();
3535
+ return;
3454
3536
  }
3537
+ const previousTouch = this.previousTouch;
3538
+ const x = touch.clientX - previousTouch.clientX;
3539
+ const y = touch.clientY - previousTouch.clientY;
3540
+ this.previousTouch = touch;
3541
+ this.processMoveThresholdVerification(x, y, () => {
3542
+ this.removeWindowTouchListeners();
3543
+ });
3455
3544
  });
3456
- this.params.onAfterApplied();
3545
+ __publicField(this, "onWindowTouchEnd", (event) => {
3546
+ this.removeWindowTouchListeners();
3547
+ this.onSelected(this.selectionCandidate, event);
3548
+ });
3549
+ __publicField(this, "onWindowTouchCancel", () => {
3550
+ this.removeWindowTouchListeners();
3551
+ });
3552
+ this.window = window2;
3553
+ this.pointInsideVerifier = pointInsideVerifier;
3554
+ this.mouseDownEventVerifier = params.mouseDownEventVerifier;
3555
+ this.mouseUpEventVerifier = params.mouseUpEventVerifier;
3556
+ this.onSelected = params.onSelected;
3557
+ this.movementThreshold = params.movementThreshold;
3558
+ }
3559
+ enable(element) {
3560
+ element.addEventListener("mousedown", this.onElementMouseDown);
3561
+ element.addEventListener("touchstart", this.onElementTouchStart);
3562
+ }
3563
+ disable(element) {
3564
+ element.removeEventListener("mousedown", this.onElementMouseDown);
3565
+ element.removeEventListener("touchstart", this.onElementTouchStart);
3566
+ if (element === this.selectionCandidate) {
3567
+ this.removeWindowMouseListeners();
3568
+ this.removeWindowTouchListeners();
3569
+ }
3570
+ }
3571
+ removeWindowMouseListeners() {
3572
+ this.window.removeEventListener("mousemove", this.onWindowMouseMove);
3573
+ this.window.removeEventListener("mouseup", this.onWindowMouseUp);
3574
+ }
3575
+ removeWindowTouchListeners() {
3576
+ this.window.removeEventListener("touchmove", this.onWindowTouchMove);
3577
+ this.window.removeEventListener("touchend", this.onWindowTouchEnd);
3578
+ this.window.removeEventListener("touchcancel", this.onWindowTouchCancel);
3579
+ }
3580
+ processMoveThresholdVerification(x, y, thresholdReachedCallback) {
3581
+ const distance = Math.sqrt(x * x + y * y);
3582
+ this.movedDistance += distance;
3583
+ if (this.movedDistance > this.movementThreshold) {
3584
+ thresholdReachedCallback();
3585
+ }
3457
3586
  }
3458
3587
  }
3459
3588
  class UserDraggableNodesConfigurator {
@@ -4193,34 +4322,39 @@ class UserConnectablePortsConfigurator {
4193
4322
  this.viewportStore,
4194
4323
  this.window
4195
4324
  );
4325
+ const draggablePortsParams = {
4326
+ mouseDownEventVerifier: this.params.mouseDownEventVerifier,
4327
+ mouseUpEventVerifier: this.params.mouseUpEventVerifier,
4328
+ portDragAllowedVerifier: (portId, cursor) => {
4329
+ const connectionType = this.params.connectionTypeResolver(portId);
4330
+ if (connectionType === null) {
4331
+ return false;
4332
+ }
4333
+ this.grabPort(portId, cursor, connectionType);
4334
+ return true;
4335
+ },
4336
+ onPointerMove: (cursor) => {
4337
+ this.moveDraggingPort(cursor);
4338
+ },
4339
+ onPointerUp: (cursor) => {
4340
+ this.tryCreateConnection(cursor);
4341
+ this.resetDragState();
4342
+ },
4343
+ onPointerOutside: () => {
4344
+ const staticPortId = this.staticPortId;
4345
+ const isTargetDragging = this.isTargetDragging;
4346
+ this.resetDragState();
4347
+ this.params.onEdgeCreationInterrupted({
4348
+ staticPortId,
4349
+ isDirect: isTargetDragging
4350
+ });
4351
+ }
4352
+ };
4196
4353
  DraggablePortsConfigurator.configure(
4197
4354
  this.canvas,
4198
4355
  this.window,
4199
4356
  this.pointInsideVerifier,
4200
- {
4201
- mouseDownEventVerifier: this.params.mouseDownEventVerifier,
4202
- mouseUpEventVerifier: this.params.mouseUpEventVerifier,
4203
- onStopDrag: () => {
4204
- this.resetDragState();
4205
- },
4206
- onPortPointerDown: (portId, cursor) => {
4207
- const connectionType = this.params.connectionTypeResolver(portId);
4208
- if (connectionType === null) {
4209
- return false;
4210
- }
4211
- this.grabPort(portId, cursor, connectionType);
4212
- return true;
4213
- },
4214
- onPointerMove: (cursor) => {
4215
- this.moveDraggingPort(cursor);
4216
- },
4217
- onPointerMoveOutside: () => {
4218
- this.handleEdgeCreationInterrupted();
4219
- },
4220
- onPointerUp: (cursor) => {
4221
- this.tryCreateConnection(cursor);
4222
- }
4223
- }
4357
+ draggablePortsParams
4224
4358
  );
4225
4359
  }
4226
4360
  static configure(canvas, overlayLayer, viewportStore, win, pointInsideVerifier, params) {
@@ -4276,15 +4410,19 @@ class UserConnectablePortsConfigurator {
4276
4410
  tryCreateConnection(cursor) {
4277
4411
  const draggingPortId = findPortAtPoint(this.canvas.graph, cursor);
4278
4412
  if (draggingPortId === null) {
4279
- this.handleEdgeCreationInterrupted();
4413
+ this.params.onEdgeCreationInterrupted({
4414
+ staticPortId: this.staticPortId,
4415
+ isDirect: this.isTargetDragging
4416
+ });
4280
4417
  return;
4281
4418
  }
4282
4419
  const staticPortId = this.staticPortId;
4283
4420
  const sourceId = this.isTargetDragging ? staticPortId : draggingPortId;
4284
4421
  const targetId = this.isTargetDragging ? draggingPortId : staticPortId;
4285
4422
  const request = { from: sourceId, to: targetId };
4423
+ const connectionAllowed = this.params.connectionAllowedVerifier(request);
4286
4424
  const processedRequest = this.params.connectionPreprocessor(request);
4287
- if (processedRequest !== null) {
4425
+ if (connectionAllowed && processedRequest !== null) {
4288
4426
  this.canvas.graph.onAfterEdgeAdded.subscribe(this.onEdgeCreated);
4289
4427
  this.canvas.addEdge(processedRequest);
4290
4428
  this.canvas.graph.onAfterEdgeAdded.unsubscribe(this.onEdgeCreated);
@@ -4303,13 +4441,6 @@ class UserConnectablePortsConfigurator {
4303
4441
  y: nodeContentCoords.y
4304
4442
  });
4305
4443
  }
4306
- handleEdgeCreationInterrupted() {
4307
- const staticPortId = this.staticPortId;
4308
- this.params.onEdgeCreationInterrupted({
4309
- staticPortId,
4310
- isDirect: this.isTargetDragging
4311
- });
4312
- }
4313
4444
  }
4314
4445
  class UserDraggableEdgesConfigurator {
4315
4446
  constructor(canvas, overlayLayer, viewportStore, window2, pointInsideVerifier, params) {
@@ -4331,38 +4462,36 @@ class UserDraggableEdgesConfigurator {
4331
4462
  this.viewportStore,
4332
4463
  this.window
4333
4464
  );
4465
+ const draggablePortsParams = {
4466
+ mouseDownEventVerifier: this.params.mouseDownEventVerifier,
4467
+ mouseUpEventVerifier: this.params.mouseUpEventVerifier,
4468
+ portDragAllowedVerifier: (portId, cursor) => {
4469
+ return this.tryStartEdgeDragging(portId, cursor);
4470
+ },
4471
+ onPointerMove: (cursor) => {
4472
+ this.moveDraggingPort(cursor);
4473
+ },
4474
+ onPointerUp: (cursor) => {
4475
+ this.tryCreateConnection(cursor);
4476
+ this.resetDragState();
4477
+ },
4478
+ onPointerOutside: () => {
4479
+ const edge = this.draggingEdgePayload;
4480
+ this.resetDragState();
4481
+ this.params.onEdgeReattachInterrupted({
4482
+ id: edge.id,
4483
+ from: edge.from,
4484
+ to: edge.to,
4485
+ shape: edge.shape,
4486
+ priority: edge.priority
4487
+ });
4488
+ }
4489
+ };
4334
4490
  DraggablePortsConfigurator.configure(
4335
4491
  this.canvas,
4336
4492
  this.window,
4337
4493
  this.pointInsideVerifier,
4338
- {
4339
- mouseDownEventVerifier: this.params.mouseDownEventVerifier,
4340
- mouseUpEventVerifier: this.params.mouseUpEventVerifier,
4341
- onStopDrag: () => {
4342
- this.resetDragState();
4343
- },
4344
- onPortPointerDown: (portId, cursor) => {
4345
- return this.tryStartEdgeDragging(portId, cursor);
4346
- },
4347
- onPointerMove: (cursor) => {
4348
- this.moveDraggingPort(cursor);
4349
- },
4350
- onPointerMoveOutside: () => {
4351
- const edge = this.draggingEdgePayload;
4352
- queueMicrotask(() => {
4353
- this.params.onEdgeReattachInterrupted({
4354
- id: edge.id,
4355
- from: edge.from,
4356
- to: edge.to,
4357
- shape: edge.shape,
4358
- priority: edge.priority
4359
- });
4360
- });
4361
- },
4362
- onPointerUp: (cursor) => {
4363
- this.tryCreateConnection(cursor);
4364
- }
4365
- }
4494
+ draggablePortsParams
4366
4495
  );
4367
4496
  }
4368
4497
  static configure(canvas, overlayLayer, viewportStore, win, pointInsideVerifier, params) {
@@ -4377,7 +4506,7 @@ class UserDraggableEdgesConfigurator {
4377
4506
  }
4378
4507
  tryStartEdgeDragging(portId, cursor) {
4379
4508
  const edgeId = this.params.draggingEdgeResolver(portId);
4380
- if (edgeId === null || !this.canvas.graph.hasEdge(edgeId)) {
4509
+ if (edgeId === null) {
4381
4510
  return false;
4382
4511
  }
4383
4512
  const edge = this.canvas.graph.getEdge(edgeId);
@@ -4466,8 +4595,12 @@ class UserDraggableEdgesConfigurator {
4466
4595
  shape: edge.shape,
4467
4596
  priority: edge.priority
4468
4597
  };
4598
+ const connectionAllowed = this.params.connectionAllowedVerifier({
4599
+ from,
4600
+ to
4601
+ });
4469
4602
  const processedRequest = this.params.connectionPreprocessor(request);
4470
- if (processedRequest !== null) {
4603
+ if (connectionAllowed && processedRequest !== null) {
4471
4604
  this.canvas.graph.onAfterEdgeAdded.subscribe(this.onEdgeReattached);
4472
4605
  this.canvas.addEdge(processedRequest);
4473
4606
  this.canvas.graph.onAfterEdgeAdded.unsubscribe(this.onEdgeReattached);
@@ -4543,6 +4676,26 @@ class TopologyChangeAsyncLayoutApplicationStrategyConfigurator {
4543
4676
  this.defererFn(this.apply);
4544
4677
  }
4545
4678
  }
4679
+ class LayoutApplier {
4680
+ constructor(canvas, layoutAlgorithm, params) {
4681
+ this.canvas = canvas;
4682
+ this.layoutAlgorithm = layoutAlgorithm;
4683
+ this.params = params;
4684
+ }
4685
+ apply() {
4686
+ const coords = this.layoutAlgorithm.calculateCoordinates({
4687
+ graph: this.canvas.graph,
4688
+ viewport: this.canvas.viewport
4689
+ });
4690
+ this.params.onBeforeApplied();
4691
+ coords.forEach((point, nodeId) => {
4692
+ if (!this.params.staticNodeResolver(nodeId)) {
4693
+ this.canvas.updateNode(nodeId, point);
4694
+ }
4695
+ });
4696
+ this.params.onAfterApplied();
4697
+ }
4698
+ }
4546
4699
  class LayoutConfigurator {
4547
4700
  static configure(canvas, params) {
4548
4701
  const strategy = params.applyOn;
@@ -4588,6 +4741,27 @@ class AnimationSeries {
4588
4741
  this.win.requestAnimationFrame(this.step);
4589
4742
  }
4590
4743
  }
4744
+ class AnimatedLayoutApplier {
4745
+ constructor(canvas, layoutAlgorithm, params) {
4746
+ this.canvas = canvas;
4747
+ this.layoutAlgorithm = layoutAlgorithm;
4748
+ this.params = params;
4749
+ }
4750
+ apply(dt) {
4751
+ const coords = this.layoutAlgorithm.calculateNextCoordinates({
4752
+ graph: this.canvas.graph,
4753
+ viewport: this.canvas.viewport,
4754
+ dt
4755
+ });
4756
+ this.params.onBeforeApplied();
4757
+ coords.forEach((point, nodeId) => {
4758
+ if (!this.params.staticNodeResolver(nodeId)) {
4759
+ this.canvas.updateNode(nodeId, point);
4760
+ }
4761
+ });
4762
+ this.params.onAfterApplied();
4763
+ }
4764
+ }
4591
4765
  class AnimatedLayoutConfigurator {
4592
4766
  constructor(canvas, params, win) {
4593
4767
  __publicField(this, "applier");
@@ -4607,311 +4781,151 @@ class AnimatedLayoutConfigurator {
4607
4781
  }
4608
4782
  }
4609
4783
  class UserSelectableNodesConfigurator {
4610
- constructor(canvas, window2, pointInsideVerifier, params) {
4784
+ constructor(canvas, window2, pointInsideVerifier, eventTagger, params) {
4785
+ __publicField(this, "configurator");
4611
4786
  __publicField(this, "onNodeSelected");
4612
- __publicField(this, "mouseDownEventVerifier");
4613
- __publicField(this, "mouseUpEventVerifier");
4614
- __publicField(this, "movementThreshold");
4615
- __publicField(this, "selectionCandidateNodeId", null);
4616
- __publicField(this, "movedDistance", 0);
4617
- __publicField(this, "previousMouse", null);
4618
- __publicField(this, "previousTouch", null);
4787
+ __publicField(this, "selectionHandledTag", selectionHandled);
4619
4788
  __publicField(this, "onAfterNodeAdded", (nodeId) => {
4620
4789
  const { element } = this.canvas.graph.getNode(nodeId);
4621
- element.addEventListener("mousedown", this.onNodeMouseDown, {
4622
- passive: true
4623
- });
4624
- element.addEventListener("touchstart", this.onNodeTouchStart, {
4625
- passive: true
4626
- });
4790
+ this.configurator.enable(element);
4627
4791
  });
4628
4792
  __publicField(this, "onBeforeNodeRemoved", (nodeId) => {
4629
4793
  const { element } = this.canvas.graph.getNode(nodeId);
4630
- element.removeEventListener("mousedown", this.onNodeMouseDown);
4631
- element.removeEventListener("touchstart", this.onNodeTouchStart);
4794
+ this.configurator.disable(element);
4632
4795
  });
4633
4796
  __publicField(this, "reset", () => {
4634
4797
  this.canvas.graph.getAllNodeIds().forEach((nodeId) => {
4635
4798
  const { element } = this.canvas.graph.getNode(nodeId);
4636
- element.removeEventListener("mousedown", this.onNodeMouseDown);
4637
- element.removeEventListener("touchstart", this.onNodeTouchStart);
4799
+ this.configurator.disable(element);
4638
4800
  });
4639
4801
  });
4640
- __publicField(this, "revert", () => {
4641
- this.reset();
4642
- this.removeWindowMouseListeners();
4643
- this.removeWindowTouchListeners();
4644
- });
4645
- __publicField(this, "onNodeMouseDown", (event) => {
4646
- const mouseEvent = event;
4647
- if (!this.mouseDownEventVerifier(mouseEvent)) {
4648
- return;
4649
- }
4650
- const nodeId = this.canvas.graph.findNodeIdByElement(
4651
- event.currentTarget
4652
- );
4653
- this.selectionCandidateNodeId = nodeId;
4654
- this.previousMouse = { x: mouseEvent.clientX, y: mouseEvent.clientY };
4655
- this.movedDistance = 0;
4656
- this.window.addEventListener("mousemove", this.onWindowMouseMove, {
4657
- passive: true
4658
- });
4659
- this.window.addEventListener("mouseup", this.onWindowMouseUp, {
4660
- passive: true
4661
- });
4662
- });
4663
- __publicField(this, "onNodeTouchStart", (event) => {
4664
- const touchEvent = event;
4665
- if (touchEvent.touches.length !== 1) {
4666
- return;
4667
- }
4668
- const nodeId = this.canvas.graph.findNodeIdByElement(
4669
- touchEvent.currentTarget
4670
- );
4671
- this.selectionCandidateNodeId = nodeId;
4672
- this.previousTouch = touchEvent.touches[0];
4673
- this.movedDistance = 0;
4674
- this.window.addEventListener("touchmove", this.onWindowTouchMove, {
4675
- passive: true
4676
- });
4677
- this.window.addEventListener("touchend", this.onWindowTouchEnd, {
4678
- passive: true
4679
- });
4680
- this.window.addEventListener("touchcancel", this.onWindowTouchCancel, {
4681
- passive: true
4682
- });
4683
- });
4684
- __publicField(this, "onWindowMouseMove", (event) => {
4685
- const mouseEvent = event;
4686
- const previousMouse = this.previousMouse;
4687
- const x = mouseEvent.clientX - previousMouse.x;
4688
- const y = mouseEvent.clientY - previousMouse.y;
4689
- if (!this.pointInsideVerifier.verify(mouseEvent.clientX, mouseEvent.clientY)) {
4690
- this.removeWindowMouseListeners();
4691
- return;
4692
- }
4693
- this.processMoveThresholdVerification(x, y, () => {
4694
- this.removeWindowMouseListeners();
4695
- });
4696
- this.previousMouse = { x: mouseEvent.clientX, y: mouseEvent.clientY };
4697
- });
4698
- __publicField(this, "onWindowTouchMove", (event) => {
4699
- const touchEvent = event;
4700
- if (touchEvent.touches.length !== 1) {
4701
- this.removeWindowTouchListeners();
4702
- return;
4703
- }
4704
- const touch = touchEvent.touches[0];
4705
- if (!this.pointInsideVerifier.verify(touch.clientX, touch.clientY)) {
4706
- this.removeWindowTouchListeners();
4707
- return;
4708
- }
4709
- const previousTouch = this.previousTouch;
4710
- const x = touch.clientX - previousTouch.clientX;
4711
- const y = touch.clientY - previousTouch.clientY;
4712
- this.processMoveThresholdVerification(x, y, () => {
4713
- this.removeWindowTouchListeners();
4714
- });
4715
- this.previousTouch = touch;
4716
- });
4717
- __publicField(this, "onWindowMouseUp", (event) => {
4718
- const mouseEvent = event;
4719
- if (!this.mouseUpEventVerifier(mouseEvent)) {
4720
- return;
4721
- }
4722
- this.removeWindowMouseListeners();
4723
- this.trySelectNode(event);
4724
- });
4725
- __publicField(this, "onWindowTouchEnd", (event) => {
4726
- this.removeWindowTouchListeners();
4727
- this.trySelectNode(event);
4728
- });
4729
- __publicField(this, "onWindowTouchCancel", () => {
4730
- this.removeWindowTouchListeners();
4731
- });
4732
4802
  this.canvas = canvas;
4733
4803
  this.window = window2;
4734
4804
  this.pointInsideVerifier = pointInsideVerifier;
4735
- this.mouseDownEventVerifier = params.mouseDownEventVerifier;
4736
- this.mouseUpEventVerifier = params.mouseUpEventVerifier;
4805
+ this.eventTagger = eventTagger;
4737
4806
  this.onNodeSelected = params.onNodeSelected;
4738
- this.movementThreshold = params.movementThreshold;
4807
+ this.configurator = new UserSelectableElementsConfigurator(
4808
+ this.window,
4809
+ this.pointInsideVerifier,
4810
+ {
4811
+ onSelected: (element, event) => {
4812
+ const nodeId = this.canvas.graph.findNodeIdByElement(element);
4813
+ this.eventTagger.tag(event, this.selectionHandledTag);
4814
+ this.onNodeSelected(nodeId);
4815
+ },
4816
+ movementThreshold: params.movementThreshold,
4817
+ mouseDownEventVerifier: params.mouseDownEventVerifier,
4818
+ mouseUpEventVerifier: params.mouseUpEventVerifier
4819
+ }
4820
+ );
4739
4821
  this.canvas.graph.onAfterNodeAdded.subscribe(this.onAfterNodeAdded);
4740
4822
  this.canvas.graph.onBeforeNodeRemoved.subscribe(this.onBeforeNodeRemoved);
4741
4823
  this.canvas.graph.onBeforeClear.subscribe(this.reset);
4742
- this.canvas.onBeforeDestroy.subscribe(this.revert);
4824
+ this.canvas.onBeforeDestroy.subscribe(this.reset);
4743
4825
  }
4744
- static configure(canvas, window2, pointInsideVerifier, params) {
4826
+ static configure(canvas, window2, pointInsideVerifier, eventTagger, params) {
4745
4827
  new UserSelectableNodesConfigurator(
4746
4828
  canvas,
4747
4829
  window2,
4748
4830
  pointInsideVerifier,
4831
+ eventTagger,
4749
4832
  params
4750
4833
  );
4751
4834
  }
4752
- removeWindowMouseListeners() {
4753
- this.window.removeEventListener("mouseup", this.onWindowMouseUp);
4754
- this.window.removeEventListener("mousemove", this.onWindowMouseMove);
4755
- }
4756
- removeWindowTouchListeners() {
4757
- this.window.removeEventListener("touchmove", this.onWindowTouchMove);
4758
- this.window.removeEventListener("touchend", this.onWindowTouchEnd);
4759
- this.window.removeEventListener("touchcancel", this.onWindowTouchCancel);
4760
- }
4761
- trySelectNode(event) {
4762
- const nodeId = this.selectionCandidateNodeId;
4763
- if (this.canvas.graph.hasNode(nodeId)) {
4764
- this.onNodeSelected(nodeId);
4765
- event.ignoreCanvasSelection = true;
4766
- }
4767
- }
4768
- processMoveThresholdVerification(x, y, thresholdReachedCallback) {
4769
- const distance = Math.sqrt(x * x + y * y);
4770
- this.movedDistance += distance;
4771
- if (this.movedDistance > this.movementThreshold) {
4772
- thresholdReachedCallback();
4773
- }
4774
- }
4775
4835
  }
4776
- class UserSelectableCanvasConfigurator {
4777
- constructor(canvas, element, window2, pointInsideVerifier, params) {
4778
- __publicField(this, "onCanvasSelected");
4779
- __publicField(this, "movementThreshold");
4780
- __publicField(this, "mouseDownEventVerifier");
4781
- __publicField(this, "mouseUpEventVerifier");
4782
- __publicField(this, "movedDistance", 0);
4783
- __publicField(this, "previousMouseDown", null);
4784
- __publicField(this, "previousTouch", null);
4785
- __publicField(this, "onMouseDown", (event) => {
4786
- const mouseEvent = event;
4787
- if (!this.mouseDownEventVerifier(mouseEvent)) {
4788
- return;
4789
- }
4790
- this.previousMouseDown = { x: mouseEvent.clientX, y: mouseEvent.clientY };
4791
- this.movedDistance = 0;
4792
- this.window.addEventListener("mousemove", this.onWindowMouseMove, {
4793
- passive: true
4794
- });
4795
- this.window.addEventListener("mouseup", this.onWindowMouseUp, {
4796
- passive: true
4797
- });
4798
- });
4799
- __publicField(this, "onTouchStart", (event) => {
4800
- const touchEvent = event;
4801
- if (touchEvent.touches.length !== 1) {
4802
- return;
4803
- }
4804
- const touch = touchEvent.touches[0];
4805
- this.previousTouch = touch;
4806
- this.movedDistance = 0;
4807
- this.window.addEventListener("touchmove", this.onWindowTouchMove, {
4808
- passive: true
4809
- });
4810
- this.window.addEventListener("touchend", this.onWindowTouchEnd, {
4811
- passive: true
4812
- });
4813
- this.window.addEventListener("touchcancel", this.onWindowTouchCancel, {
4814
- passive: true
4815
- });
4836
+ class UserSelectableEdgesConfigurator {
4837
+ constructor(canvas, window2, pointInsideVerifier, eventTagger, params) {
4838
+ __publicField(this, "configurator");
4839
+ __publicField(this, "selectionHandledTag", selectionHandled);
4840
+ __publicField(this, "onEdgeSelected");
4841
+ __publicField(this, "onAfterEdgeAdded", (edgeId) => {
4842
+ const { shape } = this.canvas.graph.getEdge(edgeId);
4843
+ this.configurator.enable(shape.svg);
4816
4844
  });
4817
- __publicField(this, "onWindowMouseMove", (event) => {
4818
- const mouseEvent = event;
4819
- if (!this.pointInsideVerifier.verify(mouseEvent.clientX, mouseEvent.clientY)) {
4820
- this.removeWindowMouseListeners();
4821
- return;
4822
- }
4823
- const previous = this.previousMouseDown;
4824
- const dx = mouseEvent.clientX - previous.x;
4825
- const dy = mouseEvent.clientY - previous.y;
4826
- this.processMoveThresholdVerification(dx, dy, () => {
4827
- this.removeWindowMouseListeners();
4828
- });
4829
- this.previousMouseDown = { x: mouseEvent.clientX, y: mouseEvent.clientY };
4845
+ __publicField(this, "onBeforeEdgeRemoved", (edgeId) => {
4846
+ const { shape } = this.canvas.graph.getEdge(edgeId);
4847
+ this.configurator.disable(shape.svg);
4830
4848
  });
4831
- __publicField(this, "onWindowTouchMove", (event) => {
4832
- const touchEvent = event;
4833
- if (touchEvent.touches.length !== 1) {
4834
- this.removeWindowTouchListeners();
4835
- return;
4836
- }
4837
- const touch = touchEvent.touches[0];
4838
- if (!this.pointInsideVerifier.verify(touch.clientX, touch.clientY)) {
4839
- this.removeWindowTouchListeners();
4840
- return;
4841
- }
4842
- const previous = this.previousTouch;
4843
- const dx = touch.clientX - previous.clientX;
4844
- const dy = touch.clientY - previous.clientY;
4845
- this.processMoveThresholdVerification(dx, dy, () => {
4846
- this.removeWindowTouchListeners();
4849
+ __publicField(this, "reset", () => {
4850
+ this.canvas.graph.getAllEdgeIds().forEach((edgeId) => {
4851
+ const { shape } = this.canvas.graph.getEdge(edgeId);
4852
+ this.configurator.disable(shape.svg);
4847
4853
  });
4848
- this.previousTouch = touch;
4849
4854
  });
4850
- __publicField(this, "onWindowMouseUp", (event) => {
4851
- const mouseEvent = event;
4852
- if (!this.mouseUpEventVerifier(mouseEvent)) {
4853
- return;
4854
- }
4855
- const ignore = event.ignoreCanvasSelection;
4856
- if (ignore !== true) {
4857
- this.onCanvasSelected();
4855
+ this.canvas = canvas;
4856
+ this.window = window2;
4857
+ this.pointInsideVerifier = pointInsideVerifier;
4858
+ this.eventTagger = eventTagger;
4859
+ this.onEdgeSelected = params.onEdgeSelected;
4860
+ this.configurator = new UserSelectableElementsConfigurator(
4861
+ this.window,
4862
+ this.pointInsideVerifier,
4863
+ {
4864
+ onSelected: (element, event) => {
4865
+ const edgeId = this.canvas.graph.findEdgeIdByElement(element);
4866
+ this.eventTagger.tag(event, this.selectionHandledTag);
4867
+ this.onEdgeSelected(edgeId);
4868
+ },
4869
+ movementThreshold: params.movementThreshold,
4870
+ mouseDownEventVerifier: params.mouseDownEventVerifier,
4871
+ mouseUpEventVerifier: params.mouseUpEventVerifier
4858
4872
  }
4859
- this.removeWindowMouseListeners();
4860
- });
4861
- __publicField(this, "onWindowTouchEnd", () => {
4862
- this.onCanvasSelected();
4863
- this.removeWindowTouchListeners();
4864
- });
4865
- __publicField(this, "onWindowTouchCancel", () => {
4866
- this.removeWindowTouchListeners();
4867
- });
4868
- __publicField(this, "restore", () => {
4869
- this.element.removeEventListener("mousedown", this.onMouseDown);
4870
- this.element.removeEventListener("touchstart", this.onTouchStart);
4871
- this.removeWindowMouseListeners();
4872
- this.removeWindowTouchListeners();
4873
- });
4873
+ );
4874
+ this.canvas.graph.onAfterEdgeAdded.subscribe(this.onAfterEdgeAdded);
4875
+ this.canvas.graph.onBeforeEdgeRemoved.subscribe(this.onBeforeEdgeRemoved);
4876
+ this.canvas.graph.onBeforeClear.subscribe(this.reset);
4877
+ this.canvas.onBeforeDestroy.subscribe(this.reset);
4878
+ }
4879
+ static configure(canvas, window2, pointInsideVerifier, eventTagger, params) {
4880
+ new UserSelectableEdgesConfigurator(
4881
+ canvas,
4882
+ window2,
4883
+ pointInsideVerifier,
4884
+ eventTagger,
4885
+ params
4886
+ );
4887
+ }
4888
+ }
4889
+ class UserSelectableCanvasConfigurator {
4890
+ constructor(canvas, element, window2, pointInsideVerifier, eventTagger, params) {
4891
+ __publicField(this, "configurator");
4892
+ __publicField(this, "onCanvasSelected");
4893
+ __publicField(this, "selectionHandledTag", selectionHandled);
4874
4894
  this.canvas = canvas;
4875
4895
  this.element = element;
4876
4896
  this.window = window2;
4877
4897
  this.pointInsideVerifier = pointInsideVerifier;
4898
+ this.eventTagger = eventTagger;
4878
4899
  this.onCanvasSelected = params.onCanvasSelected;
4879
- this.movementThreshold = params.movementThreshold;
4880
- this.mouseDownEventVerifier = params.mouseDownEventVerifier;
4881
- this.mouseUpEventVerifier = params.mouseUpEventVerifier;
4882
- this.canvas.onBeforeDestroy.subscribe(this.restore);
4883
- this.element.addEventListener("mousedown", this.onMouseDown, {
4884
- passive: true
4885
- });
4886
- this.element.addEventListener("touchstart", this.onTouchStart, {
4887
- passive: true
4900
+ this.configurator = new UserSelectableElementsConfigurator(
4901
+ this.window,
4902
+ this.pointInsideVerifier,
4903
+ {
4904
+ onSelected: (_element, event) => {
4905
+ if (!this.eventTagger.has(event, this.selectionHandledTag)) {
4906
+ this.onCanvasSelected();
4907
+ }
4908
+ },
4909
+ movementThreshold: params.movementThreshold,
4910
+ mouseDownEventVerifier: params.mouseDownEventVerifier,
4911
+ mouseUpEventVerifier: params.mouseUpEventVerifier
4912
+ }
4913
+ );
4914
+ this.configurator.enable(this.element);
4915
+ this.canvas.onBeforeDestroy.subscribe(() => {
4916
+ this.configurator.disable(this.element);
4888
4917
  });
4889
4918
  }
4890
- static configure(canvas, element, window2, pointInsideVerifier, params) {
4919
+ static configure(canvas, element, window2, pointInsideVerifier, eventTagger, params) {
4891
4920
  new UserSelectableCanvasConfigurator(
4892
4921
  canvas,
4893
4922
  element,
4894
4923
  window2,
4895
4924
  pointInsideVerifier,
4925
+ eventTagger,
4896
4926
  params
4897
4927
  );
4898
4928
  }
4899
- removeWindowMouseListeners() {
4900
- this.window.removeEventListener("mousemove", this.onWindowMouseMove);
4901
- this.window.removeEventListener("mouseup", this.onWindowMouseUp);
4902
- }
4903
- removeWindowTouchListeners() {
4904
- this.window.removeEventListener("touchmove", this.onWindowTouchMove);
4905
- this.window.removeEventListener("touchend", this.onWindowTouchEnd);
4906
- this.window.removeEventListener("touchcancel", this.onWindowTouchCancel);
4907
- }
4908
- processMoveThresholdVerification(x, y, thresholdReachedCallback) {
4909
- const distance = Math.sqrt(x * x + y * y);
4910
- this.movedDistance += distance;
4911
- if (this.movedDistance > this.movementThreshold) {
4912
- thresholdReachedCallback();
4913
- }
4914
- }
4915
4929
  }
4916
4930
  const createHost = () => {
4917
4931
  const host = document.createElement("div");
@@ -4953,22 +4967,38 @@ class Layers {
4953
4967
  this.element.removeChild(this.host);
4954
4968
  }
4955
4969
  }
4970
+ const forceDirectedDefaults = Object.freeze({
4971
+ seed: "HTMLGraph is awesome",
4972
+ maxTimeDeltaSec: 0.01,
4973
+ nodeCharge: 1e5,
4974
+ nodeMass: 1,
4975
+ edgeEquilibriumLength: 300,
4976
+ edgeStiffness: 1e3,
4977
+ dtSec: 0.01,
4978
+ maxIterations: 1e3,
4979
+ convergenceVelocity: 10,
4980
+ maxForce: 1e7,
4981
+ nodeForceCoefficient: 1,
4982
+ barnesHutAreaRadiusThreshold: 0.01,
4983
+ barnesHutTheta: 1
4984
+ });
4985
+ const selectionDefaults = Object.freeze({
4986
+ mouseDownEventVerifier: (event) => event.button === 0,
4987
+ mouseUpEventVerifier: (event) => event.button === 0,
4988
+ movementThreshold: 10
4989
+ });
4990
+ const noopFn = () => {
4991
+ };
4956
4992
  const createDraggableNodesParams = (config) => {
4957
4993
  var _a, _b, _c, _d, _e, _f;
4958
- const onNodeDragStarted = ((_a = config.events) == null ? void 0 : _a.onNodeDragStarted) ?? (() => {
4959
- });
4960
- const onNodeDrag = ((_b = config.events) == null ? void 0 : _b.onNodeDrag) ?? (() => {
4961
- });
4962
4994
  const nodeDragVerifier = config.nodeDragVerifier ?? (() => true);
4963
- const onNodeDragFinished = ((_c = config.events) == null ? void 0 : _c.onNodeDragFinished) ?? (() => {
4964
- });
4965
4995
  const moveOnTop = config.moveOnTop !== false;
4966
4996
  const moveEdgesOnTop = config.moveEdgesOnTop !== false && moveOnTop;
4967
- const cursor = (_d = config.mouse) == null ? void 0 : _d.dragCursor;
4997
+ const cursor = (_a = config.mouse) == null ? void 0 : _a.dragCursor;
4968
4998
  const dragCursor = cursor !== void 0 ? cursor : "grab";
4969
- const defaultMouseDownEventVerifier = (_e = config.mouse) == null ? void 0 : _e.mouseDownEventVerifier;
4999
+ const defaultMouseDownEventVerifier = (_b = config.mouse) == null ? void 0 : _b.mouseDownEventVerifier;
4970
5000
  const mouseDownEventVerifier = defaultMouseDownEventVerifier !== void 0 ? defaultMouseDownEventVerifier : (event) => event.button === 0;
4971
- const defaultMouseUpEventVerifier = (_f = config.mouse) == null ? void 0 : _f.mouseUpEventVerifier;
5001
+ const defaultMouseUpEventVerifier = (_c = config.mouse) == null ? void 0 : _c.mouseUpEventVerifier;
4972
5002
  const mouseUpEventVerifier = defaultMouseUpEventVerifier !== void 0 ? defaultMouseUpEventVerifier : (event) => event.button === 0;
4973
5003
  return {
4974
5004
  moveOnTop,
@@ -4977,10 +5007,10 @@ const createDraggableNodesParams = (config) => {
4977
5007
  gridSize: config.gridSize ?? null,
4978
5008
  mouseDownEventVerifier,
4979
5009
  mouseUpEventVerifier,
4980
- onNodeDragStarted,
4981
- onNodeDrag,
5010
+ onNodeDragStarted: ((_d = config.events) == null ? void 0 : _d.onNodeDragStarted) ?? noopFn,
5011
+ onNodeDrag: ((_e = config.events) == null ? void 0 : _e.onNodeDrag) ?? noopFn,
4982
5012
  nodeDragVerifier,
4983
- onNodeDragFinished
5013
+ onNodeDragFinished: ((_f = config.events) == null ? void 0 : _f.onNodeDragFinished) ?? noopFn
4984
5014
  };
4985
5015
  };
4986
5016
  const createShiftLimitTransformPreprocessor = (preprocessorParams) => {
@@ -5098,34 +5128,26 @@ const createTransformableViewportParams = (transformConfig) => {
5098
5128
  };
5099
5129
  }
5100
5130
  const shiftCursor = ((_b = transformConfig == null ? void 0 : transformConfig.shift) == null ? void 0 : _b.cursor) !== void 0 ? transformConfig.shift.cursor : "grab";
5101
- const onBeforeTransformStarted = ((_c = transformConfig == null ? void 0 : transformConfig.events) == null ? void 0 : _c.onBeforeTransformChange) ?? (() => {
5102
- });
5103
- const onTransformFinished = ((_d = transformConfig == null ? void 0 : transformConfig.events) == null ? void 0 : _d.onTransformChange) ?? (() => {
5104
- });
5105
- const defaultMouseDownEventVerifier = (_e = transformConfig == null ? void 0 : transformConfig.shift) == null ? void 0 : _e.mouseDownEventVerifier;
5131
+ const defaultMouseDownEventVerifier = (_c = transformConfig == null ? void 0 : transformConfig.shift) == null ? void 0 : _c.mouseDownEventVerifier;
5106
5132
  const mouseDownEventVerifier = defaultMouseDownEventVerifier !== void 0 ? defaultMouseDownEventVerifier : (event) => event.button === 0;
5107
- const defaultMouseUpEventVerifier = (_f = transformConfig == null ? void 0 : transformConfig.shift) == null ? void 0 : _f.mouseUpEventVerifier;
5133
+ const defaultMouseUpEventVerifier = (_d = transformConfig == null ? void 0 : transformConfig.shift) == null ? void 0 : _d.mouseUpEventVerifier;
5108
5134
  const mouseUpEventVerifier = defaultMouseUpEventVerifier !== void 0 ? defaultMouseUpEventVerifier : (event) => event.button === 0;
5109
- const defaultMouseWheelEventVerifier = (_g = transformConfig == null ? void 0 : transformConfig.scale) == null ? void 0 : _g.mouseWheelEventVerifier;
5135
+ const defaultMouseWheelEventVerifier = (_e = transformConfig == null ? void 0 : transformConfig.scale) == null ? void 0 : _e.mouseWheelEventVerifier;
5110
5136
  const mouseWheelEventVerifier = defaultMouseWheelEventVerifier !== void 0 ? defaultMouseWheelEventVerifier : () => true;
5111
5137
  return {
5112
5138
  wheelSensitivity,
5113
- onTransformStarted: ((_h = transformConfig == null ? void 0 : transformConfig.events) == null ? void 0 : _h.onTransformStarted) ?? (() => {
5114
- }),
5115
- onTransformFinished: ((_i = transformConfig == null ? void 0 : transformConfig.events) == null ? void 0 : _i.onTransformFinished) ?? (() => {
5116
- }),
5117
- onBeforeTransformChange: onBeforeTransformStarted,
5118
- onTransformChange: onTransformFinished,
5139
+ onTransformStarted: ((_f = transformConfig == null ? void 0 : transformConfig.events) == null ? void 0 : _f.onTransformStarted) ?? noopFn,
5140
+ onTransformFinished: ((_g = transformConfig == null ? void 0 : transformConfig.events) == null ? void 0 : _g.onTransformFinished) ?? noopFn,
5141
+ onBeforeTransformChange: ((_h = transformConfig == null ? void 0 : transformConfig.events) == null ? void 0 : _h.onBeforeTransformChange) ?? noopFn,
5142
+ onTransformChange: ((_i = transformConfig == null ? void 0 : transformConfig.events) == null ? void 0 : _i.onTransformChange) ?? noopFn,
5119
5143
  transformPreprocessor,
5120
5144
  shiftCursor,
5121
5145
  mouseDownEventVerifier,
5122
5146
  mouseUpEventVerifier,
5123
5147
  mouseWheelEventVerifier,
5124
5148
  scaleWheelFinishTimeout: ((_j = transformConfig == null ? void 0 : transformConfig.scale) == null ? void 0 : _j.wheelFinishTimeout) ?? 500,
5125
- onResizeTransformStarted: ((_k = transformConfig == null ? void 0 : transformConfig.events) == null ? void 0 : _k.onResizeTransformStarted) ?? (() => {
5126
- }),
5127
- onResizeTransformFinished: ((_l = transformConfig == null ? void 0 : transformConfig.events) == null ? void 0 : _l.onResizeTransformFinished) ?? (() => {
5128
- })
5149
+ onResizeTransformStarted: ((_k = transformConfig == null ? void 0 : transformConfig.events) == null ? void 0 : _k.onResizeTransformStarted) ?? noopFn,
5150
+ onResizeTransformFinished: ((_l = transformConfig == null ? void 0 : transformConfig.events) == null ? void 0 : _l.onResizeTransformFinished) ?? noopFn
5129
5151
  };
5130
5152
  };
5131
5153
  const createContent = (radius, color) => {
@@ -5233,34 +5255,35 @@ const resolveEdgeShapeFactory = (config) => {
5233
5255
  });
5234
5256
  }
5235
5257
  };
5258
+ const defaults$3 = Object.freeze({
5259
+ connectionTypeResolver: () => "direct",
5260
+ connectionPreprocessor: (request) => request,
5261
+ connectionAllowedVerifier: () => true,
5262
+ mouseEventVerifier: (event) => event.button === 0
5263
+ });
5236
5264
  const createConnectablePortsParams = (config, defaultEdgeShapeFactory, defaultDragPortDirection) => {
5237
5265
  var _a, _b, _c;
5238
- const defaultConnectionTypeResolver = () => "direct";
5239
- const defaultConnectionPreprocessor = (request) => request;
5240
- const defaultMouseEventVerifier = (event) => event.button === 0;
5241
- const defaultOnAfterEdgeCreated = () => {
5242
- };
5243
- const defaultOnAfterEdgeConnectionPrevented = () => {
5244
- };
5245
- const defaultOnAfterEdgeConnectionInterrupted = () => {
5246
- };
5247
5266
  return {
5248
- connectionTypeResolver: config.connectionTypeResolver ?? defaultConnectionTypeResolver,
5249
- connectionPreprocessor: config.connectionPreprocessor ?? defaultConnectionPreprocessor,
5250
- mouseDownEventVerifier: config.mouseDownEventVerifier ?? defaultMouseEventVerifier,
5251
- mouseUpEventVerifier: config.mouseUpEventVerifier ?? defaultMouseEventVerifier,
5252
- onAfterEdgeCreated: ((_a = config.events) == null ? void 0 : _a.onAfterEdgeCreated) ?? defaultOnAfterEdgeCreated,
5253
- onEdgeCreationInterrupted: ((_b = config.events) == null ? void 0 : _b.onEdgeCreationInterrupted) ?? defaultOnAfterEdgeConnectionInterrupted,
5254
- onEdgeCreationPrevented: ((_c = config.events) == null ? void 0 : _c.onEdgeCreationPrevented) ?? defaultOnAfterEdgeConnectionPrevented,
5267
+ connectionTypeResolver: config.connectionTypeResolver ?? defaults$3.connectionTypeResolver,
5268
+ connectionPreprocessor: config.connectionPreprocessor ?? defaults$3.connectionPreprocessor,
5269
+ connectionAllowedVerifier: config.connectionAllowedVerifier ?? defaults$3.connectionAllowedVerifier,
5270
+ mouseDownEventVerifier: config.mouseDownEventVerifier ?? defaults$3.mouseEventVerifier,
5271
+ mouseUpEventVerifier: config.mouseUpEventVerifier ?? defaults$3.mouseEventVerifier,
5272
+ onAfterEdgeCreated: ((_a = config.events) == null ? void 0 : _a.onAfterEdgeCreated) ?? noopFn,
5273
+ onEdgeCreationInterrupted: ((_b = config.events) == null ? void 0 : _b.onEdgeCreationInterrupted) ?? noopFn,
5274
+ onEdgeCreationPrevented: ((_c = config.events) == null ? void 0 : _c.onEdgeCreationPrevented) ?? noopFn,
5255
5275
  dragPortDirection: config.dragPortDirection ?? defaultDragPortDirection,
5256
5276
  edgeShapeFactory: config.edgeShape !== void 0 ? resolveEdgeShapeFactory(config.edgeShape) : defaultEdgeShapeFactory
5257
5277
  };
5258
5278
  };
5279
+ const defaults$2 = Object.freeze({
5280
+ connectionAllowedVerifier: () => true,
5281
+ connectionPreprocessor: (request) => request,
5282
+ mouseDownEventVerifier: (event) => event.button === 0 && event.ctrlKey,
5283
+ mouseUpEventVerifier: (event) => event.button === 0
5284
+ });
5259
5285
  const createDraggableEdgeParams = (config, graph) => {
5260
5286
  var _a, _b, _c;
5261
- const defaultConnectionPreprocessor = (request) => request;
5262
- const defaultMouseDownEventVerifier = (event) => event.button === 0 && event.ctrlKey;
5263
- const defaultMouseUpEventVerifier = (event) => event.button === 0;
5264
5287
  const defaultDraggingEdgeResolver = (portId) => {
5265
5288
  const edgeIds = graph.getPortAdjacentEdgeIds(portId);
5266
5289
  if (edgeIds.length > 0) {
@@ -5269,21 +5292,16 @@ const createDraggableEdgeParams = (config, graph) => {
5269
5292
  return null;
5270
5293
  }
5271
5294
  };
5272
- const defaultOnAfterEdgeReattached = () => {
5273
- };
5274
- const defaultOnAfterEdgeReattachPrevented = () => {
5275
- };
5276
- const defaultOnAfterEdgeReattachInterrupted = () => {
5277
- };
5278
5295
  return {
5279
- connectionPreprocessor: config.connectionPreprocessor ?? defaultConnectionPreprocessor,
5280
- mouseDownEventVerifier: config.mouseDownEventVerifier ?? defaultMouseDownEventVerifier,
5281
- mouseUpEventVerifier: config.mouseUpEventVerifier ?? defaultMouseUpEventVerifier,
5296
+ connectionPreprocessor: config.connectionPreprocessor ?? defaults$2.connectionPreprocessor,
5297
+ connectionAllowedVerifier: config.connectionAllowedVerifier ?? defaults$2.connectionAllowedVerifier,
5298
+ mouseDownEventVerifier: config.mouseDownEventVerifier ?? defaults$2.mouseDownEventVerifier,
5299
+ mouseUpEventVerifier: config.mouseUpEventVerifier ?? defaults$2.mouseUpEventVerifier,
5282
5300
  draggingEdgeResolver: config.draggingEdgeResolver ?? defaultDraggingEdgeResolver,
5283
5301
  draggingEdgeShapeFactory: config.draggingEdgeShape !== void 0 ? resolveEdgeShapeFactory(config.draggingEdgeShape) : null,
5284
- onAfterEdgeReattached: ((_a = config.events) == null ? void 0 : _a.onAfterEdgeReattached) ?? defaultOnAfterEdgeReattached,
5285
- onEdgeReattachInterrupted: ((_b = config.events) == null ? void 0 : _b.onEdgeReattachInterrupted) ?? defaultOnAfterEdgeReattachInterrupted,
5286
- onEdgeReattachPrevented: ((_c = config.events) == null ? void 0 : _c.onEdgeReattachPrevented) ?? defaultOnAfterEdgeReattachPrevented
5302
+ onAfterEdgeReattached: ((_a = config.events) == null ? void 0 : _a.onAfterEdgeReattached) ?? noopFn,
5303
+ onEdgeReattachInterrupted: ((_b = config.events) == null ? void 0 : _b.onEdgeReattachInterrupted) ?? noopFn,
5304
+ onEdgeReattachPrevented: ((_c = config.events) == null ? void 0 : _c.onEdgeReattachPrevented) ?? noopFn
5287
5305
  };
5288
5306
  };
5289
5307
  const createVirtualScrollParams = (config) => {
@@ -5295,10 +5313,8 @@ const createVirtualScrollParams = (config) => {
5295
5313
  const createVirtualScrollHtmlViewParams = (config) => {
5296
5314
  var _a, _b;
5297
5315
  return {
5298
- onAfterNodeDetached: ((_a = config == null ? void 0 : config.events) == null ? void 0 : _a.onAfterNodeDetached) ?? (() => {
5299
- }),
5300
- onBeforeNodeAttached: ((_b = config == null ? void 0 : config.events) == null ? void 0 : _b.onBeforeNodeAttached) ?? (() => {
5301
- })
5316
+ onAfterNodeDetached: ((_a = config == null ? void 0 : config.events) == null ? void 0 : _a.onAfterNodeDetached) ?? noopFn,
5317
+ onBeforeNodeAttached: ((_b = config == null ? void 0 : config.events) == null ? void 0 : _b.onBeforeNodeAttached) ?? noopFn
5302
5318
  };
5303
5319
  };
5304
5320
  class CanvasBuilderError extends Error {
@@ -6309,26 +6325,6 @@ const sfc32 = (a, b, c, d) => {
6309
6325
  return (t >>> 0) / 4294967296;
6310
6326
  };
6311
6327
  };
6312
- const forceDirectedDefaults = Object.freeze({
6313
- seed: "HTMLGraph is awesome",
6314
- maxTimeDeltaSec: 0.01,
6315
- nodeCharge: 1e5,
6316
- nodeMass: 1,
6317
- edgeEquilibriumLength: 300,
6318
- edgeStiffness: 1e3,
6319
- dtSec: 0.01,
6320
- maxIterations: 1e3,
6321
- convergenceVelocity: 10,
6322
- maxForce: 1e7,
6323
- nodeForceCoefficient: 1,
6324
- barnesHutAreaRadiusThreshold: 0.01,
6325
- barnesHutTheta: 1
6326
- });
6327
- const selectionDefaults = Object.freeze({
6328
- mouseDownEventVerifier: (event) => event.button === 0,
6329
- mouseUpEventVerifier: (event) => event.button === 0,
6330
- movementThreshold: 10
6331
- });
6332
6328
  const resolveAnimatedLayoutAlgorithm = (config) => {
6333
6329
  var _a, _b;
6334
6330
  switch (config == null ? void 0 : config.type) {
@@ -6355,11 +6351,7 @@ const resolveAnimatedLayoutAlgorithm = (config) => {
6355
6351
  }
6356
6352
  };
6357
6353
  const defaults$1 = {
6358
- staticNodeResolver: () => false,
6359
- onBeforeApplied: () => {
6360
- },
6361
- onAfterApplied: () => {
6362
- }
6354
+ staticNodeResolver: () => false
6363
6355
  };
6364
6356
  const createAnimatedLayoutParams = (config) => {
6365
6357
  var _a, _b;
@@ -6367,8 +6359,8 @@ const createAnimatedLayoutParams = (config) => {
6367
6359
  return {
6368
6360
  algorithm,
6369
6361
  staticNodeResolver: (config == null ? void 0 : config.staticNodeResolver) ?? defaults$1.staticNodeResolver,
6370
- onBeforeApplied: ((_a = config == null ? void 0 : config.events) == null ? void 0 : _a.onBeforeApplied) ?? defaults$1.onBeforeApplied,
6371
- onAfterApplied: ((_b = config == null ? void 0 : config.events) == null ? void 0 : _b.onAfterApplied) ?? defaults$1.onAfterApplied
6362
+ onBeforeApplied: ((_a = config == null ? void 0 : config.events) == null ? void 0 : _a.onBeforeApplied) ?? noopFn,
6363
+ onAfterApplied: ((_b = config == null ? void 0 : config.events) == null ? void 0 : _b.onAfterApplied) ?? noopFn
6372
6364
  };
6373
6365
  };
6374
6366
  const resolveLayoutApplyOn = (applyOn) => {
@@ -6391,10 +6383,6 @@ const resolveLayoutApplyOn = (applyOn) => {
6391
6383
  };
6392
6384
  const defaults = Object.freeze({
6393
6385
  staticNodeResolver: () => false,
6394
- onBeforeApplied: () => {
6395
- },
6396
- onAfterApplied: () => {
6397
- },
6398
6386
  hierarchicalLayout: {
6399
6387
  layerWidth: 300,
6400
6388
  layerSpace: 300
@@ -6601,8 +6589,8 @@ const createLayoutParams = (config) => {
6601
6589
  algorithm: resolveLayoutAlgorithm(config.algorithm),
6602
6590
  applyOn: resolveLayoutApplyOn(config.applyOn),
6603
6591
  staticNodeResolver: config.staticNodeResolver ?? defaults.staticNodeResolver,
6604
- onBeforeApplied: ((_a = config.events) == null ? void 0 : _a.onBeforeApplied) ?? defaults.onBeforeApplied,
6605
- onAfterApplied: ((_b = config.events) == null ? void 0 : _b.onAfterApplied) ?? defaults.onAfterApplied
6592
+ onBeforeApplied: ((_a = config.events) == null ? void 0 : _a.onBeforeApplied) ?? noopFn,
6593
+ onAfterApplied: ((_b = config.events) == null ? void 0 : _b.onAfterApplied) ?? noopFn
6606
6594
  };
6607
6595
  };
6608
6596
  const patchAnimatedLayoutDraggableNodesParams = (params, staticNodes) => {
@@ -6725,6 +6713,14 @@ const createUserSelectableCanvasParams = (config) => {
6725
6713
  movementThreshold: config.movementThreshold ?? selectionDefaults.movementThreshold
6726
6714
  };
6727
6715
  };
6716
+ const createUserSelectableEdgesParams = (config) => {
6717
+ return {
6718
+ onEdgeSelected: config.onEdgeSelected,
6719
+ mouseDownEventVerifier: config.mouseDownEventVerifier ?? selectionDefaults.mouseDownEventVerifier,
6720
+ mouseUpEventVerifier: config.mouseUpEventVerifier ?? selectionDefaults.mouseUpEventVerifier,
6721
+ movementThreshold: config.movementThreshold ?? selectionDefaults.movementThreshold
6722
+ };
6723
+ };
6728
6724
  class CanvasBuilder {
6729
6725
  constructor(element) {
6730
6726
  __publicField(this, "used", false);
@@ -6738,6 +6734,7 @@ class CanvasBuilder {
6738
6734
  __publicField(this, "layoutConfig", {});
6739
6735
  __publicField(this, "animatedLayoutConfig", {});
6740
6736
  __publicField(this, "userSelectableNodesConfig");
6737
+ __publicField(this, "userSelectableEdgesConfig");
6741
6738
  __publicField(this, "userSelectableCanvasConfig");
6742
6739
  __publicField(this, "hasDraggableNodes", false);
6743
6740
  __publicField(this, "hasTransformableViewport", false);
@@ -6751,6 +6748,7 @@ class CanvasBuilder {
6751
6748
  __publicField(this, "window", window);
6752
6749
  __publicField(this, "animationStaticNodes", /* @__PURE__ */ new Set());
6753
6750
  __publicField(this, "pointInsideVerifier");
6751
+ __publicField(this, "eventTagger", new EventTagger());
6754
6752
  this.element = element;
6755
6753
  this.pointInsideVerifier = new PointInsideVerifier(element, this.window);
6756
6754
  }
@@ -6807,6 +6805,10 @@ class CanvasBuilder {
6807
6805
  this.userSelectableNodesConfig = config;
6808
6806
  return this;
6809
6807
  }
6808
+ enableUserSelectableEdges(config) {
6809
+ this.userSelectableEdgesConfig = config;
6810
+ return this;
6811
+ }
6810
6812
  enableUserSelectableCanvas(config) {
6811
6813
  this.userSelectableCanvasConfig = config;
6812
6814
  return this;
@@ -6864,6 +6866,18 @@ class CanvasBuilder {
6864
6866
  if (this.hasNodeResizeReactiveEdges) {
6865
6867
  NodeResizeReactiveEdgesConfigurator.configure(canvas);
6866
6868
  }
6869
+ if (this.userSelectableEdgesConfig !== void 0) {
6870
+ const params = createUserSelectableEdgesParams(
6871
+ this.userSelectableEdgesConfig
6872
+ );
6873
+ UserSelectableEdgesConfigurator.configure(
6874
+ canvas,
6875
+ this.window,
6876
+ this.pointInsideVerifier,
6877
+ this.eventTagger,
6878
+ params
6879
+ );
6880
+ }
6867
6881
  if (this.userSelectableNodesConfig !== void 0) {
6868
6882
  const params = createUserSelectableNodesParams(
6869
6883
  this.userSelectableNodesConfig
@@ -6872,6 +6886,7 @@ class CanvasBuilder {
6872
6886
  canvas,
6873
6887
  this.window,
6874
6888
  this.pointInsideVerifier,
6889
+ this.eventTagger,
6875
6890
  params
6876
6891
  );
6877
6892
  }
@@ -6884,6 +6899,7 @@ class CanvasBuilder {
6884
6899
  layers.main,
6885
6900
  this.window,
6886
6901
  this.pointInsideVerifier,
6902
+ this.eventTagger,
6887
6903
  params
6888
6904
  );
6889
6905
  }
@@ -6955,9 +6971,7 @@ class CanvasBuilder {
6955
6971
  LayoutConfigurator.configure(canvas, layoutParams);
6956
6972
  }
6957
6973
  if (this.hasAnimatedLayout) {
6958
- let config = createAnimatedLayoutParams(
6959
- this.animatedLayoutConfig
6960
- );
6974
+ let config = createAnimatedLayoutParams(this.animatedLayoutConfig);
6961
6975
  if (this.hasDraggableNodes) {
6962
6976
  subscribeAnimatedLayoutStaticNodesUpdate(
6963
6977
  canvas,
@@ -6970,11 +6984,9 @@ class CanvasBuilder {
6970
6984
  }
6971
6985
  AnimatedLayoutConfigurator.configure(canvas, config, this.window);
6972
6986
  }
6973
- const onBeforeDestroy = () => {
6987
+ canvas.onBeforeDestroy.subscribe(() => {
6974
6988
  layers.destroy();
6975
- canvas.onBeforeDestroy.unsubscribe(onBeforeDestroy);
6976
- };
6977
- canvas.onBeforeDestroy.subscribe(onBeforeDestroy);
6989
+ });
6978
6990
  return canvas;
6979
6991
  }
6980
6992
  createHtmlView(host, graphStore, viewportStore) {