@html-graph/html-graph 8.15.0 → 8.16.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) => {
@@ -2829,6 +2843,9 @@ class Graph {
2829
2843
  shape: payload.shape
2830
2844
  };
2831
2845
  }
2846
+ findEdgeIdByElement(element) {
2847
+ return this.graphStore.findEdgeIdByElement(element);
2848
+ }
2832
2849
  getPortIncomingEdgeIds(portId) {
2833
2850
  return this.graphStore.getPortIncomingEdgeIds(portId);
2834
2851
  }
@@ -3456,6 +3473,163 @@ class AnimatedLayoutApplier {
3456
3473
  this.params.onAfterApplied();
3457
3474
  }
3458
3475
  }
3476
+ class EventTagger {
3477
+ constructor() {
3478
+ __publicField(this, "field", "_htmlGraphTags");
3479
+ }
3480
+ has(event, tag) {
3481
+ const e = event;
3482
+ const tags = e[this.field];
3483
+ return tags !== void 0 && tags.has(tag);
3484
+ }
3485
+ tag(event, tag) {
3486
+ const e = event;
3487
+ const tags = e[this.field];
3488
+ if (tags === void 0) {
3489
+ e[this.field] = /* @__PURE__ */ new Set([tag]);
3490
+ } else {
3491
+ tags.add(tag);
3492
+ }
3493
+ }
3494
+ }
3495
+ const selectionHandled = Symbol();
3496
+ class UserSelectableElementsConfigurator {
3497
+ constructor(window2, pointInsideVerifier, params) {
3498
+ __publicField(this, "onSelected");
3499
+ __publicField(this, "mouseDownEventVerifier");
3500
+ __publicField(this, "mouseUpEventVerifier");
3501
+ __publicField(this, "movementThreshold");
3502
+ __publicField(this, "selectionCandidate", null);
3503
+ __publicField(this, "previousMouse", null);
3504
+ __publicField(this, "previousTouch", null);
3505
+ __publicField(this, "movedDistance", 0);
3506
+ __publicField(this, "onElementMouseDown", (event) => {
3507
+ const mouseEvent = event;
3508
+ if (!this.mouseDownEventVerifier(mouseEvent)) {
3509
+ return;
3510
+ }
3511
+ this.selectionCandidate = mouseEvent.currentTarget;
3512
+ this.previousMouse = { x: mouseEvent.clientX, y: mouseEvent.clientY };
3513
+ this.movedDistance = 0;
3514
+ this.window.addEventListener("mousemove", this.onWindowMouseMove, {
3515
+ passive: true
3516
+ });
3517
+ this.window.addEventListener("mouseup", this.onWindowMouseUp, {
3518
+ passive: true
3519
+ });
3520
+ });
3521
+ __publicField(this, "onElementTouchStart", (event) => {
3522
+ const touchEvent = event;
3523
+ const touches = touchEvent.touches;
3524
+ if (touches.length !== 1) {
3525
+ return;
3526
+ }
3527
+ this.selectionCandidate = touchEvent.currentTarget;
3528
+ this.previousTouch = touches[0];
3529
+ this.movedDistance = 0;
3530
+ this.window.addEventListener("touchmove", this.onWindowTouchMove, {
3531
+ passive: true
3532
+ });
3533
+ this.window.addEventListener("touchend", this.onWindowTouchEnd, {
3534
+ passive: true
3535
+ });
3536
+ this.window.addEventListener("touchcancel", this.onWindowTouchCancel, {
3537
+ passive: true
3538
+ });
3539
+ });
3540
+ __publicField(this, "onWindowMouseMove", (event) => {
3541
+ const mouseEvent = event;
3542
+ const inside = this.pointInsideVerifier.verify(
3543
+ mouseEvent.clientX,
3544
+ mouseEvent.clientY
3545
+ );
3546
+ if (!inside) {
3547
+ this.removeWindowMouseListeners();
3548
+ return;
3549
+ }
3550
+ const previousMouse = this.previousMouse;
3551
+ const x = mouseEvent.clientX - previousMouse.x;
3552
+ const y = mouseEvent.clientY - previousMouse.y;
3553
+ this.previousMouse = { x: mouseEvent.clientX, y: mouseEvent.clientY };
3554
+ this.processMoveThresholdVerification(x, y, () => {
3555
+ this.removeWindowMouseListeners();
3556
+ });
3557
+ });
3558
+ __publicField(this, "onWindowMouseUp", (event) => {
3559
+ const mouseEvent = event;
3560
+ if (!this.mouseUpEventVerifier(mouseEvent)) {
3561
+ return;
3562
+ }
3563
+ this.removeWindowMouseListeners();
3564
+ this.onSelected(this.selectionCandidate, event);
3565
+ });
3566
+ __publicField(this, "onWindowTouchMove", (event) => {
3567
+ const touchEvent = event;
3568
+ const touches = touchEvent.touches;
3569
+ if (touches.length !== 1) {
3570
+ this.removeWindowTouchListeners();
3571
+ return;
3572
+ }
3573
+ const touch = touches[0];
3574
+ const inside = this.pointInsideVerifier.verify(
3575
+ touch.clientX,
3576
+ touch.clientY
3577
+ );
3578
+ if (!inside) {
3579
+ this.removeWindowTouchListeners();
3580
+ return;
3581
+ }
3582
+ const previousTouch = this.previousTouch;
3583
+ const x = touch.clientX - previousTouch.clientX;
3584
+ const y = touch.clientY - previousTouch.clientY;
3585
+ this.previousTouch = touch;
3586
+ this.processMoveThresholdVerification(x, y, () => {
3587
+ this.removeWindowTouchListeners();
3588
+ });
3589
+ });
3590
+ __publicField(this, "onWindowTouchEnd", (event) => {
3591
+ this.removeWindowTouchListeners();
3592
+ this.onSelected(this.selectionCandidate, event);
3593
+ });
3594
+ __publicField(this, "onWindowTouchCancel", () => {
3595
+ this.removeWindowTouchListeners();
3596
+ });
3597
+ this.window = window2;
3598
+ this.pointInsideVerifier = pointInsideVerifier;
3599
+ this.mouseDownEventVerifier = params.mouseDownEventVerifier;
3600
+ this.mouseUpEventVerifier = params.mouseUpEventVerifier;
3601
+ this.onSelected = params.onSelected;
3602
+ this.movementThreshold = params.movementThreshold;
3603
+ }
3604
+ enable(element) {
3605
+ element.addEventListener("mousedown", this.onElementMouseDown);
3606
+ element.addEventListener("touchstart", this.onElementTouchStart);
3607
+ }
3608
+ disable(element) {
3609
+ element.removeEventListener("mousedown", this.onElementMouseDown);
3610
+ element.removeEventListener("touchstart", this.onElementTouchStart);
3611
+ if (element === this.selectionCandidate) {
3612
+ this.removeWindowMouseListeners();
3613
+ this.removeWindowTouchListeners();
3614
+ }
3615
+ }
3616
+ removeWindowMouseListeners() {
3617
+ this.window.removeEventListener("mousemove", this.onWindowMouseMove);
3618
+ this.window.removeEventListener("mouseup", this.onWindowMouseUp);
3619
+ }
3620
+ removeWindowTouchListeners() {
3621
+ this.window.removeEventListener("touchmove", this.onWindowTouchMove);
3622
+ this.window.removeEventListener("touchend", this.onWindowTouchEnd);
3623
+ this.window.removeEventListener("touchcancel", this.onWindowTouchCancel);
3624
+ }
3625
+ processMoveThresholdVerification(x, y, thresholdReachedCallback) {
3626
+ const distance = Math.sqrt(x * x + y * y);
3627
+ this.movedDistance += distance;
3628
+ if (this.movedDistance > this.movementThreshold) {
3629
+ thresholdReachedCallback();
3630
+ }
3631
+ }
3632
+ }
3459
3633
  class UserDraggableNodesConfigurator {
3460
3634
  constructor(canvas, element, window2, pointInsideVerifier, params) {
3461
3635
  __publicField(this, "grabbedNode", null);
@@ -4348,7 +4522,16 @@ class UserDraggableEdgesConfigurator {
4348
4522
  this.moveDraggingPort(cursor);
4349
4523
  },
4350
4524
  onPointerMoveOutside: () => {
4351
- this.handleEdgeReattachInterrupted();
4525
+ const edge = this.draggingEdgePayload;
4526
+ queueMicrotask(() => {
4527
+ this.params.onEdgeReattachInterrupted({
4528
+ id: edge.id,
4529
+ from: edge.from,
4530
+ to: edge.to,
4531
+ shape: edge.shape,
4532
+ priority: edge.priority
4533
+ });
4534
+ });
4352
4535
  },
4353
4536
  onPointerUp: (cursor) => {
4354
4537
  this.tryCreateConnection(cursor);
@@ -4598,311 +4781,152 @@ class AnimatedLayoutConfigurator {
4598
4781
  }
4599
4782
  }
4600
4783
  class UserSelectableNodesConfigurator {
4601
- constructor(canvas, window2, pointInsideVerifier, params) {
4784
+ constructor(canvas, window2, pointInsideVerifier, eventTagger, params) {
4785
+ __publicField(this, "configurator");
4602
4786
  __publicField(this, "onNodeSelected");
4603
- __publicField(this, "mouseDownEventVerifier");
4604
- __publicField(this, "mouseUpEventVerifier");
4605
- __publicField(this, "movementThreshold");
4606
- __publicField(this, "selectionCandidateNodeId", null);
4607
- __publicField(this, "movedDistance", 0);
4608
- __publicField(this, "previousMouse", null);
4609
- __publicField(this, "previousTouch", null);
4787
+ __publicField(this, "selectionHandledTag", selectionHandled);
4610
4788
  __publicField(this, "onAfterNodeAdded", (nodeId) => {
4611
4789
  const { element } = this.canvas.graph.getNode(nodeId);
4612
- element.addEventListener("mousedown", this.onNodeMouseDown, {
4613
- passive: true
4614
- });
4615
- element.addEventListener("touchstart", this.onNodeTouchStart, {
4616
- passive: true
4617
- });
4790
+ this.configurator.enable(element);
4618
4791
  });
4619
4792
  __publicField(this, "onBeforeNodeRemoved", (nodeId) => {
4620
4793
  const { element } = this.canvas.graph.getNode(nodeId);
4621
- element.removeEventListener("mousedown", this.onNodeMouseDown);
4622
- element.removeEventListener("touchstart", this.onNodeTouchStart);
4794
+ this.configurator.disable(element);
4623
4795
  });
4624
4796
  __publicField(this, "reset", () => {
4625
4797
  this.canvas.graph.getAllNodeIds().forEach((nodeId) => {
4626
4798
  const { element } = this.canvas.graph.getNode(nodeId);
4627
- element.removeEventListener("mousedown", this.onNodeMouseDown);
4628
- element.removeEventListener("touchstart", this.onNodeTouchStart);
4629
- });
4630
- });
4631
- __publicField(this, "revert", () => {
4632
- this.reset();
4633
- this.removeWindowMouseListeners();
4634
- this.removeWindowTouchListeners();
4635
- });
4636
- __publicField(this, "onNodeMouseDown", (event) => {
4637
- const mouseEvent = event;
4638
- if (!this.mouseDownEventVerifier(mouseEvent)) {
4639
- return;
4640
- }
4641
- const nodeId = this.canvas.graph.findNodeIdByElement(
4642
- event.currentTarget
4643
- );
4644
- this.selectionCandidateNodeId = nodeId;
4645
- this.previousMouse = { x: mouseEvent.clientX, y: mouseEvent.clientY };
4646
- this.movedDistance = 0;
4647
- this.window.addEventListener("mousemove", this.onWindowMouseMove, {
4648
- passive: true
4649
- });
4650
- this.window.addEventListener("mouseup", this.onWindowMouseUp, {
4651
- passive: true
4652
- });
4653
- });
4654
- __publicField(this, "onNodeTouchStart", (event) => {
4655
- const touchEvent = event;
4656
- if (touchEvent.touches.length !== 1) {
4657
- return;
4658
- }
4659
- const nodeId = this.canvas.graph.findNodeIdByElement(
4660
- touchEvent.currentTarget
4661
- );
4662
- this.selectionCandidateNodeId = nodeId;
4663
- this.previousTouch = touchEvent.touches[0];
4664
- this.movedDistance = 0;
4665
- this.window.addEventListener("touchmove", this.onWindowTouchMove, {
4666
- passive: true
4667
- });
4668
- this.window.addEventListener("touchend", this.onWindowTouchEnd, {
4669
- passive: true
4670
- });
4671
- this.window.addEventListener("touchcancel", this.onWindowTouchCancel, {
4672
- passive: true
4799
+ this.configurator.disable(element);
4673
4800
  });
4674
4801
  });
4675
- __publicField(this, "onWindowMouseMove", (event) => {
4676
- const mouseEvent = event;
4677
- const previousMouse = this.previousMouse;
4678
- const x = mouseEvent.clientX - previousMouse.x;
4679
- const y = mouseEvent.clientY - previousMouse.y;
4680
- if (!this.pointInsideVerifier.verify(mouseEvent.clientX, mouseEvent.clientY)) {
4681
- this.removeWindowMouseListeners();
4682
- return;
4683
- }
4684
- this.processMoveThresholdVerification(x, y, () => {
4685
- this.removeWindowMouseListeners();
4686
- });
4687
- this.previousMouse = { x: mouseEvent.clientX, y: mouseEvent.clientY };
4688
- });
4689
- __publicField(this, "onWindowTouchMove", (event) => {
4690
- const touchEvent = event;
4691
- if (touchEvent.touches.length !== 1) {
4692
- this.removeWindowTouchListeners();
4693
- return;
4694
- }
4695
- const touch = touchEvent.touches[0];
4696
- if (!this.pointInsideVerifier.verify(touch.clientX, touch.clientY)) {
4697
- this.removeWindowTouchListeners();
4698
- return;
4699
- }
4700
- const previousTouch = this.previousTouch;
4701
- const x = touch.clientX - previousTouch.clientX;
4702
- const y = touch.clientY - previousTouch.clientY;
4703
- this.processMoveThresholdVerification(x, y, () => {
4704
- this.removeWindowTouchListeners();
4705
- });
4706
- this.previousTouch = touch;
4707
- });
4708
- __publicField(this, "onWindowMouseUp", (event) => {
4709
- const mouseEvent = event;
4710
- if (!this.mouseUpEventVerifier(mouseEvent)) {
4711
- return;
4712
- }
4713
- this.removeWindowMouseListeners();
4714
- this.trySelectNode(event);
4715
- });
4716
- __publicField(this, "onWindowTouchEnd", (event) => {
4717
- this.removeWindowTouchListeners();
4718
- this.trySelectNode(event);
4719
- });
4720
- __publicField(this, "onWindowTouchCancel", () => {
4721
- this.removeWindowTouchListeners();
4722
- });
4723
4802
  this.canvas = canvas;
4724
4803
  this.window = window2;
4725
4804
  this.pointInsideVerifier = pointInsideVerifier;
4726
- this.mouseDownEventVerifier = params.mouseDownEventVerifier;
4727
- this.mouseUpEventVerifier = params.mouseUpEventVerifier;
4805
+ this.eventTagger = eventTagger;
4728
4806
  this.onNodeSelected = params.onNodeSelected;
4729
- 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
+ );
4730
4821
  this.canvas.graph.onAfterNodeAdded.subscribe(this.onAfterNodeAdded);
4731
4822
  this.canvas.graph.onBeforeNodeRemoved.subscribe(this.onBeforeNodeRemoved);
4732
4823
  this.canvas.graph.onBeforeClear.subscribe(this.reset);
4733
- this.canvas.onBeforeDestroy.subscribe(this.revert);
4824
+ this.canvas.onBeforeDestroy.subscribe(this.reset);
4734
4825
  }
4735
- static configure(canvas, window2, pointInsideVerifier, params) {
4826
+ static configure(canvas, window2, pointInsideVerifier, eventTagger, params) {
4736
4827
  new UserSelectableNodesConfigurator(
4737
4828
  canvas,
4738
4829
  window2,
4739
4830
  pointInsideVerifier,
4831
+ eventTagger,
4740
4832
  params
4741
4833
  );
4742
4834
  }
4743
- removeWindowMouseListeners() {
4744
- this.window.removeEventListener("mouseup", this.onWindowMouseUp);
4745
- this.window.removeEventListener("mousemove", this.onWindowMouseMove);
4746
- }
4747
- removeWindowTouchListeners() {
4748
- this.window.removeEventListener("touchmove", this.onWindowTouchMove);
4749
- this.window.removeEventListener("touchend", this.onWindowTouchEnd);
4750
- this.window.removeEventListener("touchcancel", this.onWindowTouchCancel);
4751
- }
4752
- trySelectNode(event) {
4753
- const nodeId = this.selectionCandidateNodeId;
4754
- if (this.canvas.graph.hasNode(nodeId)) {
4755
- this.onNodeSelected(nodeId);
4756
- event.ignoreCanvasSelection = true;
4757
- }
4758
- }
4759
- processMoveThresholdVerification(x, y, thresholdReachedCallback) {
4760
- const distance = Math.sqrt(x * x + y * y);
4761
- this.movedDistance += distance;
4762
- if (this.movedDistance > this.movementThreshold) {
4763
- thresholdReachedCallback();
4764
- }
4765
- }
4766
4835
  }
4767
- class UserSelectableCanvasConfigurator {
4768
- constructor(canvas, element, window2, pointInsideVerifier, params) {
4769
- __publicField(this, "onCanvasSelected");
4770
- __publicField(this, "movementThreshold");
4771
- __publicField(this, "mouseDownEventVerifier");
4772
- __publicField(this, "mouseUpEventVerifier");
4773
- __publicField(this, "movedDistance", 0);
4774
- __publicField(this, "previousMouseDown", null);
4775
- __publicField(this, "previousTouch", null);
4776
- __publicField(this, "onMouseDown", (event) => {
4777
- const mouseEvent = event;
4778
- if (!this.mouseDownEventVerifier(mouseEvent)) {
4779
- return;
4780
- }
4781
- this.previousMouseDown = { x: mouseEvent.clientX, y: mouseEvent.clientY };
4782
- this.movedDistance = 0;
4783
- this.window.addEventListener("mousemove", this.onWindowMouseMove, {
4784
- passive: true
4785
- });
4786
- this.window.addEventListener("mouseup", this.onWindowMouseUp, {
4787
- passive: true
4788
- });
4789
- });
4790
- __publicField(this, "onTouchStart", (event) => {
4791
- const touchEvent = event;
4792
- if (touchEvent.touches.length !== 1) {
4793
- return;
4794
- }
4795
- const touch = touchEvent.touches[0];
4796
- this.previousTouch = touch;
4797
- this.movedDistance = 0;
4798
- this.window.addEventListener("touchmove", this.onWindowTouchMove, {
4799
- passive: true
4800
- });
4801
- this.window.addEventListener("touchend", this.onWindowTouchEnd, {
4802
- passive: true
4803
- });
4804
- this.window.addEventListener("touchcancel", this.onWindowTouchCancel, {
4805
- passive: true
4806
- });
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);
4807
4844
  });
4808
- __publicField(this, "onWindowMouseMove", (event) => {
4809
- const mouseEvent = event;
4810
- if (!this.pointInsideVerifier.verify(mouseEvent.clientX, mouseEvent.clientY)) {
4811
- this.removeWindowMouseListeners();
4812
- return;
4813
- }
4814
- const previous = this.previousMouseDown;
4815
- const dx = mouseEvent.clientX - previous.x;
4816
- const dy = mouseEvent.clientY - previous.y;
4817
- this.processMoveThresholdVerification(dx, dy, () => {
4818
- this.removeWindowMouseListeners();
4819
- });
4820
- 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);
4821
4848
  });
4822
- __publicField(this, "onWindowTouchMove", (event) => {
4823
- const touchEvent = event;
4824
- if (touchEvent.touches.length !== 1) {
4825
- this.removeWindowTouchListeners();
4826
- return;
4827
- }
4828
- const touch = touchEvent.touches[0];
4829
- if (!this.pointInsideVerifier.verify(touch.clientX, touch.clientY)) {
4830
- this.removeWindowTouchListeners();
4831
- return;
4832
- }
4833
- const previous = this.previousTouch;
4834
- const dx = touch.clientX - previous.clientX;
4835
- const dy = touch.clientY - previous.clientY;
4836
- this.processMoveThresholdVerification(dx, dy, () => {
4837
- 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);
4838
4853
  });
4839
- this.previousTouch = touch;
4840
4854
  });
4841
- __publicField(this, "onWindowMouseUp", (event) => {
4842
- const mouseEvent = event;
4843
- if (!this.mouseUpEventVerifier(mouseEvent)) {
4844
- return;
4845
- }
4846
- const ignore = event.ignoreCanvasSelection;
4847
- if (ignore !== true) {
4848
- 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
4849
4872
  }
4850
- this.removeWindowMouseListeners();
4851
- });
4852
- __publicField(this, "onWindowTouchEnd", () => {
4853
- this.onCanvasSelected();
4854
- this.removeWindowTouchListeners();
4855
- });
4856
- __publicField(this, "onWindowTouchCancel", () => {
4857
- this.removeWindowTouchListeners();
4858
- });
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);
4859
4894
  __publicField(this, "restore", () => {
4860
- this.element.removeEventListener("mousedown", this.onMouseDown);
4861
- this.element.removeEventListener("touchstart", this.onTouchStart);
4862
- this.removeWindowMouseListeners();
4863
- this.removeWindowTouchListeners();
4895
+ this.configurator.disable(this.element);
4864
4896
  });
4865
4897
  this.canvas = canvas;
4866
4898
  this.element = element;
4867
4899
  this.window = window2;
4868
4900
  this.pointInsideVerifier = pointInsideVerifier;
4901
+ this.eventTagger = eventTagger;
4869
4902
  this.onCanvasSelected = params.onCanvasSelected;
4870
- this.movementThreshold = params.movementThreshold;
4871
- this.mouseDownEventVerifier = params.mouseDownEventVerifier;
4872
- this.mouseUpEventVerifier = params.mouseUpEventVerifier;
4903
+ this.configurator = new UserSelectableElementsConfigurator(
4904
+ this.window,
4905
+ this.pointInsideVerifier,
4906
+ {
4907
+ onSelected: (_element, event) => {
4908
+ if (!this.eventTagger.has(event, this.selectionHandledTag)) {
4909
+ this.onCanvasSelected();
4910
+ }
4911
+ },
4912
+ movementThreshold: params.movementThreshold,
4913
+ mouseDownEventVerifier: params.mouseDownEventVerifier,
4914
+ mouseUpEventVerifier: params.mouseUpEventVerifier
4915
+ }
4916
+ );
4917
+ this.configurator.enable(this.element);
4873
4918
  this.canvas.onBeforeDestroy.subscribe(this.restore);
4874
- this.element.addEventListener("mousedown", this.onMouseDown, {
4875
- passive: true
4876
- });
4877
- this.element.addEventListener("touchstart", this.onTouchStart, {
4878
- passive: true
4879
- });
4880
4919
  }
