tree-element 0.1.1 → 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 +43 -31
- package/lib/animation.d.ts +2 -2
- package/lib/animation.d.ts.map +1 -1
- package/lib/animation.js +16 -12
- package/lib/animation.js.map +1 -1
- package/lib/classNames.d.ts.map +1 -1
- package/lib/classNames.js +2 -2
- package/lib/classNames.js.map +1 -1
- package/lib/dataLoader.d.ts +1 -0
- package/lib/dataLoader.d.ts.map +1 -1
- package/lib/dataLoader.js +22 -20
- package/lib/dataLoader.js.map +1 -1
- package/lib/dragAndDropHandler/binarySearch.js +3 -3
- package/lib/dragAndDropHandler/binarySearch.js.map +1 -1
- package/lib/dragAndDropHandler/dragElement.d.ts.map +1 -1
- package/lib/dragAndDropHandler/dragElement.js +11 -13
- package/lib/dragAndDropHandler/dragElement.js.map +1 -1
- package/lib/dragAndDropHandler/generateHitAreas.d.ts.map +1 -1
- package/lib/dragAndDropHandler/generateHitAreas.js +25 -25
- package/lib/dragAndDropHandler/generateHitAreas.js.map +1 -1
- package/lib/dragAndDropHandler/index.d.ts.map +1 -1
- package/lib/dragAndDropHandler/index.js +125 -158
- package/lib/dragAndDropHandler/index.js.map +1 -1
- package/lib/dragAndDropHandler/iterateVisibleNodes.d.ts.map +1 -1
- package/lib/dragAndDropHandler/iterateVisibleNodes.js +23 -22
- package/lib/dragAndDropHandler/iterateVisibleNodes.js.map +1 -1
- package/lib/dragAndDropHandler/types.d.ts.map +1 -1
- package/lib/elementsRenderer.d.ts +20 -7
- package/lib/elementsRenderer.d.ts.map +1 -1
- package/lib/elementsRenderer.js +195 -136
- 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 +36 -13
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +386 -349
- package/lib/index.js.map +1 -1
- package/lib/keyHandler.d.ts +13 -8
- package/lib/keyHandler.d.ts.map +1 -1
- package/lib/keyHandler.js +106 -51
- package/lib/keyHandler.js.map +1 -1
- package/lib/methodTypes.d.ts +3 -3
- 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 +36 -49
- package/lib/mouseHandler.js.map +1 -1
- package/lib/mouseUtils.d.ts.map +1 -1
- package/lib/mouseUtils.js +2 -2
- package/lib/mouseUtils.js.map +1 -1
- package/lib/node.d.ts +47 -16
- package/lib/node.d.ts.map +1 -1
- package/lib/node.js +169 -171
- package/lib/node.js.map +1 -1
- package/lib/nodeElement/borderDropHint.d.ts.map +1 -1
- package/lib/nodeElement/borderDropHint.js +4 -5
- package/lib/nodeElement/borderDropHint.js.map +1 -1
- package/lib/nodeElement/folderElement.d.ts +8 -5
- package/lib/nodeElement/folderElement.d.ts.map +1 -1
- package/lib/nodeElement/folderElement.js +75 -67
- package/lib/nodeElement/folderElement.js.map +1 -1
- package/lib/nodeElement/ghostDropHint.d.ts.map +1 -1
- package/lib/nodeElement/ghostDropHint.js +13 -13
- package/lib/nodeElement/ghostDropHint.js.map +1 -1
- package/lib/nodeElement/index.d.ts +2 -1
- package/lib/nodeElement/index.d.ts.map +1 -1
- package/lib/nodeElement/index.js +38 -30
- 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/positionUtils.js +3 -3
- package/lib/positionUtils.js.map +1 -1
- package/lib/requestUrl.d.ts +1 -1
- package/lib/requestUrl.d.ts.map +1 -1
- package/lib/requestUrl.js +6 -17
- package/lib/requestUrl.js.map +1 -1
- package/lib/saveStateHandler.d.ts.map +1 -1
- package/lib/saveStateHandler.js +59 -89
- package/lib/saveStateHandler.js.map +1 -1
- package/lib/scrollHandler/containerScrollParent.d.ts.map +1 -1
- package/lib/scrollHandler/containerScrollParent.js +11 -18
- package/lib/scrollHandler/containerScrollParent.js.map +1 -1
- package/lib/scrollHandler/createScrollParent.d.ts.map +1 -1
- package/lib/scrollHandler/createScrollParent.js +12 -13
- package/lib/scrollHandler/createScrollParent.js.map +1 -1
- package/lib/scrollHandler/documentScrollParent.d.ts.map +1 -1
- package/lib/scrollHandler/documentScrollParent.js +18 -27
- package/lib/scrollHandler/documentScrollParent.js.map +1 -1
- package/lib/scrollHandler/scrollParent.d.ts.map +1 -1
- package/lib/scrollHandler/scrollParent.js +30 -34
- package/lib/scrollHandler/scrollParent.js.map +1 -1
- package/lib/scrollHandler.d.ts.map +1 -1
- package/lib/scrollHandler.js +11 -14
- package/lib/scrollHandler.js.map +1 -1
- package/lib/selectNodeHandler.d.ts +4 -2
- package/lib/selectNodeHandler.d.ts.map +1 -1
- package/lib/selectNodeHandler.js +64 -83
- package/lib/selectNodeHandler.js.map +1 -1
- package/lib/setDefaultOptions.d.ts.map +1 -1
- package/lib/setDefaultOptions.js +34 -38
- package/lib/setDefaultOptions.js.map +1 -1
- package/lib/triggerCustomEvent.d.ts.map +1 -1
- package/lib/triggerCustomEvent.js +2 -2
- package/lib/triggerCustomEvent.js.map +1 -1
- package/lib/util.d.ts.map +1 -1
- package/lib/util.js +2 -2
- 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 +43 -32
- package/src/animation.ts +14 -12
- package/src/classNames.ts +52 -52
- package/src/dataLoader.ts +79 -71
- package/src/dragAndDropHandler/binarySearch.ts +17 -17
- package/src/dragAndDropHandler/dragElement.ts +51 -50
- package/src/dragAndDropHandler/generateHitAreas.ts +156 -161
- package/src/dragAndDropHandler/index.ts +334 -348
- package/src/dragAndDropHandler/iterateVisibleNodes.ts +61 -63
- package/src/dragAndDropHandler/types.ts +5 -5
- package/src/elementsRenderer.ts +377 -294
- package/src/events.ts +241 -208
- package/src/header.txt +1 -1
- package/src/index.ts +259 -229
- package/src/keyHandler.ts +179 -115
- package/src/methodTypes.ts +7 -10
- package/src/mouseHandler.ts +316 -316
- package/src/mouseUtils.ts +14 -14
- package/src/node.ts +773 -771
- package/src/nodeElement/borderDropHint.ts +25 -25
- package/src/nodeElement/folderElement.ts +116 -102
- package/src/nodeElement/ghostDropHint.ts +64 -62
- package/src/nodeElement/index.ts +81 -73
- package/src/nodeUtils.ts +5 -5
- package/src/options.ts +25 -5
- package/src/requestUrl.ts +7 -14
- package/src/saveStateHandler.ts +191 -207
- package/src/scrollHandler/containerScrollParent.ts +40 -49
- package/src/scrollHandler/createScrollParent.ts +26 -27
- package/src/scrollHandler/documentScrollParent.ts +66 -72
- package/src/scrollHandler/scrollParent.ts +90 -86
- package/src/scrollHandler.ts +45 -45
- package/src/selectNodeHandler.ts +171 -165
- package/src/setDefaultOptions.ts +44 -32
- package/src/triggerCustomEvent.ts +7 -3
- package/src/util.ts +2 -3
- package/src/version.ts +1 -1
- package/tree_element.css +87 -69
- package/tree_element.debug.js +3866 -3831
- package/tree_element.debug.js.map +1 -1
- package/tree_element.js +2 -2
- package/tree_element.js.map +1 -1
package/src/options.ts
CHANGED
|
@@ -17,9 +17,13 @@ export type OnCanMoveTo = (
|
|
|
17
17
|
positionName: string,
|
|
18
18
|
) => boolean;
|
|
19
19
|
|
|
20
|
-
export type OnCanSelectNode = (node: Node) => boolean
|
|
20
|
+
export type OnCanSelectNode = (node: Node) => boolean;
|
|
21
21
|
|
|
22
|
-
export type OnCreateLi = (
|
|
22
|
+
export type OnCreateLi = (
|
|
23
|
+
node: Node,
|
|
24
|
+
el: HTMLElement,
|
|
25
|
+
isSelected: boolean,
|
|
26
|
+
) => void;
|
|
23
27
|
|
|
24
28
|
export type OnGetStateFromStorage = (() => string) | undefined;
|
|
25
29
|
|
|
@@ -32,10 +36,25 @@ export interface TreeElementOptions {
|
|
|
32
36
|
* The duration of the slide animation: `"fast"` is 200ms, `"slow"` is
|
|
33
37
|
* 600ms, a number is milliseconds.
|
|
34
38
|
*
|
|
35
|
-
* @defaultValue `"fast"`
|
|
39
|
+
* @defaultValue `"fast"`, or `0` when the user prefers reduced motion
|
|
40
|
+
* (`prefers-reduced-motion: reduce`).
|
|
36
41
|
* @group Appearance
|
|
37
42
|
*/
|
|
38
43
|
animationSpeed: AnimationSpeed;
|
|
44
|
+
/**
|
|
45
|
+
* The accessible name of the tree, set as `aria-label` on the root `ul`.
|
|
46
|
+
* Use `ariaLabelledBy` instead when the name is visible on the page.
|
|
47
|
+
*
|
|
48
|
+
* @group Appearance
|
|
49
|
+
*/
|
|
50
|
+
ariaLabel?: string;
|
|
51
|
+
/**
|
|
52
|
+
* The id of the element that names the tree, set as `aria-labelledby` on
|
|
53
|
+
* the root `ul`.
|
|
54
|
+
*
|
|
55
|
+
* @group Appearance
|
|
56
|
+
*/
|
|
57
|
+
ariaLabelledBy?: string;
|
|
39
58
|
/**
|
|
40
59
|
* Escape node names. With `false`, names are inserted as html — only do
|
|
41
60
|
* that for data you control.
|
|
@@ -125,7 +144,7 @@ export interface TreeElementOptions {
|
|
|
125
144
|
*/
|
|
126
145
|
dragAndDrop: boolean;
|
|
127
146
|
/**
|
|
128
|
-
* Handle the
|
|
147
|
+
* Handle the keyboard when the focus is on the tree. See
|
|
129
148
|
* [Selection](/guide/selection#keyboard-navigation).
|
|
130
149
|
*
|
|
131
150
|
* @defaultValue `true`
|
|
@@ -298,7 +317,8 @@ export interface TreeElementOptions {
|
|
|
298
317
|
startDndDelay?: number;
|
|
299
318
|
/**
|
|
300
319
|
* The `tabindex` of the selected node's title, which is what makes the
|
|
301
|
-
* tree focusable.
|
|
320
|
+
* tree focusable. When no node is selected, the first node gets it. The
|
|
321
|
+
* other nodes get `-1`.
|
|
302
322
|
*
|
|
303
323
|
* @defaultValue `0`
|
|
304
324
|
* @group Selection
|
package/src/requestUrl.ts
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
// Url class for absolute and relative urls.
|
|
2
2
|
|
|
3
3
|
const isAbsoluteUrl = (inputUrl: string) => {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
return true;
|
|
7
|
-
} catch {
|
|
8
|
-
return false;
|
|
9
|
-
}
|
|
10
|
-
}
|
|
4
|
+
return URL.canParse(inputUrl);
|
|
5
|
+
};
|
|
11
6
|
|
|
12
7
|
const LOCALHOST = "http://localhost";
|
|
13
8
|
|
|
@@ -29,13 +24,11 @@ class RequestUrl {
|
|
|
29
24
|
this.url.searchParams.set(key, value);
|
|
30
25
|
}
|
|
31
26
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return this.url.href.slice(LOCALHOST.length);
|
|
37
|
-
}
|
|
27
|
+
value() {
|
|
28
|
+
return this.isAbsolute
|
|
29
|
+
? this.url.href
|
|
30
|
+
: this.url.href.slice(LOCALHOST.length);
|
|
38
31
|
}
|
|
39
32
|
}
|
|
40
33
|
|
|
41
|
-
export default RequestUrl;
|
|
34
|
+
export default RequestUrl;
|
package/src/saveStateHandler.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
AddToSelection,
|
|
3
|
+
GetNodeById,
|
|
4
|
+
GetSelectedNodes,
|
|
5
|
+
GetTree,
|
|
6
|
+
OpenNode,
|
|
7
|
+
RefreshElements,
|
|
8
|
+
RemoveFromSelection,
|
|
9
9
|
} from "./methodTypes";
|
|
10
10
|
import type { Node, NodeId } from "./node";
|
|
11
11
|
import type { OnGetStateFromStorage, OnSetStateFromStorage } from "./options";
|
|
@@ -13,267 +13,251 @@ import type { OnGetStateFromStorage, OnSetStateFromStorage } from "./options";
|
|
|
13
13
|
import { isInt } from "./util";
|
|
14
14
|
|
|
15
15
|
export interface SavedState {
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
open_nodes?: NodeId[];
|
|
17
|
+
selected_node?: NodeId[];
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
interface SaveStateHandlerParams {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
21
|
+
addToSelection: AddToSelection;
|
|
22
|
+
getNodeById: GetNodeById;
|
|
23
|
+
getSelectedNodes: GetSelectedNodes;
|
|
24
|
+
getTree: GetTree;
|
|
25
|
+
onGetStateFromStorage?: OnGetStateFromStorage;
|
|
26
|
+
onSetStateFromStorage?: OnSetStateFromStorage;
|
|
27
|
+
openNode: OpenNode;
|
|
28
|
+
refreshElements: RefreshElements;
|
|
29
|
+
removeFromSelection: RemoveFromSelection;
|
|
30
|
+
saveState: boolean | string;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
export default class SaveStateHandler {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
34
|
+
private addToSelection: AddToSelection;
|
|
35
|
+
private getNodeById: GetNodeById;
|
|
36
|
+
private getSelectedNodes: GetSelectedNodes;
|
|
37
|
+
private getTree: GetTree;
|
|
38
|
+
private onGetStateFromStorage?: OnGetStateFromStorage;
|
|
39
|
+
private onSetStateFromStorage?: OnSetStateFromStorage;
|
|
40
|
+
private openNode: OpenNode;
|
|
41
|
+
private refreshElements: RefreshElements;
|
|
42
|
+
private removeFromSelection: RemoveFromSelection;
|
|
43
|
+
private saveStateOption: boolean | string;
|
|
44
|
+
|
|
45
|
+
constructor({
|
|
46
|
+
addToSelection,
|
|
47
|
+
getNodeById,
|
|
48
|
+
getSelectedNodes,
|
|
49
|
+
getTree,
|
|
50
|
+
onGetStateFromStorage,
|
|
51
|
+
onSetStateFromStorage,
|
|
52
|
+
openNode,
|
|
53
|
+
refreshElements,
|
|
54
|
+
removeFromSelection,
|
|
55
|
+
saveState,
|
|
56
|
+
}: SaveStateHandlerParams) {
|
|
57
|
+
this.addToSelection = addToSelection;
|
|
58
|
+
this.getNodeById = getNodeById;
|
|
59
|
+
this.getSelectedNodes = getSelectedNodes;
|
|
60
|
+
this.getTree = getTree;
|
|
61
|
+
this.onGetStateFromStorage = onGetStateFromStorage;
|
|
62
|
+
this.onSetStateFromStorage = onSetStateFromStorage;
|
|
63
|
+
this.openNode = openNode;
|
|
64
|
+
this.refreshElements = refreshElements;
|
|
65
|
+
this.removeFromSelection = removeFromSelection;
|
|
66
|
+
this.saveStateOption = saveState;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
public getNodeIdToBeSelected(): NodeId | null {
|
|
70
|
+
if (!this.saveStateOption) {
|
|
71
|
+
return null;
|
|
67
72
|
}
|
|
68
73
|
|
|
69
|
-
|
|
70
|
-
if (!this.saveStateOption) {
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
74
|
+
const state = this.getStateFromStorage();
|
|
73
75
|
|
|
74
|
-
|
|
76
|
+
return state?.selected_node ? (state.selected_node[0] ?? null) : null;
|
|
77
|
+
}
|
|
75
78
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
return null;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
79
|
+
public getState(): SavedState {
|
|
80
|
+
const getOpenNodeIds = (): NodeId[] => {
|
|
81
|
+
const openNodes: NodeId[] = [];
|
|
82
82
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
this.getTree()?.iterate((node: Node) => {
|
|
84
|
+
if (node.is_open && node.id && node.hasChildren()) {
|
|
85
|
+
openNodes.push(node.id);
|
|
86
|
+
}
|
|
87
|
+
return true;
|
|
88
|
+
});
|
|
86
89
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
openNodes.push(node.id);
|
|
90
|
-
}
|
|
91
|
-
return true;
|
|
92
|
-
});
|
|
90
|
+
return openNodes;
|
|
91
|
+
};
|
|
93
92
|
|
|
94
|
-
|
|
95
|
-
|
|
93
|
+
const getSelectedNodeIds = (): NodeId[] => {
|
|
94
|
+
const selectedNodeIds: NodeId[] = [];
|
|
96
95
|
|
|
97
|
-
|
|
98
|
-
|
|
96
|
+
for (const node of this.getSelectedNodes()) {
|
|
97
|
+
if (node.id != null) {
|
|
98
|
+
selectedNodeIds.push(node.id);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
99
101
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
selectedNodeIds.push(node.id);
|
|
103
|
-
}
|
|
104
|
-
});
|
|
102
|
+
return selectedNodeIds;
|
|
103
|
+
};
|
|
105
104
|
|
|
106
|
-
|
|
107
|
-
|
|
105
|
+
return {
|
|
106
|
+
open_nodes: getOpenNodeIds(),
|
|
107
|
+
selected_node: getSelectedNodeIds(),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
108
110
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
};
|
|
111
|
+
public getStateFromStorage(): null | SavedState {
|
|
112
|
+
if (!this.saveStateOption) {
|
|
113
|
+
return null;
|
|
113
114
|
}
|
|
114
115
|
|
|
115
|
-
|
|
116
|
-
if (!this.saveStateOption) {
|
|
117
|
-
return null;
|
|
118
|
-
}
|
|
116
|
+
const jsonData = this.loadFromStorage();
|
|
119
117
|
|
|
120
|
-
|
|
118
|
+
return jsonData ? this.parseState(jsonData) : null;
|
|
119
|
+
}
|
|
121
120
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
return null;
|
|
126
|
-
}
|
|
121
|
+
public saveState(): void {
|
|
122
|
+
if (!this.saveStateOption) {
|
|
123
|
+
return;
|
|
127
124
|
}
|
|
128
125
|
|
|
129
|
-
|
|
130
|
-
if (!this.saveStateOption) {
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
126
|
+
const state = JSON.stringify(this.getState());
|
|
133
127
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
} else {
|
|
139
|
-
localStorage.setItem(this.getKeyName(), state);
|
|
140
|
-
}
|
|
128
|
+
if (this.onSetStateFromStorage) {
|
|
129
|
+
this.onSetStateFromStorage(state);
|
|
130
|
+
} else {
|
|
131
|
+
localStorage.setItem(this.getKeyName(), state);
|
|
141
132
|
}
|
|
133
|
+
}
|
|
142
134
|
|
|
143
|
-
|
|
135
|
+
/*
|
|
144
136
|
Set initial state
|
|
145
137
|
Don't handle nodes that are loaded on demand
|
|
146
138
|
|
|
147
139
|
result: must load on demand (boolean)
|
|
148
140
|
*/
|
|
149
|
-
|
|
150
|
-
|
|
141
|
+
public setInitialState(state: SavedState): boolean {
|
|
142
|
+
const mustLoadOnDemand = state.open_nodes
|
|
143
|
+
? this.openInitialNodes(state.open_nodes)
|
|
144
|
+
: false;
|
|
151
145
|
|
|
152
|
-
|
|
153
|
-
mustLoadOnDemand = this.openInitialNodes(state.open_nodes);
|
|
154
|
-
}
|
|
146
|
+
this.resetSelection();
|
|
155
147
|
|
|
156
|
-
|
|
148
|
+
if (state.selected_node) {
|
|
149
|
+
this.selectInitialNodes(state.selected_node);
|
|
150
|
+
}
|
|
157
151
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}
|
|
152
|
+
return mustLoadOnDemand;
|
|
153
|
+
}
|
|
161
154
|
|
|
162
|
-
|
|
163
|
-
|
|
155
|
+
public async setInitialStateOnDemand(state: SavedState): Promise<void> {
|
|
156
|
+
let nodeIds = state.open_nodes;
|
|
164
157
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
158
|
+
const openNodes = async () => {
|
|
159
|
+
if (!nodeIds) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
169
162
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
163
|
+
const newNodesIds = [];
|
|
164
|
+
|
|
165
|
+
for (const nodeId of nodeIds) {
|
|
166
|
+
const node = this.getNodeById(nodeId);
|
|
174
167
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
newNodesIds.push(nodeId);
|
|
182
|
-
} else {
|
|
183
|
-
if (!node.is_loading) {
|
|
184
|
-
if (node.load_on_demand) {
|
|
185
|
-
await loadAndOpenNode(node);
|
|
186
|
-
} else {
|
|
187
|
-
await this.openNode(node, false);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}
|
|
168
|
+
if (node) {
|
|
169
|
+
if (!node.is_loading) {
|
|
170
|
+
if (node.load_on_demand) {
|
|
171
|
+
await loadAndOpenNode(node);
|
|
172
|
+
} else {
|
|
173
|
+
await this.openNode(node, false);
|
|
191
174
|
}
|
|
175
|
+
}
|
|
176
|
+
} else {
|
|
177
|
+
newNodesIds.push(nodeId);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
192
180
|
|
|
193
|
-
|
|
181
|
+
nodeIds = newNodesIds;
|
|
194
182
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
}
|
|
200
|
-
};
|
|
183
|
+
if (state.selected_node && this.selectInitialNodes(state.selected_node)) {
|
|
184
|
+
this.refreshElements(null);
|
|
185
|
+
}
|
|
186
|
+
};
|
|
201
187
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
188
|
+
const loadAndOpenNode = async (node: Node) => {
|
|
189
|
+
await this.openNode(node, false);
|
|
190
|
+
await openNodes();
|
|
191
|
+
};
|
|
206
192
|
|
|
207
|
-
|
|
208
|
-
|
|
193
|
+
await openNodes();
|
|
194
|
+
}
|
|
209
195
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
}
|
|
216
|
-
}
|
|
196
|
+
private getKeyName(): string {
|
|
197
|
+
return typeof this.saveStateOption === "string"
|
|
198
|
+
? this.saveStateOption
|
|
199
|
+
: "tree";
|
|
200
|
+
}
|
|
217
201
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
}
|
|
224
|
-
}
|
|
202
|
+
private loadFromStorage(): null | string {
|
|
203
|
+
return this.onGetStateFromStorage
|
|
204
|
+
? this.onGetStateFromStorage()
|
|
205
|
+
: localStorage.getItem(this.getKeyName());
|
|
206
|
+
}
|
|
225
207
|
|
|
226
|
-
|
|
227
|
-
|
|
208
|
+
private openInitialNodes(nodeIds: NodeId[]): boolean {
|
|
209
|
+
let mustLoadOnDemand = false;
|
|
228
210
|
|
|
229
|
-
|
|
230
|
-
|
|
211
|
+
for (const nodeId of nodeIds) {
|
|
212
|
+
const node = this.getNodeById(nodeId);
|
|
231
213
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
}
|
|
238
|
-
}
|
|
214
|
+
if (node) {
|
|
215
|
+
if (node.load_on_demand) {
|
|
216
|
+
mustLoadOnDemand = true;
|
|
217
|
+
} else {
|
|
218
|
+
node.is_open = true;
|
|
239
219
|
}
|
|
240
|
-
|
|
241
|
-
return mustLoadOnDemand;
|
|
220
|
+
}
|
|
242
221
|
}
|
|
243
222
|
|
|
244
|
-
|
|
245
|
-
|
|
223
|
+
return mustLoadOnDemand;
|
|
224
|
+
}
|
|
246
225
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
// Convert to array
|
|
250
|
-
state.selected_node = [state.selected_node];
|
|
251
|
-
}
|
|
226
|
+
private parseState(jsonData: string): SavedState {
|
|
227
|
+
const state = JSON.parse(jsonData) as Record<string, unknown>;
|
|
252
228
|
|
|
253
|
-
|
|
229
|
+
// Check if selected_node is an int (instead of an array)
|
|
230
|
+
if (state.selected_node && isInt(state.selected_node)) {
|
|
231
|
+
// Convert to array
|
|
232
|
+
state.selected_node = [state.selected_node];
|
|
254
233
|
}
|
|
255
234
|
|
|
256
|
-
|
|
257
|
-
|
|
235
|
+
return state;
|
|
236
|
+
}
|
|
258
237
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
238
|
+
private resetSelection(): void {
|
|
239
|
+
const selectedNodes = this.getSelectedNodes();
|
|
240
|
+
|
|
241
|
+
for (const node of selectedNodes) {
|
|
242
|
+
this.removeFromSelection(node);
|
|
262
243
|
}
|
|
244
|
+
}
|
|
263
245
|
|
|
264
|
-
|
|
265
|
-
|
|
246
|
+
private selectInitialNodes(nodeIds: NodeId[]): boolean {
|
|
247
|
+
let selectCount = 0;
|
|
266
248
|
|
|
267
|
-
|
|
268
|
-
|
|
249
|
+
for (const nodeId of nodeIds) {
|
|
250
|
+
const node = this.getNodeById(nodeId);
|
|
269
251
|
|
|
270
|
-
|
|
271
|
-
|
|
252
|
+
if (!node) {
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
272
255
|
|
|
273
|
-
|
|
274
|
-
}
|
|
275
|
-
}
|
|
256
|
+
selectCount += 1;
|
|
276
257
|
|
|
277
|
-
|
|
258
|
+
this.addToSelection(node);
|
|
278
259
|
}
|
|
260
|
+
|
|
261
|
+
return selectCount !== 0;
|
|
262
|
+
}
|
|
279
263
|
}
|
|
@@ -1,71 +1,62 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
HorizontalScrollDirection,
|
|
3
|
+
VerticalScrollDirection,
|
|
4
4
|
} from "./scrollParent";
|
|
5
5
|
|
|
6
6
|
import { getElementPosition, getOffsetTop } from "../positionUtils";
|
|
7
7
|
import { ScrollParent } from "./scrollParent";
|
|
8
8
|
|
|
9
|
-
|
|
10
9
|
export default class ContainerScrollParent extends ScrollParent {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
public stopScrolling() {
|
|
15
|
-
super.stopScrolling();
|
|
10
|
+
private scrollParentBottom?: number;
|
|
11
|
+
private scrollParentTop?: number;
|
|
16
12
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
13
|
+
public stopScrolling() {
|
|
14
|
+
super.stopScrolling();
|
|
20
15
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const scrollParentOffset = getElementPosition(this.container);
|
|
25
|
-
const containerWidth = this.container.getBoundingClientRect().width;
|
|
16
|
+
this.horizontalScrollDirection = undefined;
|
|
17
|
+
this.verticalScrollDirection = undefined;
|
|
18
|
+
}
|
|
26
19
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
20
|
+
protected getNewHorizontalScrollDirection(
|
|
21
|
+
pageX: number,
|
|
22
|
+
): HorizontalScrollDirection | undefined {
|
|
23
|
+
const scrollParentOffset = getElementPosition(this.container);
|
|
24
|
+
const containerWidth = this.container.getBoundingClientRect().width;
|
|
31
25
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return "left";
|
|
36
|
-
}
|
|
26
|
+
const rightEdge = scrollParentOffset.left + containerWidth;
|
|
27
|
+
const leftEdge = scrollParentOffset.left;
|
|
28
|
+
const isNearRightEdge = pageX > rightEdge - 20;
|
|
37
29
|
|
|
38
|
-
|
|
30
|
+
if (isNearRightEdge) {
|
|
31
|
+
return "right";
|
|
39
32
|
}
|
|
40
33
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
if (pageY < this.getScrollParentTop()) {
|
|
45
|
-
return "top";
|
|
46
|
-
}
|
|
34
|
+
const isNearLeftEdge = pageX < leftEdge + 20;
|
|
35
|
+
return isNearLeftEdge ? "left" : undefined;
|
|
36
|
+
}
|
|
47
37
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
38
|
+
protected getNewVerticalScrollDirection(
|
|
39
|
+
pageY: number,
|
|
40
|
+
): undefined | VerticalScrollDirection {
|
|
41
|
+
if (pageY < this.getScrollParentTop()) {
|
|
42
|
+
return "top";
|
|
53
43
|
}
|
|
54
44
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const containerHeight =
|
|
58
|
-
this.container.getBoundingClientRect().height;
|
|
59
|
-
this.scrollParentBottom =
|
|
60
|
-
this.getScrollParentTop() + containerHeight;
|
|
61
|
-
}
|
|
45
|
+
return pageY > this.getScrollParentBottom() ? "bottom" : undefined;
|
|
46
|
+
}
|
|
62
47
|
|
|
63
|
-
|
|
48
|
+
private getScrollParentBottom() {
|
|
49
|
+
if (this.scrollParentBottom == null) {
|
|
50
|
+
const containerHeight = this.container.getBoundingClientRect().height;
|
|
51
|
+
this.scrollParentBottom = this.getScrollParentTop() + containerHeight;
|
|
64
52
|
}
|
|
65
53
|
|
|
66
|
-
|
|
67
|
-
|
|
54
|
+
return this.scrollParentBottom;
|
|
55
|
+
}
|
|
68
56
|
|
|
69
|
-
|
|
70
|
-
|
|
57
|
+
private getScrollParentTop() {
|
|
58
|
+
this.scrollParentTop ??= getOffsetTop(this.container);
|
|
59
|
+
|
|
60
|
+
return this.scrollParentTop;
|
|
61
|
+
}
|
|
71
62
|
}
|