jqtree 1.8.0 → 1.8.2
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/.eslintrc +13 -3
- package/.github/workflows/ci.yml +6 -6
- package/.github/workflows/codeql-analysis.yml +4 -4
- package/.github/workflows/size.yml +3 -3
- package/.github/workflows/static.yml +1 -1
- package/bower.json +1 -1
- package/config/jest.config.js +4 -0
- package/config/jest.polyfills.js +14 -0
- package/devserver/test_index.html +9 -0
- package/docs/.ruby-version +1 -1
- package/docs/_config.yml +1 -1
- package/docs/_entries/general/changelog.md +8 -0
- package/docs/_entries/multiple_selection/get-selected-nodes.md +1 -1
- package/docs/_entries/node/getnextnode.md +3 -6
- package/docs/_entries/node/getnextsibling.md +1 -1
- package/docs/_entries/node/getnextvisiblenode.md +8 -5
- package/docs/_entries/node/getpreviousnode.md +12 -0
- package/docs/_entries/node/getprevioussibling.md +1 -1
- package/docs/_entries/node/getpreviousvisiblenode.md +6 -5
- package/package.json +32 -30
- package/src/dataLoader.ts +19 -21
- package/src/dragAndDropHandler/dragElement.ts +37 -25
- package/src/dragAndDropHandler/generateHitAreas.ts +187 -0
- package/src/dragAndDropHandler/index.ts +32 -48
- package/src/dragAndDropHandler/iterateVisibleNodes.ts +91 -0
- package/src/dragAndDropHandler/types.ts +2 -1
- package/src/mouseHandler.ts +385 -0
- package/src/mouseUtils.ts +23 -0
- package/src/node.ts +1 -29
- package/src/nodeElement/folderElement.ts +1 -1
- package/src/nodeElement/ghostDropHint.ts +2 -1
- package/src/nodeElement/index.ts +2 -1
- package/src/playwright/coverage.ts +3 -3
- package/src/playwright/playwright.test.ts +150 -49
- package/src/playwright/testUtils.ts +28 -5
- package/src/position.ts +28 -0
- package/src/scrollHandler/containerScrollParent.ts +13 -23
- package/src/scrollHandler/createScrollParent.ts +22 -22
- package/src/scrollHandler/documentScrollParent.ts +16 -13
- package/src/scrollHandler.ts +6 -14
- package/src/test/jqTree/events.test.ts +97 -30
- package/src/test/jqTree/loadOnDemand.test.ts +22 -15
- package/src/test/jqTree/methods.test.ts +8 -11
- package/src/test/jqTree/mouse.test.ts +82 -0
- package/src/test/jqTree/options.test.ts +9 -8
- package/src/test/node.test.ts +2 -1
- package/src/test/{nodeUtil.test.ts → position.test.ts} +1 -1
- package/src/tree.jquery.ts +108 -184
- package/src/util.ts +10 -1
- package/src/version.ts +1 -1
- package/tree.jquery.debug.js +2167 -2134
- package/tree.jquery.debug.js.map +1 -1
- package/tree.jquery.js +3 -3
- package/tree.jquery.js.map +1 -1
- package/tsconfig.json +5 -3
- package/docs/_entries/functions/get-selected-nodes.md +0 -10
- package/src/dragAndDropHandler/hitAreasGenerator.ts +0 -175
- package/src/dragAndDropHandler/visibleNodeIterator.ts +0 -97
- package/src/mouse.widget.ts +0 -266
- package/src/mouseWidgetTypes.ts +0 -6
package/tree.jquery.debug.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
|
-
JqTree 1.8.
|
|
2
|
+
JqTree 1.8.2
|
|
3
3
|
|
|
4
|
-
Copyright
|
|
4
|
+
Copyright 2024 Marco Braak
|
|
5
5
|
|
|
6
6
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
7
|
you may not use this file except in compliance with the License.
|
|
@@ -20,9 +20,7 @@ limitations under the License.
|
|
|
20
20
|
var jqtree = (function (exports) {
|
|
21
21
|
'use strict';
|
|
22
22
|
|
|
23
|
-
const version = "1.8.
|
|
24
|
-
|
|
25
|
-
const isNodeRecordWithChildren = data => typeof data === "object" && "children" in data && data["children"] instanceof Array;
|
|
23
|
+
const version = "1.8.2";
|
|
26
24
|
|
|
27
25
|
let Position = /*#__PURE__*/function (Position) {
|
|
28
26
|
Position[Position["Before"] = 1] = "Before";
|
|
@@ -48,2360 +46,2452 @@ var jqtree = (function (exports) {
|
|
|
48
46
|
return "";
|
|
49
47
|
};
|
|
50
48
|
const getPosition = name => positionNames[name];
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
let
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
this.
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
49
|
+
|
|
50
|
+
class DragElement {
|
|
51
|
+
constructor(_ref) {
|
|
52
|
+
let {
|
|
53
|
+
autoEscape,
|
|
54
|
+
nodeName,
|
|
55
|
+
offsetX,
|
|
56
|
+
offsetY,
|
|
57
|
+
treeElement
|
|
58
|
+
} = _ref;
|
|
59
|
+
this.offsetX = offsetX;
|
|
60
|
+
this.offsetY = offsetY;
|
|
61
|
+
this.element = this.createElement(nodeName, autoEscape);
|
|
62
|
+
treeElement.appendChild(this.element);
|
|
63
|
+
}
|
|
64
|
+
move(pageX, pageY) {
|
|
65
|
+
this.element.style.left = `${pageX - this.offsetX}px`;
|
|
66
|
+
this.element.style.top = `${pageY - this.offsetY}px`;
|
|
67
|
+
}
|
|
68
|
+
remove() {
|
|
69
|
+
this.element.remove();
|
|
70
|
+
}
|
|
71
|
+
createElement(nodeName, autoEscape) {
|
|
72
|
+
const element = document.createElement("span");
|
|
73
|
+
element.classList.add("jqtree-title", "jqtree-dragging");
|
|
74
|
+
if (autoEscape) {
|
|
75
|
+
element.textContent = nodeName;
|
|
76
|
+
} else {
|
|
77
|
+
element.innerHTML = nodeName;
|
|
66
78
|
}
|
|
79
|
+
element.style.position = "absolute";
|
|
80
|
+
return element;
|
|
67
81
|
}
|
|
82
|
+
}
|
|
68
83
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
84
|
+
const isInt = n => typeof n === "number" && n % 1 === 0;
|
|
85
|
+
const isFunction = v => typeof v === "function";
|
|
86
|
+
const getBoolString = value => value ? "true" : "false";
|
|
87
|
+
const getOffsetTop = element => getElementPosition(element).top;
|
|
88
|
+
const getElementPosition = element => {
|
|
89
|
+
const rect = element.getBoundingClientRect();
|
|
90
|
+
return {
|
|
91
|
+
left: rect.x + window.scrollX,
|
|
92
|
+
top: rect.y + window.scrollY
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const iterateVisibleNodes = (tree, _ref) => {
|
|
97
|
+
let {
|
|
98
|
+
handleAfterOpenFolder,
|
|
99
|
+
handleClosedFolder,
|
|
100
|
+
handleFirstNode,
|
|
101
|
+
handleNode,
|
|
102
|
+
handleOpenFolder
|
|
103
|
+
} = _ref;
|
|
104
|
+
let isFirstNode = true;
|
|
105
|
+
const iterate = (node, nextNode) => {
|
|
106
|
+
let mustIterateInside = (node.is_open || !node.element) && node.hasChildren();
|
|
107
|
+
let element = null;
|
|
108
|
+
|
|
109
|
+
// Is the element visible?
|
|
110
|
+
if (node.element?.offsetParent) {
|
|
111
|
+
element = node.element;
|
|
112
|
+
if (isFirstNode) {
|
|
113
|
+
handleFirstNode(node);
|
|
114
|
+
isFirstNode = false;
|
|
115
|
+
}
|
|
116
|
+
if (!node.hasChildren()) {
|
|
117
|
+
handleNode(node, nextNode, node.element);
|
|
118
|
+
} else if (node.is_open) {
|
|
119
|
+
if (!handleOpenFolder(node, node.element)) {
|
|
120
|
+
mustIterateInside = false;
|
|
121
|
+
}
|
|
122
|
+
} else {
|
|
123
|
+
handleClosedFolder(node, nextNode, element);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (mustIterateInside) {
|
|
127
|
+
const childrenLength = node.children.length;
|
|
128
|
+
node.children.forEach((_, i) => {
|
|
129
|
+
const child = node.children[i];
|
|
130
|
+
if (child) {
|
|
131
|
+
if (i === childrenLength - 1) {
|
|
132
|
+
iterate(child, null);
|
|
133
|
+
} else {
|
|
134
|
+
const nextChild = node.children[i + 1];
|
|
135
|
+
if (nextChild) {
|
|
136
|
+
iterate(child, nextChild);
|
|
93
137
|
}
|
|
94
|
-
} else if (key !== "children" && key !== "parent") {
|
|
95
|
-
// You can't update the children or the parent using this function
|
|
96
|
-
this[key] = value;
|
|
97
138
|
}
|
|
98
139
|
}
|
|
140
|
+
});
|
|
141
|
+
if (node.is_open && element) {
|
|
142
|
+
handleAfterOpenFolder(node, nextNode);
|
|
99
143
|
}
|
|
100
144
|
}
|
|
101
|
-
}
|
|
145
|
+
};
|
|
146
|
+
iterate(tree, null);
|
|
147
|
+
};
|
|
102
148
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
149
|
+
const generatePositions = (tree, currentNode) => {
|
|
150
|
+
const positions = [];
|
|
151
|
+
let lastTop = 0;
|
|
152
|
+
const addPosition = (node, position, top) => {
|
|
153
|
+
const area = {
|
|
154
|
+
top,
|
|
155
|
+
bottom: 0,
|
|
156
|
+
node,
|
|
157
|
+
position
|
|
158
|
+
};
|
|
159
|
+
positions.push(area);
|
|
160
|
+
lastTop = top;
|
|
161
|
+
};
|
|
162
|
+
const handleAfterOpenFolder = (node, nextNode) => {
|
|
163
|
+
if (node === currentNode || nextNode === currentNode) {
|
|
164
|
+
// Cannot move before or after current item
|
|
165
|
+
addPosition(node, Position.None, lastTop);
|
|
166
|
+
} else {
|
|
167
|
+
addPosition(node, Position.After, lastTop);
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
const handleClosedFolder = (node, nextNode, element) => {
|
|
171
|
+
const top = getOffsetTop(element);
|
|
172
|
+
if (node === currentNode) {
|
|
173
|
+
// Cannot move after current item
|
|
174
|
+
addPosition(node, Position.None, top);
|
|
175
|
+
} else {
|
|
176
|
+
addPosition(node, Position.Inside, top);
|
|
177
|
+
|
|
178
|
+
// Cannot move before current item
|
|
179
|
+
if (nextNode !== currentNode) {
|
|
180
|
+
addPosition(node, Position.After, top);
|
|
126
181
|
}
|
|
127
182
|
}
|
|
128
|
-
|
|
129
|
-
|
|
183
|
+
};
|
|
184
|
+
const handleFirstNode = node => {
|
|
185
|
+
if (node !== currentNode) {
|
|
186
|
+
addPosition(node, Position.Before, getOffsetTop(node.element));
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
const handleNode = (node, nextNode, element) => {
|
|
190
|
+
const top = getOffsetTop(element);
|
|
191
|
+
if (node === currentNode) {
|
|
192
|
+
// Cannot move inside current item
|
|
193
|
+
addPosition(node, Position.None, top);
|
|
194
|
+
} else {
|
|
195
|
+
addPosition(node, Position.Inside, top);
|
|
196
|
+
}
|
|
197
|
+
if (nextNode === currentNode || node === currentNode) {
|
|
198
|
+
// Cannot move before or after current item
|
|
199
|
+
addPosition(node, Position.None, top);
|
|
200
|
+
} else {
|
|
201
|
+
addPosition(node, Position.After, top);
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
const handleOpenFolder = (node, element) => {
|
|
205
|
+
if (node === currentNode) {
|
|
206
|
+
// Cannot move inside current item
|
|
130
207
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
node.setParent(this);
|
|
140
|
-
}
|
|
208
|
+
// Dnd over the current element is not possible: add a position with type None for the top and the bottom.
|
|
209
|
+
const top = getOffsetTop(element);
|
|
210
|
+
const height = element.clientHeight;
|
|
211
|
+
addPosition(node, Position.None, top);
|
|
212
|
+
if (height > 5) {
|
|
213
|
+
// Subtract 5 pixels to allow more space for the next element.
|
|
214
|
+
addPosition(node, Position.None, top + height - 5);
|
|
215
|
+
}
|
|
141
216
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
new Node('abc'),
|
|
146
|
-
1
|
|
147
|
-
);
|
|
148
|
-
*/
|
|
149
|
-
addChildAtPosition(node, index) {
|
|
150
|
-
this.children.splice(index, 0, node);
|
|
151
|
-
node.setParent(this);
|
|
152
|
-
}
|
|
217
|
+
// Stop iterating
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
153
220
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
removeChild(node) {
|
|
159
|
-
// remove children from the index
|
|
160
|
-
node.removeChildren();
|
|
161
|
-
this.doRemoveChild(node);
|
|
162
|
-
}
|
|
221
|
+
// Cannot move before current item
|
|
222
|
+
if (node.children[0] !== currentNode) {
|
|
223
|
+
addPosition(node, Position.Inside, getOffsetTop(element));
|
|
224
|
+
}
|
|
163
225
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
226
|
+
// Continue iterating
|
|
227
|
+
return true;
|
|
228
|
+
};
|
|
229
|
+
iterateVisibleNodes(tree, {
|
|
230
|
+
handleAfterOpenFolder,
|
|
231
|
+
handleClosedFolder,
|
|
232
|
+
handleFirstNode,
|
|
233
|
+
handleNode,
|
|
234
|
+
handleOpenFolder
|
|
235
|
+
});
|
|
236
|
+
return positions;
|
|
237
|
+
};
|
|
238
|
+
const generateHitAreasForGroup = (hitAreas, positionsInGroup, top, bottom) => {
|
|
239
|
+
// limit positions in group
|
|
240
|
+
const positionCount = Math.min(positionsInGroup.length, 4);
|
|
241
|
+
const areaHeight = Math.round((bottom - top) / positionCount);
|
|
242
|
+
let areaTop = top;
|
|
243
|
+
let i = 0;
|
|
244
|
+
while (i < positionCount) {
|
|
245
|
+
const position = positionsInGroup[i];
|
|
246
|
+
if (position && position.position !== Position.None) {
|
|
247
|
+
hitAreas.push({
|
|
248
|
+
top: areaTop,
|
|
249
|
+
bottom: areaTop + areaHeight,
|
|
250
|
+
node: position.node,
|
|
251
|
+
position: position.position
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
areaTop += areaHeight;
|
|
255
|
+
i += 1;
|
|
170
256
|
}
|
|
257
|
+
};
|
|
258
|
+
const generateHitAreasFromPositions = (positions, treeBottom) => {
|
|
259
|
+
let previousTop = positions[0]?.top ?? 0;
|
|
260
|
+
let group = [];
|
|
261
|
+
const hitAreas = [];
|
|
262
|
+
for (const position of positions) {
|
|
263
|
+
if (position.top !== previousTop && group.length) {
|
|
264
|
+
generateHitAreasForGroup(hitAreas, group, previousTop, position.top);
|
|
265
|
+
previousTop = position.top;
|
|
266
|
+
group = [];
|
|
267
|
+
}
|
|
268
|
+
group.push(position);
|
|
269
|
+
}
|
|
270
|
+
generateHitAreasForGroup(hitAreas, group, previousTop, treeBottom);
|
|
271
|
+
return hitAreas;
|
|
272
|
+
};
|
|
273
|
+
const generateHitAreas = (tree, currentNode, treeBottom) => {
|
|
274
|
+
const positions = generatePositions(tree, currentNode);
|
|
275
|
+
return generateHitAreasFromPositions(positions, treeBottom);
|
|
276
|
+
};
|
|
171
277
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
278
|
+
class DragAndDropHandler {
|
|
279
|
+
constructor(_ref) {
|
|
280
|
+
let {
|
|
281
|
+
autoEscape,
|
|
282
|
+
getNodeElement,
|
|
283
|
+
getNodeElementForNode,
|
|
284
|
+
getScrollLeft,
|
|
285
|
+
getTree,
|
|
286
|
+
onCanMove,
|
|
287
|
+
onCanMoveTo,
|
|
288
|
+
onDragMove,
|
|
289
|
+
onDragStop,
|
|
290
|
+
onIsMoveHandle,
|
|
291
|
+
openNode,
|
|
292
|
+
refreshElements,
|
|
293
|
+
slide,
|
|
294
|
+
treeElement,
|
|
295
|
+
triggerEvent
|
|
296
|
+
} = _ref;
|
|
297
|
+
this.autoEscape = autoEscape;
|
|
298
|
+
this.getNodeElement = getNodeElement;
|
|
299
|
+
this.getNodeElementForNode = getNodeElementForNode;
|
|
300
|
+
this.getScrollLeft = getScrollLeft;
|
|
301
|
+
this.getTree = getTree;
|
|
302
|
+
this.onCanMove = onCanMove;
|
|
303
|
+
this.onCanMoveTo = onCanMoveTo;
|
|
304
|
+
this.onDragMove = onDragMove;
|
|
305
|
+
this.onDragStop = onDragStop;
|
|
306
|
+
this.onIsMoveHandle = onIsMoveHandle;
|
|
307
|
+
this.openNode = openNode;
|
|
308
|
+
this.refreshElements = refreshElements;
|
|
309
|
+
this.slide = slide;
|
|
310
|
+
this.treeElement = treeElement;
|
|
311
|
+
this.triggerEvent = triggerEvent;
|
|
312
|
+
this.hoveredArea = null;
|
|
313
|
+
this.hitAreas = [];
|
|
314
|
+
this.isDragging = false;
|
|
315
|
+
this.currentItem = null;
|
|
176
316
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
317
|
+
mouseCapture(positionInfo) {
|
|
318
|
+
const element = positionInfo.target;
|
|
319
|
+
if (!this.mustCaptureElement(element)) {
|
|
320
|
+
return null;
|
|
321
|
+
}
|
|
322
|
+
if (this.onIsMoveHandle && !this.onIsMoveHandle(jQuery(element))) {
|
|
323
|
+
return null;
|
|
324
|
+
}
|
|
325
|
+
let nodeElement = this.getNodeElement(element);
|
|
326
|
+
if (nodeElement && this.onCanMove) {
|
|
327
|
+
if (!this.onCanMove(nodeElement.node)) {
|
|
328
|
+
nodeElement = null;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
this.currentItem = nodeElement;
|
|
332
|
+
return this.currentItem != null;
|
|
180
333
|
}
|
|
181
|
-
|
|
182
|
-
|
|
334
|
+
mouseStart(positionInfo) {
|
|
335
|
+
if (!this.currentItem) {
|
|
336
|
+
return false;
|
|
337
|
+
}
|
|
338
|
+
this.refresh();
|
|
339
|
+
const {
|
|
340
|
+
left,
|
|
341
|
+
top
|
|
342
|
+
} = getElementPosition(positionInfo.target);
|
|
343
|
+
const node = this.currentItem.node;
|
|
344
|
+
this.dragElement = new DragElement({
|
|
345
|
+
autoEscape: this.autoEscape ?? true,
|
|
346
|
+
nodeName: node.name,
|
|
347
|
+
offsetX: positionInfo.pageX - left,
|
|
348
|
+
offsetY: positionInfo.pageY - top,
|
|
349
|
+
treeElement: this.treeElement
|
|
350
|
+
});
|
|
351
|
+
this.isDragging = true;
|
|
352
|
+
this.currentItem.element.classList.add("jqtree-moving");
|
|
353
|
+
return true;
|
|
183
354
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
return (level <= 2);
|
|
355
|
+
mouseDrag(positionInfo) {
|
|
356
|
+
if (!this.currentItem || !this.dragElement) {
|
|
357
|
+
return false;
|
|
358
|
+
}
|
|
359
|
+
this.dragElement.move(positionInfo.pageX, positionInfo.pageY);
|
|
360
|
+
const area = this.findHoveredArea(positionInfo.pageX, positionInfo.pageY);
|
|
361
|
+
if (area && this.canMoveToArea(area)) {
|
|
362
|
+
if (!area.node.isFolder()) {
|
|
363
|
+
this.stopOpenFolderTimer();
|
|
194
364
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
_iterate(child, level + 1);
|
|
204
|
-
}
|
|
365
|
+
if (this.hoveredArea !== area) {
|
|
366
|
+
this.hoveredArea = area;
|
|
367
|
+
|
|
368
|
+
// If this is a closed folder, start timer to open it
|
|
369
|
+
if (this.mustOpenFolderTimer(area)) {
|
|
370
|
+
this.startOpenFolderTimer(area.node);
|
|
371
|
+
} else {
|
|
372
|
+
this.stopOpenFolderTimer();
|
|
205
373
|
}
|
|
374
|
+
this.updateDropHint();
|
|
206
375
|
}
|
|
207
|
-
};
|
|
208
|
-
_iterate(this, 0);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/*
|
|
212
|
-
Move node relative to another node.
|
|
213
|
-
Argument position: Position.BEFORE, Position.AFTER or Position.Inside
|
|
214
|
-
// move node1 after node2
|
|
215
|
-
tree.moveNode(node1, node2, Position.AFTER);
|
|
216
|
-
*/
|
|
217
|
-
moveNode(movedNode, targetNode, position) {
|
|
218
|
-
if (!movedNode.parent || movedNode.isParentOf(targetNode)) {
|
|
219
|
-
// - Node is parent of target node
|
|
220
|
-
// - Or, parent is empty
|
|
221
|
-
return false;
|
|
222
376
|
} else {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
}
|
|
231
|
-
return false;
|
|
232
|
-
}
|
|
233
|
-
case Position.Before:
|
|
234
|
-
{
|
|
235
|
-
if (targetNode.parent) {
|
|
236
|
-
targetNode.parent.addChildAtPosition(movedNode, targetNode.parent.getChildIndex(targetNode));
|
|
237
|
-
return true;
|
|
238
|
-
}
|
|
239
|
-
return false;
|
|
240
|
-
}
|
|
241
|
-
case Position.Inside:
|
|
242
|
-
{
|
|
243
|
-
// move inside as first child
|
|
244
|
-
targetNode.addChildAtPosition(movedNode, 0);
|
|
245
|
-
return true;
|
|
246
|
-
}
|
|
247
|
-
default:
|
|
248
|
-
return false;
|
|
377
|
+
this.removeDropHint();
|
|
378
|
+
this.stopOpenFolderTimer();
|
|
379
|
+
this.hoveredArea = area;
|
|
380
|
+
}
|
|
381
|
+
if (!area) {
|
|
382
|
+
if (this.onDragMove) {
|
|
383
|
+
this.onDragMove(this.currentItem.node, positionInfo.originalEvent);
|
|
249
384
|
}
|
|
250
385
|
}
|
|
386
|
+
return true;
|
|
251
387
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
const
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
if (["parent", "children", "element", "idMapping", "load_on_demand", "nodeClass", "tree", "isEmptyFolder"].indexOf(k) === -1 && Object.prototype.hasOwnProperty.call(node, k)) {
|
|
263
|
-
const v = node[k];
|
|
264
|
-
tmpNode[k] = v;
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
if (node.hasChildren()) {
|
|
268
|
-
tmpNode["children"] = getDataFromNodes(node.children);
|
|
269
|
-
}
|
|
270
|
-
return tmpNode;
|
|
271
|
-
});
|
|
272
|
-
};
|
|
273
|
-
if (includeParent) {
|
|
274
|
-
return getDataFromNodes([this]);
|
|
275
|
-
} else {
|
|
276
|
-
return getDataFromNodes(this.children);
|
|
388
|
+
mouseStop(positionInfo) {
|
|
389
|
+
this.moveItem(positionInfo);
|
|
390
|
+
this.clear();
|
|
391
|
+
this.removeHover();
|
|
392
|
+
this.removeDropHint();
|
|
393
|
+
this.removeHitAreas();
|
|
394
|
+
const currentItem = this.currentItem;
|
|
395
|
+
if (this.currentItem) {
|
|
396
|
+
this.currentItem.element.classList.remove("jqtree-moving");
|
|
397
|
+
this.currentItem = null;
|
|
277
398
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
const node = this.getNodeByCallback(n => n.name === name);
|
|
284
|
-
if (!node) {
|
|
285
|
-
throw `Node with name ${name} not found`;
|
|
399
|
+
this.isDragging = false;
|
|
400
|
+
if (!this.hoveredArea && currentItem) {
|
|
401
|
+
if (this.onDragStop) {
|
|
402
|
+
this.onDragStop(currentItem.node, positionInfo.originalEvent);
|
|
403
|
+
}
|
|
286
404
|
}
|
|
287
|
-
return
|
|
405
|
+
return false;
|
|
288
406
|
}
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
this.
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
return false;
|
|
297
|
-
} else {
|
|
298
|
-
return true;
|
|
407
|
+
refresh() {
|
|
408
|
+
this.removeHitAreas();
|
|
409
|
+
if (this.currentItem) {
|
|
410
|
+
this.generateHitAreas();
|
|
411
|
+
this.currentItem = this.getNodeElementForNode(this.currentItem.node);
|
|
412
|
+
if (this.isDragging) {
|
|
413
|
+
this.currentItem.element.classList.add("jqtree-moving");
|
|
299
414
|
}
|
|
300
|
-
});
|
|
301
|
-
return result;
|
|
302
|
-
}
|
|
303
|
-
addAfter(nodeInfo) {
|
|
304
|
-
if (!this.parent) {
|
|
305
|
-
return null;
|
|
306
|
-
} else {
|
|
307
|
-
const node = this.createNode(nodeInfo);
|
|
308
|
-
const childIndex = this.parent.getChildIndex(this);
|
|
309
|
-
this.parent.addChildAtPosition(node, childIndex + 1);
|
|
310
|
-
node.loadChildrenFromData(nodeInfo);
|
|
311
|
-
return node;
|
|
312
415
|
}
|
|
313
416
|
}
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
417
|
+
generateHitAreas() {
|
|
418
|
+
const tree = this.getTree();
|
|
419
|
+
if (!this.currentItem || !tree) {
|
|
420
|
+
this.hitAreas = [];
|
|
317
421
|
} else {
|
|
318
|
-
|
|
319
|
-
const childIndex = this.parent.getChildIndex(this);
|
|
320
|
-
this.parent.addChildAtPosition(node, childIndex);
|
|
321
|
-
node.loadChildrenFromData(nodeInfo);
|
|
322
|
-
return node;
|
|
422
|
+
this.hitAreas = generateHitAreas(tree, this.currentItem.node, this.getTreeDimensions().bottom);
|
|
323
423
|
}
|
|
324
424
|
}
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
} else {
|
|
329
|
-
const newParent = this.createNode(nodeInfo);
|
|
330
|
-
if (this.tree) {
|
|
331
|
-
newParent.setParent(this.tree);
|
|
332
|
-
}
|
|
333
|
-
const originalParent = this.parent;
|
|
334
|
-
for (const child of originalParent.children) {
|
|
335
|
-
newParent.addChild(child);
|
|
336
|
-
}
|
|
337
|
-
originalParent.children = [];
|
|
338
|
-
originalParent.addChild(newParent);
|
|
339
|
-
return newParent;
|
|
340
|
-
}
|
|
425
|
+
mustCaptureElement(element) {
|
|
426
|
+
const nodeName = element.nodeName;
|
|
427
|
+
return nodeName !== "INPUT" && nodeName !== "SELECT" && nodeName !== "TEXTAREA";
|
|
341
428
|
}
|
|
342
|
-
|
|
343
|
-
if (this.
|
|
344
|
-
|
|
345
|
-
this.parent = null;
|
|
429
|
+
canMoveToArea(area) {
|
|
430
|
+
if (!this.onCanMoveTo) {
|
|
431
|
+
return true;
|
|
346
432
|
}
|
|
433
|
+
if (!this.currentItem) {
|
|
434
|
+
return false;
|
|
435
|
+
}
|
|
436
|
+
const positionName = getPositionName(area.position);
|
|
437
|
+
return this.onCanMoveTo(this.currentItem.node, area.node, positionName);
|
|
347
438
|
}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
this.addChild(node);
|
|
351
|
-
node.loadChildrenFromData(nodeInfo);
|
|
352
|
-
return node;
|
|
353
|
-
}
|
|
354
|
-
prepend(nodeInfo) {
|
|
355
|
-
const node = this.createNode(nodeInfo);
|
|
356
|
-
this.addChildAtPosition(node, 0);
|
|
357
|
-
node.loadChildrenFromData(nodeInfo);
|
|
358
|
-
return node;
|
|
439
|
+
removeHitAreas() {
|
|
440
|
+
this.hitAreas = [];
|
|
359
441
|
}
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
return true;
|
|
365
|
-
}
|
|
366
|
-
parent = parent.parent;
|
|
442
|
+
clear() {
|
|
443
|
+
if (this.dragElement) {
|
|
444
|
+
this.dragElement.remove();
|
|
445
|
+
this.dragElement = null;
|
|
367
446
|
}
|
|
368
|
-
return false;
|
|
369
447
|
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
while (node.parent) {
|
|
375
|
-
level += 1;
|
|
376
|
-
node = node.parent;
|
|
448
|
+
removeDropHint() {
|
|
449
|
+
if (this.previousGhost) {
|
|
450
|
+
this.previousGhost.remove();
|
|
377
451
|
}
|
|
378
|
-
return level;
|
|
379
|
-
}
|
|
380
|
-
getNodeById(nodeId) {
|
|
381
|
-
return this.idMapping.get(nodeId) || null;
|
|
382
452
|
}
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
this.idMapping.set(node.id, node);
|
|
386
|
-
}
|
|
453
|
+
removeHover() {
|
|
454
|
+
this.hoveredArea = null;
|
|
387
455
|
}
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
456
|
+
findHoveredArea(x, y) {
|
|
457
|
+
const dimensions = this.getTreeDimensions();
|
|
458
|
+
if (x < dimensions.left || y < dimensions.top || x > dimensions.right || y > dimensions.bottom) {
|
|
459
|
+
return null;
|
|
391
460
|
}
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
this.children = [];
|
|
399
|
-
}
|
|
400
|
-
getPreviousSibling() {
|
|
401
|
-
if (!this.parent) {
|
|
402
|
-
return null;
|
|
403
|
-
} else {
|
|
404
|
-
const previousIndex = this.parent.getChildIndex(this) - 1;
|
|
405
|
-
if (previousIndex >= 0) {
|
|
406
|
-
return this.parent.children[previousIndex] || null;
|
|
407
|
-
} else {
|
|
461
|
+
let low = 0;
|
|
462
|
+
let high = this.hitAreas.length;
|
|
463
|
+
while (low < high) {
|
|
464
|
+
const mid = low + high >> 1;
|
|
465
|
+
const area = this.hitAreas[mid];
|
|
466
|
+
if (!area) {
|
|
408
467
|
return null;
|
|
409
468
|
}
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
return null;
|
|
415
|
-
} else {
|
|
416
|
-
const nextIndex = this.parent.getChildIndex(this) + 1;
|
|
417
|
-
if (nextIndex < this.parent.children.length) {
|
|
418
|
-
return this.parent.children[nextIndex] || null;
|
|
469
|
+
if (y < area.top) {
|
|
470
|
+
high = mid;
|
|
471
|
+
} else if (y > area.bottom) {
|
|
472
|
+
low = mid + 1;
|
|
419
473
|
} else {
|
|
420
|
-
return
|
|
474
|
+
return area;
|
|
421
475
|
}
|
|
422
476
|
}
|
|
477
|
+
return null;
|
|
423
478
|
}
|
|
424
|
-
|
|
425
|
-
|
|
479
|
+
mustOpenFolderTimer(area) {
|
|
480
|
+
const node = area.node;
|
|
481
|
+
return node.isFolder() && !node.is_open && area.position === Position.Inside;
|
|
426
482
|
}
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
483
|
+
updateDropHint() {
|
|
484
|
+
if (!this.hoveredArea) {
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
// remove previous drop hint
|
|
489
|
+
this.removeDropHint();
|
|
490
|
+
|
|
491
|
+
// add new drop hint
|
|
492
|
+
const nodeElement = this.getNodeElementForNode(this.hoveredArea.node);
|
|
493
|
+
this.previousGhost = nodeElement.addDropHint(this.hoveredArea.position);
|
|
436
494
|
}
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
return this.parent.getNextNode(false);
|
|
449
|
-
}
|
|
495
|
+
startOpenFolderTimer(folder) {
|
|
496
|
+
const openFolder = () => {
|
|
497
|
+
this.openNode(folder, this.slide, () => {
|
|
498
|
+
this.refresh();
|
|
499
|
+
this.updateDropHint();
|
|
500
|
+
});
|
|
501
|
+
};
|
|
502
|
+
this.stopOpenFolderTimer();
|
|
503
|
+
const openFolderDelay = this.openFolderDelay;
|
|
504
|
+
if (openFolderDelay !== false) {
|
|
505
|
+
this.openFolderTimer = window.setTimeout(openFolder, openFolderDelay);
|
|
450
506
|
}
|
|
451
507
|
}
|
|
452
|
-
|
|
453
|
-
if (this.
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
508
|
+
stopOpenFolderTimer() {
|
|
509
|
+
if (this.openFolderTimer) {
|
|
510
|
+
clearTimeout(this.openFolderTimer);
|
|
511
|
+
this.openFolderTimer = null;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
moveItem(positionInfo) {
|
|
515
|
+
if (this.currentItem && this.hoveredArea && this.hoveredArea.position !== Position.None && this.canMoveToArea(this.hoveredArea)) {
|
|
516
|
+
const movedNode = this.currentItem.node;
|
|
517
|
+
const targetNode = this.hoveredArea.node;
|
|
518
|
+
const position = this.hoveredArea.position;
|
|
519
|
+
const previousParent = movedNode.parent;
|
|
520
|
+
if (position === Position.Inside) {
|
|
521
|
+
this.hoveredArea.node.is_open = true;
|
|
522
|
+
}
|
|
523
|
+
const doMove = () => {
|
|
524
|
+
const tree = this.getTree();
|
|
525
|
+
if (tree) {
|
|
526
|
+
tree.moveNode(movedNode, targetNode, position);
|
|
527
|
+
this.treeElement.textContent = "";
|
|
528
|
+
this.refreshElements(null);
|
|
529
|
+
}
|
|
530
|
+
};
|
|
531
|
+
const event = this.triggerEvent("tree.move", {
|
|
532
|
+
move_info: {
|
|
533
|
+
moved_node: movedNode,
|
|
534
|
+
target_node: targetNode,
|
|
535
|
+
position: getPositionName(position),
|
|
536
|
+
previous_parent: previousParent,
|
|
537
|
+
do_move: doMove,
|
|
538
|
+
original_event: positionInfo.originalEvent
|
|
467
539
|
}
|
|
540
|
+
});
|
|
541
|
+
if (!event.isDefaultPrevented()) {
|
|
542
|
+
doMove();
|
|
468
543
|
}
|
|
469
544
|
}
|
|
470
545
|
}
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
546
|
+
getTreeDimensions() {
|
|
547
|
+
// Return the dimensions of the tree. Add a margin to the bottom to allow
|
|
548
|
+
// to drag-and-drop after the last element.
|
|
549
|
+
const treePosition = getElementPosition(this.treeElement);
|
|
550
|
+
const left = treePosition.left + this.getScrollLeft();
|
|
551
|
+
const top = treePosition.top;
|
|
552
|
+
return {
|
|
553
|
+
left,
|
|
554
|
+
top,
|
|
555
|
+
right: left + this.treeElement.clientWidth,
|
|
556
|
+
bottom: top + this.treeElement.clientHeight + 16
|
|
557
|
+
};
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
class ElementsRenderer {
|
|
562
|
+
constructor(_ref) {
|
|
563
|
+
let {
|
|
564
|
+
autoEscape,
|
|
565
|
+
buttonLeft,
|
|
566
|
+
closedIcon,
|
|
567
|
+
onCreateLi,
|
|
568
|
+
dragAndDrop,
|
|
569
|
+
$element,
|
|
570
|
+
getTree,
|
|
571
|
+
isNodeSelected,
|
|
572
|
+
openedIcon,
|
|
573
|
+
rtl,
|
|
574
|
+
showEmptyFolder,
|
|
575
|
+
tabIndex
|
|
576
|
+
} = _ref;
|
|
577
|
+
this.autoEscape = autoEscape;
|
|
578
|
+
this.buttonLeft = buttonLeft;
|
|
579
|
+
this.dragAndDrop = dragAndDrop;
|
|
580
|
+
this.$element = $element;
|
|
581
|
+
this.getTree = getTree;
|
|
582
|
+
this.isNodeSelected = isNodeSelected;
|
|
583
|
+
this.onCreateLi = onCreateLi;
|
|
584
|
+
this.rtl = rtl;
|
|
585
|
+
this.showEmptyFolder = showEmptyFolder;
|
|
586
|
+
this.tabIndex = tabIndex;
|
|
587
|
+
this.openedIconElement = this.createButtonElement(openedIcon || "+");
|
|
588
|
+
this.closedIconElement = this.createButtonElement(closedIcon || "-");
|
|
589
|
+
}
|
|
590
|
+
render(fromNode) {
|
|
591
|
+
if (fromNode && fromNode.parent) {
|
|
592
|
+
this.renderFromNode(fromNode);
|
|
474
593
|
} else {
|
|
475
|
-
|
|
476
|
-
if (!previousSibling) {
|
|
477
|
-
return this.getParent();
|
|
478
|
-
} else if (previousSibling.hasChildren()) {
|
|
479
|
-
return previousSibling.getLastChild();
|
|
480
|
-
} else {
|
|
481
|
-
return previousSibling;
|
|
482
|
-
}
|
|
594
|
+
this.renderFromRoot();
|
|
483
595
|
}
|
|
484
596
|
}
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
if (!previousSibling) {
|
|
491
|
-
return this.getParent();
|
|
492
|
-
} else if (!previousSibling.hasChildren() || !previousSibling.is_open) {
|
|
493
|
-
// Previous sibling
|
|
494
|
-
return previousSibling;
|
|
495
|
-
} else {
|
|
496
|
-
// Last child of previous sibling
|
|
497
|
-
return previousSibling.getLastChild();
|
|
498
|
-
}
|
|
597
|
+
renderFromRoot() {
|
|
598
|
+
this.$element.empty();
|
|
599
|
+
const tree = this.getTree();
|
|
600
|
+
if (this.$element[0] && tree) {
|
|
601
|
+
this.createDomElements(this.$element[0], tree.children, true, 1);
|
|
499
602
|
}
|
|
500
603
|
}
|
|
501
|
-
|
|
502
|
-
//
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
604
|
+
renderFromNode(node) {
|
|
605
|
+
// remember current li
|
|
606
|
+
const $previousLi = jQuery(node.element);
|
|
607
|
+
|
|
608
|
+
// create element
|
|
609
|
+
const li = this.createLi(node, node.getLevel());
|
|
610
|
+
this.attachNodeData(node, li);
|
|
611
|
+
|
|
612
|
+
// add element to dom
|
|
613
|
+
$previousLi.after(li);
|
|
614
|
+
|
|
615
|
+
// remove previous li
|
|
616
|
+
$previousLi.remove();
|
|
617
|
+
|
|
618
|
+
// create children
|
|
619
|
+
if (node.children) {
|
|
620
|
+
this.createDomElements(li, node.children, false, node.getLevel() + 1);
|
|
510
621
|
}
|
|
511
622
|
}
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
const
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
return lastChild;
|
|
522
|
-
} else {
|
|
523
|
-
return lastChild?.getLastChild();
|
|
623
|
+
createDomElements(element, children, isRootNode, level) {
|
|
624
|
+
const ul = this.createUl(isRootNode);
|
|
625
|
+
element.appendChild(ul);
|
|
626
|
+
for (const child of children) {
|
|
627
|
+
const li = this.createLi(child, level);
|
|
628
|
+
ul.appendChild(li);
|
|
629
|
+
this.attachNodeData(child, li);
|
|
630
|
+
if (child.hasChildren()) {
|
|
631
|
+
this.createDomElements(li, child.children, false, level + 1);
|
|
524
632
|
}
|
|
525
633
|
}
|
|
526
634
|
}
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
const addNode = nodeData => {
|
|
531
|
-
this.setData(nodeData);
|
|
532
|
-
if (isNodeRecordWithChildren(nodeData) && nodeData.children.length) {
|
|
533
|
-
addChildren(nodeData.children);
|
|
534
|
-
}
|
|
535
|
-
};
|
|
536
|
-
const addChildren = childrenData => {
|
|
537
|
-
for (const child of childrenData) {
|
|
538
|
-
const node = this.createNode();
|
|
539
|
-
node.initFromData(child);
|
|
540
|
-
this.addChild(node);
|
|
541
|
-
}
|
|
542
|
-
};
|
|
543
|
-
addNode(data);
|
|
544
|
-
}
|
|
545
|
-
setParent(parent) {
|
|
546
|
-
this.parent = parent;
|
|
547
|
-
this.tree = parent.tree;
|
|
548
|
-
this.tree?.addNodeToIndex(this);
|
|
549
|
-
}
|
|
550
|
-
doRemoveChild(node) {
|
|
551
|
-
this.children.splice(this.getChildIndex(node), 1);
|
|
552
|
-
this.tree?.removeNodeFromIndex(node);
|
|
553
|
-
}
|
|
554
|
-
getNodeClass() {
|
|
555
|
-
return this.nodeClass || this?.tree?.nodeClass || Node;
|
|
556
|
-
}
|
|
557
|
-
createNode(nodeData) {
|
|
558
|
-
const nodeClass = this.getNodeClass();
|
|
559
|
-
return new nodeClass(nodeData);
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
// Load children data from nodeInfo if it has children
|
|
563
|
-
loadChildrenFromData(nodeInfo) {
|
|
564
|
-
if (isNodeRecordWithChildren(nodeInfo) && nodeInfo.children.length) {
|
|
565
|
-
this.loadFromData(nodeInfo.children);
|
|
566
|
-
}
|
|
635
|
+
attachNodeData(node, li) {
|
|
636
|
+
node.element = li;
|
|
637
|
+
jQuery(li).data("node", node);
|
|
567
638
|
}
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
this.$element = jQuery("<span>").addClass("jqtree-title jqtree-dragging");
|
|
575
|
-
if (autoEscape) {
|
|
576
|
-
this.$element.text(nodeName);
|
|
639
|
+
createUl(isRootNode) {
|
|
640
|
+
let classString;
|
|
641
|
+
let role;
|
|
642
|
+
if (!isRootNode) {
|
|
643
|
+
classString = "";
|
|
644
|
+
role = "group";
|
|
577
645
|
} else {
|
|
578
|
-
|
|
646
|
+
classString = "jqtree-tree";
|
|
647
|
+
role = "tree";
|
|
648
|
+
if (this.rtl) {
|
|
649
|
+
classString += " jqtree-rtl";
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
if (this.dragAndDrop) {
|
|
653
|
+
classString += " jqtree-dnd";
|
|
579
654
|
}
|
|
580
|
-
|
|
581
|
-
$
|
|
655
|
+
const ul = document.createElement("ul");
|
|
656
|
+
ul.className = `jqtree_common ${classString}`;
|
|
657
|
+
ul.setAttribute("role", role);
|
|
658
|
+
return ul;
|
|
582
659
|
}
|
|
583
|
-
|
|
584
|
-
this
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
660
|
+
createLi(node, level) {
|
|
661
|
+
const isSelected = Boolean(this.isNodeSelected(node));
|
|
662
|
+
const mustShowFolder = node.isFolder() || node.isEmptyFolder && this.showEmptyFolder;
|
|
663
|
+
const li = mustShowFolder ? this.createFolderLi(node, level, isSelected) : this.createNodeLi(node, level, isSelected);
|
|
664
|
+
if (this.onCreateLi) {
|
|
665
|
+
this.onCreateLi(node, jQuery(li), isSelected);
|
|
666
|
+
}
|
|
667
|
+
return li;
|
|
588
668
|
}
|
|
589
|
-
|
|
590
|
-
|
|
669
|
+
setTreeItemAriaAttributes(element, name, level, isSelected) {
|
|
670
|
+
element.setAttribute("aria-label", name);
|
|
671
|
+
element.setAttribute("aria-level", `${level}`);
|
|
672
|
+
element.setAttribute("aria-selected", getBoolString(isSelected));
|
|
673
|
+
element.setAttribute("role", "treeitem");
|
|
591
674
|
}
|
|
592
|
-
|
|
675
|
+
createFolderLi(node, level, isSelected) {
|
|
676
|
+
const buttonClasses = this.getButtonClasses(node);
|
|
677
|
+
const folderClasses = this.getFolderClasses(node, isSelected);
|
|
678
|
+
const iconElement = node.is_open ? this.openedIconElement : this.closedIconElement;
|
|
593
679
|
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
class VisibleNodeIterator {
|
|
600
|
-
constructor(tree) {
|
|
601
|
-
this.tree = tree;
|
|
602
|
-
}
|
|
603
|
-
iterate() {
|
|
604
|
-
let isFirstNode = true;
|
|
605
|
-
const _iterateNode = (node, nextNode) => {
|
|
606
|
-
let mustIterateInside = (node.is_open || !node.element) && node.hasChildren();
|
|
607
|
-
let element = null;
|
|
608
|
-
|
|
609
|
-
// Is the element visible?
|
|
610
|
-
if (node.element?.offsetParent) {
|
|
611
|
-
element = node.element;
|
|
612
|
-
if (isFirstNode) {
|
|
613
|
-
this.handleFirstNode(node);
|
|
614
|
-
isFirstNode = false;
|
|
615
|
-
}
|
|
616
|
-
if (!node.hasChildren()) {
|
|
617
|
-
this.handleNode(node, nextNode, node.element);
|
|
618
|
-
} else if (node.is_open) {
|
|
619
|
-
if (!this.handleOpenFolder(node, node.element)) {
|
|
620
|
-
mustIterateInside = false;
|
|
621
|
-
}
|
|
622
|
-
} else {
|
|
623
|
-
this.handleClosedFolder(node, nextNode, element);
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
if (mustIterateInside) {
|
|
627
|
-
const childrenLength = node.children.length;
|
|
628
|
-
node.children.forEach((_, i) => {
|
|
629
|
-
const child = node.children[i];
|
|
630
|
-
if (child) {
|
|
631
|
-
if (i === childrenLength - 1) {
|
|
632
|
-
_iterateNode(child, null);
|
|
633
|
-
} else {
|
|
634
|
-
const nextChild = node.children[i + 1];
|
|
635
|
-
if (nextChild) {
|
|
636
|
-
_iterateNode(child, nextChild);
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
});
|
|
641
|
-
if (node.is_open && element) {
|
|
642
|
-
this.handleAfterOpenFolder(node, nextNode);
|
|
643
|
-
}
|
|
644
|
-
}
|
|
645
|
-
};
|
|
646
|
-
_iterateNode(this.tree, null);
|
|
647
|
-
}
|
|
680
|
+
// li
|
|
681
|
+
const li = document.createElement("li");
|
|
682
|
+
li.className = `jqtree_common ${folderClasses}`;
|
|
683
|
+
li.setAttribute("role", "none");
|
|
648
684
|
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
*/
|
|
655
|
-
}
|
|
685
|
+
// div
|
|
686
|
+
const div = document.createElement("div");
|
|
687
|
+
div.className = "jqtree-element jqtree_common";
|
|
688
|
+
div.setAttribute("role", "none");
|
|
689
|
+
li.appendChild(div);
|
|
656
690
|
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
}
|
|
663
|
-
generate() {
|
|
664
|
-
this.positions = [];
|
|
665
|
-
this.lastTop = 0;
|
|
666
|
-
this.iterate();
|
|
667
|
-
return this.generateHitAreas(this.positions);
|
|
668
|
-
}
|
|
669
|
-
generateHitAreas(positions) {
|
|
670
|
-
let previousTop = positions[0]?.top ?? 0;
|
|
671
|
-
let group = [];
|
|
672
|
-
const hitAreas = [];
|
|
673
|
-
for (const position of positions) {
|
|
674
|
-
if (position.top !== previousTop && group.length) {
|
|
675
|
-
this.generateHitAreasForGroup(hitAreas, group, previousTop, position.top);
|
|
676
|
-
previousTop = position.top;
|
|
677
|
-
group = [];
|
|
678
|
-
}
|
|
679
|
-
group.push(position);
|
|
680
|
-
}
|
|
681
|
-
this.generateHitAreasForGroup(hitAreas, group, previousTop, this.treeBottom);
|
|
682
|
-
return hitAreas;
|
|
683
|
-
}
|
|
684
|
-
handleOpenFolder(node, element) {
|
|
685
|
-
if (node === this.currentNode) {
|
|
686
|
-
// Cannot move inside current item
|
|
687
|
-
// Stop iterating
|
|
688
|
-
return false;
|
|
691
|
+
// button link
|
|
692
|
+
const buttonLink = document.createElement("a");
|
|
693
|
+
buttonLink.className = buttonClasses;
|
|
694
|
+
if (iconElement) {
|
|
695
|
+
buttonLink.appendChild(iconElement.cloneNode(true));
|
|
689
696
|
}
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
if (node.children[0] !== this.currentNode) {
|
|
693
|
-
this.addPosition(node, Position.Inside, getOffsetTop(element));
|
|
697
|
+
if (this.buttonLeft) {
|
|
698
|
+
div.appendChild(buttonLink);
|
|
694
699
|
}
|
|
695
700
|
|
|
696
|
-
//
|
|
697
|
-
|
|
701
|
+
// title span
|
|
702
|
+
const titleSpan = this.createTitleSpan(node.name, isSelected, true, level);
|
|
703
|
+
titleSpan.setAttribute("aria-expanded", getBoolString(node.is_open));
|
|
704
|
+
div.appendChild(titleSpan);
|
|
705
|
+
if (!this.buttonLeft) {
|
|
706
|
+
div.appendChild(buttonLink);
|
|
707
|
+
}
|
|
708
|
+
return li;
|
|
698
709
|
}
|
|
699
|
-
|
|
700
|
-
const
|
|
701
|
-
if (
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
this.addPosition(node, Position.Inside, top);
|
|
710
|
+
createNodeLi(node, level, isSelected) {
|
|
711
|
+
const liClasses = ["jqtree_common"];
|
|
712
|
+
if (isSelected) {
|
|
713
|
+
liClasses.push("jqtree-selected");
|
|
714
|
+
}
|
|
715
|
+
const classString = liClasses.join(" ");
|
|
706
716
|
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
717
|
+
// li
|
|
718
|
+
const li = document.createElement("li");
|
|
719
|
+
li.className = classString;
|
|
720
|
+
li.setAttribute("role", "none");
|
|
721
|
+
|
|
722
|
+
// div
|
|
723
|
+
const div = document.createElement("div");
|
|
724
|
+
div.className = "jqtree-element jqtree_common";
|
|
725
|
+
div.setAttribute("role", "none");
|
|
726
|
+
li.appendChild(div);
|
|
727
|
+
|
|
728
|
+
// title span
|
|
729
|
+
const titleSpan = this.createTitleSpan(node.name, isSelected, false, level);
|
|
730
|
+
div.appendChild(titleSpan);
|
|
731
|
+
return li;
|
|
732
|
+
}
|
|
733
|
+
createTitleSpan(nodeName, isSelected, isFolder, level) {
|
|
734
|
+
const titleSpan = document.createElement("span");
|
|
735
|
+
let classes = "jqtree-title jqtree_common";
|
|
736
|
+
if (isFolder) {
|
|
737
|
+
classes += " jqtree-title-folder";
|
|
738
|
+
}
|
|
739
|
+
classes += ` jqtree-title-button-${this.buttonLeft ? "left" : "right"}`;
|
|
740
|
+
titleSpan.className = classes;
|
|
741
|
+
if (isSelected) {
|
|
742
|
+
const tabIndex = this.tabIndex;
|
|
743
|
+
if (tabIndex !== undefined) {
|
|
744
|
+
titleSpan.setAttribute("tabindex", `${tabIndex}`);
|
|
710
745
|
}
|
|
711
746
|
}
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
747
|
+
this.setTreeItemAriaAttributes(titleSpan, nodeName, level, isSelected);
|
|
748
|
+
if (this.autoEscape) {
|
|
749
|
+
titleSpan.textContent = nodeName;
|
|
750
|
+
} else {
|
|
751
|
+
titleSpan.innerHTML = nodeName;
|
|
716
752
|
}
|
|
753
|
+
return titleSpan;
|
|
717
754
|
}
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
755
|
+
getButtonClasses(node) {
|
|
756
|
+
const classes = ["jqtree-toggler", "jqtree_common"];
|
|
757
|
+
if (!node.is_open) {
|
|
758
|
+
classes.push("jqtree-closed");
|
|
759
|
+
}
|
|
760
|
+
if (this.buttonLeft) {
|
|
761
|
+
classes.push("jqtree-toggler-left");
|
|
722
762
|
} else {
|
|
723
|
-
|
|
763
|
+
classes.push("jqtree-toggler-right");
|
|
724
764
|
}
|
|
765
|
+
return classes.join(" ");
|
|
725
766
|
}
|
|
726
|
-
|
|
727
|
-
const
|
|
728
|
-
if (node
|
|
729
|
-
|
|
730
|
-
this.addPosition(node, Position.None, top);
|
|
731
|
-
} else {
|
|
732
|
-
this.addPosition(node, Position.Inside, top);
|
|
767
|
+
getFolderClasses(node, isSelected) {
|
|
768
|
+
const classes = ["jqtree-folder"];
|
|
769
|
+
if (!node.is_open) {
|
|
770
|
+
classes.push("jqtree-closed");
|
|
733
771
|
}
|
|
734
|
-
if (
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
772
|
+
if (isSelected) {
|
|
773
|
+
classes.push("jqtree-selected");
|
|
774
|
+
}
|
|
775
|
+
if (node.is_loading) {
|
|
776
|
+
classes.push("jqtree-loading");
|
|
739
777
|
}
|
|
778
|
+
return classes.join(" ");
|
|
740
779
|
}
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
const positionCount = Math.min(positionsInGroup.length, 4);
|
|
754
|
-
const areaHeight = Math.round((bottom - top) / positionCount);
|
|
755
|
-
let areaTop = top;
|
|
756
|
-
let i = 0;
|
|
757
|
-
while (i < positionCount) {
|
|
758
|
-
const position = positionsInGroup[i];
|
|
759
|
-
if (position) {
|
|
760
|
-
hitAreas.push({
|
|
761
|
-
top: areaTop,
|
|
762
|
-
bottom: areaTop + areaHeight,
|
|
763
|
-
node: position.node,
|
|
764
|
-
position: position.position
|
|
765
|
-
});
|
|
766
|
-
}
|
|
767
|
-
areaTop += areaHeight;
|
|
768
|
-
i += 1;
|
|
780
|
+
createButtonElement(value) {
|
|
781
|
+
if (typeof value === "string") {
|
|
782
|
+
// convert value to html
|
|
783
|
+
const div = document.createElement("div");
|
|
784
|
+
div.innerHTML = value;
|
|
785
|
+
return document.createTextNode(div.innerHTML);
|
|
786
|
+
} else if (value == null) {
|
|
787
|
+
return undefined;
|
|
788
|
+
} else if (value.nodeType) {
|
|
789
|
+
return value;
|
|
790
|
+
} else {
|
|
791
|
+
return jQuery(value)[0];
|
|
769
792
|
}
|
|
770
793
|
}
|
|
771
794
|
}
|
|
772
795
|
|
|
773
|
-
class
|
|
796
|
+
class DataLoader {
|
|
774
797
|
constructor(_ref) {
|
|
775
798
|
let {
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
onCanMove,
|
|
782
|
-
onCanMoveTo,
|
|
783
|
-
onDragMove,
|
|
784
|
-
onDragStop,
|
|
785
|
-
onIsMoveHandle,
|
|
786
|
-
openNode,
|
|
787
|
-
refreshElements,
|
|
788
|
-
slide,
|
|
789
|
-
$treeElement,
|
|
799
|
+
dataFilter,
|
|
800
|
+
loadData,
|
|
801
|
+
onLoadFailed,
|
|
802
|
+
onLoading,
|
|
803
|
+
treeElement,
|
|
790
804
|
triggerEvent
|
|
791
805
|
} = _ref;
|
|
792
|
-
this.
|
|
793
|
-
this.
|
|
794
|
-
this.
|
|
795
|
-
this.
|
|
796
|
-
this.
|
|
797
|
-
this.onCanMove = onCanMove;
|
|
798
|
-
this.onCanMoveTo = onCanMoveTo;
|
|
799
|
-
this.onDragMove = onDragMove;
|
|
800
|
-
this.onDragStop = onDragStop;
|
|
801
|
-
this.onIsMoveHandle = onIsMoveHandle;
|
|
802
|
-
this.openNode = openNode;
|
|
803
|
-
this.refreshElements = refreshElements;
|
|
804
|
-
this.slide = slide;
|
|
805
|
-
this.$treeElement = $treeElement;
|
|
806
|
+
this.dataFilter = dataFilter;
|
|
807
|
+
this.loadData = loadData;
|
|
808
|
+
this.onLoadFailed = onLoadFailed;
|
|
809
|
+
this.onLoading = onLoading;
|
|
810
|
+
this.treeElement = treeElement;
|
|
806
811
|
this.triggerEvent = triggerEvent;
|
|
807
|
-
this.hoveredArea = null;
|
|
808
|
-
this.hitAreas = [];
|
|
809
|
-
this.isDragging = false;
|
|
810
|
-
this.currentItem = null;
|
|
811
812
|
}
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
return null;
|
|
816
|
-
}
|
|
817
|
-
if (this.onIsMoveHandle && !this.onIsMoveHandle(jQuery(element))) {
|
|
818
|
-
return null;
|
|
813
|
+
loadFromUrl(urlInfo, parentNode, onFinished) {
|
|
814
|
+
if (!urlInfo) {
|
|
815
|
+
return;
|
|
819
816
|
}
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
817
|
+
const element = this.getDomElement(parentNode);
|
|
818
|
+
this.addLoadingClass(element);
|
|
819
|
+
this.notifyLoading(true, parentNode, element);
|
|
820
|
+
const stopLoading = () => {
|
|
821
|
+
this.removeLoadingClass(element);
|
|
822
|
+
this.notifyLoading(false, parentNode, element);
|
|
823
|
+
};
|
|
824
|
+
const handleSuccess = data => {
|
|
825
|
+
stopLoading();
|
|
826
|
+
this.loadData(this.parseData(data), parentNode);
|
|
827
|
+
if (onFinished && typeof onFinished === "function") {
|
|
828
|
+
onFinished();
|
|
824
829
|
}
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
|
|
830
|
+
};
|
|
831
|
+
const handleError = jqXHR => {
|
|
832
|
+
stopLoading();
|
|
833
|
+
if (this.onLoadFailed) {
|
|
834
|
+
this.onLoadFailed(jqXHR);
|
|
835
|
+
}
|
|
836
|
+
};
|
|
837
|
+
this.submitRequest(urlInfo, handleSuccess, handleError);
|
|
828
838
|
}
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
839
|
+
addLoadingClass(element) {
|
|
840
|
+
element.classList.add("jqtree-loading");
|
|
841
|
+
}
|
|
842
|
+
removeLoadingClass(element) {
|
|
843
|
+
element.classList.remove("jqtree-loading");
|
|
844
|
+
}
|
|
845
|
+
getDomElement(parentNode) {
|
|
846
|
+
if (parentNode) {
|
|
847
|
+
return parentNode.element;
|
|
848
|
+
} else {
|
|
849
|
+
return this.treeElement;
|
|
832
850
|
}
|
|
833
|
-
this.refresh();
|
|
834
|
-
const offset = jQuery(positionInfo.target).offset();
|
|
835
|
-
const left = offset ? offset.left : 0;
|
|
836
|
-
const top = offset ? offset.top : 0;
|
|
837
|
-
const node = this.currentItem.node;
|
|
838
|
-
this.dragElement = new DragElement(node.name, positionInfo.pageX - left, positionInfo.pageY - top, this.$treeElement, this.autoEscape ?? true);
|
|
839
|
-
this.isDragging = true;
|
|
840
|
-
this.currentItem.element.classList.add("jqtree-moving");
|
|
841
|
-
return true;
|
|
842
851
|
}
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
852
|
+
notifyLoading(isLoading, node, element) {
|
|
853
|
+
const $el = jQuery(element);
|
|
854
|
+
if (this.onLoading) {
|
|
855
|
+
this.onLoading(isLoading, node, $el);
|
|
846
856
|
}
|
|
847
|
-
this.
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
857
|
+
this.triggerEvent("tree.loading_data", {
|
|
858
|
+
isLoading,
|
|
859
|
+
node,
|
|
860
|
+
$el
|
|
861
|
+
});
|
|
862
|
+
}
|
|
863
|
+
submitRequest(urlInfoInput, handleSuccess, handleError) {
|
|
864
|
+
const urlInfo = typeof urlInfoInput === "string" ? {
|
|
865
|
+
url: urlInfoInput
|
|
866
|
+
} : urlInfoInput;
|
|
867
|
+
const ajaxSettings = {
|
|
868
|
+
method: "GET",
|
|
869
|
+
cache: false,
|
|
870
|
+
dataType: "json",
|
|
871
|
+
success: handleSuccess,
|
|
872
|
+
error: handleError,
|
|
873
|
+
...urlInfo
|
|
874
|
+
};
|
|
875
|
+
ajaxSettings.method = ajaxSettings.method?.toUpperCase() || "GET";
|
|
876
|
+
void jQuery.ajax(ajaxSettings);
|
|
877
|
+
}
|
|
878
|
+
parseData(data) {
|
|
879
|
+
const getParsedData = () => {
|
|
880
|
+
if (typeof data === "string") {
|
|
881
|
+
return JSON.parse(data);
|
|
882
|
+
} else {
|
|
883
|
+
return data;
|
|
863
884
|
}
|
|
885
|
+
};
|
|
886
|
+
const parsedData = getParsedData();
|
|
887
|
+
if (this.dataFilter) {
|
|
888
|
+
return this.dataFilter(parsedData);
|
|
864
889
|
} else {
|
|
865
|
-
|
|
866
|
-
this.stopOpenFolderTimer();
|
|
867
|
-
this.hoveredArea = area;
|
|
868
|
-
}
|
|
869
|
-
if (!area) {
|
|
870
|
-
if (this.onDragMove) {
|
|
871
|
-
this.onDragMove(this.currentItem.node, positionInfo.originalEvent);
|
|
872
|
-
}
|
|
890
|
+
return parsedData;
|
|
873
891
|
}
|
|
874
|
-
return true;
|
|
875
892
|
}
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
class KeyHandler {
|
|
896
|
+
constructor(_ref) {
|
|
897
|
+
let {
|
|
898
|
+
closeNode,
|
|
899
|
+
getSelectedNode,
|
|
900
|
+
isFocusOnTree,
|
|
901
|
+
keyboardSupport,
|
|
902
|
+
openNode,
|
|
903
|
+
selectNode
|
|
904
|
+
} = _ref;
|
|
905
|
+
this.closeNode = closeNode;
|
|
906
|
+
this.getSelectedNode = getSelectedNode;
|
|
907
|
+
this.isFocusOnTree = isFocusOnTree;
|
|
908
|
+
this.keyboardSupport = keyboardSupport;
|
|
909
|
+
this.openNode = openNode;
|
|
910
|
+
this.originalSelectNode = selectNode;
|
|
911
|
+
if (keyboardSupport) {
|
|
912
|
+
this.handleKeyDownHandler = this.handleKeyDown.bind(this);
|
|
913
|
+
document.addEventListener("keydown", this.handleKeyDownHandler);
|
|
886
914
|
}
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
}
|
|
915
|
+
}
|
|
916
|
+
deinit() {
|
|
917
|
+
if (this.handleKeyDownHandler) {
|
|
918
|
+
document.removeEventListener("keydown", this.handleKeyDownHandler);
|
|
892
919
|
}
|
|
893
|
-
return false;
|
|
894
920
|
}
|
|
895
|
-
|
|
896
|
-
this.
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
921
|
+
moveDown(selectedNode) {
|
|
922
|
+
return this.selectNode(selectedNode.getNextVisibleNode());
|
|
923
|
+
}
|
|
924
|
+
moveUp(selectedNode) {
|
|
925
|
+
return this.selectNode(selectedNode.getPreviousVisibleNode());
|
|
926
|
+
}
|
|
927
|
+
moveRight(selectedNode) {
|
|
928
|
+
if (!selectedNode.isFolder()) {
|
|
929
|
+
return true;
|
|
930
|
+
} else {
|
|
931
|
+
// folder node
|
|
932
|
+
if (selectedNode.is_open) {
|
|
933
|
+
// Right moves to the first child of an open node
|
|
934
|
+
return this.selectNode(selectedNode.getNextVisibleNode());
|
|
935
|
+
} else {
|
|
936
|
+
// Right expands a closed node
|
|
937
|
+
this.openNode(selectedNode);
|
|
938
|
+
return false;
|
|
902
939
|
}
|
|
903
940
|
}
|
|
904
941
|
}
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
this.
|
|
942
|
+
moveLeft(selectedNode) {
|
|
943
|
+
if (selectedNode.isFolder() && selectedNode.is_open) {
|
|
944
|
+
// Left on an open node closes the node
|
|
945
|
+
this.closeNode(selectedNode);
|
|
946
|
+
return false;
|
|
909
947
|
} else {
|
|
910
|
-
|
|
911
|
-
this.
|
|
948
|
+
// Left on a closed or end node moves focus to the node's parent
|
|
949
|
+
return this.selectNode(selectedNode.getParent());
|
|
912
950
|
}
|
|
913
951
|
}
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
return nodeName !== "INPUT" && nodeName !== "SELECT" && nodeName !== "TEXTAREA";
|
|
917
|
-
}
|
|
918
|
-
canMoveToArea(area) {
|
|
919
|
-
if (!this.onCanMoveTo) {
|
|
952
|
+
selectNode(node) {
|
|
953
|
+
if (!node) {
|
|
920
954
|
return true;
|
|
921
|
-
}
|
|
922
|
-
|
|
955
|
+
} else {
|
|
956
|
+
this.originalSelectNode(node);
|
|
923
957
|
return false;
|
|
924
958
|
}
|
|
925
|
-
const positionName = getPositionName(area.position);
|
|
926
|
-
return this.onCanMoveTo(this.currentItem.node, area.node, positionName);
|
|
927
|
-
}
|
|
928
|
-
removeHitAreas() {
|
|
929
|
-
this.hitAreas = [];
|
|
930
959
|
}
|
|
931
|
-
|
|
932
|
-
if (this.
|
|
933
|
-
|
|
934
|
-
this.dragElement = null;
|
|
960
|
+
handleKeyDown = e => {
|
|
961
|
+
if (!this.canHandleKeyboard()) {
|
|
962
|
+
return true;
|
|
935
963
|
}
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
this.previousGhost.remove();
|
|
964
|
+
const selectedNode = this.getSelectedNode();
|
|
965
|
+
if (!selectedNode) {
|
|
966
|
+
return true;
|
|
940
967
|
}
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
968
|
+
switch (e.key) {
|
|
969
|
+
case "ArrowDown":
|
|
970
|
+
return this.moveDown(selectedNode);
|
|
971
|
+
case "ArrowUp":
|
|
972
|
+
return this.moveUp(selectedNode);
|
|
973
|
+
case "ArrowRight":
|
|
974
|
+
return this.moveRight(selectedNode);
|
|
975
|
+
case "ArrowLeft":
|
|
976
|
+
return this.moveLeft(selectedNode);
|
|
977
|
+
default:
|
|
978
|
+
return true;
|
|
949
979
|
}
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
const mid = low + high >> 1;
|
|
954
|
-
const area = this.hitAreas[mid];
|
|
955
|
-
if (!area) {
|
|
956
|
-
return null;
|
|
957
|
-
}
|
|
958
|
-
if (y < area.top) {
|
|
959
|
-
high = mid;
|
|
960
|
-
} else if (y > area.bottom) {
|
|
961
|
-
low = mid + 1;
|
|
962
|
-
} else {
|
|
963
|
-
return area;
|
|
964
|
-
}
|
|
965
|
-
}
|
|
966
|
-
return null;
|
|
967
|
-
}
|
|
968
|
-
mustOpenFolderTimer(area) {
|
|
969
|
-
const node = area.node;
|
|
970
|
-
return node.isFolder() && !node.is_open && area.position === Position.Inside;
|
|
980
|
+
};
|
|
981
|
+
canHandleKeyboard() {
|
|
982
|
+
return this.keyboardSupport && this.isFocusOnTree();
|
|
971
983
|
}
|
|
972
|
-
|
|
973
|
-
if (!this.hoveredArea) {
|
|
974
|
-
return;
|
|
975
|
-
}
|
|
984
|
+
}
|
|
976
985
|
|
|
977
|
-
|
|
978
|
-
|
|
986
|
+
const getPositionInfoFromMouseEvent = e => ({
|
|
987
|
+
originalEvent: e,
|
|
988
|
+
pageX: e.pageX,
|
|
989
|
+
pageY: e.pageY,
|
|
990
|
+
target: e.target
|
|
991
|
+
});
|
|
992
|
+
const getPositionInfoFromTouch = (touch, e) => ({
|
|
993
|
+
originalEvent: e,
|
|
994
|
+
pageX: touch.pageX,
|
|
995
|
+
pageY: touch.pageY,
|
|
996
|
+
target: touch.target
|
|
997
|
+
});
|
|
979
998
|
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
999
|
+
class MouseHandler {
|
|
1000
|
+
constructor(_ref) {
|
|
1001
|
+
let {
|
|
1002
|
+
element,
|
|
1003
|
+
getMouseDelay,
|
|
1004
|
+
getNode,
|
|
1005
|
+
onClickButton,
|
|
1006
|
+
onClickTitle,
|
|
1007
|
+
onMouseCapture,
|
|
1008
|
+
onMouseDrag,
|
|
1009
|
+
onMouseStart,
|
|
1010
|
+
onMouseStop,
|
|
1011
|
+
triggerEvent,
|
|
1012
|
+
useContextMenu
|
|
1013
|
+
} = _ref;
|
|
1014
|
+
this.element = element;
|
|
1015
|
+
this.getMouseDelay = getMouseDelay;
|
|
1016
|
+
this.getNode = getNode;
|
|
1017
|
+
this.onClickButton = onClickButton;
|
|
1018
|
+
this.onClickTitle = onClickTitle;
|
|
1019
|
+
this.onMouseCapture = onMouseCapture;
|
|
1020
|
+
this.onMouseDrag = onMouseDrag;
|
|
1021
|
+
this.onMouseStart = onMouseStart;
|
|
1022
|
+
this.onMouseStop = onMouseStop;
|
|
1023
|
+
this.triggerEvent = triggerEvent;
|
|
1024
|
+
this.useContextMenu = useContextMenu;
|
|
1025
|
+
element.addEventListener("click", this.handleClick);
|
|
1026
|
+
element.addEventListener("dblclick", this.handleDblclick);
|
|
1027
|
+
element.addEventListener("mousedown", this.mouseDown, {
|
|
1028
|
+
passive: false
|
|
1029
|
+
});
|
|
1030
|
+
element.addEventListener("touchstart", this.touchStart, {
|
|
1031
|
+
passive: false
|
|
1032
|
+
});
|
|
1033
|
+
if (useContextMenu) {
|
|
1034
|
+
element.addEventListener("contextmenu", this.handleContextmenu);
|
|
995
1035
|
}
|
|
1036
|
+
this.isMouseStarted = false;
|
|
1037
|
+
this.mouseDelayTimer = null;
|
|
1038
|
+
this.isMouseDelayMet = false;
|
|
1039
|
+
this.mouseDownInfo = null;
|
|
996
1040
|
}
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1041
|
+
deinit() {
|
|
1042
|
+
this.element.removeEventListener("click", this.handleClick);
|
|
1043
|
+
this.element.removeEventListener("dblclick", this.handleDblclick);
|
|
1044
|
+
if (this.useContextMenu) {
|
|
1045
|
+
this.element.removeEventListener("contextmenu", this.handleContextmenu);
|
|
1001
1046
|
}
|
|
1047
|
+
this.element.removeEventListener("mousedown", this.mouseDown);
|
|
1048
|
+
this.element.removeEventListener("touchstart", this.touchStart);
|
|
1049
|
+
this.removeMouseMoveEventListeners();
|
|
1002
1050
|
}
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
const position = this.hoveredArea.position;
|
|
1008
|
-
const previousParent = movedNode.parent;
|
|
1009
|
-
if (position === Position.Inside) {
|
|
1010
|
-
this.hoveredArea.node.is_open = true;
|
|
1011
|
-
}
|
|
1012
|
-
const doMove = () => {
|
|
1013
|
-
const tree = this.getTree();
|
|
1014
|
-
if (tree) {
|
|
1015
|
-
tree.moveNode(movedNode, targetNode, position);
|
|
1016
|
-
this.$treeElement.empty();
|
|
1017
|
-
this.refreshElements(null);
|
|
1018
|
-
}
|
|
1019
|
-
};
|
|
1020
|
-
const event = this.triggerEvent("tree.move", {
|
|
1021
|
-
move_info: {
|
|
1022
|
-
moved_node: movedNode,
|
|
1023
|
-
target_node: targetNode,
|
|
1024
|
-
position: getPositionName(position),
|
|
1025
|
-
previous_parent: previousParent,
|
|
1026
|
-
do_move: doMove,
|
|
1027
|
-
original_event: positionInfo.originalEvent
|
|
1028
|
-
}
|
|
1029
|
-
});
|
|
1030
|
-
if (!event.isDefaultPrevented()) {
|
|
1031
|
-
doMove();
|
|
1032
|
-
}
|
|
1051
|
+
mouseDown = e => {
|
|
1052
|
+
// Left mouse button?
|
|
1053
|
+
if (e.button !== 0) {
|
|
1054
|
+
return;
|
|
1033
1055
|
}
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
// to drag-and-drop after the last element.
|
|
1038
|
-
const offset = this.$treeElement.offset();
|
|
1039
|
-
if (!offset) {
|
|
1040
|
-
return {
|
|
1041
|
-
left: 0,
|
|
1042
|
-
top: 0,
|
|
1043
|
-
right: 0,
|
|
1044
|
-
bottom: 0
|
|
1045
|
-
};
|
|
1046
|
-
} else {
|
|
1047
|
-
const el = this.$treeElement;
|
|
1048
|
-
const width = el.width() || 0;
|
|
1049
|
-
const height = el.height() || 0;
|
|
1050
|
-
const left = offset.left + this.getScrollLeft();
|
|
1051
|
-
return {
|
|
1052
|
-
left,
|
|
1053
|
-
top: offset.top,
|
|
1054
|
-
right: left + width,
|
|
1055
|
-
bottom: offset.top + height + 16
|
|
1056
|
-
};
|
|
1056
|
+
const result = this.handleMouseDown(getPositionInfoFromMouseEvent(e));
|
|
1057
|
+
if (result && e.cancelable) {
|
|
1058
|
+
e.preventDefault();
|
|
1057
1059
|
}
|
|
1058
|
-
}
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
let {
|
|
1064
|
-
autoEscape,
|
|
1065
|
-
buttonLeft,
|
|
1066
|
-
closedIcon,
|
|
1067
|
-
onCreateLi,
|
|
1068
|
-
dragAndDrop,
|
|
1069
|
-
$element,
|
|
1070
|
-
getTree,
|
|
1071
|
-
isNodeSelected,
|
|
1072
|
-
openedIcon,
|
|
1073
|
-
rtl,
|
|
1074
|
-
showEmptyFolder,
|
|
1075
|
-
tabIndex
|
|
1076
|
-
} = _ref;
|
|
1077
|
-
this.autoEscape = autoEscape;
|
|
1078
|
-
this.buttonLeft = buttonLeft;
|
|
1079
|
-
this.dragAndDrop = dragAndDrop;
|
|
1080
|
-
this.$element = $element;
|
|
1081
|
-
this.getTree = getTree;
|
|
1082
|
-
this.isNodeSelected = isNodeSelected;
|
|
1083
|
-
this.onCreateLi = onCreateLi;
|
|
1084
|
-
this.rtl = rtl;
|
|
1085
|
-
this.showEmptyFolder = showEmptyFolder;
|
|
1086
|
-
this.tabIndex = tabIndex;
|
|
1087
|
-
this.openedIconElement = this.createButtonElement(openedIcon || "+");
|
|
1088
|
-
this.closedIconElement = this.createButtonElement(closedIcon || "-");
|
|
1089
|
-
}
|
|
1090
|
-
render(fromNode) {
|
|
1091
|
-
if (fromNode && fromNode.parent) {
|
|
1092
|
-
this.renderFromNode(fromNode);
|
|
1093
|
-
} else {
|
|
1094
|
-
this.renderFromRoot();
|
|
1060
|
+
};
|
|
1061
|
+
handleMouseDown(positionInfo) {
|
|
1062
|
+
// We may have missed mouseup (out of window)
|
|
1063
|
+
if (this.isMouseStarted) {
|
|
1064
|
+
this.handleMouseUp(positionInfo);
|
|
1095
1065
|
}
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
const tree = this.getTree();
|
|
1100
|
-
if (this.$element[0] && tree) {
|
|
1101
|
-
this.createDomElements(this.$element[0], tree.children, true, 1);
|
|
1066
|
+
this.mouseDownInfo = positionInfo;
|
|
1067
|
+
if (!this.onMouseCapture(positionInfo)) {
|
|
1068
|
+
return false;
|
|
1102
1069
|
}
|
|
1070
|
+
this.handleStartMouse();
|
|
1071
|
+
return true;
|
|
1103
1072
|
}
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1073
|
+
handleStartMouse() {
|
|
1074
|
+
document.addEventListener("mousemove", this.mouseMove, {
|
|
1075
|
+
passive: false
|
|
1076
|
+
});
|
|
1077
|
+
document.addEventListener("touchmove", this.touchMove, {
|
|
1078
|
+
passive: false
|
|
1079
|
+
});
|
|
1080
|
+
document.addEventListener("mouseup", this.mouseUp, {
|
|
1081
|
+
passive: false
|
|
1082
|
+
});
|
|
1083
|
+
document.addEventListener("touchend", this.touchEnd, {
|
|
1084
|
+
passive: false
|
|
1085
|
+
});
|
|
1086
|
+
const mouseDelay = this.getMouseDelay();
|
|
1087
|
+
if (mouseDelay) {
|
|
1088
|
+
this.startMouseDelayTimer(mouseDelay);
|
|
1089
|
+
} else {
|
|
1090
|
+
this.isMouseDelayMet = true;
|
|
1121
1091
|
}
|
|
1122
1092
|
}
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
for (const child of children) {
|
|
1127
|
-
const li = this.createLi(child, level);
|
|
1128
|
-
ul.appendChild(li);
|
|
1129
|
-
this.attachNodeData(child, li);
|
|
1130
|
-
if (child.hasChildren()) {
|
|
1131
|
-
this.createDomElements(li, child.children, false, level + 1);
|
|
1132
|
-
}
|
|
1093
|
+
startMouseDelayTimer(mouseDelay) {
|
|
1094
|
+
if (this.mouseDelayTimer) {
|
|
1095
|
+
clearTimeout(this.mouseDelayTimer);
|
|
1133
1096
|
}
|
|
1097
|
+
this.mouseDelayTimer = window.setTimeout(() => {
|
|
1098
|
+
if (this.mouseDownInfo) {
|
|
1099
|
+
this.isMouseDelayMet = true;
|
|
1100
|
+
}
|
|
1101
|
+
}, mouseDelay);
|
|
1102
|
+
this.isMouseDelayMet = false;
|
|
1134
1103
|
}
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
classString = "";
|
|
1144
|
-
role = "group";
|
|
1145
|
-
} else {
|
|
1146
|
-
classString = "jqtree-tree";
|
|
1147
|
-
role = "tree";
|
|
1148
|
-
if (this.rtl) {
|
|
1149
|
-
classString += " jqtree-rtl";
|
|
1104
|
+
mouseMove = e => {
|
|
1105
|
+
this.handleMouseMove(e, getPositionInfoFromMouseEvent(e));
|
|
1106
|
+
};
|
|
1107
|
+
handleMouseMove(e, positionInfo) {
|
|
1108
|
+
if (this.isMouseStarted) {
|
|
1109
|
+
this.onMouseDrag(positionInfo);
|
|
1110
|
+
if (e.cancelable) {
|
|
1111
|
+
e.preventDefault();
|
|
1150
1112
|
}
|
|
1113
|
+
return;
|
|
1151
1114
|
}
|
|
1152
|
-
if (this.
|
|
1153
|
-
|
|
1115
|
+
if (!this.isMouseDelayMet) {
|
|
1116
|
+
return;
|
|
1154
1117
|
}
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
this.onCreateLi(node, jQuery(li), isSelected);
|
|
1118
|
+
if (this.mouseDownInfo) {
|
|
1119
|
+
this.isMouseStarted = this.onMouseStart(this.mouseDownInfo) !== false;
|
|
1120
|
+
}
|
|
1121
|
+
if (this.isMouseStarted) {
|
|
1122
|
+
this.onMouseDrag(positionInfo);
|
|
1123
|
+
if (e.cancelable) {
|
|
1124
|
+
e.preventDefault();
|
|
1125
|
+
}
|
|
1126
|
+
} else {
|
|
1127
|
+
this.handleMouseUp(positionInfo);
|
|
1166
1128
|
}
|
|
1167
|
-
return li;
|
|
1168
1129
|
}
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1130
|
+
mouseUp = e => {
|
|
1131
|
+
this.handleMouseUp(getPositionInfoFromMouseEvent(e));
|
|
1132
|
+
};
|
|
1133
|
+
handleMouseUp(positionInfo) {
|
|
1134
|
+
this.removeMouseMoveEventListeners();
|
|
1135
|
+
this.isMouseDelayMet = false;
|
|
1136
|
+
this.mouseDownInfo = null;
|
|
1137
|
+
if (this.isMouseStarted) {
|
|
1138
|
+
this.isMouseStarted = false;
|
|
1139
|
+
this.onMouseStop(positionInfo);
|
|
1140
|
+
}
|
|
1174
1141
|
}
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
// div
|
|
1186
|
-
const div = document.createElement("div");
|
|
1187
|
-
div.className = "jqtree-element jqtree_common";
|
|
1188
|
-
div.setAttribute("role", "none");
|
|
1189
|
-
li.appendChild(div);
|
|
1190
|
-
|
|
1191
|
-
// button link
|
|
1192
|
-
const buttonLink = document.createElement("a");
|
|
1193
|
-
buttonLink.className = buttonClasses;
|
|
1194
|
-
if (iconElement) {
|
|
1195
|
-
buttonLink.appendChild(iconElement.cloneNode(true));
|
|
1142
|
+
removeMouseMoveEventListeners() {
|
|
1143
|
+
document.removeEventListener("mousemove", this.mouseMove);
|
|
1144
|
+
document.removeEventListener("touchmove", this.touchMove);
|
|
1145
|
+
document.removeEventListener("mouseup", this.mouseUp);
|
|
1146
|
+
document.removeEventListener("touchend", this.touchEnd);
|
|
1147
|
+
}
|
|
1148
|
+
touchStart = e => {
|
|
1149
|
+
if (!e) {
|
|
1150
|
+
return;
|
|
1196
1151
|
}
|
|
1197
|
-
if (
|
|
1198
|
-
|
|
1152
|
+
if (e.touches.length > 1) {
|
|
1153
|
+
return;
|
|
1199
1154
|
}
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
titleSpan.setAttribute("aria-expanded", getBoolString(node.is_open));
|
|
1204
|
-
div.appendChild(titleSpan);
|
|
1205
|
-
if (!this.buttonLeft) {
|
|
1206
|
-
div.appendChild(buttonLink);
|
|
1155
|
+
const touch = e.touches[0];
|
|
1156
|
+
if (!touch) {
|
|
1157
|
+
return;
|
|
1207
1158
|
}
|
|
1208
|
-
|
|
1209
|
-
}
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
liClasses.push("jqtree-selected");
|
|
1159
|
+
this.handleMouseDown(getPositionInfoFromTouch(touch, e));
|
|
1160
|
+
};
|
|
1161
|
+
touchMove = e => {
|
|
1162
|
+
if (!e) {
|
|
1163
|
+
return;
|
|
1214
1164
|
}
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
// li
|
|
1218
|
-
const li = document.createElement("li");
|
|
1219
|
-
li.className = classString;
|
|
1220
|
-
li.setAttribute("role", "none");
|
|
1221
|
-
|
|
1222
|
-
// div
|
|
1223
|
-
const div = document.createElement("div");
|
|
1224
|
-
div.className = "jqtree-element jqtree_common";
|
|
1225
|
-
div.setAttribute("role", "none");
|
|
1226
|
-
li.appendChild(div);
|
|
1227
|
-
|
|
1228
|
-
// title span
|
|
1229
|
-
const titleSpan = this.createTitleSpan(node.name, isSelected, false, level);
|
|
1230
|
-
div.appendChild(titleSpan);
|
|
1231
|
-
return li;
|
|
1232
|
-
}
|
|
1233
|
-
createTitleSpan(nodeName, isSelected, isFolder, level) {
|
|
1234
|
-
const titleSpan = document.createElement("span");
|
|
1235
|
-
let classes = "jqtree-title jqtree_common";
|
|
1236
|
-
if (isFolder) {
|
|
1237
|
-
classes += " jqtree-title-folder";
|
|
1165
|
+
if (e.touches.length > 1) {
|
|
1166
|
+
return;
|
|
1238
1167
|
}
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
const tabIndex = this.tabIndex;
|
|
1243
|
-
if (tabIndex !== undefined) {
|
|
1244
|
-
titleSpan.setAttribute("tabindex", `${tabIndex}`);
|
|
1245
|
-
}
|
|
1168
|
+
const touch = e.touches[0];
|
|
1169
|
+
if (!touch) {
|
|
1170
|
+
return;
|
|
1246
1171
|
}
|
|
1247
|
-
this.
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1172
|
+
this.handleMouseMove(e, getPositionInfoFromTouch(touch, e));
|
|
1173
|
+
};
|
|
1174
|
+
touchEnd = e => {
|
|
1175
|
+
if (!e) {
|
|
1176
|
+
return;
|
|
1252
1177
|
}
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
getButtonClasses(node) {
|
|
1256
|
-
const classes = ["jqtree-toggler", "jqtree_common"];
|
|
1257
|
-
if (!node.is_open) {
|
|
1258
|
-
classes.push("jqtree-closed");
|
|
1178
|
+
if (e.touches.length > 1) {
|
|
1179
|
+
return;
|
|
1259
1180
|
}
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
classes.push("jqtree-toggler-right");
|
|
1181
|
+
const touch = e.touches[0];
|
|
1182
|
+
if (!touch) {
|
|
1183
|
+
return;
|
|
1264
1184
|
}
|
|
1265
|
-
|
|
1266
|
-
}
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
classes.push("jqtree-closed");
|
|
1185
|
+
this.handleMouseUp(getPositionInfoFromTouch(touch, e));
|
|
1186
|
+
};
|
|
1187
|
+
handleClick = e => {
|
|
1188
|
+
if (!e.target) {
|
|
1189
|
+
return;
|
|
1271
1190
|
}
|
|
1272
|
-
|
|
1273
|
-
|
|
1191
|
+
const clickTarget = this.getClickTarget(e.target);
|
|
1192
|
+
if (!clickTarget) {
|
|
1193
|
+
return;
|
|
1274
1194
|
}
|
|
1275
|
-
if (
|
|
1276
|
-
|
|
1195
|
+
if (clickTarget.type === "button") {
|
|
1196
|
+
this.onClickButton(clickTarget.node);
|
|
1197
|
+
e.preventDefault();
|
|
1198
|
+
e.stopPropagation();
|
|
1199
|
+
} else if (clickTarget.type === "label") {
|
|
1200
|
+
const event = this.triggerEvent("tree.click", {
|
|
1201
|
+
node: clickTarget.node,
|
|
1202
|
+
click_event: e
|
|
1203
|
+
});
|
|
1204
|
+
if (!event.isDefaultPrevented()) {
|
|
1205
|
+
this.onClickTitle(clickTarget.node);
|
|
1206
|
+
}
|
|
1277
1207
|
}
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1208
|
+
};
|
|
1209
|
+
handleDblclick = e => {
|
|
1210
|
+
if (!e.target) {
|
|
1211
|
+
return;
|
|
1212
|
+
}
|
|
1213
|
+
const clickTarget = this.getClickTarget(e.target);
|
|
1214
|
+
if (clickTarget?.type === "label") {
|
|
1215
|
+
this.triggerEvent("tree.dblclick", {
|
|
1216
|
+
node: clickTarget.node,
|
|
1217
|
+
click_event: e
|
|
1218
|
+
});
|
|
1219
|
+
}
|
|
1220
|
+
};
|
|
1221
|
+
handleContextmenu = e => {
|
|
1222
|
+
if (!e.target) {
|
|
1223
|
+
return;
|
|
1224
|
+
}
|
|
1225
|
+
const div = e.target.closest("ul.jqtree-tree .jqtree-element");
|
|
1226
|
+
if (div) {
|
|
1227
|
+
const node = this.getNode(div);
|
|
1228
|
+
if (node) {
|
|
1229
|
+
e.preventDefault();
|
|
1230
|
+
e.stopPropagation();
|
|
1231
|
+
this.triggerEvent("tree.contextmenu", {
|
|
1232
|
+
node,
|
|
1233
|
+
click_event: e
|
|
1234
|
+
});
|
|
1235
|
+
return false;
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
return null;
|
|
1239
|
+
};
|
|
1240
|
+
getClickTarget(element) {
|
|
1241
|
+
const button = element.closest(".jqtree-toggler");
|
|
1242
|
+
if (button) {
|
|
1243
|
+
const node = this.getNode(button);
|
|
1244
|
+
if (node) {
|
|
1245
|
+
return {
|
|
1246
|
+
type: "button",
|
|
1247
|
+
node
|
|
1248
|
+
};
|
|
1249
|
+
}
|
|
1290
1250
|
} else {
|
|
1291
|
-
|
|
1251
|
+
const jqTreeElement = element.closest(".jqtree-element");
|
|
1252
|
+
if (jqTreeElement) {
|
|
1253
|
+
const node = this.getNode(jqTreeElement);
|
|
1254
|
+
if (node) {
|
|
1255
|
+
return {
|
|
1256
|
+
type: "label",
|
|
1257
|
+
node
|
|
1258
|
+
};
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1292
1261
|
}
|
|
1262
|
+
return null;
|
|
1293
1263
|
}
|
|
1294
1264
|
}
|
|
1295
1265
|
|
|
1296
|
-
class
|
|
1266
|
+
class SaveStateHandler {
|
|
1297
1267
|
constructor(_ref) {
|
|
1298
1268
|
let {
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1269
|
+
addToSelection,
|
|
1270
|
+
getNodeById,
|
|
1271
|
+
getSelectedNodes,
|
|
1272
|
+
getTree,
|
|
1273
|
+
onGetStateFromStorage,
|
|
1274
|
+
onSetStateFromStorage,
|
|
1275
|
+
openNode,
|
|
1276
|
+
refreshElements,
|
|
1277
|
+
removeFromSelection,
|
|
1278
|
+
saveState
|
|
1305
1279
|
} = _ref;
|
|
1306
|
-
this.
|
|
1307
|
-
this.
|
|
1308
|
-
this.
|
|
1309
|
-
this.
|
|
1310
|
-
this
|
|
1311
|
-
this.
|
|
1280
|
+
this.addToSelection = addToSelection;
|
|
1281
|
+
this.getNodeById = getNodeById;
|
|
1282
|
+
this.getSelectedNodes = getSelectedNodes;
|
|
1283
|
+
this.getTree = getTree;
|
|
1284
|
+
this.onGetStateFromStorage = onGetStateFromStorage;
|
|
1285
|
+
this.onSetStateFromStorage = onSetStateFromStorage;
|
|
1286
|
+
this.openNode = openNode;
|
|
1287
|
+
this.refreshElements = refreshElements;
|
|
1288
|
+
this.removeFromSelection = removeFromSelection;
|
|
1289
|
+
this.saveStateOption = saveState;
|
|
1312
1290
|
}
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1291
|
+
saveState() {
|
|
1292
|
+
const state = JSON.stringify(this.getState());
|
|
1293
|
+
if (this.onSetStateFromStorage) {
|
|
1294
|
+
this.onSetStateFromStorage(state);
|
|
1295
|
+
} else if (this.supportsLocalStorage()) {
|
|
1296
|
+
localStorage.setItem(this.getKeyName(), state);
|
|
1316
1297
|
}
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
this.
|
|
1320
|
-
|
|
1321
|
-
this.
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1298
|
+
}
|
|
1299
|
+
getStateFromStorage() {
|
|
1300
|
+
const jsonData = this.loadFromStorage();
|
|
1301
|
+
if (jsonData) {
|
|
1302
|
+
return this.parseState(jsonData);
|
|
1303
|
+
} else {
|
|
1304
|
+
return null;
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
getState() {
|
|
1308
|
+
const getOpenNodeIds = () => {
|
|
1309
|
+
const openNodes = [];
|
|
1310
|
+
this.getTree()?.iterate(node => {
|
|
1311
|
+
if (node.is_open && node.id && node.hasChildren()) {
|
|
1312
|
+
openNodes.push(node.id);
|
|
1313
|
+
}
|
|
1314
|
+
return true;
|
|
1315
|
+
});
|
|
1316
|
+
return openNodes;
|
|
1330
1317
|
};
|
|
1331
|
-
const
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1318
|
+
const getSelectedNodeIds = () => {
|
|
1319
|
+
const selectedNodeIds = [];
|
|
1320
|
+
this.getSelectedNodes().forEach(node => {
|
|
1321
|
+
if (node.id != null) {
|
|
1322
|
+
selectedNodeIds.push(node.id);
|
|
1323
|
+
}
|
|
1324
|
+
});
|
|
1325
|
+
return selectedNodeIds;
|
|
1326
|
+
};
|
|
1327
|
+
return {
|
|
1328
|
+
open_nodes: getOpenNodeIds(),
|
|
1329
|
+
selected_node: getSelectedNodeIds()
|
|
1336
1330
|
};
|
|
1337
|
-
this.submitRequest(urlInfo, handleSuccess, handleError);
|
|
1338
1331
|
}
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1332
|
+
|
|
1333
|
+
/*
|
|
1334
|
+
Set initial state
|
|
1335
|
+
Don't handle nodes that are loaded on demand
|
|
1336
|
+
result: must load on demand
|
|
1337
|
+
*/
|
|
1338
|
+
setInitialState(state) {
|
|
1339
|
+
if (!state) {
|
|
1340
|
+
return false;
|
|
1341
|
+
} else {
|
|
1342
|
+
let mustLoadOnDemand = false;
|
|
1343
|
+
if (state.open_nodes) {
|
|
1344
|
+
mustLoadOnDemand = this.openInitialNodes(state.open_nodes);
|
|
1345
|
+
}
|
|
1346
|
+
if (state.selected_node) {
|
|
1347
|
+
this.resetSelection();
|
|
1348
|
+
this.selectInitialNodes(state.selected_node);
|
|
1349
|
+
}
|
|
1350
|
+
return mustLoadOnDemand;
|
|
1342
1351
|
}
|
|
1343
1352
|
}
|
|
1344
|
-
|
|
1345
|
-
if (
|
|
1346
|
-
|
|
1353
|
+
setInitialStateOnDemand(state, cbFinished) {
|
|
1354
|
+
if (state) {
|
|
1355
|
+
this.doSetInitialStateOnDemand(state.open_nodes, state.selected_node, cbFinished);
|
|
1356
|
+
} else {
|
|
1357
|
+
cbFinished();
|
|
1347
1358
|
}
|
|
1348
1359
|
}
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1360
|
+
getNodeIdToBeSelected() {
|
|
1361
|
+
const state = this.getStateFromStorage();
|
|
1362
|
+
if (state && state.selected_node) {
|
|
1363
|
+
return state.selected_node[0] || null;
|
|
1352
1364
|
} else {
|
|
1353
|
-
return
|
|
1365
|
+
return null;
|
|
1354
1366
|
}
|
|
1355
1367
|
}
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1368
|
+
parseState(jsonData) {
|
|
1369
|
+
const state = JSON.parse(jsonData);
|
|
1370
|
+
|
|
1371
|
+
// Check if selected_node is an int (instead of an array)
|
|
1372
|
+
if (state && state.selected_node && isInt(state.selected_node)) {
|
|
1373
|
+
// Convert to array
|
|
1374
|
+
state.selected_node = [state.selected_node];
|
|
1359
1375
|
}
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1376
|
+
return state;
|
|
1377
|
+
}
|
|
1378
|
+
loadFromStorage() {
|
|
1379
|
+
if (this.onGetStateFromStorage) {
|
|
1380
|
+
return this.onGetStateFromStorage();
|
|
1381
|
+
} else if (this.supportsLocalStorage()) {
|
|
1382
|
+
return localStorage.getItem(this.getKeyName());
|
|
1383
|
+
} else {
|
|
1384
|
+
return null;
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
openInitialNodes(nodeIds) {
|
|
1388
|
+
let mustLoadOnDemand = false;
|
|
1389
|
+
for (const nodeId of nodeIds) {
|
|
1390
|
+
const node = this.getNodeById(nodeId);
|
|
1391
|
+
if (node) {
|
|
1392
|
+
if (!node.load_on_demand) {
|
|
1393
|
+
node.is_open = true;
|
|
1394
|
+
} else {
|
|
1395
|
+
mustLoadOnDemand = true;
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
return mustLoadOnDemand;
|
|
1400
|
+
}
|
|
1401
|
+
selectInitialNodes(nodeIds) {
|
|
1402
|
+
let selectCount = 0;
|
|
1403
|
+
for (const nodeId of nodeIds) {
|
|
1404
|
+
const node = this.getNodeById(nodeId);
|
|
1405
|
+
if (node) {
|
|
1406
|
+
selectCount += 1;
|
|
1407
|
+
this.addToSelection(node);
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
return selectCount !== 0;
|
|
1411
|
+
}
|
|
1412
|
+
resetSelection() {
|
|
1413
|
+
const selectedNodes = this.getSelectedNodes();
|
|
1414
|
+
selectedNodes.forEach(node => {
|
|
1415
|
+
this.removeFromSelection(node);
|
|
1364
1416
|
});
|
|
1365
1417
|
}
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1418
|
+
doSetInitialStateOnDemand(nodeIdsParam, selectedNodes, cbFinished) {
|
|
1419
|
+
let loadingCount = 0;
|
|
1420
|
+
let nodeIds = nodeIdsParam;
|
|
1421
|
+
const openNodes = () => {
|
|
1422
|
+
const newNodesIds = [];
|
|
1423
|
+
for (const nodeId of nodeIds) {
|
|
1424
|
+
const node = this.getNodeById(nodeId);
|
|
1425
|
+
if (!node) {
|
|
1426
|
+
newNodesIds.push(nodeId);
|
|
1427
|
+
} else {
|
|
1428
|
+
if (!node.is_loading) {
|
|
1429
|
+
if (node.load_on_demand) {
|
|
1430
|
+
loadAndOpenNode(node);
|
|
1431
|
+
} else {
|
|
1432
|
+
this.openNode(node, false);
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
nodeIds = newNodesIds;
|
|
1438
|
+
if (this.selectInitialNodes(selectedNodes)) {
|
|
1439
|
+
this.refreshElements(null);
|
|
1440
|
+
}
|
|
1441
|
+
if (loadingCount === 0) {
|
|
1442
|
+
cbFinished();
|
|
1443
|
+
}
|
|
1377
1444
|
};
|
|
1378
|
-
|
|
1379
|
-
|
|
1445
|
+
const loadAndOpenNode = node => {
|
|
1446
|
+
loadingCount += 1;
|
|
1447
|
+
this.openNode(node, false, () => {
|
|
1448
|
+
loadingCount -= 1;
|
|
1449
|
+
openNodes();
|
|
1450
|
+
});
|
|
1451
|
+
};
|
|
1452
|
+
openNodes();
|
|
1380
1453
|
}
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1454
|
+
getKeyName() {
|
|
1455
|
+
if (typeof this.saveStateOption === "string") {
|
|
1456
|
+
return this.saveStateOption;
|
|
1457
|
+
} else {
|
|
1458
|
+
return "tree";
|
|
1459
|
+
}
|
|
1460
|
+
}
|
|
1461
|
+
supportsLocalStorage() {
|
|
1462
|
+
const testSupport = () => {
|
|
1463
|
+
// Is local storage supported?
|
|
1464
|
+
if (localStorage == null) {
|
|
1465
|
+
return false;
|
|
1385
1466
|
} else {
|
|
1386
|
-
|
|
1467
|
+
// Check if it's possible to store an item. Safari does not allow this in private browsing mode.
|
|
1468
|
+
try {
|
|
1469
|
+
const key = "_storage_test";
|
|
1470
|
+
sessionStorage.setItem(key, "value");
|
|
1471
|
+
sessionStorage.removeItem(key);
|
|
1472
|
+
} catch (error) {
|
|
1473
|
+
return false;
|
|
1474
|
+
}
|
|
1475
|
+
return true;
|
|
1387
1476
|
}
|
|
1388
1477
|
};
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
return this.dataFilter(parsedData);
|
|
1392
|
-
} else {
|
|
1393
|
-
return parsedData;
|
|
1478
|
+
if (this._supportsLocalStorage == null) {
|
|
1479
|
+
this._supportsLocalStorage = testSupport();
|
|
1394
1480
|
}
|
|
1481
|
+
return this._supportsLocalStorage;
|
|
1395
1482
|
}
|
|
1396
1483
|
}
|
|
1397
1484
|
|
|
1398
|
-
class
|
|
1485
|
+
class ContainerScrollParent {
|
|
1399
1486
|
constructor(_ref) {
|
|
1400
1487
|
let {
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
isFocusOnTree,
|
|
1404
|
-
keyboardSupport,
|
|
1405
|
-
openNode,
|
|
1406
|
-
selectNode
|
|
1488
|
+
container,
|
|
1489
|
+
refreshHitAreas
|
|
1407
1490
|
} = _ref;
|
|
1408
|
-
this.
|
|
1409
|
-
this.
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
this.
|
|
1414
|
-
|
|
1415
|
-
this.
|
|
1416
|
-
|
|
1491
|
+
this.container = container;
|
|
1492
|
+
this.refreshHitAreas = refreshHitAreas;
|
|
1493
|
+
}
|
|
1494
|
+
checkHorizontalScrolling(pageX) {
|
|
1495
|
+
const newHorizontalScrollDirection = this.getNewHorizontalScrollDirection(pageX);
|
|
1496
|
+
if (this.horizontalScrollDirection !== newHorizontalScrollDirection) {
|
|
1497
|
+
this.horizontalScrollDirection = newHorizontalScrollDirection;
|
|
1498
|
+
if (this.horizontalScrollTimeout != null) {
|
|
1499
|
+
window.clearTimeout(this.verticalScrollTimeout);
|
|
1500
|
+
}
|
|
1501
|
+
if (newHorizontalScrollDirection) {
|
|
1502
|
+
this.horizontalScrollTimeout = window.setTimeout(this.scrollHorizontally.bind(this), 40);
|
|
1503
|
+
}
|
|
1417
1504
|
}
|
|
1418
1505
|
}
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1506
|
+
checkVerticalScrolling(pageY) {
|
|
1507
|
+
const newVerticalScrollDirection = this.getNewVerticalScrollDirection(pageY);
|
|
1508
|
+
if (this.verticalScrollDirection !== newVerticalScrollDirection) {
|
|
1509
|
+
this.verticalScrollDirection = newVerticalScrollDirection;
|
|
1510
|
+
if (this.verticalScrollTimeout != null) {
|
|
1511
|
+
window.clearTimeout(this.verticalScrollTimeout);
|
|
1512
|
+
this.verticalScrollTimeout = undefined;
|
|
1513
|
+
}
|
|
1514
|
+
if (newVerticalScrollDirection) {
|
|
1515
|
+
this.verticalScrollTimeout = window.setTimeout(this.scrollVertically.bind(this), 40);
|
|
1516
|
+
}
|
|
1422
1517
|
}
|
|
1423
1518
|
}
|
|
1424
|
-
|
|
1425
|
-
return this.
|
|
1519
|
+
getScrollLeft() {
|
|
1520
|
+
return this.container.scrollLeft;
|
|
1426
1521
|
}
|
|
1427
|
-
|
|
1428
|
-
|
|
1522
|
+
scrollToY(top) {
|
|
1523
|
+
this.container.scrollTop = top;
|
|
1429
1524
|
}
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1525
|
+
stopScrolling() {
|
|
1526
|
+
this.horizontalScrollDirection = undefined;
|
|
1527
|
+
this.verticalScrollDirection = undefined;
|
|
1528
|
+
this.scrollParentTop = undefined;
|
|
1529
|
+
this.scrollParentBottom = undefined;
|
|
1530
|
+
}
|
|
1531
|
+
getNewHorizontalScrollDirection(pageX) {
|
|
1532
|
+
const scrollParentOffset = getElementPosition(this.container);
|
|
1533
|
+
const rightEdge = scrollParentOffset.left + this.container.clientWidth;
|
|
1534
|
+
const leftEdge = scrollParentOffset.left;
|
|
1535
|
+
const isNearRightEdge = pageX > rightEdge - 20;
|
|
1536
|
+
const isNearLeftEdge = pageX < leftEdge + 20;
|
|
1537
|
+
if (isNearRightEdge) {
|
|
1538
|
+
return "right";
|
|
1539
|
+
} else if (isNearLeftEdge) {
|
|
1540
|
+
return "left";
|
|
1443
1541
|
}
|
|
1542
|
+
return undefined;
|
|
1444
1543
|
}
|
|
1445
|
-
|
|
1446
|
-
if (
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
// Left on a closed or end node moves focus to the node's parent
|
|
1452
|
-
return this.selectNode(selectedNode.getParent());
|
|
1544
|
+
getNewVerticalScrollDirection(pageY) {
|
|
1545
|
+
if (pageY < this.getScrollParentTop()) {
|
|
1546
|
+
return "top";
|
|
1547
|
+
}
|
|
1548
|
+
if (pageY > this.getScrollParentBottom()) {
|
|
1549
|
+
return "bottom";
|
|
1453
1550
|
}
|
|
1551
|
+
return undefined;
|
|
1454
1552
|
}
|
|
1455
|
-
|
|
1456
|
-
if (!
|
|
1457
|
-
return
|
|
1458
|
-
} else {
|
|
1459
|
-
this.originalSelectNode(node);
|
|
1460
|
-
return false;
|
|
1553
|
+
scrollHorizontally() {
|
|
1554
|
+
if (!this.horizontalScrollDirection) {
|
|
1555
|
+
return;
|
|
1461
1556
|
}
|
|
1557
|
+
const distance = this.horizontalScrollDirection === "left" ? -20 : 20;
|
|
1558
|
+
this.container.scrollBy({
|
|
1559
|
+
left: distance,
|
|
1560
|
+
top: 0,
|
|
1561
|
+
behavior: "instant"
|
|
1562
|
+
});
|
|
1563
|
+
this.refreshHitAreas();
|
|
1564
|
+
setTimeout(this.scrollHorizontally.bind(this), 40);
|
|
1462
1565
|
}
|
|
1463
|
-
|
|
1464
|
-
if (!this.
|
|
1465
|
-
return
|
|
1566
|
+
scrollVertically() {
|
|
1567
|
+
if (!this.verticalScrollDirection) {
|
|
1568
|
+
return;
|
|
1466
1569
|
}
|
|
1467
|
-
const
|
|
1468
|
-
|
|
1469
|
-
|
|
1570
|
+
const distance = this.verticalScrollDirection === "top" ? -20 : 20;
|
|
1571
|
+
this.container.scrollBy({
|
|
1572
|
+
left: 0,
|
|
1573
|
+
top: distance,
|
|
1574
|
+
behavior: "instant"
|
|
1575
|
+
});
|
|
1576
|
+
this.refreshHitAreas();
|
|
1577
|
+
setTimeout(this.scrollVertically.bind(this), 40);
|
|
1578
|
+
}
|
|
1579
|
+
getScrollParentTop() {
|
|
1580
|
+
if (this.scrollParentTop == null) {
|
|
1581
|
+
this.scrollParentTop = getOffsetTop(this.container);
|
|
1470
1582
|
}
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
case "ArrowRight":
|
|
1477
|
-
return this.moveRight(selectedNode);
|
|
1478
|
-
case "ArrowLeft":
|
|
1479
|
-
return this.moveLeft(selectedNode);
|
|
1480
|
-
default:
|
|
1481
|
-
return true;
|
|
1583
|
+
return this.scrollParentTop;
|
|
1584
|
+
}
|
|
1585
|
+
getScrollParentBottom() {
|
|
1586
|
+
if (this.scrollParentBottom == null) {
|
|
1587
|
+
this.scrollParentBottom = this.getScrollParentTop() + this.container.clientHeight;
|
|
1482
1588
|
}
|
|
1483
|
-
|
|
1484
|
-
canHandleKeyboard() {
|
|
1485
|
-
return this.keyboardSupport && this.isFocusOnTree();
|
|
1589
|
+
return this.scrollParentBottom;
|
|
1486
1590
|
}
|
|
1487
1591
|
}
|
|
1488
1592
|
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
const simpleWidgetClass = widgetClass;
|
|
1505
|
-
const widget = new simpleWidgetClass(el, options);
|
|
1506
|
-
if (!jQuery.data(el, dataKey)) {
|
|
1507
|
-
jQuery.data(el, dataKey, widget);
|
|
1508
|
-
}
|
|
1509
|
-
|
|
1510
|
-
// Call init after setting data, so we can call methods
|
|
1511
|
-
widget.init();
|
|
1593
|
+
class DocumentScrollParent {
|
|
1594
|
+
constructor(_ref) {
|
|
1595
|
+
let {
|
|
1596
|
+
refreshHitAreas,
|
|
1597
|
+
treeElement
|
|
1598
|
+
} = _ref;
|
|
1599
|
+
this.refreshHitAreas = refreshHitAreas;
|
|
1600
|
+
this.treeElement = treeElement;
|
|
1601
|
+
}
|
|
1602
|
+
checkHorizontalScrolling(pageX) {
|
|
1603
|
+
const newHorizontalScrollDirection = this.getNewHorizontalScrollDirection(pageX);
|
|
1604
|
+
if (this.horizontalScrollDirection !== newHorizontalScrollDirection) {
|
|
1605
|
+
this.horizontalScrollDirection = newHorizontalScrollDirection;
|
|
1606
|
+
if (this.horizontalScrollTimeout != null) {
|
|
1607
|
+
window.clearTimeout(this.horizontalScrollTimeout);
|
|
1512
1608
|
}
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
};
|
|
1516
|
-
const destroyWidget = $el => {
|
|
1517
|
-
const dataKey = getDataKey();
|
|
1518
|
-
for (const el of $el.get()) {
|
|
1519
|
-
const widget = getWidgetData(el, dataKey);
|
|
1520
|
-
if (widget) {
|
|
1521
|
-
widget.destroy();
|
|
1609
|
+
if (newHorizontalScrollDirection) {
|
|
1610
|
+
this.horizontalScrollTimeout = window.setTimeout(this.scrollHorizontally.bind(this), 40);
|
|
1522
1611
|
}
|
|
1523
|
-
jQuery.removeData(el, dataKey);
|
|
1524
1612
|
}
|
|
1525
|
-
}
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
if (
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
if (widgetFunction && typeof widgetFunction === "function") {
|
|
1534
|
-
result = widgetFunction.apply(widget, args);
|
|
1535
|
-
}
|
|
1613
|
+
}
|
|
1614
|
+
checkVerticalScrolling(pageY) {
|
|
1615
|
+
const newVerticalScrollDirection = this.getNewVerticalScrollDirection(pageY);
|
|
1616
|
+
if (this.verticalScrollDirection !== newVerticalScrollDirection) {
|
|
1617
|
+
this.verticalScrollDirection = newVerticalScrollDirection;
|
|
1618
|
+
if (this.verticalScrollTimeout != null) {
|
|
1619
|
+
window.clearTimeout(this.verticalScrollTimeout);
|
|
1620
|
+
this.verticalScrollTimeout = undefined;
|
|
1536
1621
|
}
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
};
|
|
1540
|
-
|
|
1541
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
1542
|
-
jQuery.fn[widgetName] = function (argument1) {
|
|
1543
|
-
if (!argument1) {
|
|
1544
|
-
return createWidget(this, null);
|
|
1545
|
-
} else if (typeof argument1 === "object") {
|
|
1546
|
-
const options = argument1;
|
|
1547
|
-
return createWidget(this, options);
|
|
1548
|
-
} else if (typeof argument1 === "string" && argument1[0] !== "_") {
|
|
1549
|
-
const functionName = argument1;
|
|
1550
|
-
if (functionName === "destroy") {
|
|
1551
|
-
return destroyWidget(this);
|
|
1552
|
-
} else if (functionName === "get_widget_class") {
|
|
1553
|
-
return widgetClass;
|
|
1554
|
-
} else {
|
|
1555
|
-
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
1556
|
-
args[_key - 1] = arguments[_key];
|
|
1557
|
-
}
|
|
1558
|
-
return callFunction(this, functionName, args);
|
|
1622
|
+
if (newVerticalScrollDirection) {
|
|
1623
|
+
this.verticalScrollTimeout = window.setTimeout(this.scrollVertically.bind(this), 40);
|
|
1559
1624
|
}
|
|
1560
|
-
} else {
|
|
1561
|
-
return undefined;
|
|
1562
1625
|
}
|
|
1563
|
-
};
|
|
1564
|
-
};
|
|
1565
|
-
class SimpleWidget {
|
|
1566
|
-
static register(widgetClass, widgetName) {
|
|
1567
|
-
register(widgetClass, widgetName);
|
|
1568
|
-
}
|
|
1569
|
-
static defaults = {};
|
|
1570
|
-
constructor(el, options) {
|
|
1571
|
-
this.$el = jQuery(el);
|
|
1572
|
-
|
|
1573
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
1574
|
-
const defaults = this.constructor["defaults"];
|
|
1575
|
-
this.options = {
|
|
1576
|
-
...defaults,
|
|
1577
|
-
...options
|
|
1578
|
-
};
|
|
1579
1626
|
}
|
|
1580
|
-
|
|
1581
|
-
|
|
1627
|
+
getScrollLeft() {
|
|
1628
|
+
return document.documentElement.scrollLeft;
|
|
1582
1629
|
}
|
|
1583
|
-
|
|
1584
|
-
|
|
1630
|
+
scrollToY(top) {
|
|
1631
|
+
const treeTop = getOffsetTop(this.treeElement);
|
|
1632
|
+
document.documentElement.scrollTop = top + treeTop;
|
|
1585
1633
|
}
|
|
1586
|
-
|
|
1587
|
-
|
|
1634
|
+
stopScrolling() {
|
|
1635
|
+
this.horizontalScrollDirection = undefined;
|
|
1636
|
+
this.verticalScrollDirection = undefined;
|
|
1637
|
+
this.documentScrollHeight = undefined;
|
|
1638
|
+
this.documentScrollWidth = undefined;
|
|
1588
1639
|
}
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
pageY: e.pageY,
|
|
1597
|
-
target: e.target,
|
|
1598
|
-
originalEvent: e
|
|
1599
|
-
});
|
|
1600
|
-
const getPositionInfoFromTouch = (touch, e) => ({
|
|
1601
|
-
pageX: touch.pageX,
|
|
1602
|
-
pageY: touch.pageY,
|
|
1603
|
-
target: touch.target,
|
|
1604
|
-
originalEvent: e
|
|
1605
|
-
});
|
|
1606
|
-
class MouseWidget extends SimpleWidget {
|
|
1607
|
-
init() {
|
|
1608
|
-
const element = this.$el.get(0);
|
|
1609
|
-
if (element) {
|
|
1610
|
-
element.addEventListener("mousedown", this.mouseDown, {
|
|
1611
|
-
passive: false
|
|
1612
|
-
});
|
|
1613
|
-
element.addEventListener("touchstart", this.touchStart, {
|
|
1614
|
-
passive: false
|
|
1615
|
-
});
|
|
1640
|
+
getNewHorizontalScrollDirection(pageX) {
|
|
1641
|
+
const scrollLeft = document.documentElement.scrollLeft;
|
|
1642
|
+
const windowWidth = window.innerWidth;
|
|
1643
|
+
const isNearRightEdge = pageX > windowWidth - 20;
|
|
1644
|
+
const isNearLeftEdge = pageX - scrollLeft < 20;
|
|
1645
|
+
if (isNearRightEdge && this.canScrollRight()) {
|
|
1646
|
+
return "right";
|
|
1616
1647
|
}
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
this.isMouseDelayMet = false;
|
|
1620
|
-
this.mouseDownInfo = null;
|
|
1621
|
-
}
|
|
1622
|
-
deinit() {
|
|
1623
|
-
const el = this.$el.get(0);
|
|
1624
|
-
if (el) {
|
|
1625
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
1626
|
-
el.removeEventListener("mousedown", this.mouseDown, {
|
|
1627
|
-
passive: false
|
|
1628
|
-
});
|
|
1629
|
-
|
|
1630
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
1631
|
-
el.removeEventListener("touchstart", this.touchStart, {
|
|
1632
|
-
passive: false
|
|
1633
|
-
});
|
|
1648
|
+
if (isNearLeftEdge) {
|
|
1649
|
+
return "left";
|
|
1634
1650
|
}
|
|
1635
|
-
|
|
1651
|
+
return undefined;
|
|
1636
1652
|
}
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
const
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
if (this.isMouseStarted) {
|
|
1650
|
-
this.handleMouseUp(positionInfo);
|
|
1651
|
-
}
|
|
1652
|
-
this.mouseDownInfo = positionInfo;
|
|
1653
|
-
if (!this.mouseCapture(positionInfo)) {
|
|
1654
|
-
return false;
|
|
1653
|
+
canScrollRight() {
|
|
1654
|
+
const documentElement = document.documentElement;
|
|
1655
|
+
return documentElement.scrollLeft + documentElement.clientWidth < this.getDocumentScrollWidth();
|
|
1656
|
+
}
|
|
1657
|
+
canScrollDown() {
|
|
1658
|
+
const documentElement = document.documentElement;
|
|
1659
|
+
return documentElement.scrollTop + documentElement.clientHeight < this.getDocumentScrollHeight();
|
|
1660
|
+
}
|
|
1661
|
+
getDocumentScrollHeight() {
|
|
1662
|
+
// Store the original scroll height because the scroll height can increase when the drag element is moved beyond the scroll height.
|
|
1663
|
+
if (this.documentScrollHeight == null) {
|
|
1664
|
+
this.documentScrollHeight = document.documentElement.scrollHeight;
|
|
1655
1665
|
}
|
|
1656
|
-
this.
|
|
1657
|
-
return true;
|
|
1666
|
+
return this.documentScrollHeight;
|
|
1658
1667
|
}
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
document.addEventListener("touchmove", this.touchMove, {
|
|
1664
|
-
passive: false
|
|
1665
|
-
});
|
|
1666
|
-
document.addEventListener("mouseup", this.mouseUp, {
|
|
1667
|
-
passive: false
|
|
1668
|
-
});
|
|
1669
|
-
document.addEventListener("touchend", this.touchEnd, {
|
|
1670
|
-
passive: false
|
|
1671
|
-
});
|
|
1672
|
-
const mouseDelay = this.getMouseDelay();
|
|
1673
|
-
if (mouseDelay) {
|
|
1674
|
-
this.startMouseDelayTimer(mouseDelay);
|
|
1675
|
-
} else {
|
|
1676
|
-
this.isMouseDelayMet = true;
|
|
1668
|
+
getDocumentScrollWidth() {
|
|
1669
|
+
// Store the original scroll width because the scroll width can increase when the drag element is moved beyond the scroll width.
|
|
1670
|
+
if (this.documentScrollWidth == null) {
|
|
1671
|
+
this.documentScrollWidth = document.documentElement.scrollWidth;
|
|
1677
1672
|
}
|
|
1673
|
+
return this.documentScrollWidth;
|
|
1678
1674
|
}
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1675
|
+
getNewVerticalScrollDirection(pageY) {
|
|
1676
|
+
const scrollTop = jQuery(document).scrollTop() || 0;
|
|
1677
|
+
const distanceTop = pageY - scrollTop;
|
|
1678
|
+
if (distanceTop < 20) {
|
|
1679
|
+
return "top";
|
|
1682
1680
|
}
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
this.isMouseDelayMet = false;
|
|
1681
|
+
const windowHeight = window.innerHeight;
|
|
1682
|
+
if (windowHeight - (pageY - scrollTop) < 20 && this.canScrollDown()) {
|
|
1683
|
+
return "bottom";
|
|
1684
|
+
}
|
|
1685
|
+
return undefined;
|
|
1689
1686
|
}
|
|
1690
|
-
|
|
1691
|
-
this.
|
|
1692
|
-
};
|
|
1693
|
-
handleMouseMove(e, positionInfo) {
|
|
1694
|
-
if (this.isMouseStarted) {
|
|
1695
|
-
this.mouseDrag(positionInfo);
|
|
1696
|
-
if (e.cancelable) {
|
|
1697
|
-
e.preventDefault();
|
|
1698
|
-
}
|
|
1687
|
+
scrollHorizontally() {
|
|
1688
|
+
if (!this.horizontalScrollDirection) {
|
|
1699
1689
|
return;
|
|
1700
1690
|
}
|
|
1701
|
-
|
|
1691
|
+
const distance = this.horizontalScrollDirection === "left" ? -20 : 20;
|
|
1692
|
+
window.scrollBy({
|
|
1693
|
+
left: distance,
|
|
1694
|
+
top: 0,
|
|
1695
|
+
behavior: "instant"
|
|
1696
|
+
});
|
|
1697
|
+
this.refreshHitAreas();
|
|
1698
|
+
setTimeout(this.scrollHorizontally.bind(this), 40);
|
|
1699
|
+
}
|
|
1700
|
+
scrollVertically() {
|
|
1701
|
+
if (!this.verticalScrollDirection) {
|
|
1702
1702
|
return;
|
|
1703
1703
|
}
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
} else {
|
|
1713
|
-
this.handleMouseUp(positionInfo);
|
|
1714
|
-
}
|
|
1704
|
+
const distance = this.verticalScrollDirection === "top" ? -20 : 20;
|
|
1705
|
+
window.scrollBy({
|
|
1706
|
+
left: 0,
|
|
1707
|
+
top: distance,
|
|
1708
|
+
behavior: "instant"
|
|
1709
|
+
});
|
|
1710
|
+
this.refreshHitAreas();
|
|
1711
|
+
setTimeout(this.scrollVertically.bind(this), 40);
|
|
1715
1712
|
}
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1713
|
+
}
|
|
1714
|
+
|
|
1715
|
+
const isOverflow = overflowValue => overflowValue === "auto" || overflowValue === "scroll";
|
|
1716
|
+
const hasOverFlow = element => {
|
|
1717
|
+
const style = getComputedStyle(element);
|
|
1718
|
+
return isOverflow(style.overflowX) || isOverflow(style.overflowY);
|
|
1719
|
+
};
|
|
1720
|
+
const getParentWithOverflow = treeElement => {
|
|
1721
|
+
if (hasOverFlow(treeElement)) {
|
|
1722
|
+
return treeElement;
|
|
1723
|
+
}
|
|
1724
|
+
let parent = treeElement.parentElement;
|
|
1725
|
+
while (parent) {
|
|
1726
|
+
if (hasOverFlow(parent)) {
|
|
1727
|
+
return parent;
|
|
1726
1728
|
}
|
|
1729
|
+
parent = parent.parentElement;
|
|
1727
1730
|
}
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
});
|
|
1737
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
1738
|
-
document.removeEventListener("mouseup", this.mouseUp, {
|
|
1739
|
-
passive: false
|
|
1731
|
+
return null;
|
|
1732
|
+
};
|
|
1733
|
+
const createScrollParent = (treeElement, refreshHitAreas) => {
|
|
1734
|
+
const container = getParentWithOverflow(treeElement);
|
|
1735
|
+
if (container && container.tagName !== "HTML") {
|
|
1736
|
+
return new ContainerScrollParent({
|
|
1737
|
+
container,
|
|
1738
|
+
refreshHitAreas
|
|
1740
1739
|
});
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1740
|
+
} else {
|
|
1741
|
+
return new DocumentScrollParent({
|
|
1742
|
+
refreshHitAreas,
|
|
1743
|
+
treeElement
|
|
1744
1744
|
});
|
|
1745
1745
|
}
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
if (!touch) {
|
|
1781
|
-
return;
|
|
1746
|
+
};
|
|
1747
|
+
|
|
1748
|
+
class ScrollHandler {
|
|
1749
|
+
constructor(_ref) {
|
|
1750
|
+
let {
|
|
1751
|
+
refreshHitAreas,
|
|
1752
|
+
treeElement
|
|
1753
|
+
} = _ref;
|
|
1754
|
+
this.refreshHitAreas = refreshHitAreas;
|
|
1755
|
+
this.scrollParent = undefined;
|
|
1756
|
+
this.treeElement = treeElement;
|
|
1757
|
+
}
|
|
1758
|
+
checkScrolling(positionInfo) {
|
|
1759
|
+
this.checkVerticalScrolling(positionInfo);
|
|
1760
|
+
this.checkHorizontalScrolling(positionInfo);
|
|
1761
|
+
}
|
|
1762
|
+
stopScrolling() {
|
|
1763
|
+
this.getScrollParent().stopScrolling();
|
|
1764
|
+
}
|
|
1765
|
+
scrollToY(top) {
|
|
1766
|
+
this.getScrollParent().scrollToY(top);
|
|
1767
|
+
}
|
|
1768
|
+
getScrollLeft() {
|
|
1769
|
+
return this.getScrollParent().getScrollLeft();
|
|
1770
|
+
}
|
|
1771
|
+
checkVerticalScrolling(positionInfo) {
|
|
1772
|
+
this.getScrollParent().checkVerticalScrolling(positionInfo.pageY);
|
|
1773
|
+
}
|
|
1774
|
+
checkHorizontalScrolling(positionInfo) {
|
|
1775
|
+
this.getScrollParent().checkHorizontalScrolling(positionInfo.pageX);
|
|
1776
|
+
}
|
|
1777
|
+
getScrollParent() {
|
|
1778
|
+
if (!this.scrollParent) {
|
|
1779
|
+
this.scrollParent = createScrollParent(this.treeElement, this.refreshHitAreas);
|
|
1782
1780
|
}
|
|
1783
|
-
this.
|
|
1784
|
-
}
|
|
1781
|
+
return this.scrollParent;
|
|
1782
|
+
}
|
|
1785
1783
|
}
|
|
1786
1784
|
|
|
1787
|
-
class
|
|
1785
|
+
class SelectNodeHandler {
|
|
1788
1786
|
constructor(_ref) {
|
|
1789
1787
|
let {
|
|
1790
|
-
|
|
1791
|
-
getNodeById,
|
|
1792
|
-
getSelectedNodes,
|
|
1793
|
-
getTree,
|
|
1794
|
-
onGetStateFromStorage,
|
|
1795
|
-
onSetStateFromStorage,
|
|
1796
|
-
openNode,
|
|
1797
|
-
refreshElements,
|
|
1798
|
-
removeFromSelection,
|
|
1799
|
-
saveState
|
|
1788
|
+
getNodeById
|
|
1800
1789
|
} = _ref;
|
|
1801
|
-
this.addToSelection = addToSelection;
|
|
1802
1790
|
this.getNodeById = getNodeById;
|
|
1803
|
-
this.
|
|
1804
|
-
this.
|
|
1805
|
-
this.onGetStateFromStorage = onGetStateFromStorage;
|
|
1806
|
-
this.onSetStateFromStorage = onSetStateFromStorage;
|
|
1807
|
-
this.openNode = openNode;
|
|
1808
|
-
this.refreshElements = refreshElements;
|
|
1809
|
-
this.removeFromSelection = removeFromSelection;
|
|
1810
|
-
this.saveStateOption = saveState;
|
|
1791
|
+
this.selectedNodes = new Set();
|
|
1792
|
+
this.clear();
|
|
1811
1793
|
}
|
|
1812
|
-
|
|
1813
|
-
const
|
|
1814
|
-
if (
|
|
1815
|
-
|
|
1816
|
-
} else
|
|
1817
|
-
|
|
1794
|
+
getSelectedNode() {
|
|
1795
|
+
const selectedNodes = this.getSelectedNodes();
|
|
1796
|
+
if (selectedNodes.length) {
|
|
1797
|
+
return selectedNodes[0] || false;
|
|
1798
|
+
} else {
|
|
1799
|
+
return false;
|
|
1818
1800
|
}
|
|
1819
1801
|
}
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
return this.parseState(jsonData);
|
|
1802
|
+
getSelectedNodes() {
|
|
1803
|
+
if (this.selectedSingleNode) {
|
|
1804
|
+
return [this.selectedSingleNode];
|
|
1824
1805
|
} else {
|
|
1825
|
-
|
|
1806
|
+
const selectedNodes = [];
|
|
1807
|
+
this.selectedNodes.forEach(id => {
|
|
1808
|
+
const node = this.getNodeById(id);
|
|
1809
|
+
if (node) {
|
|
1810
|
+
selectedNodes.push(node);
|
|
1811
|
+
}
|
|
1812
|
+
});
|
|
1813
|
+
return selectedNodes;
|
|
1826
1814
|
}
|
|
1827
1815
|
}
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
}
|
|
1835
|
-
return true;
|
|
1836
|
-
});
|
|
1837
|
-
return openNodes;
|
|
1838
|
-
};
|
|
1839
|
-
const getSelectedNodeIds = () => {
|
|
1840
|
-
const selectedNodeIds = [];
|
|
1841
|
-
this.getSelectedNodes().forEach(node => {
|
|
1842
|
-
if (node.id != null) {
|
|
1843
|
-
selectedNodeIds.push(node.id);
|
|
1844
|
-
}
|
|
1845
|
-
});
|
|
1846
|
-
return selectedNodeIds;
|
|
1847
|
-
};
|
|
1848
|
-
return {
|
|
1849
|
-
open_nodes: getOpenNodeIds(),
|
|
1850
|
-
selected_node: getSelectedNodeIds()
|
|
1851
|
-
};
|
|
1852
|
-
}
|
|
1853
|
-
|
|
1854
|
-
/*
|
|
1855
|
-
Set initial state
|
|
1856
|
-
Don't handle nodes that are loaded on demand
|
|
1857
|
-
result: must load on demand
|
|
1858
|
-
*/
|
|
1859
|
-
setInitialState(state) {
|
|
1860
|
-
if (!state) {
|
|
1861
|
-
return false;
|
|
1862
|
-
} else {
|
|
1863
|
-
let mustLoadOnDemand = false;
|
|
1864
|
-
if (state.open_nodes) {
|
|
1865
|
-
mustLoadOnDemand = this.openInitialNodes(state.open_nodes);
|
|
1816
|
+
getSelectedNodesUnder(parent) {
|
|
1817
|
+
if (this.selectedSingleNode) {
|
|
1818
|
+
if (parent.isParentOf(this.selectedSingleNode)) {
|
|
1819
|
+
return [this.selectedSingleNode];
|
|
1820
|
+
} else {
|
|
1821
|
+
return [];
|
|
1866
1822
|
}
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1823
|
+
} else {
|
|
1824
|
+
const selectedNodes = [];
|
|
1825
|
+
for (const id in this.selectedNodes) {
|
|
1826
|
+
if (Object.prototype.hasOwnProperty.call(this.selectedNodes, id)) {
|
|
1827
|
+
const node = this.getNodeById(id);
|
|
1828
|
+
if (node && parent.isParentOf(node)) {
|
|
1829
|
+
selectedNodes.push(node);
|
|
1830
|
+
}
|
|
1831
|
+
}
|
|
1870
1832
|
}
|
|
1871
|
-
return
|
|
1833
|
+
return selectedNodes;
|
|
1872
1834
|
}
|
|
1873
1835
|
}
|
|
1874
|
-
|
|
1875
|
-
if (
|
|
1876
|
-
this.
|
|
1836
|
+
isNodeSelected(node) {
|
|
1837
|
+
if (node.id != null) {
|
|
1838
|
+
return this.selectedNodes.has(node.id);
|
|
1839
|
+
} else if (this.selectedSingleNode) {
|
|
1840
|
+
return this.selectedSingleNode.element === node.element;
|
|
1877
1841
|
} else {
|
|
1878
|
-
|
|
1842
|
+
return false;
|
|
1879
1843
|
}
|
|
1880
1844
|
}
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1845
|
+
clear() {
|
|
1846
|
+
this.selectedNodes.clear();
|
|
1847
|
+
this.selectedSingleNode = null;
|
|
1848
|
+
}
|
|
1849
|
+
removeFromSelection(node) {
|
|
1850
|
+
let includeChildren = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
1851
|
+
if (node.id == null) {
|
|
1852
|
+
if (this.selectedSingleNode && node.element === this.selectedSingleNode.element) {
|
|
1853
|
+
this.selectedSingleNode = null;
|
|
1854
|
+
}
|
|
1885
1855
|
} else {
|
|
1886
|
-
|
|
1856
|
+
this.selectedNodes.delete(node.id);
|
|
1857
|
+
if (includeChildren) {
|
|
1858
|
+
node.iterate(() => {
|
|
1859
|
+
if (node.id != null) {
|
|
1860
|
+
this.selectedNodes.delete(node.id);
|
|
1861
|
+
}
|
|
1862
|
+
return true;
|
|
1863
|
+
});
|
|
1864
|
+
}
|
|
1887
1865
|
}
|
|
1888
1866
|
}
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
// Convert to array
|
|
1895
|
-
state.selected_node = [state.selected_node];
|
|
1867
|
+
addToSelection(node) {
|
|
1868
|
+
if (node.id != null) {
|
|
1869
|
+
this.selectedNodes.add(node.id);
|
|
1870
|
+
} else {
|
|
1871
|
+
this.selectedSingleNode = node;
|
|
1896
1872
|
}
|
|
1897
|
-
return state;
|
|
1898
1873
|
}
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1874
|
+
}
|
|
1875
|
+
|
|
1876
|
+
const register = (widgetClass, widgetName) => {
|
|
1877
|
+
const getDataKey = () => `simple_widget_${widgetName}`;
|
|
1878
|
+
const getWidgetData = (el, dataKey) => {
|
|
1879
|
+
const widget = jQuery.data(el, dataKey);
|
|
1880
|
+
if (widget && widget instanceof SimpleWidget) {
|
|
1881
|
+
return widget;
|
|
1904
1882
|
} else {
|
|
1905
1883
|
return null;
|
|
1906
1884
|
}
|
|
1907
|
-
}
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
for (const
|
|
1911
|
-
const
|
|
1912
|
-
if (
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1885
|
+
};
|
|
1886
|
+
const createWidget = ($el, options) => {
|
|
1887
|
+
const dataKey = getDataKey();
|
|
1888
|
+
for (const el of $el.get()) {
|
|
1889
|
+
const existingWidget = getWidgetData(el, dataKey);
|
|
1890
|
+
if (!existingWidget) {
|
|
1891
|
+
const simpleWidgetClass = widgetClass;
|
|
1892
|
+
const widget = new simpleWidgetClass(el, options);
|
|
1893
|
+
if (!jQuery.data(el, dataKey)) {
|
|
1894
|
+
jQuery.data(el, dataKey, widget);
|
|
1917
1895
|
}
|
|
1896
|
+
|
|
1897
|
+
// Call init after setting data, so we can call methods
|
|
1898
|
+
widget.init();
|
|
1918
1899
|
}
|
|
1919
1900
|
}
|
|
1920
|
-
return
|
|
1921
|
-
}
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
for (const
|
|
1925
|
-
const
|
|
1926
|
-
if (
|
|
1927
|
-
|
|
1928
|
-
this.addToSelection(node);
|
|
1901
|
+
return $el;
|
|
1902
|
+
};
|
|
1903
|
+
const destroyWidget = $el => {
|
|
1904
|
+
const dataKey = getDataKey();
|
|
1905
|
+
for (const el of $el.get()) {
|
|
1906
|
+
const widget = getWidgetData(el, dataKey);
|
|
1907
|
+
if (widget) {
|
|
1908
|
+
widget.destroy();
|
|
1929
1909
|
}
|
|
1910
|
+
jQuery.removeData(el, dataKey);
|
|
1930
1911
|
}
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
const
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
let nodeIds = nodeIdsParam;
|
|
1942
|
-
const openNodes = () => {
|
|
1943
|
-
const newNodesIds = [];
|
|
1944
|
-
for (const nodeId of nodeIds) {
|
|
1945
|
-
const node = this.getNodeById(nodeId);
|
|
1946
|
-
if (!node) {
|
|
1947
|
-
newNodesIds.push(nodeId);
|
|
1948
|
-
} else {
|
|
1949
|
-
if (!node.is_loading) {
|
|
1950
|
-
if (node.load_on_demand) {
|
|
1951
|
-
loadAndOpenNode(node);
|
|
1952
|
-
} else {
|
|
1953
|
-
this.openNode(node, false);
|
|
1954
|
-
}
|
|
1955
|
-
}
|
|
1912
|
+
};
|
|
1913
|
+
const callFunction = ($el, functionName, args) => {
|
|
1914
|
+
let result = null;
|
|
1915
|
+
for (const el of $el.get()) {
|
|
1916
|
+
const widget = jQuery.data(el, getDataKey());
|
|
1917
|
+
if (widget && widget instanceof SimpleWidget) {
|
|
1918
|
+
const simpleWidget = widget;
|
|
1919
|
+
const widgetFunction = simpleWidget[functionName];
|
|
1920
|
+
if (widgetFunction && typeof widgetFunction === "function") {
|
|
1921
|
+
result = widgetFunction.apply(widget, args);
|
|
1956
1922
|
}
|
|
1957
1923
|
}
|
|
1958
|
-
nodeIds = newNodesIds;
|
|
1959
|
-
if (this.selectInitialNodes(selectedNodes)) {
|
|
1960
|
-
this.refreshElements(null);
|
|
1961
|
-
}
|
|
1962
|
-
if (loadingCount === 0) {
|
|
1963
|
-
cbFinished();
|
|
1964
|
-
}
|
|
1965
|
-
};
|
|
1966
|
-
const loadAndOpenNode = node => {
|
|
1967
|
-
loadingCount += 1;
|
|
1968
|
-
this.openNode(node, false, () => {
|
|
1969
|
-
loadingCount -= 1;
|
|
1970
|
-
openNodes();
|
|
1971
|
-
});
|
|
1972
|
-
};
|
|
1973
|
-
openNodes();
|
|
1974
|
-
}
|
|
1975
|
-
getKeyName() {
|
|
1976
|
-
if (typeof this.saveStateOption === "string") {
|
|
1977
|
-
return this.saveStateOption;
|
|
1978
|
-
} else {
|
|
1979
|
-
return "tree";
|
|
1980
1924
|
}
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1925
|
+
return result;
|
|
1926
|
+
};
|
|
1927
|
+
|
|
1928
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
1929
|
+
jQuery.fn[widgetName] = function (argument1) {
|
|
1930
|
+
if (!argument1) {
|
|
1931
|
+
return createWidget(this, null);
|
|
1932
|
+
} else if (typeof argument1 === "object") {
|
|
1933
|
+
const options = argument1;
|
|
1934
|
+
return createWidget(this, options);
|
|
1935
|
+
} else if (typeof argument1 === "string" && argument1[0] !== "_") {
|
|
1936
|
+
const functionName = argument1;
|
|
1937
|
+
if (functionName === "destroy") {
|
|
1938
|
+
return destroyWidget(this);
|
|
1939
|
+
} else if (functionName === "get_widget_class") {
|
|
1940
|
+
return widgetClass;
|
|
1987
1941
|
} else {
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
const key = "_storage_test";
|
|
1991
|
-
sessionStorage.setItem(key, "value");
|
|
1992
|
-
sessionStorage.removeItem(key);
|
|
1993
|
-
} catch (error) {
|
|
1994
|
-
return false;
|
|
1942
|
+
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
1943
|
+
args[_key - 1] = arguments[_key];
|
|
1995
1944
|
}
|
|
1996
|
-
return
|
|
1945
|
+
return callFunction(this, functionName, args);
|
|
1997
1946
|
}
|
|
1998
|
-
}
|
|
1999
|
-
|
|
2000
|
-
this._supportsLocalStorage = testSupport();
|
|
1947
|
+
} else {
|
|
1948
|
+
return undefined;
|
|
2001
1949
|
}
|
|
2002
|
-
|
|
1950
|
+
};
|
|
1951
|
+
};
|
|
1952
|
+
class SimpleWidget {
|
|
1953
|
+
static register(widgetClass, widgetName) {
|
|
1954
|
+
register(widgetClass, widgetName);
|
|
2003
1955
|
}
|
|
2004
|
-
|
|
1956
|
+
static defaults = {};
|
|
1957
|
+
constructor(el, options) {
|
|
1958
|
+
this.$el = jQuery(el);
|
|
2005
1959
|
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
}
|
|
2012
|
-
this.$container = $container;
|
|
2013
|
-
this.refreshHitAreas = refreshHitAreas;
|
|
1960
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
1961
|
+
const defaults = this.constructor["defaults"];
|
|
1962
|
+
this.options = {
|
|
1963
|
+
...defaults,
|
|
1964
|
+
...options
|
|
1965
|
+
};
|
|
2014
1966
|
}
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
1967
|
+
destroy() {
|
|
1968
|
+
this.deinit();
|
|
1969
|
+
}
|
|
1970
|
+
init() {
|
|
1971
|
+
//
|
|
1972
|
+
}
|
|
1973
|
+
deinit() {
|
|
1974
|
+
//
|
|
1975
|
+
}
|
|
1976
|
+
}
|
|
1977
|
+
|
|
1978
|
+
const isNodeRecordWithChildren = data => typeof data === "object" && "children" in data && data["children"] instanceof Array;
|
|
1979
|
+
|
|
1980
|
+
class Node {
|
|
1981
|
+
constructor() {
|
|
1982
|
+
let nodeData = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
|
|
1983
|
+
let isRoot = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
1984
|
+
let nodeClass = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : Node;
|
|
1985
|
+
this.name = "";
|
|
1986
|
+
this.load_on_demand = false;
|
|
1987
|
+
this.isEmptyFolder = nodeData != null && isNodeRecordWithChildren(nodeData) && nodeData.children.length === 0;
|
|
1988
|
+
this.setData(nodeData);
|
|
1989
|
+
this.children = [];
|
|
1990
|
+
this.parent = null;
|
|
1991
|
+
if (isRoot) {
|
|
1992
|
+
this.idMapping = new Map();
|
|
1993
|
+
this.tree = this;
|
|
1994
|
+
this.nodeClass = nodeClass;
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1997
|
+
|
|
1998
|
+
/*
|
|
1999
|
+
Set the data of this node.
|
|
2000
|
+
setData(string): set the name of the node
|
|
2001
|
+
setData(object): set attributes of the node
|
|
2002
|
+
Examples:
|
|
2003
|
+
setData('node1')
|
|
2004
|
+
setData({ name: 'node1', id: 1});
|
|
2005
|
+
setData({ name: 'node2', id: 2, color: 'green'});
|
|
2006
|
+
* This is an internal function; it is not in the docs
|
|
2007
|
+
* Does not remove existing node values
|
|
2008
|
+
*/
|
|
2009
|
+
setData(o) {
|
|
2010
|
+
if (!o) {
|
|
2011
|
+
return;
|
|
2012
|
+
} else if (typeof o === "string") {
|
|
2013
|
+
this.name = o;
|
|
2014
|
+
} else if (typeof o === "object") {
|
|
2015
|
+
for (const key in o) {
|
|
2016
|
+
if (Object.prototype.hasOwnProperty.call(o, key)) {
|
|
2017
|
+
const value = o[key];
|
|
2018
|
+
if (key === "label" || key === "name") {
|
|
2019
|
+
// You can use the 'label' key instead of 'name'; this is a legacy feature
|
|
2020
|
+
if (typeof value === "string") {
|
|
2021
|
+
this.name = value;
|
|
2022
|
+
}
|
|
2023
|
+
} else if (key !== "children" && key !== "parent") {
|
|
2024
|
+
// You can't update the children or the parent using this function
|
|
2025
|
+
this[key] = value;
|
|
2026
|
+
}
|
|
2027
|
+
}
|
|
2024
2028
|
}
|
|
2025
2029
|
}
|
|
2026
2030
|
}
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2031
|
+
|
|
2032
|
+
/*
|
|
2033
|
+
Create tree from data.
|
|
2034
|
+
Structure of data is:
|
|
2035
|
+
[
|
|
2036
|
+
{
|
|
2037
|
+
name: 'node1',
|
|
2038
|
+
children: [
|
|
2039
|
+
{ name: 'child1' },
|
|
2040
|
+
{ name: 'child2' }
|
|
2041
|
+
]
|
|
2042
|
+
},
|
|
2043
|
+
{
|
|
2044
|
+
name: 'node2'
|
|
2034
2045
|
}
|
|
2035
|
-
|
|
2036
|
-
|
|
2046
|
+
]
|
|
2047
|
+
*/
|
|
2048
|
+
loadFromData(data) {
|
|
2049
|
+
this.removeChildren();
|
|
2050
|
+
for (const childData of data) {
|
|
2051
|
+
const node = this.createNode(childData);
|
|
2052
|
+
this.addChild(node);
|
|
2053
|
+
if (isNodeRecordWithChildren(childData)) {
|
|
2054
|
+
node.loadFromData(childData.children);
|
|
2037
2055
|
}
|
|
2038
2056
|
}
|
|
2057
|
+
return this;
|
|
2039
2058
|
}
|
|
2040
|
-
|
|
2041
|
-
|
|
2059
|
+
|
|
2060
|
+
/*
|
|
2061
|
+
Add child.
|
|
2062
|
+
tree.addChild(
|
|
2063
|
+
new Node('child1')
|
|
2064
|
+
);
|
|
2065
|
+
*/
|
|
2066
|
+
addChild(node) {
|
|
2067
|
+
this.children.push(node);
|
|
2068
|
+
node.setParent(this);
|
|
2042
2069
|
}
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2070
|
+
|
|
2071
|
+
/*
|
|
2072
|
+
Add child at position. Index starts at 0.
|
|
2073
|
+
tree.addChildAtPosition(
|
|
2074
|
+
new Node('abc'),
|
|
2075
|
+
1
|
|
2076
|
+
);
|
|
2077
|
+
*/
|
|
2078
|
+
addChildAtPosition(node, index) {
|
|
2079
|
+
this.children.splice(index, 0, node);
|
|
2080
|
+
node.setParent(this);
|
|
2046
2081
|
}
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2082
|
+
|
|
2083
|
+
/*
|
|
2084
|
+
Remove child. This also removes the children of the node.
|
|
2085
|
+
tree.removeChild(tree.children[0]);
|
|
2086
|
+
*/
|
|
2087
|
+
removeChild(node) {
|
|
2088
|
+
// remove children from the index
|
|
2089
|
+
node.removeChildren();
|
|
2090
|
+
this.doRemoveChild(node);
|
|
2052
2091
|
}
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
const leftEdge = scrollParentOffset.left;
|
|
2061
|
-
const isNearRightEdge = pageX > rightEdge - 20;
|
|
2062
|
-
const isNearLeftEdge = pageX < leftEdge + 20;
|
|
2063
|
-
if (isNearRightEdge) {
|
|
2064
|
-
return "right";
|
|
2065
|
-
} else if (isNearLeftEdge) {
|
|
2066
|
-
return "left";
|
|
2067
|
-
}
|
|
2068
|
-
return undefined;
|
|
2092
|
+
|
|
2093
|
+
/*
|
|
2094
|
+
Get child index.
|
|
2095
|
+
var index = getChildIndex(node);
|
|
2096
|
+
*/
|
|
2097
|
+
getChildIndex(node) {
|
|
2098
|
+
return this.children.indexOf(node);
|
|
2069
2099
|
}
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
return "bottom";
|
|
2076
|
-
}
|
|
2077
|
-
return undefined;
|
|
2100
|
+
|
|
2101
|
+
/*
|
|
2102
|
+
Does the tree have children?
|
|
2103
|
+
if (tree.hasChildren()) {
|
|
2104
|
+
//
|
|
2078
2105
|
}
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2106
|
+
*/
|
|
2107
|
+
hasChildren() {
|
|
2108
|
+
return this.children.length !== 0;
|
|
2109
|
+
}
|
|
2110
|
+
isFolder() {
|
|
2111
|
+
return this.hasChildren() || this.load_on_demand;
|
|
2112
|
+
}
|
|
2113
|
+
|
|
2114
|
+
/*
|
|
2115
|
+
Iterate over all the nodes in the tree.
|
|
2116
|
+
Calls callback with (node, level).
|
|
2117
|
+
The callback must return true to continue the iteration on current node.
|
|
2118
|
+
tree.iterate(
|
|
2119
|
+
function(node, level) {
|
|
2120
|
+
console.log(node.name);
|
|
2121
|
+
// stop iteration after level 2
|
|
2122
|
+
return (level <= 2);
|
|
2123
|
+
}
|
|
2124
|
+
);
|
|
2125
|
+
*/
|
|
2126
|
+
iterate(callback) {
|
|
2127
|
+
const _iterate = (node, level) => {
|
|
2128
|
+
if (node.children) {
|
|
2129
|
+
for (const child of node.children) {
|
|
2130
|
+
const result = callback(child, level);
|
|
2131
|
+
if (result && child.hasChildren()) {
|
|
2132
|
+
_iterate(child, level + 1);
|
|
2133
|
+
}
|
|
2134
|
+
}
|
|
2135
|
+
}
|
|
2136
|
+
};
|
|
2137
|
+
_iterate(this, 0);
|
|
2138
|
+
}
|
|
2139
|
+
|
|
2140
|
+
/*
|
|
2141
|
+
Move node relative to another node.
|
|
2142
|
+
Argument position: Position.BEFORE, Position.AFTER or Position.Inside
|
|
2143
|
+
// move node1 after node2
|
|
2144
|
+
tree.moveNode(node1, node2, Position.AFTER);
|
|
2145
|
+
*/
|
|
2146
|
+
moveNode(movedNode, targetNode, position) {
|
|
2147
|
+
if (!movedNode.parent || movedNode.isParentOf(targetNode)) {
|
|
2148
|
+
// - Node is parent of target node
|
|
2149
|
+
// - Or, parent is empty
|
|
2150
|
+
return false;
|
|
2151
|
+
} else {
|
|
2152
|
+
movedNode.parent.doRemoveChild(movedNode);
|
|
2153
|
+
switch (position) {
|
|
2154
|
+
case Position.After:
|
|
2155
|
+
{
|
|
2156
|
+
if (targetNode.parent) {
|
|
2157
|
+
targetNode.parent.addChildAtPosition(movedNode, targetNode.parent.getChildIndex(targetNode) + 1);
|
|
2158
|
+
return true;
|
|
2159
|
+
}
|
|
2160
|
+
return false;
|
|
2161
|
+
}
|
|
2162
|
+
case Position.Before:
|
|
2163
|
+
{
|
|
2164
|
+
if (targetNode.parent) {
|
|
2165
|
+
targetNode.parent.addChildAtPosition(movedNode, targetNode.parent.getChildIndex(targetNode));
|
|
2166
|
+
return true;
|
|
2167
|
+
}
|
|
2168
|
+
return false;
|
|
2169
|
+
}
|
|
2170
|
+
case Position.Inside:
|
|
2171
|
+
{
|
|
2172
|
+
// move inside as first child
|
|
2173
|
+
targetNode.addChildAtPosition(movedNode, 0);
|
|
2174
|
+
return true;
|
|
2175
|
+
}
|
|
2176
|
+
default:
|
|
2177
|
+
return false;
|
|
2178
|
+
}
|
|
2082
2179
|
}
|
|
2083
|
-
const distance = this.horizontalScrollDirection === "left" ? -20 : 20;
|
|
2084
|
-
const container = this.$container.get(0);
|
|
2085
|
-
container.scrollBy({
|
|
2086
|
-
left: distance,
|
|
2087
|
-
top: 0,
|
|
2088
|
-
behavior: "instant"
|
|
2089
|
-
});
|
|
2090
|
-
this.refreshHitAreas();
|
|
2091
|
-
setTimeout(this.scrollHorizontally.bind(this), 40);
|
|
2092
2180
|
}
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2181
|
+
|
|
2182
|
+
/*
|
|
2183
|
+
Get the tree as data.
|
|
2184
|
+
*/
|
|
2185
|
+
getData() {
|
|
2186
|
+
let includeParent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
2187
|
+
const getDataFromNodes = nodes => {
|
|
2188
|
+
return nodes.map(node => {
|
|
2189
|
+
const tmpNode = {};
|
|
2190
|
+
for (const k in node) {
|
|
2191
|
+
if (["parent", "children", "element", "idMapping", "load_on_demand", "nodeClass", "tree", "isEmptyFolder"].indexOf(k) === -1 && Object.prototype.hasOwnProperty.call(node, k)) {
|
|
2192
|
+
const v = node[k];
|
|
2193
|
+
tmpNode[k] = v;
|
|
2194
|
+
}
|
|
2195
|
+
}
|
|
2196
|
+
if (node.hasChildren()) {
|
|
2197
|
+
tmpNode["children"] = getDataFromNodes(node.children);
|
|
2198
|
+
}
|
|
2199
|
+
return tmpNode;
|
|
2200
|
+
});
|
|
2201
|
+
};
|
|
2202
|
+
if (includeParent) {
|
|
2203
|
+
return getDataFromNodes([this]);
|
|
2204
|
+
} else {
|
|
2205
|
+
return getDataFromNodes(this.children);
|
|
2096
2206
|
}
|
|
2097
|
-
const distance = this.verticalScrollDirection === "top" ? -20 : 20;
|
|
2098
|
-
const container = this.$container.get(0);
|
|
2099
|
-
container.scrollBy({
|
|
2100
|
-
left: 0,
|
|
2101
|
-
top: distance,
|
|
2102
|
-
behavior: "instant"
|
|
2103
|
-
});
|
|
2104
|
-
this.refreshHitAreas();
|
|
2105
|
-
setTimeout(this.scrollVertically.bind(this), 40);
|
|
2106
2207
|
}
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2208
|
+
getNodeByName(name) {
|
|
2209
|
+
return this.getNodeByCallback(node => node.name === name);
|
|
2210
|
+
}
|
|
2211
|
+
getNodeByNameMustExist(name) {
|
|
2212
|
+
const node = this.getNodeByCallback(n => n.name === name);
|
|
2213
|
+
if (!node) {
|
|
2214
|
+
throw `Node with name ${name} not found`;
|
|
2110
2215
|
}
|
|
2111
|
-
return
|
|
2216
|
+
return node;
|
|
2217
|
+
}
|
|
2218
|
+
getNodeByCallback(callback) {
|
|
2219
|
+
let result = null;
|
|
2220
|
+
this.iterate(node => {
|
|
2221
|
+
if (result) {
|
|
2222
|
+
return false;
|
|
2223
|
+
} else if (callback(node)) {
|
|
2224
|
+
result = node;
|
|
2225
|
+
return false;
|
|
2226
|
+
} else {
|
|
2227
|
+
return true;
|
|
2228
|
+
}
|
|
2229
|
+
});
|
|
2230
|
+
return result;
|
|
2112
2231
|
}
|
|
2113
|
-
|
|
2114
|
-
if (this.
|
|
2115
|
-
|
|
2232
|
+
addAfter(nodeInfo) {
|
|
2233
|
+
if (!this.parent) {
|
|
2234
|
+
return null;
|
|
2235
|
+
} else {
|
|
2236
|
+
const node = this.createNode(nodeInfo);
|
|
2237
|
+
const childIndex = this.parent.getChildIndex(this);
|
|
2238
|
+
this.parent.addChildAtPosition(node, childIndex + 1);
|
|
2239
|
+
node.loadChildrenFromData(nodeInfo);
|
|
2240
|
+
return node;
|
|
2116
2241
|
}
|
|
2117
|
-
return this.scrollParentBottom;
|
|
2118
|
-
}
|
|
2119
|
-
}
|
|
2120
|
-
|
|
2121
|
-
class DocumentScrollParent {
|
|
2122
|
-
constructor($element, refreshHitAreas) {
|
|
2123
|
-
this.$element = $element;
|
|
2124
|
-
this.refreshHitAreas = refreshHitAreas;
|
|
2125
2242
|
}
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
}
|
|
2243
|
+
addBefore(nodeInfo) {
|
|
2244
|
+
if (!this.parent) {
|
|
2245
|
+
return null;
|
|
2246
|
+
} else {
|
|
2247
|
+
const node = this.createNode(nodeInfo);
|
|
2248
|
+
const childIndex = this.parent.getChildIndex(this);
|
|
2249
|
+
this.parent.addChildAtPosition(node, childIndex);
|
|
2250
|
+
node.loadChildrenFromData(nodeInfo);
|
|
2251
|
+
return node;
|
|
2136
2252
|
}
|
|
2137
2253
|
}
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
this.
|
|
2254
|
+
addParent(nodeInfo) {
|
|
2255
|
+
if (!this.parent) {
|
|
2256
|
+
return null;
|
|
2257
|
+
} else {
|
|
2258
|
+
const newParent = this.createNode(nodeInfo);
|
|
2259
|
+
if (this.tree) {
|
|
2260
|
+
newParent.setParent(this.tree);
|
|
2145
2261
|
}
|
|
2146
|
-
|
|
2147
|
-
|
|
2262
|
+
const originalParent = this.parent;
|
|
2263
|
+
for (const child of originalParent.children) {
|
|
2264
|
+
newParent.addChild(child);
|
|
2148
2265
|
}
|
|
2266
|
+
originalParent.children = [];
|
|
2267
|
+
originalParent.addChild(newParent);
|
|
2268
|
+
return newParent;
|
|
2149
2269
|
}
|
|
2150
2270
|
}
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
const offset = this.$element.offset();
|
|
2156
|
-
const treeTop = offset ? offset.top : 0;
|
|
2157
|
-
jQuery(document).scrollTop(top + treeTop);
|
|
2158
|
-
}
|
|
2159
|
-
stopScrolling() {
|
|
2160
|
-
this.horizontalScrollDirection = undefined;
|
|
2161
|
-
this.verticalScrollDirection = undefined;
|
|
2162
|
-
this.documentScrollHeight = undefined;
|
|
2163
|
-
this.documentScrollWidth = undefined;
|
|
2164
|
-
}
|
|
2165
|
-
getNewHorizontalScrollDirection(pageX) {
|
|
2166
|
-
const $document = jQuery(document);
|
|
2167
|
-
const scrollLeft = $document.scrollLeft() || 0;
|
|
2168
|
-
const windowWidth = jQuery(window).width() || 0;
|
|
2169
|
-
const isNearRightEdge = pageX > windowWidth - 20;
|
|
2170
|
-
const isNearLeftEdge = pageX - scrollLeft < 20;
|
|
2171
|
-
if (isNearRightEdge && this.canScrollRight()) {
|
|
2172
|
-
return "right";
|
|
2173
|
-
}
|
|
2174
|
-
if (isNearLeftEdge) {
|
|
2175
|
-
return "left";
|
|
2271
|
+
remove() {
|
|
2272
|
+
if (this.parent) {
|
|
2273
|
+
this.parent.removeChild(this);
|
|
2274
|
+
this.parent = null;
|
|
2176
2275
|
}
|
|
2177
|
-
return undefined;
|
|
2178
2276
|
}
|
|
2179
|
-
|
|
2180
|
-
const
|
|
2181
|
-
|
|
2277
|
+
append(nodeInfo) {
|
|
2278
|
+
const node = this.createNode(nodeInfo);
|
|
2279
|
+
this.addChild(node);
|
|
2280
|
+
node.loadChildrenFromData(nodeInfo);
|
|
2281
|
+
return node;
|
|
2182
2282
|
}
|
|
2183
|
-
|
|
2184
|
-
const
|
|
2185
|
-
|
|
2283
|
+
prepend(nodeInfo) {
|
|
2284
|
+
const node = this.createNode(nodeInfo);
|
|
2285
|
+
this.addChildAtPosition(node, 0);
|
|
2286
|
+
node.loadChildrenFromData(nodeInfo);
|
|
2287
|
+
return node;
|
|
2186
2288
|
}
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
this
|
|
2289
|
+
isParentOf(node) {
|
|
2290
|
+
let parent = node.parent;
|
|
2291
|
+
while (parent) {
|
|
2292
|
+
if (parent === this) {
|
|
2293
|
+
return true;
|
|
2294
|
+
}
|
|
2295
|
+
parent = parent.parent;
|
|
2191
2296
|
}
|
|
2192
|
-
return
|
|
2297
|
+
return false;
|
|
2193
2298
|
}
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2299
|
+
getLevel() {
|
|
2300
|
+
let level = 0;
|
|
2301
|
+
let node = this; // eslint-disable-line @typescript-eslint/no-this-alias
|
|
2302
|
+
|
|
2303
|
+
while (node.parent) {
|
|
2304
|
+
level += 1;
|
|
2305
|
+
node = node.parent;
|
|
2198
2306
|
}
|
|
2199
|
-
return
|
|
2307
|
+
return level;
|
|
2200
2308
|
}
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
const distanceTop = pageY - scrollTop;
|
|
2204
|
-
if (distanceTop < 20) {
|
|
2205
|
-
return "top";
|
|
2206
|
-
}
|
|
2207
|
-
const windowHeight = jQuery(window).height() || 0;
|
|
2208
|
-
if (windowHeight - (pageY - scrollTop) < 20 && this.canScrollDown()) {
|
|
2209
|
-
return "bottom";
|
|
2210
|
-
}
|
|
2211
|
-
return undefined;
|
|
2309
|
+
getNodeById(nodeId) {
|
|
2310
|
+
return this.idMapping.get(nodeId) || null;
|
|
2212
2311
|
}
|
|
2213
|
-
|
|
2214
|
-
if (
|
|
2215
|
-
|
|
2312
|
+
addNodeToIndex(node) {
|
|
2313
|
+
if (node.id != null) {
|
|
2314
|
+
this.idMapping.set(node.id, node);
|
|
2216
2315
|
}
|
|
2217
|
-
const distance = this.horizontalScrollDirection === "left" ? -20 : 20;
|
|
2218
|
-
window.scrollBy({
|
|
2219
|
-
left: distance,
|
|
2220
|
-
top: 0,
|
|
2221
|
-
behavior: "instant"
|
|
2222
|
-
});
|
|
2223
|
-
this.refreshHitAreas();
|
|
2224
|
-
setTimeout(this.scrollHorizontally.bind(this), 40);
|
|
2225
2316
|
}
|
|
2226
|
-
|
|
2227
|
-
if (
|
|
2228
|
-
|
|
2317
|
+
removeNodeFromIndex(node) {
|
|
2318
|
+
if (node.id != null) {
|
|
2319
|
+
this.idMapping.delete(node.id);
|
|
2229
2320
|
}
|
|
2230
|
-
const distance = this.verticalScrollDirection === "top" ? -20 : 20;
|
|
2231
|
-
window.scrollBy({
|
|
2232
|
-
left: 0,
|
|
2233
|
-
top: distance,
|
|
2234
|
-
behavior: "instant"
|
|
2235
|
-
});
|
|
2236
|
-
this.refreshHitAreas();
|
|
2237
|
-
setTimeout(this.scrollVertically.bind(this), 40);
|
|
2238
2321
|
}
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
for (const attr of ["overflow", "overflow-y"]) {
|
|
2243
|
-
const overflowValue = $element.css(attr);
|
|
2244
|
-
if (overflowValue === "auto" || overflowValue === "scroll") {
|
|
2322
|
+
removeChildren() {
|
|
2323
|
+
this.iterate(child => {
|
|
2324
|
+
this.tree?.removeNodeFromIndex(child);
|
|
2245
2325
|
return true;
|
|
2246
|
-
}
|
|
2247
|
-
}
|
|
2248
|
-
return false;
|
|
2249
|
-
};
|
|
2250
|
-
const getParentWithOverflow = $treeElement => {
|
|
2251
|
-
if (hasOverFlow($treeElement)) {
|
|
2252
|
-
return $treeElement;
|
|
2253
|
-
}
|
|
2254
|
-
for (const element of $treeElement.parents().get()) {
|
|
2255
|
-
const $element = jQuery(element);
|
|
2256
|
-
if (hasOverFlow($element)) {
|
|
2257
|
-
return $element;
|
|
2258
|
-
}
|
|
2259
|
-
}
|
|
2260
|
-
return null;
|
|
2261
|
-
};
|
|
2262
|
-
const createScrollParent = ($treeElement, refreshHitAreas) => {
|
|
2263
|
-
const $container = getParentWithOverflow($treeElement);
|
|
2264
|
-
if ($container?.length && $container[0]?.tagName !== "HTML") {
|
|
2265
|
-
return new ContainerScrollParent({
|
|
2266
|
-
$container,
|
|
2267
|
-
refreshHitAreas,
|
|
2268
|
-
$treeElement
|
|
2269
2326
|
});
|
|
2270
|
-
|
|
2271
|
-
return new DocumentScrollParent($treeElement, refreshHitAreas);
|
|
2272
|
-
}
|
|
2273
|
-
};
|
|
2274
|
-
|
|
2275
|
-
class ScrollHandler {
|
|
2276
|
-
constructor(_ref) {
|
|
2277
|
-
let {
|
|
2278
|
-
refreshHitAreas,
|
|
2279
|
-
$treeElement
|
|
2280
|
-
} = _ref;
|
|
2281
|
-
this.refreshHitAreas = refreshHitAreas;
|
|
2282
|
-
this.scrollParent = undefined;
|
|
2283
|
-
this.$treeElement = $treeElement;
|
|
2284
|
-
}
|
|
2285
|
-
checkScrolling(positionInfo) {
|
|
2286
|
-
this.checkVerticalScrolling(positionInfo);
|
|
2287
|
-
this.checkHorizontalScrolling(positionInfo);
|
|
2288
|
-
}
|
|
2289
|
-
stopScrolling() {
|
|
2290
|
-
this.getScrollParent().stopScrolling();
|
|
2291
|
-
}
|
|
2292
|
-
scrollToY(top) {
|
|
2293
|
-
this.getScrollParent().scrollToY(top);
|
|
2294
|
-
}
|
|
2295
|
-
getScrollLeft() {
|
|
2296
|
-
return this.getScrollParent().getScrollLeft();
|
|
2327
|
+
this.children = [];
|
|
2297
2328
|
}
|
|
2298
|
-
|
|
2299
|
-
if (
|
|
2300
|
-
return;
|
|
2329
|
+
getPreviousSibling() {
|
|
2330
|
+
if (!this.parent) {
|
|
2331
|
+
return null;
|
|
2332
|
+
} else {
|
|
2333
|
+
const previousIndex = this.parent.getChildIndex(this) - 1;
|
|
2334
|
+
if (previousIndex >= 0) {
|
|
2335
|
+
return this.parent.children[previousIndex] || null;
|
|
2336
|
+
} else {
|
|
2337
|
+
return null;
|
|
2338
|
+
}
|
|
2301
2339
|
}
|
|
2302
|
-
this.getScrollParent().checkVerticalScrolling(positionInfo.pageY);
|
|
2303
2340
|
}
|
|
2304
|
-
|
|
2305
|
-
if (
|
|
2306
|
-
return;
|
|
2341
|
+
getNextSibling() {
|
|
2342
|
+
if (!this.parent) {
|
|
2343
|
+
return null;
|
|
2344
|
+
} else {
|
|
2345
|
+
const nextIndex = this.parent.getChildIndex(this) + 1;
|
|
2346
|
+
if (nextIndex < this.parent.children.length) {
|
|
2347
|
+
return this.parent.children[nextIndex] || null;
|
|
2348
|
+
} else {
|
|
2349
|
+
return null;
|
|
2350
|
+
}
|
|
2307
2351
|
}
|
|
2308
|
-
this.getScrollParent().checkHorizontalScrolling(positionInfo.pageX);
|
|
2309
2352
|
}
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
this.scrollParent = createScrollParent(this.$treeElement, this.refreshHitAreas);
|
|
2313
|
-
}
|
|
2314
|
-
return this.scrollParent;
|
|
2353
|
+
getNodesByProperty(key, value) {
|
|
2354
|
+
return this.filter(node => node[key] === value);
|
|
2315
2355
|
}
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
this.clear();
|
|
2356
|
+
filter(f) {
|
|
2357
|
+
const result = [];
|
|
2358
|
+
this.iterate(node => {
|
|
2359
|
+
if (f(node)) {
|
|
2360
|
+
result.push(node);
|
|
2361
|
+
}
|
|
2362
|
+
return true;
|
|
2363
|
+
});
|
|
2364
|
+
return result;
|
|
2326
2365
|
}
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
if (
|
|
2330
|
-
return
|
|
2366
|
+
getNextNode() {
|
|
2367
|
+
let includeChildren = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
|
2368
|
+
if (includeChildren && this.hasChildren()) {
|
|
2369
|
+
return this.children[0] || null;
|
|
2370
|
+
} else if (!this.parent) {
|
|
2371
|
+
return null;
|
|
2331
2372
|
} else {
|
|
2332
|
-
|
|
2373
|
+
const nextSibling = this.getNextSibling();
|
|
2374
|
+
if (nextSibling) {
|
|
2375
|
+
return nextSibling;
|
|
2376
|
+
} else {
|
|
2377
|
+
return this.parent.getNextNode(false);
|
|
2378
|
+
}
|
|
2333
2379
|
}
|
|
2334
2380
|
}
|
|
2335
|
-
|
|
2336
|
-
if (this.
|
|
2337
|
-
|
|
2381
|
+
getNextVisibleNode() {
|
|
2382
|
+
if (this.hasChildren() && this.is_open) {
|
|
2383
|
+
// First child
|
|
2384
|
+
return this.children[0] || null;
|
|
2338
2385
|
} else {
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2386
|
+
if (!this.parent) {
|
|
2387
|
+
return null;
|
|
2388
|
+
} else {
|
|
2389
|
+
const nextSibling = this.getNextSibling();
|
|
2390
|
+
if (nextSibling) {
|
|
2391
|
+
// Next sibling
|
|
2392
|
+
return nextSibling;
|
|
2393
|
+
} else {
|
|
2394
|
+
// Next node of parent
|
|
2395
|
+
return this.parent.getNextNode(false);
|
|
2344
2396
|
}
|
|
2345
|
-
}
|
|
2346
|
-
return selectedNodes;
|
|
2397
|
+
}
|
|
2347
2398
|
}
|
|
2348
2399
|
}
|
|
2349
|
-
|
|
2350
|
-
if (this.
|
|
2351
|
-
|
|
2352
|
-
|
|
2400
|
+
getPreviousNode() {
|
|
2401
|
+
if (!this.parent) {
|
|
2402
|
+
return null;
|
|
2403
|
+
} else {
|
|
2404
|
+
const previousSibling = this.getPreviousSibling();
|
|
2405
|
+
if (!previousSibling) {
|
|
2406
|
+
return this.getParent();
|
|
2407
|
+
} else if (previousSibling.hasChildren()) {
|
|
2408
|
+
return previousSibling.getLastChild();
|
|
2353
2409
|
} else {
|
|
2354
|
-
return
|
|
2410
|
+
return previousSibling;
|
|
2355
2411
|
}
|
|
2412
|
+
}
|
|
2413
|
+
}
|
|
2414
|
+
getPreviousVisibleNode() {
|
|
2415
|
+
if (!this.parent) {
|
|
2416
|
+
return null;
|
|
2356
2417
|
} else {
|
|
2357
|
-
const
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2418
|
+
const previousSibling = this.getPreviousSibling();
|
|
2419
|
+
if (!previousSibling) {
|
|
2420
|
+
return this.getParent();
|
|
2421
|
+
} else if (!previousSibling.hasChildren() || !previousSibling.is_open) {
|
|
2422
|
+
// Previous sibling
|
|
2423
|
+
return previousSibling;
|
|
2424
|
+
} else {
|
|
2425
|
+
// Last child of previous sibling
|
|
2426
|
+
return previousSibling.getLastChild();
|
|
2365
2427
|
}
|
|
2366
|
-
return selectedNodes;
|
|
2367
2428
|
}
|
|
2368
2429
|
}
|
|
2369
|
-
|
|
2370
|
-
if
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2430
|
+
getParent() {
|
|
2431
|
+
// Return parent except if it is the root node
|
|
2432
|
+
if (!this.parent) {
|
|
2433
|
+
return null;
|
|
2434
|
+
} else if (!this.parent.parent) {
|
|
2435
|
+
// Root node -> null
|
|
2436
|
+
return null;
|
|
2374
2437
|
} else {
|
|
2375
|
-
return
|
|
2438
|
+
return this.parent;
|
|
2376
2439
|
}
|
|
2377
2440
|
}
|
|
2378
|
-
|
|
2379
|
-
this.
|
|
2380
|
-
|
|
2381
|
-
}
|
|
2382
|
-
removeFromSelection(node) {
|
|
2383
|
-
let includeChildren = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
2384
|
-
if (node.id == null) {
|
|
2385
|
-
if (this.selectedSingleNode && node.element === this.selectedSingleNode.element) {
|
|
2386
|
-
this.selectedSingleNode = null;
|
|
2387
|
-
}
|
|
2441
|
+
getLastChild() {
|
|
2442
|
+
if (!this.hasChildren()) {
|
|
2443
|
+
return null;
|
|
2388
2444
|
} else {
|
|
2389
|
-
this.
|
|
2390
|
-
if (
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2445
|
+
const lastChild = this.children[this.children.length - 1];
|
|
2446
|
+
if (!lastChild) {
|
|
2447
|
+
return null;
|
|
2448
|
+
}
|
|
2449
|
+
if (!(lastChild.hasChildren() && lastChild.is_open)) {
|
|
2450
|
+
return lastChild;
|
|
2451
|
+
} else {
|
|
2452
|
+
return lastChild?.getLastChild();
|
|
2397
2453
|
}
|
|
2398
2454
|
}
|
|
2399
2455
|
}
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
this.
|
|
2456
|
+
|
|
2457
|
+
// Init Node from data without making it the root of the tree
|
|
2458
|
+
initFromData(data) {
|
|
2459
|
+
const addNode = nodeData => {
|
|
2460
|
+
this.setData(nodeData);
|
|
2461
|
+
if (isNodeRecordWithChildren(nodeData) && nodeData.children.length) {
|
|
2462
|
+
addChildren(nodeData.children);
|
|
2463
|
+
}
|
|
2464
|
+
};
|
|
2465
|
+
const addChildren = childrenData => {
|
|
2466
|
+
for (const child of childrenData) {
|
|
2467
|
+
const node = this.createNode();
|
|
2468
|
+
node.initFromData(child);
|
|
2469
|
+
this.addChild(node);
|
|
2470
|
+
}
|
|
2471
|
+
};
|
|
2472
|
+
addNode(data);
|
|
2473
|
+
}
|
|
2474
|
+
setParent(parent) {
|
|
2475
|
+
this.parent = parent;
|
|
2476
|
+
this.tree = parent.tree;
|
|
2477
|
+
this.tree?.addNodeToIndex(this);
|
|
2478
|
+
}
|
|
2479
|
+
doRemoveChild(node) {
|
|
2480
|
+
this.children.splice(this.getChildIndex(node), 1);
|
|
2481
|
+
this.tree?.removeNodeFromIndex(node);
|
|
2482
|
+
}
|
|
2483
|
+
getNodeClass() {
|
|
2484
|
+
return this.nodeClass || this?.tree?.nodeClass || Node;
|
|
2485
|
+
}
|
|
2486
|
+
createNode(nodeData) {
|
|
2487
|
+
const nodeClass = this.getNodeClass();
|
|
2488
|
+
return new nodeClass(nodeData);
|
|
2489
|
+
}
|
|
2490
|
+
|
|
2491
|
+
// Load children data from nodeInfo if it has children
|
|
2492
|
+
loadChildrenFromData(nodeInfo) {
|
|
2493
|
+
if (isNodeRecordWithChildren(nodeInfo) && nodeInfo.children.length) {
|
|
2494
|
+
this.loadFromData(nodeInfo.children);
|
|
2405
2495
|
}
|
|
2406
2496
|
}
|
|
2407
2497
|
}
|
|
@@ -2634,7 +2724,7 @@ var jqtree = (function (exports) {
|
|
|
2634
2724
|
|
|
2635
2725
|
const NODE_PARAM_IS_EMPTY = "Node parameter is empty";
|
|
2636
2726
|
const PARAM_IS_EMPTY = "Parameter is empty: ";
|
|
2637
|
-
class JqTreeWidget extends
|
|
2727
|
+
class JqTreeWidget extends SimpleWidget {
|
|
2638
2728
|
static defaults = {
|
|
2639
2729
|
animationSpeed: "fast",
|
|
2640
2730
|
autoEscape: true,
|
|
@@ -2740,7 +2830,7 @@ var jqtree = (function (exports) {
|
|
|
2740
2830
|
return this.element;
|
|
2741
2831
|
}
|
|
2742
2832
|
refresh() {
|
|
2743
|
-
this.
|
|
2833
|
+
this.refreshElements(null);
|
|
2744
2834
|
return this.element;
|
|
2745
2835
|
}
|
|
2746
2836
|
getNodeById(nodeId) {
|
|
@@ -2785,7 +2875,7 @@ var jqtree = (function (exports) {
|
|
|
2785
2875
|
return [slide, onFinished];
|
|
2786
2876
|
};
|
|
2787
2877
|
const [slide, onFinished] = parseParams();
|
|
2788
|
-
this.
|
|
2878
|
+
this.openNodeInternal(node, slide, onFinished);
|
|
2789
2879
|
return this.element;
|
|
2790
2880
|
}
|
|
2791
2881
|
closeNode(node, slideParam) {
|
|
@@ -2809,7 +2899,7 @@ var jqtree = (function (exports) {
|
|
|
2809
2899
|
addNodeAfter(newNodeInfo, existingNode) {
|
|
2810
2900
|
const newNode = existingNode.addAfter(newNodeInfo);
|
|
2811
2901
|
if (newNode) {
|
|
2812
|
-
this.
|
|
2902
|
+
this.refreshElements(existingNode.parent);
|
|
2813
2903
|
}
|
|
2814
2904
|
return newNode;
|
|
2815
2905
|
}
|
|
@@ -2819,7 +2909,7 @@ var jqtree = (function (exports) {
|
|
|
2819
2909
|
}
|
|
2820
2910
|
const newNode = existingNode.addBefore(newNodeInfo);
|
|
2821
2911
|
if (newNode) {
|
|
2822
|
-
this.
|
|
2912
|
+
this.refreshElements(existingNode.parent);
|
|
2823
2913
|
}
|
|
2824
2914
|
return newNode;
|
|
2825
2915
|
}
|
|
@@ -2829,7 +2919,7 @@ var jqtree = (function (exports) {
|
|
|
2829
2919
|
}
|
|
2830
2920
|
const newNode = existingNode.addParent(newNodeInfo);
|
|
2831
2921
|
if (newNode) {
|
|
2832
|
-
this.
|
|
2922
|
+
this.refreshElements(newNode.parent);
|
|
2833
2923
|
}
|
|
2834
2924
|
return newNode;
|
|
2835
2925
|
}
|
|
@@ -2844,19 +2934,19 @@ var jqtree = (function (exports) {
|
|
|
2844
2934
|
|
|
2845
2935
|
const parent = node.parent;
|
|
2846
2936
|
node.remove();
|
|
2847
|
-
this.
|
|
2937
|
+
this.refreshElements(parent);
|
|
2848
2938
|
return this.element;
|
|
2849
2939
|
}
|
|
2850
2940
|
appendNode(newNodeInfo, parentNodeParam) {
|
|
2851
2941
|
const parentNode = parentNodeParam || this.tree;
|
|
2852
2942
|
const node = parentNode.append(newNodeInfo);
|
|
2853
|
-
this.
|
|
2943
|
+
this.refreshElements(parentNode);
|
|
2854
2944
|
return node;
|
|
2855
2945
|
}
|
|
2856
2946
|
prependNode(newNodeInfo, parentNodeParam) {
|
|
2857
2947
|
const parentNode = parentNodeParam ?? this.tree;
|
|
2858
2948
|
const node = parentNode.prepend(newNodeInfo);
|
|
2859
|
-
this.
|
|
2949
|
+
this.refreshElements(parentNode);
|
|
2860
2950
|
return node;
|
|
2861
2951
|
}
|
|
2862
2952
|
updateNode(node, data) {
|
|
@@ -2877,7 +2967,7 @@ var jqtree = (function (exports) {
|
|
|
2877
2967
|
node.loadFromData(data.children);
|
|
2878
2968
|
}
|
|
2879
2969
|
}
|
|
2880
|
-
this.
|
|
2970
|
+
this.refreshElements(node);
|
|
2881
2971
|
return this.element;
|
|
2882
2972
|
}
|
|
2883
2973
|
isSelectedNodeInSubtree(subtree) {
|
|
@@ -2898,7 +2988,7 @@ var jqtree = (function (exports) {
|
|
|
2898
2988
|
const positionIndex = getPosition(position);
|
|
2899
2989
|
if (positionIndex !== undefined) {
|
|
2900
2990
|
this.tree.moveNode(node, targetNode, positionIndex);
|
|
2901
|
-
this.
|
|
2991
|
+
this.refreshElements(null);
|
|
2902
2992
|
}
|
|
2903
2993
|
return this.element;
|
|
2904
2994
|
}
|
|
@@ -2911,7 +3001,7 @@ var jqtree = (function (exports) {
|
|
|
2911
3001
|
}
|
|
2912
3002
|
this.selectNodeHandler.addToSelection(node);
|
|
2913
3003
|
this.openParents(node);
|
|
2914
|
-
this.
|
|
3004
|
+
this.getNodeElementForNode(node).select(mustSetFocus === undefined ? true : mustSetFocus);
|
|
2915
3005
|
this.saveState();
|
|
2916
3006
|
return this.element;
|
|
2917
3007
|
}
|
|
@@ -2929,7 +3019,7 @@ var jqtree = (function (exports) {
|
|
|
2929
3019
|
throw Error(NODE_PARAM_IS_EMPTY);
|
|
2930
3020
|
}
|
|
2931
3021
|
this.selectNodeHandler.removeFromSelection(node);
|
|
2932
|
-
this.
|
|
3022
|
+
this.getNodeElementForNode(node).deselect();
|
|
2933
3023
|
this.saveState();
|
|
2934
3024
|
return this.element;
|
|
2935
3025
|
}
|
|
@@ -2937,9 +3027,7 @@ var jqtree = (function (exports) {
|
|
|
2937
3027
|
if (!node) {
|
|
2938
3028
|
throw Error(NODE_PARAM_IS_EMPTY);
|
|
2939
3029
|
}
|
|
2940
|
-
const
|
|
2941
|
-
const treeTop = this.$el.offset()?.top ?? 0;
|
|
2942
|
-
const top = nodeTop - treeTop;
|
|
3030
|
+
const top = getOffsetTop(node.element) - getOffsetTop(this.$el.get(0));
|
|
2943
3031
|
this.scrollHandler.scrollToY(top);
|
|
2944
3032
|
return this.element;
|
|
2945
3033
|
}
|
|
@@ -2948,7 +3036,7 @@ var jqtree = (function (exports) {
|
|
|
2948
3036
|
}
|
|
2949
3037
|
setState(state) {
|
|
2950
3038
|
this.saveStateHandler.setInitialState(state);
|
|
2951
|
-
this.
|
|
3039
|
+
this.refreshElements(null);
|
|
2952
3040
|
return this.element;
|
|
2953
3041
|
}
|
|
2954
3042
|
setOption(option, value) {
|
|
@@ -2972,12 +3060,7 @@ var jqtree = (function (exports) {
|
|
|
2972
3060
|
getVersion() {
|
|
2973
3061
|
return version;
|
|
2974
3062
|
}
|
|
2975
|
-
|
|
2976
|
-
const event = jQuery.Event(eventName, values);
|
|
2977
|
-
this.element.trigger(event);
|
|
2978
|
-
return event;
|
|
2979
|
-
}
|
|
2980
|
-
_openNode(node) {
|
|
3063
|
+
openNodeInternal(node) {
|
|
2981
3064
|
let slide = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
2982
3065
|
let onFinished = arguments.length > 2 ? arguments[2] : undefined;
|
|
2983
3066
|
const doOpenNode = (_node, _slide, _onFinished) => {
|
|
@@ -3006,33 +3089,30 @@ var jqtree = (function (exports) {
|
|
|
3006
3089
|
Redraw the tree or part of the tree.
|
|
3007
3090
|
from_node: redraw this subtree
|
|
3008
3091
|
*/
|
|
3009
|
-
|
|
3092
|
+
refreshElements(fromNode) {
|
|
3010
3093
|
const mustSetFocus = this.isFocusOnTree();
|
|
3011
3094
|
const mustSelect = fromNode ? this.isSelectedNodeInSubtree(fromNode) : false;
|
|
3012
3095
|
this.renderer.render(fromNode);
|
|
3013
3096
|
if (mustSelect) {
|
|
3014
3097
|
this.selectCurrentNode(mustSetFocus);
|
|
3015
3098
|
}
|
|
3016
|
-
this.
|
|
3099
|
+
this.triggerEvent("tree.refresh");
|
|
3017
3100
|
}
|
|
3018
|
-
|
|
3101
|
+
getNodeElementForNode(node) {
|
|
3019
3102
|
if (node.isFolder()) {
|
|
3020
3103
|
return this.createFolderElement(node);
|
|
3021
3104
|
} else {
|
|
3022
3105
|
return this.createNodeElement(node);
|
|
3023
3106
|
}
|
|
3024
3107
|
}
|
|
3025
|
-
|
|
3108
|
+
getNodeElement(element) {
|
|
3026
3109
|
const node = this.getNode(element);
|
|
3027
3110
|
if (node) {
|
|
3028
|
-
return this.
|
|
3111
|
+
return this.getNodeElementForNode(node);
|
|
3029
3112
|
} else {
|
|
3030
3113
|
return null;
|
|
3031
3114
|
}
|
|
3032
3115
|
}
|
|
3033
|
-
_getScrollLeft() {
|
|
3034
|
-
return this.scrollHandler.getScrollLeft();
|
|
3035
|
-
}
|
|
3036
3116
|
init() {
|
|
3037
3117
|
super.init();
|
|
3038
3118
|
this.element = this.$el;
|
|
@@ -3043,19 +3123,20 @@ var jqtree = (function (exports) {
|
|
|
3043
3123
|
}
|
|
3044
3124
|
this.connectHandlers();
|
|
3045
3125
|
this.initData();
|
|
3046
|
-
this.element.on("click", this.handleClick);
|
|
3047
|
-
this.element.on("dblclick", this.handleDblclick);
|
|
3048
|
-
if (this.options.useContextMenu) {
|
|
3049
|
-
this.element.on("contextmenu", this.handleContextmenu);
|
|
3050
|
-
}
|
|
3051
3126
|
}
|
|
3052
3127
|
deinit() {
|
|
3053
3128
|
this.element.empty();
|
|
3054
3129
|
this.element.off();
|
|
3055
3130
|
this.keyHandler.deinit();
|
|
3131
|
+
this.mouseHandler.deinit();
|
|
3056
3132
|
this.tree = new Node({}, true);
|
|
3057
3133
|
super.deinit();
|
|
3058
3134
|
}
|
|
3135
|
+
triggerEvent(eventName, values) {
|
|
3136
|
+
const event = jQuery.Event(eventName, values);
|
|
3137
|
+
this.element.trigger(event);
|
|
3138
|
+
return event;
|
|
3139
|
+
}
|
|
3059
3140
|
mouseCapture(positionInfo) {
|
|
3060
3141
|
if (this.options.dragAndDrop) {
|
|
3061
3142
|
return this.dndHandler.mouseCapture(positionInfo);
|
|
@@ -3087,9 +3168,6 @@ var jqtree = (function (exports) {
|
|
|
3087
3168
|
return false;
|
|
3088
3169
|
}
|
|
3089
3170
|
}
|
|
3090
|
-
getMouseDelay() {
|
|
3091
|
-
return this.options.startDndDelay ?? 0;
|
|
3092
|
-
}
|
|
3093
3171
|
initData() {
|
|
3094
3172
|
if (this.options.data) {
|
|
3095
3173
|
this.doLoadData(this.options.data, null);
|
|
@@ -3151,7 +3229,7 @@ var jqtree = (function (exports) {
|
|
|
3151
3229
|
const doInit = () => {
|
|
3152
3230
|
if (!this.isInitialized) {
|
|
3153
3231
|
this.isInitialized = true;
|
|
3154
|
-
this.
|
|
3232
|
+
this.triggerEvent("tree.init");
|
|
3155
3233
|
}
|
|
3156
3234
|
};
|
|
3157
3235
|
if (!this.options.nodeClass) {
|
|
@@ -3161,7 +3239,7 @@ var jqtree = (function (exports) {
|
|
|
3161
3239
|
this.selectNodeHandler.clear();
|
|
3162
3240
|
this.tree.loadFromData(data);
|
|
3163
3241
|
const mustLoadOnDemand = this.setInitialState();
|
|
3164
|
-
this.
|
|
3242
|
+
this.refreshElements(null);
|
|
3165
3243
|
if (!mustLoadOnDemand) {
|
|
3166
3244
|
doInit();
|
|
3167
3245
|
} else {
|
|
@@ -3238,7 +3316,7 @@ var jqtree = (function (exports) {
|
|
|
3238
3316
|
let loadingCount = 0;
|
|
3239
3317
|
const loadAndOpenNode = node => {
|
|
3240
3318
|
loadingCount += 1;
|
|
3241
|
-
this.
|
|
3319
|
+
this.openNodeInternal(node, false, () => {
|
|
3242
3320
|
loadingCount -= 1;
|
|
3243
3321
|
openNodes();
|
|
3244
3322
|
});
|
|
@@ -3251,7 +3329,7 @@ var jqtree = (function (exports) {
|
|
|
3251
3329
|
}
|
|
3252
3330
|
return false;
|
|
3253
3331
|
} else {
|
|
3254
|
-
this.
|
|
3332
|
+
this.openNodeInternal(node, false);
|
|
3255
3333
|
return level !== maxLevel;
|
|
3256
3334
|
}
|
|
3257
3335
|
});
|
|
@@ -3276,58 +3354,6 @@ var jqtree = (function (exports) {
|
|
|
3276
3354
|
return 0;
|
|
3277
3355
|
}
|
|
3278
3356
|
}
|
|
3279
|
-
handleClick = e => {
|
|
3280
|
-
const clickTarget = this.getClickTarget(e.target);
|
|
3281
|
-
if (clickTarget) {
|
|
3282
|
-
if (clickTarget.type === "button") {
|
|
3283
|
-
this.toggle(clickTarget.node, this.options.slide);
|
|
3284
|
-
e.preventDefault();
|
|
3285
|
-
e.stopPropagation();
|
|
3286
|
-
} else if (clickTarget.type === "label") {
|
|
3287
|
-
const node = clickTarget.node;
|
|
3288
|
-
const event = this._triggerEvent("tree.click", {
|
|
3289
|
-
node,
|
|
3290
|
-
click_event: e
|
|
3291
|
-
});
|
|
3292
|
-
if (!event.isDefaultPrevented()) {
|
|
3293
|
-
this.doSelectNode(node);
|
|
3294
|
-
}
|
|
3295
|
-
}
|
|
3296
|
-
}
|
|
3297
|
-
};
|
|
3298
|
-
handleDblclick = e => {
|
|
3299
|
-
const clickTarget = this.getClickTarget(e.target);
|
|
3300
|
-
if (clickTarget?.type === "label") {
|
|
3301
|
-
this._triggerEvent("tree.dblclick", {
|
|
3302
|
-
node: clickTarget.node,
|
|
3303
|
-
click_event: e
|
|
3304
|
-
});
|
|
3305
|
-
}
|
|
3306
|
-
};
|
|
3307
|
-
getClickTarget(element) {
|
|
3308
|
-
const button = element.closest(".jqtree-toggler");
|
|
3309
|
-
if (button) {
|
|
3310
|
-
const node = this.getNode(button);
|
|
3311
|
-
if (node) {
|
|
3312
|
-
return {
|
|
3313
|
-
type: "button",
|
|
3314
|
-
node
|
|
3315
|
-
};
|
|
3316
|
-
}
|
|
3317
|
-
} else {
|
|
3318
|
-
const jqTreeElement = element.closest(".jqtree-element");
|
|
3319
|
-
if (jqTreeElement) {
|
|
3320
|
-
const node = this.getNode(jqTreeElement);
|
|
3321
|
-
if (node) {
|
|
3322
|
-
return {
|
|
3323
|
-
type: "label",
|
|
3324
|
-
node
|
|
3325
|
-
};
|
|
3326
|
-
}
|
|
3327
|
-
}
|
|
3328
|
-
}
|
|
3329
|
-
return null;
|
|
3330
|
-
}
|
|
3331
3357
|
getNode(element) {
|
|
3332
3358
|
const liElement = element.closest("li.jqtree_common");
|
|
3333
3359
|
if (liElement) {
|
|
@@ -3336,22 +3362,6 @@ var jqtree = (function (exports) {
|
|
|
3336
3362
|
return null;
|
|
3337
3363
|
}
|
|
3338
3364
|
}
|
|
3339
|
-
handleContextmenu = e => {
|
|
3340
|
-
const div = e.target.closest("ul.jqtree-tree .jqtree-element");
|
|
3341
|
-
if (div) {
|
|
3342
|
-
const node = this.getNode(div);
|
|
3343
|
-
if (node) {
|
|
3344
|
-
e.preventDefault();
|
|
3345
|
-
e.stopPropagation();
|
|
3346
|
-
this._triggerEvent("tree.contextmenu", {
|
|
3347
|
-
node,
|
|
3348
|
-
click_event: e
|
|
3349
|
-
});
|
|
3350
|
-
return false;
|
|
3351
|
-
}
|
|
3352
|
-
}
|
|
3353
|
-
return null;
|
|
3354
|
-
};
|
|
3355
3365
|
saveState() {
|
|
3356
3366
|
if (this.options.saveState) {
|
|
3357
3367
|
this.saveStateHandler.saveState();
|
|
@@ -3360,7 +3370,7 @@ var jqtree = (function (exports) {
|
|
|
3360
3370
|
selectCurrentNode(mustSetFocus) {
|
|
3361
3371
|
const node = this.getSelectedNode();
|
|
3362
3372
|
if (node) {
|
|
3363
|
-
const nodeElement = this.
|
|
3373
|
+
const nodeElement = this.getNodeElementForNode(node);
|
|
3364
3374
|
if (nodeElement) {
|
|
3365
3375
|
nodeElement.select(mustSetFocus);
|
|
3366
3376
|
}
|
|
@@ -3426,7 +3436,7 @@ var jqtree = (function (exports) {
|
|
|
3426
3436
|
if (this.selectNodeHandler.isNodeSelected(node)) {
|
|
3427
3437
|
if (selectOptions.mustToggle) {
|
|
3428
3438
|
this.deselectCurrentNode();
|
|
3429
|
-
this.
|
|
3439
|
+
this.triggerEvent("tree.select", {
|
|
3430
3440
|
node: null,
|
|
3431
3441
|
previous_node: node
|
|
3432
3442
|
});
|
|
@@ -3435,7 +3445,7 @@ var jqtree = (function (exports) {
|
|
|
3435
3445
|
const deselectedNode = this.getSelectedNode() || null;
|
|
3436
3446
|
this.deselectCurrentNode();
|
|
3437
3447
|
this.addToSelection(node, selectOptions.mustSetFocus);
|
|
3438
|
-
this.
|
|
3448
|
+
this.triggerEvent("tree.select", {
|
|
3439
3449
|
node,
|
|
3440
3450
|
deselected_node: deselectedNode
|
|
3441
3451
|
});
|
|
@@ -3455,7 +3465,7 @@ var jqtree = (function (exports) {
|
|
|
3455
3465
|
this.dndHandler.refresh();
|
|
3456
3466
|
}
|
|
3457
3467
|
}
|
|
3458
|
-
this.
|
|
3468
|
+
this.triggerEvent("tree.load_data", {
|
|
3459
3469
|
tree_data: data,
|
|
3460
3470
|
parent_node: parentNode
|
|
3461
3471
|
});
|
|
@@ -3470,7 +3480,7 @@ var jqtree = (function (exports) {
|
|
|
3470
3480
|
parentNode.loadFromData(data);
|
|
3471
3481
|
parentNode.load_on_demand = false;
|
|
3472
3482
|
parentNode.is_loading = false;
|
|
3473
|
-
this.
|
|
3483
|
+
this.refreshElements(parentNode);
|
|
3474
3484
|
}
|
|
3475
3485
|
doLoadDataFromUrl(urlInfoParam, parentNode, onFinished) {
|
|
3476
3486
|
const urlInfo = urlInfoParam || this.getDataUrlInfo(parentNode);
|
|
@@ -3481,7 +3491,7 @@ var jqtree = (function (exports) {
|
|
|
3481
3491
|
let onFinished = arguments.length > 2 ? arguments[2] : undefined;
|
|
3482
3492
|
node.is_loading = true;
|
|
3483
3493
|
this.doLoadDataFromUrl(null, node, () => {
|
|
3484
|
-
this.
|
|
3494
|
+
this.openNodeInternal(node, slide, onFinished);
|
|
3485
3495
|
});
|
|
3486
3496
|
}
|
|
3487
3497
|
containsElement(element) {
|
|
@@ -3501,6 +3511,7 @@ var jqtree = (function (exports) {
|
|
|
3501
3511
|
dragAndDrop,
|
|
3502
3512
|
keyboardSupport,
|
|
3503
3513
|
onCanMove,
|
|
3514
|
+
onCanMoveTo,
|
|
3504
3515
|
onCreateLi,
|
|
3505
3516
|
onDragMove,
|
|
3506
3517
|
onDragStop,
|
|
@@ -3518,20 +3529,20 @@ var jqtree = (function (exports) {
|
|
|
3518
3529
|
tabIndex
|
|
3519
3530
|
} = this.options;
|
|
3520
3531
|
const closeNode = this.closeNode.bind(this);
|
|
3521
|
-
const getNodeElement = this.
|
|
3522
|
-
const getNodeElementForNode = this.
|
|
3532
|
+
const getNodeElement = this.getNodeElement.bind(this);
|
|
3533
|
+
const getNodeElementForNode = this.getNodeElementForNode.bind(this);
|
|
3523
3534
|
const getNodeById = this.getNodeById.bind(this);
|
|
3524
|
-
const getScrollLeft = this._getScrollLeft.bind(this);
|
|
3525
3535
|
const getSelectedNode = this.getSelectedNode.bind(this);
|
|
3526
3536
|
const getTree = this.getTree.bind(this);
|
|
3527
3537
|
const isFocusOnTree = this.isFocusOnTree.bind(this);
|
|
3528
3538
|
const loadData = this.loadData.bind(this);
|
|
3529
|
-
const openNode = this.
|
|
3530
|
-
const refreshElements = this.
|
|
3539
|
+
const openNode = this.openNodeInternal.bind(this);
|
|
3540
|
+
const refreshElements = this.refreshElements.bind(this);
|
|
3531
3541
|
const refreshHitAreas = this.refreshHitAreas.bind(this);
|
|
3532
3542
|
const selectNode = this.selectNode.bind(this);
|
|
3533
3543
|
const $treeElement = this.element;
|
|
3534
|
-
const
|
|
3544
|
+
const treeElement = this.element.get(0);
|
|
3545
|
+
const triggerEvent = this.triggerEvent.bind(this);
|
|
3535
3546
|
const selectNodeHandler = new SelectNodeHandler({
|
|
3536
3547
|
getNodeById
|
|
3537
3548
|
});
|
|
@@ -3539,12 +3550,13 @@ var jqtree = (function (exports) {
|
|
|
3539
3550
|
const getSelectedNodes = selectNodeHandler.getSelectedNodes.bind(selectNodeHandler);
|
|
3540
3551
|
const isNodeSelected = selectNodeHandler.isNodeSelected.bind(selectNodeHandler);
|
|
3541
3552
|
const removeFromSelection = selectNodeHandler.removeFromSelection.bind(selectNodeHandler);
|
|
3553
|
+
const getMouseDelay = () => this.options.startDndDelay ?? 0;
|
|
3542
3554
|
const dataLoader = new DataLoader({
|
|
3543
3555
|
dataFilter,
|
|
3544
3556
|
loadData,
|
|
3545
3557
|
onLoadFailed,
|
|
3546
3558
|
onLoading,
|
|
3547
|
-
|
|
3559
|
+
treeElement,
|
|
3548
3560
|
triggerEvent
|
|
3549
3561
|
});
|
|
3550
3562
|
const saveStateHandler = new SaveStateHandler({
|
|
@@ -3559,6 +3571,11 @@ var jqtree = (function (exports) {
|
|
|
3559
3571
|
removeFromSelection,
|
|
3560
3572
|
saveState
|
|
3561
3573
|
});
|
|
3574
|
+
const scrollHandler = new ScrollHandler({
|
|
3575
|
+
refreshHitAreas,
|
|
3576
|
+
treeElement
|
|
3577
|
+
});
|
|
3578
|
+
const getScrollLeft = scrollHandler.getScrollLeft.bind(scrollHandler);
|
|
3562
3579
|
const dndHandler = new DragAndDropHandler({
|
|
3563
3580
|
autoEscape,
|
|
3564
3581
|
getNodeElement,
|
|
@@ -3566,6 +3583,7 @@ var jqtree = (function (exports) {
|
|
|
3566
3583
|
getScrollLeft,
|
|
3567
3584
|
getTree,
|
|
3568
3585
|
onCanMove,
|
|
3586
|
+
onCanMoveTo,
|
|
3569
3587
|
onDragMove,
|
|
3570
3588
|
onDragStop,
|
|
3571
3589
|
onIsMoveHandle,
|
|
@@ -3573,13 +3591,9 @@ var jqtree = (function (exports) {
|
|
|
3573
3591
|
openNode,
|
|
3574
3592
|
refreshElements,
|
|
3575
3593
|
slide,
|
|
3576
|
-
|
|
3594
|
+
treeElement,
|
|
3577
3595
|
triggerEvent
|
|
3578
3596
|
});
|
|
3579
|
-
const scrollHandler = new ScrollHandler({
|
|
3580
|
-
refreshHitAreas,
|
|
3581
|
-
$treeElement
|
|
3582
|
-
});
|
|
3583
3597
|
const keyHandler = new KeyHandler({
|
|
3584
3598
|
closeNode,
|
|
3585
3599
|
getSelectedNode,
|
|
@@ -3602,9 +3616,28 @@ var jqtree = (function (exports) {
|
|
|
3602
3616
|
showEmptyFolder,
|
|
3603
3617
|
tabIndex
|
|
3604
3618
|
});
|
|
3619
|
+
const getNode = this.getNode.bind(this);
|
|
3620
|
+
const onMouseCapture = this.mouseCapture.bind(this);
|
|
3621
|
+
const onMouseDrag = this.mouseDrag.bind(this);
|
|
3622
|
+
const onMouseStart = this.mouseStart.bind(this);
|
|
3623
|
+
const onMouseStop = this.mouseStop.bind(this);
|
|
3624
|
+
const mouseHandler = new MouseHandler({
|
|
3625
|
+
element: treeElement,
|
|
3626
|
+
getMouseDelay,
|
|
3627
|
+
getNode,
|
|
3628
|
+
onClickButton: this.toggle.bind(this),
|
|
3629
|
+
onClickTitle: this.doSelectNode.bind(this),
|
|
3630
|
+
onMouseCapture,
|
|
3631
|
+
onMouseDrag,
|
|
3632
|
+
onMouseStart,
|
|
3633
|
+
onMouseStop,
|
|
3634
|
+
triggerEvent,
|
|
3635
|
+
useContextMenu: this.options.useContextMenu
|
|
3636
|
+
});
|
|
3605
3637
|
this.dataLoader = dataLoader;
|
|
3606
3638
|
this.dndHandler = dndHandler;
|
|
3607
3639
|
this.keyHandler = keyHandler;
|
|
3640
|
+
this.mouseHandler = mouseHandler;
|
|
3608
3641
|
this.renderer = renderer;
|
|
3609
3642
|
this.saveStateHandler = saveStateHandler;
|
|
3610
3643
|
this.scrollHandler = scrollHandler;
|
|
@@ -3612,11 +3645,11 @@ var jqtree = (function (exports) {
|
|
|
3612
3645
|
}
|
|
3613
3646
|
createFolderElement(node) {
|
|
3614
3647
|
const closedIconElement = this.renderer.closedIconElement;
|
|
3615
|
-
const getScrollLeft = this.
|
|
3648
|
+
const getScrollLeft = this.scrollHandler.getScrollLeft.bind(this.scrollHandler);
|
|
3616
3649
|
const openedIconElement = this.renderer.openedIconElement;
|
|
3617
3650
|
const tabIndex = this.options.tabIndex;
|
|
3618
3651
|
const $treeElement = this.element;
|
|
3619
|
-
const triggerEvent = this.
|
|
3652
|
+
const triggerEvent = this.triggerEvent.bind(this);
|
|
3620
3653
|
return new FolderElement({
|
|
3621
3654
|
closedIconElement,
|
|
3622
3655
|
getScrollLeft,
|
|
@@ -3628,7 +3661,7 @@ var jqtree = (function (exports) {
|
|
|
3628
3661
|
});
|
|
3629
3662
|
}
|
|
3630
3663
|
createNodeElement(node) {
|
|
3631
|
-
const getScrollLeft = this.
|
|
3664
|
+
const getScrollLeft = this.scrollHandler.getScrollLeft.bind(this.scrollHandler);
|
|
3632
3665
|
const tabIndex = this.options.tabIndex;
|
|
3633
3666
|
const $treeElement = this.element;
|
|
3634
3667
|
return new NodeElement({
|