@html-graph/html-graph 8.15.1 → 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);
@@ -4607,311 +4781,152 @@ 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);
4638
- });
4639
- });
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
4799
+ this.configurator.disable(element);
4682
4800
  });
4683
4801
  });
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
- });
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);
4868
4894
  __publicField(this, "restore", () => {
4869
- this.element.removeEventListener("mousedown", this.onMouseDown);
4870
- this.element.removeEventListener("touchstart", this.onTouchStart);
4871
- this.removeWindowMouseListeners();
4872
- this.removeWindowTouchListeners();
4895
+ this.configurator.disable(this.element);
4873
4896
  });
4874
4897
  this.canvas = canvas;
4875
4898
  this.element = element;
4876
4899
  this.window = window2;
4877
4900
  this.pointInsideVerifier = pointInsideVerifier;
4901
+ this.eventTagger = eventTagger;
4878
4902
  this.onCanvasSelected = params.onCanvasSelected;
4879
- this.movementThreshold = params.movementThreshold;
4880
- this.mouseDownEventVerifier = params.mouseDownEventVerifier;
4881
- 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);
4882
4918
  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
4888
- });
4889
4919
  }
4890
- static configure(canvas, element, window2, pointInsideVerifier, params) {
4920
+ static configure(canvas, element, window2, pointInsideVerifier, eventTagger, params) {
4891
4921
  new UserSelectableCanvasConfigurator(
4892
4922
  canvas,
4893
4923
  element,
4894
4924
  window2,
4895
4925
  pointInsideVerifier,
4926
+ eventTagger,
4896
4927
  params
4897
4928
  );
4898
4929
  }
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
4930
  }
4916
4931
  const createHost = () => {
4917
4932
  const host = document.createElement("div");
@@ -6725,6 +6740,14 @@ const createUserSelectableCanvasParams = (config) => {
6725
6740
  movementThreshold: config.movementThreshold ?? selectionDefaults.movementThreshold
6726
6741
  };
6727
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
+ };
6728
6751
  class CanvasBuilder {
6729
6752
  constructor(element) {
6730
6753
  __publicField(this, "used", false);
@@ -6738,6 +6761,7 @@ class CanvasBuilder {
6738
6761
  __publicField(this, "layoutConfig", {});
6739
6762
  __publicField(this, "animatedLayoutConfig", {});
6740
6763
  __publicField(this, "userSelectableNodesConfig");
6764
+ __publicField(this, "userSelectableEdgesConfig");
6741
6765
  __publicField(this, "userSelectableCanvasConfig");
6742
6766
  __publicField(this, "hasDraggableNodes", false);
6743
6767
  __publicField(this, "hasTransformableViewport", false);
@@ -6751,6 +6775,7 @@ class CanvasBuilder {
6751
6775
  __publicField(this, "window", window);
6752
6776
  __publicField(this, "animationStaticNodes", /* @__PURE__ */ new Set());
6753
6777
  __publicField(this, "pointInsideVerifier");
6778
+ __publicField(this, "eventTagger", new EventTagger());
6754
6779
  this.element = element;
6755
6780
  this.pointInsideVerifier = new PointInsideVerifier(element, this.window);
6756
6781
  }
@@ -6807,6 +6832,10 @@ class CanvasBuilder {
6807
6832
  this.userSelectableNodesConfig = config;
6808
6833
  return this;
6809
6834
  }
6835
+ enableUserSelectableEdges(config) {
6836
+ this.userSelectableEdgesConfig = config;
6837
+ return this;
6838
+ }
6810
6839
  enableUserSelectableCanvas(config) {
6811
6840
  this.userSelectableCanvasConfig = config;
6812
6841
  return this;
@@ -6864,6 +6893,18 @@ class CanvasBuilder {
6864
6893
  if (this.hasNodeResizeReactiveEdges) {
6865
6894
  NodeResizeReactiveEdgesConfigurator.configure(canvas);
6866
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
+ }
6867
6908
  if (this.userSelectableNodesConfig !== void 0) {
6868
6909
  const params = createUserSelectableNodesParams(
6869
6910
  this.userSelectableNodesConfig
@@ -6872,6 +6913,7 @@ class CanvasBuilder {
6872
6913
  canvas,
6873
6914
  this.window,
6874
6915
  this.pointInsideVerifier,
6916
+ this.eventTagger,
6875
6917
  params
6876
6918
  );
6877
6919
  }
@@ -6884,6 +6926,7 @@ class CanvasBuilder {
6884
6926
  layers.main,
6885
6927
  this.window,
6886
6928
  this.pointInsideVerifier,
6929
+ this.eventTagger,
6887
6930
  params
6888
6931
  );
6889
6932
  }