4881
- static configure(canvas, element, window2, pointInsideVerifier, params) {
4920
+ static configure(canvas, element, window2, pointInsideVerifier, eventTagger, params) {
4882
4921
  new UserSelectableCanvasConfigurator(
4883
4922
  canvas,
4884
4923
  element,
4885
4924
  window2,
4886
4925
  pointInsideVerifier,
4926
+ eventTagger,
4887
4927
  params
4888
4928
  );
4889
4929
  }
4890
- removeWindowMouseListeners() {
4891
- this.window.removeEventListener("mousemove", this.onWindowMouseMove);
4892
- this.window.removeEventListener("mouseup", this.onWindowMouseUp);
4893
- }
4894
- removeWindowTouchListeners() {
4895
- this.window.removeEventListener("touchmove", this.onWindowTouchMove);
4896
- this.window.removeEventListener("touchend", this.onWindowTouchEnd);
4897
- this.window.removeEventListener("touchcancel", this.onWindowTouchCancel);
4898
- }
4899
- processMoveThresholdVerification(x, y, thresholdReachedCallback) {
4900
- const distance = Math.sqrt(x * x + y * y);
4901
- this.movedDistance += distance;
4902
- if (this.movedDistance > this.movementThreshold) {
4903
- thresholdReachedCallback();
4904
- }
4905
- }
4906
4930
  }
