jqtree 1.8.10 → 1.9.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 +3 -10
- package/eslint.config.mjs +47 -9
- package/package.json +50 -53
- package/pnpm-workspace.yaml +4 -0
- package/src/animation.ts +48 -0
- package/src/dataLoader.ts +38 -48
- package/src/dragAndDropHandler/dragElement.ts +11 -11
- package/src/dragAndDropHandler/generateHitAreas.ts +4 -3
- package/src/dragAndDropHandler/index.ts +119 -120
- package/src/dragAndDropHandler/iterateVisibleNodes.ts +1 -1
- package/src/dragAndDropHandler/types.ts +1 -1
- package/src/elementsRenderer.ts +71 -78
- package/src/jqtreeMethodTypes.ts +2 -2
- package/src/jqtreeOptions.ts +3 -2
- package/src/keyHandler.ts +34 -34
- package/src/mouseHandler.ts +125 -123
- package/src/node.ts +23 -27
- package/src/nodeElement/borderDropHint.ts +6 -6
- package/src/nodeElement/folderElement.ts +30 -22
- package/src/nodeElement/ghostDropHint.ts +24 -24
- package/src/nodeElement/index.ts +13 -14
- package/src/positionUtils.ts +18 -0
- package/src/saveStateHandler.ts +56 -55
- package/src/scrollHandler/containerScrollParent.ts +27 -124
- package/src/scrollHandler/createScrollParent.ts +1 -1
- package/src/scrollHandler/documentScrollParent.ts +43 -125
- package/src/scrollHandler/scrollParent.ts +117 -0
- package/src/scrollHandler.ts +24 -25
- package/src/selectNodeHandler.ts +28 -28
- package/src/simple.widget.ts +1 -3
- package/src/tree.jquery.ts +253 -279
- package/src/util.ts +0 -14
- package/src/version.ts +1 -1
- package/tree.jquery.debug.js +1044 -998
- package/tree.jquery.debug.js.map +1 -1
- package/tree.jquery.js +3 -3
- package/tree.jquery.js.map +1 -1
- package/.tool-versions +0 -2
- package/src/scrollHandler/types.ts +0 -7
package/src/mouseHandler.ts
CHANGED
|
@@ -1,57 +1,61 @@
|
|
|
1
|
-
import { TriggerEvent } from "./jqtreeMethodTypes";
|
|
1
|
+
import type { TriggerEvent } from "./jqtreeMethodTypes";
|
|
2
|
+
import type { PositionInfo } from "./mouseUtils";
|
|
3
|
+
import type { Node } from "./node";
|
|
4
|
+
|
|
2
5
|
import {
|
|
3
6
|
getPositionInfoFromMouseEvent,
|
|
4
7
|
getPositionInfoFromTouch,
|
|
5
|
-
PositionInfo,
|
|
6
8
|
} from "./mouseUtils";
|
|
7
|
-
|
|
9
|
+
|
|
10
|
+
export type GetMouseDelay = () => number;
|
|
11
|
+
export type GetNode = (element: HTMLElement) => Node | null;
|
|
12
|
+
export type MouseCapture = (positionInfo: PositionInfo) => boolean | null;
|
|
13
|
+
export type MouseStart = (positionInfo: PositionInfo) => boolean;
|
|
8
14
|
|
|
9
15
|
interface ClickTarget {
|
|
10
16
|
node: Node;
|
|
11
17
|
type: "button" | "label";
|
|
12
18
|
}
|
|
13
19
|
|
|
14
|
-
type GetNode = (element: HTMLElement) => Node | null;
|
|
15
|
-
|
|
16
20
|
interface MouseHandlerParams {
|
|
17
21
|
element: HTMLElement;
|
|
18
22
|
getMouseDelay: () => number;
|
|
19
23
|
getNode: GetNode;
|
|
20
24
|
onClickButton: (node: Node) => void;
|
|
21
25
|
onClickTitle: (node: Node) => void;
|
|
22
|
-
onMouseCapture:
|
|
26
|
+
onMouseCapture: MouseCapture;
|
|
23
27
|
onMouseDrag: (positionInfo: PositionInfo) => void;
|
|
24
|
-
onMouseStart:
|
|
28
|
+
onMouseStart: MouseStart;
|
|
25
29
|
onMouseStop: (positionInfo: PositionInfo) => void;
|
|
26
30
|
triggerEvent: TriggerEvent;
|
|
27
31
|
useContextMenu: boolean;
|
|
28
32
|
}
|
|
29
33
|
|
|
30
34
|
class MouseHandler {
|
|
31
|
-
private
|
|
32
|
-
private
|
|
33
|
-
private
|
|
35
|
+
private _element: HTMLElement;
|
|
36
|
+
private _getMouseDelay: GetMouseDelay;
|
|
37
|
+
private _getNode: GetNode;
|
|
34
38
|
|
|
35
|
-
private
|
|
39
|
+
private _isMouseDelayMet: boolean;
|
|
36
40
|
|
|
37
|
-
private
|
|
41
|
+
private _isMouseStarted: boolean;
|
|
38
42
|
|
|
39
|
-
private
|
|
43
|
+
private _mouseDelayTimer: null | number;
|
|
40
44
|
|
|
41
|
-
private
|
|
42
|
-
private
|
|
43
|
-
private
|
|
45
|
+
private _mouseDownInfo: null | PositionInfo;
|
|
46
|
+
private _onClickButton: (node: Node) => void;
|
|
47
|
+
private _onClickTitle: (node: Node) => void;
|
|
44
48
|
|
|
45
|
-
private
|
|
49
|
+
private _onMouseCapture: MouseCapture;
|
|
46
50
|
|
|
47
|
-
private
|
|
51
|
+
private _onMouseDrag: (positionInfo: PositionInfo) => void;
|
|
48
52
|
|
|
49
|
-
private
|
|
53
|
+
private _onMouseStart: MouseStart;
|
|
50
54
|
|
|
51
|
-
private
|
|
55
|
+
private _onMouseStop: (positionInfo: PositionInfo) => void;
|
|
52
56
|
|
|
53
|
-
private
|
|
54
|
-
private
|
|
57
|
+
private _triggerEvent: TriggerEvent;
|
|
58
|
+
private _useContextMenu: boolean;
|
|
55
59
|
constructor({
|
|
56
60
|
element,
|
|
57
61
|
getMouseDelay,
|
|
@@ -65,56 +69,56 @@ class MouseHandler {
|
|
|
65
69
|
triggerEvent,
|
|
66
70
|
useContextMenu,
|
|
67
71
|
}: MouseHandlerParams) {
|
|
68
|
-
this.
|
|
69
|
-
this.
|
|
70
|
-
this.
|
|
71
|
-
this.
|
|
72
|
-
this.
|
|
73
|
-
this.
|
|
74
|
-
this.
|
|
75
|
-
this.
|
|
76
|
-
this.
|
|
77
|
-
this.
|
|
78
|
-
this.
|
|
79
|
-
|
|
80
|
-
element.addEventListener("click", this.
|
|
81
|
-
element.addEventListener("dblclick", this.
|
|
82
|
-
element.addEventListener("mousedown", this.
|
|
72
|
+
this._element = element;
|
|
73
|
+
this._getMouseDelay = getMouseDelay;
|
|
74
|
+
this._getNode = getNode;
|
|
75
|
+
this._onClickButton = onClickButton;
|
|
76
|
+
this._onClickTitle = onClickTitle;
|
|
77
|
+
this._onMouseCapture = onMouseCapture;
|
|
78
|
+
this._onMouseDrag = onMouseDrag;
|
|
79
|
+
this._onMouseStart = onMouseStart;
|
|
80
|
+
this._onMouseStop = onMouseStop;
|
|
81
|
+
this._triggerEvent = triggerEvent;
|
|
82
|
+
this._useContextMenu = useContextMenu;
|
|
83
|
+
|
|
84
|
+
element.addEventListener("click", this._handleClick);
|
|
85
|
+
element.addEventListener("dblclick", this._handleDblclick);
|
|
86
|
+
element.addEventListener("mousedown", this._mouseDown, {
|
|
83
87
|
passive: false,
|
|
84
88
|
});
|
|
85
|
-
element.addEventListener("touchstart", this.
|
|
89
|
+
element.addEventListener("touchstart", this._touchStart, {
|
|
86
90
|
passive: false,
|
|
87
91
|
});
|
|
88
92
|
|
|
89
93
|
if (useContextMenu) {
|
|
90
|
-
element.addEventListener("contextmenu", this.
|
|
94
|
+
element.addEventListener("contextmenu", this._handleContextmenu);
|
|
91
95
|
}
|
|
92
96
|
|
|
93
|
-
this.
|
|
94
|
-
this.
|
|
95
|
-
this.
|
|
96
|
-
this.
|
|
97
|
+
this._isMouseStarted = false;
|
|
98
|
+
this._mouseDelayTimer = null;
|
|
99
|
+
this._isMouseDelayMet = false;
|
|
100
|
+
this._mouseDownInfo = null;
|
|
97
101
|
}
|
|
98
102
|
public deinit(): void {
|
|
99
|
-
this.
|
|
100
|
-
this.
|
|
103
|
+
this._element.removeEventListener("click", this._handleClick);
|
|
104
|
+
this._element.removeEventListener("dblclick", this._handleDblclick);
|
|
101
105
|
|
|
102
|
-
if (this.
|
|
103
|
-
this.
|
|
106
|
+
if (this._useContextMenu) {
|
|
107
|
+
this._element.removeEventListener(
|
|
104
108
|
"contextmenu",
|
|
105
|
-
this.
|
|
109
|
+
this._handleContextmenu,
|
|
106
110
|
);
|
|
107
111
|
}
|
|
108
112
|
|
|
109
|
-
this.
|
|
110
|
-
this.
|
|
111
|
-
this.
|
|
113
|
+
this._element.removeEventListener("mousedown", this._mouseDown);
|
|
114
|
+
this._element.removeEventListener("touchstart", this._touchStart);
|
|
115
|
+
this._removeMouseMoveEventListeners();
|
|
112
116
|
}
|
|
113
|
-
private
|
|
117
|
+
private _getClickTarget(element: HTMLElement): ClickTarget | null {
|
|
114
118
|
const button = element.closest<HTMLElement>(".jqtree-toggler");
|
|
115
119
|
|
|
116
120
|
if (button) {
|
|
117
|
-
const node = this.
|
|
121
|
+
const node = this._getNode(button);
|
|
118
122
|
|
|
119
123
|
if (node) {
|
|
120
124
|
return {
|
|
@@ -127,7 +131,7 @@ class MouseHandler {
|
|
|
127
131
|
element.closest<HTMLElement>(".jqtree-element");
|
|
128
132
|
|
|
129
133
|
if (jqTreeElement) {
|
|
130
|
-
const node = this.
|
|
134
|
+
const node = this._getNode(jqTreeElement);
|
|
131
135
|
if (node) {
|
|
132
136
|
return {
|
|
133
137
|
node,
|
|
@@ -139,12 +143,12 @@ class MouseHandler {
|
|
|
139
143
|
|
|
140
144
|
return null;
|
|
141
145
|
}
|
|
142
|
-
private
|
|
146
|
+
private _handleClick = (e: MouseEvent): void => {
|
|
143
147
|
if (!e.target) {
|
|
144
148
|
return;
|
|
145
149
|
}
|
|
146
150
|
|
|
147
|
-
const clickTarget = this.
|
|
151
|
+
const clickTarget = this._getClickTarget(e.target as HTMLElement);
|
|
148
152
|
|
|
149
153
|
if (!clickTarget) {
|
|
150
154
|
return;
|
|
@@ -152,27 +156,25 @@ class MouseHandler {
|
|
|
152
156
|
|
|
153
157
|
switch (clickTarget.type) {
|
|
154
158
|
case "button":
|
|
155
|
-
this.
|
|
159
|
+
this._onClickButton(clickTarget.node);
|
|
156
160
|
|
|
157
161
|
e.preventDefault();
|
|
158
162
|
e.stopPropagation();
|
|
159
163
|
break;
|
|
160
164
|
|
|
161
165
|
case "label": {
|
|
162
|
-
|
|
166
|
+
if (this._triggerEvent("tree.click", {
|
|
163
167
|
click_event: e,
|
|
164
168
|
node: clickTarget.node,
|
|
165
|
-
})
|
|
166
|
-
|
|
167
|
-
if (!event.isDefaultPrevented()) {
|
|
168
|
-
this.onClickTitle(clickTarget.node);
|
|
169
|
+
})) {
|
|
170
|
+
this._onClickTitle(clickTarget.node);
|
|
169
171
|
}
|
|
170
172
|
break;
|
|
171
173
|
}
|
|
172
174
|
}
|
|
173
175
|
};
|
|
174
176
|
|
|
175
|
-
private
|
|
177
|
+
private _handleContextmenu = (e: MouseEvent) => {
|
|
176
178
|
if (!e.target) {
|
|
177
179
|
return;
|
|
178
180
|
}
|
|
@@ -182,12 +184,12 @@ class MouseHandler {
|
|
|
182
184
|
);
|
|
183
185
|
|
|
184
186
|
if (div) {
|
|
185
|
-
const node = this.
|
|
187
|
+
const node = this._getNode(div);
|
|
186
188
|
if (node) {
|
|
187
189
|
e.preventDefault();
|
|
188
190
|
e.stopPropagation();
|
|
189
191
|
|
|
190
|
-
this.
|
|
192
|
+
this._triggerEvent("tree.contextmenu", {
|
|
191
193
|
click_event: e,
|
|
192
194
|
node,
|
|
193
195
|
});
|
|
@@ -198,44 +200,44 @@ class MouseHandler {
|
|
|
198
200
|
return null;
|
|
199
201
|
};
|
|
200
202
|
|
|
201
|
-
private
|
|
203
|
+
private _handleDblclick = (e: MouseEvent): void => {
|
|
202
204
|
if (!e.target) {
|
|
203
205
|
return;
|
|
204
206
|
}
|
|
205
207
|
|
|
206
|
-
const clickTarget = this.
|
|
208
|
+
const clickTarget = this._getClickTarget(e.target as HTMLElement);
|
|
207
209
|
|
|
208
210
|
if (clickTarget?.type === "label") {
|
|
209
|
-
this.
|
|
211
|
+
this._triggerEvent("tree.dblclick", {
|
|
210
212
|
click_event: e,
|
|
211
213
|
node: clickTarget.node,
|
|
212
214
|
});
|
|
213
215
|
}
|
|
214
216
|
};
|
|
215
217
|
|
|
216
|
-
private
|
|
218
|
+
private _handleMouseDown(positionInfo: PositionInfo): boolean {
|
|
217
219
|
// We may have missed mouseup (out of window)
|
|
218
|
-
if (this.
|
|
219
|
-
this.
|
|
220
|
+
if (this._isMouseStarted) {
|
|
221
|
+
this._handleMouseUp(positionInfo);
|
|
220
222
|
}
|
|
221
223
|
|
|
222
|
-
this.
|
|
224
|
+
this._mouseDownInfo = positionInfo;
|
|
223
225
|
|
|
224
|
-
if (!this.
|
|
226
|
+
if (!this._onMouseCapture(positionInfo)) {
|
|
225
227
|
return false;
|
|
226
228
|
}
|
|
227
229
|
|
|
228
|
-
this.
|
|
230
|
+
this._handleStartMouse();
|
|
229
231
|
|
|
230
232
|
return true;
|
|
231
233
|
}
|
|
232
234
|
|
|
233
|
-
private
|
|
235
|
+
private _handleMouseMove(
|
|
234
236
|
e: MouseEvent | TouchEvent,
|
|
235
237
|
positionInfo: PositionInfo,
|
|
236
238
|
): void {
|
|
237
|
-
if (this.
|
|
238
|
-
this.
|
|
239
|
+
if (this._isMouseStarted) {
|
|
240
|
+
this._onMouseDrag(positionInfo);
|
|
239
241
|
|
|
240
242
|
if (e.cancelable) {
|
|
241
243
|
e.preventDefault();
|
|
@@ -243,99 +245,99 @@ class MouseHandler {
|
|
|
243
245
|
return;
|
|
244
246
|
}
|
|
245
247
|
|
|
246
|
-
if (!this.
|
|
248
|
+
if (!this._isMouseDelayMet) {
|
|
247
249
|
return;
|
|
248
250
|
}
|
|
249
251
|
|
|
250
|
-
if (this.
|
|
251
|
-
this.
|
|
252
|
+
if (this._mouseDownInfo) {
|
|
253
|
+
this._isMouseStarted = this._onMouseStart(this._mouseDownInfo);
|
|
252
254
|
}
|
|
253
255
|
|
|
254
|
-
if (this.
|
|
255
|
-
this.
|
|
256
|
+
if (this._isMouseStarted) {
|
|
257
|
+
this._onMouseDrag(positionInfo);
|
|
256
258
|
|
|
257
259
|
if (e.cancelable) {
|
|
258
260
|
e.preventDefault();
|
|
259
261
|
}
|
|
260
262
|
} else {
|
|
261
|
-
this.
|
|
263
|
+
this._handleMouseUp(positionInfo);
|
|
262
264
|
}
|
|
263
265
|
}
|
|
264
|
-
private
|
|
265
|
-
this.
|
|
266
|
-
this.
|
|
267
|
-
this.
|
|
268
|
-
|
|
269
|
-
if (this.
|
|
270
|
-
this.
|
|
271
|
-
this.
|
|
266
|
+
private _handleMouseUp(positionInfo: PositionInfo): void {
|
|
267
|
+
this._removeMouseMoveEventListeners();
|
|
268
|
+
this._isMouseDelayMet = false;
|
|
269
|
+
this._mouseDownInfo = null;
|
|
270
|
+
|
|
271
|
+
if (this._isMouseStarted) {
|
|
272
|
+
this._isMouseStarted = false;
|
|
273
|
+
this._onMouseStop(positionInfo);
|
|
272
274
|
}
|
|
273
275
|
}
|
|
274
276
|
|
|
275
|
-
private
|
|
276
|
-
document.addEventListener("mousemove", this.
|
|
277
|
+
private _handleStartMouse(): void {
|
|
278
|
+
document.addEventListener("mousemove", this._mouseMove, {
|
|
277
279
|
passive: false,
|
|
278
280
|
});
|
|
279
|
-
document.addEventListener("touchmove", this.
|
|
281
|
+
document.addEventListener("touchmove", this._touchMove, {
|
|
280
282
|
passive: false,
|
|
281
283
|
});
|
|
282
|
-
document.addEventListener("mouseup", this.
|
|
283
|
-
document.addEventListener("touchend", this.
|
|
284
|
+
document.addEventListener("mouseup", this._mouseUp, { passive: false });
|
|
285
|
+
document.addEventListener("touchend", this._touchEnd, {
|
|
284
286
|
passive: false,
|
|
285
287
|
});
|
|
286
288
|
|
|
287
|
-
const mouseDelay = this.
|
|
289
|
+
const mouseDelay = this._getMouseDelay();
|
|
288
290
|
|
|
289
291
|
if (mouseDelay) {
|
|
290
|
-
this.
|
|
292
|
+
this._startMouseDelayTimer(mouseDelay);
|
|
291
293
|
} else {
|
|
292
|
-
this.
|
|
294
|
+
this._isMouseDelayMet = true;
|
|
293
295
|
}
|
|
294
296
|
}
|
|
295
297
|
|
|
296
|
-
private
|
|
298
|
+
private _mouseDown = (e: MouseEvent): void => {
|
|
297
299
|
// Left mouse button?
|
|
298
300
|
if (e.button !== 0) {
|
|
299
301
|
return;
|
|
300
302
|
}
|
|
301
303
|
|
|
302
|
-
const result = this.
|
|
304
|
+
const result = this._handleMouseDown(getPositionInfoFromMouseEvent(e));
|
|
303
305
|
|
|
304
306
|
if (result && e.cancelable) {
|
|
305
307
|
e.preventDefault();
|
|
306
308
|
}
|
|
307
309
|
};
|
|
308
310
|
|
|
309
|
-
private
|
|
310
|
-
this.
|
|
311
|
+
private _mouseMove = (e: MouseEvent): void => {
|
|
312
|
+
this._handleMouseMove(e, getPositionInfoFromMouseEvent(e));
|
|
311
313
|
};
|
|
312
314
|
|
|
313
|
-
private
|
|
314
|
-
this.
|
|
315
|
+
private _mouseUp = (e: MouseEvent): void => {
|
|
316
|
+
this._handleMouseUp(getPositionInfoFromMouseEvent(e));
|
|
315
317
|
};
|
|
316
318
|
|
|
317
|
-
private
|
|
318
|
-
document.removeEventListener("mousemove", this.
|
|
319
|
-
document.removeEventListener("touchmove", this.
|
|
320
|
-
document.removeEventListener("mouseup", this.
|
|
321
|
-
document.removeEventListener("touchend", this.
|
|
319
|
+
private _removeMouseMoveEventListeners() {
|
|
320
|
+
document.removeEventListener("mousemove", this._mouseMove);
|
|
321
|
+
document.removeEventListener("touchmove", this._touchMove);
|
|
322
|
+
document.removeEventListener("mouseup", this._mouseUp);
|
|
323
|
+
document.removeEventListener("touchend", this._touchEnd);
|
|
322
324
|
}
|
|
323
325
|
|
|
324
|
-
private
|
|
325
|
-
if (this.
|
|
326
|
-
clearTimeout(this.
|
|
326
|
+
private _startMouseDelayTimer(mouseDelay: number): void {
|
|
327
|
+
if (this._mouseDelayTimer) {
|
|
328
|
+
clearTimeout(this._mouseDelayTimer);
|
|
327
329
|
}
|
|
328
330
|
|
|
329
|
-
this.
|
|
330
|
-
if (this.
|
|
331
|
-
this.
|
|
331
|
+
this._mouseDelayTimer = window.setTimeout(() => {
|
|
332
|
+
if (this._mouseDownInfo) {
|
|
333
|
+
this._isMouseDelayMet = true;
|
|
332
334
|
}
|
|
333
335
|
}, mouseDelay);
|
|
334
336
|
|
|
335
|
-
this.
|
|
337
|
+
this._isMouseDelayMet = false;
|
|
336
338
|
}
|
|
337
339
|
|
|
338
|
-
private
|
|
340
|
+
private _touchEnd = (e: TouchEvent): void => {
|
|
339
341
|
if (e.touches.length > 1) {
|
|
340
342
|
return;
|
|
341
343
|
}
|
|
@@ -346,10 +348,10 @@ class MouseHandler {
|
|
|
346
348
|
return;
|
|
347
349
|
}
|
|
348
350
|
|
|
349
|
-
this.
|
|
351
|
+
this._handleMouseUp(getPositionInfoFromTouch(touch, e));
|
|
350
352
|
};
|
|
351
353
|
|
|
352
|
-
private
|
|
354
|
+
private _touchMove = (e: TouchEvent): void => {
|
|
353
355
|
if (e.touches.length > 1) {
|
|
354
356
|
return;
|
|
355
357
|
}
|
|
@@ -360,10 +362,10 @@ class MouseHandler {
|
|
|
360
362
|
return;
|
|
361
363
|
}
|
|
362
364
|
|
|
363
|
-
this.
|
|
365
|
+
this._handleMouseMove(e, getPositionInfoFromTouch(touch, e));
|
|
364
366
|
};
|
|
365
367
|
|
|
366
|
-
private
|
|
368
|
+
private _touchStart = (e: TouchEvent): void => {
|
|
367
369
|
if (e.touches.length > 1) {
|
|
368
370
|
return;
|
|
369
371
|
}
|
|
@@ -374,7 +376,7 @@ class MouseHandler {
|
|
|
374
376
|
return;
|
|
375
377
|
}
|
|
376
378
|
|
|
377
|
-
this.
|
|
379
|
+
this._handleMouseDown(getPositionInfoFromTouch(touch, e));
|
|
378
380
|
};
|
|
379
381
|
}
|
|
380
382
|
|
package/src/node.ts
CHANGED
|
@@ -49,12 +49,12 @@ export class Node implements INode {
|
|
|
49
49
|
if (!this.parent) {
|
|
50
50
|
return null;
|
|
51
51
|
} else {
|
|
52
|
-
const node = this.
|
|
52
|
+
const node = this._createNode(nodeInfo);
|
|
53
53
|
|
|
54
54
|
const childIndex = this.parent.getChildIndex(this);
|
|
55
55
|
this.parent.addChildAtPosition(node, childIndex + 1);
|
|
56
56
|
|
|
57
|
-
node.
|
|
57
|
+
node._loadChildrenFromData(nodeInfo);
|
|
58
58
|
return node;
|
|
59
59
|
}
|
|
60
60
|
}
|
|
@@ -63,12 +63,12 @@ export class Node implements INode {
|
|
|
63
63
|
if (!this.parent) {
|
|
64
64
|
return null;
|
|
65
65
|
} else {
|
|
66
|
-
const node = this.
|
|
66
|
+
const node = this._createNode(nodeInfo);
|
|
67
67
|
|
|
68
68
|
const childIndex = this.parent.getChildIndex(this);
|
|
69
69
|
this.parent.addChildAtPosition(node, childIndex);
|
|
70
70
|
|
|
71
|
-
node.
|
|
71
|
+
node._loadChildrenFromData(nodeInfo);
|
|
72
72
|
return node;
|
|
73
73
|
}
|
|
74
74
|
}
|
|
@@ -82,7 +82,7 @@ export class Node implements INode {
|
|
|
82
82
|
*/
|
|
83
83
|
public addChild(node: Node): void {
|
|
84
84
|
this.children.push(node);
|
|
85
|
-
node.
|
|
85
|
+
node._setParent(this);
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
/*
|
|
@@ -95,7 +95,7 @@ export class Node implements INode {
|
|
|
95
95
|
*/
|
|
96
96
|
public addChildAtPosition(node: Node, index: number): void {
|
|
97
97
|
this.children.splice(index, 0, node);
|
|
98
|
-
node.
|
|
98
|
+
node._setParent(this);
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
public addNodeToIndex(node: Node): void {
|
|
@@ -108,10 +108,10 @@ export class Node implements INode {
|
|
|
108
108
|
if (!this.parent) {
|
|
109
109
|
return null;
|
|
110
110
|
} else {
|
|
111
|
-
const newParent = this.
|
|
111
|
+
const newParent = this._createNode(nodeInfo);
|
|
112
112
|
|
|
113
113
|
if (this.tree) {
|
|
114
|
-
newParent.
|
|
114
|
+
newParent._setParent(this.tree);
|
|
115
115
|
}
|
|
116
116
|
const originalParent = this.parent;
|
|
117
117
|
|
|
@@ -126,10 +126,10 @@ export class Node implements INode {
|
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
public append(nodeInfo: NodeData): Node {
|
|
129
|
-
const node = this.
|
|
129
|
+
const node = this._createNode(nodeInfo);
|
|
130
130
|
this.addChild(node);
|
|
131
131
|
|
|
132
|
-
node.
|
|
132
|
+
node._loadChildrenFromData(nodeInfo);
|
|
133
133
|
return node;
|
|
134
134
|
}
|
|
135
135
|
|
|
@@ -202,11 +202,7 @@ export class Node implements INode {
|
|
|
202
202
|
if (!this.hasChildren()) {
|
|
203
203
|
return null;
|
|
204
204
|
} else {
|
|
205
|
-
const lastChild = this.children[this.children.length - 1];
|
|
206
|
-
|
|
207
|
-
if (!lastChild) {
|
|
208
|
-
return null;
|
|
209
|
-
}
|
|
205
|
+
const lastChild = this.children[this.children.length - 1] as Node;
|
|
210
206
|
|
|
211
207
|
if (!(lastChild.hasChildren() && lastChild.is_open)) {
|
|
212
208
|
return lastChild;
|
|
@@ -404,7 +400,7 @@ export class Node implements INode {
|
|
|
404
400
|
|
|
405
401
|
const addChildren = (childrenData: NodeData[]): void => {
|
|
406
402
|
for (const child of childrenData) {
|
|
407
|
-
const node = this.
|
|
403
|
+
const node = this._createNode();
|
|
408
404
|
node.initFromData(child);
|
|
409
405
|
this.addChild(node);
|
|
410
406
|
}
|
|
@@ -483,7 +479,7 @@ export class Node implements INode {
|
|
|
483
479
|
this.removeChildren();
|
|
484
480
|
|
|
485
481
|
for (const childData of data) {
|
|
486
|
-
const node = this.
|
|
482
|
+
const node = this._createNode(childData);
|
|
487
483
|
this.addChild(node);
|
|
488
484
|
|
|
489
485
|
if (isNodeRecordWithChildren(childData)) {
|
|
@@ -512,7 +508,7 @@ export class Node implements INode {
|
|
|
512
508
|
// - Or, parent is empty
|
|
513
509
|
return false;
|
|
514
510
|
} else {
|
|
515
|
-
movedNode.parent.
|
|
511
|
+
movedNode.parent._doRemoveChild(movedNode);
|
|
516
512
|
|
|
517
513
|
switch (position) {
|
|
518
514
|
case "after": {
|
|
@@ -547,10 +543,10 @@ export class Node implements INode {
|
|
|
547
543
|
}
|
|
548
544
|
|
|
549
545
|
public prepend(nodeInfo: NodeData): Node {
|
|
550
|
-
const node = this.
|
|
546
|
+
const node = this._createNode(nodeInfo);
|
|
551
547
|
this.addChildAtPosition(node, 0);
|
|
552
548
|
|
|
553
|
-
node.
|
|
549
|
+
node._loadChildrenFromData(nodeInfo);
|
|
554
550
|
return node;
|
|
555
551
|
}
|
|
556
552
|
|
|
@@ -570,7 +566,7 @@ export class Node implements INode {
|
|
|
570
566
|
// remove children from the index
|
|
571
567
|
node.removeChildren();
|
|
572
568
|
|
|
573
|
-
this.
|
|
569
|
+
this._doRemoveChild(node);
|
|
574
570
|
}
|
|
575
571
|
|
|
576
572
|
public removeChildren(): void {
|
|
@@ -628,28 +624,28 @@ export class Node implements INode {
|
|
|
628
624
|
}
|
|
629
625
|
}
|
|
630
626
|
|
|
631
|
-
private
|
|
632
|
-
const nodeClass = this.
|
|
627
|
+
private _createNode(nodeData?: NodeData): Node {
|
|
628
|
+
const nodeClass = this._getNodeClass();
|
|
633
629
|
return new nodeClass(nodeData);
|
|
634
630
|
}
|
|
635
631
|
|
|
636
|
-
private
|
|
632
|
+
private _doRemoveChild(node: Node): void {
|
|
637
633
|
this.children.splice(this.getChildIndex(node), 1);
|
|
638
634
|
this.tree?.removeNodeFromIndex(node);
|
|
639
635
|
}
|
|
640
636
|
|
|
641
|
-
private
|
|
637
|
+
private _getNodeClass(): typeof Node {
|
|
642
638
|
return this.nodeClass ?? this.tree?.nodeClass ?? Node;
|
|
643
639
|
}
|
|
644
640
|
|
|
645
641
|
// Load children data from nodeInfo if it has children
|
|
646
|
-
private
|
|
642
|
+
private _loadChildrenFromData(nodeInfo: NodeData) {
|
|
647
643
|
if (isNodeRecordWithChildren(nodeInfo) && nodeInfo.children.length) {
|
|
648
644
|
this.loadFromData(nodeInfo.children);
|
|
649
645
|
}
|
|
650
646
|
}
|
|
651
647
|
|
|
652
|
-
private
|
|
648
|
+
private _setParent(parent: Node): void {
|
|
653
649
|
this.parent = parent;
|
|
654
650
|
this.tree = parent.tree;
|
|
655
651
|
this.tree?.addNodeToIndex(this);
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { DropHint } from "../dragAndDropHandler/types";
|
|
1
|
+
import type { DropHint } from "../dragAndDropHandler/types";
|
|
2
2
|
|
|
3
3
|
class BorderDropHint implements DropHint {
|
|
4
|
-
private
|
|
4
|
+
private _hint?: HTMLElement;
|
|
5
5
|
|
|
6
6
|
constructor(element: HTMLElement, scrollLeft: number) {
|
|
7
7
|
const div = element.querySelector(":scope > .jqtree-element");
|
|
8
8
|
|
|
9
9
|
if (!div) {
|
|
10
|
-
this.
|
|
10
|
+
this._hint = undefined;
|
|
11
11
|
return;
|
|
12
12
|
}
|
|
13
13
|
|
|
@@ -19,13 +19,13 @@ class BorderDropHint implements DropHint {
|
|
|
19
19
|
hint.style.width = `${width}px`;
|
|
20
20
|
hint.style.height = `${height}px`;
|
|
21
21
|
|
|
22
|
-
this.
|
|
22
|
+
this._hint = hint;
|
|
23
23
|
|
|
24
|
-
div.append(this.
|
|
24
|
+
div.append(this._hint);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
public remove(): void {
|
|
28
|
-
this.
|
|
28
|
+
this._hint?.remove();
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|