tree-element 0.2.0 → 0.3.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.
- package/README.md +12 -4
- package/lib/animation.d.ts +2 -2
- package/lib/animation.d.ts.map +1 -1
- package/lib/animation.js +13 -9
- package/lib/animation.js.map +1 -1
- package/lib/dataLoader.d.ts +1 -0
- package/lib/dataLoader.d.ts.map +1 -1
- package/lib/dataLoader.js +8 -0
- package/lib/dataLoader.js.map +1 -1
- package/lib/dragAndDropHandler/dragElement.d.ts.map +1 -1
- package/lib/dragAndDropHandler/dragElement.js +2 -1
- package/lib/dragAndDropHandler/dragElement.js.map +1 -1
- package/lib/dragAndDropHandler/index.d.ts.map +1 -1
- package/lib/dragAndDropHandler/index.js +56 -65
- package/lib/dragAndDropHandler/index.js.map +1 -1
- package/lib/dragAndDropHandler/iterateVisibleNodes.d.ts.map +1 -1
- package/lib/dragAndDropHandler/iterateVisibleNodes.js +16 -15
- package/lib/dragAndDropHandler/iterateVisibleNodes.js.map +1 -1
- package/lib/elementsRenderer.d.ts +5 -1
- package/lib/elementsRenderer.d.ts.map +1 -1
- package/lib/elementsRenderer.js +62 -39
- package/lib/elementsRenderer.js.map +1 -1
- package/lib/events.d.ts +44 -11
- package/lib/events.d.ts.map +1 -1
- package/lib/index.d.ts +31 -8
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +162 -122
- package/lib/index.js.map +1 -1
- package/lib/keyHandler.d.ts +11 -5
- package/lib/keyHandler.d.ts.map +1 -1
- package/lib/keyHandler.js +87 -33
- package/lib/keyHandler.js.map +1 -1
- package/lib/methodTypes.d.ts +2 -2
- package/lib/methodTypes.d.ts.map +1 -1
- package/lib/mouseHandler.d.ts +1 -1
- package/lib/mouseHandler.d.ts.map +1 -1
- package/lib/mouseHandler.js +10 -7
- package/lib/mouseHandler.js.map +1 -1
- package/lib/node.d.ts +45 -15
- package/lib/node.d.ts.map +1 -1
- package/lib/node.js +136 -139
- package/lib/node.js.map +1 -1
- package/lib/nodeElement/folderElement.d.ts +1 -1
- package/lib/nodeElement/folderElement.d.ts.map +1 -1
- package/lib/nodeElement/folderElement.js +46 -57
- package/lib/nodeElement/folderElement.js.map +1 -1
- package/lib/nodeElement/ghostDropHint.d.ts.map +1 -1
- package/lib/nodeElement/ghostDropHint.js +8 -4
- package/lib/nodeElement/ghostDropHint.js.map +1 -1
- package/lib/nodeElement/index.d.ts.map +1 -1
- package/lib/nodeElement/index.js +6 -6
- package/lib/nodeElement/index.js.map +1 -1
- package/lib/nodeUtils.d.ts.map +1 -1
- package/lib/nodeUtils.js +1 -1
- package/lib/nodeUtils.js.map +1 -1
- package/lib/options.d.ts +19 -3
- package/lib/options.d.ts.map +1 -1
- package/lib/requestUrl.d.ts.map +1 -1
- package/lib/requestUrl.js +2 -11
- package/lib/requestUrl.js.map +1 -1
- package/lib/saveStateHandler.d.ts.map +1 -1
- package/lib/saveStateHandler.js +21 -41
- package/lib/saveStateHandler.js.map +1 -1
- package/lib/scrollHandler/containerScrollParent.d.ts.map +1 -1
- package/lib/scrollHandler/containerScrollParent.js +3 -8
- package/lib/scrollHandler/containerScrollParent.js.map +1 -1
- package/lib/scrollHandler/createScrollParent.d.ts.map +1 -1
- package/lib/scrollHandler/createScrollParent.js +4 -5
- package/lib/scrollHandler/createScrollParent.js.map +1 -1
- package/lib/scrollHandler/documentScrollParent.d.ts.map +1 -1
- package/lib/scrollHandler/documentScrollParent.js +3 -9
- package/lib/scrollHandler/documentScrollParent.js.map +1 -1
- package/lib/scrollHandler/scrollParent.d.ts.map +1 -1
- package/lib/scrollHandler/scrollParent.js +19 -17
- package/lib/scrollHandler/scrollParent.js.map +1 -1
- package/lib/selectNodeHandler.d.ts +3 -1
- package/lib/selectNodeHandler.d.ts.map +1 -1
- package/lib/selectNodeHandler.js +27 -37
- package/lib/selectNodeHandler.js.map +1 -1
- package/lib/setDefaultOptions.d.ts.map +1 -1
- package/lib/setDefaultOptions.js +11 -10
- package/lib/setDefaultOptions.js.map +1 -1
- package/lib/util.d.ts.map +1 -1
- package/lib/util.js +1 -1
- package/lib/util.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/version.js.map +1 -1
- package/package.json +42 -33
- package/src/animation.ts +13 -11
- package/src/dataLoader.ts +11 -0
- package/src/dragAndDropHandler/dragElement.ts +2 -1
- package/src/dragAndDropHandler/index.ts +70 -75
- package/src/dragAndDropHandler/iterateVisibleNodes.ts +18 -16
- package/src/elementsRenderer.ts +76 -46
- package/src/events.ts +44 -11
- package/src/index.ts +210 -150
- package/src/keyHandler.ts +95 -41
- package/src/methodTypes.ts +3 -3
- package/src/mouseHandler.ts +10 -7
- package/src/node.ts +155 -148
- package/src/nodeElement/folderElement.ts +54 -63
- package/src/nodeElement/ghostDropHint.ts +4 -2
- package/src/nodeElement/index.ts +9 -15
- package/src/nodeUtils.ts +1 -1
- package/src/options.ts +19 -3
- package/src/requestUrl.ts +4 -11
- package/src/saveStateHandler.ts +29 -43
- package/src/scrollHandler/containerScrollParent.ts +3 -9
- package/src/scrollHandler/createScrollParent.ts +1 -2
- package/src/scrollHandler/documentScrollParent.ts +5 -11
- package/src/scrollHandler/scrollParent.ts +29 -25
- package/src/selectNodeHandler.ts +34 -38
- package/src/setDefaultOptions.ts +19 -10
- package/src/util.ts +1 -2
- package/src/version.ts +1 -1
- package/tree_element.css +87 -69
- package/tree_element.debug.js +706 -639
- package/tree_element.debug.js.map +1 -1
- package/tree_element.js +2 -2
- package/tree_element.js.map +1 -1
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/lib/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
Tree-element 0.
|
|
2
|
+
Tree-element 0.3.0
|
|
3
3
|
|
|
4
4
|
Copyright 2026 Marco Braak
|
|
5
5
|
|
|
@@ -44,6 +44,7 @@ class TreeElement {
|
|
|
44
44
|
_classNames;
|
|
45
45
|
_dataLoader;
|
|
46
46
|
_dndHandler;
|
|
47
|
+
_fallbackTabStop;
|
|
47
48
|
_htmlElement;
|
|
48
49
|
_isInitialized;
|
|
49
50
|
_keyHandler;
|
|
@@ -57,7 +58,9 @@ class TreeElement {
|
|
|
57
58
|
_tree;
|
|
58
59
|
_triggerEventProvider;
|
|
59
60
|
|
|
60
|
-
/**
|
|
61
|
+
/**
|
|
62
|
+
@hidden
|
|
63
|
+
*/
|
|
61
64
|
constructor({
|
|
62
65
|
htmlElement,
|
|
63
66
|
overrideTriggerEventProvider,
|
|
@@ -70,7 +73,10 @@ class TreeElement {
|
|
|
70
73
|
this._isInitialized = false;
|
|
71
74
|
this._tree = new Node({}, true);
|
|
72
75
|
this._nodeMap = new WeakMap();
|
|
76
|
+
this._fallbackTabStop = null;
|
|
73
77
|
let {
|
|
78
|
+
ariaLabel,
|
|
79
|
+
ariaLabelledBy,
|
|
74
80
|
autoEscape,
|
|
75
81
|
buttonLeft,
|
|
76
82
|
closedIcon,
|
|
@@ -97,10 +103,10 @@ class TreeElement {
|
|
|
97
103
|
let closeNode = this.closeNode.bind(this);
|
|
98
104
|
let getNodeElement = this._getNodeElement.bind(this);
|
|
99
105
|
let getNodeElementForNode = this._getNodeElementForNode.bind(this);
|
|
106
|
+
let getFocusedNode = this._getFocusedNode.bind(this);
|
|
100
107
|
let getNodeById = this.getNodeById.bind(this);
|
|
101
108
|
let getSelectedNode = this.getSelectedNode.bind(this);
|
|
102
109
|
let getTree = this.getTree.bind(this);
|
|
103
|
-
let isFocusOnTree = this._isFocusOnTree.bind(this);
|
|
104
110
|
let loadData = this.loadData.bind(this);
|
|
105
111
|
let openNode = this.openNode.bind(this);
|
|
106
112
|
let openParents = this._openParents.bind(this);
|
|
@@ -109,6 +115,7 @@ class TreeElement {
|
|
|
109
115
|
let setNodeElement = this._setNodeElement.bind(this);
|
|
110
116
|
let treeElement = this._htmlElement;
|
|
111
117
|
let triggerEvent = this._triggerEvent.bind(this);
|
|
118
|
+
let updateTabStop = this._updateTabStop.bind(this);
|
|
112
119
|
let saveState = () => {
|
|
113
120
|
saveStateHandler._saveState();
|
|
114
121
|
};
|
|
@@ -119,7 +126,8 @@ class TreeElement {
|
|
|
119
126
|
_getSelectable: () => this._options.selectable,
|
|
120
127
|
_openParents: openParents,
|
|
121
128
|
_saveState: saveState,
|
|
122
|
-
_triggerEvent: triggerEvent
|
|
129
|
+
_triggerEvent: triggerEvent,
|
|
130
|
+
_updateTabStop: updateTabStop
|
|
123
131
|
});
|
|
124
132
|
let addToSelection = selectNodeHandler._addToSelection.bind(selectNodeHandler);
|
|
125
133
|
let getSelectedNodes = selectNodeHandler._getSelectedNodes.bind(selectNodeHandler);
|
|
@@ -172,13 +180,17 @@ class TreeElement {
|
|
|
172
180
|
});
|
|
173
181
|
let keyHandler = new KeyHandler({
|
|
174
182
|
_closeNode: closeNode,
|
|
183
|
+
_getFocusedNode: getFocusedNode,
|
|
175
184
|
_getSelectedNode: getSelectedNode,
|
|
176
|
-
|
|
185
|
+
_getTree: getTree,
|
|
177
186
|
_keyboardSupport: keyboardSupport,
|
|
178
187
|
_openNode: openNode,
|
|
179
|
-
_selectNode: selectNode
|
|
188
|
+
_selectNode: selectNode,
|
|
189
|
+
_triggerEvent: triggerEvent
|
|
180
190
|
});
|
|
181
191
|
let renderer = new ElementsRenderer({
|
|
192
|
+
_ariaLabel: ariaLabel,
|
|
193
|
+
_ariaLabelledBy: ariaLabelledBy,
|
|
182
194
|
_autoEscape: autoEscape,
|
|
183
195
|
_buttonLeft: buttonLeft,
|
|
184
196
|
_classNames: classNames,
|
|
@@ -273,10 +285,11 @@ class TreeElement {
|
|
|
273
285
|
* @param mustSetFocus - Move the focus to the node. Default `true`.
|
|
274
286
|
* @group Selection
|
|
275
287
|
*/
|
|
276
|
-
addToSelection(node, mustSetFocus) {
|
|
288
|
+
addToSelection(node, mustSetFocus = true) {
|
|
277
289
|
this._selectNodeHandler._addToSelection(node);
|
|
278
290
|
this._openParents(node);
|
|
279
|
-
this._getNodeElementForNode(node)._select(mustSetFocus
|
|
291
|
+
this._getNodeElementForNode(node)._select(mustSetFocus);
|
|
292
|
+
this._updateTabStop();
|
|
280
293
|
this._saveState();
|
|
281
294
|
}
|
|
282
295
|
|
|
@@ -298,16 +311,24 @@ class TreeElement {
|
|
|
298
311
|
}
|
|
299
312
|
|
|
300
313
|
/**
|
|
301
|
-
* Closes a folder.
|
|
314
|
+
* Closes a folder. Await the promise when you need to know the closing
|
|
315
|
+
* animation has finished.
|
|
316
|
+
*
|
|
317
|
+
* @example
|
|
318
|
+
* ```js
|
|
319
|
+
* await tree.closeNode(node);
|
|
320
|
+
* console.log("closed");
|
|
321
|
+
* ```
|
|
302
322
|
*
|
|
303
323
|
* @param slide - Override the `slide` option for this call.
|
|
304
324
|
* @group Opening and closing
|
|
305
325
|
*/
|
|
306
|
-
closeNode(node, slide) {
|
|
307
|
-
if (node.isFolder() || node.isEmptyFolder) {
|
|
308
|
-
|
|
309
|
-
this._saveState();
|
|
326
|
+
async closeNode(node, slide) {
|
|
327
|
+
if (!(node.isFolder() || node.isEmptyFolder)) {
|
|
328
|
+
return;
|
|
310
329
|
}
|
|
330
|
+
await this._createFolderElement(node)._close(slide ?? this._options.slide, this._options.animationSpeed);
|
|
331
|
+
this._saveState();
|
|
311
332
|
}
|
|
312
333
|
|
|
313
334
|
/**
|
|
@@ -331,11 +352,7 @@ class TreeElement {
|
|
|
331
352
|
*/
|
|
332
353
|
getNode(element) {
|
|
333
354
|
let liElement = element.closest(`li.${this._classNames.common}`);
|
|
334
|
-
|
|
335
|
-
return this._nodeMap.get(liElement) ?? null;
|
|
336
|
-
} else {
|
|
337
|
-
return null;
|
|
338
|
-
}
|
|
355
|
+
return liElement ? this._nodeMap.get(liElement) ?? null : null;
|
|
339
356
|
}
|
|
340
357
|
|
|
341
358
|
/**
|
|
@@ -626,6 +643,7 @@ class TreeElement {
|
|
|
626
643
|
removeFromSelection(node) {
|
|
627
644
|
this._selectNodeHandler._removeFromSelection(node);
|
|
628
645
|
this._getNodeElementForNode(node)._deselect();
|
|
646
|
+
this._updateTabStop();
|
|
629
647
|
this._saveState();
|
|
630
648
|
}
|
|
631
649
|
|
|
@@ -671,7 +689,12 @@ class TreeElement {
|
|
|
671
689
|
this._saveStateHandler._saveState();
|
|
672
690
|
return;
|
|
673
691
|
}
|
|
674
|
-
|
|
692
|
+
|
|
693
|
+
// Unlike a click, selecting the selected node again keeps it selected
|
|
694
|
+
this._selectNodeHandler._selectSingleNode(node, {
|
|
695
|
+
mustToggle: false,
|
|
696
|
+
...options
|
|
697
|
+
});
|
|
675
698
|
}
|
|
676
699
|
|
|
677
700
|
/**
|
|
@@ -697,17 +720,19 @@ class TreeElement {
|
|
|
697
720
|
}
|
|
698
721
|
|
|
699
722
|
/**
|
|
700
|
-
* Closes an open node and opens a closed one.
|
|
723
|
+
* Closes an open node and opens a closed one. Await the promise when you
|
|
724
|
+
* need to know the node is really open or closed, like with `openNode` and
|
|
725
|
+
* `closeNode`.
|
|
701
726
|
*
|
|
702
727
|
* @param slide - Override the `slide` option for this call.
|
|
703
728
|
* @group Opening and closing
|
|
704
729
|
*/
|
|
705
|
-
toggle(node, slide = null) {
|
|
730
|
+
async toggle(node, slide = null) {
|
|
706
731
|
let mustSlide = slide ?? this._options.slide;
|
|
707
732
|
if (node.is_open) {
|
|
708
|
-
this.closeNode(node, mustSlide);
|
|
733
|
+
await this.closeNode(node, mustSlide);
|
|
709
734
|
} else {
|
|
710
|
-
|
|
735
|
+
await this.openNode(node, mustSlide);
|
|
711
736
|
}
|
|
712
737
|
}
|
|
713
738
|
|
|
@@ -745,7 +770,7 @@ class TreeElement {
|
|
|
745
770
|
if (idIsChanged) {
|
|
746
771
|
this._tree.addNodeToIndex(node);
|
|
747
772
|
}
|
|
748
|
-
if (typeof data === "object" && data.children && data.children
|
|
773
|
+
if (typeof data === "object" && data.children && Array.isArray(data.children)) {
|
|
749
774
|
node.removeChildren();
|
|
750
775
|
if (data.children.length) {
|
|
751
776
|
node.loadFromData(data.children);
|
|
@@ -753,15 +778,45 @@ class TreeElement {
|
|
|
753
778
|
}
|
|
754
779
|
this._refreshElements(node);
|
|
755
780
|
}
|
|
781
|
+
|
|
782
|
+
// Open the nodes up to the autoOpen level. A folder that is loaded on
|
|
783
|
+
// demand is fetched first, and its children are opened when the data has
|
|
784
|
+
// arrived.
|
|
785
|
+
async _autoOpenNodesOnDemand() {
|
|
786
|
+
let maxLevel = this._getAutoOpenMaxLevel();
|
|
787
|
+
let openNodes = async () => {
|
|
788
|
+
let loading = [];
|
|
789
|
+
this._tree.iterate((node, level) => {
|
|
790
|
+
if (node.load_on_demand) {
|
|
791
|
+
if (!node.is_loading) {
|
|
792
|
+
loading.push(this.openNode(node, false).then(openNodes));
|
|
793
|
+
}
|
|
794
|
+
return false;
|
|
795
|
+
}
|
|
796
|
+
void this.openNode(node, false);
|
|
797
|
+
return level !== maxLevel;
|
|
798
|
+
});
|
|
799
|
+
await Promise.all(loading);
|
|
800
|
+
};
|
|
801
|
+
await openNodes();
|
|
802
|
+
}
|
|
756
803
|
_createFolderElement(node) {
|
|
757
804
|
let classNames = this._classNames;
|
|
758
805
|
let closedIconElement = this._renderer._closedIconElement;
|
|
759
806
|
let getScrollLeft = this._scrollHandler._getScrollLeft.bind(this._scrollHandler);
|
|
760
807
|
let openedIconElement = this._renderer._openedIconElement;
|
|
761
|
-
let renderChildren = this._renderer._renderChildren.bind(this._renderer);
|
|
762
808
|
let tabIndex = this._options.tabIndex;
|
|
763
809
|
let treeElement = this._htmlElement;
|
|
764
810
|
let triggerEvent = this._triggerEvent.bind(this);
|
|
811
|
+
|
|
812
|
+
// A selected node in a closed folder is rendered when the folder is
|
|
813
|
+
// opened, which can be after it was selected. It becomes the tab stop
|
|
814
|
+
// then, so the fallback tab stop must go.
|
|
815
|
+
let renderChildren = folder => {
|
|
816
|
+
let ul = this._renderer._renderChildren(folder);
|
|
817
|
+
this._updateTabStop();
|
|
818
|
+
return ul;
|
|
819
|
+
};
|
|
765
820
|
return new FolderElement({
|
|
766
821
|
_classNames: classNames,
|
|
767
822
|
_closedIconElement: closedIconElement,
|
|
@@ -794,12 +849,7 @@ class TreeElement {
|
|
|
794
849
|
*/
|
|
795
850
|
_createRequestUrl(node) {
|
|
796
851
|
let dataUrl = this._options.dataUrl;
|
|
797
|
-
let url;
|
|
798
|
-
if (typeof dataUrl === "function") {
|
|
799
|
-
url = dataUrl(node);
|
|
800
|
-
} else {
|
|
801
|
-
url = dataUrl;
|
|
802
|
-
}
|
|
852
|
+
let url = typeof dataUrl === "function" ? dataUrl(node) : dataUrl;
|
|
803
853
|
if (!url) {
|
|
804
854
|
return null;
|
|
805
855
|
}
|
|
@@ -835,33 +885,54 @@ class TreeElement {
|
|
|
835
885
|
_getAutoOpenMaxLevel() {
|
|
836
886
|
if (this._options.autoOpen === true) {
|
|
837
887
|
return -1;
|
|
838
|
-
}
|
|
888
|
+
}
|
|
889
|
+
if (typeof this._options.autoOpen === "number") {
|
|
839
890
|
return this._options.autoOpen;
|
|
840
|
-
}
|
|
891
|
+
}
|
|
892
|
+
if (typeof this._options.autoOpen === "string") {
|
|
841
893
|
return parseInt(this._options.autoOpen, 10);
|
|
842
894
|
}
|
|
843
895
|
|
|
844
896
|
/* istanbul ignore next @preserve */
|
|
845
897
|
return 0;
|
|
846
898
|
}
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
}
|
|
899
|
+
|
|
900
|
+
// The title span of the first node, or null when the tree is empty
|
|
901
|
+
_getFirstTitleSpan() {
|
|
902
|
+
let firstElement = this._tree.children[0]?.element;
|
|
903
|
+
return firstElement ? firstElement.querySelector(`:scope > .${this._classNames.element} > span.${this._classNames.title}`) : null;
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
// The node of the HTML element that has the focus, if it is in this tree
|
|
907
|
+
_getFocusedNode() {
|
|
908
|
+
let activeElement = document.activeElement;
|
|
909
|
+
|
|
910
|
+
/* istanbul ignore if */
|
|
911
|
+
if (!activeElement) {
|
|
912
|
+
return null;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
// The keyboard must still work for input elements.
|
|
916
|
+
let tagName = activeElement.tagName;
|
|
917
|
+
if (tagName !== "A" && tagName !== "SPAN") {
|
|
852
918
|
return null;
|
|
853
919
|
}
|
|
920
|
+
let node = this.getNode(activeElement);
|
|
921
|
+
return node?.tree === this._tree ? node : null;
|
|
922
|
+
}
|
|
923
|
+
_getNodeElement(element) {
|
|
924
|
+
let node = this.getNode(element);
|
|
925
|
+
return node ? this._getNodeElementForNode(node) : null;
|
|
854
926
|
}
|
|
855
927
|
_getNodeElementForNode(node) {
|
|
856
|
-
|
|
857
|
-
return this._createFolderElement(node);
|
|
858
|
-
} else {
|
|
859
|
-
return this._createNodeElement(node);
|
|
860
|
-
}
|
|
928
|
+
return node.isFolder() ? this._createFolderElement(node) : this._createNodeElement(node);
|
|
861
929
|
}
|
|
862
930
|
_getNodeIdToBeSelected() {
|
|
863
931
|
return this._saveStateHandler._getNodeIdToBeSelected();
|
|
864
932
|
}
|
|
933
|
+
_hasRenderedSelectedNode() {
|
|
934
|
+
return this.getSelectedNodes().some(node => Boolean(node.element));
|
|
935
|
+
}
|
|
865
936
|
_initData() {
|
|
866
937
|
if (this._options.data) {
|
|
867
938
|
this.loadData(this._options.data);
|
|
@@ -876,10 +947,11 @@ class TreeElement {
|
|
|
876
947
|
}
|
|
877
948
|
_initTree(data) {
|
|
878
949
|
let doInit = () => {
|
|
879
|
-
if (
|
|
880
|
-
|
|
881
|
-
this._triggerEvent("tree.init");
|
|
950
|
+
if (this._isInitialized) {
|
|
951
|
+
return;
|
|
882
952
|
}
|
|
953
|
+
this._isInitialized = true;
|
|
954
|
+
this._triggerEvent("tree.init");
|
|
883
955
|
};
|
|
884
956
|
this._tree = new this._options.nodeClass(null, true, this._options.nodeClass);
|
|
885
957
|
this._selectNodeHandler._clear();
|
|
@@ -896,32 +968,22 @@ class TreeElement {
|
|
|
896
968
|
|
|
897
969
|
// Does an HTML element of the tree have the focus?
|
|
898
970
|
_isFocusOnTree() {
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
/* istanbul ignore if */
|
|
902
|
-
if (!activeElement) {
|
|
903
|
-
return false;
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
// The keyboard must still work for input elements.
|
|
907
|
-
let tagName = activeElement.tagName;
|
|
908
|
-
if (tagName !== "A" && tagName !== "SPAN") {
|
|
909
|
-
return false;
|
|
910
|
-
}
|
|
911
|
-
let node = this.getNode(activeElement);
|
|
912
|
-
return node?.tree === this._tree;
|
|
971
|
+
return this._getFocusedNode() !== null;
|
|
913
972
|
}
|
|
914
973
|
_isSelectedNodeInSubtree(subtree) {
|
|
915
974
|
let selectedNode = this.getSelectedNode();
|
|
916
|
-
|
|
917
|
-
return false;
|
|
918
|
-
} else {
|
|
919
|
-
return subtree === selectedNode || subtree.isParentOf(selectedNode);
|
|
920
|
-
}
|
|
975
|
+
return selectedNode ? subtree === selectedNode || subtree.isParentOf(selectedNode) : false;
|
|
921
976
|
}
|
|
922
977
|
async _loadFolderOnDemand(node, slide) {
|
|
923
978
|
node.is_loading = true;
|
|
924
979
|
await this.loadDataFromUrl(undefined, node);
|
|
980
|
+
|
|
981
|
+
// Loading failed, or there is no url. Opening the node now would load it
|
|
982
|
+
// again, without end. Leave it closed so the user can try again.
|
|
983
|
+
if (node.load_on_demand) {
|
|
984
|
+
node.is_loading = false;
|
|
985
|
+
return;
|
|
986
|
+
}
|
|
925
987
|
await this.openNode(node, slide);
|
|
926
988
|
}
|
|
927
989
|
_loadSubtree(data, parentNode) {
|
|
@@ -931,10 +993,7 @@ class TreeElement {
|
|
|
931
993
|
this._refreshElements(parentNode);
|
|
932
994
|
}
|
|
933
995
|
_mouseCapture(positionInfo) {
|
|
934
|
-
|
|
935
|
-
return false;
|
|
936
|
-
}
|
|
937
|
-
return this._dndHandler._mouseCapture(positionInfo);
|
|
996
|
+
return this._options.dragAndDrop ? this._dndHandler._mouseCapture(positionInfo) : false;
|
|
938
997
|
}
|
|
939
998
|
_mouseDrag(positionInfo) {
|
|
940
999
|
/* istanbul ignore if */
|
|
@@ -947,6 +1006,7 @@ class TreeElement {
|
|
|
947
1006
|
}
|
|
948
1007
|
_mouseStart(positionInfo) {
|
|
949
1008
|
/* istanbul ignore if */
|
|
1009
|
+
// eslint-disable-next-line unicorn/prefer-ternary
|
|
950
1010
|
if (!this._options.dragAndDrop) {
|
|
951
1011
|
return false;
|
|
952
1012
|
}
|
|
@@ -978,6 +1038,7 @@ class TreeElement {
|
|
|
978
1038
|
if (mustSelect) {
|
|
979
1039
|
this._selectCurrentNode(mustSetFocus);
|
|
980
1040
|
}
|
|
1041
|
+
this._updateTabStop();
|
|
981
1042
|
this._triggerEvent("tree.refresh");
|
|
982
1043
|
}
|
|
983
1044
|
_saveState() {
|
|
@@ -985,10 +1046,11 @@ class TreeElement {
|
|
|
985
1046
|
}
|
|
986
1047
|
_selectCurrentNode(mustSetFocus) {
|
|
987
1048
|
let node = this.getSelectedNode();
|
|
988
|
-
if (node) {
|
|
989
|
-
|
|
990
|
-
nodeElement._select(mustSetFocus);
|
|
1049
|
+
if (!node) {
|
|
1050
|
+
return;
|
|
991
1051
|
}
|
|
1052
|
+
let nodeElement = this._getNodeElementForNode(node);
|
|
1053
|
+
nodeElement._select(mustSetFocus);
|
|
992
1054
|
}
|
|
993
1055
|
|
|
994
1056
|
// Set initial state, either by restoring the state or auto-opening nodes
|
|
@@ -997,14 +1059,13 @@ class TreeElement {
|
|
|
997
1059
|
let restoreState = () => {
|
|
998
1060
|
// result: is state restored, must load on demand?
|
|
999
1061
|
let state = this._saveStateHandler._getStateFromStorage();
|
|
1000
|
-
if (
|
|
1001
|
-
return [false, false];
|
|
1002
|
-
} else {
|
|
1062
|
+
if (state) {
|
|
1003
1063
|
let mustLoadOnDemand = this._saveStateHandler._setInitialState(state);
|
|
1004
1064
|
|
|
1005
1065
|
// return true: the state is restored
|
|
1006
1066
|
return [true, mustLoadOnDemand];
|
|
1007
1067
|
}
|
|
1068
|
+
return [false, false];
|
|
1008
1069
|
};
|
|
1009
1070
|
let autoOpenNodes = () => {
|
|
1010
1071
|
// result: must load on demand?
|
|
@@ -1017,12 +1078,12 @@ class TreeElement {
|
|
|
1017
1078
|
if (node.load_on_demand) {
|
|
1018
1079
|
mustLoadOnDemand = true;
|
|
1019
1080
|
return false;
|
|
1020
|
-
}
|
|
1021
|
-
|
|
1022
|
-
} else {
|
|
1081
|
+
}
|
|
1082
|
+
if (node.hasChildren()) {
|
|
1023
1083
|
node.is_open = true;
|
|
1024
1084
|
return level !== maxLevel;
|
|
1025
1085
|
}
|
|
1086
|
+
return false;
|
|
1026
1087
|
});
|
|
1027
1088
|
return mustLoadOnDemand;
|
|
1028
1089
|
};
|
|
@@ -1036,50 +1097,12 @@ class TreeElement {
|
|
|
1036
1097
|
|
|
1037
1098
|
// Set the initial state for nodes that are loaded on demand
|
|
1038
1099
|
async _setInitialStateOnDemand() {
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
void this._saveStateHandler._setInitialStateOnDemand(state).then(() => {
|
|
1046
|
-
resolve();
|
|
1047
|
-
});
|
|
1048
|
-
return true;
|
|
1049
|
-
}
|
|
1050
|
-
};
|
|
1051
|
-
let autoOpenNodes = () => {
|
|
1052
|
-
let maxLevel = this._getAutoOpenMaxLevel();
|
|
1053
|
-
let loadingCount = 0;
|
|
1054
|
-
let loadAndOpenNode = node => {
|
|
1055
|
-
loadingCount += 1;
|
|
1056
|
-
void this.openNode(node, false).then(() => {
|
|
1057
|
-
loadingCount -= 1;
|
|
1058
|
-
openNodes();
|
|
1059
|
-
});
|
|
1060
|
-
};
|
|
1061
|
-
let openNodes = () => {
|
|
1062
|
-
this._tree.iterate((node, level) => {
|
|
1063
|
-
if (node.load_on_demand) {
|
|
1064
|
-
if (!node.is_loading) {
|
|
1065
|
-
loadAndOpenNode(node);
|
|
1066
|
-
}
|
|
1067
|
-
return false;
|
|
1068
|
-
} else {
|
|
1069
|
-
void this.openNode(node, false);
|
|
1070
|
-
return level !== maxLevel;
|
|
1071
|
-
}
|
|
1072
|
-
});
|
|
1073
|
-
if (loadingCount === 0) {
|
|
1074
|
-
resolve();
|
|
1075
|
-
}
|
|
1076
|
-
};
|
|
1077
|
-
openNodes();
|
|
1078
|
-
};
|
|
1079
|
-
if (!restoreState()) {
|
|
1080
|
-
autoOpenNodes();
|
|
1081
|
-
}
|
|
1082
|
-
});
|
|
1100
|
+
let state = this._saveStateHandler._getStateFromStorage();
|
|
1101
|
+
if (state) {
|
|
1102
|
+
await this._saveStateHandler._setInitialStateOnDemand(state);
|
|
1103
|
+
} else {
|
|
1104
|
+
await this._autoOpenNodesOnDemand();
|
|
1105
|
+
}
|
|
1083
1106
|
}
|
|
1084
1107
|
|
|
1085
1108
|
// Set this HTML element to this node in the node map.
|
|
@@ -1089,6 +1112,23 @@ class TreeElement {
|
|
|
1089
1112
|
_triggerEvent(eventName, values) {
|
|
1090
1113
|
return this._triggerEventProvider(this._htmlElement, eventName, values);
|
|
1091
1114
|
}
|
|
1115
|
+
|
|
1116
|
+
/* Keyboard users reach the tree through the tab stop. The selected node is
|
|
1117
|
+
* the tab stop, see NodeElement.select. Without a selected node, the first
|
|
1118
|
+
* node is the tab stop, so the tree can always be reached.
|
|
1119
|
+
*/
|
|
1120
|
+
_updateTabStop() {
|
|
1121
|
+
let tabIndex = this._options.tabIndex;
|
|
1122
|
+
let previousTabStop = this._fallbackTabStop;
|
|
1123
|
+
let tabStop = tabIndex == null || this._hasRenderedSelectedNode() ? null : this._getFirstTitleSpan();
|
|
1124
|
+
if (previousTabStop && previousTabStop !== tabStop && previousTabStop.getAttribute("aria-selected") !== "true") {
|
|
1125
|
+
previousTabStop.setAttribute("tabindex", "-1");
|
|
1126
|
+
}
|
|
1127
|
+
if (tabStop && tabIndex != null) {
|
|
1128
|
+
tabStop.setAttribute("tabindex", String(tabIndex));
|
|
1129
|
+
}
|
|
1130
|
+
this._fallbackTabStop = tabStop;
|
|
1131
|
+
}
|
|
1092
1132
|
}
|
|
1093
1133
|
|
|
1094
1134
|
export { TreeElement as default };
|