4907
4931
  const createHost = () => {
4908
4932
  const host = document.createElement("div");
@@ -6716,6 +6740,14 @@ const createUserSelectableCanvasParams = (config) => {
6716
6740
  movementThreshold: config.movementThreshold ?? selectionDefaults.movementThreshold
6717
6741
  };
6718
6742
  };
6743
+ const createUserSelectableEdgesParams = (config) => {
6744
+ return {
6745
+ onEdgeSelected: config.onEdgeSelected,
6746
+ mouseDownEventVerifier: config.mouseDownEventVerifier ?? selectionDefaults.mouseDownEventVerifier,
6747
+ mouseUpEventVerifier: config.mouseUpEventVerifier ?? selectionDefaults.mouseUpEventVerifier,
6748
+ movementThreshold: config.movementThreshold ?? selectionDefaults.movementThreshold
6749
+ };
6750
+ };
6719
6751
  class CanvasBuilder {
6720
6752
  constructor(element) {
6721
6753
  __publicField(this, "used", false);
@@ -6729,6 +6761,7 @@ class CanvasBuilder {
6729
6761
  __publicField(this, "layoutConfig", {});
6730
6762
  __publicField(this, "animatedLayoutConfig", {});
6731
6763
  __publicField(this, "userSelectableNodesConfig");
6764
+ __publicField(this, "userSelectableEdgesConfig");
6732
6765
  __publicField(this, "userSelectableCanvasConfig");
6733
6766
  __publicField(this, "hasDraggableNodes", false);
6734
6767
  __publicField(this, "hasTransformableViewport", false);
@@ -6742,6 +6775,7 @@ class CanvasBuilder {
6742
6775
  __publicField(this, "window", window);
6743
6776
  __publicField(this, "animationStaticNodes", /* @__PURE__ */ new Set());
6744
6777
  __publicField(this, "pointInsideVerifier");
6778
+ __publicField(this, "eventTagger", new EventTagger());
6745
6779
  this.element = element;
6746
6780
  this.pointInsideVerifier = new PointInsideVerifier(element, this.window);
6747
6781
  }
@@ -6798,6 +6832,10 @@ class CanvasBuilder {
6798
6832
  this.userSelectableNodesConfig = config;
6799
6833
  return this;
6800
6834
  }
6835
+ enableUserSelectableEdges(config) {
6836
+ this.userSelectableEdgesConfig = config;
6837
+ return this;
6838
+ }
6801
6839
  enableUserSelectableCanvas(config) {
6802
6840
  this.userSelectableCanvasConfig = config;
6803
6841
  return this;
@@ -6855,6 +6893,18 @@ class CanvasBuilder {
6855
6893
  if (this.hasNodeResizeReactiveEdges) {
6856
6894
  NodeResizeReactiveEdgesConfigurator.configure(canvas);
6857
6895
  }
6896
+ if (this.userSelectableEdgesConfig !== void 0) {
6897
+ const params = createUserSelectableEdgesParams(
6898
+ this.userSelectableEdgesConfig
6899
+ );
6900
+ UserSelectableEdgesConfigurator.configure(
6901
+ canvas,
6902
+ this.window,
6903
+ this.pointInsideVerifier,
6904
+ this.eventTagger,
6905
+ params
6906
+ );
6907
+ }
6858
6908
  if (this.userSelectableNodesConfig !== void 0) {
6859
6909
  const params = createUserSelectableNodesParams(
6860
6910
  this.userSelectableNodesConfig
@@ -6863,6 +6913,7 @@ class CanvasBuilder {
6863
6913
  canvas,
6864
6914
  this.window,
6865
6915
  this.pointInsideVerifier,
6916
+ this.eventTagger,
6866
6917
  params
6867
6918
  );
6868
6919
  }
@@ -6875,6 +6926,7 @@ class CanvasBuilder {
6875
6926
  layers.main,
6876
6927
  this.window,
6877
6928
  this.pointInsideVerifier,
6929
+ this.eventTagger,
6878
6930
  params
6879
6931
  );
6880
6932
  }