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
|
@@ -1,24 +1,25 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type {
|
|
2
2
|
GetScrollLeft,
|
|
3
3
|
GetTree,
|
|
4
4
|
OpenNode,
|
|
5
5
|
RefreshElements,
|
|
6
6
|
TriggerEvent,
|
|
7
7
|
} from "../jqtreeMethodTypes";
|
|
8
|
-
import {
|
|
8
|
+
import type {
|
|
9
9
|
DragMethod,
|
|
10
10
|
OnCanMove,
|
|
11
11
|
OnCanMoveTo,
|
|
12
12
|
OnIsMoveHandle,
|
|
13
13
|
} from "../jqtreeOptions";
|
|
14
|
-
import { PositionInfo } from "../mouseUtils";
|
|
15
|
-
import { Node } from "../node";
|
|
16
|
-
import NodeElement from "../nodeElement";
|
|
17
|
-
import {
|
|
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";
|
|
18
20
|
import binarySearch from "./binarySearch";
|
|
19
21
|
import DragElement from "./dragElement";
|
|
20
22
|
import generateHitAreas from "./generateHitAreas";
|
|
21
|
-
import { DropHint, HitArea } from "./types";
|
|
22
23
|
|
|
23
24
|
interface Dimensions {
|
|
24
25
|
bottom: number;
|
|
@@ -55,25 +56,25 @@ export class DragAndDropHandler {
|
|
|
55
56
|
public hoveredArea: HitArea | null;
|
|
56
57
|
public isDragging: boolean;
|
|
57
58
|
|
|
58
|
-
private
|
|
59
|
-
private
|
|
60
|
-
private
|
|
61
|
-
private
|
|
62
|
-
private
|
|
63
|
-
private
|
|
64
|
-
private
|
|
65
|
-
private
|
|
66
|
-
private
|
|
67
|
-
private
|
|
68
|
-
private
|
|
69
|
-
private
|
|
70
|
-
private
|
|
71
|
-
private
|
|
72
|
-
private
|
|
73
|
-
private
|
|
74
|
-
private
|
|
75
|
-
private
|
|
76
|
-
private
|
|
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;
|
|
77
78
|
|
|
78
79
|
constructor({
|
|
79
80
|
autoEscape,
|
|
@@ -93,22 +94,22 @@ export class DragAndDropHandler {
|
|
|
93
94
|
treeElement,
|
|
94
95
|
triggerEvent,
|
|
95
96
|
}: DragAndDropHandlerParams) {
|
|
96
|
-
this.
|
|
97
|
-
this.
|
|
98
|
-
this.
|
|
99
|
-
this.
|
|
100
|
-
this.
|
|
101
|
-
this.
|
|
102
|
-
this.
|
|
103
|
-
this.
|
|
104
|
-
this.
|
|
105
|
-
this.
|
|
106
|
-
this.
|
|
107
|
-
this.
|
|
108
|
-
this.
|
|
109
|
-
this.
|
|
110
|
-
this.
|
|
111
|
-
this.
|
|
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;
|
|
112
113
|
|
|
113
114
|
this.hoveredArea = null;
|
|
114
115
|
this.hitAreas = [];
|
|
@@ -119,18 +120,18 @@ export class DragAndDropHandler {
|
|
|
119
120
|
public mouseCapture(positionInfo: PositionInfo): boolean | null {
|
|
120
121
|
const element = positionInfo.target;
|
|
121
122
|
|
|
122
|
-
if (!this.
|
|
123
|
+
if (!this._mustCaptureElement(element)) {
|
|
123
124
|
return null;
|
|
124
125
|
}
|
|
125
126
|
|
|
126
|
-
if (this.
|
|
127
|
+
if (this._onIsMoveHandle && !this._onIsMoveHandle(jQuery(element))) {
|
|
127
128
|
return null;
|
|
128
129
|
}
|
|
129
130
|
|
|
130
|
-
let nodeElement = this.
|
|
131
|
+
let nodeElement = this._getNodeElement(element);
|
|
131
132
|
|
|
132
|
-
if (nodeElement && this.
|
|
133
|
-
if (!this.
|
|
133
|
+
if (nodeElement && this._onCanMove) {
|
|
134
|
+
if (!this._onCanMove(nodeElement.node)) {
|
|
134
135
|
nodeElement = null;
|
|
135
136
|
}
|
|
136
137
|
}
|
|
@@ -140,43 +141,43 @@ export class DragAndDropHandler {
|
|
|
140
141
|
}
|
|
141
142
|
|
|
142
143
|
public mouseDrag(positionInfo: PositionInfo): boolean {
|
|
143
|
-
if (!this.currentItem || !this.
|
|
144
|
+
if (!this.currentItem || !this._dragElement) {
|
|
144
145
|
return false;
|
|
145
146
|
}
|
|
146
147
|
|
|
147
|
-
this.
|
|
148
|
+
this._dragElement.move(positionInfo.pageX, positionInfo.pageY);
|
|
148
149
|
|
|
149
|
-
const area = this.
|
|
150
|
+
const area = this._findHoveredArea(
|
|
150
151
|
positionInfo.pageX,
|
|
151
152
|
positionInfo.pageY,
|
|
152
153
|
);
|
|
153
154
|
|
|
154
|
-
if (area && this.
|
|
155
|
+
if (area && this._canMoveToArea(area, this.currentItem)) {
|
|
155
156
|
if (!area.node.isFolder()) {
|
|
156
|
-
this.
|
|
157
|
+
this._stopOpenFolderTimer();
|
|
157
158
|
}
|
|
158
159
|
|
|
159
160
|
if (this.hoveredArea !== area) {
|
|
160
161
|
this.hoveredArea = area;
|
|
161
162
|
|
|
162
163
|
// If this is a closed folder, start timer to open it
|
|
163
|
-
if (this.
|
|
164
|
-
this.
|
|
164
|
+
if (this._mustOpenFolderTimer(area)) {
|
|
165
|
+
this._startOpenFolderTimer(area.node);
|
|
165
166
|
} else {
|
|
166
|
-
this.
|
|
167
|
+
this._stopOpenFolderTimer();
|
|
167
168
|
}
|
|
168
169
|
|
|
169
|
-
this.
|
|
170
|
+
this._updateDropHint();
|
|
170
171
|
}
|
|
171
172
|
} else {
|
|
172
|
-
this.
|
|
173
|
-
this.
|
|
173
|
+
this._removeDropHint();
|
|
174
|
+
this._stopOpenFolderTimer();
|
|
174
175
|
this.hoveredArea = area;
|
|
175
176
|
}
|
|
176
177
|
|
|
177
178
|
if (!area) {
|
|
178
|
-
if (this.
|
|
179
|
-
this.
|
|
179
|
+
if (this._onDragMove) {
|
|
180
|
+
this._onDragMove(
|
|
180
181
|
this.currentItem.node,
|
|
181
182
|
positionInfo.originalEvent,
|
|
182
183
|
);
|
|
@@ -197,12 +198,12 @@ export class DragAndDropHandler {
|
|
|
197
198
|
|
|
198
199
|
const node = this.currentItem.node;
|
|
199
200
|
|
|
200
|
-
this.
|
|
201
|
-
autoEscape: this.
|
|
201
|
+
this._dragElement = new DragElement({
|
|
202
|
+
autoEscape: this._autoEscape ?? true,
|
|
202
203
|
nodeName: node.name,
|
|
203
204
|
offsetX: positionInfo.pageX - left,
|
|
204
205
|
offsetY: positionInfo.pageY - top,
|
|
205
|
-
treeElement: this.
|
|
206
|
+
treeElement: this._treeElement,
|
|
206
207
|
});
|
|
207
208
|
|
|
208
209
|
this.isDragging = true;
|
|
@@ -212,11 +213,11 @@ export class DragAndDropHandler {
|
|
|
212
213
|
}
|
|
213
214
|
|
|
214
215
|
public mouseStop(positionInfo: PositionInfo): boolean {
|
|
215
|
-
this.
|
|
216
|
-
this.
|
|
217
|
-
this.
|
|
218
|
-
this.
|
|
219
|
-
this.
|
|
216
|
+
this._moveItem(positionInfo);
|
|
217
|
+
this._clear();
|
|
218
|
+
this._removeHover();
|
|
219
|
+
this._removeDropHint();
|
|
220
|
+
this._removeHitAreas();
|
|
220
221
|
|
|
221
222
|
const currentItem = this.currentItem;
|
|
222
223
|
|
|
@@ -228,8 +229,8 @@ export class DragAndDropHandler {
|
|
|
228
229
|
this.isDragging = false;
|
|
229
230
|
|
|
230
231
|
if (!this.hoveredArea && currentItem) {
|
|
231
|
-
if (this.
|
|
232
|
-
this.
|
|
232
|
+
if (this._onDragStop) {
|
|
233
|
+
this._onDragStop(currentItem.node, positionInfo.originalEvent);
|
|
233
234
|
}
|
|
234
235
|
}
|
|
235
236
|
|
|
@@ -237,12 +238,12 @@ export class DragAndDropHandler {
|
|
|
237
238
|
}
|
|
238
239
|
|
|
239
240
|
public refresh(): void {
|
|
240
|
-
this.
|
|
241
|
+
this._removeHitAreas();
|
|
241
242
|
|
|
242
243
|
if (this.currentItem) {
|
|
243
244
|
const currentNode = this.currentItem.node;
|
|
244
|
-
this.
|
|
245
|
-
this.currentItem = this.
|
|
245
|
+
this._generateHitAreas(currentNode);
|
|
246
|
+
this.currentItem = this._getNodeElementForNode(currentNode);
|
|
246
247
|
|
|
247
248
|
if (this.isDragging) {
|
|
248
249
|
this.currentItem.element.classList.add("jqtree-moving");
|
|
@@ -250,23 +251,23 @@ export class DragAndDropHandler {
|
|
|
250
251
|
}
|
|
251
252
|
}
|
|
252
253
|
|
|
253
|
-
private
|
|
254
|
-
if (!this.
|
|
254
|
+
private _canMoveToArea(area: HitArea, currentItem: NodeElement): boolean {
|
|
255
|
+
if (!this._onCanMoveTo) {
|
|
255
256
|
return true;
|
|
256
257
|
}
|
|
257
258
|
|
|
258
|
-
return this.
|
|
259
|
+
return this._onCanMoveTo(currentItem.node, area.node, area.position);
|
|
259
260
|
}
|
|
260
261
|
|
|
261
|
-
private
|
|
262
|
-
if (this.
|
|
263
|
-
this.
|
|
264
|
-
this.
|
|
262
|
+
private _clear(): void {
|
|
263
|
+
if (this._dragElement) {
|
|
264
|
+
this._dragElement.remove();
|
|
265
|
+
this._dragElement = null;
|
|
265
266
|
}
|
|
266
267
|
}
|
|
267
268
|
|
|
268
|
-
private
|
|
269
|
-
const dimensions = this.
|
|
269
|
+
private _findHoveredArea(x: number, y: number): HitArea | null {
|
|
270
|
+
const dimensions = this._getTreeDimensions();
|
|
270
271
|
|
|
271
272
|
if (
|
|
272
273
|
x < dimensions.left ||
|
|
@@ -288,8 +289,8 @@ export class DragAndDropHandler {
|
|
|
288
289
|
});
|
|
289
290
|
}
|
|
290
291
|
|
|
291
|
-
private
|
|
292
|
-
const tree = this.
|
|
292
|
+
private _generateHitAreas(currentNode: Node): void {
|
|
293
|
+
const tree = this._getTree();
|
|
293
294
|
|
|
294
295
|
if (!tree) {
|
|
295
296
|
this.hitAreas = [];
|
|
@@ -297,32 +298,32 @@ export class DragAndDropHandler {
|
|
|
297
298
|
this.hitAreas = generateHitAreas(
|
|
298
299
|
tree,
|
|
299
300
|
currentNode,
|
|
300
|
-
this.
|
|
301
|
+
this._getTreeDimensions().bottom,
|
|
301
302
|
);
|
|
302
303
|
}
|
|
303
304
|
}
|
|
304
305
|
|
|
305
|
-
private
|
|
306
|
+
private _getTreeDimensions(): Dimensions {
|
|
306
307
|
// Return the dimensions of the tree. Add a margin to the bottom to allow
|
|
307
308
|
// to drag-and-drop after the last element.
|
|
308
|
-
const treePosition = getElementPosition(this.
|
|
309
|
-
const left = treePosition.left + this.
|
|
309
|
+
const treePosition = getElementPosition(this._treeElement);
|
|
310
|
+
const left = treePosition.left + this._getScrollLeft();
|
|
310
311
|
const top = treePosition.top;
|
|
311
312
|
|
|
312
313
|
return {
|
|
313
|
-
bottom: top + this.
|
|
314
|
+
bottom: top + this._treeElement.clientHeight + 16,
|
|
314
315
|
left,
|
|
315
|
-
right: left + this.
|
|
316
|
+
right: left + this._treeElement.clientWidth,
|
|
316
317
|
top,
|
|
317
318
|
};
|
|
318
319
|
}
|
|
319
320
|
|
|
320
321
|
/* Move the dragged node to the selected position in the tree. */
|
|
321
|
-
private
|
|
322
|
+
private _moveItem(positionInfo: PositionInfo): void {
|
|
322
323
|
if (
|
|
323
324
|
this.currentItem &&
|
|
324
325
|
this.hoveredArea?.position &&
|
|
325
|
-
this.
|
|
326
|
+
this._canMoveToArea(this.hoveredArea, this.currentItem)
|
|
326
327
|
) {
|
|
327
328
|
const movedNode = this.currentItem.node;
|
|
328
329
|
const targetNode = this.hoveredArea.node;
|
|
@@ -334,17 +335,17 @@ export class DragAndDropHandler {
|
|
|
334
335
|
}
|
|
335
336
|
|
|
336
337
|
const doMove = (): void => {
|
|
337
|
-
const tree = this.
|
|
338
|
+
const tree = this._getTree();
|
|
338
339
|
|
|
339
340
|
if (tree) {
|
|
340
341
|
tree.moveNode(movedNode, targetNode, position);
|
|
341
342
|
|
|
342
|
-
this.
|
|
343
|
-
this.
|
|
343
|
+
this._treeElement.textContent = "";
|
|
344
|
+
this._refreshElements(null);
|
|
344
345
|
}
|
|
345
346
|
};
|
|
346
347
|
|
|
347
|
-
|
|
348
|
+
if (this._triggerEvent("tree.move", {
|
|
348
349
|
move_info: {
|
|
349
350
|
do_move: doMove,
|
|
350
351
|
moved_node: movedNode,
|
|
@@ -353,15 +354,13 @@ export class DragAndDropHandler {
|
|
|
353
354
|
previous_parent: previousParent,
|
|
354
355
|
target_node: targetNode,
|
|
355
356
|
},
|
|
356
|
-
})
|
|
357
|
-
|
|
358
|
-
if (!event.isDefaultPrevented()) {
|
|
357
|
+
})) {
|
|
359
358
|
doMove();
|
|
360
359
|
}
|
|
361
360
|
}
|
|
362
361
|
}
|
|
363
362
|
|
|
364
|
-
private
|
|
363
|
+
private _mustCaptureElement(element: HTMLElement): boolean {
|
|
365
364
|
const nodeName = element.nodeName;
|
|
366
365
|
|
|
367
366
|
return (
|
|
@@ -371,63 +370,63 @@ export class DragAndDropHandler {
|
|
|
371
370
|
);
|
|
372
371
|
}
|
|
373
372
|
|
|
374
|
-
private
|
|
373
|
+
private _mustOpenFolderTimer(area: HitArea): boolean {
|
|
375
374
|
const node = area.node;
|
|
376
375
|
|
|
377
376
|
return node.isFolder() && !node.is_open && area.position === "inside";
|
|
378
377
|
}
|
|
379
378
|
|
|
380
|
-
private
|
|
381
|
-
if (this.
|
|
382
|
-
this.
|
|
379
|
+
private _removeDropHint(): void {
|
|
380
|
+
if (this._previousGhost) {
|
|
381
|
+
this._previousGhost.remove();
|
|
383
382
|
}
|
|
384
383
|
}
|
|
385
384
|
|
|
386
|
-
private
|
|
385
|
+
private _removeHitAreas(): void {
|
|
387
386
|
this.hitAreas = [];
|
|
388
387
|
}
|
|
389
388
|
|
|
390
|
-
private
|
|
389
|
+
private _removeHover(): void {
|
|
391
390
|
this.hoveredArea = null;
|
|
392
391
|
}
|
|
393
392
|
|
|
394
|
-
private
|
|
393
|
+
private _startOpenFolderTimer(folder: Node): void {
|
|
395
394
|
const openFolder = (): void => {
|
|
396
|
-
this.
|
|
395
|
+
this._openNode(folder, this._slide, () => {
|
|
397
396
|
this.refresh();
|
|
398
|
-
this.
|
|
397
|
+
this._updateDropHint();
|
|
399
398
|
});
|
|
400
399
|
};
|
|
401
400
|
|
|
402
|
-
this.
|
|
401
|
+
this._stopOpenFolderTimer();
|
|
403
402
|
|
|
404
|
-
const openFolderDelay = this.
|
|
403
|
+
const openFolderDelay = this._openFolderDelay;
|
|
405
404
|
|
|
406
405
|
if (openFolderDelay !== false) {
|
|
407
|
-
this.
|
|
406
|
+
this._openFolderTimer = window.setTimeout(
|
|
408
407
|
openFolder,
|
|
409
408
|
openFolderDelay,
|
|
410
409
|
);
|
|
411
410
|
}
|
|
412
411
|
}
|
|
413
412
|
|
|
414
|
-
private
|
|
415
|
-
if (this.
|
|
416
|
-
clearTimeout(this.
|
|
417
|
-
this.
|
|
413
|
+
private _stopOpenFolderTimer(): void {
|
|
414
|
+
if (this._openFolderTimer) {
|
|
415
|
+
clearTimeout(this._openFolderTimer);
|
|
416
|
+
this._openFolderTimer = null;
|
|
418
417
|
}
|
|
419
418
|
}
|
|
420
419
|
|
|
421
|
-
private
|
|
420
|
+
private _updateDropHint(): void {
|
|
422
421
|
if (!this.hoveredArea) {
|
|
423
422
|
return;
|
|
424
423
|
}
|
|
425
424
|
|
|
426
425
|
// remove previous drop hint
|
|
427
|
-
this.
|
|
426
|
+
this._removeDropHint();
|
|
428
427
|
|
|
429
428
|
// add new drop hint
|
|
430
|
-
const nodeElement = this.
|
|
431
|
-
this.
|
|
429
|
+
const nodeElement = this._getNodeElementForNode(this.hoveredArea.node);
|
|
430
|
+
this._previousGhost = nodeElement.addDropHint(this.hoveredArea.position);
|
|
432
431
|
}
|
|
433
432
|
}
|