jqtree 1.9.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bower.json +1 -1
- package/js-coverage/coverage-final.json +13 -0
- package/lib/jqtreeOptions.js +1 -0
- package/lib/tree.jquery.d.js +0 -0
- package/lib/tree.jquery.js +394 -0
- package/lib/triggerJQueryEvent.js +68 -0
- package/lib/typings.d.js +1 -0
- package/lib/version.js +2 -0
- package/package.json +34 -29
- package/pnpm-workspace.yaml +3 -3
- package/src/jqtreeOptions.ts +20 -62
- package/src/tree.jquery.d.ts +81 -92
- package/src/tree.jquery.ts +234 -938
- package/src/triggerJQueryEvent.ts +97 -0
- package/src/version.ts +2 -2
- package/tree.jquery.debug.js +4226 -3281
- package/tree.jquery.debug.js.map +1 -1
- package/tree.jquery.js +22 -2
- package/tree.jquery.js.map +1 -1
- package/eslint.config.mjs +0 -112
- package/src/animation.ts +0 -48
- package/src/dataLoader.ts +0 -143
- package/src/dragAndDropHandler/binarySearch.ts +0 -27
- package/src/dragAndDropHandler/dragElement.ts +0 -54
- package/src/dragAndDropHandler/generateHitAreas.ts +0 -195
- package/src/dragAndDropHandler/index.ts +0 -432
- package/src/dragAndDropHandler/iterateVisibleNodes.ts +0 -91
- package/src/dragAndDropHandler/types.ts +0 -12
- package/src/elementsRenderer.ts +0 -359
- package/src/jqtreeMethodTypes.ts +0 -40
- package/src/keyHandler.ts +0 -139
- package/src/mouseHandler.ts +0 -383
- package/src/mouseUtils.ts +0 -23
- package/src/node.ts +0 -653
- package/src/nodeElement/borderDropHint.ts +0 -32
- package/src/nodeElement/folderElement.ts +0 -138
- package/src/nodeElement/ghostDropHint.ts +0 -74
- package/src/nodeElement/index.ts +0 -94
- package/src/nodeUtils.ts +0 -10
- package/src/positionUtils.ts +0 -18
- package/src/saveStateHandler.ts +0 -276
- package/src/scrollHandler/containerScrollParent.ts +0 -71
- package/src/scrollHandler/createScrollParent.ts +0 -51
- package/src/scrollHandler/documentScrollParent.ts +0 -104
- package/src/scrollHandler/scrollParent.ts +0 -117
- package/src/scrollHandler.ts +0 -55
- package/src/selectNodeHandler.ts +0 -111
- package/src/simple.widget.ts +0 -134
- package/src/util.ts +0 -5
|
@@ -1,432 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
GetScrollLeft,
|
|
3
|
-
GetTree,
|
|
4
|
-
OpenNode,
|
|
5
|
-
RefreshElements,
|
|
6
|
-
TriggerEvent,
|
|
7
|
-
} from "../jqtreeMethodTypes";
|
|
8
|
-
import type {
|
|
9
|
-
DragMethod,
|
|
10
|
-
OnCanMove,
|
|
11
|
-
OnCanMoveTo,
|
|
12
|
-
OnIsMoveHandle,
|
|
13
|
-
} from "../jqtreeOptions";
|
|
14
|
-
import type { PositionInfo } from "../mouseUtils";
|
|
15
|
-
import type { Node } from "../node";
|
|
16
|
-
import type NodeElement from "../nodeElement";
|
|
17
|
-
import type { DropHint, HitArea } from "./types";
|
|
18
|
-
|
|
19
|
-
import { getElementPosition } from "../positionUtils";
|
|
20
|
-
import binarySearch from "./binarySearch";
|
|
21
|
-
import DragElement from "./dragElement";
|
|
22
|
-
import generateHitAreas from "./generateHitAreas";
|
|
23
|
-
|
|
24
|
-
interface Dimensions {
|
|
25
|
-
bottom: number;
|
|
26
|
-
left: number;
|
|
27
|
-
right: number;
|
|
28
|
-
top: number;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
interface DragAndDropHandlerParams {
|
|
32
|
-
autoEscape?: boolean;
|
|
33
|
-
getNodeElement: GetNodeElement;
|
|
34
|
-
getNodeElementForNode: GetNodeElementForNode;
|
|
35
|
-
getScrollLeft: GetScrollLeft;
|
|
36
|
-
getTree: GetTree;
|
|
37
|
-
onCanMove?: OnCanMove;
|
|
38
|
-
onCanMoveTo?: OnCanMoveTo;
|
|
39
|
-
onDragMove?: DragMethod;
|
|
40
|
-
onDragStop?: DragMethod;
|
|
41
|
-
onIsMoveHandle?: OnIsMoveHandle;
|
|
42
|
-
openFolderDelay: false | number;
|
|
43
|
-
openNode: OpenNode;
|
|
44
|
-
refreshElements: RefreshElements;
|
|
45
|
-
slide: boolean;
|
|
46
|
-
treeElement: HTMLElement;
|
|
47
|
-
triggerEvent: TriggerEvent;
|
|
48
|
-
}
|
|
49
|
-
type GetNodeElement = (element: HTMLElement) => NodeElement | null;
|
|
50
|
-
|
|
51
|
-
type GetNodeElementForNode = (node: Node) => NodeElement;
|
|
52
|
-
|
|
53
|
-
export class DragAndDropHandler {
|
|
54
|
-
public currentItem: NodeElement | null;
|
|
55
|
-
public hitAreas: HitArea[];
|
|
56
|
-
public hoveredArea: HitArea | null;
|
|
57
|
-
public isDragging: boolean;
|
|
58
|
-
|
|
59
|
-
private _autoEscape?: boolean;
|
|
60
|
-
private _dragElement: DragElement | null;
|
|
61
|
-
private _getNodeElement: GetNodeElement;
|
|
62
|
-
private _getNodeElementForNode: GetNodeElementForNode;
|
|
63
|
-
private _getScrollLeft: GetScrollLeft;
|
|
64
|
-
private _getTree: GetTree;
|
|
65
|
-
private _onCanMove?: OnCanMove;
|
|
66
|
-
private _onCanMoveTo?: OnCanMoveTo;
|
|
67
|
-
private _onDragMove?: DragMethod;
|
|
68
|
-
private _onDragStop?: DragMethod;
|
|
69
|
-
private _onIsMoveHandle?: OnIsMoveHandle;
|
|
70
|
-
private _openFolderDelay: false | number;
|
|
71
|
-
private _openFolderTimer: null | number;
|
|
72
|
-
private _openNode: OpenNode;
|
|
73
|
-
private _previousGhost: DropHint | null;
|
|
74
|
-
private _refreshElements: RefreshElements;
|
|
75
|
-
private _slide: boolean;
|
|
76
|
-
private _treeElement: HTMLElement;
|
|
77
|
-
private _triggerEvent: TriggerEvent;
|
|
78
|
-
|
|
79
|
-
constructor({
|
|
80
|
-
autoEscape,
|
|
81
|
-
getNodeElement,
|
|
82
|
-
getNodeElementForNode,
|
|
83
|
-
getScrollLeft,
|
|
84
|
-
getTree,
|
|
85
|
-
onCanMove,
|
|
86
|
-
onCanMoveTo,
|
|
87
|
-
onDragMove,
|
|
88
|
-
onDragStop,
|
|
89
|
-
onIsMoveHandle,
|
|
90
|
-
openFolderDelay,
|
|
91
|
-
openNode,
|
|
92
|
-
refreshElements,
|
|
93
|
-
slide,
|
|
94
|
-
treeElement,
|
|
95
|
-
triggerEvent,
|
|
96
|
-
}: DragAndDropHandlerParams) {
|
|
97
|
-
this._autoEscape = autoEscape;
|
|
98
|
-
this._getNodeElement = getNodeElement;
|
|
99
|
-
this._getNodeElementForNode = getNodeElementForNode;
|
|
100
|
-
this._getScrollLeft = getScrollLeft;
|
|
101
|
-
this._getTree = getTree;
|
|
102
|
-
this._onCanMove = onCanMove;
|
|
103
|
-
this._onCanMoveTo = onCanMoveTo;
|
|
104
|
-
this._onDragMove = onDragMove;
|
|
105
|
-
this._onDragStop = onDragStop;
|
|
106
|
-
this._onIsMoveHandle = onIsMoveHandle;
|
|
107
|
-
this._openFolderDelay = openFolderDelay;
|
|
108
|
-
this._openNode = openNode;
|
|
109
|
-
this._refreshElements = refreshElements;
|
|
110
|
-
this._slide = slide;
|
|
111
|
-
this._treeElement = treeElement;
|
|
112
|
-
this._triggerEvent = triggerEvent;
|
|
113
|
-
|
|
114
|
-
this.hoveredArea = null;
|
|
115
|
-
this.hitAreas = [];
|
|
116
|
-
this.isDragging = false;
|
|
117
|
-
this.currentItem = null;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
public mouseCapture(positionInfo: PositionInfo): boolean | null {
|
|
121
|
-
const element = positionInfo.target;
|
|
122
|
-
|
|
123
|
-
if (!this._mustCaptureElement(element)) {
|
|
124
|
-
return null;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
if (this._onIsMoveHandle && !this._onIsMoveHandle(jQuery(element))) {
|
|
128
|
-
return null;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
let nodeElement = this._getNodeElement(element);
|
|
132
|
-
|
|
133
|
-
if (nodeElement && this._onCanMove) {
|
|
134
|
-
if (!this._onCanMove(nodeElement.node)) {
|
|
135
|
-
nodeElement = null;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
this.currentItem = nodeElement;
|
|
140
|
-
return this.currentItem != null;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
public mouseDrag(positionInfo: PositionInfo): boolean {
|
|
144
|
-
if (!this.currentItem || !this._dragElement) {
|
|
145
|
-
return false;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
this._dragElement.move(positionInfo.pageX, positionInfo.pageY);
|
|
149
|
-
|
|
150
|
-
const area = this._findHoveredArea(
|
|
151
|
-
positionInfo.pageX,
|
|
152
|
-
positionInfo.pageY,
|
|
153
|
-
);
|
|
154
|
-
|
|
155
|
-
if (area && this._canMoveToArea(area, this.currentItem)) {
|
|
156
|
-
if (!area.node.isFolder()) {
|
|
157
|
-
this._stopOpenFolderTimer();
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
if (this.hoveredArea !== area) {
|
|
161
|
-
this.hoveredArea = area;
|
|
162
|
-
|
|
163
|
-
// If this is a closed folder, start timer to open it
|
|
164
|
-
if (this._mustOpenFolderTimer(area)) {
|
|
165
|
-
this._startOpenFolderTimer(area.node);
|
|
166
|
-
} else {
|
|
167
|
-
this._stopOpenFolderTimer();
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
this._updateDropHint();
|
|
171
|
-
}
|
|
172
|
-
} else {
|
|
173
|
-
this._removeDropHint();
|
|
174
|
-
this._stopOpenFolderTimer();
|
|
175
|
-
this.hoveredArea = area;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
if (!area) {
|
|
179
|
-
if (this._onDragMove) {
|
|
180
|
-
this._onDragMove(
|
|
181
|
-
this.currentItem.node,
|
|
182
|
-
positionInfo.originalEvent,
|
|
183
|
-
);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
return true;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
public mouseStart(positionInfo: PositionInfo): boolean {
|
|
191
|
-
if (!this.currentItem) {
|
|
192
|
-
return false;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
this.refresh();
|
|
196
|
-
|
|
197
|
-
const { left, top } = getElementPosition(positionInfo.target);
|
|
198
|
-
|
|
199
|
-
const node = this.currentItem.node;
|
|
200
|
-
|
|
201
|
-
this._dragElement = new DragElement({
|
|
202
|
-
autoEscape: this._autoEscape ?? true,
|
|
203
|
-
nodeName: node.name,
|
|
204
|
-
offsetX: positionInfo.pageX - left,
|
|
205
|
-
offsetY: positionInfo.pageY - top,
|
|
206
|
-
treeElement: this._treeElement,
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
this.isDragging = true;
|
|
210
|
-
this.currentItem.element.classList.add("jqtree-moving");
|
|
211
|
-
|
|
212
|
-
return true;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
public mouseStop(positionInfo: PositionInfo): boolean {
|
|
216
|
-
this._moveItem(positionInfo);
|
|
217
|
-
this._clear();
|
|
218
|
-
this._removeHover();
|
|
219
|
-
this._removeDropHint();
|
|
220
|
-
this._removeHitAreas();
|
|
221
|
-
|
|
222
|
-
const currentItem = this.currentItem;
|
|
223
|
-
|
|
224
|
-
if (this.currentItem) {
|
|
225
|
-
this.currentItem.element.classList.remove("jqtree-moving");
|
|
226
|
-
this.currentItem = null;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
this.isDragging = false;
|
|
230
|
-
|
|
231
|
-
if (!this.hoveredArea && currentItem) {
|
|
232
|
-
if (this._onDragStop) {
|
|
233
|
-
this._onDragStop(currentItem.node, positionInfo.originalEvent);
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
return false;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
public refresh(): void {
|
|
241
|
-
this._removeHitAreas();
|
|
242
|
-
|
|
243
|
-
if (this.currentItem) {
|
|
244
|
-
const currentNode = this.currentItem.node;
|
|
245
|
-
this._generateHitAreas(currentNode);
|
|
246
|
-
this.currentItem = this._getNodeElementForNode(currentNode);
|
|
247
|
-
|
|
248
|
-
if (this.isDragging) {
|
|
249
|
-
this.currentItem.element.classList.add("jqtree-moving");
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
private _canMoveToArea(area: HitArea, currentItem: NodeElement): boolean {
|
|
255
|
-
if (!this._onCanMoveTo) {
|
|
256
|
-
return true;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
return this._onCanMoveTo(currentItem.node, area.node, area.position);
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
private _clear(): void {
|
|
263
|
-
if (this._dragElement) {
|
|
264
|
-
this._dragElement.remove();
|
|
265
|
-
this._dragElement = null;
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
private _findHoveredArea(x: number, y: number): HitArea | null {
|
|
270
|
-
const dimensions = this._getTreeDimensions();
|
|
271
|
-
|
|
272
|
-
if (
|
|
273
|
-
x < dimensions.left ||
|
|
274
|
-
y < dimensions.top ||
|
|
275
|
-
x > dimensions.right ||
|
|
276
|
-
y > dimensions.bottom
|
|
277
|
-
) {
|
|
278
|
-
return null;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
return binarySearch<HitArea>(this.hitAreas, (area) => {
|
|
282
|
-
if (y < area.top) {
|
|
283
|
-
return 1;
|
|
284
|
-
} else if (y > area.bottom) {
|
|
285
|
-
return -1;
|
|
286
|
-
} else {
|
|
287
|
-
return 0;
|
|
288
|
-
}
|
|
289
|
-
});
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
private _generateHitAreas(currentNode: Node): void {
|
|
293
|
-
const tree = this._getTree();
|
|
294
|
-
|
|
295
|
-
if (!tree) {
|
|
296
|
-
this.hitAreas = [];
|
|
297
|
-
} else {
|
|
298
|
-
this.hitAreas = generateHitAreas(
|
|
299
|
-
tree,
|
|
300
|
-
currentNode,
|
|
301
|
-
this._getTreeDimensions().bottom,
|
|
302
|
-
);
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
private _getTreeDimensions(): Dimensions {
|
|
307
|
-
// Return the dimensions of the tree. Add a margin to the bottom to allow
|
|
308
|
-
// to drag-and-drop after the last element.
|
|
309
|
-
const treePosition = getElementPosition(this._treeElement);
|
|
310
|
-
const left = treePosition.left + this._getScrollLeft();
|
|
311
|
-
const top = treePosition.top;
|
|
312
|
-
|
|
313
|
-
return {
|
|
314
|
-
bottom: top + this._treeElement.clientHeight + 16,
|
|
315
|
-
left,
|
|
316
|
-
right: left + this._treeElement.clientWidth,
|
|
317
|
-
top,
|
|
318
|
-
};
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
/* Move the dragged node to the selected position in the tree. */
|
|
322
|
-
private _moveItem(positionInfo: PositionInfo): void {
|
|
323
|
-
if (
|
|
324
|
-
this.currentItem &&
|
|
325
|
-
this.hoveredArea?.position &&
|
|
326
|
-
this._canMoveToArea(this.hoveredArea, this.currentItem)
|
|
327
|
-
) {
|
|
328
|
-
const movedNode = this.currentItem.node;
|
|
329
|
-
const targetNode = this.hoveredArea.node;
|
|
330
|
-
const position = this.hoveredArea.position;
|
|
331
|
-
const previousParent = movedNode.parent;
|
|
332
|
-
|
|
333
|
-
if (position === "inside") {
|
|
334
|
-
this.hoveredArea.node.is_open = true;
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
const doMove = (): void => {
|
|
338
|
-
const tree = this._getTree();
|
|
339
|
-
|
|
340
|
-
if (tree) {
|
|
341
|
-
tree.moveNode(movedNode, targetNode, position);
|
|
342
|
-
|
|
343
|
-
this._treeElement.textContent = "";
|
|
344
|
-
this._refreshElements(null);
|
|
345
|
-
}
|
|
346
|
-
};
|
|
347
|
-
|
|
348
|
-
if (this._triggerEvent("tree.move", {
|
|
349
|
-
move_info: {
|
|
350
|
-
do_move: doMove,
|
|
351
|
-
moved_node: movedNode,
|
|
352
|
-
original_event: positionInfo.originalEvent,
|
|
353
|
-
position,
|
|
354
|
-
previous_parent: previousParent,
|
|
355
|
-
target_node: targetNode,
|
|
356
|
-
},
|
|
357
|
-
})) {
|
|
358
|
-
doMove();
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
private _mustCaptureElement(element: HTMLElement): boolean {
|
|
364
|
-
const nodeName = element.nodeName;
|
|
365
|
-
|
|
366
|
-
return (
|
|
367
|
-
nodeName !== "INPUT" &&
|
|
368
|
-
nodeName !== "SELECT" &&
|
|
369
|
-
nodeName !== "TEXTAREA"
|
|
370
|
-
);
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
private _mustOpenFolderTimer(area: HitArea): boolean {
|
|
374
|
-
const node = area.node;
|
|
375
|
-
|
|
376
|
-
return node.isFolder() && !node.is_open && area.position === "inside";
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
private _removeDropHint(): void {
|
|
380
|
-
if (this._previousGhost) {
|
|
381
|
-
this._previousGhost.remove();
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
private _removeHitAreas(): void {
|
|
386
|
-
this.hitAreas = [];
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
private _removeHover(): void {
|
|
390
|
-
this.hoveredArea = null;
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
private _startOpenFolderTimer(folder: Node): void {
|
|
394
|
-
const openFolder = (): void => {
|
|
395
|
-
this._openNode(folder, this._slide, () => {
|
|
396
|
-
this.refresh();
|
|
397
|
-
this._updateDropHint();
|
|
398
|
-
});
|
|
399
|
-
};
|
|
400
|
-
|
|
401
|
-
this._stopOpenFolderTimer();
|
|
402
|
-
|
|
403
|
-
const openFolderDelay = this._openFolderDelay;
|
|
404
|
-
|
|
405
|
-
if (openFolderDelay !== false) {
|
|
406
|
-
this._openFolderTimer = window.setTimeout(
|
|
407
|
-
openFolder,
|
|
408
|
-
openFolderDelay,
|
|
409
|
-
);
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
private _stopOpenFolderTimer(): void {
|
|
414
|
-
if (this._openFolderTimer) {
|
|
415
|
-
clearTimeout(this._openFolderTimer);
|
|
416
|
-
this._openFolderTimer = null;
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
private _updateDropHint(): void {
|
|
421
|
-
if (!this.hoveredArea) {
|
|
422
|
-
return;
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
// remove previous drop hint
|
|
426
|
-
this._removeDropHint();
|
|
427
|
-
|
|
428
|
-
// add new drop hint
|
|
429
|
-
const nodeElement = this._getNodeElementForNode(this.hoveredArea.node);
|
|
430
|
-
this._previousGhost = nodeElement.addDropHint(this.hoveredArea.position);
|
|
431
|
-
}
|
|
432
|
-
}
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import type { Node } from "../node";
|
|
2
|
-
|
|
3
|
-
interface Options {
|
|
4
|
-
handleAfterOpenFolder: (node: Node, nextNode: Node | null) => void;
|
|
5
|
-
handleClosedFolder: (
|
|
6
|
-
node: Node,
|
|
7
|
-
nextNode: Node | null,
|
|
8
|
-
element: HTMLElement,
|
|
9
|
-
) => void;
|
|
10
|
-
handleFirstNode: (node: Node) => void;
|
|
11
|
-
handleNode: (
|
|
12
|
-
node: Node,
|
|
13
|
-
nextNode: Node | null,
|
|
14
|
-
element: HTMLElement,
|
|
15
|
-
) => void;
|
|
16
|
-
|
|
17
|
-
/*
|
|
18
|
-
override
|
|
19
|
-
return
|
|
20
|
-
- true: continue iterating
|
|
21
|
-
- false: stop iterating
|
|
22
|
-
*/
|
|
23
|
-
handleOpenFolder: (node: Node, element: HTMLElement) => boolean;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const iterateVisibleNodes = (
|
|
27
|
-
tree: Node,
|
|
28
|
-
{
|
|
29
|
-
handleAfterOpenFolder,
|
|
30
|
-
handleClosedFolder,
|
|
31
|
-
handleFirstNode,
|
|
32
|
-
handleNode,
|
|
33
|
-
handleOpenFolder,
|
|
34
|
-
}: Options,
|
|
35
|
-
) => {
|
|
36
|
-
let isFirstNode = true;
|
|
37
|
-
|
|
38
|
-
const iterate = (node: Node, nextNode: Node | null): void => {
|
|
39
|
-
let mustIterateInside =
|
|
40
|
-
(node.is_open || !node.element) && node.hasChildren();
|
|
41
|
-
|
|
42
|
-
let element: HTMLElement | null = null;
|
|
43
|
-
|
|
44
|
-
// Is the element visible?
|
|
45
|
-
if (node.element?.offsetParent) {
|
|
46
|
-
element = node.element;
|
|
47
|
-
|
|
48
|
-
if (isFirstNode) {
|
|
49
|
-
handleFirstNode(node);
|
|
50
|
-
isFirstNode = false;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (!node.hasChildren()) {
|
|
54
|
-
handleNode(node, nextNode, node.element);
|
|
55
|
-
} else if (node.is_open) {
|
|
56
|
-
if (!handleOpenFolder(node, node.element)) {
|
|
57
|
-
mustIterateInside = false;
|
|
58
|
-
}
|
|
59
|
-
} else {
|
|
60
|
-
handleClosedFolder(node, nextNode, element);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (mustIterateInside) {
|
|
65
|
-
const childrenLength = node.children.length;
|
|
66
|
-
node.children.forEach((_, i) => {
|
|
67
|
-
const child = node.children[i];
|
|
68
|
-
|
|
69
|
-
if (child) {
|
|
70
|
-
if (i === childrenLength - 1) {
|
|
71
|
-
iterate(child, null);
|
|
72
|
-
} else {
|
|
73
|
-
const nextChild = node.children[i + 1];
|
|
74
|
-
|
|
75
|
-
if (nextChild) {
|
|
76
|
-
iterate(child, nextChild);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
if (node.is_open && element) {
|
|
83
|
-
handleAfterOpenFolder(node, nextNode);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
iterate(tree, null);
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
export default iterateVisibleNodes;
|