jqtree 1.7.4 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/.eslintrc +5 -1
  2. package/bower.json +1 -1
  3. package/config/babel.config.json +1 -1
  4. package/config/production +2 -0
  5. package/devserver/devserver_scroll.js +8 -0
  6. package/devserver/test_scroll.html +28 -0
  7. package/devserver/test_scroll_container.html +39 -0
  8. package/docs/_config.yml +1 -1
  9. package/docs/_entries/general/changelog.md +12 -0
  10. package/docs/package.json +1 -1
  11. package/docs/pnpm-lock.yaml +30 -30
  12. package/package.json +31 -27
  13. package/src/dataLoader.ts +44 -19
  14. package/src/dragAndDropHandler/dragElement.ts +42 -0
  15. package/src/dragAndDropHandler/hitAreasGenerator.ts +175 -0
  16. package/src/dragAndDropHandler/index.ts +470 -0
  17. package/src/dragAndDropHandler/types.ts +12 -0
  18. package/src/dragAndDropHandler/visibleNodeIterator.ts +97 -0
  19. package/src/elementsRenderer.ts +75 -40
  20. package/src/jqtreeMethodTypes.ts +40 -0
  21. package/src/jqtreeOptions.ts +43 -25
  22. package/src/keyHandler.ts +59 -38
  23. package/src/mouse.widget.ts +3 -3
  24. package/src/mouseWidgetTypes.ts +6 -0
  25. package/src/node.ts +32 -48
  26. package/src/nodeElement/borderDropHint.ts +32 -0
  27. package/src/nodeElement/folderElement.ts +133 -0
  28. package/src/nodeElement/ghostDropHint.ts +68 -0
  29. package/src/nodeElement/index.ts +101 -0
  30. package/src/nodeUtils.ts +10 -0
  31. package/src/playwright/coverage.ts +1 -4
  32. package/src/playwright/playwright.test.ts +203 -15
  33. package/src/playwright/testUtils.ts +23 -15
  34. package/src/saveStateHandler.ts +75 -26
  35. package/src/scrollHandler/containerScrollParent.ts +177 -0
  36. package/src/scrollHandler/createScrollParent.ts +50 -0
  37. package/src/scrollHandler/documentScrollParent.ts +182 -0
  38. package/src/scrollHandler/types.ts +7 -0
  39. package/src/scrollHandler.ts +36 -248
  40. package/src/selectNodeHandler.ts +10 -16
  41. package/src/test/jqTree/keyboard.test.ts +18 -23
  42. package/src/test/jqTree/loadOnDemand.test.ts +2 -3
  43. package/src/test/jqTree/methods.test.ts +33 -4
  44. package/src/test/jqTree/options.test.ts +15 -4
  45. package/src/test/node.test.ts +85 -26
  46. package/src/test/nodeUtils.test.ts +21 -0
  47. package/src/tree.jquery.ts +262 -83
  48. package/src/util.ts +3 -0
  49. package/src/version.ts +1 -1
  50. package/tree.jquery.debug.js +1922 -2608
  51. package/tree.jquery.debug.js.map +1 -1
  52. package/tree.jquery.js +2 -2
  53. package/tree.jquery.js.map +1 -1
  54. package/lib/dataLoader.js +0 -124
  55. package/lib/dragAndDropHandler.js +0 -596
  56. package/lib/elementsRenderer.js +0 -268
  57. package/lib/jqtreeOptions.js +0 -1
  58. package/lib/keyHandler.js +0 -115
  59. package/lib/mouse.widget.js +0 -256
  60. package/lib/node.js +0 -717
  61. package/lib/nodeElement.js +0 -277
  62. package/lib/playwright/coverage.js +0 -96
  63. package/lib/playwright/playwright.test.js +0 -228
  64. package/lib/playwright/testUtils.js +0 -184
  65. package/lib/saveStateHandler.js +0 -278
  66. package/lib/scrollHandler.js +0 -250
  67. package/lib/selectNodeHandler.js +0 -129
  68. package/lib/simple.widget.js +0 -159
  69. package/lib/test/global.d.js +0 -3
  70. package/lib/test/jqTree/accessibility.test.js +0 -37
  71. package/lib/test/jqTree/create.test.js +0 -48
  72. package/lib/test/jqTree/events.test.js +0 -210
  73. package/lib/test/jqTree/keyboard.test.js +0 -225
  74. package/lib/test/jqTree/loadOnDemand.test.js +0 -218
  75. package/lib/test/jqTree/methods.test.js +0 -1347
  76. package/lib/test/jqTree/options.test.js +0 -548
  77. package/lib/test/node.test.js +0 -1160
  78. package/lib/test/nodeUtil.test.js +0 -27
  79. package/lib/test/support/exampleData.js +0 -36
  80. package/lib/test/support/jqTreeMatchers.js +0 -70
  81. package/lib/test/support/matchers.d.js +0 -1
  82. package/lib/test/support/setupTests.js +0 -7
  83. package/lib/test/support/testUtil.js +0 -32
  84. package/lib/test/support/treeStructure.js +0 -39
  85. package/lib/test/util.test.js +0 -26
  86. package/lib/tree.jquery.d.js +0 -1
  87. package/lib/tree.jquery.js +0 -1106
  88. package/lib/types.js +0 -1
  89. package/lib/typings.d.js +0 -2
  90. package/lib/util.js +0 -18
  91. package/lib/version.js +0 -9
  92. package/src/dragAndDropHandler.ts +0 -719
  93. package/src/nodeElement.ts +0 -272
  94. package/src/types.ts +0 -19
