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/tree_element.debug.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
|
|
|
@@ -78,12 +78,17 @@ var TreeElement = (function () {
|
|
|
78
78
|
async _loadFromUrl(url, node) {
|
|
79
79
|
let element = node?.element ?? this._treeElement;
|
|
80
80
|
element.classList.add(this._classNames.loading);
|
|
81
|
+
|
|
82
|
+
// Tell screen readers that the children of the folder are loading
|
|
83
|
+
let titleSpan = node ? this._getTitleSpan(element) : null;
|
|
84
|
+
titleSpan?.setAttribute("aria-busy", "true");
|
|
81
85
|
this._triggerEvent("tree.loading_data", {
|
|
82
86
|
element,
|
|
83
87
|
node
|
|
84
88
|
});
|
|
85
89
|
let stopLoading = () => {
|
|
86
90
|
element.classList.remove(this._classNames.loading);
|
|
91
|
+
titleSpan?.removeAttribute("aria-busy");
|
|
87
92
|
this._triggerEvent("tree.loaded_data", {
|
|
88
93
|
element,
|
|
89
94
|
node
|
|
@@ -119,6 +124,9 @@ var TreeElement = (function () {
|
|
|
119
124
|
});
|
|
120
125
|
});
|
|
121
126
|
}
|
|
127
|
+
_getTitleSpan(element) {
|
|
128
|
+
return element.querySelector(`:scope > .${this._classNames.element} > .${this._classNames.title}`);
|
|
129
|
+
}
|
|
122
130
|
}
|
|
123
131
|
|
|
124
132
|
// Get the top position of the HTML element.
|
|
@@ -166,7 +174,7 @@ var TreeElement = (function () {
|
|
|
166
174
|
this._offsetX = offsetX;
|
|
167
175
|
this._offsetY = offsetY;
|
|
168
176
|
this._element = this._createElement(nodeName, autoEscape, classNames);
|
|
169
|
-
treeElement.
|
|
177
|
+
treeElement.append(this._element);
|
|
170
178
|
}
|
|
171
179
|
_move(pageX, pageY) {
|
|
172
180
|
this._element.style.left = `${pageX - this._offsetX}px`;
|
|
@@ -181,6 +189,7 @@ var TreeElement = (function () {
|
|
|
181
189
|
if (autoEscape) {
|
|
182
190
|
element.textContent = nodeName;
|
|
183
191
|
} else {
|
|
192
|
+
// eslint-disable-next-line no-unsanitized/property -- the user opted out of escaping with autoEscape: false
|
|
184
193
|
element.innerHTML = nodeName;
|
|
185
194
|
}
|
|
186
195
|
element.style.position = "absolute";
|
|
@@ -217,25 +226,26 @@ var TreeElement = (function () {
|
|
|
217
226
|
handleClosedFolder(node, nextNode, element);
|
|
218
227
|
}
|
|
219
228
|
}
|
|
220
|
-
if (mustIterateInside) {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
229
|
+
if (!mustIterateInside) {
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
let childrenLength = node.children.length;
|
|
233
|
+
for (let i of node.children.keys()) {
|
|
234
|
+
let child = node.children[i];
|
|
235
|
+
if (child) {
|
|
236
|
+
if (i === childrenLength - 1) {
|
|
237
|
+
iterate(child, null);
|
|
238
|
+
} else {
|
|
239
|
+
let nextChild = node.children[i + 1];
|
|
240
|
+
if (nextChild) {
|
|
241
|
+
iterate(child, nextChild);
|
|
232
242
|
}
|
|
233
243
|
}
|
|
234
|
-
});
|
|
235
|
-
if (node.is_open && element) {
|
|
236
|
-
handleAfterOpenFolder(node, nextNode);
|
|
237
244
|
}
|
|
238
245
|
}
|
|
246
|
+
if (node.is_open && element) {
|
|
247
|
+
handleAfterOpenFolder(node, nextNode);
|
|
248
|
+
}
|
|
239
249
|
};
|
|
240
250
|
iterate(tree, null);
|
|
241
251
|
};
|
|
@@ -419,10 +429,8 @@ var TreeElement = (function () {
|
|
|
419
429
|
return null;
|
|
420
430
|
}
|
|
421
431
|
let nodeElement = this._getNodeElement(element);
|
|
422
|
-
if (nodeElement && this._onCanMove) {
|
|
423
|
-
|
|
424
|
-
nodeElement = null;
|
|
425
|
-
}
|
|
432
|
+
if (nodeElement && this._onCanMove && !this._onCanMove(nodeElement._node)) {
|
|
433
|
+
nodeElement = null;
|
|
426
434
|
}
|
|
427
435
|
this._currentItem = nodeElement;
|
|
428
436
|
return this._currentItem != null;
|
|
@@ -453,10 +461,8 @@ var TreeElement = (function () {
|
|
|
453
461
|
this._stopOpenFolderTimer();
|
|
454
462
|
this._hoveredArea = area;
|
|
455
463
|
}
|
|
456
|
-
if (!area) {
|
|
457
|
-
|
|
458
|
-
this._onDragMove(this._currentItem._node, positionInfo.originalEvent);
|
|
459
|
-
}
|
|
464
|
+
if (!area && this._onDragMove) {
|
|
465
|
+
this._onDragMove(this._currentItem._node, positionInfo.originalEvent);
|
|
460
466
|
}
|
|
461
467
|
return true;
|
|
462
468
|
}
|
|
@@ -494,35 +500,32 @@ var TreeElement = (function () {
|
|
|
494
500
|
this._currentItem = null;
|
|
495
501
|
}
|
|
496
502
|
this._isDragging = false;
|
|
497
|
-
if (!this._hoveredArea && currentItem) {
|
|
498
|
-
|
|
499
|
-
this._onDragStop(currentItem._node, positionInfo.originalEvent);
|
|
500
|
-
}
|
|
503
|
+
if (!this._hoveredArea && currentItem && this._onDragStop) {
|
|
504
|
+
this._onDragStop(currentItem._node, positionInfo.originalEvent);
|
|
501
505
|
}
|
|
502
506
|
return false;
|
|
503
507
|
}
|
|
504
508
|
_refresh() {
|
|
505
509
|
this._removeHitAreas();
|
|
506
|
-
if (this._currentItem) {
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
510
|
+
if (!this._currentItem) {
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
let currentNode = this._currentItem._node;
|
|
514
|
+
this._generateHitAreas(currentNode);
|
|
515
|
+
this._currentItem = this._getNodeElementForNode(currentNode);
|
|
516
|
+
if (this._isDragging) {
|
|
517
|
+
this._currentItem._element.classList.add(this._classNames.moving);
|
|
513
518
|
}
|
|
514
519
|
}
|
|
515
520
|
_canMoveToArea(area, currentItem) {
|
|
516
|
-
|
|
517
|
-
return true;
|
|
518
|
-
}
|
|
519
|
-
return this._onCanMoveTo(currentItem._node, area.node, area.position);
|
|
521
|
+
return this._onCanMoveTo ? this._onCanMoveTo(currentItem._node, area.node, area.position) : true;
|
|
520
522
|
}
|
|
521
523
|
_clear() {
|
|
522
|
-
if (this._dragElement) {
|
|
523
|
-
|
|
524
|
-
this._dragElement = null;
|
|
524
|
+
if (!this._dragElement) {
|
|
525
|
+
return;
|
|
525
526
|
}
|
|
527
|
+
this._dragElement._remove();
|
|
528
|
+
this._dragElement = null;
|
|
526
529
|
}
|
|
527
530
|
_findHoveredArea(x, y) {
|
|
528
531
|
let dimensions = this._getTreeDimensions();
|
|
@@ -532,20 +535,13 @@ var TreeElement = (function () {
|
|
|
532
535
|
return binarySearch(this._hitAreas, area => {
|
|
533
536
|
if (y < area.top) {
|
|
534
537
|
return 1;
|
|
535
|
-
} else if (y > area.bottom) {
|
|
536
|
-
return -1;
|
|
537
|
-
} else {
|
|
538
|
-
return 0;
|
|
539
538
|
}
|
|
539
|
+
return y > area.bottom ? -1 : 0;
|
|
540
540
|
});
|
|
541
541
|
}
|
|
542
542
|
_generateHitAreas(currentNode) {
|
|
543
543
|
let tree = this._getTree();
|
|
544
|
-
|
|
545
|
-
this._hitAreas = [];
|
|
546
|
-
} else {
|
|
547
|
-
this._hitAreas = generateHitAreas(tree, currentNode, this._getTreeDimensions().bottom);
|
|
548
|
-
}
|
|
544
|
+
this._hitAreas = tree ? generateHitAreas(tree, currentNode, this._getTreeDimensions().bottom) : [];
|
|
549
545
|
}
|
|
550
546
|
_getTreeDimensions() {
|
|
551
547
|
// Return the dimensions of the tree. Add a margin to the bottom to allow
|
|
@@ -561,36 +557,40 @@ var TreeElement = (function () {
|
|
|
561
557
|
};
|
|
562
558
|
}
|
|
563
559
|
|
|
564
|
-
/*
|
|
560
|
+
/*
|
|
561
|
+
Move the dragged node to the selected position in the tree.
|
|
562
|
+
*/
|
|
565
563
|
_moveItem(positionInfo) {
|
|
566
|
-
if (this._currentItem && this._hoveredArea?.position && this._canMoveToArea(this._hoveredArea, this._currentItem)) {
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
564
|
+
if (!(this._currentItem && this._hoveredArea?.position && this._canMoveToArea(this._hoveredArea, this._currentItem))) {
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
let movedNode = this._currentItem._node;
|
|
568
|
+
let targetNode = this._hoveredArea.node;
|
|
569
|
+
let position = this._hoveredArea.position;
|
|
570
|
+
let previousParent = movedNode.parent;
|
|
571
|
+
if (position === "inside") {
|
|
572
|
+
this._hoveredArea.node.is_open = true;
|
|
573
|
+
}
|
|
574
|
+
let doMove = () => {
|
|
575
|
+
let tree = this._getTree();
|
|
576
|
+
if (!tree) {
|
|
577
|
+
return;
|
|
573
578
|
}
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
originalEvent: positionInfo.originalEvent,
|
|
587
|
-
position,
|
|
588
|
-
previousParent,
|
|
589
|
-
targetNode
|
|
590
|
-
}
|
|
591
|
-
})) {
|
|
592
|
-
doMove();
|
|
579
|
+
tree.moveNode(movedNode, targetNode, position);
|
|
580
|
+
this._treeElement.textContent = "";
|
|
581
|
+
this._refreshElements(null);
|
|
582
|
+
};
|
|
583
|
+
if (this._triggerEvent("tree.move", {
|
|
584
|
+
moveInfo: {
|
|
585
|
+
doMove,
|
|
586
|
+
movedNode,
|
|
587
|
+
originalEvent: positionInfo.originalEvent,
|
|
588
|
+
position,
|
|
589
|
+
previousParent,
|
|
590
|
+
targetNode
|
|
593
591
|
}
|
|
592
|
+
})) {
|
|
593
|
+
doMove();
|
|
594
594
|
}
|
|
595
595
|
}
|
|
596
596
|
_mustCaptureElement(element) {
|
|
@@ -626,10 +626,11 @@ var TreeElement = (function () {
|
|
|
626
626
|
}
|
|
627
627
|
}
|
|
628
628
|
_stopOpenFolderTimer() {
|
|
629
|
-
if (this._openFolderTimer) {
|
|
630
|
-
|
|
631
|
-
this._openFolderTimer = null;
|
|
629
|
+
if (!this._openFolderTimer) {
|
|
630
|
+
return;
|
|
632
631
|
}
|
|
632
|
+
clearTimeout(this._openFolderTimer);
|
|
633
|
+
this._openFolderTimer = null;
|
|
633
634
|
}
|
|
634
635
|
_updateDropHint() {
|
|
635
636
|
if (!this._hoveredArea) {
|
|
@@ -645,7 +646,7 @@ var TreeElement = (function () {
|
|
|
645
646
|
}
|
|
646
647
|
}
|
|
647
648
|
|
|
648
|
-
let isInt = n =>
|
|
649
|
+
let isInt = n => Number.isInteger(n);
|
|
649
650
|
let getBoolString = value => value ? "true" : "false";
|
|
650
651
|
|
|
651
652
|
/* Renders the tree to html.
|
|
@@ -661,21 +662,25 @@ var TreeElement = (function () {
|
|
|
661
662
|
*/
|
|
662
663
|
class ElementsRenderer {
|
|
663
664
|
constructor({
|
|
665
|
+
_ariaLabel: ariaLabel,
|
|
666
|
+
_ariaLabelledBy: ariaLabelledBy,
|
|
664
667
|
_autoEscape: autoEscape,
|
|
665
668
|
_buttonLeft: buttonLeft,
|
|
666
669
|
_classNames: classNames,
|
|
667
|
-
_closedIcon: closedIcon,
|
|
670
|
+
_closedIcon: closedIcon = "-",
|
|
668
671
|
_dragAndDrop: dragAndDrop,
|
|
669
672
|
_getTree: getTree,
|
|
670
673
|
_htmlElement: htmlElement,
|
|
671
674
|
_isNodeSelected: isNodeSelected,
|
|
672
675
|
_onCreateLi: onCreateLi,
|
|
673
|
-
_openedIcon: openedIcon,
|
|
676
|
+
_openedIcon: openedIcon = "+",
|
|
674
677
|
_rtl: rtl,
|
|
675
678
|
_setNodeElement: setNodeElement,
|
|
676
679
|
_showEmptyFolder: showEmptyFolder,
|
|
677
680
|
_tabIndex: tabIndex
|
|
678
681
|
}) {
|
|
682
|
+
this._ariaLabel = ariaLabel;
|
|
683
|
+
this._ariaLabelledBy = ariaLabelledBy;
|
|
679
684
|
this._autoEscape = autoEscape;
|
|
680
685
|
this._buttonLeft = buttonLeft;
|
|
681
686
|
this._classNames = classNames;
|
|
@@ -688,8 +693,8 @@ var TreeElement = (function () {
|
|
|
688
693
|
this._setNodeElement = setNodeElement;
|
|
689
694
|
this._showEmptyFolder = showEmptyFolder;
|
|
690
695
|
this._tabIndex = tabIndex;
|
|
691
|
-
this._openedIconElement = this._createButtonElement(openedIcon
|
|
692
|
-
this._closedIconElement = this._createButtonElement(closedIcon
|
|
696
|
+
this._openedIconElement = this._createButtonElement(openedIcon);
|
|
697
|
+
this._closedIconElement = this._createButtonElement(closedIcon);
|
|
693
698
|
this._rootUlTemplate = this._createUlTemplate(true);
|
|
694
699
|
this._groupUlTemplate = this._createUlTemplate(false);
|
|
695
700
|
this._nodeTemplate = this._createNodeTemplate();
|
|
@@ -708,10 +713,7 @@ var TreeElement = (function () {
|
|
|
708
713
|
* null when the folder is not rendered or has no children.
|
|
709
714
|
*/
|
|
710
715
|
_renderChildren(node) {
|
|
711
|
-
|
|
712
|
-
return null;
|
|
713
|
-
}
|
|
714
|
-
return this._createDomElements(node.element, node.children, false, node.getLevel() + 1);
|
|
716
|
+
return !node.element || !node.hasChildren() ? null : this._createDomElements(node.element, node.children, false, node.getLevel() + 1);
|
|
715
717
|
}
|
|
716
718
|
_renderFromNode(node) {
|
|
717
719
|
if (!node.element) {
|
|
@@ -743,21 +745,19 @@ var TreeElement = (function () {
|
|
|
743
745
|
_createButtonElement(value) {
|
|
744
746
|
if (typeof value === "string") {
|
|
745
747
|
let template = document.createElement("template");
|
|
748
|
+
// eslint-disable-next-line no-unsanitized/property -- icon options are documented to accept html
|
|
746
749
|
template.innerHTML = value;
|
|
747
750
|
return template.content;
|
|
748
|
-
} else if (value.nodeType) {
|
|
749
|
-
return value;
|
|
750
|
-
} else {
|
|
751
|
-
return undefined;
|
|
752
751
|
}
|
|
752
|
+
return value.nodeType ? value : undefined;
|
|
753
753
|
}
|
|
754
754
|
_createDomElements(element, children, isRootNode, level) {
|
|
755
755
|
let template = isRootNode ? this._rootUlTemplate : this._groupUlTemplate;
|
|
756
756
|
let ul = template.cloneNode();
|
|
757
|
-
element.
|
|
757
|
+
element.append(ul);
|
|
758
758
|
for (let child of children) {
|
|
759
759
|
let li = this._createLi(child, level);
|
|
760
|
-
ul.
|
|
760
|
+
ul.append(li);
|
|
761
761
|
if (this._mustRenderChildren(child)) {
|
|
762
762
|
this._createDomElements(li, child.children, false, level + 1);
|
|
763
763
|
}
|
|
@@ -770,19 +770,20 @@ var TreeElement = (function () {
|
|
|
770
770
|
if (isSelected) {
|
|
771
771
|
li.classList.add(this._classNames.selected);
|
|
772
772
|
}
|
|
773
|
-
if (node.is_loading) {
|
|
774
|
-
li.classList.add(this._classNames.loading);
|
|
775
|
-
}
|
|
776
773
|
|
|
777
|
-
// li > div > [
|
|
774
|
+
// li > div > [toggler], title span, [toggler]
|
|
778
775
|
let div = li.firstChild;
|
|
779
776
|
let titleSpan = div.childNodes[this._buttonLeft ? 1 : 0];
|
|
780
777
|
this._fillTitleSpan(titleSpan, node.name, isSelected, level);
|
|
778
|
+
if (node.is_loading) {
|
|
779
|
+
li.classList.add(this._classNames.loading);
|
|
780
|
+
titleSpan.setAttribute("aria-busy", "true");
|
|
781
|
+
}
|
|
781
782
|
return li;
|
|
782
783
|
}
|
|
783
784
|
|
|
784
785
|
/* Template for a folder <li>:
|
|
785
|
-
* li > div > [
|
|
786
|
+
* li > div > [toggler], title span, [toggler]
|
|
786
787
|
* The toggler icon and the aria-expanded attribute depend on the open
|
|
787
788
|
* state, so there is a template for each.
|
|
788
789
|
*/
|
|
@@ -794,23 +795,25 @@ var TreeElement = (function () {
|
|
|
794
795
|
let li = this._createLiTemplate(liClasses.join(" "));
|
|
795
796
|
let div = li.firstChild;
|
|
796
797
|
|
|
797
|
-
//
|
|
798
|
-
|
|
799
|
-
|
|
798
|
+
// The toggler is hidden from screen readers: the icon is decoration, and
|
|
799
|
+
// aria-expanded on the treeitem has the open state.
|
|
800
|
+
let toggler = document.createElement("span");
|
|
801
|
+
toggler.className = this._getButtonClasses(isOpen);
|
|
802
|
+
toggler.setAttribute("aria-hidden", "true");
|
|
800
803
|
let iconElement = isOpen ? this._openedIconElement : this._closedIconElement;
|
|
801
804
|
if (iconElement) {
|
|
802
|
-
|
|
805
|
+
toggler.append(iconElement.cloneNode(true));
|
|
803
806
|
}
|
|
804
807
|
if (this._buttonLeft) {
|
|
805
|
-
div.
|
|
808
|
+
div.append(toggler);
|
|
806
809
|
}
|
|
807
810
|
|
|
808
811
|
// title span
|
|
809
812
|
let titleSpan = this._createTitleSpanTemplate(true);
|
|
810
813
|
titleSpan.setAttribute("aria-expanded", getBoolString(isOpen));
|
|
811
|
-
div.
|
|
814
|
+
div.append(titleSpan);
|
|
812
815
|
if (!this._buttonLeft) {
|
|
813
|
-
div.
|
|
816
|
+
div.append(toggler);
|
|
814
817
|
}
|
|
815
818
|
return li;
|
|
816
819
|
}
|
|
@@ -830,7 +833,9 @@ var TreeElement = (function () {
|
|
|
830
833
|
return li;
|
|
831
834
|
}
|
|
832
835
|
|
|
833
|
-
/*
|
|
836
|
+
/*
|
|
837
|
+
Create the outer part of a <li> template: li > div
|
|
838
|
+
*/
|
|
834
839
|
_createLiTemplate(liClasses) {
|
|
835
840
|
let li = document.createElement("li");
|
|
836
841
|
li.className = liClasses;
|
|
@@ -838,7 +843,7 @@ var TreeElement = (function () {
|
|
|
838
843
|
let div = document.createElement("div");
|
|
839
844
|
div.className = `${this._classNames.element} ${this._classNames.common}`;
|
|
840
845
|
div.setAttribute("role", "none");
|
|
841
|
-
li.
|
|
846
|
+
li.append(div);
|
|
842
847
|
return li;
|
|
843
848
|
}
|
|
844
849
|
_createNodeLi(node, level, isSelected) {
|
|
@@ -854,11 +859,13 @@ var TreeElement = (function () {
|
|
|
854
859
|
return li;
|
|
855
860
|
}
|
|
856
861
|
|
|
857
|
-
/*
|
|
862
|
+
/*
|
|
863
|
+
Template for a <li> without children: li > div > title span
|
|
864
|
+
*/
|
|
858
865
|
_createNodeTemplate() {
|
|
859
866
|
let li = this._createLiTemplate(this._classNames.common);
|
|
860
867
|
let div = li.firstChild;
|
|
861
|
-
div.
|
|
868
|
+
div.append(this._createTitleSpanTemplate(false));
|
|
862
869
|
return li;
|
|
863
870
|
}
|
|
864
871
|
_createTitleSpanTemplate(isFolder) {
|
|
@@ -871,20 +878,25 @@ var TreeElement = (function () {
|
|
|
871
878
|
titleSpan.className = classes;
|
|
872
879
|
titleSpan.setAttribute("role", "treeitem");
|
|
873
880
|
titleSpan.setAttribute("aria-selected", "false");
|
|
881
|
+
|
|
882
|
+
// Every node is focusable, but only the tab stop is in the tab order
|
|
883
|
+
if (this._tabIndex !== undefined) {
|
|
884
|
+
titleSpan.setAttribute("tabindex", "-1");
|
|
885
|
+
}
|
|
874
886
|
return titleSpan;
|
|
875
887
|
}
|
|
876
888
|
_createUlTemplate(isRootNode) {
|
|
877
889
|
let classString;
|
|
878
890
|
let role;
|
|
879
|
-
if (
|
|
880
|
-
classString = "";
|
|
881
|
-
role = "group";
|
|
882
|
-
} else {
|
|
891
|
+
if (isRootNode) {
|
|
883
892
|
classString = this._classNames.tree;
|
|
884
893
|
role = "tree";
|
|
885
894
|
if (this._rtl) {
|
|
886
895
|
classString += ` ${this._classNames.rtl}`;
|
|
887
896
|
}
|
|
897
|
+
} else {
|
|
898
|
+
classString = "";
|
|
899
|
+
role = "group";
|
|
888
900
|
}
|
|
889
901
|
if (this._dragAndDrop) {
|
|
890
902
|
classString += ` ${this._classNames.dnd}`;
|
|
@@ -892,23 +904,33 @@ var TreeElement = (function () {
|
|
|
892
904
|
let ul = document.createElement("ul");
|
|
893
905
|
ul.className = `${this._classNames.common} ${classString}`;
|
|
894
906
|
ul.setAttribute("role", role);
|
|
907
|
+
if (isRootNode) {
|
|
908
|
+
if (this._ariaLabel !== undefined) {
|
|
909
|
+
ul.setAttribute("aria-label", this._ariaLabel);
|
|
910
|
+
}
|
|
911
|
+
if (this._ariaLabelledBy !== undefined) {
|
|
912
|
+
ul.setAttribute("aria-labelledby", this._ariaLabelledBy);
|
|
913
|
+
}
|
|
914
|
+
}
|
|
895
915
|
return ul;
|
|
896
916
|
}
|
|
897
917
|
|
|
898
|
-
/*
|
|
918
|
+
/*
|
|
919
|
+
Set the parts of a cloned title span that differ per node
|
|
920
|
+
*/
|
|
899
921
|
_fillTitleSpan(titleSpan, nodeName, isSelected, level) {
|
|
900
|
-
titleSpan.setAttribute("aria-
|
|
901
|
-
titleSpan.setAttribute("aria-level", `${level}`);
|
|
922
|
+
titleSpan.setAttribute("aria-level", String(level));
|
|
902
923
|
if (isSelected) {
|
|
903
924
|
titleSpan.setAttribute("aria-selected", "true");
|
|
904
925
|
let tabIndex = this._tabIndex;
|
|
905
926
|
if (tabIndex !== undefined) {
|
|
906
|
-
titleSpan.setAttribute("tabindex",
|
|
927
|
+
titleSpan.setAttribute("tabindex", String(tabIndex));
|
|
907
928
|
}
|
|
908
929
|
}
|
|
909
930
|
if (this._autoEscape) {
|
|
910
931
|
titleSpan.textContent = nodeName;
|
|
911
932
|
} else {
|
|
933
|
+
// eslint-disable-next-line no-unsanitized/property -- the user opted out of escaping with autoEscape: false
|
|
912
934
|
titleSpan.innerHTML = nodeName;
|
|
913
935
|
}
|
|
914
936
|
}
|
|
@@ -925,7 +947,9 @@ var TreeElement = (function () {
|
|
|
925
947
|
return classes.join(" ");
|
|
926
948
|
}
|
|
927
949
|
|
|
928
|
-
/*
|
|
950
|
+
/*
|
|
951
|
+
The children of a closed folder are rendered when it is opened
|
|
952
|
+
*/
|
|
929
953
|
_mustRenderChildren(node) {
|
|
930
954
|
return node.hasChildren() && node.is_open === true;
|
|
931
955
|
}
|
|
@@ -934,18 +958,22 @@ var TreeElement = (function () {
|
|
|
934
958
|
class KeyHandler {
|
|
935
959
|
constructor({
|
|
936
960
|
_closeNode: closeNode,
|
|
961
|
+
_getFocusedNode: getFocusedNode,
|
|
937
962
|
_getSelectedNode: getSelectedNode,
|
|
938
|
-
|
|
963
|
+
_getTree: getTree,
|
|
939
964
|
_keyboardSupport: keyboardSupport,
|
|
940
965
|
_openNode: openNode,
|
|
941
|
-
_selectNode: selectNode
|
|
966
|
+
_selectNode: selectNode,
|
|
967
|
+
_triggerEvent: triggerEvent
|
|
942
968
|
}) {
|
|
943
969
|
this._closeNode = closeNode;
|
|
970
|
+
this._getFocusedNode = getFocusedNode;
|
|
944
971
|
this._getSelectedNode = getSelectedNode;
|
|
945
|
-
this.
|
|
972
|
+
this._getTree = getTree;
|
|
946
973
|
this._keyboardSupport = keyboardSupport;
|
|
947
974
|
this._openNode = openNode;
|
|
948
975
|
this._originalSelectNode = selectNode;
|
|
976
|
+
this._triggerEvent = triggerEvent;
|
|
949
977
|
if (keyboardSupport) {
|
|
950
978
|
document.addEventListener("keydown", this._handleKeyDown);
|
|
951
979
|
}
|
|
@@ -961,35 +989,89 @@ var TreeElement = (function () {
|
|
|
961
989
|
_moveUp() {
|
|
962
990
|
return this._selectNode(this._getSelectedNode()?.getPreviousVisibleNode());
|
|
963
991
|
}
|
|
964
|
-
|
|
965
|
-
|
|
992
|
+
|
|
993
|
+
// Activate the node, for example to open its edit page.
|
|
994
|
+
_activate(node, originalEvent) {
|
|
995
|
+
this._triggerEvent("tree.activate", {
|
|
996
|
+
node,
|
|
997
|
+
originalEvent
|
|
998
|
+
});
|
|
999
|
+
return true;
|
|
1000
|
+
}
|
|
1001
|
+
_handleArrowKey(key) {
|
|
1002
|
+
switch (key) {
|
|
1003
|
+
case "ArrowDown":
|
|
1004
|
+
{
|
|
1005
|
+
return this._moveDown();
|
|
1006
|
+
}
|
|
1007
|
+
case "ArrowLeft":
|
|
1008
|
+
{
|
|
1009
|
+
return this._moveLeft();
|
|
1010
|
+
}
|
|
1011
|
+
case "ArrowRight":
|
|
1012
|
+
{
|
|
1013
|
+
return this._moveRight();
|
|
1014
|
+
}
|
|
1015
|
+
case "ArrowUp":
|
|
1016
|
+
{
|
|
1017
|
+
return this._moveUp();
|
|
1018
|
+
}
|
|
1019
|
+
default:
|
|
1020
|
+
{
|
|
1021
|
+
return false;
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
966
1024
|
}
|
|
967
1025
|
_handleKeyDown = e => {
|
|
968
|
-
|
|
1026
|
+
let focusedNode = this._getFocusedNode();
|
|
1027
|
+
if (!focusedNode) {
|
|
969
1028
|
return;
|
|
970
1029
|
}
|
|
971
|
-
let isKeyHandled
|
|
1030
|
+
let isKeyHandled;
|
|
972
1031
|
let selectedNode = this._getSelectedNode();
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
isKeyHandled = this.
|
|
977
|
-
break;
|
|
978
|
-
case "ArrowLeft":
|
|
979
|
-
isKeyHandled = this._moveLeft();
|
|
1032
|
+
switch (e.key) {
|
|
1033
|
+
case "End":
|
|
1034
|
+
{
|
|
1035
|
+
isKeyHandled = this._selectNode(this._getTree()?.getLastChild());
|
|
980
1036
|
break;
|
|
981
|
-
|
|
982
|
-
|
|
1037
|
+
}
|
|
1038
|
+
case "Enter":
|
|
1039
|
+
{
|
|
1040
|
+
// Without a selected node, activate the focused node
|
|
1041
|
+
isKeyHandled = this._activate(selectedNode ?? focusedNode, e);
|
|
983
1042
|
break;
|
|
984
|
-
|
|
985
|
-
|
|
1043
|
+
}
|
|
1044
|
+
case "Home":
|
|
1045
|
+
{
|
|
1046
|
+
isKeyHandled = this._selectNode(this._getTree()?.children[0]);
|
|
986
1047
|
break;
|
|
987
|
-
|
|
1048
|
+
}
|
|
1049
|
+
default:
|
|
1050
|
+
{
|
|
1051
|
+
isKeyHandled = selectedNode ? this._handleArrowKey(e.key) : this._handleKeyWithoutSelection(e.key, focusedNode);
|
|
1052
|
+
}
|
|
988
1053
|
}
|
|
989
1054
|
if (isKeyHandled) {
|
|
990
1055
|
e.preventDefault();
|
|
991
1056
|
}
|
|
992
1057
|
};
|
|
1058
|
+
|
|
1059
|
+
// No node is selected. These keys select the focused node, which is
|
|
1060
|
+
// usually the first node, see TreeElement.updateTabStop.
|
|
1061
|
+
_handleKeyWithoutSelection(key, focusedNode) {
|
|
1062
|
+
switch (key) {
|
|
1063
|
+
case " ":
|
|
1064
|
+
case "ArrowDown":
|
|
1065
|
+
case "ArrowRight":
|
|
1066
|
+
{
|
|
1067
|
+
return this._selectNode(focusedNode);
|
|
1068
|
+
}
|
|
1069
|
+
default:
|
|
1070
|
+
{
|
|
1071
|
+
return false;
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
993
1075
|
_moveLeft() {
|
|
994
1076
|
let selectedNode = this._getSelectedNode();
|
|
995
1077
|
|
|
@@ -999,28 +1081,25 @@ var TreeElement = (function () {
|
|
|
999
1081
|
}
|
|
1000
1082
|
if (selectedNode.isFolder() && selectedNode.is_open) {
|
|
1001
1083
|
// Left on an open node closes the node
|
|
1002
|
-
this._closeNode(selectedNode);
|
|
1084
|
+
void this._closeNode(selectedNode);
|
|
1003
1085
|
return true;
|
|
1004
|
-
} else {
|
|
1005
|
-
// Left on a closed or end node moves focus to the node's parent
|
|
1006
|
-
return this._selectNode(selectedNode.getParent());
|
|
1007
1086
|
}
|
|
1087
|
+
// Left on a closed or end node moves focus to the node's parent
|
|
1088
|
+
return this._selectNode(selectedNode.getParent());
|
|
1008
1089
|
}
|
|
1009
1090
|
_moveRight() {
|
|
1010
1091
|
let selectedNode = this._getSelectedNode();
|
|
1011
|
-
if (
|
|
1012
|
-
return false;
|
|
1013
|
-
} else {
|
|
1092
|
+
if (selectedNode?.isFolder()) {
|
|
1014
1093
|
// folder node
|
|
1015
1094
|
if (selectedNode.is_open) {
|
|
1016
1095
|
// Right moves to the first child of an open node
|
|
1017
1096
|
return this._selectNode(selectedNode.getNextVisibleNode());
|
|
1018
|
-
} else {
|
|
1019
|
-
// Right expands a closed node
|
|
1020
|
-
void this._openNode(selectedNode);
|
|
1021
|
-
return true;
|
|
1022
1097
|
}
|
|
1098
|
+
// Right expands a closed node
|
|
1099
|
+
void this._openNode(selectedNode);
|
|
1100
|
+
return true;
|
|
1023
1101
|
}
|
|
1102
|
+
return false;
|
|
1024
1103
|
}
|
|
1025
1104
|
|
|
1026
1105
|
/* Select the node.
|
|
@@ -1028,12 +1107,11 @@ var TreeElement = (function () {
|
|
|
1028
1107
|
* Result: a different node was selected.
|
|
1029
1108
|
*/
|
|
1030
1109
|
_selectNode(node) {
|
|
1031
|
-
if (
|
|
1032
|
-
return false;
|
|
1033
|
-
} else {
|
|
1110
|
+
if (node) {
|
|
1034
1111
|
this._originalSelectNode(node);
|
|
1035
1112
|
return true;
|
|
1036
1113
|
}
|
|
1114
|
+
return false;
|
|
1037
1115
|
}
|
|
1038
1116
|
}
|
|
1039
1117
|
|
|
@@ -1137,10 +1215,12 @@ var TreeElement = (function () {
|
|
|
1137
1215
|
}
|
|
1138
1216
|
switch (clickTarget.type) {
|
|
1139
1217
|
case "button":
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1218
|
+
{
|
|
1219
|
+
void this._onClickButton(clickTarget.node);
|
|
1220
|
+
e.preventDefault();
|
|
1221
|
+
e.stopPropagation();
|
|
1222
|
+
break;
|
|
1223
|
+
}
|
|
1144
1224
|
case "label":
|
|
1145
1225
|
{
|
|
1146
1226
|
if (this._triggerEvent("tree.click", {
|
|
@@ -1223,10 +1303,11 @@ var TreeElement = (function () {
|
|
|
1223
1303
|
this._removeMouseMoveEventListeners();
|
|
1224
1304
|
this._isMouseDelayMet = false;
|
|
1225
1305
|
this._mouseDownInfo = null;
|
|
1226
|
-
if (this._isMouseStarted) {
|
|
1227
|
-
|
|
1228
|
-
this._onMouseStop(positionInfo);
|
|
1306
|
+
if (!this._isMouseStarted) {
|
|
1307
|
+
return;
|
|
1229
1308
|
}
|
|
1309
|
+
this._isMouseStarted = false;
|
|
1310
|
+
this._onMouseStop(positionInfo);
|
|
1230
1311
|
}
|
|
1231
1312
|
_handleStartMouse() {
|
|
1232
1313
|
document.addEventListener("mousemove", this._mouseMove, {
|
|
@@ -1313,7 +1394,7 @@ var TreeElement = (function () {
|
|
|
1313
1394
|
};
|
|
1314
1395
|
}
|
|
1315
1396
|
|
|
1316
|
-
let isNodeRecordWithChildren = data => typeof data === "object" && "children" in data && data.children
|
|
1397
|
+
let isNodeRecordWithChildren = data => typeof data === "object" && "children" in data && Array.isArray(data.children);
|
|
1317
1398
|
|
|
1318
1399
|
/*
|
|
1319
1400
|
A node reads and writes the private members of other nodes (node.setParent),
|
|
@@ -1341,38 +1422,62 @@ var TreeElement = (function () {
|
|
|
1341
1422
|
* :::
|
|
1342
1423
|
*/
|
|
1343
1424
|
class Node {
|
|
1344
|
-
/**
|
|
1425
|
+
/**
|
|
1426
|
+
@hidden
|
|
1427
|
+
*/
|
|
1345
1428
|
|
|
1346
|
-
/**
|
|
1429
|
+
/**
|
|
1430
|
+
The child nodes.
|
|
1431
|
+
*/
|
|
1347
1432
|
children;
|
|
1348
1433
|
/** The `li` element, once the node is rendered. Nodes inside a closed
|
|
1349
1434
|
* folder are rendered when the folder is opened. */
|
|
1350
1435
|
element;
|
|
1351
|
-
/**
|
|
1436
|
+
/**
|
|
1437
|
+
The id from the node data.
|
|
1438
|
+
*/
|
|
1352
1439
|
id;
|
|
1353
|
-
/**
|
|
1440
|
+
/**
|
|
1441
|
+
@hidden
|
|
1442
|
+
*/
|
|
1354
1443
|
idMapping;
|
|
1355
|
-
/**
|
|
1444
|
+
/**
|
|
1445
|
+
Whether the node's children are being fetched.
|
|
1446
|
+
*/
|
|
1356
1447
|
is_loading;
|
|
1357
|
-
/**
|
|
1448
|
+
/**
|
|
1449
|
+
Whether the folder is open.
|
|
1450
|
+
*/
|
|
1358
1451
|
is_open;
|
|
1359
|
-
/**
|
|
1452
|
+
/**
|
|
1453
|
+
Whether the node data had an empty `children` array.
|
|
1454
|
+
*/
|
|
1360
1455
|
isEmptyFolder;
|
|
1361
|
-
/**
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
/**
|
|
1456
|
+
/**
|
|
1457
|
+
Whether the children still have to be fetched.
|
|
1458
|
+
*/
|
|
1459
|
+
load_on_demand = false;
|
|
1460
|
+
/**
|
|
1461
|
+
The label. Also settable from the `label` key in node data.
|
|
1462
|
+
*/
|
|
1463
|
+
name = "";
|
|
1464
|
+
/**
|
|
1465
|
+
@hidden
|
|
1466
|
+
*/
|
|
1366
1467
|
nodeClass;
|
|
1367
|
-
/**
|
|
1468
|
+
/**
|
|
1469
|
+
The parent; `null` for the root node.
|
|
1470
|
+
*/
|
|
1368
1471
|
parent;
|
|
1369
|
-
/**
|
|
1472
|
+
/**
|
|
1473
|
+
The root node.
|
|
1474
|
+
*/
|
|
1370
1475
|
tree;
|
|
1371
1476
|
|
|
1372
|
-
/**
|
|
1477
|
+
/**
|
|
1478
|
+
@hidden
|
|
1479
|
+
*/
|
|
1373
1480
|
constructor(nodeData = null, isRoot = false, nodeClass = Node) {
|
|
1374
|
-
this.name = "";
|
|
1375
|
-
this.load_on_demand = false;
|
|
1376
1481
|
this.isEmptyFolder = nodeData != null && isNodeRecordWithChildren(nodeData) && nodeData.children.length === 0;
|
|
1377
1482
|
this.setData(nodeData);
|
|
1378
1483
|
this.children = [];
|
|
@@ -1395,15 +1500,14 @@ var TreeElement = (function () {
|
|
|
1395
1500
|
* @group Changing the tree
|
|
1396
1501
|
*/
|
|
1397
1502
|
addAfter(nodeInfo) {
|
|
1398
|
-
if (
|
|
1399
|
-
return null;
|
|
1400
|
-
} else {
|
|
1503
|
+
if (this.parent) {
|
|
1401
1504
|
let node = this._createNode(nodeInfo);
|
|
1402
1505
|
let childIndex = this.parent.getChildIndex(this);
|
|
1403
1506
|
this.parent.addChildAtPosition(node, childIndex + 1);
|
|
1404
1507
|
node._loadChildrenFromData(nodeInfo);
|
|
1405
1508
|
return node;
|
|
1406
1509
|
}
|
|
1510
|
+
return null;
|
|
1407
1511
|
}
|
|
1408
1512
|
|
|
1409
1513
|
/**
|
|
@@ -1413,15 +1517,14 @@ var TreeElement = (function () {
|
|
|
1413
1517
|
* @group Changing the tree
|
|
1414
1518
|
*/
|
|
1415
1519
|
addBefore(nodeInfo) {
|
|
1416
|
-
if (
|
|
1417
|
-
return null;
|
|
1418
|
-
} else {
|
|
1520
|
+
if (this.parent) {
|
|
1419
1521
|
let node = this._createNode(nodeInfo);
|
|
1420
1522
|
let childIndex = this.parent.getChildIndex(this);
|
|
1421
1523
|
this.parent.addChildAtPosition(node, childIndex);
|
|
1422
1524
|
node._loadChildrenFromData(nodeInfo);
|
|
1423
1525
|
return node;
|
|
1424
1526
|
}
|
|
1527
|
+
return null;
|
|
1425
1528
|
}
|
|
1426
1529
|
|
|
1427
1530
|
/**
|
|
@@ -1445,7 +1548,9 @@ var TreeElement = (function () {
|
|
|
1445
1548
|
node._setParent(this);
|
|
1446
1549
|
}
|
|
1447
1550
|
|
|
1448
|
-
/**
|
|
1551
|
+
/**
|
|
1552
|
+
@hidden
|
|
1553
|
+
*/
|
|
1449
1554
|
addNodeToIndex(node) {
|
|
1450
1555
|
if (node.id != null) {
|
|
1451
1556
|
this.idMapping?.set(node.id, node);
|
|
@@ -1459,9 +1564,7 @@ var TreeElement = (function () {
|
|
|
1459
1564
|
* @group Changing the tree
|
|
1460
1565
|
*/
|
|
1461
1566
|
addParent(nodeInfo) {
|
|
1462
|
-
if (
|
|
1463
|
-
return null;
|
|
1464
|
-
} else {
|
|
1567
|
+
if (this.parent) {
|
|
1465
1568
|
let newParent = this._createNode(nodeInfo);
|
|
1466
1569
|
if (this.tree) {
|
|
1467
1570
|
newParent._setParent(this.tree);
|
|
@@ -1474,6 +1577,7 @@ var TreeElement = (function () {
|
|
|
1474
1577
|
originalParent.addChild(newParent);
|
|
1475
1578
|
return newParent;
|
|
1476
1579
|
}
|
|
1580
|
+
return null;
|
|
1477
1581
|
}
|
|
1478
1582
|
|
|
1479
1583
|
/**
|
|
@@ -1540,10 +1644,11 @@ var TreeElement = (function () {
|
|
|
1540
1644
|
return nodes.map(node => {
|
|
1541
1645
|
let tmpNode = {};
|
|
1542
1646
|
for (let k in node) {
|
|
1543
|
-
if (["
|
|
1544
|
-
|
|
1545
|
-
tmpNode[k] = v;
|
|
1647
|
+
if (["children", "element", "idMapping", "isEmptyFolder", "load_on_demand", "nodeClass", "parent", "tree"].includes(k) || !Object.prototype.hasOwnProperty.call(node, k)) {
|
|
1648
|
+
continue;
|
|
1546
1649
|
}
|
|
1650
|
+
let v = node[k];
|
|
1651
|
+
tmpNode[k] = v;
|
|
1547
1652
|
}
|
|
1548
1653
|
if (node.hasChildren()) {
|
|
1549
1654
|
tmpNode.children = getDataFromNodes(node.children);
|
|
@@ -1551,11 +1656,7 @@ var TreeElement = (function () {
|
|
|
1551
1656
|
return tmpNode;
|
|
1552
1657
|
});
|
|
1553
1658
|
};
|
|
1554
|
-
|
|
1555
|
-
return getDataFromNodes([this]);
|
|
1556
|
-
} else {
|
|
1557
|
-
return getDataFromNodes(this.children);
|
|
1558
|
-
}
|
|
1659
|
+
return getDataFromNodes(includeParent ? [this] : this.children);
|
|
1559
1660
|
}
|
|
1560
1661
|
|
|
1561
1662
|
/**
|
|
@@ -1565,16 +1666,11 @@ var TreeElement = (function () {
|
|
|
1565
1666
|
* @group Moving around the tree
|
|
1566
1667
|
*/
|
|
1567
1668
|
getLastChild() {
|
|
1568
|
-
if (
|
|
1569
|
-
return null;
|
|
1570
|
-
} else {
|
|
1669
|
+
if (this.hasChildren()) {
|
|
1571
1670
|
let lastChild = this.children[this.children.length - 1];
|
|
1572
|
-
|
|
1573
|
-
return lastChild;
|
|
1574
|
-
} else {
|
|
1575
|
-
return lastChild.getLastChild();
|
|
1576
|
-
}
|
|
1671
|
+
return lastChild.hasChildren() && lastChild.is_open ? lastChild.getLastChild() : lastChild;
|
|
1577
1672
|
}
|
|
1673
|
+
return null;
|
|
1578
1674
|
}
|
|
1579
1675
|
|
|
1580
1676
|
/**
|
|
@@ -1584,7 +1680,7 @@ var TreeElement = (function () {
|
|
|
1584
1680
|
*/
|
|
1585
1681
|
getLevel() {
|
|
1586
1682
|
let level = 0;
|
|
1587
|
-
let node = this; // eslint-disable-line @typescript-eslint/no-this-alias
|
|
1683
|
+
let node = this; // eslint-disable-line @typescript-eslint/no-this-alias, unicorn/no-this-assignment
|
|
1588
1684
|
|
|
1589
1685
|
while (node.parent) {
|
|
1590
1686
|
level += 1;
|
|
@@ -1602,16 +1698,12 @@ var TreeElement = (function () {
|
|
|
1602
1698
|
getNextNode(includeChildren = true) {
|
|
1603
1699
|
if (includeChildren && this.hasChildren()) {
|
|
1604
1700
|
return this.children[0] ?? null;
|
|
1605
|
-
}
|
|
1606
|
-
|
|
1607
|
-
} else {
|
|
1701
|
+
}
|
|
1702
|
+
if (this.parent) {
|
|
1608
1703
|
let nextSibling = this.getNextSibling();
|
|
1609
|
-
|
|
1610
|
-
return nextSibling;
|
|
1611
|
-
} else {
|
|
1612
|
-
return this.parent.getNextNode(false);
|
|
1613
|
-
}
|
|
1704
|
+
return nextSibling ?? this.parent.getNextNode(false);
|
|
1614
1705
|
}
|
|
1706
|
+
return null;
|
|
1615
1707
|
}
|
|
1616
1708
|
|
|
1617
1709
|
/**
|
|
@@ -1620,16 +1712,11 @@ var TreeElement = (function () {
|
|
|
1620
1712
|
* @group Moving around the tree
|
|
1621
1713
|
*/
|
|
1622
1714
|
getNextSibling() {
|
|
1623
|
-
if (
|
|
1624
|
-
return null;
|
|
1625
|
-
} else {
|
|
1715
|
+
if (this.parent) {
|
|
1626
1716
|
let nextIndex = this.parent.getChildIndex(this) + 1;
|
|
1627
|
-
|
|
1628
|
-
return this.parent.children[nextIndex] ?? null;
|
|
1629
|
-
} else {
|
|
1630
|
-
return null;
|
|
1631
|
-
}
|
|
1717
|
+
return nextIndex < this.parent.children.length ? this.parent.children[nextIndex] ?? null : null;
|
|
1632
1718
|
}
|
|
1719
|
+
return null;
|
|
1633
1720
|
}
|
|
1634
1721
|
|
|
1635
1722
|
/**
|
|
@@ -1642,20 +1729,17 @@ var TreeElement = (function () {
|
|
|
1642
1729
|
if (this.hasChildren() && this.is_open) {
|
|
1643
1730
|
// First child
|
|
1644
1731
|
return this.children[0] ?? null;
|
|
1645
|
-
}
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
// Next sibling
|
|
1652
|
-
return nextSibling;
|
|
1653
|
-
} else {
|
|
1654
|
-
// Next node of parent
|
|
1655
|
-
return this.parent.getNextNode(false);
|
|
1656
|
-
}
|
|
1732
|
+
}
|
|
1733
|
+
if (this.parent) {
|
|
1734
|
+
let nextSibling = this.getNextSibling();
|
|
1735
|
+
if (nextSibling) {
|
|
1736
|
+
// Next sibling
|
|
1737
|
+
return nextSibling;
|
|
1657
1738
|
}
|
|
1739
|
+
// Next node of parent
|
|
1740
|
+
return this.parent.getNextNode(false);
|
|
1658
1741
|
}
|
|
1742
|
+
return null;
|
|
1659
1743
|
}
|
|
1660
1744
|
|
|
1661
1745
|
/**
|
|
@@ -1668,12 +1752,12 @@ var TreeElement = (function () {
|
|
|
1668
1752
|
this.iterate(node => {
|
|
1669
1753
|
if (result) {
|
|
1670
1754
|
return false;
|
|
1671
|
-
}
|
|
1755
|
+
}
|
|
1756
|
+
if (callback(node)) {
|
|
1672
1757
|
result = node;
|
|
1673
1758
|
return false;
|
|
1674
|
-
} else {
|
|
1675
|
-
return true;
|
|
1676
1759
|
}
|
|
1760
|
+
return true;
|
|
1677
1761
|
});
|
|
1678
1762
|
return result;
|
|
1679
1763
|
}
|
|
@@ -1729,12 +1813,12 @@ var TreeElement = (function () {
|
|
|
1729
1813
|
// Return parent except if it is the root node
|
|
1730
1814
|
if (!this.parent) {
|
|
1731
1815
|
return null;
|
|
1732
|
-
}
|
|
1733
|
-
|
|
1734
|
-
return null;
|
|
1735
|
-
} else {
|
|
1816
|
+
}
|
|
1817
|
+
if (this.parent.parent) {
|
|
1736
1818
|
return this.parent;
|
|
1737
1819
|
}
|
|
1820
|
+
// Root node -> null
|
|
1821
|
+
return null;
|
|
1738
1822
|
}
|
|
1739
1823
|
|
|
1740
1824
|
/**
|
|
@@ -1744,18 +1828,14 @@ var TreeElement = (function () {
|
|
|
1744
1828
|
* @group Moving around the tree
|
|
1745
1829
|
*/
|
|
1746
1830
|
getPreviousNode() {
|
|
1747
|
-
if (
|
|
1748
|
-
return null;
|
|
1749
|
-
} else {
|
|
1831
|
+
if (this.parent) {
|
|
1750
1832
|
let previousSibling = this.getPreviousSibling();
|
|
1751
1833
|
if (!previousSibling) {
|
|
1752
1834
|
return this.getParent();
|
|
1753
|
-
} else if (previousSibling.hasChildren()) {
|
|
1754
|
-
return previousSibling.getLastChild();
|
|
1755
|
-
} else {
|
|
1756
|
-
return previousSibling;
|
|
1757
1835
|
}
|
|
1836
|
+
return previousSibling.hasChildren() ? previousSibling.getLastChild() : previousSibling;
|
|
1758
1837
|
}
|
|
1838
|
+
return null;
|
|
1759
1839
|
}
|
|
1760
1840
|
|
|
1761
1841
|
/**
|
|
@@ -1764,16 +1844,11 @@ var TreeElement = (function () {
|
|
|
1764
1844
|
* @group Moving around the tree
|
|
1765
1845
|
*/
|
|
1766
1846
|
getPreviousSibling() {
|
|
1767
|
-
if (
|
|
1768
|
-
return null;
|
|
1769
|
-
} else {
|
|
1847
|
+
if (this.parent) {
|
|
1770
1848
|
let previousIndex = this.parent.getChildIndex(this) - 1;
|
|
1771
|
-
|
|
1772
|
-
return this.parent.children[previousIndex] ?? null;
|
|
1773
|
-
} else {
|
|
1774
|
-
return null;
|
|
1775
|
-
}
|
|
1849
|
+
return previousIndex >= 0 ? this.parent.children[previousIndex] ?? null : null;
|
|
1776
1850
|
}
|
|
1851
|
+
return null;
|
|
1777
1852
|
}
|
|
1778
1853
|
|
|
1779
1854
|
/**
|
|
@@ -1783,20 +1858,19 @@ var TreeElement = (function () {
|
|
|
1783
1858
|
* @group Moving around the tree
|
|
1784
1859
|
*/
|
|
1785
1860
|
getPreviousVisibleNode() {
|
|
1786
|
-
if (
|
|
1787
|
-
return null;
|
|
1788
|
-
} else {
|
|
1861
|
+
if (this.parent) {
|
|
1789
1862
|
let previousSibling = this.getPreviousSibling();
|
|
1790
1863
|
if (!previousSibling) {
|
|
1791
1864
|
return this.getParent();
|
|
1792
|
-
}
|
|
1865
|
+
}
|
|
1866
|
+
if (!previousSibling.hasChildren() || !previousSibling.is_open) {
|
|
1793
1867
|
// Previous sibling
|
|
1794
1868
|
return previousSibling;
|
|
1795
|
-
} else {
|
|
1796
|
-
// Last child of previous sibling
|
|
1797
|
-
return previousSibling.getLastChild();
|
|
1798
1869
|
}
|
|
1870
|
+
// Last child of previous sibling
|
|
1871
|
+
return previousSibling.getLastChild();
|
|
1799
1872
|
}
|
|
1873
|
+
return null;
|
|
1800
1874
|
}
|
|
1801
1875
|
|
|
1802
1876
|
/**
|
|
@@ -1910,32 +1984,31 @@ var TreeElement = (function () {
|
|
|
1910
1984
|
// - Node is parent of target node
|
|
1911
1985
|
// - Or, parent is empty
|
|
1912
1986
|
return false;
|
|
1913
|
-
}
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
}
|
|
1922
|
-
return false;
|
|
1923
|
-
}
|
|
1924
|
-
case "before":
|
|
1925
|
-
{
|
|
1926
|
-
if (targetNode.parent) {
|
|
1927
|
-
targetNode.parent.addChildAtPosition(movedNode, targetNode.parent.getChildIndex(targetNode));
|
|
1928
|
-
return true;
|
|
1929
|
-
}
|
|
1930
|
-
return false;
|
|
1987
|
+
}
|
|
1988
|
+
movedNode.parent._doRemoveChild(movedNode);
|
|
1989
|
+
switch (position) {
|
|
1990
|
+
case "after":
|
|
1991
|
+
{
|
|
1992
|
+
if (targetNode.parent) {
|
|
1993
|
+
targetNode.parent.addChildAtPosition(movedNode, targetNode.parent.getChildIndex(targetNode) + 1);
|
|
1994
|
+
return true;
|
|
1931
1995
|
}
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1996
|
+
return false;
|
|
1997
|
+
}
|
|
1998
|
+
case "before":
|
|
1999
|
+
{
|
|
2000
|
+
if (targetNode.parent) {
|
|
2001
|
+
targetNode.parent.addChildAtPosition(movedNode, targetNode.parent.getChildIndex(targetNode));
|
|
1936
2002
|
return true;
|
|
1937
2003
|
}
|
|
1938
|
-
|
|
2004
|
+
return false;
|
|
2005
|
+
}
|
|
2006
|
+
case "inside":
|
|
2007
|
+
{
|
|
2008
|
+
// move inside as first child
|
|
2009
|
+
targetNode.addChildAtPosition(movedNode, 0);
|
|
2010
|
+
return true;
|
|
2011
|
+
}
|
|
1939
2012
|
}
|
|
1940
2013
|
}
|
|
1941
2014
|
|
|
@@ -1958,10 +2031,11 @@ var TreeElement = (function () {
|
|
|
1958
2031
|
* @group Changing the tree
|
|
1959
2032
|
*/
|
|
1960
2033
|
remove() {
|
|
1961
|
-
if (this.parent) {
|
|
1962
|
-
|
|
1963
|
-
this.parent = null;
|
|
2034
|
+
if (!this.parent) {
|
|
2035
|
+
return;
|
|
1964
2036
|
}
|
|
2037
|
+
this.parent.removeChild(this);
|
|
2038
|
+
this.parent = null;
|
|
1965
2039
|
}
|
|
1966
2040
|
|
|
1967
2041
|
/**
|
|
@@ -1988,7 +2062,9 @@ var TreeElement = (function () {
|
|
|
1988
2062
|
this.children = [];
|
|
1989
2063
|
}
|
|
1990
2064
|
|
|
1991
|
-
/**
|
|
2065
|
+
/**
|
|
2066
|
+
@hidden
|
|
2067
|
+
*/
|
|
1992
2068
|
removeNodeFromIndex(node) {
|
|
1993
2069
|
if (node.id != null) {
|
|
1994
2070
|
this.idMapping?.delete(node.id);
|
|
@@ -2005,21 +2081,23 @@ var TreeElement = (function () {
|
|
|
2005
2081
|
setData(o) {
|
|
2006
2082
|
if (!o) {
|
|
2007
2083
|
return;
|
|
2008
|
-
}
|
|
2084
|
+
}
|
|
2085
|
+
if (typeof o === "string") {
|
|
2009
2086
|
this.name = o;
|
|
2010
2087
|
} else if (typeof o === "object") {
|
|
2011
2088
|
for (let key in o) {
|
|
2012
|
-
if (Object.prototype.hasOwnProperty.call(o, key)) {
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
// You can't update the children or the parent using this function
|
|
2021
|
-
this[key] = value;
|
|
2089
|
+
if (!Object.prototype.hasOwnProperty.call(o, key)) {
|
|
2090
|
+
continue;
|
|
2091
|
+
}
|
|
2092
|
+
let value = o[key];
|
|
2093
|
+
if (key === "label" || key === "name") {
|
|
2094
|
+
// You can use the 'label' key instead of 'name'; this is a legacy feature
|
|
2095
|
+
if (typeof value === "string") {
|
|
2096
|
+
this.name = value;
|
|
2022
2097
|
}
|
|
2098
|
+
} else if (key !== "children" && key !== "parent") {
|
|
2099
|
+
// You can't update the children or the parent using this function
|
|
2100
|
+
this[key] = value;
|
|
2023
2101
|
}
|
|
2024
2102
|
}
|
|
2025
2103
|
}
|
|
@@ -2078,11 +2156,15 @@ var TreeElement = (function () {
|
|
|
2078
2156
|
this._ghost = this._createGhostElement();
|
|
2079
2157
|
switch (position) {
|
|
2080
2158
|
case "after":
|
|
2081
|
-
|
|
2082
|
-
|
|
2159
|
+
{
|
|
2160
|
+
this._moveAfter();
|
|
2161
|
+
break;
|
|
2162
|
+
}
|
|
2083
2163
|
case "before":
|
|
2084
|
-
|
|
2085
|
-
|
|
2164
|
+
{
|
|
2165
|
+
this._moveBefore();
|
|
2166
|
+
break;
|
|
2167
|
+
}
|
|
2086
2168
|
case "inside":
|
|
2087
2169
|
{
|
|
2088
2170
|
if (node.isFolder() && node.is_open) {
|
|
@@ -2149,11 +2231,7 @@ var TreeElement = (function () {
|
|
|
2149
2231
|
this._element = node.element ?? this._treeElement;
|
|
2150
2232
|
}
|
|
2151
2233
|
_addDropHint(position) {
|
|
2152
|
-
|
|
2153
|
-
return new BorderDropHint(this._element, this._getScrollLeft(), this._classNames);
|
|
2154
|
-
} else {
|
|
2155
|
-
return new GhostDropHint(this._node, this._element, position, this._classNames);
|
|
2156
|
-
}
|
|
2234
|
+
return this._mustShowBorderDropHint(position) ? new BorderDropHint(this._element, this._getScrollLeft(), this._classNames) : new GhostDropHint(this._node, this._element, position, this._classNames);
|
|
2157
2235
|
}
|
|
2158
2236
|
_deselect() {
|
|
2159
2237
|
if (!this._isRendered()) {
|
|
@@ -2161,7 +2239,11 @@ var TreeElement = (function () {
|
|
|
2161
2239
|
}
|
|
2162
2240
|
this._element.classList.remove(this._classNames.selected);
|
|
2163
2241
|
let titleSpan = this._getTitleSpan();
|
|
2164
|
-
|
|
2242
|
+
|
|
2243
|
+
// Check for null or undefined
|
|
2244
|
+
if (this._tabIndex != null) {
|
|
2245
|
+
titleSpan.setAttribute("tabindex", "-1");
|
|
2246
|
+
}
|
|
2165
2247
|
titleSpan.setAttribute("aria-selected", "false");
|
|
2166
2248
|
titleSpan.blur();
|
|
2167
2249
|
}
|
|
@@ -2206,7 +2288,7 @@ var TreeElement = (function () {
|
|
|
2206
2288
|
}
|
|
2207
2289
|
return duration === "slow" ? 600 : 200;
|
|
2208
2290
|
};
|
|
2209
|
-
let slideDown = (element, animationSpeed
|
|
2291
|
+
let slideDown = (element, animationSpeed) => {
|
|
2210
2292
|
element.style.display = "block";
|
|
2211
2293
|
let animation = element.animate([{
|
|
2212
2294
|
height: "0",
|
|
@@ -2217,11 +2299,13 @@ var TreeElement = (function () {
|
|
|
2217
2299
|
}], {
|
|
2218
2300
|
duration: getAnimationDuration(animationSpeed)
|
|
2219
2301
|
});
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2302
|
+
return new Promise(resolve => {
|
|
2303
|
+
animation.onfinish = () => {
|
|
2304
|
+
resolve();
|
|
2305
|
+
};
|
|
2306
|
+
});
|
|
2223
2307
|
};
|
|
2224
|
-
let slideUp = (element, animationSpeed
|
|
2308
|
+
let slideUp = (element, animationSpeed) => {
|
|
2225
2309
|
let animation = element.animate([{
|
|
2226
2310
|
height: `${element.scrollHeight}px`,
|
|
2227
2311
|
overflow: "hidden"
|
|
@@ -2231,10 +2315,12 @@ var TreeElement = (function () {
|
|
|
2231
2315
|
}], {
|
|
2232
2316
|
duration: getAnimationDuration(animationSpeed)
|
|
2233
2317
|
});
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2318
|
+
return new Promise(resolve => {
|
|
2319
|
+
animation.onfinish = () => {
|
|
2320
|
+
element.style.display = "none";
|
|
2321
|
+
resolve();
|
|
2322
|
+
};
|
|
2323
|
+
});
|
|
2238
2324
|
};
|
|
2239
2325
|
|
|
2240
2326
|
class FolderElement extends NodeElement {
|
|
@@ -2261,7 +2347,7 @@ var TreeElement = (function () {
|
|
|
2261
2347
|
this._renderChildren = renderChildren;
|
|
2262
2348
|
this._triggerEvent = triggerEvent;
|
|
2263
2349
|
}
|
|
2264
|
-
_close(slide, animationSpeed) {
|
|
2350
|
+
async _close(slide, animationSpeed) {
|
|
2265
2351
|
if (!this._node.is_open) {
|
|
2266
2352
|
return;
|
|
2267
2353
|
}
|
|
@@ -2274,92 +2360,76 @@ var TreeElement = (function () {
|
|
|
2274
2360
|
}
|
|
2275
2361
|
let button = this._getButton();
|
|
2276
2362
|
button.classList.add(this._classNames.closed);
|
|
2277
|
-
button.
|
|
2363
|
+
button.replaceChildren();
|
|
2278
2364
|
let closedIconElement = this._closedIconElement;
|
|
2279
2365
|
if (closedIconElement) {
|
|
2280
2366
|
let icon = closedIconElement.cloneNode(true);
|
|
2281
|
-
button.
|
|
2367
|
+
button.append(icon);
|
|
2282
2368
|
}
|
|
2283
|
-
let doClose = () => {
|
|
2284
|
-
this._element.classList.add(this._classNames.closed);
|
|
2285
|
-
let titleSpan = this._getTitleSpan();
|
|
2286
|
-
titleSpan.setAttribute("aria-expanded", "false");
|
|
2287
|
-
this._triggerEvent("tree.close", {
|
|
2288
|
-
node: this._node
|
|
2289
|
-
});
|
|
2290
|
-
};
|
|
2291
2369
|
let ul = this._getUl();
|
|
2292
|
-
if (
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
doClose();
|
|
2370
|
+
if (ul) {
|
|
2371
|
+
if (slide) {
|
|
2372
|
+
await slideUp(ul, animationSpeed);
|
|
2373
|
+
} else {
|
|
2374
|
+
ul.style.display = "none";
|
|
2375
|
+
}
|
|
2299
2376
|
}
|
|
2377
|
+
this._element.classList.add(this._classNames.closed);
|
|
2378
|
+
let titleSpan = this._getTitleSpan();
|
|
2379
|
+
titleSpan.setAttribute("aria-expanded", "false");
|
|
2380
|
+
this._triggerEvent("tree.close", {
|
|
2381
|
+
node: this._node
|
|
2382
|
+
});
|
|
2300
2383
|
}
|
|
2301
2384
|
async _open(slide, animationSpeed) {
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
titleSpan.setAttribute("aria-expanded", "true");
|
|
2328
|
-
this._triggerEvent("tree.open", {
|
|
2329
|
-
node: this._node
|
|
2330
|
-
});
|
|
2331
|
-
resolve();
|
|
2332
|
-
};
|
|
2333
|
-
|
|
2334
|
-
// The children are rendered the first time the folder is opened
|
|
2335
|
-
let ul = this._getUl() ?? this._renderChildren(this._node);
|
|
2336
|
-
if (!ul) {
|
|
2337
|
-
doOpen();
|
|
2338
|
-
} else if (slide) {
|
|
2339
|
-
slideDown(ul, animationSpeed, doOpen);
|
|
2385
|
+
if (this._node.is_open) {
|
|
2386
|
+
return;
|
|
2387
|
+
}
|
|
2388
|
+
this._node.is_open = true;
|
|
2389
|
+
if (!this._isRendered()) {
|
|
2390
|
+
// The folder is rendered open when its parent is opened
|
|
2391
|
+
this._triggerEvent("tree.open", {
|
|
2392
|
+
node: this._node
|
|
2393
|
+
});
|
|
2394
|
+
return;
|
|
2395
|
+
}
|
|
2396
|
+
let button = this._getButton();
|
|
2397
|
+
button.classList.remove(this._classNames.closed);
|
|
2398
|
+
button.replaceChildren();
|
|
2399
|
+
let openedIconElement = this._openedIconElement;
|
|
2400
|
+
if (openedIconElement) {
|
|
2401
|
+
let icon = openedIconElement.cloneNode(true);
|
|
2402
|
+
button.append(icon);
|
|
2403
|
+
}
|
|
2404
|
+
|
|
2405
|
+
// The children are rendered the first time the folder is opened
|
|
2406
|
+
let ul = this._getUl() ?? this._renderChildren(this._node);
|
|
2407
|
+
if (ul) {
|
|
2408
|
+
if (slide) {
|
|
2409
|
+
await slideDown(ul, animationSpeed);
|
|
2340
2410
|
} else {
|
|
2341
2411
|
ul.style.display = "block";
|
|
2342
|
-
doOpen();
|
|
2343
2412
|
}
|
|
2413
|
+
}
|
|
2414
|
+
this._element.classList.remove(this._classNames.closed);
|
|
2415
|
+
let titleSpan = this._getTitleSpan();
|
|
2416
|
+
titleSpan.setAttribute("aria-expanded", "true");
|
|
2417
|
+
this._triggerEvent("tree.open", {
|
|
2418
|
+
node: this._node
|
|
2344
2419
|
});
|
|
2345
2420
|
}
|
|
2346
2421
|
_mustShowBorderDropHint(position) {
|
|
2347
2422
|
return !this._node.is_open && position === "inside";
|
|
2348
2423
|
}
|
|
2349
2424
|
_getButton() {
|
|
2350
|
-
return this._element.querySelector(`:scope > .${this._classNames.element} >
|
|
2425
|
+
return this._element.querySelector(`:scope > .${this._classNames.element} > .${this._classNames.toggler}`);
|
|
2351
2426
|
}
|
|
2352
2427
|
}
|
|
2353
2428
|
|
|
2354
2429
|
// Url class for absolute and relative urls.
|
|
2355
2430
|
|
|
2356
2431
|
let isAbsoluteUrl = inputUrl => {
|
|
2357
|
-
|
|
2358
|
-
new URL(inputUrl);
|
|
2359
|
-
return true;
|
|
2360
|
-
} catch {
|
|
2361
|
-
return false;
|
|
2362
|
-
}
|
|
2432
|
+
return URL.canParse(inputUrl);
|
|
2363
2433
|
};
|
|
2364
2434
|
let LOCALHOST = "http://localhost";
|
|
2365
2435
|
class RequestUrl {
|
|
@@ -2376,11 +2446,7 @@ var TreeElement = (function () {
|
|
|
2376
2446
|
this._url.searchParams.set(key, value);
|
|
2377
2447
|
}
|
|
2378
2448
|
_value() {
|
|
2379
|
-
|
|
2380
|
-
return this._url.href;
|
|
2381
|
-
} else {
|
|
2382
|
-
return this._url.href.slice(LOCALHOST.length);
|
|
2383
|
-
}
|
|
2449
|
+
return this._isAbsolute ? this._url.href : this._url.href.slice(LOCALHOST.length);
|
|
2384
2450
|
}
|
|
2385
2451
|
}
|
|
2386
2452
|
|
|
@@ -2413,11 +2479,7 @@ var TreeElement = (function () {
|
|
|
2413
2479
|
return null;
|
|
2414
2480
|
}
|
|
2415
2481
|
let state = this._getStateFromStorage();
|
|
2416
|
-
|
|
2417
|
-
return state.selected_node[0] ?? null;
|
|
2418
|
-
} else {
|
|
2419
|
-
return null;
|
|
2420
|
-
}
|
|
2482
|
+
return state?.selected_node ? state.selected_node[0] ?? null : null;
|
|
2421
2483
|
}
|
|
2422
2484
|
_getState() {
|
|
2423
2485
|
let getOpenNodeIds = () => {
|
|
@@ -2432,11 +2494,11 @@ var TreeElement = (function () {
|
|
|
2432
2494
|
};
|
|
2433
2495
|
let getSelectedNodeIds = () => {
|
|
2434
2496
|
let selectedNodeIds = [];
|
|
2435
|
-
this._getSelectedNodes()
|
|
2497
|
+
for (let node of this._getSelectedNodes()) {
|
|
2436
2498
|
if (node.id != null) {
|
|
2437
2499
|
selectedNodeIds.push(node.id);
|
|
2438
2500
|
}
|
|
2439
|
-
}
|
|
2501
|
+
}
|
|
2440
2502
|
return selectedNodeIds;
|
|
2441
2503
|
};
|
|
2442
2504
|
return {
|
|
@@ -2449,11 +2511,7 @@ var TreeElement = (function () {
|
|
|
2449
2511
|
return null;
|
|
2450
2512
|
}
|
|
2451
2513
|
let jsonData = this._loadFromStorage();
|
|
2452
|
-
|
|
2453
|
-
return this._parseState(jsonData);
|
|
2454
|
-
} else {
|
|
2455
|
-
return null;
|
|
2456
|
-
}
|
|
2514
|
+
return jsonData ? this._parseState(jsonData) : null;
|
|
2457
2515
|
}
|
|
2458
2516
|
_saveState() {
|
|
2459
2517
|
if (!this._saveStateOption) {
|
|
@@ -2473,10 +2531,7 @@ var TreeElement = (function () {
|
|
|
2473
2531
|
result: must load on demand (boolean)
|
|
2474
2532
|
*/
|
|
2475
2533
|
_setInitialState(state) {
|
|
2476
|
-
let mustLoadOnDemand = false;
|
|
2477
|
-
if (state.open_nodes) {
|
|
2478
|
-
mustLoadOnDemand = this._openInitialNodes(state.open_nodes);
|
|
2479
|
-
}
|
|
2534
|
+
let mustLoadOnDemand = state.open_nodes ? this._openInitialNodes(state.open_nodes) : false;
|
|
2480
2535
|
this._resetSelection();
|
|
2481
2536
|
if (state.selected_node) {
|
|
2482
2537
|
this._selectInitialNodes(state.selected_node);
|
|
@@ -2492,9 +2547,7 @@ var TreeElement = (function () {
|
|
|
2492
2547
|
let newNodesIds = [];
|
|
2493
2548
|
for (let nodeId of nodeIds) {
|
|
2494
2549
|
let node = this._getNodeById(nodeId);
|
|
2495
|
-
if (
|
|
2496
|
-
newNodesIds.push(nodeId);
|
|
2497
|
-
} else {
|
|
2550
|
+
if (node) {
|
|
2498
2551
|
if (!node.is_loading) {
|
|
2499
2552
|
if (node.load_on_demand) {
|
|
2500
2553
|
await loadAndOpenNode(node);
|
|
@@ -2502,13 +2555,13 @@ var TreeElement = (function () {
|
|
|
2502
2555
|
await this._openNode(node, false);
|
|
2503
2556
|
}
|
|
2504
2557
|
}
|
|
2558
|
+
} else {
|
|
2559
|
+
newNodesIds.push(nodeId);
|
|
2505
2560
|
}
|
|
2506
2561
|
}
|
|
2507
2562
|
nodeIds = newNodesIds;
|
|
2508
|
-
if (state.selected_node) {
|
|
2509
|
-
|
|
2510
|
-
this._refreshElements(null);
|
|
2511
|
-
}
|
|
2563
|
+
if (state.selected_node && this._selectInitialNodes(state.selected_node)) {
|
|
2564
|
+
this._refreshElements(null);
|
|
2512
2565
|
}
|
|
2513
2566
|
};
|
|
2514
2567
|
let loadAndOpenNode = async node => {
|
|
@@ -2518,28 +2571,20 @@ var TreeElement = (function () {
|
|
|
2518
2571
|
await openNodes();
|
|
2519
2572
|
}
|
|
2520
2573
|
_getKeyName() {
|
|
2521
|
-
|
|
2522
|
-
return this._saveStateOption;
|
|
2523
|
-
} else {
|
|
2524
|
-
return "tree";
|
|
2525
|
-
}
|
|
2574
|
+
return typeof this._saveStateOption === "string" ? this._saveStateOption : "tree";
|
|
2526
2575
|
}
|
|
2527
2576
|
_loadFromStorage() {
|
|
2528
|
-
|
|
2529
|
-
return this._onGetStateFromStorage();
|
|
2530
|
-
} else {
|
|
2531
|
-
return localStorage.getItem(this._getKeyName());
|
|
2532
|
-
}
|
|
2577
|
+
return this._onGetStateFromStorage ? this._onGetStateFromStorage() : localStorage.getItem(this._getKeyName());
|
|
2533
2578
|
}
|
|
2534
2579
|
_openInitialNodes(nodeIds) {
|
|
2535
2580
|
let mustLoadOnDemand = false;
|
|
2536
2581
|
for (let nodeId of nodeIds) {
|
|
2537
2582
|
let node = this._getNodeById(nodeId);
|
|
2538
2583
|
if (node) {
|
|
2539
|
-
if (
|
|
2540
|
-
node.is_open = true;
|
|
2541
|
-
} else {
|
|
2584
|
+
if (node.load_on_demand) {
|
|
2542
2585
|
mustLoadOnDemand = true;
|
|
2586
|
+
} else {
|
|
2587
|
+
node.is_open = true;
|
|
2543
2588
|
}
|
|
2544
2589
|
}
|
|
2545
2590
|
}
|
|
@@ -2557,18 +2602,19 @@ var TreeElement = (function () {
|
|
|
2557
2602
|
}
|
|
2558
2603
|
_resetSelection() {
|
|
2559
2604
|
let selectedNodes = this._getSelectedNodes();
|
|
2560
|
-
|
|
2605
|
+
for (let node of selectedNodes) {
|
|
2561
2606
|
this._removeFromSelection(node);
|
|
2562
|
-
}
|
|
2607
|
+
}
|
|
2563
2608
|
}
|
|
2564
2609
|
_selectInitialNodes(nodeIds) {
|
|
2565
2610
|
let selectCount = 0;
|
|
2566
2611
|
for (let nodeId of nodeIds) {
|
|
2567
2612
|
let node = this._getNodeById(nodeId);
|
|
2568
|
-
if (node) {
|
|
2569
|
-
|
|
2570
|
-
this._addToSelection(node);
|
|
2613
|
+
if (!node) {
|
|
2614
|
+
continue;
|
|
2571
2615
|
}
|
|
2616
|
+
selectCount += 1;
|
|
2617
|
+
this._addToSelection(node);
|
|
2572
2618
|
}
|
|
2573
2619
|
return selectCount !== 0;
|
|
2574
2620
|
}
|
|
@@ -2584,27 +2630,29 @@ var TreeElement = (function () {
|
|
|
2584
2630
|
}
|
|
2585
2631
|
_checkHorizontalScrolling(pageX) {
|
|
2586
2632
|
let newHorizontalScrollDirection = this._getNewHorizontalScrollDirection(pageX);
|
|
2587
|
-
if (this._horizontalScrollDirection
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2633
|
+
if (this._horizontalScrollDirection === newHorizontalScrollDirection) {
|
|
2634
|
+
return;
|
|
2635
|
+
}
|
|
2636
|
+
this._horizontalScrollDirection = newHorizontalScrollDirection;
|
|
2637
|
+
if (this._horizontalScrollTimeout != null) {
|
|
2638
|
+
window.clearTimeout(this._horizontalScrollTimeout);
|
|
2639
|
+
}
|
|
2640
|
+
if (newHorizontalScrollDirection) {
|
|
2641
|
+
this._horizontalScrollTimeout = window.setTimeout(this._scrollHorizontally.bind(this), 40);
|
|
2595
2642
|
}
|
|
2596
2643
|
}
|
|
2597
2644
|
_checkVerticalScrolling(pageY) {
|
|
2598
2645
|
let newVerticalScrollDirection = this._getNewVerticalScrollDirection(pageY);
|
|
2599
|
-
if (this._verticalScrollDirection
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2646
|
+
if (this._verticalScrollDirection === newVerticalScrollDirection) {
|
|
2647
|
+
return;
|
|
2648
|
+
}
|
|
2649
|
+
this._verticalScrollDirection = newVerticalScrollDirection;
|
|
2650
|
+
if (this._verticalScrollTimeout != null) {
|
|
2651
|
+
window.clearTimeout(this._verticalScrollTimeout);
|
|
2652
|
+
this._verticalScrollTimeout = undefined;
|
|
2653
|
+
}
|
|
2654
|
+
if (newVerticalScrollDirection) {
|
|
2655
|
+
this._verticalScrollTimeout = window.setTimeout(this._scrollVertically.bind(this), 40);
|
|
2608
2656
|
}
|
|
2609
2657
|
}
|
|
2610
2658
|
_getScrollLeft() {
|
|
@@ -2657,22 +2705,17 @@ var TreeElement = (function () {
|
|
|
2657
2705
|
let rightEdge = scrollParentOffset.left + containerWidth;
|
|
2658
2706
|
let leftEdge = scrollParentOffset.left;
|
|
2659
2707
|
let isNearRightEdge = pageX > rightEdge - 20;
|
|
2660
|
-
let isNearLeftEdge = pageX < leftEdge + 20;
|
|
2661
2708
|
if (isNearRightEdge) {
|
|
2662
2709
|
return "right";
|
|
2663
|
-
} else if (isNearLeftEdge) {
|
|
2664
|
-
return "left";
|
|
2665
2710
|
}
|
|
2666
|
-
|
|
2711
|
+
let isNearLeftEdge = pageX < leftEdge + 20;
|
|
2712
|
+
return isNearLeftEdge ? "left" : undefined;
|
|
2667
2713
|
}
|
|
2668
2714
|
_getNewVerticalScrollDirection(pageY) {
|
|
2669
2715
|
if (pageY < this._getScrollParentTop()) {
|
|
2670
2716
|
return "top";
|
|
2671
2717
|
}
|
|
2672
|
-
|
|
2673
|
-
return "bottom";
|
|
2674
|
-
}
|
|
2675
|
-
return undefined;
|
|
2718
|
+
return pageY > this._getScrollParentBottom() ? "bottom" : undefined;
|
|
2676
2719
|
}
|
|
2677
2720
|
_getScrollParentBottom() {
|
|
2678
2721
|
if (this._scrollParentBottom == null) {
|
|
@@ -2711,14 +2754,11 @@ var TreeElement = (function () {
|
|
|
2711
2754
|
let scrollLeft = this._container.scrollLeft;
|
|
2712
2755
|
let windowWidth = window.innerWidth;
|
|
2713
2756
|
let isNearRightEdge = pageX > windowWidth - 20;
|
|
2714
|
-
let isNearLeftEdge = pageX - scrollLeft < 20;
|
|
2715
2757
|
if (isNearRightEdge && this._canScrollRight()) {
|
|
2716
2758
|
return "right";
|
|
2717
2759
|
}
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
}
|
|
2721
|
-
return undefined;
|
|
2760
|
+
let isNearLeftEdge = pageX - scrollLeft < 20;
|
|
2761
|
+
return isNearLeftEdge ? "left" : undefined;
|
|
2722
2762
|
}
|
|
2723
2763
|
_getNewVerticalScrollDirection(pageY) {
|
|
2724
2764
|
let scrollTop = this._container.scrollTop;
|
|
@@ -2727,10 +2767,7 @@ var TreeElement = (function () {
|
|
|
2727
2767
|
return "top";
|
|
2728
2768
|
}
|
|
2729
2769
|
let windowHeight = window.innerHeight;
|
|
2730
|
-
|
|
2731
|
-
return "bottom";
|
|
2732
|
-
}
|
|
2733
|
-
return undefined;
|
|
2770
|
+
return windowHeight - (pageY - scrollTop) < 20 && this._canScrollDown() ? "bottom" : undefined;
|
|
2734
2771
|
}
|
|
2735
2772
|
_canScrollDown() {
|
|
2736
2773
|
return this._container.scrollTop + this._container.clientHeight < this._getDocumentScrollHeight();
|
|
@@ -2775,12 +2812,11 @@ var TreeElement = (function () {
|
|
|
2775
2812
|
_container: container,
|
|
2776
2813
|
_refreshHitAreas: refreshHitAreas
|
|
2777
2814
|
});
|
|
2778
|
-
} else {
|
|
2779
|
-
return new DocumentScrollParent({
|
|
2780
|
-
_refreshHitAreas: refreshHitAreas,
|
|
2781
|
-
_treeElement: treeElement
|
|
2782
|
-
});
|
|
2783
2815
|
}
|
|
2816
|
+
return new DocumentScrollParent({
|
|
2817
|
+
_refreshHitAreas: refreshHitAreas,
|
|
2818
|
+
_treeElement: treeElement
|
|
2819
|
+
});
|
|
2784
2820
|
};
|
|
2785
2821
|
|
|
2786
2822
|
class ScrollHandler {
|
|
@@ -2825,7 +2861,8 @@ var TreeElement = (function () {
|
|
|
2825
2861
|
_getSelectable: getSelectable,
|
|
2826
2862
|
_openParents: openParents,
|
|
2827
2863
|
_saveState: saveState,
|
|
2828
|
-
_triggerEvent: triggerEvent
|
|
2864
|
+
_triggerEvent: triggerEvent,
|
|
2865
|
+
_updateTabStop: updateTabStop
|
|
2829
2866
|
}) {
|
|
2830
2867
|
this._getNodeById = getNodeById;
|
|
2831
2868
|
this._getNodeElementForNode = getNodeElementForNode;
|
|
@@ -2836,12 +2873,13 @@ var TreeElement = (function () {
|
|
|
2836
2873
|
this._selectedNodes = new Set();
|
|
2837
2874
|
this._selectedSingleNode = null;
|
|
2838
2875
|
this._triggerEvent = triggerEvent;
|
|
2876
|
+
this._updateTabStop = updateTabStop;
|
|
2839
2877
|
}
|
|
2840
2878
|
_addToSelection(node) {
|
|
2841
|
-
if (node.id
|
|
2842
|
-
this._selectedNodes.add(node.id);
|
|
2843
|
-
} else {
|
|
2879
|
+
if (node.id == null) {
|
|
2844
2880
|
this._selectedSingleNode = node;
|
|
2881
|
+
} else {
|
|
2882
|
+
this._selectedNodes.add(node.id);
|
|
2845
2883
|
}
|
|
2846
2884
|
}
|
|
2847
2885
|
_clear() {
|
|
@@ -2850,52 +2888,39 @@ var TreeElement = (function () {
|
|
|
2850
2888
|
}
|
|
2851
2889
|
_getSelectedNode() {
|
|
2852
2890
|
let selectedNodes = this._getSelectedNodes();
|
|
2853
|
-
|
|
2854
|
-
return selectedNodes[0] ?? null;
|
|
2855
|
-
} else {
|
|
2856
|
-
return null;
|
|
2857
|
-
}
|
|
2891
|
+
return selectedNodes.length ? selectedNodes[0] ?? null : null;
|
|
2858
2892
|
}
|
|
2859
2893
|
_getSelectedNodes() {
|
|
2860
2894
|
if (this._selectedSingleNode) {
|
|
2861
2895
|
return [this._selectedSingleNode];
|
|
2862
|
-
} else {
|
|
2863
|
-
let selectedNodes = [];
|
|
2864
|
-
this._selectedNodes.forEach(id => {
|
|
2865
|
-
let node = this._getNodeById(id);
|
|
2866
|
-
if (node) {
|
|
2867
|
-
selectedNodes.push(node);
|
|
2868
|
-
}
|
|
2869
|
-
});
|
|
2870
|
-
return selectedNodes;
|
|
2871
2896
|
}
|
|
2897
|
+
let selectedNodes = [];
|
|
2898
|
+
this._selectedNodes.forEach(id => {
|
|
2899
|
+
let node = this._getNodeById(id);
|
|
2900
|
+
if (node) {
|
|
2901
|
+
selectedNodes.push(node);
|
|
2902
|
+
}
|
|
2903
|
+
});
|
|
2904
|
+
return selectedNodes;
|
|
2872
2905
|
}
|
|
2873
2906
|
_getSelectedNodesUnder(parent) {
|
|
2874
2907
|
if (this._selectedSingleNode) {
|
|
2875
|
-
|
|
2876
|
-
return [this._selectedSingleNode];
|
|
2877
|
-
} else {
|
|
2878
|
-
return [];
|
|
2879
|
-
}
|
|
2880
|
-
} else {
|
|
2881
|
-
let selectedNodes = [];
|
|
2882
|
-
this._selectedNodes.forEach(id => {
|
|
2883
|
-
let node = this._getNodeById(id);
|
|
2884
|
-
if (node && parent.isParentOf(node)) {
|
|
2885
|
-
selectedNodes.push(node);
|
|
2886
|
-
}
|
|
2887
|
-
});
|
|
2888
|
-
return selectedNodes;
|
|
2908
|
+
return parent.isParentOf(this._selectedSingleNode) ? [this._selectedSingleNode] : [];
|
|
2889
2909
|
}
|
|
2910
|
+
let selectedNodes = [];
|
|
2911
|
+
this._selectedNodes.forEach(id => {
|
|
2912
|
+
let node = this._getNodeById(id);
|
|
2913
|
+
if (node && parent.isParentOf(node)) {
|
|
2914
|
+
selectedNodes.push(node);
|
|
2915
|
+
}
|
|
2916
|
+
});
|
|
2917
|
+
return selectedNodes;
|
|
2890
2918
|
}
|
|
2891
2919
|
_isNodeSelected(node) {
|
|
2892
2920
|
if (node.id != null) {
|
|
2893
2921
|
return this._selectedNodes.has(node.id);
|
|
2894
|
-
} else if (this._selectedSingleNode) {
|
|
2895
|
-
return this._selectedSingleNode === node;
|
|
2896
|
-
} else {
|
|
2897
|
-
return false;
|
|
2898
2922
|
}
|
|
2923
|
+
return this._selectedSingleNode ? this._selectedSingleNode === node : false;
|
|
2899
2924
|
}
|
|
2900
2925
|
_removeFromSelection(node, includeChildren = false) {
|
|
2901
2926
|
if (node.id == null) {
|
|
@@ -2932,7 +2957,7 @@ var TreeElement = (function () {
|
|
|
2932
2957
|
};
|
|
2933
2958
|
let selectOptions = {
|
|
2934
2959
|
...defaultOptions,
|
|
2935
|
-
...
|
|
2960
|
+
...optionsParam
|
|
2936
2961
|
};
|
|
2937
2962
|
let canSelect = () => {
|
|
2938
2963
|
if (!this._getSelectable()) {
|
|
@@ -2968,6 +2993,7 @@ var TreeElement = (function () {
|
|
|
2968
2993
|
node
|
|
2969
2994
|
});
|
|
2970
2995
|
}
|
|
2996
|
+
this._updateTabStop();
|
|
2971
2997
|
this._saveState();
|
|
2972
2998
|
}
|
|
2973
2999
|
}
|
|
@@ -2981,7 +3007,7 @@ var TreeElement = (function () {
|
|
|
2981
3007
|
classPrefix: DEFAULT_CLASS_PREFIX,
|
|
2982
3008
|
// the prefix of all css classes
|
|
2983
3009
|
// The symbol to use for a closed node - ► BLACK RIGHT-POINTING POINTER
|
|
2984
|
-
//
|
|
3010
|
+
// https://www.fileformat.info/info/unicode/char/25ba/index.htm
|
|
2985
3011
|
// closedIcon: undefined,
|
|
2986
3012
|
// commonClassName: undefined, // the class of every element; the default is "<classPrefix>-common"
|
|
2987
3013
|
// data: undefined,
|
|
@@ -3003,7 +3029,7 @@ var TreeElement = (function () {
|
|
|
3003
3029
|
openFolderDelay: 500,
|
|
3004
3030
|
// The delay for opening a folder during drag and drop; the value is in milliseconds
|
|
3005
3031
|
// The symbol to use for an open node - ▼ BLACK DOWN-POINTING TRIANGLE
|
|
3006
|
-
//
|
|
3032
|
+
// https://www.fileformat.info/info/unicode/char/25bc/index.htm
|
|
3007
3033
|
// rtl: undefined, // right-to-left support; true / false (default)
|
|
3008
3034
|
saveState: false,
|
|
3009
3035
|
// true / false / string (local storage key; the default key is "tree")
|
|
@@ -3020,7 +3046,8 @@ var TreeElement = (function () {
|
|
|
3020
3046
|
let setDefaultOptions = (htmlElement, inputOptions) => {
|
|
3021
3047
|
let options = {
|
|
3022
3048
|
...defaults,
|
|
3023
|
-
...inputOptions
|
|
3049
|
+
...inputOptions,
|
|
3050
|
+
animationSpeed: inputOptions.animationSpeed ?? getDefaultAnimationSpeed()
|
|
3024
3051
|
};
|
|
3025
3052
|
options.dataUrl ??= htmlElement.dataset.url;
|
|
3026
3053
|
options.rtl ??= getRtlOptionFromHTMLElement(htmlElement);
|
|
@@ -3028,24 +3055,24 @@ var TreeElement = (function () {
|
|
|
3028
3055
|
options.openedIcon ??= "▼";
|
|
3029
3056
|
return options;
|
|
3030
3057
|
};
|
|
3058
|
+
|
|
3059
|
+
// No animation when the user asked the system for reduced motion
|
|
3060
|
+
let getDefaultAnimationSpeed = () => prefersReducedMotion() ? 0 : defaults.animationSpeed;
|
|
3061
|
+
let prefersReducedMotion = () => typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
3031
3062
|
let getDefaultClosedIcon = options => {
|
|
3032
3063
|
if (options.rtl) {
|
|
3033
3064
|
// triangle to the left
|
|
3034
3065
|
return "◀";
|
|
3035
|
-
} else {
|
|
3036
|
-
// triangle to the right
|
|
3037
|
-
return "►";
|
|
3038
3066
|
}
|
|
3067
|
+
// triangle to the right
|
|
3068
|
+
return "►";
|
|
3039
3069
|
};
|
|
3040
3070
|
let getRtlOptionFromHTMLElement = htmlElement => {
|
|
3041
3071
|
let dataRtl = htmlElement.dataset.rtl;
|
|
3042
3072
|
if (dataRtl == "") {
|
|
3043
3073
|
return true;
|
|
3044
|
-
} else if (dataRtl === "false") {
|
|
3045
|
-
return false;
|
|
3046
|
-
} else {
|
|
3047
|
-
return Boolean(dataRtl);
|
|
3048
3074
|
}
|
|
3075
|
+
return dataRtl === "false" ? false : Boolean(dataRtl);
|
|
3049
3076
|
};
|
|
3050
3077
|
|
|
3051
3078
|
// Trigger a CustomEvent. Return if the event is processed (true) or cancelled (false).
|
|
@@ -3060,7 +3087,7 @@ var TreeElement = (function () {
|
|
|
3060
3087
|
};
|
|
3061
3088
|
|
|
3062
3089
|
// Generated by config/generateVersion.mjs. Do not edit.
|
|
3063
|
-
let version = "0.
|
|
3090
|
+
let version = "0.3.0";
|
|
3064
3091
|
|
|
3065
3092
|
// The types that appear in the public api. Consumers cannot import them from
|
|
3066
3093
|
// the submodules directly, because those are not exposed in package.json.
|
|
@@ -3071,6 +3098,7 @@ var TreeElement = (function () {
|
|
|
3071
3098
|
_classNames;
|
|
3072
3099
|
_dataLoader;
|
|
3073
3100
|
_dndHandler;
|
|
3101
|
+
_fallbackTabStop;
|
|
3074
3102
|
_htmlElement;
|
|
3075
3103
|
_isInitialized;
|
|
3076
3104
|
_keyHandler;
|
|
@@ -3084,7 +3112,9 @@ var TreeElement = (function () {
|
|
|
3084
3112
|
_tree;
|
|
3085
3113
|
_triggerEventProvider;
|
|
3086
3114
|
|
|
3087
|
-
/**
|
|
3115
|
+
/**
|
|
3116
|
+
@hidden
|
|
3117
|
+
*/
|
|
3088
3118
|
constructor({
|
|
3089
3119
|
htmlElement,
|
|
3090
3120
|
overrideTriggerEventProvider,
|
|
@@ -3097,7 +3127,10 @@ var TreeElement = (function () {
|
|
|
3097
3127
|
this._isInitialized = false;
|
|
3098
3128
|
this._tree = new Node({}, true);
|
|
3099
3129
|
this._nodeMap = new WeakMap();
|
|
3130
|
+
this._fallbackTabStop = null;
|
|
3100
3131
|
let {
|
|
3132
|
+
ariaLabel,
|
|
3133
|
+
ariaLabelledBy,
|
|
3101
3134
|
autoEscape,
|
|
3102
3135
|
buttonLeft,
|
|
3103
3136
|
closedIcon,
|
|
@@ -3124,10 +3157,10 @@ var TreeElement = (function () {
|
|
|
3124
3157
|
let closeNode = this.closeNode.bind(this);
|
|
3125
3158
|
let getNodeElement = this._getNodeElement.bind(this);
|
|
3126
3159
|
let getNodeElementForNode = this._getNodeElementForNode.bind(this);
|
|
3160
|
+
let getFocusedNode = this._getFocusedNode.bind(this);
|
|
3127
3161
|
let getNodeById = this.getNodeById.bind(this);
|
|
3128
3162
|
let getSelectedNode = this.getSelectedNode.bind(this);
|
|
3129
3163
|
let getTree = this.getTree.bind(this);
|
|
3130
|
-
let isFocusOnTree = this._isFocusOnTree.bind(this);
|
|
3131
3164
|
let loadData = this.loadData.bind(this);
|
|
3132
3165
|
let openNode = this.openNode.bind(this);
|
|
3133
3166
|
let openParents = this._openParents.bind(this);
|
|
@@ -3136,6 +3169,7 @@ var TreeElement = (function () {
|
|
|
3136
3169
|
let setNodeElement = this._setNodeElement.bind(this);
|
|
3137
3170
|
let treeElement = this._htmlElement;
|
|
3138
3171
|
let triggerEvent = this._triggerEvent.bind(this);
|
|
3172
|
+
let updateTabStop = this._updateTabStop.bind(this);
|
|
3139
3173
|
let saveState = () => {
|
|
3140
3174
|
saveStateHandler._saveState();
|
|
3141
3175
|
};
|
|
@@ -3146,7 +3180,8 @@ var TreeElement = (function () {
|
|
|
3146
3180
|
_getSelectable: () => this._options.selectable,
|
|
3147
3181
|
_openParents: openParents,
|
|
3148
3182
|
_saveState: saveState,
|
|
3149
|
-
_triggerEvent: triggerEvent
|
|
3183
|
+
_triggerEvent: triggerEvent,
|
|
3184
|
+
_updateTabStop: updateTabStop
|
|
3150
3185
|
});
|
|
3151
3186
|
let addToSelection = selectNodeHandler._addToSelection.bind(selectNodeHandler);
|
|
3152
3187
|
let getSelectedNodes = selectNodeHandler._getSelectedNodes.bind(selectNodeHandler);
|
|
@@ -3199,13 +3234,17 @@ var TreeElement = (function () {
|
|
|
3199
3234
|
});
|
|
3200
3235
|
let keyHandler = new KeyHandler({
|
|
3201
3236
|
_closeNode: closeNode,
|
|
3237
|
+
_getFocusedNode: getFocusedNode,
|
|
3202
3238
|
_getSelectedNode: getSelectedNode,
|
|
3203
|
-
|
|
3239
|
+
_getTree: getTree,
|
|
3204
3240
|
_keyboardSupport: keyboardSupport,
|
|
3205
3241
|
_openNode: openNode,
|
|
3206
|
-
_selectNode: selectNode
|
|
3242
|
+
_selectNode: selectNode,
|
|
3243
|
+
_triggerEvent: triggerEvent
|
|
3207
3244
|
});
|
|
3208
3245
|
let renderer = new ElementsRenderer({
|
|
3246
|
+
_ariaLabel: ariaLabel,
|
|
3247
|
+
_ariaLabelledBy: ariaLabelledBy,
|
|
3209
3248
|
_autoEscape: autoEscape,
|
|
3210
3249
|
_buttonLeft: buttonLeft,
|
|
3211
3250
|
_classNames: classNames,
|
|
@@ -3300,10 +3339,11 @@ var TreeElement = (function () {
|
|
|
3300
3339
|
* @param mustSetFocus - Move the focus to the node. Default `true`.
|
|
3301
3340
|
* @group Selection
|
|
3302
3341
|
*/
|
|
3303
|
-
addToSelection(node, mustSetFocus) {
|
|
3342
|
+
addToSelection(node, mustSetFocus = true) {
|
|
3304
3343
|
this._selectNodeHandler._addToSelection(node);
|
|
3305
3344
|
this._openParents(node);
|
|
3306
|
-
this._getNodeElementForNode(node)._select(mustSetFocus
|
|
3345
|
+
this._getNodeElementForNode(node)._select(mustSetFocus);
|
|
3346
|
+
this._updateTabStop();
|
|
3307
3347
|
this._saveState();
|
|
3308
3348
|
}
|
|
3309
3349
|
|
|
@@ -3325,16 +3365,24 @@ var TreeElement = (function () {
|
|
|
3325
3365
|
}
|
|
3326
3366
|
|
|
3327
3367
|
/**
|
|
3328
|
-
* Closes a folder.
|
|
3368
|
+
* Closes a folder. Await the promise when you need to know the closing
|
|
3369
|
+
* animation has finished.
|
|
3370
|
+
*
|
|
3371
|
+
* @example
|
|
3372
|
+
* ```js
|
|
3373
|
+
* await tree.closeNode(node);
|
|
3374
|
+
* console.log("closed");
|
|
3375
|
+
* ```
|
|
3329
3376
|
*
|
|
3330
3377
|
* @param slide - Override the `slide` option for this call.
|
|
3331
3378
|
* @group Opening and closing
|
|
3332
3379
|
*/
|
|
3333
|
-
closeNode(node, slide) {
|
|
3334
|
-
if (node.isFolder() || node.isEmptyFolder) {
|
|
3335
|
-
|
|
3336
|
-
this._saveState();
|
|
3380
|
+
async closeNode(node, slide) {
|
|
3381
|
+
if (!(node.isFolder() || node.isEmptyFolder)) {
|
|
3382
|
+
return;
|
|
3337
3383
|
}
|
|
3384
|
+
await this._createFolderElement(node)._close(slide ?? this._options.slide, this._options.animationSpeed);
|
|
3385
|
+
this._saveState();
|
|
3338
3386
|
}
|
|
3339
3387
|
|
|
3340
3388
|
/**
|
|
@@ -3358,11 +3406,7 @@ var TreeElement = (function () {
|
|
|
3358
3406
|
*/
|
|
3359
3407
|
getNode(element) {
|
|
3360
3408
|
let liElement = element.closest(`li.${this._classNames.common}`);
|
|
3361
|
-
|
|
3362
|
-
return this._nodeMap.get(liElement) ?? null;
|
|
3363
|
-
} else {
|
|
3364
|
-
return null;
|
|
3365
|
-
}
|
|
3409
|
+
return liElement ? this._nodeMap.get(liElement) ?? null : null;
|
|
3366
3410
|
}
|
|
3367
3411
|
|
|
3368
3412
|
/**
|
|
@@ -3653,6 +3697,7 @@ var TreeElement = (function () {
|
|
|
3653
3697
|
removeFromSelection(node) {
|
|
3654
3698
|
this._selectNodeHandler._removeFromSelection(node);
|
|
3655
3699
|
this._getNodeElementForNode(node)._deselect();
|
|
3700
|
+
this._updateTabStop();
|
|
3656
3701
|
this._saveState();
|
|
3657
3702
|
}
|
|
3658
3703
|
|
|
@@ -3698,7 +3743,12 @@ var TreeElement = (function () {
|
|
|
3698
3743
|
this._saveStateHandler._saveState();
|
|
3699
3744
|
return;
|
|
3700
3745
|
}
|
|
3701
|
-
|
|
3746
|
+
|
|
3747
|
+
// Unlike a click, selecting the selected node again keeps it selected
|
|
3748
|
+
this._selectNodeHandler._selectSingleNode(node, {
|
|
3749
|
+
mustToggle: false,
|
|
3750
|
+
...options
|
|
3751
|
+
});
|
|
3702
3752
|
}
|
|
3703
3753
|
|
|
3704
3754
|
/**
|
|
@@ -3724,17 +3774,19 @@ var TreeElement = (function () {
|
|
|
3724
3774
|
}
|
|
3725
3775
|
|
|
3726
3776
|
/**
|
|
3727
|
-
* Closes an open node and opens a closed one.
|
|
3777
|
+
* Closes an open node and opens a closed one. Await the promise when you
|
|
3778
|
+
* need to know the node is really open or closed, like with `openNode` and
|
|
3779
|
+
* `closeNode`.
|
|
3728
3780
|
*
|
|
3729
3781
|
* @param slide - Override the `slide` option for this call.
|
|
3730
3782
|
* @group Opening and closing
|
|
3731
3783
|
*/
|
|
3732
|
-
toggle(node, slide = null) {
|
|
3784
|
+
async toggle(node, slide = null) {
|
|
3733
3785
|
let mustSlide = slide ?? this._options.slide;
|
|
3734
3786
|
if (node.is_open) {
|
|
3735
|
-
this.closeNode(node, mustSlide);
|
|
3787
|
+
await this.closeNode(node, mustSlide);
|
|
3736
3788
|
} else {
|
|
3737
|
-
|
|
3789
|
+
await this.openNode(node, mustSlide);
|
|
3738
3790
|
}
|
|
3739
3791
|
}
|
|
3740
3792
|
|
|
@@ -3772,7 +3824,7 @@ var TreeElement = (function () {
|
|
|
3772
3824
|
if (idIsChanged) {
|
|
3773
3825
|
this._tree.addNodeToIndex(node);
|
|
3774
3826
|
}
|
|
3775
|
-
if (typeof data === "object" && data.children && data.children
|
|
3827
|
+
if (typeof data === "object" && data.children && Array.isArray(data.children)) {
|
|
3776
3828
|
node.removeChildren();
|
|
3777
3829
|
if (data.children.length) {
|
|
3778
3830
|
node.loadFromData(data.children);
|
|
@@ -3780,15 +3832,45 @@ var TreeElement = (function () {
|
|
|
3780
3832
|
}
|
|
3781
3833
|
this._refreshElements(node);
|
|
3782
3834
|
}
|
|
3835
|
+
|
|
3836
|
+
// Open the nodes up to the autoOpen level. A folder that is loaded on
|
|
3837
|
+
// demand is fetched first, and its children are opened when the data has
|
|
3838
|
+
// arrived.
|
|
3839
|
+
async _autoOpenNodesOnDemand() {
|
|
3840
|
+
let maxLevel = this._getAutoOpenMaxLevel();
|
|
3841
|
+
let openNodes = async () => {
|
|
3842
|
+
let loading = [];
|
|
3843
|
+
this._tree.iterate((node, level) => {
|
|
3844
|
+
if (node.load_on_demand) {
|
|
3845
|
+
if (!node.is_loading) {
|
|
3846
|
+
loading.push(this.openNode(node, false).then(openNodes));
|
|
3847
|
+
}
|
|
3848
|
+
return false;
|
|
3849
|
+
}
|
|
3850
|
+
void this.openNode(node, false);
|
|
3851
|
+
return level !== maxLevel;
|
|
3852
|
+
});
|
|
3853
|
+
await Promise.all(loading);
|
|
3854
|
+
};
|
|
3855
|
+
await openNodes();
|
|
3856
|
+
}
|
|
3783
3857
|
_createFolderElement(node) {
|
|
3784
3858
|
let classNames = this._classNames;
|
|
3785
3859
|
let closedIconElement = this._renderer._closedIconElement;
|
|
3786
3860
|
let getScrollLeft = this._scrollHandler._getScrollLeft.bind(this._scrollHandler);
|
|
3787
3861
|
let openedIconElement = this._renderer._openedIconElement;
|
|
3788
|
-
let renderChildren = this._renderer._renderChildren.bind(this._renderer);
|
|
3789
3862
|
let tabIndex = this._options.tabIndex;
|
|
3790
3863
|
let treeElement = this._htmlElement;
|
|
3791
3864
|
let triggerEvent = this._triggerEvent.bind(this);
|
|
3865
|
+
|
|
3866
|
+
// A selected node in a closed folder is rendered when the folder is
|
|
3867
|
+
// opened, which can be after it was selected. It becomes the tab stop
|
|
3868
|
+
// then, so the fallback tab stop must go.
|
|
3869
|
+
let renderChildren = folder => {
|
|
3870
|
+
let ul = this._renderer._renderChildren(folder);
|
|
3871
|
+
this._updateTabStop();
|
|
3872
|
+
return ul;
|
|
3873
|
+
};
|
|
3792
3874
|
return new FolderElement({
|
|
3793
3875
|
_classNames: classNames,
|
|
3794
3876
|
_closedIconElement: closedIconElement,
|
|
@@ -3821,12 +3903,7 @@ var TreeElement = (function () {
|
|
|
3821
3903
|
*/
|
|
3822
3904
|
_createRequestUrl(node) {
|
|
3823
3905
|
let dataUrl = this._options.dataUrl;
|
|
3824
|
-
let url;
|
|
3825
|
-
if (typeof dataUrl === "function") {
|
|
3826
|
-
url = dataUrl(node);
|
|
3827
|
-
} else {
|
|
3828
|
-
url = dataUrl;
|
|
3829
|
-
}
|
|
3906
|
+
let url = typeof dataUrl === "function" ? dataUrl(node) : dataUrl;
|
|
3830
3907
|
if (!url) {
|
|
3831
3908
|
return null;
|
|
3832
3909
|
}
|
|
@@ -3862,33 +3939,54 @@ var TreeElement = (function () {
|
|
|
3862
3939
|
_getAutoOpenMaxLevel() {
|
|
3863
3940
|
if (this._options.autoOpen === true) {
|
|
3864
3941
|
return -1;
|
|
3865
|
-
}
|
|
3942
|
+
}
|
|
3943
|
+
if (typeof this._options.autoOpen === "number") {
|
|
3866
3944
|
return this._options.autoOpen;
|
|
3867
|
-
}
|
|
3945
|
+
}
|
|
3946
|
+
if (typeof this._options.autoOpen === "string") {
|
|
3868
3947
|
return parseInt(this._options.autoOpen, 10);
|
|
3869
3948
|
}
|
|
3870
3949
|
|
|
3871
3950
|
/* istanbul ignore next @preserve */
|
|
3872
3951
|
return 0;
|
|
3873
3952
|
}
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
}
|
|
3953
|
+
|
|
3954
|
+
// The title span of the first node, or null when the tree is empty
|
|
3955
|
+
_getFirstTitleSpan() {
|
|
3956
|
+
let firstElement = this._tree.children[0]?.element;
|
|
3957
|
+
return firstElement ? firstElement.querySelector(`:scope > .${this._classNames.element} > span.${this._classNames.title}`) : null;
|
|
3958
|
+
}
|
|
3959
|
+
|
|
3960
|
+
// The node of the HTML element that has the focus, if it is in this tree
|
|
3961
|
+
_getFocusedNode() {
|
|
3962
|
+
let activeElement = document.activeElement;
|
|
3963
|
+
|
|
3964
|
+
/* istanbul ignore if */
|
|
3965
|
+
if (!activeElement) {
|
|
3966
|
+
return null;
|
|
3967
|
+
}
|
|
3968
|
+
|
|
3969
|
+
// The keyboard must still work for input elements.
|
|
3970
|
+
let tagName = activeElement.tagName;
|
|
3971
|
+
if (tagName !== "A" && tagName !== "SPAN") {
|
|
3879
3972
|
return null;
|
|
3880
3973
|
}
|
|
3974
|
+
let node = this.getNode(activeElement);
|
|
3975
|
+
return node?.tree === this._tree ? node : null;
|
|
3976
|
+
}
|
|
3977
|
+
_getNodeElement(element) {
|
|
3978
|
+
let node = this.getNode(element);
|
|
3979
|
+
return node ? this._getNodeElementForNode(node) : null;
|
|
3881
3980
|
}
|
|
3882
3981
|
_getNodeElementForNode(node) {
|
|
3883
|
-
|
|
3884
|
-
return this._createFolderElement(node);
|
|
3885
|
-
} else {
|
|
3886
|
-
return this._createNodeElement(node);
|
|
3887
|
-
}
|
|
3982
|
+
return node.isFolder() ? this._createFolderElement(node) : this._createNodeElement(node);
|
|
3888
3983
|
}
|
|
3889
3984
|
_getNodeIdToBeSelected() {
|
|
3890
3985
|
return this._saveStateHandler._getNodeIdToBeSelected();
|
|
3891
3986
|
}
|
|
3987
|
+
_hasRenderedSelectedNode() {
|
|
3988
|
+
return this.getSelectedNodes().some(node => Boolean(node.element));
|
|
3989
|
+
}
|
|
3892
3990
|
_initData() {
|
|
3893
3991
|
if (this._options.data) {
|
|
3894
3992
|
this.loadData(this._options.data);
|
|
@@ -3903,10 +4001,11 @@ var TreeElement = (function () {
|
|
|
3903
4001
|
}
|
|
3904
4002
|
_initTree(data) {
|
|
3905
4003
|
let doInit = () => {
|
|
3906
|
-
if (
|
|
3907
|
-
|
|
3908
|
-
this._triggerEvent("tree.init");
|
|
4004
|
+
if (this._isInitialized) {
|
|
4005
|
+
return;
|
|
3909
4006
|
}
|
|
4007
|
+
this._isInitialized = true;
|
|
4008
|
+
this._triggerEvent("tree.init");
|
|
3910
4009
|
};
|
|
3911
4010
|
this._tree = new this._options.nodeClass(null, true, this._options.nodeClass);
|
|
3912
4011
|
this._selectNodeHandler._clear();
|
|
@@ -3923,32 +4022,22 @@ var TreeElement = (function () {
|
|
|
3923
4022
|
|
|
3924
4023
|
// Does an HTML element of the tree have the focus?
|
|
3925
4024
|
_isFocusOnTree() {
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
/* istanbul ignore if */
|
|
3929
|
-
if (!activeElement) {
|
|
3930
|
-
return false;
|
|
3931
|
-
}
|
|
3932
|
-
|
|
3933
|
-
// The keyboard must still work for input elements.
|
|
3934
|
-
let tagName = activeElement.tagName;
|
|
3935
|
-
if (tagName !== "A" && tagName !== "SPAN") {
|
|
3936
|
-
return false;
|
|
3937
|
-
}
|
|
3938
|
-
let node = this.getNode(activeElement);
|
|
3939
|
-
return node?.tree === this._tree;
|
|
4025
|
+
return this._getFocusedNode() !== null;
|
|
3940
4026
|
}
|
|
3941
4027
|
_isSelectedNodeInSubtree(subtree) {
|
|
3942
4028
|
let selectedNode = this.getSelectedNode();
|
|
3943
|
-
|
|
3944
|
-
return false;
|
|
3945
|
-
} else {
|
|
3946
|
-
return subtree === selectedNode || subtree.isParentOf(selectedNode);
|
|
3947
|
-
}
|
|
4029
|
+
return selectedNode ? subtree === selectedNode || subtree.isParentOf(selectedNode) : false;
|
|
3948
4030
|
}
|
|
3949
4031
|
async _loadFolderOnDemand(node, slide) {
|
|
3950
4032
|
node.is_loading = true;
|
|
3951
4033
|
await this.loadDataFromUrl(undefined, node);
|
|
4034
|
+
|
|
4035
|
+
// Loading failed, or there is no url. Opening the node now would load it
|
|
4036
|
+
// again, without end. Leave it closed so the user can try again.
|
|
4037
|
+
if (node.load_on_demand) {
|
|
4038
|
+
node.is_loading = false;
|
|
4039
|
+
return;
|
|
4040
|
+
}
|
|
3952
4041
|
await this.openNode(node, slide);
|
|
3953
4042
|
}
|
|
3954
4043
|
_loadSubtree(data, parentNode) {
|
|
@@ -3958,10 +4047,7 @@ var TreeElement = (function () {
|
|
|
3958
4047
|
this._refreshElements(parentNode);
|
|
3959
4048
|
}
|
|
3960
4049
|
_mouseCapture(positionInfo) {
|
|
3961
|
-
|
|
3962
|
-
return false;
|
|
3963
|
-
}
|
|
3964
|
-
return this._dndHandler._mouseCapture(positionInfo);
|
|
4050
|
+
return this._options.dragAndDrop ? this._dndHandler._mouseCapture(positionInfo) : false;
|
|
3965
4051
|
}
|
|
3966
4052
|
_mouseDrag(positionInfo) {
|
|
3967
4053
|
/* istanbul ignore if */
|
|
@@ -3974,6 +4060,7 @@ var TreeElement = (function () {
|
|
|
3974
4060
|
}
|
|
3975
4061
|
_mouseStart(positionInfo) {
|
|
3976
4062
|
/* istanbul ignore if */
|
|
4063
|
+
// eslint-disable-next-line unicorn/prefer-ternary
|
|
3977
4064
|
if (!this._options.dragAndDrop) {
|
|
3978
4065
|
return false;
|
|
3979
4066
|
}
|
|
@@ -4005,6 +4092,7 @@ var TreeElement = (function () {
|
|
|
4005
4092
|
if (mustSelect) {
|
|
4006
4093
|
this._selectCurrentNode(mustSetFocus);
|
|
4007
4094
|
}
|
|
4095
|
+
this._updateTabStop();
|
|
4008
4096
|
this._triggerEvent("tree.refresh");
|
|
4009
4097
|
}
|
|
4010
4098
|
_saveState() {
|
|
@@ -4012,10 +4100,11 @@ var TreeElement = (function () {
|
|
|
4012
4100
|
}
|
|
4013
4101
|
_selectCurrentNode(mustSetFocus) {
|
|
4014
4102
|
let node = this.getSelectedNode();
|
|
4015
|
-
if (node) {
|
|
4016
|
-
|
|
4017
|
-
nodeElement._select(mustSetFocus);
|
|
4103
|
+
if (!node) {
|
|
4104
|
+
return;
|
|
4018
4105
|
}
|
|
4106
|
+
let nodeElement = this._getNodeElementForNode(node);
|
|
4107
|
+
nodeElement._select(mustSetFocus);
|
|
4019
4108
|
}
|
|
4020
4109
|
|
|
4021
4110
|
// Set initial state, either by restoring the state or auto-opening nodes
|
|
@@ -4024,14 +4113,13 @@ var TreeElement = (function () {
|
|
|
4024
4113
|
let restoreState = () => {
|
|
4025
4114
|
// result: is state restored, must load on demand?
|
|
4026
4115
|
let state = this._saveStateHandler._getStateFromStorage();
|
|
4027
|
-
if (
|
|
4028
|
-
return [false, false];
|
|
4029
|
-
} else {
|
|
4116
|
+
if (state) {
|
|
4030
4117
|
let mustLoadOnDemand = this._saveStateHandler._setInitialState(state);
|
|
4031
4118
|
|
|
4032
4119
|
// return true: the state is restored
|
|
4033
4120
|
return [true, mustLoadOnDemand];
|
|
4034
4121
|
}
|
|
4122
|
+
return [false, false];
|
|
4035
4123
|
};
|
|
4036
4124
|
let autoOpenNodes = () => {
|
|
4037
4125
|
// result: must load on demand?
|
|
@@ -4044,12 +4132,12 @@ var TreeElement = (function () {
|
|
|
4044
4132
|
if (node.load_on_demand) {
|
|
4045
4133
|
mustLoadOnDemand = true;
|
|
4046
4134
|
return false;
|
|
4047
|
-
}
|
|
4048
|
-
|
|
4049
|
-
} else {
|
|
4135
|
+
}
|
|
4136
|
+
if (node.hasChildren()) {
|
|
4050
4137
|
node.is_open = true;
|
|
4051
4138
|
return level !== maxLevel;
|
|
4052
4139
|
}
|
|
4140
|
+
return false;
|
|
4053
4141
|
});
|
|
4054
4142
|
return mustLoadOnDemand;
|
|
4055
4143
|
};
|
|
@@ -4063,50 +4151,12 @@ var TreeElement = (function () {
|
|
|
4063
4151
|
|
|
4064
4152
|
// Set the initial state for nodes that are loaded on demand
|
|
4065
4153
|
async _setInitialStateOnDemand() {
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
void this._saveStateHandler._setInitialStateOnDemand(state).then(() => {
|
|
4073
|
-
resolve();
|
|
4074
|
-
});
|
|
4075
|
-
return true;
|
|
4076
|
-
}
|
|
4077
|
-
};
|
|
4078
|
-
let autoOpenNodes = () => {
|
|
4079
|
-
let maxLevel = this._getAutoOpenMaxLevel();
|
|
4080
|
-
let loadingCount = 0;
|
|
4081
|
-
let loadAndOpenNode = node => {
|
|
4082
|
-
loadingCount += 1;
|
|
4083
|
-
void this.openNode(node, false).then(() => {
|
|
4084
|
-
loadingCount -= 1;
|
|
4085
|
-
openNodes();
|
|
4086
|
-
});
|
|
4087
|
-
};
|
|
4088
|
-
let openNodes = () => {
|
|
4089
|
-
this._tree.iterate((node, level) => {
|
|
4090
|
-
if (node.load_on_demand) {
|
|
4091
|
-
if (!node.is_loading) {
|
|
4092
|
-
loadAndOpenNode(node);
|
|
4093
|
-
}
|
|
4094
|
-
return false;
|
|
4095
|
-
} else {
|
|
4096
|
-
void this.openNode(node, false);
|
|
4097
|
-
return level !== maxLevel;
|
|
4098
|
-
}
|
|
4099
|
-
});
|
|
4100
|
-
if (loadingCount === 0) {
|
|
4101
|
-
resolve();
|
|
4102
|
-
}
|
|
4103
|
-
};
|
|
4104
|
-
openNodes();
|
|
4105
|
-
};
|
|
4106
|
-
if (!restoreState()) {
|
|
4107
|
-
autoOpenNodes();
|
|
4108
|
-
}
|
|
4109
|
-
});
|
|
4154
|
+
let state = this._saveStateHandler._getStateFromStorage();
|
|
4155
|
+
if (state) {
|
|
4156
|
+
await this._saveStateHandler._setInitialStateOnDemand(state);
|
|
4157
|
+
} else {
|
|
4158
|
+
await this._autoOpenNodesOnDemand();
|
|
4159
|
+
}
|
|
4110
4160
|
}
|
|
4111
4161
|
|
|
4112
4162
|
// Set this HTML element to this node in the node map.
|
|
@@ -4116,6 +4166,23 @@ var TreeElement = (function () {
|
|
|
4116
4166
|
_triggerEvent(eventName, values) {
|
|
4117
4167
|
return this._triggerEventProvider(this._htmlElement, eventName, values);
|
|
4118
4168
|
}
|
|
4169
|
+
|
|
4170
|
+
/* Keyboard users reach the tree through the tab stop. The selected node is
|
|
4171
|
+
* the tab stop, see NodeElement.select. Without a selected node, the first
|
|
4172
|
+
* node is the tab stop, so the tree can always be reached.
|
|
4173
|
+
*/
|
|
4174
|
+
_updateTabStop() {
|
|
4175
|
+
let tabIndex = this._options.tabIndex;
|
|
4176
|
+
let previousTabStop = this._fallbackTabStop;
|
|
4177
|
+
let tabStop = tabIndex == null || this._hasRenderedSelectedNode() ? null : this._getFirstTitleSpan();
|
|
4178
|
+
if (previousTabStop && previousTabStop !== tabStop && previousTabStop.getAttribute("aria-selected") !== "true") {
|
|
4179
|
+
previousTabStop.setAttribute("tabindex", "-1");
|
|
4180
|
+
}
|
|
4181
|
+
if (tabStop && tabIndex != null) {
|
|
4182
|
+
tabStop.setAttribute("tabindex", String(tabIndex));
|
|
4183
|
+
}
|
|
4184
|
+
this._fallbackTabStop = tabStop;
|
|
4185
|
+
}
|
|
4119
4186
|
}
|
|
4120
4187
|
|
|
4121
4188
|
return TreeElement;
|