jqtree 1.9.0 → 2.0.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/bower.json +1 -1
- package/js-coverage/coverage-final.json +13 -0
- package/lib/jqtreeOptions.js +1 -0
- package/lib/tree.jquery.d.js +0 -0
- package/lib/tree.jquery.js +394 -0
- package/lib/triggerJQueryEvent.js +68 -0
- package/lib/typings.d.js +1 -0
- package/lib/version.js +2 -0
- package/package.json +34 -29
- package/pnpm-workspace.yaml +3 -3
- package/src/jqtreeOptions.ts +20 -62
- package/src/tree.jquery.d.ts +81 -92
- package/src/tree.jquery.ts +234 -938
- package/src/triggerJQueryEvent.ts +97 -0
- package/src/version.ts +2 -2
- package/tree.jquery.debug.js +4226 -3281
- package/tree.jquery.debug.js.map +1 -1
- package/tree.jquery.js +22 -2
- package/tree.jquery.js.map +1 -1
- package/eslint.config.mjs +0 -112
- package/src/animation.ts +0 -48
- package/src/dataLoader.ts +0 -143
- package/src/dragAndDropHandler/binarySearch.ts +0 -27
- package/src/dragAndDropHandler/dragElement.ts +0 -54
- package/src/dragAndDropHandler/generateHitAreas.ts +0 -195
- package/src/dragAndDropHandler/index.ts +0 -432
- package/src/dragAndDropHandler/iterateVisibleNodes.ts +0 -91
- package/src/dragAndDropHandler/types.ts +0 -12
- package/src/elementsRenderer.ts +0 -359
- package/src/jqtreeMethodTypes.ts +0 -40
- package/src/keyHandler.ts +0 -139
- package/src/mouseHandler.ts +0 -383
- package/src/mouseUtils.ts +0 -23
- package/src/node.ts +0 -653
- package/src/nodeElement/borderDropHint.ts +0 -32
- package/src/nodeElement/folderElement.ts +0 -138
- package/src/nodeElement/ghostDropHint.ts +0 -74
- package/src/nodeElement/index.ts +0 -94
- package/src/nodeUtils.ts +0 -10
- package/src/positionUtils.ts +0 -18
- package/src/saveStateHandler.ts +0 -276
- package/src/scrollHandler/containerScrollParent.ts +0 -71
- package/src/scrollHandler/createScrollParent.ts +0 -51
- package/src/scrollHandler/documentScrollParent.ts +0 -104
- package/src/scrollHandler/scrollParent.ts +0 -117
- package/src/scrollHandler.ts +0 -55
- package/src/selectNodeHandler.ts +0 -111
- package/src/simple.widget.ts +0 -134
- package/src/util.ts +0 -5
package/src/tree.jquery.ts
CHANGED
|
@@ -1,97 +1,49 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
import type {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
import DataLoader from "./dataLoader";
|
|
9
|
-
import { DragAndDropHandler } from "./dragAndDropHandler";
|
|
10
|
-
import ElementsRenderer from "./elementsRenderer";
|
|
11
|
-
import KeyHandler from "./keyHandler";
|
|
12
|
-
import MouseHandler from "./mouseHandler";
|
|
13
|
-
import { Node } from "./node";
|
|
14
|
-
import NodeElement from "./nodeElement";
|
|
15
|
-
import FolderElement from "./nodeElement/folderElement";
|
|
16
|
-
import { getOffsetTop } from "./positionUtils";
|
|
17
|
-
import SaveStateHandler from "./saveStateHandler";
|
|
18
|
-
import ScrollHandler from "./scrollHandler";
|
|
19
|
-
import SelectNodeHandler from "./selectNodeHandler";
|
|
20
|
-
import SimpleWidget from "./simple.widget";
|
|
1
|
+
import type { Node, NodeData, NodeId, Position, SavedState, SelectNodeOptions, TreeElementOptions } from "tree-element"
|
|
2
|
+
|
|
3
|
+
import TreeElement from "tree-element";
|
|
4
|
+
|
|
5
|
+
import type { JQTreeIconElement, JQTreeOptions } from "./jqtreeOptions";
|
|
6
|
+
|
|
7
|
+
import triggerJQueryEvent from "./triggerJQueryEvent";
|
|
21
8
|
import __version__ from "./version";
|
|
22
9
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
10
|
+
type IconElement = HTMLElement | string
|
|
11
|
+
|
|
12
|
+
interface LoadFailedEvent {
|
|
13
|
+
response: Response;
|
|
26
14
|
}
|
|
27
15
|
|
|
16
|
+
interface LoadingDataEvent {
|
|
17
|
+
$el: JQuery;
|
|
18
|
+
isLoading: boolean;
|
|
19
|
+
node: Node | null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
type OnCreateLi = (node: Node, el: HTMLElement, isSelected: boolean) => void;
|
|
23
|
+
type OnFinishOpenNode = (node: Node) => void;
|
|
24
|
+
type OnIsMoveHandle = (el: HTMLElement) => boolean;
|
|
25
|
+
|
|
28
26
|
const NODE_PARAM_IS_EMPTY = "Node parameter is empty";
|
|
29
27
|
const PARAM_IS_EMPTY = "Parameter is empty: ";
|
|
30
28
|
|
|
31
|
-
export class JqTreeWidget
|
|
32
|
-
|
|
33
|
-
animationSpeed: "fast",
|
|
34
|
-
autoEscape: true,
|
|
35
|
-
autoOpen: false, // true / false / int (open n levels starting at 0)
|
|
36
|
-
buttonLeft: true,
|
|
37
|
-
// The symbol to use for a closed node - ► BLACK RIGHT-POINTING POINTER
|
|
38
|
-
// http://www.fileformat.info/info/unicode/char/25ba/index.htm
|
|
39
|
-
closedIcon: undefined,
|
|
40
|
-
data: undefined,
|
|
41
|
-
dataFilter: undefined,
|
|
42
|
-
dataUrl: undefined,
|
|
43
|
-
dragAndDrop: false,
|
|
44
|
-
keyboardSupport: true,
|
|
45
|
-
nodeClass: Node,
|
|
46
|
-
onCanMove: undefined, // Can this node be moved?
|
|
47
|
-
onCanMoveTo: undefined, // Can this node be moved to this position? function(moved_node, target_node, position)
|
|
48
|
-
onCanSelectNode: undefined,
|
|
49
|
-
onCreateLi: undefined,
|
|
50
|
-
onDragMove: undefined,
|
|
51
|
-
onDragStop: undefined,
|
|
52
|
-
onGetStateFromStorage: undefined,
|
|
53
|
-
onIsMoveHandle: undefined,
|
|
54
|
-
onLoadFailed: undefined,
|
|
55
|
-
onLoading: undefined,
|
|
56
|
-
onSetStateFromStorage: undefined,
|
|
57
|
-
openedIcon: "▼",
|
|
58
|
-
openFolderDelay: 500, // The delay for opening a folder during drag and drop; the value is in milliseconds
|
|
59
|
-
// The symbol to use for an open node - ▼ BLACK DOWN-POINTING TRIANGLE
|
|
60
|
-
// http://www.fileformat.info/info/unicode/char/25bc/index.htm
|
|
61
|
-
rtl: undefined, // right-to-left support; true / false (default)
|
|
62
|
-
saveState: false, // true / false / string (cookie name)
|
|
63
|
-
selectable: true,
|
|
64
|
-
showEmptyFolder: false,
|
|
65
|
-
slide: true, // must display slide animation?
|
|
66
|
-
startDndDelay: 300, // The delay for starting dnd (in milliseconds)
|
|
67
|
-
tabIndex: 0,
|
|
68
|
-
useContextMenu: true,
|
|
69
|
-
};
|
|
29
|
+
export class JqTreeWidget {
|
|
30
|
+
[key: string]: unknown;
|
|
70
31
|
|
|
71
|
-
private _dataLoader: DataLoader;
|
|
72
|
-
private _dndHandler: DragAndDropHandler;
|
|
73
32
|
private _element: JQuery;
|
|
74
|
-
private
|
|
75
|
-
private
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
private _tree: Node;
|
|
33
|
+
private _inputOptions: Partial<JQTreeOptions>;
|
|
34
|
+
private _treeElement: TreeElement;
|
|
35
|
+
|
|
36
|
+
constructor(el: HTMLElement, options: Partial<JQTreeOptions>) {
|
|
37
|
+
this._element = jQuery(el);
|
|
38
|
+
|
|
39
|
+
this._inputOptions = options;
|
|
40
|
+
}
|
|
83
41
|
|
|
84
42
|
public addNodeAfter(
|
|
85
43
|
newNodeInfo: NodeData,
|
|
86
44
|
existingNode: Node,
|
|
87
45
|
): Node | null {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
if (newNode) {
|
|
91
|
-
this._refreshElements(existingNode.parent);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return newNode;
|
|
46
|
+
return this._treeElement.addNodeAfter(newNodeInfo, existingNode);
|
|
95
47
|
}
|
|
96
48
|
|
|
97
49
|
public addNodeBefore(
|
|
@@ -102,13 +54,7 @@ export class JqTreeWidget extends SimpleWidget<JQTreeOptions> {
|
|
|
102
54
|
throw Error(PARAM_IS_EMPTY + "existingNode");
|
|
103
55
|
}
|
|
104
56
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
if (newNode) {
|
|
108
|
-
this._refreshElements(existingNode.parent);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
return newNode;
|
|
57
|
+
return this._treeElement.addNodeBefore(newNodeInfo, existingNode);
|
|
112
58
|
}
|
|
113
59
|
|
|
114
60
|
public addParentNode(
|
|
@@ -119,13 +65,7 @@ export class JqTreeWidget extends SimpleWidget<JQTreeOptions> {
|
|
|
119
65
|
throw Error(PARAM_IS_EMPTY + "existingNode");
|
|
120
66
|
}
|
|
121
67
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
if (newNode) {
|
|
125
|
-
this._refreshElements(newNode.parent);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
return newNode;
|
|
68
|
+
return this._treeElement.addParentNode(newNodeInfo, existingNode);
|
|
129
69
|
}
|
|
130
70
|
|
|
131
71
|
public addToSelection(node?: Node, mustSetFocus?: boolean): JQuery {
|
|
@@ -133,24 +73,14 @@ export class JqTreeWidget extends SimpleWidget<JQTreeOptions> {
|
|
|
133
73
|
throw Error(NODE_PARAM_IS_EMPTY);
|
|
134
74
|
}
|
|
135
75
|
|
|
136
|
-
this.
|
|
137
|
-
this._openParents(node);
|
|
138
|
-
|
|
139
|
-
this._getNodeElementForNode(node).select(mustSetFocus ?? true);
|
|
140
|
-
|
|
141
|
-
this._saveState();
|
|
142
|
-
|
|
76
|
+
this._treeElement.addToSelection(node, mustSetFocus);
|
|
143
77
|
return this._element;
|
|
144
78
|
}
|
|
145
79
|
|
|
146
80
|
public appendNode(newNodeInfo: NodeData, parentNodeParam?: Node): Node {
|
|
147
|
-
const parentNode = parentNodeParam ?? this.
|
|
81
|
+
const parentNode = parentNodeParam ?? this._treeElement.tree;
|
|
148
82
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
this._refreshElements(parentNode);
|
|
152
|
-
|
|
153
|
-
return node;
|
|
83
|
+
return this._treeElement.appendNode(newNodeInfo, parentNode);
|
|
154
84
|
}
|
|
155
85
|
|
|
156
86
|
public closeNode(node?: Node, slideParam?: boolean | null): JQuery {
|
|
@@ -158,34 +88,22 @@ export class JqTreeWidget extends SimpleWidget<JQTreeOptions> {
|
|
|
158
88
|
throw Error(NODE_PARAM_IS_EMPTY);
|
|
159
89
|
}
|
|
160
90
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
if (node.isFolder() || node.isEmptyFolder) {
|
|
164
|
-
this._createFolderElement(node).close(
|
|
165
|
-
slide,
|
|
166
|
-
this.options.animationSpeed,
|
|
167
|
-
);
|
|
168
|
-
|
|
169
|
-
this._saveState();
|
|
170
|
-
}
|
|
91
|
+
this._treeElement.closeNode(node, slideParam ?? undefined);
|
|
171
92
|
|
|
172
93
|
return this._element;
|
|
173
94
|
}
|
|
174
95
|
|
|
175
96
|
public deinit(): void {
|
|
176
|
-
this._htmlElement.textContent = "";
|
|
177
97
|
this._element.off();
|
|
98
|
+
this._treeElement.deinit();
|
|
99
|
+
}
|
|
178
100
|
|
|
179
|
-
|
|
180
|
-
this.
|
|
181
|
-
|
|
182
|
-
this._tree = new Node({}, true);
|
|
183
|
-
|
|
184
|
-
super.deinit();
|
|
101
|
+
public destroy(): void {
|
|
102
|
+
this.deinit();
|
|
185
103
|
}
|
|
186
104
|
|
|
187
105
|
public getNodeByCallback(callback: (node: Node) => boolean): Node | null {
|
|
188
|
-
return this.
|
|
106
|
+
return this._treeElement.getNodeByCallback(callback);
|
|
189
107
|
}
|
|
190
108
|
|
|
191
109
|
public getNodeByHtmlElement(
|
|
@@ -200,43 +118,43 @@ export class JqTreeWidget extends SimpleWidget<JQTreeOptions> {
|
|
|
200
118
|
return null;
|
|
201
119
|
}
|
|
202
120
|
|
|
203
|
-
return this.
|
|
121
|
+
return this._treeElement.getNode(element);
|
|
204
122
|
}
|
|
205
123
|
|
|
206
124
|
public getNodeById(nodeId: NodeId): Node | null {
|
|
207
|
-
return this.
|
|
125
|
+
return this._treeElement.getNodeById(nodeId);
|
|
208
126
|
}
|
|
209
127
|
|
|
210
128
|
public getNodeByName(name: string): Node | null {
|
|
211
|
-
return this.
|
|
129
|
+
return this._treeElement.getNodeByName(name);
|
|
212
130
|
}
|
|
213
131
|
|
|
214
132
|
public getNodeByNameMustExist(name: string): Node {
|
|
215
|
-
return this.
|
|
133
|
+
return this._treeElement.getNodeByNameMustExist(name);
|
|
216
134
|
}
|
|
217
135
|
|
|
218
136
|
public getNodesByProperty(key: string, value: unknown): Node[] {
|
|
219
|
-
return this.
|
|
137
|
+
return this._treeElement.getNodesByProperty(key, value);
|
|
220
138
|
}
|
|
221
139
|
|
|
222
140
|
public getSelectedNode(): false | Node {
|
|
223
|
-
return this.
|
|
141
|
+
return this._treeElement.getSelectedNode();
|
|
224
142
|
}
|
|
225
143
|
|
|
226
144
|
public getSelectedNodes(): Node[] {
|
|
227
|
-
return this.
|
|
145
|
+
return this._treeElement.getSelectedNodes();
|
|
228
146
|
}
|
|
229
147
|
|
|
230
148
|
public getState(): null | SavedState {
|
|
231
|
-
return this.
|
|
149
|
+
return this._treeElement.getState();
|
|
232
150
|
}
|
|
233
151
|
|
|
234
152
|
public getStateFromStorage(): null | SavedState {
|
|
235
|
-
return this.
|
|
153
|
+
return this._treeElement.getStateFromStorage();
|
|
236
154
|
}
|
|
237
155
|
|
|
238
156
|
public getTree(): Node {
|
|
239
|
-
return this.
|
|
157
|
+
return this._treeElement.getTree();
|
|
240
158
|
}
|
|
241
159
|
|
|
242
160
|
public getVersion(): string {
|
|
@@ -244,25 +162,29 @@ export class JqTreeWidget extends SimpleWidget<JQTreeOptions> {
|
|
|
244
162
|
}
|
|
245
163
|
|
|
246
164
|
public init(): void {
|
|
247
|
-
|
|
165
|
+
const htmlElement = this._element.get(0) as HTMLElement;
|
|
248
166
|
|
|
249
|
-
this._element
|
|
250
|
-
this.
|
|
251
|
-
this._isInitialized = false;
|
|
167
|
+
this._element.on("tree.loading_data", this._handleLoadingDataEvent.bind(this));
|
|
168
|
+
this._element.on("tree.load_failed", this._handleLoadFailedEvent.bind(this));
|
|
252
169
|
|
|
253
|
-
|
|
170
|
+
const options = this._transformInputOptions();
|
|
254
171
|
|
|
255
|
-
const
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
172
|
+
const treeElement = new TreeElement(
|
|
173
|
+
{
|
|
174
|
+
...options,
|
|
175
|
+
classPrefix: "jqtree",
|
|
176
|
+
commonClassName: "jqtree_common",
|
|
177
|
+
htmlElement,
|
|
178
|
+
overrideTriggerEventProvider: triggerJQueryEvent,
|
|
179
|
+
treeClassName: "jqtree-tree"
|
|
180
|
+
}
|
|
181
|
+
);
|
|
259
182
|
|
|
260
|
-
this.
|
|
261
|
-
this._initData();
|
|
183
|
+
this._treeElement = treeElement;
|
|
262
184
|
}
|
|
263
185
|
|
|
264
186
|
public isDragging(): boolean {
|
|
265
|
-
return this.
|
|
187
|
+
return this._treeElement.isDragging();
|
|
266
188
|
}
|
|
267
189
|
|
|
268
190
|
public isNodeSelected(node?: Node): boolean {
|
|
@@ -270,11 +192,11 @@ export class JqTreeWidget extends SimpleWidget<JQTreeOptions> {
|
|
|
270
192
|
throw Error(NODE_PARAM_IS_EMPTY);
|
|
271
193
|
}
|
|
272
194
|
|
|
273
|
-
return this.
|
|
195
|
+
return this._treeElement.isNodeSelected(node);
|
|
274
196
|
}
|
|
275
197
|
|
|
276
|
-
public loadData(data: NodeData[], parentNode
|
|
277
|
-
this.
|
|
198
|
+
public loadData(data: NodeData[], parentNode?: Node): JQuery {
|
|
199
|
+
this._treeElement.loadData(data, parentNode);
|
|
278
200
|
return this._element;
|
|
279
201
|
}
|
|
280
202
|
|
|
@@ -285,7 +207,7 @@ export class JqTreeWidget extends SimpleWidget<JQTreeOptions> {
|
|
|
285
207
|
loadDataFromUrl('/my_data', node1);
|
|
286
208
|
loadDataFromUrl('/my_data', node1, function() { console.log('finished'); });
|
|
287
209
|
loadDataFromUrl('/my_data', null, function() { console.log('finished'); });
|
|
288
|
-
|
|
210
|
+
|
|
289
211
|
- loadDataFromUrl(parent_node=null, on_finished=null)
|
|
290
212
|
loadDataFromUrl();
|
|
291
213
|
loadDataFromUrl(node1);
|
|
@@ -293,34 +215,41 @@ export class JqTreeWidget extends SimpleWidget<JQTreeOptions> {
|
|
|
293
215
|
loadDataFromUrl(node1, function() { console.log('finished'); });
|
|
294
216
|
*/
|
|
295
217
|
public loadDataFromUrl(
|
|
296
|
-
param1
|
|
297
|
-
param2?:
|
|
298
|
-
param3?:
|
|
218
|
+
param1?: Node | string,
|
|
219
|
+
param2?: (() => void) | Node,
|
|
220
|
+
param3?: () => void,
|
|
299
221
|
): JQuery {
|
|
222
|
+
let parentNode: Node | undefined;
|
|
223
|
+
let onFinishedLoading: (() => void) | undefined;
|
|
224
|
+
let url: string | undefined;
|
|
225
|
+
|
|
226
|
+
// first parameter is url
|
|
300
227
|
if (typeof param1 === "string") {
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
param3 ?? null,
|
|
306
|
-
);
|
|
228
|
+
url = param1;
|
|
229
|
+
parentNode = param2 as (Node | undefined);
|
|
230
|
+
onFinishedLoading = param3;
|
|
231
|
+
|
|
307
232
|
} else {
|
|
308
233
|
// first parameter is not url
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
param1,
|
|
312
|
-
param2 as HandleFinishedLoading | null,
|
|
313
|
-
);
|
|
234
|
+
parentNode = param1;
|
|
235
|
+
onFinishedLoading = param2 as (() => void) | undefined;
|
|
314
236
|
}
|
|
315
237
|
|
|
238
|
+
this._treeElement.loadDataFromUrl(url, parentNode)
|
|
239
|
+
.then(() => {
|
|
240
|
+
if (onFinishedLoading) {
|
|
241
|
+
onFinishedLoading();
|
|
242
|
+
}
|
|
243
|
+
})
|
|
244
|
+
.catch((error: unknown) => {
|
|
245
|
+
throw error;
|
|
246
|
+
});
|
|
247
|
+
|
|
316
248
|
return this._element;
|
|
317
249
|
}
|
|
318
250
|
|
|
319
251
|
public moveDown(): JQuery {
|
|
320
|
-
|
|
321
|
-
if (selectedNode) {
|
|
322
|
-
this._keyHandler.moveDown(selectedNode);
|
|
323
|
-
}
|
|
252
|
+
this._treeElement.moveDown();
|
|
324
253
|
|
|
325
254
|
return this._element;
|
|
326
255
|
}
|
|
@@ -342,18 +271,13 @@ export class JqTreeWidget extends SimpleWidget<JQTreeOptions> {
|
|
|
342
271
|
throw Error(PARAM_IS_EMPTY + "position");
|
|
343
272
|
}
|
|
344
273
|
|
|
345
|
-
this.
|
|
346
|
-
this._refreshElements(null);
|
|
274
|
+
this._treeElement.moveNode(node, targetNode, position);
|
|
347
275
|
|
|
348
276
|
return this._element;
|
|
349
277
|
}
|
|
350
278
|
|
|
351
279
|
public moveUp(): JQuery {
|
|
352
|
-
|
|
353
|
-
if (selectedNode) {
|
|
354
|
-
this._keyHandler.moveUp(selectedNode);
|
|
355
|
-
}
|
|
356
|
-
|
|
280
|
+
this._treeElement.moveUp();
|
|
357
281
|
return this._element;
|
|
358
282
|
}
|
|
359
283
|
|
|
@@ -366,46 +290,45 @@ export class JqTreeWidget extends SimpleWidget<JQTreeOptions> {
|
|
|
366
290
|
throw Error(NODE_PARAM_IS_EMPTY);
|
|
367
291
|
}
|
|
368
292
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
let slide: boolean | null;
|
|
293
|
+
let onFinished: null | OnFinishOpenNode = null;
|
|
294
|
+
let slide: boolean | undefined;
|
|
372
295
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
slide ??= this.options.slide;
|
|
382
|
-
|
|
383
|
-
return [slide, onFinished];
|
|
384
|
-
};
|
|
385
|
-
|
|
386
|
-
const [slide, onFinished] = parseParams();
|
|
296
|
+
if (typeof param1 === "function") {
|
|
297
|
+
onFinished = param1;
|
|
298
|
+
slide = param2 as boolean | undefined;
|
|
299
|
+
} else {
|
|
300
|
+
slide = param1;
|
|
301
|
+
}
|
|
387
302
|
|
|
388
|
-
this.
|
|
303
|
+
void this._treeElement.openNode(node, slide).then(() => {
|
|
304
|
+
if (onFinished) {
|
|
305
|
+
onFinished(node);
|
|
306
|
+
}
|
|
307
|
+
});
|
|
389
308
|
return this._element;
|
|
390
309
|
}
|
|
391
310
|
|
|
392
311
|
public prependNode(newNodeInfo: NodeData, parentNodeParam?: Node): Node {
|
|
393
|
-
const parentNode = parentNodeParam ?? this.
|
|
312
|
+
const parentNode = parentNodeParam ?? this._treeElement.tree;
|
|
394
313
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
this._refreshElements(parentNode);
|
|
398
|
-
|
|
399
|
-
return node;
|
|
314
|
+
return this._treeElement.prependNode(newNodeInfo, parentNode);
|
|
400
315
|
}
|
|
401
316
|
|
|
402
317
|
public refresh(): JQuery {
|
|
403
|
-
this.
|
|
318
|
+
this._treeElement.refresh();
|
|
404
319
|
return this._element;
|
|
405
320
|
}
|
|
406
321
|
|
|
407
|
-
public reload(onFinished
|
|
408
|
-
this.
|
|
322
|
+
public reload(onFinished?: () => void): JQuery {
|
|
323
|
+
this._treeElement.loadDataFromUrl(undefined, undefined).then(
|
|
324
|
+
() => {
|
|
325
|
+
if (onFinished) {
|
|
326
|
+
onFinished();
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
).catch((error: unknown) => {
|
|
330
|
+
throw error;
|
|
331
|
+
});
|
|
409
332
|
return this._element;
|
|
410
333
|
}
|
|
411
334
|
|
|
@@ -414,11 +337,7 @@ export class JqTreeWidget extends SimpleWidget<JQTreeOptions> {
|
|
|
414
337
|
throw Error(NODE_PARAM_IS_EMPTY);
|
|
415
338
|
}
|
|
416
339
|
|
|
417
|
-
this.
|
|
418
|
-
|
|
419
|
-
this._getNodeElementForNode(node).deselect();
|
|
420
|
-
this._saveState();
|
|
421
|
-
|
|
340
|
+
this._treeElement.removeFromSelection(node);
|
|
422
341
|
return this._element;
|
|
423
342
|
}
|
|
424
343
|
|
|
@@ -431,12 +350,7 @@ export class JqTreeWidget extends SimpleWidget<JQTreeOptions> {
|
|
|
431
350
|
throw Error("Node has no parent");
|
|
432
351
|
}
|
|
433
352
|
|
|
434
|
-
this.
|
|
435
|
-
|
|
436
|
-
const parent = node.parent;
|
|
437
|
-
node.remove();
|
|
438
|
-
this._refreshElements(parent);
|
|
439
|
-
|
|
353
|
+
this._treeElement.removeNode(node);
|
|
440
354
|
return this._element;
|
|
441
355
|
}
|
|
442
356
|
|
|
@@ -445,16 +359,7 @@ export class JqTreeWidget extends SimpleWidget<JQTreeOptions> {
|
|
|
445
359
|
throw Error(NODE_PARAM_IS_EMPTY);
|
|
446
360
|
}
|
|
447
361
|
|
|
448
|
-
|
|
449
|
-
return this._element;
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
const top =
|
|
453
|
-
getOffsetTop(node.element) -
|
|
454
|
-
getOffsetTop(this._htmlElement);
|
|
455
|
-
|
|
456
|
-
this._scrollHandler.scrollToY(top);
|
|
457
|
-
|
|
362
|
+
this._treeElement.scrollToNode(node);
|
|
458
363
|
return this._element;
|
|
459
364
|
}
|
|
460
365
|
|
|
@@ -462,19 +367,18 @@ export class JqTreeWidget extends SimpleWidget<JQTreeOptions> {
|
|
|
462
367
|
node: Node | null,
|
|
463
368
|
optionsParam?: SelectNodeOptions,
|
|
464
369
|
): JQuery {
|
|
465
|
-
this.
|
|
370
|
+
this._treeElement.selectNode(node, optionsParam);
|
|
466
371
|
return this._element;
|
|
467
372
|
}
|
|
468
373
|
|
|
469
374
|
public setOption(option: string, value: unknown): JQuery {
|
|
470
|
-
|
|
375
|
+
this._treeElement.setOption(option, value);
|
|
471
376
|
return this._element;
|
|
472
377
|
}
|
|
473
378
|
|
|
474
379
|
public setState(state?: SavedState): JQuery {
|
|
475
380
|
if (state) {
|
|
476
|
-
this.
|
|
477
|
-
this._refreshElements(null);
|
|
381
|
+
this._treeElement.setState(state);
|
|
478
382
|
}
|
|
479
383
|
|
|
480
384
|
return this._element;
|
|
@@ -485,19 +389,12 @@ export class JqTreeWidget extends SimpleWidget<JQTreeOptions> {
|
|
|
485
389
|
throw Error(NODE_PARAM_IS_EMPTY);
|
|
486
390
|
}
|
|
487
391
|
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
if (node.is_open) {
|
|
491
|
-
this.closeNode(node, slide);
|
|
492
|
-
} else {
|
|
493
|
-
this.openNode(node, slide);
|
|
494
|
-
}
|
|
495
|
-
|
|
392
|
+
this._treeElement.toggle(node, slideParam);
|
|
496
393
|
return this._element;
|
|
497
394
|
}
|
|
498
395
|
|
|
499
396
|
public toJson(): string {
|
|
500
|
-
return
|
|
397
|
+
return this._treeElement.toJson();
|
|
501
398
|
}
|
|
502
399
|
|
|
503
400
|
public updateNode(node?: Node, data?: NodeData): JQuery {
|
|
@@ -509,758 +406,157 @@ export class JqTreeWidget extends SimpleWidget<JQTreeOptions> {
|
|
|
509
406
|
return this._element;
|
|
510
407
|
}
|
|
511
408
|
|
|
512
|
-
|
|
513
|
-
typeof data === "object" && data.id && data.id !== node.id;
|
|
514
|
-
|
|
515
|
-
if (idIsChanged) {
|
|
516
|
-
this._tree.removeNodeFromIndex(node);
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
node.setData(data);
|
|
520
|
-
|
|
521
|
-
if (idIsChanged) {
|
|
522
|
-
this._tree.addNodeToIndex(node);
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
if (
|
|
526
|
-
typeof data === "object" &&
|
|
527
|
-
data.children &&
|
|
528
|
-
data.children instanceof Array
|
|
529
|
-
) {
|
|
530
|
-
node.removeChildren();
|
|
531
|
-
|
|
532
|
-
if (data.children.length) {
|
|
533
|
-
node.loadFromData(data.children);
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
this._refreshElements(node);
|
|
538
|
-
|
|
409
|
+
this._treeElement.updateNode(node, data);
|
|
539
410
|
return this._element;
|
|
540
411
|
}
|
|
541
412
|
|
|
542
|
-
private
|
|
543
|
-
const
|
|
544
|
-
autoEscape,
|
|
545
|
-
buttonLeft,
|
|
546
|
-
closedIcon,
|
|
547
|
-
dataFilter,
|
|
548
|
-
dragAndDrop,
|
|
549
|
-
keyboardSupport,
|
|
550
|
-
onCanMove,
|
|
551
|
-
onCanMoveTo,
|
|
552
|
-
onCreateLi,
|
|
553
|
-
onDragMove,
|
|
554
|
-
onDragStop,
|
|
555
|
-
onGetStateFromStorage,
|
|
556
|
-
onIsMoveHandle,
|
|
557
|
-
onLoadFailed,
|
|
558
|
-
onLoading,
|
|
559
|
-
onSetStateFromStorage,
|
|
560
|
-
openedIcon,
|
|
561
|
-
openFolderDelay,
|
|
562
|
-
rtl,
|
|
563
|
-
saveState,
|
|
564
|
-
showEmptyFolder,
|
|
565
|
-
slide,
|
|
566
|
-
tabIndex,
|
|
567
|
-
} = this.options;
|
|
568
|
-
|
|
569
|
-
const closeNode = this.closeNode.bind(this);
|
|
570
|
-
const getNodeElement = this._getNodeElement.bind(this);
|
|
571
|
-
const getNodeElementForNode = this._getNodeElementForNode.bind(this);
|
|
572
|
-
const getNodeById = this.getNodeById.bind(this);
|
|
573
|
-
const getSelectedNode = this.getSelectedNode.bind(this);
|
|
574
|
-
const getTree = this.getTree.bind(this);
|
|
575
|
-
const isFocusOnTree = this._isFocusOnTree.bind(this);
|
|
576
|
-
const loadData = this.loadData.bind(this);
|
|
577
|
-
const openNode = this._openNodeInternal.bind(this);
|
|
578
|
-
const refreshElements = this._refreshElements.bind(this);
|
|
579
|
-
const selectNode = this.selectNode.bind(this);
|
|
580
|
-
const treeElement = this._htmlElement;
|
|
581
|
-
const triggerEvent = this._triggerEvent.bind(this);
|
|
582
|
-
|
|
583
|
-
const selectNodeHandler = new SelectNodeHandler({
|
|
584
|
-
getNodeById,
|
|
585
|
-
});
|
|
413
|
+
private _handleLoadFailedEvent(e: JQuery.TriggeredEvent) {
|
|
414
|
+
const jqTreeOnLoadFailed = this._inputOptions.onLoadFailed;
|
|
586
415
|
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
selectNodeHandler.getSelectedNodes.bind(selectNodeHandler);
|
|
591
|
-
const isNodeSelected =
|
|
592
|
-
selectNodeHandler.isNodeSelected.bind(selectNodeHandler);
|
|
593
|
-
const removeFromSelection =
|
|
594
|
-
selectNodeHandler.removeFromSelection.bind(selectNodeHandler);
|
|
595
|
-
const getMouseDelay = () => this.options.startDndDelay ?? 0;
|
|
596
|
-
|
|
597
|
-
const refreshHitAreas = () => {
|
|
598
|
-
dndHandler.refresh();
|
|
416
|
+
if (jqTreeOnLoadFailed) {
|
|
417
|
+
const { response } = e as unknown as LoadFailedEvent;
|
|
418
|
+
jqTreeOnLoadFailed(response);
|
|
599
419
|
}
|
|
600
|
-
|
|
601
|
-
const dataLoader = new DataLoader({
|
|
602
|
-
dataFilter,
|
|
603
|
-
loadData,
|
|
604
|
-
onLoadFailed,
|
|
605
|
-
onLoading,
|
|
606
|
-
treeElement,
|
|
607
|
-
triggerEvent,
|
|
608
|
-
});
|
|
609
|
-
|
|
610
|
-
const saveStateHandler = new SaveStateHandler({
|
|
611
|
-
addToSelection,
|
|
612
|
-
getNodeById,
|
|
613
|
-
getSelectedNodes,
|
|
614
|
-
getTree,
|
|
615
|
-
onGetStateFromStorage,
|
|
616
|
-
onSetStateFromStorage,
|
|
617
|
-
openNode,
|
|
618
|
-
refreshElements,
|
|
619
|
-
removeFromSelection,
|
|
620
|
-
saveState,
|
|
621
|
-
});
|
|
622
|
-
|
|
623
|
-
const scrollHandler = new ScrollHandler({
|
|
624
|
-
refreshHitAreas,
|
|
625
|
-
treeElement,
|
|
626
|
-
});
|
|
627
|
-
|
|
628
|
-
const getScrollLeft = scrollHandler.getScrollLeft.bind(scrollHandler);
|
|
629
|
-
|
|
630
|
-
const dndHandler = new DragAndDropHandler({
|
|
631
|
-
autoEscape,
|
|
632
|
-
getNodeElement,
|
|
633
|
-
getNodeElementForNode,
|
|
634
|
-
getScrollLeft,
|
|
635
|
-
getTree,
|
|
636
|
-
onCanMove,
|
|
637
|
-
onCanMoveTo,
|
|
638
|
-
onDragMove,
|
|
639
|
-
onDragStop,
|
|
640
|
-
onIsMoveHandle,
|
|
641
|
-
openFolderDelay,
|
|
642
|
-
openNode,
|
|
643
|
-
refreshElements,
|
|
644
|
-
slide,
|
|
645
|
-
treeElement,
|
|
646
|
-
triggerEvent,
|
|
647
|
-
});
|
|
648
|
-
|
|
649
|
-
const keyHandler = new KeyHandler({
|
|
650
|
-
closeNode,
|
|
651
|
-
getSelectedNode,
|
|
652
|
-
isFocusOnTree,
|
|
653
|
-
keyboardSupport,
|
|
654
|
-
openNode,
|
|
655
|
-
selectNode,
|
|
656
|
-
});
|
|
657
|
-
|
|
658
|
-
const renderer = new ElementsRenderer({
|
|
659
|
-
autoEscape,
|
|
660
|
-
buttonLeft,
|
|
661
|
-
closedIcon,
|
|
662
|
-
dragAndDrop,
|
|
663
|
-
getTree,
|
|
664
|
-
htmlElement: treeElement,
|
|
665
|
-
isNodeSelected,
|
|
666
|
-
onCreateLi,
|
|
667
|
-
openedIcon,
|
|
668
|
-
rtl,
|
|
669
|
-
showEmptyFolder,
|
|
670
|
-
tabIndex,
|
|
671
|
-
});
|
|
672
|
-
|
|
673
|
-
const getNode = this._getNode.bind(this);
|
|
674
|
-
const onMouseCapture = this._mouseCapture.bind(this);
|
|
675
|
-
const onMouseDrag = this._mouseDrag.bind(this);
|
|
676
|
-
const onMouseStart = this._mouseStart.bind(this);
|
|
677
|
-
const onMouseStop = this._mouseStop.bind(this);
|
|
678
|
-
|
|
679
|
-
const mouseHandler = new MouseHandler({
|
|
680
|
-
element: treeElement,
|
|
681
|
-
getMouseDelay,
|
|
682
|
-
getNode,
|
|
683
|
-
onClickButton: this.toggle.bind(this),
|
|
684
|
-
onClickTitle: this._doSelectNode.bind(this),
|
|
685
|
-
onMouseCapture,
|
|
686
|
-
onMouseDrag,
|
|
687
|
-
onMouseStart,
|
|
688
|
-
onMouseStop,
|
|
689
|
-
triggerEvent,
|
|
690
|
-
useContextMenu: this.options.useContextMenu,
|
|
691
|
-
});
|
|
692
|
-
|
|
693
|
-
this._dataLoader = dataLoader;
|
|
694
|
-
this._dndHandler = dndHandler;
|
|
695
|
-
this._keyHandler = keyHandler;
|
|
696
|
-
this._mouseHandler = mouseHandler;
|
|
697
|
-
this._renderer = renderer;
|
|
698
|
-
this._saveStateHandler = saveStateHandler;
|
|
699
|
-
this._scrollHandler = scrollHandler;
|
|
700
|
-
this._selectNodeHandler = selectNodeHandler;
|
|
701
420
|
}
|
|
702
421
|
|
|
703
|
-
private
|
|
704
|
-
const
|
|
705
|
-
|
|
706
|
-
return node?.tree === this._tree;
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
private _createFolderElement(node: Node) {
|
|
710
|
-
const closedIconElement = this._renderer.closedIconElement;
|
|
711
|
-
const getScrollLeft = this._scrollHandler.getScrollLeft.bind(
|
|
712
|
-
this._scrollHandler,
|
|
713
|
-
);
|
|
714
|
-
const openedIconElement = this._renderer.openedIconElement;
|
|
715
|
-
const tabIndex = this.options.tabIndex;
|
|
716
|
-
const triggerEvent = this._triggerEvent.bind(this);
|
|
717
|
-
|
|
718
|
-
return new FolderElement({
|
|
719
|
-
closedIconElement,
|
|
720
|
-
getScrollLeft,
|
|
721
|
-
node,
|
|
722
|
-
openedIconElement,
|
|
723
|
-
tabIndex,
|
|
724
|
-
treeElement: this._htmlElement,
|
|
725
|
-
triggerEvent,
|
|
726
|
-
});
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
private _createNodeElement(node: Node) {
|
|
730
|
-
const getScrollLeft = this._scrollHandler.getScrollLeft.bind(
|
|
731
|
-
this._scrollHandler,
|
|
732
|
-
);
|
|
733
|
-
const tabIndex = this.options.tabIndex;
|
|
422
|
+
private _handleLoadingDataEvent(e: JQuery.TriggeredEvent) {
|
|
423
|
+
const jqTreeOnLoading = this._inputOptions.onLoading;
|
|
734
424
|
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
node,
|
|
738
|
-
tabIndex,
|
|
739
|
-
treeElement: this._htmlElement
|
|
740
|
-
});
|
|
741
|
-
}
|
|
742
|
-
|
|
743
|
-
private _deselectCurrentNode(): void {
|
|
744
|
-
const node = this.getSelectedNode();
|
|
745
|
-
if (node) {
|
|
746
|
-
this.removeFromSelection(node);
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
private _deselectNodes(parentNode: Node): void {
|
|
751
|
-
const selectedNodesUnderParent =
|
|
752
|
-
this._selectNodeHandler.getSelectedNodesUnder(parentNode);
|
|
753
|
-
for (const n of selectedNodesUnderParent) {
|
|
754
|
-
this._selectNodeHandler.removeFromSelection(n);
|
|
425
|
+
if (jqTreeOnLoading) {
|
|
426
|
+
const { $el, isLoading, node } = e as unknown as LoadingDataEvent;
|
|
427
|
+
jqTreeOnLoading(isLoading, node ?? undefined, $el)
|
|
755
428
|
}
|
|
756
429
|
}
|
|
757
430
|
|
|
758
|
-
private
|
|
759
|
-
|
|
760
|
-
if (
|
|
761
|
-
|
|
762
|
-
this._loadSubtree(data, parentNode);
|
|
431
|
+
private _transformInputOptions(): Partial<TreeElementOptions> {
|
|
432
|
+
function convertToIconElement(jqtreeIconElement: JQTreeIconElement | undefined) {
|
|
433
|
+
if (jqtreeIconElement instanceof jQuery) {
|
|
434
|
+
return (jqtreeIconElement as JQuery).get(0);
|
|
763
435
|
} else {
|
|
764
|
-
|
|
765
|
-
}
|
|
766
|
-
|
|
767
|
-
if (this.isDragging()) {
|
|
768
|
-
this._dndHandler.refresh();
|
|
436
|
+
return jqtreeIconElement as IconElement;
|
|
769
437
|
}
|
|
770
438
|
}
|
|
771
439
|
|
|
772
|
-
this.
|
|
773
|
-
|
|
774
|
-
tree_data: data,
|
|
775
|
-
});
|
|
776
|
-
}
|
|
440
|
+
const closedIcon = convertToIconElement(this._inputOptions.closedIcon);
|
|
441
|
+
const openedIcon = convertToIconElement(this._inputOptions.openedIcon);
|
|
777
442
|
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
parentNode: Node | null,
|
|
781
|
-
onFinished: HandleFinishedLoading | null,
|
|
782
|
-
): void {
|
|
783
|
-
const urlInfo = urlInfoParam ?? this._getDataUrlInfo(parentNode);
|
|
443
|
+
let onCreateLi: OnCreateLi | undefined = undefined;
|
|
444
|
+
const jqTreeOnCreateLi = this._inputOptions.onCreateLi;
|
|
784
445
|
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
node: Node | null,
|
|
790
|
-
optionsParam?: SelectNodeOptions,
|
|
791
|
-
): void {
|
|
792
|
-
const saveState = (): void => {
|
|
793
|
-
if (this.options.saveState) {
|
|
794
|
-
this._saveStateHandler.saveState();
|
|
795
|
-
}
|
|
796
|
-
};
|
|
797
|
-
|
|
798
|
-
if (!node) {
|
|
799
|
-
// Called with empty node -> deselect current node
|
|
800
|
-
this._deselectCurrentNode();
|
|
801
|
-
saveState();
|
|
802
|
-
return;
|
|
803
|
-
}
|
|
804
|
-
const defaultOptions = { mustSetFocus: true, mustToggle: true };
|
|
805
|
-
const selectOptions = { ...defaultOptions, ...(optionsParam ?? {}) };
|
|
806
|
-
|
|
807
|
-
const canSelect = (): boolean => {
|
|
808
|
-
if (this.options.onCanSelectNode) {
|
|
809
|
-
return (
|
|
810
|
-
this.options.selectable &&
|
|
811
|
-
this.options.onCanSelectNode(node)
|
|
812
|
-
);
|
|
813
|
-
} else {
|
|
814
|
-
return this.options.selectable;
|
|
815
|
-
}
|
|
816
|
-
};
|
|
817
|
-
|
|
818
|
-
if (!canSelect()) {
|
|
819
|
-
return;
|
|
820
|
-
}
|
|
821
|
-
|
|
822
|
-
if (this._selectNodeHandler.isNodeSelected(node)) {
|
|
823
|
-
if (selectOptions.mustToggle) {
|
|
824
|
-
this._deselectCurrentNode();
|
|
825
|
-
this._triggerEvent("tree.select", {
|
|
826
|
-
node: null,
|
|
827
|
-
previous_node: node,
|
|
828
|
-
});
|
|
829
|
-
}
|
|
830
|
-
} else {
|
|
831
|
-
const deselectedNode = this.getSelectedNode() || null;
|
|
832
|
-
this._deselectCurrentNode();
|
|
833
|
-
this.addToSelection(node, selectOptions.mustSetFocus);
|
|
834
|
-
|
|
835
|
-
this._triggerEvent("tree.select", {
|
|
836
|
-
deselected_node: deselectedNode,
|
|
837
|
-
node,
|
|
838
|
-
});
|
|
839
|
-
this._openParents(node);
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
saveState();
|
|
843
|
-
}
|
|
844
|
-
|
|
845
|
-
private _getAutoOpenMaxLevel(): number {
|
|
846
|
-
if (this.options.autoOpen === true) {
|
|
847
|
-
return -1;
|
|
848
|
-
} else if (typeof this.options.autoOpen === "number") {
|
|
849
|
-
return this.options.autoOpen;
|
|
850
|
-
} else if (typeof this.options.autoOpen === "string") {
|
|
851
|
-
return parseInt(this.options.autoOpen, 10);
|
|
852
|
-
} else {
|
|
853
|
-
return 0;
|
|
446
|
+
if (jqTreeOnCreateLi) {
|
|
447
|
+
onCreateLi = (node: Node, el: HTMLElement, isSelected: boolean) => {
|
|
448
|
+
jqTreeOnCreateLi(node, jQuery(el), isSelected);
|
|
449
|
+
};
|
|
854
450
|
}
|
|
855
|
-
}
|
|
856
451
|
|
|
857
|
-
|
|
858
|
-
const
|
|
859
|
-
const urlInfo: JQuery.AjaxSettings = { url };
|
|
452
|
+
let onIsMoveHandle: OnIsMoveHandle | undefined = undefined;
|
|
453
|
+
const jqTreeOnIsMoveHandle = this._inputOptions.onIsMoveHandle;
|
|
860
454
|
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
return urlInfo;
|
|
864
|
-
};
|
|
865
|
-
|
|
866
|
-
const setUrlInfoData = (urlInfo: JQuery.AjaxSettings): void => {
|
|
867
|
-
if (node?.id) {
|
|
868
|
-
// Load on demand of a subtree; add node parameter
|
|
869
|
-
const data = { node: node.id };
|
|
870
|
-
urlInfo.data = data;
|
|
871
|
-
} else {
|
|
872
|
-
// Add selected_node parameter
|
|
873
|
-
const selectedNodeId = this._getNodeIdToBeSelected();
|
|
874
|
-
if (selectedNodeId) {
|
|
875
|
-
const data = { selected_node: selectedNodeId };
|
|
876
|
-
urlInfo.data = data;
|
|
877
|
-
}
|
|
878
|
-
}
|
|
879
|
-
};
|
|
880
|
-
|
|
881
|
-
const dataUrl = this.options.dataUrl;
|
|
882
|
-
if (typeof dataUrl === "function") {
|
|
883
|
-
return dataUrl(node);
|
|
884
|
-
} else if (typeof dataUrl === "string") {
|
|
885
|
-
return getUrlFromString(dataUrl);
|
|
886
|
-
} else if (dataUrl && typeof dataUrl === "object") {
|
|
887
|
-
setUrlInfoData(dataUrl);
|
|
888
|
-
return dataUrl;
|
|
889
|
-
} else {
|
|
890
|
-
return null;
|
|
455
|
+
if (jqTreeOnIsMoveHandle) {
|
|
456
|
+
onIsMoveHandle = (el: HTMLElement) => jqTreeOnIsMoveHandle(jQuery(el))
|
|
891
457
|
}
|
|
892
|
-
}
|
|
893
458
|
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
return "►";
|
|
459
|
+
return {
|
|
460
|
+
...this._inputOptions,
|
|
461
|
+
closedIcon,
|
|
462
|
+
onCreateLi,
|
|
463
|
+
onIsMoveHandle,
|
|
464
|
+
openedIcon,
|
|
901
465
|
}
|
|
902
466
|
}
|
|
467
|
+
}
|
|
903
468
|
|
|
904
|
-
|
|
905
|
-
|
|
469
|
+
const register = (): void => {
|
|
470
|
+
const getWidgetData = (
|
|
471
|
+
el: HTMLElement,
|
|
472
|
+
dataKey: string,
|
|
473
|
+
): JqTreeWidget | null => {
|
|
474
|
+
const widget = jQuery.data(el, dataKey) as unknown;
|
|
906
475
|
|
|
907
|
-
if (
|
|
908
|
-
return
|
|
476
|
+
if (widget && widget instanceof JqTreeWidget) {
|
|
477
|
+
return widget;
|
|
909
478
|
} else {
|
|
910
479
|
return null;
|
|
911
480
|
}
|
|
912
|
-
}
|
|
913
|
-
|
|
914
|
-
private _getNodeElement(element: HTMLElement): NodeElement | null {
|
|
915
|
-
const node = this._getNode(element);
|
|
916
|
-
if (node) {
|
|
917
|
-
return this._getNodeElementForNode(node);
|
|
918
|
-
} else {
|
|
919
|
-
return null;
|
|
920
|
-
}
|
|
921
|
-
}
|
|
922
|
-
|
|
923
|
-
private _getNodeElementForNode(node: Node): NodeElement {
|
|
924
|
-
if (node.isFolder()) {
|
|
925
|
-
return this._createFolderElement(node);
|
|
926
|
-
} else {
|
|
927
|
-
return this._createNodeElement(node);
|
|
928
|
-
}
|
|
929
|
-
}
|
|
930
|
-
|
|
931
|
-
private _getNodeIdToBeSelected(): NodeId | null {
|
|
932
|
-
if (this.options.saveState) {
|
|
933
|
-
return this._saveStateHandler.getNodeIdToBeSelected();
|
|
934
|
-
} else {
|
|
935
|
-
return null;
|
|
936
|
-
}
|
|
937
|
-
}
|
|
938
|
-
|
|
939
|
-
private _initData(): void {
|
|
940
|
-
if (this.options.data) {
|
|
941
|
-
this._doLoadData(this.options.data, null);
|
|
942
|
-
} else {
|
|
943
|
-
const dataUrl = this._getDataUrlInfo(null);
|
|
944
|
-
|
|
945
|
-
if (dataUrl) {
|
|
946
|
-
this._doLoadDataFromUrl(null, null, null);
|
|
947
|
-
} else {
|
|
948
|
-
this._doLoadData([], null);
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
|
-
}
|
|
952
|
-
|
|
953
|
-
private _initTree(data: NodeData[]): void {
|
|
954
|
-
const doInit = (): void => {
|
|
955
|
-
if (!this._isInitialized) {
|
|
956
|
-
this._isInitialized = true;
|
|
957
|
-
this._triggerEvent("tree.init");
|
|
958
|
-
}
|
|
959
|
-
};
|
|
960
|
-
|
|
961
|
-
this._tree = new this.options.nodeClass(
|
|
962
|
-
null,
|
|
963
|
-
true,
|
|
964
|
-
this.options.nodeClass,
|
|
965
|
-
);
|
|
966
|
-
|
|
967
|
-
this._selectNodeHandler.clear();
|
|
968
|
-
|
|
969
|
-
this._tree.loadFromData(data);
|
|
970
|
-
|
|
971
|
-
const mustLoadOnDemand = this._setInitialState();
|
|
972
|
-
|
|
973
|
-
this._refreshElements(null);
|
|
974
|
-
|
|
975
|
-
if (!mustLoadOnDemand) {
|
|
976
|
-
doInit();
|
|
977
|
-
} else {
|
|
978
|
-
// Load data on demand and then init the tree
|
|
979
|
-
this._setInitialStateOnDemand(doInit);
|
|
980
|
-
}
|
|
981
|
-
}
|
|
982
|
-
|
|
983
|
-
private _isFocusOnTree(): boolean {
|
|
984
|
-
const activeElement = document.activeElement;
|
|
985
|
-
|
|
986
|
-
return activeElement?.tagName === "SPAN" && this._containsElement(activeElement as HTMLElement);
|
|
987
|
-
}
|
|
988
|
-
|
|
989
|
-
private _isSelectedNodeInSubtree(subtree: Node): boolean {
|
|
990
|
-
const selectedNode = this.getSelectedNode();
|
|
991
|
-
|
|
992
|
-
if (!selectedNode) {
|
|
993
|
-
return false;
|
|
994
|
-
} else {
|
|
995
|
-
return subtree === selectedNode || subtree.isParentOf(selectedNode);
|
|
996
|
-
}
|
|
997
|
-
}
|
|
998
|
-
|
|
999
|
-
private _loadFolderOnDemand(
|
|
1000
|
-
node: Node,
|
|
1001
|
-
slide = true,
|
|
1002
|
-
onFinished?: OnFinishOpenNode,
|
|
1003
|
-
): void {
|
|
1004
|
-
node.is_loading = true;
|
|
1005
|
-
|
|
1006
|
-
this._doLoadDataFromUrl(null, node, () => {
|
|
1007
|
-
this._openNodeInternal(node, slide, onFinished);
|
|
1008
|
-
});
|
|
1009
|
-
}
|
|
1010
|
-
|
|
1011
|
-
private _loadSubtree(data: NodeData[], parentNode: Node): void {
|
|
1012
|
-
parentNode.loadFromData(data);
|
|
1013
|
-
|
|
1014
|
-
parentNode.load_on_demand = false;
|
|
1015
|
-
parentNode.is_loading = false;
|
|
1016
|
-
|
|
1017
|
-
this._refreshElements(parentNode);
|
|
1018
|
-
}
|
|
1019
|
-
|
|
1020
|
-
private _mouseCapture(positionInfo: PositionInfo): boolean | null {
|
|
1021
|
-
if (this.options.dragAndDrop) {
|
|
1022
|
-
return this._dndHandler.mouseCapture(positionInfo);
|
|
1023
|
-
} else {
|
|
1024
|
-
return false;
|
|
1025
|
-
}
|
|
1026
|
-
}
|
|
1027
|
-
|
|
1028
|
-
private _mouseDrag(positionInfo: PositionInfo): boolean {
|
|
1029
|
-
if (this.options.dragAndDrop) {
|
|
1030
|
-
const result = this._dndHandler.mouseDrag(positionInfo);
|
|
1031
|
-
|
|
1032
|
-
this._scrollHandler.checkScrolling(positionInfo);
|
|
1033
|
-
return result;
|
|
1034
|
-
} else {
|
|
1035
|
-
return false;
|
|
1036
|
-
}
|
|
1037
|
-
}
|
|
1038
|
-
|
|
1039
|
-
private _mouseStart(positionInfo: PositionInfo): boolean {
|
|
1040
|
-
if (this.options.dragAndDrop) {
|
|
1041
|
-
return this._dndHandler.mouseStart(positionInfo);
|
|
1042
|
-
} else {
|
|
1043
|
-
return false;
|
|
1044
|
-
}
|
|
1045
|
-
}
|
|
481
|
+
};
|
|
1046
482
|
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
return this._dndHandler.mouseStop(positionInfo);
|
|
1051
|
-
} else {
|
|
1052
|
-
return false;
|
|
1053
|
-
}
|
|
1054
|
-
}
|
|
483
|
+
const createWidget = ($el: JQuery, options: null | Partial<JQTreeOptions>): JQuery => {
|
|
484
|
+
for (const el of $el.get()) {
|
|
485
|
+
const existingWidget = getWidgetData(el, "jqtree");
|
|
1055
486
|
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
slide = true,
|
|
1059
|
-
onFinished?: OnFinishOpenNode,
|
|
1060
|
-
): void {
|
|
1061
|
-
const doOpenNode = (
|
|
1062
|
-
_node: Node,
|
|
1063
|
-
_slide: boolean,
|
|
1064
|
-
_onFinished?: OnFinishOpenNode,
|
|
1065
|
-
): void => {
|
|
1066
|
-
if (!node.children.length) {
|
|
1067
|
-
return;
|
|
1068
|
-
}
|
|
487
|
+
if (!existingWidget) {
|
|
488
|
+
const widget = new JqTreeWidget(el, options ?? {});
|
|
1069
489
|
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
_onFinished,
|
|
1073
|
-
_slide,
|
|
1074
|
-
this.options.animationSpeed,
|
|
1075
|
-
);
|
|
1076
|
-
};
|
|
1077
|
-
|
|
1078
|
-
if (node.isFolder() || node.isEmptyFolder) {
|
|
1079
|
-
if (node.load_on_demand) {
|
|
1080
|
-
this._loadFolderOnDemand(node, slide, onFinished);
|
|
1081
|
-
} else {
|
|
1082
|
-
let parent = node.parent;
|
|
1083
|
-
|
|
1084
|
-
while (parent) {
|
|
1085
|
-
// nb: do not open root element
|
|
1086
|
-
if (parent.parent) {
|
|
1087
|
-
doOpenNode(parent, false);
|
|
1088
|
-
}
|
|
1089
|
-
parent = parent.parent;
|
|
490
|
+
if (!jQuery.data(el, "jqtree")) {
|
|
491
|
+
jQuery.data(el, "jqtree", widget);
|
|
1090
492
|
}
|
|
1091
493
|
|
|
1092
|
-
|
|
1093
|
-
|
|
494
|
+
// Call init after setting data, so we can call methods
|
|
495
|
+
widget.init();
|
|
1094
496
|
}
|
|
1095
497
|
}
|
|
1096
|
-
}
|
|
1097
498
|
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
if (parent?.parent && !parent.is_open) {
|
|
1102
|
-
this.openNode(parent, false);
|
|
1103
|
-
}
|
|
1104
|
-
}
|
|
1105
|
-
|
|
1106
|
-
/*
|
|
1107
|
-
Redraw the tree or part of the tree.
|
|
1108
|
-
from_node: redraw this subtree
|
|
1109
|
-
*/
|
|
1110
|
-
private _refreshElements(fromNode: Node | null): void {
|
|
1111
|
-
const mustSetFocus = this._isFocusOnTree();
|
|
1112
|
-
const mustSelect = fromNode
|
|
1113
|
-
? this._isSelectedNodeInSubtree(fromNode)
|
|
1114
|
-
: false;
|
|
1115
|
-
|
|
1116
|
-
this._renderer.render(fromNode);
|
|
499
|
+
return $el;
|
|
500
|
+
};
|
|
1117
501
|
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
502
|
+
const destroyWidget = ($el: JQuery): void => {
|
|
503
|
+
for (const el of $el.get()) {
|
|
504
|
+
const widget = getWidgetData(el, "jqtree");
|
|
1121
505
|
|
|
1122
|
-
|
|
1123
|
-
|
|
506
|
+
if (widget) {
|
|
507
|
+
widget.destroy();
|
|
508
|
+
}
|
|
1124
509
|
|
|
1125
|
-
|
|
1126
|
-
if (this.options.saveState) {
|
|
1127
|
-
this._saveStateHandler.saveState();
|
|
510
|
+
jQuery.removeData(el, "jqtree");
|
|
1128
511
|
}
|
|
1129
|
-
}
|
|
512
|
+
};
|
|
1130
513
|
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
}
|
|
514
|
+
const callFunction = (
|
|
515
|
+
$el: JQuery,
|
|
516
|
+
functionName: string,
|
|
517
|
+
args: unknown[],
|
|
518
|
+
): unknown => {
|
|
519
|
+
let result = null;
|
|
1138
520
|
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
private _setInitialState(): boolean {
|
|
1142
|
-
const restoreState = (): [boolean, boolean] => {
|
|
1143
|
-
// result: is state restored, must load on demand?
|
|
1144
|
-
if (!this.options.saveState) {
|
|
1145
|
-
return [false, false];
|
|
1146
|
-
} else {
|
|
1147
|
-
const state = this._saveStateHandler.getStateFromStorage();
|
|
521
|
+
for (const el of $el.get()) {
|
|
522
|
+
const widget = jQuery.data(el, "jqtree") as unknown;
|
|
1148
523
|
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
} else {
|
|
1152
|
-
const mustLoadOnDemand =
|
|
1153
|
-
this._saveStateHandler.setInitialState(state);
|
|
524
|
+
if (widget && widget instanceof JqTreeWidget) {
|
|
525
|
+
const widgetFunction = widget[functionName];
|
|
1154
526
|
|
|
1155
|
-
|
|
1156
|
-
|
|
527
|
+
if (widgetFunction && typeof widgetFunction === "function") {
|
|
528
|
+
result = widgetFunction.apply(widget, args) as unknown;
|
|
1157
529
|
}
|
|
1158
530
|
}
|
|
1159
|
-
};
|
|
1160
|
-
|
|
1161
|
-
const autoOpenNodes = (): boolean => {
|
|
1162
|
-
// result: must load on demand?
|
|
1163
|
-
if (this.options.autoOpen === false) {
|
|
1164
|
-
return false;
|
|
1165
|
-
}
|
|
1166
|
-
|
|
1167
|
-
const maxLevel = this._getAutoOpenMaxLevel();
|
|
1168
|
-
let mustLoadOnDemand = false;
|
|
1169
|
-
|
|
1170
|
-
this._tree.iterate((node: Node, level: number) => {
|
|
1171
|
-
if (node.load_on_demand) {
|
|
1172
|
-
mustLoadOnDemand = true;
|
|
1173
|
-
return false;
|
|
1174
|
-
} else if (!node.hasChildren()) {
|
|
1175
|
-
return false;
|
|
1176
|
-
} else {
|
|
1177
|
-
node.is_open = true;
|
|
1178
|
-
return level !== maxLevel;
|
|
1179
|
-
}
|
|
1180
|
-
});
|
|
1181
|
-
|
|
1182
|
-
return mustLoadOnDemand;
|
|
1183
|
-
};
|
|
1184
|
-
|
|
1185
|
-
let [isRestored, mustLoadOnDemand] = restoreState(); // eslint-disable-line prefer-const
|
|
1186
|
-
|
|
1187
|
-
if (!isRestored) {
|
|
1188
|
-
mustLoadOnDemand = autoOpenNodes();
|
|
1189
531
|
}
|
|
1190
532
|
|
|
1191
|
-
return
|
|
1192
|
-
}
|
|
533
|
+
return result;
|
|
534
|
+
};
|
|
1193
535
|
|
|
1194
|
-
//
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
536
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
537
|
+
(jQuery.fn as any).tree = function (
|
|
538
|
+
this: JQuery,
|
|
539
|
+
argument1: unknown,
|
|
540
|
+
...args: unknown[]
|
|
541
|
+
) {
|
|
542
|
+
if (!argument1) {
|
|
543
|
+
return createWidget(this, null);
|
|
544
|
+
} else if (typeof argument1 === "object") {
|
|
545
|
+
const options = argument1 as unknown;
|
|
546
|
+
return createWidget(this, options as JQTreeOptions);
|
|
547
|
+
} else if (typeof argument1 === "string" && argument1[0] !== "_") {
|
|
548
|
+
const functionName = argument1;
|
|
549
|
+
|
|
550
|
+
if (argument1 === "destroy") {
|
|
551
|
+
destroyWidget(this);
|
|
552
|
+
return undefined;
|
|
1200
553
|
} else {
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
if (!state) {
|
|
1204
|
-
return false;
|
|
1205
|
-
} else {
|
|
1206
|
-
this._saveStateHandler.setInitialStateOnDemand(
|
|
1207
|
-
state,
|
|
1208
|
-
cbFinished,
|
|
1209
|
-
);
|
|
1210
|
-
|
|
1211
|
-
return true;
|
|
1212
|
-
}
|
|
554
|
+
return callFunction(this, functionName, args);
|
|
1213
555
|
}
|
|
1214
|
-
}
|
|
1215
|
-
|
|
1216
|
-
const autoOpenNodes = (): void => {
|
|
1217
|
-
const maxLevel = this._getAutoOpenMaxLevel();
|
|
1218
|
-
let loadingCount = 0;
|
|
1219
|
-
|
|
1220
|
-
const loadAndOpenNode = (node: Node): void => {
|
|
1221
|
-
loadingCount += 1;
|
|
1222
|
-
this._openNodeInternal(node, false, () => {
|
|
1223
|
-
loadingCount -= 1;
|
|
1224
|
-
openNodes();
|
|
1225
|
-
});
|
|
1226
|
-
};
|
|
1227
|
-
|
|
1228
|
-
const openNodes = (): void => {
|
|
1229
|
-
this._tree.iterate((node: Node, level: number) => {
|
|
1230
|
-
if (node.load_on_demand) {
|
|
1231
|
-
if (!node.is_loading) {
|
|
1232
|
-
loadAndOpenNode(node);
|
|
1233
|
-
}
|
|
1234
|
-
|
|
1235
|
-
return false;
|
|
1236
|
-
} else {
|
|
1237
|
-
this._openNodeInternal(node, false);
|
|
1238
|
-
|
|
1239
|
-
return level !== maxLevel;
|
|
1240
|
-
}
|
|
1241
|
-
});
|
|
1242
|
-
|
|
1243
|
-
if (loadingCount === 0) {
|
|
1244
|
-
cbFinished();
|
|
1245
|
-
}
|
|
1246
|
-
};
|
|
1247
|
-
|
|
1248
|
-
openNodes();
|
|
1249
|
-
};
|
|
1250
|
-
|
|
1251
|
-
if (!restoreState()) {
|
|
1252
|
-
autoOpenNodes();
|
|
556
|
+
} else {
|
|
557
|
+
return undefined;
|
|
1253
558
|
}
|
|
1254
|
-
}
|
|
1255
|
-
|
|
1256
|
-
private _triggerEvent(
|
|
1257
|
-
eventName: string,
|
|
1258
|
-
values?: Record<string, unknown>,
|
|
1259
|
-
): boolean {
|
|
1260
|
-
const event = jQuery.Event(eventName, values);
|
|
1261
|
-
this._element.trigger(event);
|
|
1262
|
-
return !event.isDefaultPrevented();
|
|
1263
|
-
}
|
|
1264
|
-
}
|
|
559
|
+
};
|
|
560
|
+
};
|
|
1265
561
|
|
|
1266
|
-
|
|
562
|
+
register();
|