@@ -4,14 +4,16 @@ import ElementsRenderer from "./elementsRenderer";
4
4
  import DataLoader, { HandleFinishedLoading } from "./dataLoader";
5
5
  import KeyHandler from "./keyHandler";
6
6
  import MouseWidget from "./mouse.widget";
7
- import { PositionInfo } from "./types";
7
+ import { PositionInfo } from "./mouseWidgetTypes";
8
8
  import SaveStateHandler, { SavedState } from "./saveStateHandler";
9
9
  import ScrollHandler from "./scrollHandler";
10
10
  import SelectNodeHandler from "./selectNodeHandler";
11
11
  import SimpleWidget from "./simple.widget";
12
12
  import { Node, getPosition } from "./node";
13
13
  import { isFunction } from "./util";
14
- import { FolderElement, NodeElement, OnFinishOpenNode } from "./nodeElement";
14
+ import NodeElement from "./nodeElement";
15
+ import FolderElement from "./nodeElement/folderElement";
16
+ import { OnFinishOpenNode } from "./jqtreeMethodTypes";
15
17
  import { JQTreeOptions } from "./jqtreeOptions";
16
18
 
17
19
  interface ClickTarget {
@@ -101,7 +103,7 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
101
103
 
102
104
  public selectNode(
103
105
  node: Node | null,
104
- optionsParam?: SelectNodeOptions
106
+ optionsParam?: SelectNodeOptions,
105
107
  ): JQuery {
106
108
  this.doSelectNode(node, optionsParam);
107
109
  return this.element;
@@ -137,21 +139,21 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
137
139
  public loadDataFromUrl(
138
140
  param1: string | null | Node,
139
141
  param2?: Node | null | HandleFinishedLoading,
140
- param3?: HandleFinishedLoading
142
+ param3?: HandleFinishedLoading,
141
143
  ): JQuery {
142
144
  if (typeof param1 === "string") {
143
145
  // first parameter is url
144
146
  this.doLoadDataFromUrl(
145
147
  param1,
146
148
  param2 as Node | null,
147
- param3 ?? null
149
+ param3 ?? null,
148
150
  );
149
151
  } else {
150
152
  // first parameter is not url
151
153
  this.doLoadDataFromUrl(
152
154
  null,
153
155
  param1,
154
- param2 as HandleFinishedLoading | null
156
+ param2 as HandleFinishedLoading | null,
155
157
  );
156
158
  }
157
159
 
@@ -185,9 +187,18 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
185
187
  }
186
188
 
187
189
  public getNodeByHtmlElement(
188
- element: HTMLElement | JQuery<HTMLElement>
190
+ inputElement: HTMLElement | JQuery<HTMLElement>,
189
191
  ): Node | null {
190
- return this.getNode(jQuery(element));
192
+ const element =
193
+ inputElement instanceof HTMLElement
194
+ ? inputElement
195
+ : inputElement[0];
196
+
197
+ if (!element) {
198
+ return null;
199
+ }
200
+
201
+ return this.getNode(element);
191
202
  }
192
203
 
193
204
  public getNodeByCallback(callback: (node: Node) => boolean): Node | null {
@@ -197,18 +208,18 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
197
208
  public openNode(
198
209
  node: Node,
199
210
  param1?: boolean | OnFinishOpenNode,
200
- param2?: OnFinishOpenNode
211
+ param2?: OnFinishOpenNode,
201
212
  ): JQuery {
202
213
  if (!node) {
203
214
  throw Error(NODE_PARAM_IS_EMPTY);
204
215
  }
205
216
 
206
- const parseParams = (): [boolean, OnFinishOpenNode | null] => {
217
+ const parseParams = (): [boolean, OnFinishOpenNode | undefined] => {
207
218
  let onFinished: OnFinishOpenNode | null;
208
219
  let slide: boolean | null;
209
220
 
210
221
  if (isFunction(param1)) {
211
- onFinished = param1 as OnFinishOpenNode | null;
222
+ onFinished = param1 as OnFinishOpenNode;
212
223
  slide = null;
213
224
  } else {
214
225
  slide = param1 as boolean;
@@ -236,9 +247,9 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
236
247
  const slide = slideParam ?? this.options.slide;
237
248
 
238
249
  if (node.isFolder() || node.isEmptyFolder) {
239
- new FolderElement(node, this).close(
250
+ this.createFolderElement(node).close(
240
251
  slide,
241
- this.options.animationSpeed
252
+ this.options.animationSpeed,
242
253
  );
243
254
 
244
255
  this.saveState();
@@ -258,7 +269,7 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
258
269
 
259
270
  public addNodeAfter(
260
271
  newNodeInfo: NodeData,
261
- existingNode: Node
272
+ existingNode: Node,
262
273
  ): Node | null {
263
274
  const newNode = existingNode.addAfter(newNodeInfo);
264
275
 
@@ -271,7 +282,7 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
271
282
 
272
283
  public addNodeBefore(
273
284
  newNodeInfo: NodeData,
274
- existingNode: Node
285
+ existingNode: Node,
275
286
  ): Node | null {
276
287
  if (!existingNode) {
277
288
  throw Error(PARAM_IS_EMPTY + "existingNode");
@@ -288,7 +299,7 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
288
299
 
289
300
  public addParentNode(
290
301
  newNodeInfo: NodeData,
291
- existingNode: Node
302
+ existingNode: Node,
292
303
  ): Node | null {
293
304
  if (!existingNode) {
294
305
  throw Error(PARAM_IS_EMPTY + "existingNode");
@@ -415,9 +426,10 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
415
426
  }
416
427
 
417
428
  this.selectNodeHandler.addToSelection(node);
429
+ this.openParents(node);
418
430
 
419
431
  this._getNodeElementForNode(node).select(
420
- mustSetFocus === undefined ? true : mustSetFocus
432
+ mustSetFocus === undefined ? true : mustSetFocus,
421
433
  );
422
434
 
423
435
  this.saveState();
@@ -455,12 +467,8 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
455
467
  throw Error(NODE_PARAM_IS_EMPTY);
456
468
  }
457
469
 
458
- const nodeOffset = jQuery(node.element).offset();
459
- const nodeTop = nodeOffset ? nodeOffset.top : 0;
460
-
461
- const treeOffset = this.$el.offset();
462
- const treeTop = treeOffset ? treeOffset.top : 0;
463
-
470
+ const nodeTop = jQuery(node.element).offset()?.top ?? 0;
471
+ const treeTop = this.$el.offset()?.top ?? 0;
464
472
  const top = nodeTop - treeTop;
465
473
 
466
474
  this.scrollHandler.scrollToY(top);
@@ -508,7 +516,7 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
508
516
 
509
517
  public _triggerEvent(
510
518
  eventName: string,
511
- values?: Record<string, unknown>
519
+ values?: Record<string, unknown>,
512
520
  ): JQuery.Event {
513
521
  const event = jQuery.Event(eventName, values);
514
522
  this.element.trigger(event);
@@ -518,18 +526,18 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
518
526
  public _openNode(
519
527
  node: Node,
520
528
  slide = true,
521
- onFinished: OnFinishOpenNode | null
529
+ onFinished?: OnFinishOpenNode,
522
530
  ): void {
523
531
  const doOpenNode = (
524
532
  _node: Node,
525
533
  _slide: boolean,
526
- _onFinished: OnFinishOpenNode | null
534
+ _onFinished?: OnFinishOpenNode,
527
535
  ): void => {
528
- const folderElement = new FolderElement(_node, this);
536
+ const folderElement = this.createFolderElement(_node);
529
537
  folderElement.open(
530
538
  _onFinished,
531
539
  _slide,
532
- this.options.animationSpeed
540
+ this.options.animationSpeed,
533
541
  );
534
542
  };
535
543
 
@@ -542,7 +550,7 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
542
550
  while (parent) {
543
551
  // nb: do not open root element
544
552
  if (parent.parent) {
545
- doOpenNode(parent, false, null);
553
+ doOpenNode(parent, false);
546
554
  }
547
555
  parent = parent.parent;
548
556
  }
@@ -558,7 +566,7 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
558
566
  from_node: redraw this subtree
559
567
  */
560
568
  public _refreshElements(fromNode: Node | null): void {
561
- const mustSetFocus = this.selectNodeHandler.isFocusOnTree();
569
+ const mustSetFocus = this.isFocusOnTree();
562
570
  const mustSelect = fromNode
563
571
  ? this.isSelectedNodeInSubtree(fromNode)
564
572
  : false;
@@ -574,14 +582,14 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
574
582
 
575
583
  public _getNodeElementForNode(node: Node): NodeElement {
576
584
  if (node.isFolder()) {
577
- return new FolderElement(node, this);
585
+ return this.createFolderElement(node);
578
586
  } else {
579
- return new NodeElement(node, this);
587
+ return this.createNodeElement(node);
580
588
  }
581
589
  }
582
590
 
583
- public _getNodeElement($element: JQuery<HTMLElement>): NodeElement | null {
584
- const node = this.getNode($element);
591
+ public _getNodeElement(element: HTMLElement): NodeElement | null {
592
+ const node = this.getNode(element);
585
593
  if (node) {
586
594
  return this._getNodeElementForNode(node);
587
595
  } else {
@@ -589,12 +597,6 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
589
597
  }
590
598
  }
591
599
 
592
- public _containsElement(element: HTMLElement): boolean {
593
- const node = this.getNode(jQuery(element));
594
-
595
- return node != null && node.tree === this.tree;
596
- }
597
-
598
600
  public _getScrollLeft(): number {
599
601
  return this.scrollHandler.getScrollLeft();
600
602
  }
@@ -611,13 +613,7 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
611
613
  this.options.closedIcon = this.getDefaultClosedIcon();
612
614
  }
613
615
 
614
- this.renderer = new ElementsRenderer(this);
615
- this.dataLoader = new DataLoader(this);
616
- this.saveStateHandler = new SaveStateHandler(this);
617
- this.selectNodeHandler = new SelectNodeHandler(this);
618
- this.dndHandler = new DragAndDropHandler(this);
619
- this.scrollHandler = new ScrollHandler(this);
620
- this.keyHandler = new KeyHandler(this);
616
+ this.connectHandlers();
621
617
 
622
618
  this.initData();
623
619
 
@@ -660,7 +656,7 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
660
656
  if (this.options.dragAndDrop) {
661
657
  const result = this.dndHandler.mouseDrag(positionInfo);
662
658
 
663
- this.scrollHandler.checkScrolling();
659
+ this.scrollHandler.checkScrolling(positionInfo);
664
660
  return result;
665
661
  } else {
666
662
  return false;
@@ -669,6 +665,7 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
669
665
 
670
666
  protected mouseStop(positionInfo: PositionInfo): boolean {
671
667
  if (this.options.dragAndDrop) {
668
+ this.scrollHandler.stopScrolling();
672
669
  return this.dndHandler.mouseStop(positionInfo);
673
670
  } else {
674
671
  return false;
@@ -755,7 +752,7 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
755
752
  this.tree = new this.options.nodeClass(
756
753
  null,
757
754
  true,
758
- this.options.nodeClass
755
+ this.options.nodeClass,
759
756
  );
760
757
 
761
758
  this.selectNodeHandler.clear();
@@ -843,7 +840,7 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
843
840
  } else {
844
841
  this.saveStateHandler.setInitialStateOnDemand(
845
842
  state,
846
- cbFinished
843
+ cbFinished,
847
844
  );
848
845
 
849
846
  return true;
@@ -872,7 +869,7 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
872
869
 
873
870
  return false;
874
871
  } else {
875
- this._openNode(node, false, null);
872
+ this._openNode(node, false);
876
873
 
877
874
  return level !== maxLevel;
878
875
  }
@@ -904,7 +901,7 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
904
901
  }
905
902
 
906
903
  private handleClick = (
907
- e: JQuery.ClickEvent<HTMLElement, any, HTMLElement, HTMLElement>
904
+ e: JQuery.ClickEvent<HTMLElement, any, HTMLElement, HTMLElement>,
908
905
  ): void => {
909
906
  const clickTarget = this.getClickTarget(e.target);
910
907
 
@@ -929,7 +926,7 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
929
926
  };
930
927
 
931
928
  private handleDblclick = (
932
- e: JQuery.DoubleClickEvent<HTMLElement, any, HTMLElement, HTMLElement>
929
+ e: JQuery.DoubleClickEvent<HTMLElement, any, HTMLElement, HTMLElement>,
933
930
  ): void => {
934
931
  const clickTarget = this.getClickTarget(e.target);
935
932
 
@@ -941,13 +938,11 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
941
938
  }
942
939
  };
943
940
 
944
- private getClickTarget(element: EventTarget): ClickTarget | null {
945
- const $target = jQuery(element);
946
-
947
- const $button = $target.closest(".jqtree-toggler");
941
+ private getClickTarget(element: HTMLElement): ClickTarget | null {
942
+ const button = element.closest(".jqtree-toggler");
948
943
 
949
- if ($button.length) {
950
- const node = this.getNode($button as JQuery<HTMLElement>);
944
+ if (button) {
945
+ const node = this.getNode(button as HTMLElement);
951
946
 
952
947
  if (node) {
953
948
  return {
@@ -956,9 +951,10 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
956
951
  };
957
952
  }
958
953
  } else {
959
- const $el = $target.closest(".jqtree-element");
960
- if ($el.length) {
961
- const node = this.getNode($el as JQuery<HTMLElement>);
954
+ const jqTreeElement = element.closest(".jqtree-element");
955
+
956
+ if (jqTreeElement) {
957
+ const node = this.getNode(jqTreeElement as HTMLElement);
962
958
  if (node) {
963
959
  return {
964
960
  type: "label",
@@ -971,21 +967,23 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
971
967
  return null;
972
968
  }
973
969
 
974
- private getNode($element: JQuery<HTMLElement>): null | Node {
975
- const $li = $element.closest("li.jqtree_common");
976
- if ($li.length === 0) {
977
- return null;
970
+ private getNode(element: HTMLElement): null | Node {
971
+ const liElement = element.closest("li.jqtree_common");
972
+
973
+ if (liElement) {
974
+ return jQuery(liElement).data("node") as Node;
978
975
  } else {
979
- return $li.data("node") as Node;
976
+ return null;
980
977
  }
981
978
  }
982
979
 
983
980
  private handleContextmenu = (
984
- e: JQuery.ContextMenuEvent<HTMLElement, any, HTMLElement, HTMLElement>
981
+ e: JQuery.ContextMenuEvent<HTMLElement, any, HTMLElement, HTMLElement>,
985
982
  ) => {
986
- const $div = jQuery(e.target).closest("ul.jqtree-tree .jqtree-element");
987
- if ($div.length) {
988
- const node = this.getNode($div);
983
+ const div = e.target.closest("ul.jqtree-tree .jqtree-element");
984
+
985
+ if (div) {
986
+ const node = this.getNode(div as HTMLElement);
989
987
  if (node) {
990
988
  e.preventDefault();
991
989
  e.stopPropagation();
@@ -1054,7 +1052,7 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
1054
1052
 
1055
1053
  private doSelectNode(
1056
1054
  node: Node | null,
1057
- optionsParam?: SelectNodeOptions
1055
+ optionsParam?: SelectNodeOptions,
1058
1056
  ): void {
1059
1057
  const saveState = (): void => {
1060
1058
  if (this.options.saveState) {
@@ -1082,14 +1080,6 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
1082
1080
  }
1083
1081
  };
1084
1082
 
1085
- const openParents = (): void => {
1086
- const parent = node.parent;
1087
-
1088
- if (parent && parent.parent && !parent.is_open) {
1089
- this.openNode(parent, false);
1090
- }
1091
- };
1092
-
1093
1083
  if (!canSelect()) {
1094
1084
  return;
1095
1085
  }
@@ -1111,7 +1101,7 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
1111
1101
  node,
1112
1102
  deselected_node: deselectedNode,
1113
1103
  });
1114
- openParents();
1104
+ this.openParents(node);
1115
1105
  }
1116
1106
 
1117
1107
  saveState();
@@ -1157,7 +1147,7 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
1157
1147
  private doLoadDataFromUrl(
1158
1148
  urlInfoParam: string | JQuery.AjaxSettings | null,
1159
1149
  parentNode: Node | null,
1160
- onFinished: HandleFinishedLoading | null
1150
+ onFinished: HandleFinishedLoading | null,
1161
1151
  ): void {
1162
1152
  const urlInfo = urlInfoParam || this.getDataUrlInfo(parentNode);
1163
1153
 
@@ -1167,7 +1157,7 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
1167
1157
  private loadFolderOnDemand(
1168
1158
  node: Node,
1169
1159
  slide = true,
1170
- onFinished: OnFinishOpenNode | null
1160
+ onFinished?: OnFinishOpenNode,
1171
1161
  ): void {
1172
1162
  node.is_loading = true;
1173
1163
 
@@ -1175,6 +1165,195 @@ export class JqTreeWidget extends MouseWidget<JQTreeOptions> {
1175
1165
  this._openNode(node, slide, onFinished);
1176
1166
  });
1177
1167
  }
1168
+
1169
+ private containsElement(element: HTMLElement): boolean {
1170
+ const node = this.getNode(element);
1171
+
1172
+ return node != null && node.tree === this.tree;
1173
+ }
1174
+
1175
+ private isFocusOnTree(): boolean {
1176
+ const activeElement = document.activeElement;
1177
+
1178
+ return Boolean(
1179
+ activeElement &&
1180
+ activeElement.tagName === "SPAN" &&
1181
+ this.containsElement(activeElement as HTMLElement),
1182
+ );
1183
+ }
1184
+
1185
+ private connectHandlers() {
1186
+ const {
1187
+ autoEscape,
1188
+ buttonLeft,
1189
+ closedIcon,
1190
+ dataFilter,
1191
+ dragAndDrop,
1192
+ keyboardSupport,
1193
+ onCanMove,
1194
+ onCreateLi,
1195
+ onDragMove,
1196
+ onDragStop,
1197
+ onGetStateFromStorage,
1198
+ onIsMoveHandle,
1199
+ onLoadFailed,
1200
+ onLoading,
1201
+ onSetStateFromStorage,
1202
+ openedIcon,
1203
+ openFolderDelay,
1204
+ rtl,
1205
+ saveState,
1206
+ showEmptyFolder,
1207
+ slide,
1208
+ tabIndex,
1209
+ } = this.options;
1210
+
1211
+ const closeNode = this.closeNode.bind(this);
1212
+ const getNodeElement = this._getNodeElement.bind(this);
1213
+ const getNodeElementForNode = this._getNodeElementForNode.bind(this);
1214
+ const getNodeById = this.getNodeById.bind(this);
1215
+ const getScrollLeft = this._getScrollLeft.bind(this);
1216
+ const getSelectedNode = this.getSelectedNode.bind(this);
1217
+ const getTree = this.getTree.bind(this);
1218
+ const isFocusOnTree = this.isFocusOnTree.bind(this);
1219
+ const loadData = this.loadData.bind(this);
1220
+ const openNode = this._openNode.bind(this);
1221
+ const refreshElements = this._refreshElements.bind(this);
1222
+ const refreshHitAreas = this.refreshHitAreas.bind(this);
1223
+ const selectNode = this.selectNode.bind(this);
1224
+ const $treeElement = this.element;
1225
+ const triggerEvent = this._triggerEvent.bind(this);
1226
+
1227
+ const selectNodeHandler = new SelectNodeHandler({
1228
+ getNodeById,
1229
+ });
1230
+
1231
+ const addToSelection =
1232
+ selectNodeHandler.addToSelection.bind(selectNodeHandler);
1233
+ const getSelectedNodes =
1234
+ selectNodeHandler.getSelectedNodes.bind(selectNodeHandler);
1235
+ const isNodeSelected =
1236
+ selectNodeHandler.isNodeSelected.bind(selectNodeHandler);
1237
+ const removeFromSelection =
1238
+ selectNodeHandler.removeFromSelection.bind(selectNodeHandler);
1239
+
1240
+ const dataLoader = new DataLoader({
1241
+ dataFilter,
1242
+ loadData,
1243
+ onLoadFailed,
1244
+ onLoading,
1245
+ $treeElement,
1246
+ triggerEvent,
1247
+ });
1248
+
1249
+ const saveStateHandler = new SaveStateHandler({
1250
+ addToSelection,
1251
+ getNodeById,
1252
+ getSelectedNodes,
1253
+ getTree,
1254
+ onGetStateFromStorage,
1255
+ onSetStateFromStorage,
1256
+ openNode,
1257
+ refreshElements,
1258
+ removeFromSelection,
1259
+ saveState,
1260
+ });
1261
+
1262
+ const dndHandler = new DragAndDropHandler({
1263
+ autoEscape,
1264
+ getNodeElement,
1265
+ getNodeElementForNode,
1266
+ getScrollLeft,
1267
+ getTree,
1268
+ onCanMove,
1269
+ onDragMove,
1270
+ onDragStop,
1271
+ onIsMoveHandle,
1272
+ openFolderDelay,
1273
+ openNode,
1274
+ refreshElements,
1275
+ slide,
1276
+ $treeElement,
1277
+ triggerEvent,
1278
+ });
1279
+
1280
+ const scrollHandler = new ScrollHandler({
1281
+ refreshHitAreas,
1282
+ $treeElement,
1283
+ });
1284
+
1285
+ const keyHandler = new KeyHandler({
1286
+ closeNode,
1287
+ getSelectedNode,
1288
+ isFocusOnTree,
1289
+ keyboardSupport,
1290
+ openNode,
1291
+ selectNode,
1292
+ });
1293
+
1294
+ const renderer = new ElementsRenderer({
1295
+ autoEscape,
1296
+ buttonLeft,
1297
+ closedIcon,
1298
+ dragAndDrop,
1299
+ $element: $treeElement,
1300
+ getTree,
1301
+ isNodeSelected,
1302
+ onCreateLi,
1303
+ openedIcon,
1304
+ rtl,
1305
+ showEmptyFolder,
1306
+ tabIndex,
1307
+ });
1308
+
1309
+ this.dataLoader = dataLoader;
1310
+ this.dndHandler = dndHandler;
1311
+ this.keyHandler = keyHandler;
1312
+ this.renderer = renderer;
1313
+ this.saveStateHandler = saveStateHandler;
1314
+ this.scrollHandler = scrollHandler;
1315
+ this.selectNodeHandler = selectNodeHandler;
1316
+ }
1317
+
1318
+ private createFolderElement(node: Node) {
1319
+ const closedIconElement = this.renderer.closedIconElement;
1320
+ const getScrollLeft = this._getScrollLeft.bind(this);
1321
+ const openedIconElement = this.renderer.openedIconElement;
1322
+ const tabIndex = this.options.tabIndex;
1323
+ const $treeElement = this.element;
1324
+ const triggerEvent = this._triggerEvent.bind(this);
1325
+
1326
+ return new FolderElement({
1327
+ closedIconElement,
1328
+ getScrollLeft,
1329
+ node,
1330
+ openedIconElement,
1331
+ tabIndex,
1332
+ $treeElement,
1333
+ triggerEvent,
1334
+ });
1335
+ }
1336
+
1337
+ private createNodeElement(node: Node) {
1338
+ const getScrollLeft = this._getScrollLeft.bind(this);
1339
+ const tabIndex = this.options.tabIndex;
1340
+ const $treeElement = this.element;
1341
+
1342
+ return new NodeElement({
1343
+ getScrollLeft,
1344
+ node,
1345
+ tabIndex,
1346
+ $treeElement,
1347
+ });
1348
+ }
1349
+
1350
+ private openParents(node: Node) {
1351
+ const parent = node.parent;
1352
+
1353
+ if (parent && parent.parent && !parent.is_open) {
1354
+ this.openNode(parent, false);
1355
+ }
1356
+ }
1178
1357
  }
1179
1358
 
1180
1359
  SimpleWidget.register(JqTreeWidget, "tree");
package/src/util.ts CHANGED
@@ -5,3 +5,6 @@ export const isFunction = (v: unknown): boolean => typeof v === "function";
5
5
 
6
6
  export const getBoolString = (value: unknown): string =>
7
7
  value ? "true" : "false";
8
+
9
+ export const getOffsetTop = (element: HTMLElement) =>
10
+ element.getBoundingClientRect().y + window.scrollY;
package/src/version.ts CHANGED
@@ -1,3 +1,3 @@
1
- const version = "1.7.4";
1
+ const version = "1.8.0";
2
2
 
3
3
  export default version;