jqtree 1.8.8 → 1.8.9

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.
@@ -37,6 +37,32 @@ var jqtree = (function (exports) {
37
37
  this.treeElement = treeElement;
38
38
  this.triggerEvent = triggerEvent;
39
39
  }
40
+ loadFromUrl(urlInfo, parentNode, onFinished) {
41
+ if (!urlInfo) {
42
+ return;
43
+ }
44
+ const element = this.getDomElement(parentNode);
45
+ this.addLoadingClass(element);
46
+ this.notifyLoading(true, parentNode, element);
47
+ const stopLoading = () => {
48
+ this.removeLoadingClass(element);
49
+ this.notifyLoading(false, parentNode, element);
50
+ };
51
+ const handleSuccess = data => {
52
+ stopLoading();
53
+ this.loadData(this.parseData(data), parentNode);
54
+ if (onFinished && typeof onFinished === "function") {
55
+ onFinished();
56
+ }
57
+ };
58
+ const handleError = jqXHR => {
59
+ stopLoading();
60
+ if (this.onLoadFailed) {
61
+ this.onLoadFailed(jqXHR);
62
+ }
63
+ };
64
+ this.submitRequest(urlInfo, handleSuccess, handleError);
65
+ }
40
66
  addLoadingClass(element) {
41
67
  element.classList.add("jqtree-loading");
42
68
  }
@@ -91,32 +117,6 @@ var jqtree = (function (exports) {
91
117
  ajaxSettings.method = ajaxSettings.method?.toUpperCase() ?? "GET";
92
118
  void jQuery.ajax(ajaxSettings);
93
119
  }
94
- loadFromUrl(urlInfo, parentNode, onFinished) {
95
- if (!urlInfo) {
96
- return;
97
- }
98
- const element = this.getDomElement(parentNode);
99
- this.addLoadingClass(element);
100
- this.notifyLoading(true, parentNode, element);
101
- const stopLoading = () => {
102
- this.removeLoadingClass(element);
103
- this.notifyLoading(false, parentNode, element);
104
- };
105
- const handleSuccess = data => {
106
- stopLoading();
107
- this.loadData(this.parseData(data), parentNode);
108
- if (onFinished && typeof onFinished === "function") {
109
- onFinished();
110
- }
111
- };
112
- const handleError = jqXHR => {
113
- stopLoading();
114
- if (this.onLoadFailed) {
115
- this.onLoadFailed(jqXHR);
116
- }
117
- };
118
- this.submitRequest(urlInfo, handleSuccess, handleError);
119
- }
120
120
  }
121
121
 
122
122
  let Position = /*#__PURE__*/function (Position) {
@@ -156,6 +156,27 @@ var jqtree = (function (exports) {
156
156
  };
157
157
  };
158
158
 
159
+ function binarySearch(items, compareFn) {
160
+ let low = 0;
161
+ let high = items.length;
162
+ while (low < high) {
163
+ const mid = low + high >> 1;
164
+ const item = items[mid];
165
+ if (item === undefined) {
166
+ return null;
167
+ }
168
+ const compareResult = compareFn(item);
169
+ if (compareResult > 0) {
170
+ high = mid;
171
+ } else if (compareResult < 0) {
172
+ low = mid + 1;
173
+ } else {
174
+ return item;
175
+ }
176
+ }
177
+ return null;
178
+ }
179
+
159
180
  class DragElement {
160
181
  constructor(_ref) {
161
182
  let {
@@ -170,6 +191,13 @@ var jqtree = (function (exports) {
170
191
  this.element = this.createElement(nodeName, autoEscape);
171
192
  treeElement.appendChild(this.element);
172
193
  }
194
+ move(pageX, pageY) {
195
+ this.element.style.left = `${pageX - this.offsetX}px`;
196
+ this.element.style.top = `${pageY - this.offsetY}px`;
197
+ }
198
+ remove() {
199
+ this.element.remove();
200
+ }
173
201
  createElement(nodeName, autoEscape) {
174
202
  const element = document.createElement("span");
175
203
  element.classList.add("jqtree-title", "jqtree-dragging");
@@ -181,13 +209,6 @@ var jqtree = (function (exports) {
181
209
  element.style.position = "absolute";
182
210
  return element;
183
211
  }
184
- move(pageX, pageY) {
185
- this.element.style.left = `${pageX - this.offsetX}px`;
186
- this.element.style.top = `${pageY - this.offsetY}px`;
187
- }
188
- remove() {
189
- this.element.remove();
190
- }
191
212
  }
192
213
 
193
214
  const iterateVisibleNodes = (tree, _ref) => {
@@ -407,15 +428,113 @@ var jqtree = (function (exports) {
407
428
  this.isDragging = false;
408
429
  this.currentItem = null;
409
430
  }
410
- canMoveToArea(area) {
411
- if (!this.onCanMoveTo) {
412
- return true;
431
+ mouseCapture(positionInfo) {
432
+ const element = positionInfo.target;
433
+ if (!this.mustCaptureElement(element)) {
434
+ return null;
435
+ }
436
+ if (this.onIsMoveHandle && !this.onIsMoveHandle(jQuery(element))) {
437
+ return null;
438
+ }
439
+ let nodeElement = this.getNodeElement(element);
440
+ if (nodeElement && this.onCanMove) {
441
+ if (!this.onCanMove(nodeElement.node)) {
442
+ nodeElement = null;
443
+ }
444
+ }
445
+ this.currentItem = nodeElement;
446
+ return this.currentItem != null;
447
+ }
448
+ mouseDrag(positionInfo) {
449
+ if (!this.currentItem || !this.dragElement) {
450
+ return false;
413
451
  }
452
+ this.dragElement.move(positionInfo.pageX, positionInfo.pageY);
453
+ const area = this.findHoveredArea(positionInfo.pageX, positionInfo.pageY);
454
+ if (area && this.canMoveToArea(area, this.currentItem)) {
455
+ if (!area.node.isFolder()) {
456
+ this.stopOpenFolderTimer();
457
+ }
458
+ if (this.hoveredArea !== area) {
459
+ this.hoveredArea = area;
460
+
461
+ // If this is a closed folder, start timer to open it
462
+ if (this.mustOpenFolderTimer(area)) {
463
+ this.startOpenFolderTimer(area.node);
464
+ } else {
465
+ this.stopOpenFolderTimer();
466
+ }
467
+ this.updateDropHint();
468
+ }
469
+ } else {
470
+ this.removeDropHint();
471
+ this.stopOpenFolderTimer();
472
+ this.hoveredArea = area;
473
+ }
474
+ if (!area) {
475
+ if (this.onDragMove) {
476
+ this.onDragMove(this.currentItem.node, positionInfo.originalEvent);
477
+ }
478
+ }
479
+ return true;
480
+ }
481
+ mouseStart(positionInfo) {
414
482
  if (!this.currentItem) {
415
483
  return false;
416
484
  }
485
+ this.refresh();
486
+ const {
487
+ left,
488
+ top
489
+ } = getElementPosition(positionInfo.target);
490
+ const node = this.currentItem.node;
491
+ this.dragElement = new DragElement({
492
+ autoEscape: this.autoEscape ?? true,
493
+ nodeName: node.name,
494
+ offsetX: positionInfo.pageX - left,
495
+ offsetY: positionInfo.pageY - top,
496
+ treeElement: this.treeElement
497
+ });
498
+ this.isDragging = true;
499
+ this.currentItem.element.classList.add("jqtree-moving");
500
+ return true;
501
+ }
502
+ mouseStop(positionInfo) {
503
+ this.moveItem(positionInfo);
504
+ this.clear();
505
+ this.removeHover();
506
+ this.removeDropHint();
507
+ this.removeHitAreas();
508
+ const currentItem = this.currentItem;
509
+ if (this.currentItem) {
510
+ this.currentItem.element.classList.remove("jqtree-moving");
511
+ this.currentItem = null;
512
+ }
513
+ this.isDragging = false;
514
+ if (!this.hoveredArea && currentItem) {
515
+ if (this.onDragStop) {
516
+ this.onDragStop(currentItem.node, positionInfo.originalEvent);
517
+ }
518
+ }
519
+ return false;
520
+ }
521
+ refresh() {
522
+ this.removeHitAreas();
523
+ if (this.currentItem) {
524
+ const currentNode = this.currentItem.node;
525
+ this.generateHitAreas(currentNode);
526
+ this.currentItem = this.getNodeElementForNode(currentNode);
527
+ if (this.isDragging) {
528
+ this.currentItem.element.classList.add("jqtree-moving");
529
+ }
530
+ }
531
+ }
532
+ canMoveToArea(area, currentItem) {
533
+ if (!this.onCanMoveTo) {
534
+ return true;
535
+ }
417
536
  const positionName = getPositionName(area.position);
418
- return this.onCanMoveTo(this.currentItem.node, area.node, positionName);
537
+ return this.onCanMoveTo(currentItem.node, area.node, positionName);
419
538
  }
420
539
  clear() {
421
540
  if (this.dragElement) {
@@ -428,30 +547,22 @@ var jqtree = (function (exports) {
428
547
  if (x < dimensions.left || y < dimensions.top || x > dimensions.right || y > dimensions.bottom) {
429
548
  return null;
430
549
  }
431
- let low = 0;
432
- let high = this.hitAreas.length;
433
- while (low < high) {
434
- const mid = low + high >> 1;
435
- const area = this.hitAreas[mid];
436
- if (!area) {
437
- return null;
438
- }
550
+ return binarySearch(this.hitAreas, area => {
439
551
  if (y < area.top) {
440
- high = mid;
552
+ return 1;
441
553
  } else if (y > area.bottom) {
442
- low = mid + 1;
554
+ return -1;
443
555
  } else {
444
- return area;
556
+ return 0;
445
557
  }
446
- }
447
- return null;
558
+ });
448
559
  }
449
- generateHitAreas() {
560
+ generateHitAreas(currentNode) {
450
561
  const tree = this.getTree();
451
- if (!this.currentItem || !tree) {
562
+ if (!tree) {
452
563
  this.hitAreas = [];
453
564
  } else {
454
- this.hitAreas = generateHitAreas(tree, this.currentItem.node, this.getTreeDimensions().bottom);
565
+ this.hitAreas = generateHitAreas(tree, currentNode, this.getTreeDimensions().bottom);
455
566
  }
456
567
  }
457
568
  getTreeDimensions() {
@@ -467,8 +578,10 @@ var jqtree = (function (exports) {
467
578
  top
468
579
  };
469
580
  }
581
+
582
+ /* Move the dragged node to the selected position in the tree. */
470
583
  moveItem(positionInfo) {
471
- if (this.currentItem && this.hoveredArea && this.hoveredArea.position !== Position.None && this.canMoveToArea(this.hoveredArea)) {
584
+ if (this.currentItem && this.hoveredArea && this.hoveredArea.position !== Position.None && this.canMoveToArea(this.hoveredArea, this.currentItem)) {
472
585
  const movedNode = this.currentItem.node;
473
586
  const targetNode = this.hoveredArea.node;
474
587
  const position = this.hoveredArea.position;
@@ -549,137 +662,71 @@ var jqtree = (function (exports) {
549
662
  const nodeElement = this.getNodeElementForNode(this.hoveredArea.node);
550
663
  this.previousGhost = nodeElement.addDropHint(this.hoveredArea.position);
551
664
  }
552
- mouseCapture(positionInfo) {
553
- const element = positionInfo.target;
554
- if (!this.mustCaptureElement(element)) {
555
- return null;
556
- }
557
- if (this.onIsMoveHandle && !this.onIsMoveHandle(jQuery(element))) {
558
- return null;
559
- }
560
- let nodeElement = this.getNodeElement(element);
561
- if (nodeElement && this.onCanMove) {
562
- if (!this.onCanMove(nodeElement.node)) {
563
- nodeElement = null;
564
- }
665
+ }
666
+
667
+ class ElementsRenderer {
668
+ constructor(_ref) {
669
+ let {
670
+ $element,
671
+ autoEscape,
672
+ buttonLeft,
673
+ closedIcon,
674
+ dragAndDrop,
675
+ getTree,
676
+ isNodeSelected,
677
+ onCreateLi,
678
+ openedIcon,
679
+ rtl,
680
+ showEmptyFolder,
681
+ tabIndex
682
+ } = _ref;
683
+ this.autoEscape = autoEscape;
684
+ this.buttonLeft = buttonLeft;
685
+ this.dragAndDrop = dragAndDrop;
686
+ this.$element = $element;
687
+ this.getTree = getTree;
688
+ this.isNodeSelected = isNodeSelected;
689
+ this.onCreateLi = onCreateLi;
690
+ this.rtl = rtl;
691
+ this.showEmptyFolder = showEmptyFolder;
692
+ this.tabIndex = tabIndex;
693
+ this.openedIconElement = this.createButtonElement(openedIcon ?? "+");
694
+ this.closedIconElement = this.createButtonElement(closedIcon ?? "-");
695
+ }
696
+ render(fromNode) {
697
+ if (fromNode?.parent) {
698
+ this.renderFromNode(fromNode);
699
+ } else {
700
+ this.renderFromRoot();
565
701
  }
566
- this.currentItem = nodeElement;
567
- return this.currentItem != null;
568
702
  }
569
- mouseDrag(positionInfo) {
570
- if (!this.currentItem || !this.dragElement) {
571
- return false;
703
+ renderFromNode(node) {
704
+ if (!node.element) {
705
+ return;
572
706
  }
573
- this.dragElement.move(positionInfo.pageX, positionInfo.pageY);
574
- const area = this.findHoveredArea(positionInfo.pageX, positionInfo.pageY);
575
- if (area && this.canMoveToArea(area)) {
576
- if (!area.node.isFolder()) {
577
- this.stopOpenFolderTimer();
578
- }
579
- if (this.hoveredArea !== area) {
580
- this.hoveredArea = area;
581
707
 
582
- // If this is a closed folder, start timer to open it
583
- if (this.mustOpenFolderTimer(area)) {
584
- this.startOpenFolderTimer(area.node);
585
- } else {
586
- this.stopOpenFolderTimer();
587
- }
588
- this.updateDropHint();
589
- }
590
- } else {
591
- this.removeDropHint();
592
- this.stopOpenFolderTimer();
593
- this.hoveredArea = area;
594
- }
595
- if (!area) {
596
- if (this.onDragMove) {
597
- this.onDragMove(this.currentItem.node, positionInfo.originalEvent);
598
- }
599
- }
600
- return true;
601
- }
602
- mouseStart(positionInfo) {
603
- if (!this.currentItem) {
604
- return false;
605
- }
606
- this.refresh();
607
- const {
608
- left,
609
- top
610
- } = getElementPosition(positionInfo.target);
611
- const node = this.currentItem.node;
612
- this.dragElement = new DragElement({
613
- autoEscape: this.autoEscape ?? true,
614
- nodeName: node.name,
615
- offsetX: positionInfo.pageX - left,
616
- offsetY: positionInfo.pageY - top,
617
- treeElement: this.treeElement
618
- });
619
- this.isDragging = true;
620
- this.currentItem.element.classList.add("jqtree-moving");
621
- return true;
622
- }
623
- mouseStop(positionInfo) {
624
- this.moveItem(positionInfo);
625
- this.clear();
626
- this.removeHover();
627
- this.removeDropHint();
628
- this.removeHitAreas();
629
- const currentItem = this.currentItem;
630
- if (this.currentItem) {
631
- this.currentItem.element.classList.remove("jqtree-moving");
632
- this.currentItem = null;
633
- }
634
- this.isDragging = false;
635
- if (!this.hoveredArea && currentItem) {
636
- if (this.onDragStop) {
637
- this.onDragStop(currentItem.node, positionInfo.originalEvent);
638
- }
639
- }
640
- return false;
708
+ // remember current li
709
+ const $previousLi = jQuery(node.element);
710
+
711
+ // create element
712
+ const li = this.createLi(node, node.getLevel());
713
+
714
+ // add element to dom
715
+ $previousLi.after(li);
716
+
717
+ // remove previous li
718
+ $previousLi.remove();
719
+
720
+ // create children
721
+ this.createDomElements(li, node.children, false, node.getLevel() + 1);
641
722
  }
642
- refresh() {
643
- this.removeHitAreas();
644
- if (this.currentItem) {
645
- this.generateHitAreas();
646
- this.currentItem = this.getNodeElementForNode(this.currentItem.node);
647
- if (this.isDragging) {
648
- this.currentItem.element.classList.add("jqtree-moving");
649
- }
723
+ renderFromRoot() {
724
+ this.$element.empty();
725
+ const tree = this.getTree();
726
+ if (this.$element[0] && tree) {
727
+ this.createDomElements(this.$element[0], tree.children, true, 1);
650
728
  }
651
729
  }
652
- }
653
-
654
- class ElementsRenderer {
655
- constructor(_ref) {
656
- let {
657
- $element,
658
- autoEscape,
659
- buttonLeft,
660
- closedIcon,
661
- dragAndDrop,
662
- getTree,
663
- isNodeSelected,
664
- onCreateLi,
665
- openedIcon,
666
- rtl,
667
- showEmptyFolder,
668
- tabIndex
669
- } = _ref;
670
- this.autoEscape = autoEscape;
671
- this.buttonLeft = buttonLeft;
672
- this.dragAndDrop = dragAndDrop;
673
- this.$element = $element;
674
- this.getTree = getTree;
675
- this.isNodeSelected = isNodeSelected;
676
- this.onCreateLi = onCreateLi;
677
- this.rtl = rtl;
678
- this.showEmptyFolder = showEmptyFolder;
679
- this.tabIndex = tabIndex;
680
- this.openedIconElement = this.createButtonElement(openedIcon ?? "+");
681
- this.closedIconElement = this.createButtonElement(closedIcon ?? "-");
682
- }
683
730
  attachNodeData(node, li) {
684
731
  node.element = li;
685
732
  jQuery(li).data("node", node);
@@ -854,43 +901,42 @@ var jqtree = (function (exports) {
854
901
  element.setAttribute("aria-selected", getBoolString(isSelected));
855
902
  element.setAttribute("role", "treeitem");
856
903
  }
857
- render(fromNode) {
858
- if (fromNode?.parent) {
859
- this.renderFromNode(fromNode);
860
- } else {
861
- this.renderFromRoot();
904
+ }
905
+
906
+ class KeyHandler {
907
+ constructor(_ref) {
908
+ let {
909
+ closeNode,
910
+ getSelectedNode,
911
+ isFocusOnTree,
912
+ keyboardSupport,
913
+ openNode,
914
+ selectNode
915
+ } = _ref;
916
+ this.closeNode = closeNode;
917
+ this.getSelectedNode = getSelectedNode;
918
+ this.isFocusOnTree = isFocusOnTree;
919
+ this.keyboardSupport = keyboardSupport;
920
+ this.openNode = openNode;
921
+ this.originalSelectNode = selectNode;
922
+ if (keyboardSupport) {
923
+ document.addEventListener("keydown", this.handleKeyDown);
862
924
  }
863
925
  }
864
- renderFromNode(node) {
865
- if (!node.element) {
866
- return;
926
+ deinit() {
927
+ if (this.keyboardSupport) {
928
+ document.removeEventListener("keydown", this.handleKeyDown);
867
929
  }
868
-
869
- // remember current li
870
- const $previousLi = jQuery(node.element);
871
-
872
- // create element
873
- const li = this.createLi(node, node.getLevel());
874
-
875
- // add element to dom
876
- $previousLi.after(li);
877
-
878
- // remove previous li
879
- $previousLi.remove();
880
-
881
- // create children
882
- this.createDomElements(li, node.children, false, node.getLevel() + 1);
883
930
  }
884
- renderFromRoot() {
885
- this.$element.empty();
886
- const tree = this.getTree();
887
- if (this.$element[0] && tree) {
888
- this.createDomElements(this.$element[0], tree.children, true, 1);
889
- }
931
+ moveDown(selectedNode) {
932
+ return this.selectNode(selectedNode.getNextVisibleNode());
933
+ }
934
+ moveUp(selectedNode) {
935
+ return this.selectNode(selectedNode.getPreviousVisibleNode());
936
+ }
937
+ canHandleKeyboard() {
938
+ return this.keyboardSupport && this.isFocusOnTree();
890
939
  }
891
- }
892
-
893
- class KeyHandler {
894
940
  handleKeyDown = e => {
895
941
  if (!this.canHandleKeyboard()) {
896
942
  return;
@@ -917,28 +963,6 @@ var jqtree = (function (exports) {
917
963
  e.preventDefault();
918
964
  }
919
965
  };
920
- constructor(_ref) {
921
- let {
922
- closeNode,
923
- getSelectedNode,
924
- isFocusOnTree,
925
- keyboardSupport,
926
- openNode,
927
- selectNode
928
- } = _ref;
929
- this.closeNode = closeNode;
930
- this.getSelectedNode = getSelectedNode;
931
- this.isFocusOnTree = isFocusOnTree;
932
- this.keyboardSupport = keyboardSupport;
933
- this.openNode = openNode;
934
- this.originalSelectNode = selectNode;
935
- if (keyboardSupport) {
936
- document.addEventListener("keydown", this.handleKeyDown);
937
- }
938
- }
939
- canHandleKeyboard() {
940
- return this.keyboardSupport && this.isFocusOnTree();
941
- }
942
966
  moveLeft(selectedNode) {
943
967
  if (selectedNode.isFolder() && selectedNode.is_open) {
944
968
  // Left on an open node closes the node
@@ -977,17 +1001,6 @@ var jqtree = (function (exports) {
977
1001
  return true;
978
1002
  }
979
1003
  }
980
- deinit() {
981
- if (this.keyboardSupport) {
982
- document.removeEventListener("keydown", this.handleKeyDown);
983
- }
984
- }
985
- moveDown(selectedNode) {
986
- return this.selectNode(selectedNode.getNextVisibleNode());
987
- }
988
- moveUp(selectedNode) {
989
- return this.selectNode(selectedNode.getPreviousVisibleNode());
990
- }
991
1004
  }
992
1005
 
993
1006
  const getPositionInfoFromMouseEvent = e => ({
@@ -1004,22 +1017,97 @@ var jqtree = (function (exports) {
1004
1017
  });
1005
1018
 
1006
1019
  class MouseHandler {
1007
- handleClick = e => {
1008
- if (!e.target) {
1009
- return;
1020
+ constructor(_ref) {
1021
+ let {
1022
+ element,
1023
+ getMouseDelay,
1024
+ getNode,
1025
+ onClickButton,
1026
+ onClickTitle,
1027
+ onMouseCapture,
1028
+ onMouseDrag,
1029
+ onMouseStart,
1030
+ onMouseStop,
1031
+ triggerEvent,
1032
+ useContextMenu
1033
+ } = _ref;
1034
+ this.element = element;
1035
+ this.getMouseDelay = getMouseDelay;
1036
+ this.getNode = getNode;
1037
+ this.onClickButton = onClickButton;
1038
+ this.onClickTitle = onClickTitle;
1039
+ this.onMouseCapture = onMouseCapture;
1040
+ this.onMouseDrag = onMouseDrag;
1041
+ this.onMouseStart = onMouseStart;
1042
+ this.onMouseStop = onMouseStop;
1043
+ this.triggerEvent = triggerEvent;
1044
+ this.useContextMenu = useContextMenu;
1045
+ element.addEventListener("click", this.handleClick);
1046
+ element.addEventListener("dblclick", this.handleDblclick);
1047
+ element.addEventListener("mousedown", this.mouseDown, {
1048
+ passive: false
1049
+ });
1050
+ element.addEventListener("touchstart", this.touchStart, {
1051
+ passive: false
1052
+ });
1053
+ if (useContextMenu) {
1054
+ element.addEventListener("contextmenu", this.handleContextmenu);
1010
1055
  }
1011
- const clickTarget = this.getClickTarget(e.target);
1012
- if (!clickTarget) {
1013
- return;
1056
+ this.isMouseStarted = false;
1057
+ this.mouseDelayTimer = null;
1058
+ this.isMouseDelayMet = false;
1059
+ this.mouseDownInfo = null;
1060
+ }
1061
+ deinit() {
1062
+ this.element.removeEventListener("click", this.handleClick);
1063
+ this.element.removeEventListener("dblclick", this.handleDblclick);
1064
+ if (this.useContextMenu) {
1065
+ this.element.removeEventListener("contextmenu", this.handleContextmenu);
1014
1066
  }
1015
- switch (clickTarget.type) {
1016
- case "button":
1017
- this.onClickButton(clickTarget.node);
1018
- e.preventDefault();
1019
- e.stopPropagation();
1020
- break;
1021
- case "label":
1022
- {
1067
+ this.element.removeEventListener("mousedown", this.mouseDown);
1068
+ this.element.removeEventListener("touchstart", this.touchStart);
1069
+ this.removeMouseMoveEventListeners();
1070
+ }
1071
+ getClickTarget(element) {
1072
+ const button = element.closest(".jqtree-toggler");
1073
+ if (button) {
1074
+ const node = this.getNode(button);
1075
+ if (node) {
1076
+ return {
1077
+ node,
1078
+ type: "button"
1079
+ };
1080
+ }
1081
+ } else {
1082
+ const jqTreeElement = element.closest(".jqtree-element");
1083
+ if (jqTreeElement) {
1084
+ const node = this.getNode(jqTreeElement);
1085
+ if (node) {
1086
+ return {
1087
+ node,
1088
+ type: "label"
1089
+ };
1090
+ }
1091
+ }
1092
+ }
1093
+ return null;
1094
+ }
1095
+ handleClick = e => {
1096
+ if (!e.target) {
1097
+ return;
1098
+ }
1099
+ const clickTarget = this.getClickTarget(e.target);
1100
+ if (!clickTarget) {
1101
+ return;
1102
+ }
1103
+ switch (clickTarget.type) {
1104
+ case "button":
1105
+ this.onClickButton(clickTarget.node);
1106
+ e.preventDefault();
1107
+ e.stopPropagation();
1108
+ break;
1109
+ case "label":
1110
+ {
1023
1111
  const event = this.triggerEvent("tree.click", {
1024
1112
  click_event: e,
1025
1113
  node: clickTarget.node
@@ -1062,117 +1150,6 @@ var jqtree = (function (exports) {
1062
1150
  });
1063
1151
  }
1064
1152
  };
1065
- mouseDown = e => {
1066
- // Left mouse button?
1067
- if (e.button !== 0) {
1068
- return;
1069
- }
1070
- const result = this.handleMouseDown(getPositionInfoFromMouseEvent(e));
1071
- if (result && e.cancelable) {
1072
- e.preventDefault();
1073
- }
1074
- };
1075
- mouseMove = e => {
1076
- this.handleMouseMove(e, getPositionInfoFromMouseEvent(e));
1077
- };
1078
- mouseUp = e => {
1079
- this.handleMouseUp(getPositionInfoFromMouseEvent(e));
1080
- };
1081
- touchEnd = e => {
1082
- if (e.touches.length > 1) {
1083
- return;
1084
- }
1085
- const touch = e.touches[0];
1086
- if (!touch) {
1087
- return;
1088
- }
1089
- this.handleMouseUp(getPositionInfoFromTouch(touch, e));
1090
- };
1091
- touchMove = e => {
1092
- if (e.touches.length > 1) {
1093
- return;
1094
- }
1095
- const touch = e.touches[0];
1096
- if (!touch) {
1097
- return;
1098
- }
1099
- this.handleMouseMove(e, getPositionInfoFromTouch(touch, e));
1100
- };
1101
- touchStart = e => {
1102
- if (e.touches.length > 1) {
1103
- return;
1104
- }
1105
- const touch = e.touches[0];
1106
- if (!touch) {
1107
- return;
1108
- }
1109
- this.handleMouseDown(getPositionInfoFromTouch(touch, e));
1110
- };
1111
- constructor(_ref) {
1112
- let {
1113
- element,
1114
- getMouseDelay,
1115
- getNode,
1116
- onClickButton,
1117
- onClickTitle,
1118
- onMouseCapture,
1119
- onMouseDrag,
1120
- onMouseStart,
1121
- onMouseStop,
1122
- triggerEvent,
1123
- useContextMenu
1124
- } = _ref;
1125
- this.element = element;
1126
- this.getMouseDelay = getMouseDelay;
1127
- this.getNode = getNode;
1128
- this.onClickButton = onClickButton;
1129
- this.onClickTitle = onClickTitle;
1130
- this.onMouseCapture = onMouseCapture;
1131
- this.onMouseDrag = onMouseDrag;
1132
- this.onMouseStart = onMouseStart;
1133
- this.onMouseStop = onMouseStop;
1134
- this.triggerEvent = triggerEvent;
1135
- this.useContextMenu = useContextMenu;
1136
- element.addEventListener("click", this.handleClick);
1137
- element.addEventListener("dblclick", this.handleDblclick);
1138
- element.addEventListener("mousedown", this.mouseDown, {
1139
- passive: false
1140
- });
1141
- element.addEventListener("touchstart", this.touchStart, {
1142
- passive: false
1143
- });
1144
- if (useContextMenu) {
1145
- element.addEventListener("contextmenu", this.handleContextmenu);
1146
- }
1147
- this.isMouseStarted = false;
1148
- this.mouseDelayTimer = null;
1149
- this.isMouseDelayMet = false;
1150
- this.mouseDownInfo = null;
1151
- }
1152
- getClickTarget(element) {
1153
- const button = element.closest(".jqtree-toggler");
1154
- if (button) {
1155
- const node = this.getNode(button);
1156
- if (node) {
1157
- return {
1158
- node,
1159
- type: "button"
1160
- };
1161
- }
1162
- } else {
1163
- const jqTreeElement = element.closest(".jqtree-element");
1164
- if (jqTreeElement) {
1165
- const node = this.getNode(jqTreeElement);
1166
- if (node) {
1167
- return {
1168
- node,
1169
- type: "label"
1170
- };
1171
- }
1172
- }
1173
- }
1174
- return null;
1175
- }
1176
1153
  handleMouseDown(positionInfo) {
1177
1154
  // We may have missed mouseup (out of window)
1178
1155
  if (this.isMouseStarted) {
@@ -1237,6 +1214,22 @@ var jqtree = (function (exports) {
1237
1214
  this.isMouseDelayMet = true;
1238
1215
  }
1239
1216
  }
1217
+ mouseDown = e => {
1218
+ // Left mouse button?
1219
+ if (e.button !== 0) {
1220
+ return;
1221
+ }
1222
+ const result = this.handleMouseDown(getPositionInfoFromMouseEvent(e));
1223
+ if (result && e.cancelable) {
1224
+ e.preventDefault();
1225
+ }
1226
+ };
1227
+ mouseMove = e => {
1228
+ this.handleMouseMove(e, getPositionInfoFromMouseEvent(e));
1229
+ };
1230
+ mouseUp = e => {
1231
+ this.handleMouseUp(getPositionInfoFromMouseEvent(e));
1232
+ };
1240
1233
  removeMouseMoveEventListeners() {
1241
1234
  document.removeEventListener("mousemove", this.mouseMove);
1242
1235
  document.removeEventListener("touchmove", this.touchMove);
@@ -1254,16 +1247,36 @@ var jqtree = (function (exports) {
1254
1247
  }, mouseDelay);
1255
1248
  this.isMouseDelayMet = false;
1256
1249
  }
1257
- deinit() {
1258
- this.element.removeEventListener("click", this.handleClick);
1259
- this.element.removeEventListener("dblclick", this.handleDblclick);
1260
- if (this.useContextMenu) {
1261
- this.element.removeEventListener("contextmenu", this.handleContextmenu);
1250
+ touchEnd = e => {
1251
+ if (e.touches.length > 1) {
1252
+ return;
1262
1253
  }
1263
- this.element.removeEventListener("mousedown", this.mouseDown);
1264
- this.element.removeEventListener("touchstart", this.touchStart);
1265
- this.removeMouseMoveEventListeners();
1266
- }
1254
+ const touch = e.touches[0];
1255
+ if (!touch) {
1256
+ return;
1257
+ }
1258
+ this.handleMouseUp(getPositionInfoFromTouch(touch, e));
1259
+ };
1260
+ touchMove = e => {
1261
+ if (e.touches.length > 1) {
1262
+ return;
1263
+ }
1264
+ const touch = e.touches[0];
1265
+ if (!touch) {
1266
+ return;
1267
+ }
1268
+ this.handleMouseMove(e, getPositionInfoFromTouch(touch, e));
1269
+ };
1270
+ touchStart = e => {
1271
+ if (e.touches.length > 1) {
1272
+ return;
1273
+ }
1274
+ const touch = e.touches[0];
1275
+ if (!touch) {
1276
+ return;
1277
+ }
1278
+ this.handleMouseDown(getPositionInfoFromTouch(touch, e));
1279
+ };
1267
1280
  }
1268
1281
 
1269
1282
  const isNodeRecordWithChildren = data => typeof data === "object" && "children" in data && data.children instanceof Array;
@@ -1285,29 +1298,6 @@ var jqtree = (function (exports) {
1285
1298
  this.nodeClass = nodeClass;
1286
1299
  }
1287
1300
  }
1288
- createNode(nodeData) {
1289
- const nodeClass = this.getNodeClass();
1290
- return new nodeClass(nodeData);
1291
- }
1292
- doRemoveChild(node) {
1293
- this.children.splice(this.getChildIndex(node), 1);
1294
- this.tree?.removeNodeFromIndex(node);
1295
- }
1296
- getNodeClass() {
1297
- return this.nodeClass ?? this.tree?.nodeClass ?? Node;
1298
- }
1299
-
1300
- // Load children data from nodeInfo if it has children
1301
- loadChildrenFromData(nodeInfo) {
1302
- if (isNodeRecordWithChildren(nodeInfo) && nodeInfo.children.length) {
1303
- this.loadFromData(nodeInfo.children);
1304
- }
1305
- }
1306
- setParent(parent) {
1307
- this.parent = parent;
1308
- this.tree = parent.tree;
1309
- this.tree?.addNodeToIndex(this);
1310
- }
1311
1301
  addAfter(nodeInfo) {
1312
1302
  if (!this.parent) {
1313
1303
  return null;
@@ -1783,6 +1773,29 @@ var jqtree = (function (exports) {
1783
1773
  }
1784
1774
  }
1785
1775
  }
1776
+ createNode(nodeData) {
1777
+ const nodeClass = this.getNodeClass();
1778
+ return new nodeClass(nodeData);
1779
+ }
1780
+ doRemoveChild(node) {
1781
+ this.children.splice(this.getChildIndex(node), 1);
1782
+ this.tree?.removeNodeFromIndex(node);
1783
+ }
1784
+ getNodeClass() {
1785
+ return this.nodeClass ?? this.tree?.nodeClass ?? Node;
1786
+ }
1787
+
1788
+ // Load children data from nodeInfo if it has children
1789
+ loadChildrenFromData(nodeInfo) {
1790
+ if (isNodeRecordWithChildren(nodeInfo) && nodeInfo.children.length) {
1791
+ this.loadFromData(nodeInfo.children);
1792
+ }
1793
+ }
1794
+ setParent(parent) {
1795
+ this.parent = parent;
1796
+ this.tree = parent.tree;
1797
+ this.tree?.addNodeToIndex(this);
1798
+ }
1786
1799
  }
1787
1800
 
1788
1801
  class BorderDropHint {
@@ -1828,7 +1841,10 @@ var jqtree = (function (exports) {
1828
1841
  }
1829
1842
  }
1830
1843
  }
1831
- createGhostElement() {
1844
+ remove() {
1845
+ this.ghost.remove();
1846
+ }
1847
+ createGhostElement() {
1832
1848
  const ghost = document.createElement("li");
1833
1849
  ghost.className = "jqtree_common jqtree-ghost";
1834
1850
  const circleSpan = document.createElement("span");
@@ -1855,9 +1871,6 @@ var jqtree = (function (exports) {
1855
1871
  childElement.before(this.ghost);
1856
1872
  }
1857
1873
  }
1858
- remove() {
1859
- this.ghost.remove();
1860
- }
1861
1874
  }
1862
1875
 
1863
1876
  class NodeElement {
@@ -1873,15 +1886,6 @@ var jqtree = (function (exports) {
1873
1886
  this.treeElement = treeElement;
1874
1887
  this.init(node);
1875
1888
  }
1876
- getTitleSpan() {
1877
- return this.element.querySelector(":scope > .jqtree-element > span.jqtree-title");
1878
- }
1879
- getUl() {
1880
- return this.element.querySelector(":scope > ul");
1881
- }
1882
- mustShowBorderDropHint(position) {
1883
- return position === Position.Inside;
1884
- }
1885
1889
  addDropHint(position) {
1886
1890
  if (this.mustShowBorderDropHint(position)) {
1887
1891
  return new BorderDropHint(this.element, this.getScrollLeft());
@@ -1917,6 +1921,15 @@ var jqtree = (function (exports) {
1917
1921
  titleSpan.focus();
1918
1922
  }
1919
1923
  }
1924
+ getTitleSpan() {
1925
+ return this.element.querySelector(":scope > .jqtree-element > span.jqtree-title");
1926
+ }
1927
+ getUl() {
1928
+ return this.element.querySelector(":scope > ul");
1929
+ }
1930
+ mustShowBorderDropHint(position) {
1931
+ return position === Position.Inside;
1932
+ }
1920
1933
  }
1921
1934
 
1922
1935
  class FolderElement extends NodeElement {
@@ -1940,12 +1953,6 @@ var jqtree = (function (exports) {
1940
1953
  this.openedIconElement = openedIconElement;
1941
1954
  this.triggerEvent = triggerEvent;
1942
1955
  }
1943
- mustShowBorderDropHint(position) {
1944
- return !this.node.is_open && position === Position.Inside;
1945
- }
1946
- getButton() {
1947
- return this.element.querySelector(":scope > .jqtree-element > a.jqtree-toggler");
1948
- }
1949
1956
  close(slide, animationSpeed) {
1950
1957
  if (!this.node.is_open) {
1951
1958
  return;
@@ -2005,6 +2012,12 @@ var jqtree = (function (exports) {
2005
2012
  doOpen();
2006
2013
  }
2007
2014
  }
2015
+ mustShowBorderDropHint(position) {
2016
+ return !this.node.is_open && position === Position.Inside;
2017
+ }
2018
+ getButton() {
2019
+ return this.element.querySelector(":scope > .jqtree-element > a.jqtree-toggler");
2020
+ }
2008
2021
  }
2009
2022
 
2010
2023
  class SaveStateHandler {
@@ -2032,61 +2045,6 @@ var jqtree = (function (exports) {
2032
2045
  this.removeFromSelection = removeFromSelection;
2033
2046
  this.saveStateOption = saveState;
2034
2047
  }
2035
- getKeyName() {
2036
- if (typeof this.saveStateOption === "string") {
2037
- return this.saveStateOption;
2038
- } else {
2039
- return "tree";
2040
- }
2041
- }
2042
- loadFromStorage() {
2043
- if (this.onGetStateFromStorage) {
2044
- return this.onGetStateFromStorage();
2045
- } else {
2046
- return localStorage.getItem(this.getKeyName());
2047
- }
2048
- }
2049
- openInitialNodes(nodeIds) {
2050
- let mustLoadOnDemand = false;
2051
- for (const nodeId of nodeIds) {
2052
- const node = this.getNodeById(nodeId);
2053
- if (node) {
2054
- if (!node.load_on_demand) {
2055
- node.is_open = true;
2056
- } else {
2057
- mustLoadOnDemand = true;
2058
- }
2059
- }
2060
- }
2061
- return mustLoadOnDemand;
2062
- }
2063
- parseState(jsonData) {
2064
- const state = JSON.parse(jsonData);
2065
-
2066
- // Check if selected_node is an int (instead of an array)
2067
- if (state.selected_node && isInt(state.selected_node)) {
2068
- // Convert to array
2069
- state.selected_node = [state.selected_node];
2070
- }
2071
- return state;
2072
- }
2073
- resetSelection() {
2074
- const selectedNodes = this.getSelectedNodes();
2075
- selectedNodes.forEach(node => {
2076
- this.removeFromSelection(node);
2077
- });
2078
- }
2079
- selectInitialNodes(nodeIds) {
2080
- let selectCount = 0;
2081
- for (const nodeId of nodeIds) {
2082
- const node = this.getNodeById(nodeId);
2083
- if (node) {
2084
- selectCount += 1;
2085
- this.addToSelection(node);
2086
- }
2087
- }
2088
- return selectCount !== 0;
2089
- }
2090
2048
  getNodeIdToBeSelected() {
2091
2049
  const state = this.getStateFromStorage();
2092
2050
  if (state?.selected_node) {
@@ -2194,6 +2152,61 @@ var jqtree = (function (exports) {
2194
2152
  };
2195
2153
  openNodes();
2196
2154
  }
2155
+ getKeyName() {
2156
+ if (typeof this.saveStateOption === "string") {
2157
+ return this.saveStateOption;
2158
+ } else {
2159
+ return "tree";
2160
+ }
2161
+ }
2162
+ loadFromStorage() {
2163
+ if (this.onGetStateFromStorage) {
2164
+ return this.onGetStateFromStorage();
2165
+ } else {
2166
+ return localStorage.getItem(this.getKeyName());
2167
+ }
2168
+ }
2169
+ openInitialNodes(nodeIds) {
2170
+ let mustLoadOnDemand = false;
2171
+ for (const nodeId of nodeIds) {
2172
+ const node = this.getNodeById(nodeId);
2173
+ if (node) {
2174
+ if (!node.load_on_demand) {
2175
+ node.is_open = true;
2176
+ } else {
2177
+ mustLoadOnDemand = true;
2178
+ }
2179
+ }
2180
+ }
2181
+ return mustLoadOnDemand;
2182
+ }
2183
+ parseState(jsonData) {
2184
+ const state = JSON.parse(jsonData);
2185
+
2186
+ // Check if selected_node is an int (instead of an array)
2187
+ if (state.selected_node && isInt(state.selected_node)) {
2188
+ // Convert to array
2189
+ state.selected_node = [state.selected_node];
2190
+ }
2191
+ return state;
2192
+ }
2193
+ resetSelection() {
2194
+ const selectedNodes = this.getSelectedNodes();
2195
+ selectedNodes.forEach(node => {
2196
+ this.removeFromSelection(node);
2197
+ });
2198
+ }
2199
+ selectInitialNodes(nodeIds) {
2200
+ let selectCount = 0;
2201
+ for (const nodeId of nodeIds) {
2202
+ const node = this.getNodeById(nodeId);
2203
+ if (node) {
2204
+ selectCount += 1;
2205
+ this.addToSelection(node);
2206
+ }
2207
+ }
2208
+ return selectCount !== 0;
2209
+ }
2197
2210
  }
2198
2211
 
2199
2212
  class ContainerScrollParent {
@@ -2205,6 +2218,43 @@ var jqtree = (function (exports) {
2205
2218
  this.container = container;
2206
2219
  this.refreshHitAreas = refreshHitAreas;
2207
2220
  }
2221
+ checkHorizontalScrolling(pageX) {
2222
+ const newHorizontalScrollDirection = this.getNewHorizontalScrollDirection(pageX);
2223
+ if (this.horizontalScrollDirection !== newHorizontalScrollDirection) {
2224
+ this.horizontalScrollDirection = newHorizontalScrollDirection;
2225
+ if (this.horizontalScrollTimeout != null) {
2226
+ window.clearTimeout(this.verticalScrollTimeout);
2227
+ }
2228
+ if (newHorizontalScrollDirection) {
2229
+ this.horizontalScrollTimeout = window.setTimeout(this.scrollHorizontally.bind(this), 40);
2230
+ }
2231
+ }
2232
+ }
2233
+ checkVerticalScrolling(pageY) {
2234
+ const newVerticalScrollDirection = this.getNewVerticalScrollDirection(pageY);
2235
+ if (this.verticalScrollDirection !== newVerticalScrollDirection) {
2236
+ this.verticalScrollDirection = newVerticalScrollDirection;
2237
+ if (this.verticalScrollTimeout != null) {
2238
+ window.clearTimeout(this.verticalScrollTimeout);
2239
+ this.verticalScrollTimeout = undefined;
2240
+ }
2241
+ if (newVerticalScrollDirection) {
2242
+ this.verticalScrollTimeout = window.setTimeout(this.scrollVertically.bind(this), 40);
2243
+ }
2244
+ }
2245
+ }
2246
+ getScrollLeft() {
2247
+ return this.container.scrollLeft;
2248
+ }
2249
+ scrollToY(top) {
2250
+ this.container.scrollTop = top;
2251
+ }
2252
+ stopScrolling() {
2253
+ this.horizontalScrollDirection = undefined;
2254
+ this.verticalScrollDirection = undefined;
2255
+ this.scrollParentTop = undefined;
2256
+ this.scrollParentBottom = undefined;
2257
+ }
2208
2258
  getNewHorizontalScrollDirection(pageX) {
2209
2259
  const scrollParentOffset = getElementPosition(this.container);
2210
2260
  const rightEdge = scrollParentOffset.left + this.container.clientWidth;
@@ -2265,12 +2315,23 @@ var jqtree = (function (exports) {
2265
2315
  this.refreshHitAreas();
2266
2316
  setTimeout(this.scrollVertically.bind(this), 40);
2267
2317
  }
2318
+ }
2319
+
2320
+ class DocumentScrollParent {
2321
+ constructor(_ref) {
2322
+ let {
2323
+ refreshHitAreas,
2324
+ treeElement
2325
+ } = _ref;
2326
+ this.refreshHitAreas = refreshHitAreas;
2327
+ this.treeElement = treeElement;
2328
+ }
2268
2329
  checkHorizontalScrolling(pageX) {
2269
2330
  const newHorizontalScrollDirection = this.getNewHorizontalScrollDirection(pageX);
2270
2331
  if (this.horizontalScrollDirection !== newHorizontalScrollDirection) {
2271
2332
  this.horizontalScrollDirection = newHorizontalScrollDirection;
2272
2333
  if (this.horizontalScrollTimeout != null) {
2273
- window.clearTimeout(this.verticalScrollTimeout);
2334
+ window.clearTimeout(this.horizontalScrollTimeout);
2274
2335
  }
2275
2336
  if (newHorizontalScrollDirection) {
2276
2337
  this.horizontalScrollTimeout = window.setTimeout(this.scrollHorizontally.bind(this), 40);
@@ -2291,27 +2352,17 @@ var jqtree = (function (exports) {
2291
2352
  }
2292
2353
  }
2293
2354
  getScrollLeft() {
2294
- return this.container.scrollLeft;
2355
+ return document.documentElement.scrollLeft;
2295
2356
  }
2296
2357
  scrollToY(top) {
2297
- this.container.scrollTop = top;
2358
+ const treeTop = getOffsetTop(this.treeElement);
2359
+ document.documentElement.scrollTop = top + treeTop;
2298
2360
  }
2299
2361
  stopScrolling() {
2300
2362
  this.horizontalScrollDirection = undefined;
2301
2363
  this.verticalScrollDirection = undefined;
2302
- this.scrollParentTop = undefined;
2303
- this.scrollParentBottom = undefined;
2304
- }
2305
- }
2306
-
2307
- class DocumentScrollParent {
2308
- constructor(_ref) {
2309
- let {
2310
- refreshHitAreas,
2311
- treeElement
2312
- } = _ref;
2313
- this.refreshHitAreas = refreshHitAreas;
2314
- this.treeElement = treeElement;
2364
+ this.documentScrollHeight = undefined;
2365
+ this.documentScrollWidth = undefined;
2315
2366
  }
2316
2367
  canScrollDown() {
2317
2368
  const documentElement = document.documentElement;
@@ -2386,44 +2437,6 @@ var jqtree = (function (exports) {
2386
2437
  this.refreshHitAreas();
2387
2438
  setTimeout(this.scrollVertically.bind(this), 40);
2388
2439
  }
2389
- checkHorizontalScrolling(pageX) {
2390
- const newHorizontalScrollDirection = this.getNewHorizontalScrollDirection(pageX);
2391
- if (this.horizontalScrollDirection !== newHorizontalScrollDirection) {
2392
- this.horizontalScrollDirection = newHorizontalScrollDirection;
2393
- if (this.horizontalScrollTimeout != null) {
2394
- window.clearTimeout(this.horizontalScrollTimeout);
2395
- }
2396
- if (newHorizontalScrollDirection) {
2397
- this.horizontalScrollTimeout = window.setTimeout(this.scrollHorizontally.bind(this), 40);
2398
- }
2399
- }
2400
- }
2401
- checkVerticalScrolling(pageY) {
2402
- const newVerticalScrollDirection = this.getNewVerticalScrollDirection(pageY);
2403
- if (this.verticalScrollDirection !== newVerticalScrollDirection) {
2404
- this.verticalScrollDirection = newVerticalScrollDirection;
2405
- if (this.verticalScrollTimeout != null) {
2406
- window.clearTimeout(this.verticalScrollTimeout);
2407
- this.verticalScrollTimeout = undefined;
2408
- }
2409
- if (newVerticalScrollDirection) {
2410
- this.verticalScrollTimeout = window.setTimeout(this.scrollVertically.bind(this), 40);
2411
- }
2412
- }
2413
- }
2414
- getScrollLeft() {
2415
- return document.documentElement.scrollLeft;
2416
- }
2417
- scrollToY(top) {
2418
- const treeTop = getOffsetTop(this.treeElement);
2419
- document.documentElement.scrollTop = top + treeTop;
2420
- }
2421
- stopScrolling() {
2422
- this.horizontalScrollDirection = undefined;
2423
- this.verticalScrollDirection = undefined;
2424
- this.documentScrollHeight = undefined;
2425
- this.documentScrollWidth = undefined;
2426
- }
2427
2440
  }
2428
2441
 
2429
2442
  const isOverflow = overflowValue => overflowValue === "auto" || overflowValue === "scroll";
@@ -2469,18 +2482,6 @@ var jqtree = (function (exports) {
2469
2482
  this.scrollParent = undefined;
2470
2483
  this.treeElement = treeElement;
2471
2484
  }
2472
- checkHorizontalScrolling(positionInfo) {
2473
- this.getScrollParent().checkHorizontalScrolling(positionInfo.pageX);
2474
- }
2475
- checkVerticalScrolling(positionInfo) {
2476
- this.getScrollParent().checkVerticalScrolling(positionInfo.pageY);
2477
- }
2478
- getScrollParent() {
2479
- if (!this.scrollParent) {
2480
- this.scrollParent = createScrollParent(this.treeElement, this.refreshHitAreas);
2481
- }
2482
- return this.scrollParent;
2483
- }
2484
2485
  checkScrolling(positionInfo) {
2485
2486
  this.checkVerticalScrolling(positionInfo);
2486
2487
  this.checkHorizontalScrolling(positionInfo);
@@ -2494,6 +2495,18 @@ var jqtree = (function (exports) {
2494
2495
  stopScrolling() {
2495
2496
  this.getScrollParent().stopScrolling();
2496
2497
  }
2498
+ checkHorizontalScrolling(positionInfo) {
2499
+ this.getScrollParent().checkHorizontalScrolling(positionInfo.pageX);
2500
+ }
2501
+ checkVerticalScrolling(positionInfo) {
2502
+ this.getScrollParent().checkVerticalScrolling(positionInfo.pageY);
2503
+ }
2504
+ getScrollParent() {
2505
+ if (!this.scrollParent) {
2506
+ this.scrollParent = createScrollParent(this.treeElement, this.refreshHitAreas);
2507
+ }
2508
+ return this.scrollParent;
2509
+ }
2497
2510
  }
2498
2511
 
2499
2512
  class SelectNodeHandler {
@@ -2739,817 +2752,213 @@ var jqtree = (function (exports) {
2739
2752
  tabIndex: 0,
2740
2753
  useContextMenu: true
2741
2754
  }))();
2742
- connectHandlers() {
2743
- const {
2744
- autoEscape,
2745
- buttonLeft,
2746
- closedIcon,
2747
- dataFilter,
2748
- dragAndDrop,
2749
- keyboardSupport,
2750
- onCanMove,
2751
- onCanMoveTo,
2752
- onCreateLi,
2753
- onDragMove,
2754
- onDragStop,
2755
- onGetStateFromStorage,
2756
- onIsMoveHandle,
2757
- onLoadFailed,
2758
- onLoading,
2759
- onSetStateFromStorage,
2760
- openedIcon,
2761
- openFolderDelay,
2762
- rtl,
2763
- saveState,
2764
- showEmptyFolder,
2765
- slide,
2766
- tabIndex
2767
- } = this.options;
2768
- const closeNode = this.closeNode.bind(this);
2769
- const getNodeElement = this.getNodeElement.bind(this);
2770
- const getNodeElementForNode = this.getNodeElementForNode.bind(this);
2771
- const getNodeById = this.getNodeById.bind(this);
2772
- const getSelectedNode = this.getSelectedNode.bind(this);
2773
- const getTree = this.getTree.bind(this);
2774
- const isFocusOnTree = this.isFocusOnTree.bind(this);
2775
- const loadData = this.loadData.bind(this);
2776
- const openNode = this.openNodeInternal.bind(this);
2777
- const refreshElements = this.refreshElements.bind(this);
2778
- const refreshHitAreas = this.refreshHitAreas.bind(this);
2779
- const selectNode = this.selectNode.bind(this);
2780
- const $treeElement = this.element;
2781
- const treeElement = this.element.get(0);
2782
- const triggerEvent = this.triggerEvent.bind(this);
2783
- const selectNodeHandler = new SelectNodeHandler({
2784
- getNodeById
2785
- });
2786
- const addToSelection = selectNodeHandler.addToSelection.bind(selectNodeHandler);
2787
- const getSelectedNodes = selectNodeHandler.getSelectedNodes.bind(selectNodeHandler);
2788
- const isNodeSelected = selectNodeHandler.isNodeSelected.bind(selectNodeHandler);
2789
- const removeFromSelection = selectNodeHandler.removeFromSelection.bind(selectNodeHandler);
2790
- const getMouseDelay = () => this.options.startDndDelay ?? 0;
2791
- const dataLoader = new DataLoader({
2792
- dataFilter,
2793
- loadData,
2794
- onLoadFailed,
2795
- onLoading,
2796
- treeElement,
2797
- triggerEvent
2798
- });
2799
- const saveStateHandler = new SaveStateHandler({
2800
- addToSelection,
2801
- getNodeById,
2802
- getSelectedNodes,
2803
- getTree,
2804
- onGetStateFromStorage,
2805
- onSetStateFromStorage,
2806
- openNode,
2807
- refreshElements,
2808
- removeFromSelection,
2809
- saveState
2810
- });
2811
- const scrollHandler = new ScrollHandler({
2812
- refreshHitAreas,
2813
- treeElement
2814
- });
2815
- const getScrollLeft = scrollHandler.getScrollLeft.bind(scrollHandler);
2816
- const dndHandler = new DragAndDropHandler({
2817
- autoEscape,
2818
- getNodeElement,
2819
- getNodeElementForNode,
2820
- getScrollLeft,
2821
- getTree,
2822
- onCanMove,
2823
- onCanMoveTo,
2824
- onDragMove,
2825
- onDragStop,
2826
- onIsMoveHandle,
2827
- openFolderDelay,
2828
- openNode,
2829
- refreshElements,
2830
- slide,
2831
- treeElement,
2832
- triggerEvent
2833
- });
2834
- const keyHandler = new KeyHandler({
2835
- closeNode,
2836
- getSelectedNode,
2837
- isFocusOnTree,
2838
- keyboardSupport,
2839
- openNode,
2840
- selectNode
2841
- });
2842
- const renderer = new ElementsRenderer({
2843
- $element: $treeElement,
2844
- autoEscape,
2845
- buttonLeft,
2846
- closedIcon,
2847
- dragAndDrop,
2848
- getTree,
2849
- isNodeSelected,
2850
- onCreateLi,
2851
- openedIcon,
2852
- rtl,
2853
- showEmptyFolder,
2854
- tabIndex
2855
- });
2856
- const getNode = this.getNode.bind(this);
2857
- const onMouseCapture = this.mouseCapture.bind(this);
2858
- const onMouseDrag = this.mouseDrag.bind(this);
2859
- const onMouseStart = this.mouseStart.bind(this);
2860
- const onMouseStop = this.mouseStop.bind(this);
2861
- const mouseHandler = new MouseHandler({
2862
- element: treeElement,
2863
- getMouseDelay,
2864
- getNode,
2865
- onClickButton: this.toggle.bind(this),
2866
- onClickTitle: this.doSelectNode.bind(this),
2867
- onMouseCapture,
2868
- onMouseDrag,
2869
- onMouseStart,
2870
- onMouseStop,
2871
- triggerEvent,
2872
- useContextMenu: this.options.useContextMenu
2873
- });
2874
- this.dataLoader = dataLoader;
2875
- this.dndHandler = dndHandler;
2876
- this.keyHandler = keyHandler;
2877
- this.mouseHandler = mouseHandler;
2878
- this.renderer = renderer;
2879
- this.saveStateHandler = saveStateHandler;
2880
- this.scrollHandler = scrollHandler;
2881
- this.selectNodeHandler = selectNodeHandler;
2882
- }
2883
- containsElement(element) {
2884
- const node = this.getNode(element);
2885
- return node != null && node.tree === this.tree;
2886
- }
2887
- createFolderElement(node) {
2888
- const closedIconElement = this.renderer.closedIconElement;
2889
- const getScrollLeft = this.scrollHandler.getScrollLeft.bind(this.scrollHandler);
2890
- const openedIconElement = this.renderer.openedIconElement;
2891
- const tabIndex = this.options.tabIndex;
2892
- const treeElement = this.element.get(0);
2893
- const triggerEvent = this.triggerEvent.bind(this);
2894
- return new FolderElement({
2895
- closedIconElement,
2896
- getScrollLeft,
2897
- node,
2898
- openedIconElement,
2899
- tabIndex,
2900
- treeElement,
2901
- triggerEvent
2902
- });
2903
- }
2904
- createNodeElement(node) {
2905
- const getScrollLeft = this.scrollHandler.getScrollLeft.bind(this.scrollHandler);
2906
- const tabIndex = this.options.tabIndex;
2907
- const treeElement = this.element.get(0);
2908
- return new NodeElement({
2909
- getScrollLeft,
2910
- node,
2911
- tabIndex,
2912
- treeElement
2913
- });
2914
- }
2915
- deselectCurrentNode() {
2916
- const node = this.getSelectedNode();
2917
- if (node) {
2918
- this.removeFromSelection(node);
2755
+ addNodeAfter(newNodeInfo, existingNode) {
2756
+ const newNode = existingNode.addAfter(newNodeInfo);
2757
+ if (newNode) {
2758
+ this.refreshElements(existingNode.parent);
2919
2759
  }
2760
+ return newNode;
2920
2761
  }
2921
- deselectNodes(parentNode) {
2922
- const selectedNodesUnderParent = this.selectNodeHandler.getSelectedNodesUnder(parentNode);
2923
- for (const n of selectedNodesUnderParent) {
2924
- this.selectNodeHandler.removeFromSelection(n);
2762
+ addNodeBefore(newNodeInfo, existingNode) {
2763
+ if (!existingNode) {
2764
+ throw Error(PARAM_IS_EMPTY + "existingNode");
2925
2765
  }
2926
- }
2927
- doLoadData(data, parentNode) {
2928
- if (data) {
2929
- if (parentNode) {
2930
- this.deselectNodes(parentNode);
2931
- this.loadSubtree(data, parentNode);
2932
- } else {
2933
- this.initTree(data);
2934
- }
2935
- if (this.isDragging()) {
2936
- this.dndHandler.refresh();
2937
- }
2766
+ const newNode = existingNode.addBefore(newNodeInfo);
2767
+ if (newNode) {
2768
+ this.refreshElements(existingNode.parent);
2938
2769
  }
2939
- this.triggerEvent("tree.load_data", {
2940
- parent_node: parentNode,
2941
- tree_data: data
2942
- });
2770
+ return newNode;
2943
2771
  }
2944
- doLoadDataFromUrl(urlInfoParam, parentNode, onFinished) {
2945
- const urlInfo = urlInfoParam ?? this.getDataUrlInfo(parentNode);
2946
- this.dataLoader.loadFromUrl(urlInfo, parentNode, onFinished);
2772
+ addParentNode(newNodeInfo, existingNode) {
2773
+ if (!existingNode) {
2774
+ throw Error(PARAM_IS_EMPTY + "existingNode");
2775
+ }
2776
+ const newNode = existingNode.addParent(newNodeInfo);
2777
+ if (newNode) {
2778
+ this.refreshElements(newNode.parent);
2779
+ }
2780
+ return newNode;
2947
2781
  }
2948
- doSelectNode(node, optionsParam) {
2949
- const saveState = () => {
2950
- if (this.options.saveState) {
2951
- this.saveStateHandler.saveState();
2952
- }
2953
- };
2782
+ addToSelection(node, mustSetFocus) {
2954
2783
  if (!node) {
2955
- // Called with empty node -> deselect current node
2956
- this.deselectCurrentNode();
2957
- saveState();
2958
- return;
2784
+ throw Error(NODE_PARAM_IS_EMPTY);
2959
2785
  }
2960
- const defaultOptions = {
2961
- mustSetFocus: true,
2962
- mustToggle: true
2963
- };
2964
- const selectOptions = {
2965
- ...defaultOptions,
2966
- ...(optionsParam ?? {})
2967
- };
2968
- const canSelect = () => {
2969
- if (this.options.onCanSelectNode) {
2970
- return this.options.selectable && this.options.onCanSelectNode(node);
2971
- } else {
2972
- return this.options.selectable;
2973
- }
2974
- };
2975
- if (!canSelect()) {
2976
- return;
2977
- }
2978
- if (this.selectNodeHandler.isNodeSelected(node)) {
2979
- if (selectOptions.mustToggle) {
2980
- this.deselectCurrentNode();
2981
- this.triggerEvent("tree.select", {
2982
- node: null,
2983
- previous_node: node
2984
- });
2985
- }
2986
- } else {
2987
- const deselectedNode = this.getSelectedNode() || null;
2988
- this.deselectCurrentNode();
2989
- this.addToSelection(node, selectOptions.mustSetFocus);
2990
- this.triggerEvent("tree.select", {
2991
- deselected_node: deselectedNode,
2992
- node
2993
- });
2994
- this.openParents(node);
2995
- }
2996
- saveState();
2786
+ this.selectNodeHandler.addToSelection(node);
2787
+ this.openParents(node);
2788
+ this.getNodeElementForNode(node).select(mustSetFocus ?? true);
2789
+ this.saveState();
2790
+ return this.element;
2997
2791
  }
2998
- getAutoOpenMaxLevel() {
2999
- if (this.options.autoOpen === true) {
3000
- return -1;
3001
- } else if (typeof this.options.autoOpen === "number") {
3002
- return this.options.autoOpen;
3003
- } else if (typeof this.options.autoOpen === "string") {
3004
- return parseInt(this.options.autoOpen, 10);
3005
- } else {
3006
- return 0;
3007
- }
2792
+ appendNode(newNodeInfo, parentNodeParam) {
2793
+ const parentNode = parentNodeParam ?? this.tree;
2794
+ const node = parentNode.append(newNodeInfo);
2795
+ this.refreshElements(parentNode);
2796
+ return node;
3008
2797
  }
3009
- getDataUrlInfo(node) {
3010
- const dataUrl = this.options.dataUrl ?? this.element.data("url");
3011
- const getUrlFromString = url => {
3012
- const urlInfo = {
3013
- url
3014
- };
3015
- setUrlInfoData(urlInfo);
3016
- return urlInfo;
3017
- };
3018
- const setUrlInfoData = urlInfo => {
3019
- if (node?.id) {
3020
- // Load on demand of a subtree; add node parameter
3021
- const data = {
3022
- node: node.id
3023
- };
3024
- urlInfo.data = data;
3025
- } else {
3026
- // Add selected_node parameter
3027
- const selectedNodeId = this.getNodeIdToBeSelected();
3028
- if (selectedNodeId) {
3029
- const data = {
3030
- selected_node: selectedNodeId
3031
- };
3032
- urlInfo.data = data;
3033
- }
3034
- }
3035
- };
3036
- if (typeof dataUrl === "function") {
3037
- return dataUrl(node);
3038
- } else if (typeof dataUrl === "string") {
3039
- return getUrlFromString(dataUrl);
3040
- } else if (dataUrl && typeof dataUrl === "object") {
3041
- setUrlInfoData(dataUrl);
3042
- return dataUrl;
3043
- } else {
3044
- return null;
2798
+ closeNode(node, slideParam) {
2799
+ if (!node) {
2800
+ throw Error(NODE_PARAM_IS_EMPTY);
3045
2801
  }
3046
- }
3047
- getDefaultClosedIcon() {
3048
- if (this.options.rtl) {
3049
- // triangle to the left
3050
- return "&#x25c0;";
3051
- } else {
3052
- // triangle to the right
3053
- return "&#x25ba;";
2802
+ const slide = slideParam ?? this.options.slide;
2803
+ if (node.isFolder() || node.isEmptyFolder) {
2804
+ this.createFolderElement(node).close(slide, this.options.animationSpeed);
2805
+ this.saveState();
3054
2806
  }
2807
+ return this.element;
3055
2808
  }
3056
- getNode(element) {
3057
- const liElement = element.closest("li.jqtree_common");
3058
- if (liElement) {
3059
- return jQuery(liElement).data("node");
3060
- } else {
3061
- return null;
3062
- }
2809
+ deinit() {
2810
+ this.element.empty();
2811
+ this.element.off();
2812
+ this.keyHandler.deinit();
2813
+ this.mouseHandler.deinit();
2814
+ this.tree = new Node({}, true);
2815
+ super.deinit();
3063
2816
  }
3064
- getNodeElement(element) {
3065
- const node = this.getNode(element);
3066
- if (node) {
3067
- return this.getNodeElementForNode(node);
3068
- } else {
2817
+ getNodeByCallback(callback) {
2818
+ return this.tree.getNodeByCallback(callback);
2819
+ }
2820
+ getNodeByHtmlElement(inputElement) {
2821
+ const element = inputElement instanceof HTMLElement ? inputElement : inputElement[0];
2822
+ if (!element) {
3069
2823
  return null;
3070
2824
  }
2825
+ return this.getNode(element);
3071
2826
  }
3072
- getNodeElementForNode(node) {
3073
- if (node.isFolder()) {
3074
- return this.createFolderElement(node);
3075
- } else {
3076
- return this.createNodeElement(node);
3077
- }
2827
+ getNodeById(nodeId) {
2828
+ return this.tree.getNodeById(nodeId);
3078
2829
  }
3079
- getNodeIdToBeSelected() {
3080
- if (this.options.saveState) {
3081
- return this.saveStateHandler.getNodeIdToBeSelected();
3082
- } else {
3083
- return null;
3084
- }
2830
+ getNodeByName(name) {
2831
+ return this.tree.getNodeByName(name);
3085
2832
  }
3086
- getRtlOption() {
3087
- if (this.options.rtl != null) {
3088
- return this.options.rtl;
3089
- } else {
3090
- const dataRtl = this.element.data("rtl");
3091
- if (dataRtl !== null && dataRtl !== false && dataRtl !== undefined) {
3092
- return true;
3093
- } else {
3094
- return false;
3095
- }
3096
- }
2833
+ getNodeByNameMustExist(name) {
2834
+ return this.tree.getNodeByNameMustExist(name);
3097
2835
  }
3098
- initData() {
3099
- if (this.options.data) {
3100
- this.doLoadData(this.options.data, null);
3101
- } else {
3102
- const dataUrl = this.getDataUrlInfo(null);
3103
- if (dataUrl) {
3104
- this.doLoadDataFromUrl(null, null, null);
3105
- } else {
3106
- this.doLoadData([], null);
3107
- }
3108
- }
2836
+ getNodesByProperty(key, value) {
2837
+ return this.tree.getNodesByProperty(key, value);
3109
2838
  }
3110
- initTree(data) {
3111
- const doInit = () => {
3112
- if (!this.isInitialized) {
3113
- this.isInitialized = true;
3114
- this.triggerEvent("tree.init");
3115
- }
3116
- };
3117
- this.tree = new this.options.nodeClass(null, true, this.options.nodeClass);
3118
- this.selectNodeHandler.clear();
3119
- this.tree.loadFromData(data);
3120
- const mustLoadOnDemand = this.setInitialState();
3121
- this.refreshElements(null);
3122
- if (!mustLoadOnDemand) {
3123
- doInit();
3124
- } else {
3125
- // Load data on demand and then init the tree
3126
- this.setInitialStateOnDemand(doInit);
3127
- }
2839
+ getSelectedNode() {
2840
+ return this.selectNodeHandler.getSelectedNode();
3128
2841
  }
3129
- isFocusOnTree() {
3130
- const activeElement = document.activeElement;
3131
- return Boolean(activeElement && activeElement.tagName === "SPAN" && this.containsElement(activeElement));
2842
+ getSelectedNodes() {
2843
+ return this.selectNodeHandler.getSelectedNodes();
3132
2844
  }
3133
- isSelectedNodeInSubtree(subtree) {
3134
- const selectedNode = this.getSelectedNode();
3135
- if (!selectedNode) {
3136
- return false;
3137
- } else {
3138
- return subtree === selectedNode || subtree.isParentOf(selectedNode);
3139
- }
2845
+ getState() {
2846
+ return this.saveStateHandler.getState();
3140
2847
  }
3141
- loadFolderOnDemand(node) {
3142
- let slide = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
3143
- let onFinished = arguments.length > 2 ? arguments[2] : undefined;
3144
- node.is_loading = true;
3145
- this.doLoadDataFromUrl(null, node, () => {
3146
- this.openNodeInternal(node, slide, onFinished);
3147
- });
2848
+ getStateFromStorage() {
2849
+ return this.saveStateHandler.getStateFromStorage();
3148
2850
  }
3149
- loadSubtree(data, parentNode) {
3150
- parentNode.loadFromData(data);
3151
- parentNode.load_on_demand = false;
3152
- parentNode.is_loading = false;
3153
- this.refreshElements(parentNode);
2851
+ getTree() {
2852
+ return this.tree;
3154
2853
  }
3155
- mouseCapture(positionInfo) {
3156
- if (this.options.dragAndDrop) {
3157
- return this.dndHandler.mouseCapture(positionInfo);
3158
- } else {
3159
- return false;
3160
- }
2854
+ getVersion() {
2855
+ return version;
3161
2856
  }
3162
- mouseDrag(positionInfo) {
3163
- if (this.options.dragAndDrop) {
3164
- const result = this.dndHandler.mouseDrag(positionInfo);
3165
- this.scrollHandler.checkScrolling(positionInfo);
3166
- return result;
3167
- } else {
3168
- return false;
2857
+ init() {
2858
+ super.init();
2859
+ this.element = this.$el;
2860
+ this.isInitialized = false;
2861
+ this.options.rtl = this.getRtlOption();
2862
+ if (this.options.closedIcon == null) {
2863
+ this.options.closedIcon = this.getDefaultClosedIcon();
3169
2864
  }
2865
+ this.connectHandlers();
2866
+ this.initData();
3170
2867
  }
3171
- mouseStart(positionInfo) {
3172
- if (this.options.dragAndDrop) {
3173
- return this.dndHandler.mouseStart(positionInfo);
3174
- } else {
3175
- return false;
3176
- }
3177
- }
3178
- mouseStop(positionInfo) {
3179
- if (this.options.dragAndDrop) {
3180
- this.scrollHandler.stopScrolling();
3181
- return this.dndHandler.mouseStop(positionInfo);
3182
- } else {
3183
- return false;
3184
- }
2868
+ isDragging() {
2869
+ return this.dndHandler.isDragging;
3185
2870
  }
3186
- openNodeInternal(node) {
3187
- let slide = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
3188
- let onFinished = arguments.length > 2 ? arguments[2] : undefined;
3189
- const doOpenNode = (_node, _slide, _onFinished) => {
3190
- if (!node.children.length) {
3191
- return;
3192
- }
3193
- const folderElement = this.createFolderElement(_node);
3194
- folderElement.open(_onFinished, _slide, this.options.animationSpeed);
3195
- };
3196
- if (node.isFolder() || node.isEmptyFolder) {
3197
- if (node.load_on_demand) {
3198
- this.loadFolderOnDemand(node, slide, onFinished);
3199
- } else {
3200
- let parent = node.parent;
3201
- while (parent) {
3202
- // nb: do not open root element
3203
- if (parent.parent) {
3204
- doOpenNode(parent, false);
3205
- }
3206
- parent = parent.parent;
3207
- }
3208
- doOpenNode(node, slide, onFinished);
3209
- this.saveState();
3210
- }
2871
+ isNodeSelected(node) {
2872
+ if (!node) {
2873
+ throw Error(NODE_PARAM_IS_EMPTY);
3211
2874
  }
2875
+ return this.selectNodeHandler.isNodeSelected(node);
3212
2876
  }
3213
- openParents(node) {
3214
- const parent = node.parent;
3215
- if (parent?.parent && !parent.is_open) {
3216
- this.openNode(parent, false);
3217
- }
2877
+ loadData(data, parentNode) {
2878
+ this.doLoadData(data, parentNode);
2879
+ return this.element;
3218
2880
  }
3219
2881
 
3220
2882
  /*
3221
- Redraw the tree or part of the tree.
3222
- from_node: redraw this subtree
2883
+ signatures:
2884
+ - loadDataFromUrl(url, parent_node=null, on_finished=null)
2885
+ loadDataFromUrl('/my_data');
2886
+ loadDataFromUrl('/my_data', node1);
2887
+ loadDataFromUrl('/my_data', node1, function() { console.log('finished'); });
2888
+ loadDataFromUrl('/my_data', null, function() { console.log('finished'); });
2889
+ - loadDataFromUrl(parent_node=null, on_finished=null)
2890
+ loadDataFromUrl();
2891
+ loadDataFromUrl(node1);
2892
+ loadDataFromUrl(null, function() { console.log('finished'); });
2893
+ loadDataFromUrl(node1, function() { console.log('finished'); });
3223
2894
  */
3224
- refreshElements(fromNode) {
3225
- const mustSetFocus = this.isFocusOnTree();
3226
- const mustSelect = fromNode ? this.isSelectedNodeInSubtree(fromNode) : false;
3227
- this.renderer.render(fromNode);
3228
- if (mustSelect) {
3229
- this.selectCurrentNode(mustSetFocus);
3230
- }
3231
- this.triggerEvent("tree.refresh");
3232
- }
3233
- saveState() {
3234
- if (this.options.saveState) {
3235
- this.saveStateHandler.saveState();
3236
- }
3237
- }
3238
- selectCurrentNode(mustSetFocus) {
3239
- const node = this.getSelectedNode();
3240
- if (node) {
3241
- const nodeElement = this.getNodeElementForNode(node);
3242
- nodeElement.select(mustSetFocus);
2895
+ loadDataFromUrl(param1, param2, param3) {
2896
+ if (typeof param1 === "string") {
2897
+ // first parameter is url
2898
+ this.doLoadDataFromUrl(param1, param2, param3 ?? null);
2899
+ } else {
2900
+ // first parameter is not url
2901
+ this.doLoadDataFromUrl(null, param1, param2);
3243
2902
  }
2903
+ return this.element;
3244
2904
  }
3245
-
3246
- // Set initial state, either by restoring the state or auto-opening nodes
3247
- // result: must load nodes on demand?
3248
- setInitialState() {
3249
- const restoreState = () => {
3250
- // result: is state restored, must load on demand?
3251
- if (!this.options.saveState) {
3252
- return [false, false];
3253
- } else {
3254
- const state = this.saveStateHandler.getStateFromStorage();
3255
- if (!state) {
3256
- return [false, false];
3257
- } else {
3258
- const mustLoadOnDemand = this.saveStateHandler.setInitialState(state);
3259
-
3260
- // return true: the state is restored
3261
- return [true, mustLoadOnDemand];
3262
- }
3263
- }
3264
- };
3265
- const autoOpenNodes = () => {
3266
- // result: must load on demand?
3267
- if (this.options.autoOpen === false) {
3268
- return false;
3269
- }
3270
- const maxLevel = this.getAutoOpenMaxLevel();
3271
- let mustLoadOnDemand = false;
3272
- this.tree.iterate((node, level) => {
3273
- if (node.load_on_demand) {
3274
- mustLoadOnDemand = true;
3275
- return false;
3276
- } else if (!node.hasChildren()) {
3277
- return false;
3278
- } else {
3279
- node.is_open = true;
3280
- return level !== maxLevel;
3281
- }
3282
- });
3283
- return mustLoadOnDemand;
3284
- };
3285
- let [isRestored, mustLoadOnDemand] = restoreState(); // eslint-disable-line prefer-const
3286
-
3287
- if (!isRestored) {
3288
- mustLoadOnDemand = autoOpenNodes();
2905
+ moveDown() {
2906
+ const selectedNode = this.getSelectedNode();
2907
+ if (selectedNode) {
2908
+ this.keyHandler.moveDown(selectedNode);
3289
2909
  }
3290
- return mustLoadOnDemand;
2910
+ return this.element;
3291
2911
  }
3292
-
3293
- // Set the initial state for nodes that are loaded on demand
3294
- // Call cb_finished when done
3295
- setInitialStateOnDemand(cbFinished) {
3296
- const restoreState = () => {
3297
- if (!this.options.saveState) {
3298
- return false;
3299
- } else {
3300
- const state = this.saveStateHandler.getStateFromStorage();
3301
- if (!state) {
3302
- return false;
3303
- } else {
3304
- this.saveStateHandler.setInitialStateOnDemand(state, cbFinished);
3305
- return true;
3306
- }
3307
- }
3308
- };
3309
- const autoOpenNodes = () => {
3310
- const maxLevel = this.getAutoOpenMaxLevel();
3311
- let loadingCount = 0;
3312
- const loadAndOpenNode = node => {
3313
- loadingCount += 1;
3314
- this.openNodeInternal(node, false, () => {
3315
- loadingCount -= 1;
3316
- openNodes();
3317
- });
3318
- };
3319
- const openNodes = () => {
3320
- this.tree.iterate((node, level) => {
3321
- if (node.load_on_demand) {
3322
- if (!node.is_loading) {
3323
- loadAndOpenNode(node);
3324
- }
3325
- return false;
3326
- } else {
3327
- this.openNodeInternal(node, false);
3328
- return level !== maxLevel;
3329
- }
3330
- });
3331
- if (loadingCount === 0) {
3332
- cbFinished();
3333
- }
3334
- };
3335
- openNodes();
3336
- };
3337
- if (!restoreState()) {
3338
- autoOpenNodes();
2912
+ moveNode(node, targetNode, position) {
2913
+ if (!node) {
2914
+ throw Error(NODE_PARAM_IS_EMPTY);
3339
2915
  }
3340
- }
3341
- triggerEvent(eventName, values) {
3342
- const event = jQuery.Event(eventName, values);
3343
- this.element.trigger(event);
3344
- return event;
3345
- }
3346
- addNodeAfter(newNodeInfo, existingNode) {
3347
- const newNode = existingNode.addAfter(newNodeInfo);
3348
- if (newNode) {
3349
- this.refreshElements(existingNode.parent);
2916
+ if (!targetNode) {
2917
+ throw Error(PARAM_IS_EMPTY + "targetNode");
3350
2918
  }
3351
- return newNode;
3352
- }
3353
- addNodeBefore(newNodeInfo, existingNode) {
3354
- if (!existingNode) {
3355
- throw Error(PARAM_IS_EMPTY + "existingNode");
2919
+ if (!position) {
2920
+ throw Error(PARAM_IS_EMPTY + "position");
3356
2921
  }
3357
- const newNode = existingNode.addBefore(newNodeInfo);
3358
- if (newNode) {
3359
- this.refreshElements(existingNode.parent);
2922
+ const positionIndex = getPosition(position);
2923
+ if (positionIndex !== undefined) {
2924
+ this.tree.moveNode(node, targetNode, positionIndex);
2925
+ this.refreshElements(null);
3360
2926
  }
3361
- return newNode;
2927
+ return this.element;
3362
2928
  }
3363
- addParentNode(newNodeInfo, existingNode) {
3364
- if (!existingNode) {
3365
- throw Error(PARAM_IS_EMPTY + "existingNode");
3366
- }
3367
- const newNode = existingNode.addParent(newNodeInfo);
3368
- if (newNode) {
3369
- this.refreshElements(newNode.parent);
2929
+ moveUp() {
2930
+ const selectedNode = this.getSelectedNode();
2931
+ if (selectedNode) {
2932
+ this.keyHandler.moveUp(selectedNode);
3370
2933
  }
3371
- return newNode;
2934
+ return this.element;
3372
2935
  }
3373
- addToSelection(node, mustSetFocus) {
2936
+ openNode(node, param1, param2) {
3374
2937
  if (!node) {
3375
2938
  throw Error(NODE_PARAM_IS_EMPTY);
3376
2939
  }
3377
- this.selectNodeHandler.addToSelection(node);
3378
- this.openParents(node);
3379
- this.getNodeElementForNode(node).select(mustSetFocus ?? true);
3380
- this.saveState();
2940
+ const parseParams = () => {
2941
+ let onFinished;
2942
+ let slide;
2943
+ if (isFunction(param1)) {
2944
+ onFinished = param1;
2945
+ slide = null;
2946
+ } else {
2947
+ slide = param1;
2948
+ onFinished = param2;
2949
+ }
2950
+ if (slide == null) {
2951
+ slide = this.options.slide;
2952
+ }
2953
+ return [slide, onFinished];
2954
+ };
2955
+ const [slide, onFinished] = parseParams();
2956
+ this.openNodeInternal(node, slide, onFinished);
3381
2957
  return this.element;
3382
2958
  }
3383
- appendNode(newNodeInfo, parentNodeParam) {
2959
+ prependNode(newNodeInfo, parentNodeParam) {
3384
2960
  const parentNode = parentNodeParam ?? this.tree;
3385
- const node = parentNode.append(newNodeInfo);
3386
- this.refreshElements(parentNode);
3387
- return node;
3388
- }
3389
- closeNode(node, slideParam) {
3390
- if (!node) {
3391
- throw Error(NODE_PARAM_IS_EMPTY);
3392
- }
3393
- const slide = slideParam ?? this.options.slide;
3394
- if (node.isFolder() || node.isEmptyFolder) {
3395
- this.createFolderElement(node).close(slide, this.options.animationSpeed);
3396
- this.saveState();
3397
- }
3398
- return this.element;
3399
- }
3400
- deinit() {
3401
- this.element.empty();
3402
- this.element.off();
3403
- this.keyHandler.deinit();
3404
- this.mouseHandler.deinit();
3405
- this.tree = new Node({}, true);
3406
- super.deinit();
3407
- }
3408
- getNodeByCallback(callback) {
3409
- return this.tree.getNodeByCallback(callback);
3410
- }
3411
- getNodeByHtmlElement(inputElement) {
3412
- const element = inputElement instanceof HTMLElement ? inputElement : inputElement[0];
3413
- if (!element) {
3414
- return null;
3415
- }
3416
- return this.getNode(element);
3417
- }
3418
- getNodeById(nodeId) {
3419
- return this.tree.getNodeById(nodeId);
3420
- }
3421
- getNodeByName(name) {
3422
- return this.tree.getNodeByName(name);
3423
- }
3424
- getNodeByNameMustExist(name) {
3425
- return this.tree.getNodeByNameMustExist(name);
3426
- }
3427
- getNodesByProperty(key, value) {
3428
- return this.tree.getNodesByProperty(key, value);
3429
- }
3430
- getSelectedNode() {
3431
- return this.selectNodeHandler.getSelectedNode();
3432
- }
3433
- getSelectedNodes() {
3434
- return this.selectNodeHandler.getSelectedNodes();
3435
- }
3436
- getState() {
3437
- return this.saveStateHandler.getState();
3438
- }
3439
- getStateFromStorage() {
3440
- return this.saveStateHandler.getStateFromStorage();
3441
- }
3442
- getTree() {
3443
- return this.tree;
3444
- }
3445
- getVersion() {
3446
- return version;
3447
- }
3448
- init() {
3449
- super.init();
3450
- this.element = this.$el;
3451
- this.isInitialized = false;
3452
- this.options.rtl = this.getRtlOption();
3453
- if (this.options.closedIcon == null) {
3454
- this.options.closedIcon = this.getDefaultClosedIcon();
3455
- }
3456
- this.connectHandlers();
3457
- this.initData();
3458
- }
3459
- isDragging() {
3460
- return this.dndHandler.isDragging;
3461
- }
3462
- isNodeSelected(node) {
3463
- if (!node) {
3464
- throw Error(NODE_PARAM_IS_EMPTY);
3465
- }
3466
- return this.selectNodeHandler.isNodeSelected(node);
3467
- }
3468
- loadData(data, parentNode) {
3469
- this.doLoadData(data, parentNode);
3470
- return this.element;
3471
- }
3472
-
3473
- /*
3474
- signatures:
3475
- - loadDataFromUrl(url, parent_node=null, on_finished=null)
3476
- loadDataFromUrl('/my_data');
3477
- loadDataFromUrl('/my_data', node1);
3478
- loadDataFromUrl('/my_data', node1, function() { console.log('finished'); });
3479
- loadDataFromUrl('/my_data', null, function() { console.log('finished'); });
3480
- - loadDataFromUrl(parent_node=null, on_finished=null)
3481
- loadDataFromUrl();
3482
- loadDataFromUrl(node1);
3483
- loadDataFromUrl(null, function() { console.log('finished'); });
3484
- loadDataFromUrl(node1, function() { console.log('finished'); });
3485
- */
3486
- loadDataFromUrl(param1, param2, param3) {
3487
- if (typeof param1 === "string") {
3488
- // first parameter is url
3489
- this.doLoadDataFromUrl(param1, param2, param3 ?? null);
3490
- } else {
3491
- // first parameter is not url
3492
- this.doLoadDataFromUrl(null, param1, param2);
3493
- }
3494
- return this.element;
3495
- }
3496
- moveDown() {
3497
- const selectedNode = this.getSelectedNode();
3498
- if (selectedNode) {
3499
- this.keyHandler.moveDown(selectedNode);
3500
- }
3501
- return this.element;
3502
- }
3503
- moveNode(node, targetNode, position) {
3504
- if (!node) {
3505
- throw Error(NODE_PARAM_IS_EMPTY);
3506
- }
3507
- if (!targetNode) {
3508
- throw Error(PARAM_IS_EMPTY + "targetNode");
3509
- }
3510
- if (!position) {
3511
- throw Error(PARAM_IS_EMPTY + "position");
3512
- }
3513
- const positionIndex = getPosition(position);
3514
- if (positionIndex !== undefined) {
3515
- this.tree.moveNode(node, targetNode, positionIndex);
3516
- this.refreshElements(null);
3517
- }
3518
- return this.element;
3519
- }
3520
- moveUp() {
3521
- const selectedNode = this.getSelectedNode();
3522
- if (selectedNode) {
3523
- this.keyHandler.moveUp(selectedNode);
3524
- }
3525
- return this.element;
3526
- }
3527
- openNode(node, param1, param2) {
3528
- if (!node) {
3529
- throw Error(NODE_PARAM_IS_EMPTY);
3530
- }
3531
- const parseParams = () => {
3532
- let onFinished;
3533
- let slide;
3534
- if (isFunction(param1)) {
3535
- onFinished = param1;
3536
- slide = null;
3537
- } else {
3538
- slide = param1;
3539
- onFinished = param2;
3540
- }
3541
- if (slide == null) {
3542
- slide = this.options.slide;
3543
- }
3544
- return [slide, onFinished];
3545
- };
3546
- const [slide, onFinished] = parseParams();
3547
- this.openNodeInternal(node, slide, onFinished);
3548
- return this.element;
3549
- }
3550
- prependNode(newNodeInfo, parentNodeParam) {
3551
- const parentNode = parentNodeParam ?? this.tree;
3552
- const node = parentNode.prepend(newNodeInfo);
2961
+ const node = parentNode.prepend(newNodeInfo);
3553
2962
  this.refreshElements(parentNode);
3554
2963
  return node;
3555
2964
  }
@@ -3654,6 +3063,610 @@ var jqtree = (function (exports) {
3654
3063
  this.refreshElements(node);
3655
3064
  return this.element;
3656
3065
  }
3066
+ connectHandlers() {
3067
+ const {
3068
+ autoEscape,
3069
+ buttonLeft,
3070
+ closedIcon,
3071
+ dataFilter,
3072
+ dragAndDrop,
3073
+ keyboardSupport,
3074
+ onCanMove,
3075
+ onCanMoveTo,
3076
+ onCreateLi,
3077
+ onDragMove,
3078
+ onDragStop,
3079
+ onGetStateFromStorage,
3080
+ onIsMoveHandle,
3081
+ onLoadFailed,
3082
+ onLoading,
3083
+ onSetStateFromStorage,
3084
+ openedIcon,
3085
+ openFolderDelay,
3086
+ rtl,
3087
+ saveState,
3088
+ showEmptyFolder,
3089
+ slide,
3090
+ tabIndex
3091
+ } = this.options;
3092
+ const closeNode = this.closeNode.bind(this);
3093
+ const getNodeElement = this.getNodeElement.bind(this);
3094
+ const getNodeElementForNode = this.getNodeElementForNode.bind(this);
3095
+ const getNodeById = this.getNodeById.bind(this);
3096
+ const getSelectedNode = this.getSelectedNode.bind(this);
3097
+ const getTree = this.getTree.bind(this);
3098
+ const isFocusOnTree = this.isFocusOnTree.bind(this);
3099
+ const loadData = this.loadData.bind(this);
3100
+ const openNode = this.openNodeInternal.bind(this);
3101
+ const refreshElements = this.refreshElements.bind(this);
3102
+ const refreshHitAreas = this.refreshHitAreas.bind(this);
3103
+ const selectNode = this.selectNode.bind(this);
3104
+ const $treeElement = this.element;
3105
+ const treeElement = this.element.get(0);
3106
+ const triggerEvent = this.triggerEvent.bind(this);
3107
+ const selectNodeHandler = new SelectNodeHandler({
3108
+ getNodeById
3109
+ });
3110
+ const addToSelection = selectNodeHandler.addToSelection.bind(selectNodeHandler);
3111
+ const getSelectedNodes = selectNodeHandler.getSelectedNodes.bind(selectNodeHandler);
3112
+ const isNodeSelected = selectNodeHandler.isNodeSelected.bind(selectNodeHandler);
3113
+ const removeFromSelection = selectNodeHandler.removeFromSelection.bind(selectNodeHandler);
3114
+ const getMouseDelay = () => this.options.startDndDelay ?? 0;
3115
+ const dataLoader = new DataLoader({
3116
+ dataFilter,
3117
+ loadData,
3118
+ onLoadFailed,
3119
+ onLoading,
3120
+ treeElement,
3121
+ triggerEvent
3122
+ });
3123
+ const saveStateHandler = new SaveStateHandler({
3124
+ addToSelection,
3125
+ getNodeById,
3126
+ getSelectedNodes,
3127
+ getTree,
3128
+ onGetStateFromStorage,
3129
+ onSetStateFromStorage,
3130
+ openNode,
3131
+ refreshElements,
3132
+ removeFromSelection,
3133
+ saveState
3134
+ });
3135
+ const scrollHandler = new ScrollHandler({
3136
+ refreshHitAreas,
3137
+ treeElement
3138
+ });
3139
+ const getScrollLeft = scrollHandler.getScrollLeft.bind(scrollHandler);
3140
+ const dndHandler = new DragAndDropHandler({
3141
+ autoEscape,
3142
+ getNodeElement,
3143
+ getNodeElementForNode,
3144
+ getScrollLeft,
3145
+ getTree,
3146
+ onCanMove,
3147
+ onCanMoveTo,
3148
+ onDragMove,
3149
+ onDragStop,
3150
+ onIsMoveHandle,
3151
+ openFolderDelay,
3152
+ openNode,
3153
+ refreshElements,
3154
+ slide,
3155
+ treeElement,
3156
+ triggerEvent
3157
+ });
3158
+ const keyHandler = new KeyHandler({
3159
+ closeNode,
3160
+ getSelectedNode,
3161
+ isFocusOnTree,
3162
+ keyboardSupport,
3163
+ openNode,
3164
+ selectNode
3165
+ });
3166
+ const renderer = new ElementsRenderer({
3167
+ $element: $treeElement,
3168
+ autoEscape,
3169
+ buttonLeft,
3170
+ closedIcon,
3171
+ dragAndDrop,
3172
+ getTree,
3173
+ isNodeSelected,
3174
+ onCreateLi,
3175
+ openedIcon,
3176
+ rtl,
3177
+ showEmptyFolder,
3178
+ tabIndex
3179
+ });
3180
+ const getNode = this.getNode.bind(this);
3181
+ const onMouseCapture = this.mouseCapture.bind(this);
3182
+ const onMouseDrag = this.mouseDrag.bind(this);
3183
+ const onMouseStart = this.mouseStart.bind(this);
3184
+ const onMouseStop = this.mouseStop.bind(this);
3185
+ const mouseHandler = new MouseHandler({
3186
+ element: treeElement,
3187
+ getMouseDelay,
3188
+ getNode,
3189
+ onClickButton: this.toggle.bind(this),
3190
+ onClickTitle: this.doSelectNode.bind(this),
3191
+ onMouseCapture,
3192
+ onMouseDrag,
3193
+ onMouseStart,
3194
+ onMouseStop,
3195
+ triggerEvent,
3196
+ useContextMenu: this.options.useContextMenu
3197
+ });
3198
+ this.dataLoader = dataLoader;
3199
+ this.dndHandler = dndHandler;
3200
+ this.keyHandler = keyHandler;
3201
+ this.mouseHandler = mouseHandler;
3202
+ this.renderer = renderer;
3203
+ this.saveStateHandler = saveStateHandler;
3204
+ this.scrollHandler = scrollHandler;
3205
+ this.selectNodeHandler = selectNodeHandler;
3206
+ }
3207
+ containsElement(element) {
3208
+ const node = this.getNode(element);
3209
+ return node != null && node.tree === this.tree;
3210
+ }
3211
+ createFolderElement(node) {
3212
+ const closedIconElement = this.renderer.closedIconElement;
3213
+ const getScrollLeft = this.scrollHandler.getScrollLeft.bind(this.scrollHandler);
3214
+ const openedIconElement = this.renderer.openedIconElement;
3215
+ const tabIndex = this.options.tabIndex;
3216
+ const treeElement = this.element.get(0);
3217
+ const triggerEvent = this.triggerEvent.bind(this);
3218
+ return new FolderElement({
3219
+ closedIconElement,
3220
+ getScrollLeft,
3221
+ node,
3222
+ openedIconElement,
3223
+ tabIndex,
3224
+ treeElement,
3225
+ triggerEvent
3226
+ });
3227
+ }
3228
+ createNodeElement(node) {
3229
+ const getScrollLeft = this.scrollHandler.getScrollLeft.bind(this.scrollHandler);
3230
+ const tabIndex = this.options.tabIndex;
3231
+ const treeElement = this.element.get(0);
3232
+ return new NodeElement({
3233
+ getScrollLeft,
3234
+ node,
3235
+ tabIndex,
3236
+ treeElement
3237
+ });
3238
+ }
3239
+ deselectCurrentNode() {
3240
+ const node = this.getSelectedNode();
3241
+ if (node) {
3242
+ this.removeFromSelection(node);
3243
+ }
3244
+ }
3245
+ deselectNodes(parentNode) {
3246
+ const selectedNodesUnderParent = this.selectNodeHandler.getSelectedNodesUnder(parentNode);
3247
+ for (const n of selectedNodesUnderParent) {
3248
+ this.selectNodeHandler.removeFromSelection(n);
3249
+ }
3250
+ }
3251
+ doLoadData(data, parentNode) {
3252
+ if (data) {
3253
+ if (parentNode) {
3254
+ this.deselectNodes(parentNode);
3255
+ this.loadSubtree(data, parentNode);
3256
+ } else {
3257
+ this.initTree(data);
3258
+ }
3259
+ if (this.isDragging()) {
3260
+ this.dndHandler.refresh();
3261
+ }
3262
+ }
3263
+ this.triggerEvent("tree.load_data", {
3264
+ parent_node: parentNode,
3265
+ tree_data: data
3266
+ });
3267
+ }
3268
+ doLoadDataFromUrl(urlInfoParam, parentNode, onFinished) {
3269
+ const urlInfo = urlInfoParam ?? this.getDataUrlInfo(parentNode);
3270
+ this.dataLoader.loadFromUrl(urlInfo, parentNode, onFinished);
3271
+ }
3272
+ doSelectNode(node, optionsParam) {
3273
+ const saveState = () => {
3274
+ if (this.options.saveState) {
3275
+ this.saveStateHandler.saveState();
3276
+ }
3277
+ };
3278
+ if (!node) {
3279
+ // Called with empty node -> deselect current node
3280
+ this.deselectCurrentNode();
3281
+ saveState();
3282
+ return;
3283
+ }
3284
+ const defaultOptions = {
3285
+ mustSetFocus: true,
3286
+ mustToggle: true
3287
+ };
3288
+ const selectOptions = {
3289
+ ...defaultOptions,
3290
+ ...(optionsParam ?? {})
3291
+ };
3292
+ const canSelect = () => {
3293
+ if (this.options.onCanSelectNode) {
3294
+ return this.options.selectable && this.options.onCanSelectNode(node);
3295
+ } else {
3296
+ return this.options.selectable;
3297
+ }
3298
+ };
3299
+ if (!canSelect()) {
3300
+ return;
3301
+ }
3302
+ if (this.selectNodeHandler.isNodeSelected(node)) {
3303
+ if (selectOptions.mustToggle) {
3304
+ this.deselectCurrentNode();
3305
+ this.triggerEvent("tree.select", {
3306
+ node: null,
3307
+ previous_node: node
3308
+ });
3309
+ }
3310
+ } else {
3311
+ const deselectedNode = this.getSelectedNode() || null;
3312
+ this.deselectCurrentNode();
3313
+ this.addToSelection(node, selectOptions.mustSetFocus);
3314
+ this.triggerEvent("tree.select", {
3315
+ deselected_node: deselectedNode,
3316
+ node
3317
+ });
3318
+ this.openParents(node);
3319
+ }
3320
+ saveState();
3321
+ }
3322
+ getAutoOpenMaxLevel() {
3323
+ if (this.options.autoOpen === true) {
3324
+ return -1;
3325
+ } else if (typeof this.options.autoOpen === "number") {
3326
+ return this.options.autoOpen;
3327
+ } else if (typeof this.options.autoOpen === "string") {
3328
+ return parseInt(this.options.autoOpen, 10);
3329
+ } else {
3330
+ return 0;
3331
+ }
3332
+ }
3333
+ getDataUrlInfo(node) {
3334
+ const dataUrl = this.options.dataUrl ?? this.element.data("url");
3335
+ const getUrlFromString = url => {
3336
+ const urlInfo = {
3337
+ url
3338
+ };
3339
+ setUrlInfoData(urlInfo);
3340
+ return urlInfo;
3341
+ };
3342
+ const setUrlInfoData = urlInfo => {
3343
+ if (node?.id) {
3344
+ // Load on demand of a subtree; add node parameter
3345
+ const data = {
3346
+ node: node.id
3347
+ };
3348
+ urlInfo.data = data;
3349
+ } else {
3350
+ // Add selected_node parameter
3351
+ const selectedNodeId = this.getNodeIdToBeSelected();
3352
+ if (selectedNodeId) {
3353
+ const data = {
3354
+ selected_node: selectedNodeId
3355
+ };
3356
+ urlInfo.data = data;
3357
+ }
3358
+ }
3359
+ };
3360
+ if (typeof dataUrl === "function") {
3361
+ return dataUrl(node);
3362
+ } else if (typeof dataUrl === "string") {
3363
+ return getUrlFromString(dataUrl);
3364
+ } else if (dataUrl && typeof dataUrl === "object") {
3365
+ setUrlInfoData(dataUrl);
3366
+ return dataUrl;
3367
+ } else {
3368
+ return null;
3369
+ }
3370
+ }
3371
+ getDefaultClosedIcon() {
3372
+ if (this.options.rtl) {
3373
+ // triangle to the left
3374
+ return "&#x25c0;";
3375
+ } else {
3376
+ // triangle to the right
3377
+ return "&#x25ba;";
3378
+ }
3379
+ }
3380
+ getNode(element) {
3381
+ const liElement = element.closest("li.jqtree_common");
3382
+ if (liElement) {
3383
+ return jQuery(liElement).data("node");
3384
+ } else {
3385
+ return null;
3386
+ }
3387
+ }
3388
+ getNodeElement(element) {
3389
+ const node = this.getNode(element);
3390
+ if (node) {
3391
+ return this.getNodeElementForNode(node);
3392
+ } else {
3393
+ return null;
3394
+ }
3395
+ }
3396
+ getNodeElementForNode(node) {
3397
+ if (node.isFolder()) {
3398
+ return this.createFolderElement(node);
3399
+ } else {
3400
+ return this.createNodeElement(node);
3401
+ }
3402
+ }
3403
+ getNodeIdToBeSelected() {
3404
+ if (this.options.saveState) {
3405
+ return this.saveStateHandler.getNodeIdToBeSelected();
3406
+ } else {
3407
+ return null;
3408
+ }
3409
+ }
3410
+ getRtlOption() {
3411
+ if (this.options.rtl != null) {
3412
+ return this.options.rtl;
3413
+ } else {
3414
+ const dataRtl = this.element.data("rtl");
3415
+ if (dataRtl !== null && dataRtl !== false && dataRtl !== undefined) {
3416
+ return true;
3417
+ } else {
3418
+ return false;
3419
+ }
3420
+ }
3421
+ }
3422
+ initData() {
3423
+ if (this.options.data) {
3424
+ this.doLoadData(this.options.data, null);
3425
+ } else {
3426
+ const dataUrl = this.getDataUrlInfo(null);
3427
+ if (dataUrl) {
3428
+ this.doLoadDataFromUrl(null, null, null);
3429
+ } else {
3430
+ this.doLoadData([], null);
3431
+ }
3432
+ }
3433
+ }
3434
+ initTree(data) {
3435
+ const doInit = () => {
3436
+ if (!this.isInitialized) {
3437
+ this.isInitialized = true;
3438
+ this.triggerEvent("tree.init");
3439
+ }
3440
+ };
3441
+ this.tree = new this.options.nodeClass(null, true, this.options.nodeClass);
3442
+ this.selectNodeHandler.clear();
3443
+ this.tree.loadFromData(data);
3444
+ const mustLoadOnDemand = this.setInitialState();
3445
+ this.refreshElements(null);
3446
+ if (!mustLoadOnDemand) {
3447
+ doInit();
3448
+ } else {
3449
+ // Load data on demand and then init the tree
3450
+ this.setInitialStateOnDemand(doInit);
3451
+ }
3452
+ }
3453
+ isFocusOnTree() {
3454
+ const activeElement = document.activeElement;
3455
+ return Boolean(activeElement && activeElement.tagName === "SPAN" && this.containsElement(activeElement));
3456
+ }
3457
+ isSelectedNodeInSubtree(subtree) {
3458
+ const selectedNode = this.getSelectedNode();
3459
+ if (!selectedNode) {
3460
+ return false;
3461
+ } else {
3462
+ return subtree === selectedNode || subtree.isParentOf(selectedNode);
3463
+ }
3464
+ }
3465
+ loadFolderOnDemand(node) {
3466
+ let slide = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
3467
+ let onFinished = arguments.length > 2 ? arguments[2] : undefined;
3468
+ node.is_loading = true;
3469
+ this.doLoadDataFromUrl(null, node, () => {
3470
+ this.openNodeInternal(node, slide, onFinished);
3471
+ });
3472
+ }
3473
+ loadSubtree(data, parentNode) {
3474
+ parentNode.loadFromData(data);
3475
+ parentNode.load_on_demand = false;
3476
+ parentNode.is_loading = false;
3477
+ this.refreshElements(parentNode);
3478
+ }
3479
+ mouseCapture(positionInfo) {
3480
+ if (this.options.dragAndDrop) {
3481
+ return this.dndHandler.mouseCapture(positionInfo);
3482
+ } else {
3483
+ return false;
3484
+ }
3485
+ }
3486
+ mouseDrag(positionInfo) {
3487
+ if (this.options.dragAndDrop) {
3488
+ const result = this.dndHandler.mouseDrag(positionInfo);
3489
+ this.scrollHandler.checkScrolling(positionInfo);
3490
+ return result;
3491
+ } else {
3492
+ return false;
3493
+ }
3494
+ }
3495
+ mouseStart(positionInfo) {
3496
+ if (this.options.dragAndDrop) {
3497
+ return this.dndHandler.mouseStart(positionInfo);
3498
+ } else {
3499
+ return false;
3500
+ }
3501
+ }
3502
+ mouseStop(positionInfo) {
3503
+ if (this.options.dragAndDrop) {
3504
+ this.scrollHandler.stopScrolling();
3505
+ return this.dndHandler.mouseStop(positionInfo);
3506
+ } else {
3507
+ return false;
3508
+ }
3509
+ }
3510
+ openNodeInternal(node) {
3511
+ let slide = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
3512
+ let onFinished = arguments.length > 2 ? arguments[2] : undefined;
3513
+ const doOpenNode = (_node, _slide, _onFinished) => {
3514
+ if (!node.children.length) {
3515
+ return;
3516
+ }
3517
+ const folderElement = this.createFolderElement(_node);
3518
+ folderElement.open(_onFinished, _slide, this.options.animationSpeed);
3519
+ };
3520
+ if (node.isFolder() || node.isEmptyFolder) {
3521
+ if (node.load_on_demand) {
3522
+ this.loadFolderOnDemand(node, slide, onFinished);
3523
+ } else {
3524
+ let parent = node.parent;
3525
+ while (parent) {
3526
+ // nb: do not open root element
3527
+ if (parent.parent) {
3528
+ doOpenNode(parent, false);
3529
+ }
3530
+ parent = parent.parent;
3531
+ }
3532
+ doOpenNode(node, slide, onFinished);
3533
+ this.saveState();
3534
+ }
3535
+ }
3536
+ }
3537
+ openParents(node) {
3538
+ const parent = node.parent;
3539
+ if (parent?.parent && !parent.is_open) {
3540
+ this.openNode(parent, false);
3541
+ }
3542
+ }
3543
+
3544
+ /*
3545
+ Redraw the tree or part of the tree.
3546
+ from_node: redraw this subtree
3547
+ */
3548
+ refreshElements(fromNode) {
3549
+ const mustSetFocus = this.isFocusOnTree();
3550
+ const mustSelect = fromNode ? this.isSelectedNodeInSubtree(fromNode) : false;
3551
+ this.renderer.render(fromNode);
3552
+ if (mustSelect) {
3553
+ this.selectCurrentNode(mustSetFocus);
3554
+ }
3555
+ this.triggerEvent("tree.refresh");
3556
+ }
3557
+ saveState() {
3558
+ if (this.options.saveState) {
3559
+ this.saveStateHandler.saveState();
3560
+ }
3561
+ }
3562
+ selectCurrentNode(mustSetFocus) {
3563
+ const node = this.getSelectedNode();
3564
+ if (node) {
3565
+ const nodeElement = this.getNodeElementForNode(node);
3566
+ nodeElement.select(mustSetFocus);
3567
+ }
3568
+ }
3569
+
3570
+ // Set initial state, either by restoring the state or auto-opening nodes
3571
+ // result: must load nodes on demand?
3572
+ setInitialState() {
3573
+ const restoreState = () => {
3574
+ // result: is state restored, must load on demand?
3575
+ if (!this.options.saveState) {
3576
+ return [false, false];
3577
+ } else {
3578
+ const state = this.saveStateHandler.getStateFromStorage();
3579
+ if (!state) {
3580
+ return [false, false];
3581
+ } else {
3582
+ const mustLoadOnDemand = this.saveStateHandler.setInitialState(state);
3583
+
3584
+ // return true: the state is restored
3585
+ return [true, mustLoadOnDemand];
3586
+ }
3587
+ }
3588
+ };
3589
+ const autoOpenNodes = () => {
3590
+ // result: must load on demand?
3591
+ if (this.options.autoOpen === false) {
3592
+ return false;
3593
+ }
3594
+ const maxLevel = this.getAutoOpenMaxLevel();
3595
+ let mustLoadOnDemand = false;
3596
+ this.tree.iterate((node, level) => {
3597
+ if (node.load_on_demand) {
3598
+ mustLoadOnDemand = true;
3599
+ return false;
3600
+ } else if (!node.hasChildren()) {
3601
+ return false;
3602
+ } else {
3603
+ node.is_open = true;
3604
+ return level !== maxLevel;
3605
+ }
3606
+ });
3607
+ return mustLoadOnDemand;
3608
+ };
3609
+ let [isRestored, mustLoadOnDemand] = restoreState(); // eslint-disable-line prefer-const
3610
+
3611
+ if (!isRestored) {
3612
+ mustLoadOnDemand = autoOpenNodes();
3613
+ }
3614
+ return mustLoadOnDemand;
3615
+ }
3616
+
3617
+ // Set the initial state for nodes that are loaded on demand
3618
+ // Call cb_finished when done
3619
+ setInitialStateOnDemand(cbFinished) {
3620
+ const restoreState = () => {
3621
+ if (!this.options.saveState) {
3622
+ return false;
3623
+ } else {
3624
+ const state = this.saveStateHandler.getStateFromStorage();
3625
+ if (!state) {
3626
+ return false;
3627
+ } else {
3628
+ this.saveStateHandler.setInitialStateOnDemand(state, cbFinished);
3629
+ return true;
3630
+ }
3631
+ }
3632
+ };
3633
+ const autoOpenNodes = () => {
3634
+ const maxLevel = this.getAutoOpenMaxLevel();
3635
+ let loadingCount = 0;
3636
+ const loadAndOpenNode = node => {
3637
+ loadingCount += 1;
3638
+ this.openNodeInternal(node, false, () => {
3639
+ loadingCount -= 1;
3640
+ openNodes();
3641
+ });
3642
+ };
3643
+ const openNodes = () => {
3644
+ this.tree.iterate((node, level) => {
3645
+ if (node.load_on_demand) {
3646
+ if (!node.is_loading) {
3647
+ loadAndOpenNode(node);
3648
+ }
3649
+ return false;
3650
+ } else {
3651
+ this.openNodeInternal(node, false);
3652
+ return level !== maxLevel;
3653
+ }
3654
+ });
3655
+ if (loadingCount === 0) {
3656
+ cbFinished();
3657
+ }
3658
+ };
3659
+ openNodes();
3660
+ };
3661
+ if (!restoreState()) {
3662
+ autoOpenNodes();
3663
+ }
3664
+ }
3665
+ triggerEvent(eventName, values) {
3666
+ const event = jQuery.Event(eventName, values);
3667
+ this.element.trigger(event);
3668
+ return event;
3669
+ }
3657
3670
  }
3658
3671
  SimpleWidget.register(JqTreeWidget, "tree");
3659
3672