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.
Files changed (49) hide show
  1. package/bower.json +1 -1
  2. package/js-coverage/coverage-final.json +13 -0
  3. package/lib/jqtreeOptions.js +1 -0
  4. package/lib/tree.jquery.d.js +0 -0
  5. package/lib/tree.jquery.js +394 -0
  6. package/lib/triggerJQueryEvent.js +68 -0
  7. package/lib/typings.d.js +1 -0
  8. package/lib/version.js +2 -0
  9. package/package.json +34 -29
  10. package/pnpm-workspace.yaml +3 -3
  11. package/src/jqtreeOptions.ts +20 -62
  12. package/src/tree.jquery.d.ts +81 -92
  13. package/src/tree.jquery.ts +234 -938
  14. package/src/triggerJQueryEvent.ts +97 -0
  15. package/src/version.ts +2 -2
  16. package/tree.jquery.debug.js +4226 -3281
  17. package/tree.jquery.debug.js.map +1 -1
  18. package/tree.jquery.js +22 -2
  19. package/tree.jquery.js.map +1 -1
  20. package/eslint.config.mjs +0 -112
  21. package/src/animation.ts +0 -48
  22. package/src/dataLoader.ts +0 -143
  23. package/src/dragAndDropHandler/binarySearch.ts +0 -27
  24. package/src/dragAndDropHandler/dragElement.ts +0 -54
  25. package/src/dragAndDropHandler/generateHitAreas.ts +0 -195
  26. package/src/dragAndDropHandler/index.ts +0 -432
  27. package/src/dragAndDropHandler/iterateVisibleNodes.ts +0 -91
  28. package/src/dragAndDropHandler/types.ts +0 -12
  29. package/src/elementsRenderer.ts +0 -359
  30. package/src/jqtreeMethodTypes.ts +0 -40
  31. package/src/keyHandler.ts +0 -139
  32. package/src/mouseHandler.ts +0 -383
  33. package/src/mouseUtils.ts +0 -23
  34. package/src/node.ts +0 -653
  35. package/src/nodeElement/borderDropHint.ts +0 -32
  36. package/src/nodeElement/folderElement.ts +0 -138
  37. package/src/nodeElement/ghostDropHint.ts +0 -74
  38. package/src/nodeElement/index.ts +0 -94
  39. package/src/nodeUtils.ts +0 -10
  40. package/src/positionUtils.ts +0 -18
  41. package/src/saveStateHandler.ts +0 -276
  42. package/src/scrollHandler/containerScrollParent.ts +0 -71
  43. package/src/scrollHandler/createScrollParent.ts +0 -51
  44. package/src/scrollHandler/documentScrollParent.ts +0 -104
  45. package/src/scrollHandler/scrollParent.ts +0 -117
  46. package/src/scrollHandler.ts +0 -55
  47. package/src/selectNodeHandler.ts +0 -111
  48. package/src/simple.widget.ts +0 -134
  49. package/src/util.ts +0 -5
package/src/node.ts DELETED
@@ -1,653 +0,0 @@
1
- import { isNodeRecordWithChildren } from "./nodeUtils";
2
-
3
- export type Position = "after" | "before" | "inside";
4
-
5
- type IterateCallback = (node: Node, level: number) => boolean;
6
-
7
- export class Node implements INode {
8
- [key: string]: unknown;
9
-
10
- public children: Node[];
11
- public element?: HTMLElement;
12
- public id?: NodeId;
13
- public idMapping: Map<NodeId, Node>;
14
- public is_loading: boolean;
15
- public is_open: boolean;
16
- public isEmptyFolder: boolean;
17
- public load_on_demand: boolean;
18
- public name: string;
19
- public nodeClass?: typeof Node;
20
- public parent: Node | null;
21
- public tree?: Node;
22
-
23
- constructor(
24
- nodeData: NodeData | null = null,
25
- isRoot = false,
26
- nodeClass = Node,
27
- ) {
28
- this.name = "";
29
- this.load_on_demand = false;
30
-
31
- this.isEmptyFolder =
32
- nodeData != null &&
33
- isNodeRecordWithChildren(nodeData) &&
34
- nodeData.children.length === 0;
35
-
36
- this.setData(nodeData);
37
-
38
- this.children = [];
39
- this.parent = null;
40
-
41
- if (isRoot) {
42
- this.idMapping = new Map<NodeId, Node>();
43
- this.tree = this;
44
- this.nodeClass = nodeClass;
45
- }
46
- }
47
-
48
- public addAfter(nodeInfo: NodeData): Node | null {
49
- if (!this.parent) {
50
- return null;
51
- } else {
52
- const node = this._createNode(nodeInfo);
53
-
54
- const childIndex = this.parent.getChildIndex(this);
55
- this.parent.addChildAtPosition(node, childIndex + 1);
56
-
57
- node._loadChildrenFromData(nodeInfo);
58
- return node;
59
- }
60
- }
61
-
62
- public addBefore(nodeInfo: NodeData): Node | null {
63
- if (!this.parent) {
64
- return null;
65
- } else {
66
- const node = this._createNode(nodeInfo);
67
-
68
- const childIndex = this.parent.getChildIndex(this);
69
- this.parent.addChildAtPosition(node, childIndex);
70
-
71
- node._loadChildrenFromData(nodeInfo);
72
- return node;
73
- }
74
- }
75
-
76
- /*
77
- Add child.
78
-
79
- tree.addChild(
80
- new Node('child1')
81
- );
82
- */
83
- public addChild(node: Node): void {
84
- this.children.push(node);
85
- node._setParent(this);
86
- }
87
-
88
- /*
89
- Add child at position. Index starts at 0.
90
-
91
- tree.addChildAtPosition(
92
- new Node('abc'),
93
- 1
94
- );
95
- */
96
- public addChildAtPosition(node: Node, index: number): void {
97
- this.children.splice(index, 0, node);
98
- node._setParent(this);
99
- }
100
-
101
- public addNodeToIndex(node: Node): void {
102
- if (node.id != null) {
103
- this.idMapping.set(node.id, node);
104
- }
105
- }
106
-
107
- public addParent(nodeInfo: NodeData): Node | null {
108
- if (!this.parent) {
109
- return null;
110
- } else {
111
- const newParent = this._createNode(nodeInfo);
112
-
113
- if (this.tree) {
114
- newParent._setParent(this.tree);
115
- }
116
- const originalParent = this.parent;
117
-
118
- for (const child of originalParent.children) {
119
- newParent.addChild(child);
120
- }
121
-
122
- originalParent.children = [];
123
- originalParent.addChild(newParent);
124
- return newParent;
125
- }
126
- }
127
-
128
- public append(nodeInfo: NodeData): Node {
129
- const node = this._createNode(nodeInfo);
130
- this.addChild(node);
131
-
132
- node._loadChildrenFromData(nodeInfo);
133
- return node;
134
- }
135
-
136
- public filter(f: (node: Node) => boolean): Node[] {
137
- const result: Node[] = [];
138
-
139
- this.iterate((node: Node) => {
140
- if (f(node)) {
141
- result.push(node);
142
- }
143
-
144
- return true;
145
- });
146
-
147
- return result;
148
- }
149
-
150
- /*
151
- Get child index.
152
-
153
- var index = getChildIndex(node);
154
- */
155
- public getChildIndex(node: Node): number {
156
- return this.children.indexOf(node);
157
- }
158
-
159
- /*
160
- Get the tree as data.
161
- */
162
- public getData(includeParent = false): NodeRecord[] {
163
- const getDataFromNodes = (nodes: Node[]): Record<string, unknown>[] => {
164
- return nodes.map((node) => {
165
- const tmpNode: Record<string, unknown> = {};
166
-
167
- for (const k in node) {
168
- if (
169
- [
170
- "parent",
171
- "children",
172
- "element",
173
- "idMapping",
174
- "load_on_demand",
175
- "nodeClass",
176
- "tree",
177
- "isEmptyFolder",
178
- ].indexOf(k) === -1 &&
179
- Object.prototype.hasOwnProperty.call(node, k)
180
- ) {
181
- const v = node[k];
182
- tmpNode[k] = v;
183
- }
184
- }
185
-
186
- if (node.hasChildren()) {
187
- tmpNode.children = getDataFromNodes(node.children);
188
- }
189
-
190
- return tmpNode;
191
- });
192
- };
193
-
194
- if (includeParent) {
195
- return getDataFromNodes([this]);
196
- } else {
197
- return getDataFromNodes(this.children);
198
- }
199
- }
200
-
201
- public getLastChild(): Node | null {
202
- if (!this.hasChildren()) {
203
- return null;
204
- } else {
205
- const lastChild = this.children[this.children.length - 1] as Node;
206
-
207
- if (!(lastChild.hasChildren() && lastChild.is_open)) {
208
- return lastChild;
209
- } else {
210
- return lastChild.getLastChild();
211
- }
212
- }
213
- }
214
-
215
- public getLevel(): number {
216
- let level = 0;
217
- let node: Node = this; // eslint-disable-line @typescript-eslint/no-this-alias
218
-
219
- while (node.parent) {
220
- level += 1;
221
- node = node.parent;
222
- }
223
-
224
- return level;
225
- }
226
-
227
- public getNextNode(includeChildren = true): Node | null {
228
- if (includeChildren && this.hasChildren()) {
229
- return this.children[0] ?? null;
230
- } else if (!this.parent) {
231
- return null;
232
- } else {
233
- const nextSibling = this.getNextSibling();
234
-
235
- if (nextSibling) {
236
- return nextSibling;
237
- } else {
238
- return this.parent.getNextNode(false);
239
- }
240
- }
241
- }
242
-
243
- public getNextSibling(): Node | null {
244
- if (!this.parent) {
245
- return null;
246
- } else {
247
- const nextIndex = this.parent.getChildIndex(this) + 1;
248
- if (nextIndex < this.parent.children.length) {
249
- return this.parent.children[nextIndex] ?? null;
250
- } else {
251
- return null;
252
- }
253
- }
254
- }
255
-
256
- public getNextVisibleNode(): Node | null {
257
- if (this.hasChildren() && this.is_open) {
258
- // First child
259
- return this.children[0] ?? null;
260
- } else {
261
- if (!this.parent) {
262
- return null;
263
- } else {
264
- const nextSibling = this.getNextSibling();
265
- if (nextSibling) {
266
- // Next sibling
267
- return nextSibling;
268
- } else {
269
- // Next node of parent
270
- return this.parent.getNextNode(false);
271
- }
272
- }
273
- }
274
- }
275
-
276
- public getNodeByCallback(callback: (node: Node) => boolean): Node | null {
277
- let result: Node | null = null;
278
-
279
- this.iterate((node: Node) => {
280
- if (result) {
281
- return false;
282
- } else if (callback(node)) {
283
- result = node;
284
- return false;
285
- } else {
286
- return true;
287
- }
288
- });
289
-
290
- return result;
291
- }
292
-
293
- public getNodeById(nodeId: NodeId): Node | null {
294
- return this.idMapping.get(nodeId) ?? null;
295
- }
296
-
297
- public getNodeByName(name: string): Node | null {
298
- return this.getNodeByCallback((node: Node) => node.name === name);
299
- }
300
-
301
- public getNodeByNameMustExist(name: string): Node {
302
- const node = this.getNodeByCallback((n: Node) => n.name === name);
303
-
304
- if (!node) {
305
- throw new Error(`Node with name ${name} not found`);
306
- }
307
-
308
- return node;
309
- }
310
-
311
- public getNodesByProperty(key: string, value: unknown): Node[] {
312
- return this.filter((node: Node) => node[key] === value);
313
- }
314
-
315
- public getParent(): Node | null {
316
- // Return parent except if it is the root node
317
- if (!this.parent) {
318
- return null;
319
- } else if (!this.parent.parent) {
320
- // Root node -> null
321
- return null;
322
- } else {
323
- return this.parent;
324
- }
325
- }
326
-
327
- public getPreviousNode(): Node | null {
328
- if (!this.parent) {
329
- return null;
330
- } else {
331
- const previousSibling = this.getPreviousSibling();
332
-
333
- if (!previousSibling) {
334
- return this.getParent();
335
- } else if (previousSibling.hasChildren()) {
336
- return previousSibling.getLastChild();
337
- } else {
338
- return previousSibling;
339
- }
340
- }
341
- }
342
-
343
- public getPreviousSibling(): Node | null {
344
- if (!this.parent) {
345
- return null;
346
- } else {
347
- const previousIndex = this.parent.getChildIndex(this) - 1;
348
- if (previousIndex >= 0) {
349
- return this.parent.children[previousIndex] ?? null;
350
- } else {
351
- return null;
352
- }
353
- }
354
- }
355
-
356
- public getPreviousVisibleNode(): Node | null {
357
- if (!this.parent) {
358
- return null;
359
- } else {
360
- const previousSibling = this.getPreviousSibling();
361
-
362
- if (!previousSibling) {
363
- return this.getParent();
364
- } else if (
365
- !previousSibling.hasChildren() ||
366
- !previousSibling.is_open
367
- ) {
368
- // Previous sibling
369
- return previousSibling;
370
- } else {
371
- // Last child of previous sibling
372
- return previousSibling.getLastChild();
373
- }
374
- }
375
- }
376
-
377
- /*
378
- Does the tree have children?
379
-
380
- if (tree.hasChildren()) {
381
- //
382
- }
383
- */
384
- public hasChildren(): boolean {
385
- return this.children.length !== 0;
386
- }
387
-
388
- // Init Node from data without making it the root of the tree
389
- public initFromData(data: NodeData): void {
390
- const addNode = (nodeData: NodeData): void => {
391
- this.setData(nodeData);
392
-
393
- if (
394
- isNodeRecordWithChildren(nodeData) &&
395
- nodeData.children.length
396
- ) {
397
- addChildren(nodeData.children);
398
- }
399
- };
400
-
401
- const addChildren = (childrenData: NodeData[]): void => {
402
- for (const child of childrenData) {
403
- const node = this._createNode();
404
- node.initFromData(child);
405
- this.addChild(node);
406
- }
407
- };
408
-
409
- addNode(data);
410
- }
411
-
412
- public isFolder(): boolean {
413
- return this.hasChildren() || this.load_on_demand;
414
- }
415
-
416
- public isParentOf(node: Node): boolean {
417
- let parent = node.parent;
418
-
419
- while (parent) {
420
- if (parent === this) {
421
- return true;
422
- }
423
-
424
- parent = parent.parent;
425
- }
426
-
427
- return false;
428
- }
429
-
430
- /*
431
- Iterate over all the nodes in the tree.
432
-
433
- Calls callback with (node, level).
434
-
435
- The callback must return true to continue the iteration on current node.
436
-
437
- tree.iterate(
438
- function(node, level) {
439
- console.log(node.name);
440
-
441
- // stop iteration after level 2
442
- return (level <= 2);
443
- }
444
- );
445
-
446
- */
447
- public iterate(callback: IterateCallback): void {
448
- const _iterate = (node: Node, level: number): void => {
449
- for (const child of node.children) {
450
- const result = callback(child, level);
451
-
452
- if (result && child.hasChildren()) {
453
- _iterate(child, level + 1);
454
- }
455
- }
456
- };
457
-
458
- _iterate(this, 0);
459
- }
460
-
461
- /*
462
- Create tree from data.
463
-
464
- Structure of data is:
465
- [
466
- {
467
- name: 'node1',
468
- children: [
469
- { name: 'child1' },
470
- { name: 'child2' }
471
- ]
472
- },
473
- {
474
- name: 'node2'
475
- }
476
- ]
477
- */
478
- public loadFromData(data: NodeData[]): this {
479
- this.removeChildren();
480
-
481
- for (const childData of data) {
482
- const node = this._createNode(childData);
483
- this.addChild(node);
484
-
485
- if (isNodeRecordWithChildren(childData)) {
486
- node.loadFromData(childData.children);
487
- }
488
- }
489
-
490
- return this;
491
- }
492
-
493
- /*
494
- Move node relative to another node.
495
-
496
- Argument position: Position.BEFORE, Position.AFTER or Position.Inside
497
-
498
- // move node1 after node2
499
- tree.moveNode(node1, node2, Position.AFTER);
500
- */
501
- public moveNode(
502
- movedNode: Node,
503
- targetNode: Node,
504
- position: Position,
505
- ): boolean {
506
- if (!movedNode.parent || movedNode.isParentOf(targetNode)) {
507
- // - Node is parent of target node
508
- // - Or, parent is empty
509
- return false;
510
- } else {
511
- movedNode.parent._doRemoveChild(movedNode);
512
-
513
- switch (position) {
514
- case "after": {
515
- if (targetNode.parent) {
516
- targetNode.parent.addChildAtPosition(
517
- movedNode,
518
- targetNode.parent.getChildIndex(targetNode) + 1,
519
- );
520
- return true;
521
- }
522
- return false;
523
- }
524
-
525
- case "before": {
526
- if (targetNode.parent) {
527
- targetNode.parent.addChildAtPosition(
528
- movedNode,
529
- targetNode.parent.getChildIndex(targetNode),
530
- );
531
- return true;
532
- }
533
- return false;
534
- }
535
-
536
- case "inside": {
537
- // move inside as first child
538
- targetNode.addChildAtPosition(movedNode, 0);
539
- return true;
540
- }
541
- }
542
- }
543
- }
544
-
545
- public prepend(nodeInfo: NodeData): Node {
546
- const node = this._createNode(nodeInfo);
547
- this.addChildAtPosition(node, 0);
548
-
549
- node._loadChildrenFromData(nodeInfo);
550
- return node;
551
- }
552
-
553
- public remove(): void {
554
- if (this.parent) {
555
- this.parent.removeChild(this);
556
- this.parent = null;
557
- }
558
- }
559
-
560
- /*
561
- Remove child. This also removes the children of the node.
562
-
563
- tree.removeChild(tree.children[0]);
564
- */
565
- public removeChild(node: Node): void {
566
- // remove children from the index
567
- node.removeChildren();
568
-
569
- this._doRemoveChild(node);
570
- }
571
-
572
- public removeChildren(): void {
573
- this.iterate((child: Node) => {
574
- this.tree?.removeNodeFromIndex(child);
575
- return true;
576
- });
577
-
578
- this.children = [];
579
- }
580
-
581
- public removeNodeFromIndex(node: Node): void {
582
- if (node.id != null) {
583
- this.idMapping.delete(node.id);
584
- }
585
- }
586
-
587
- /*
588
- Set the data of this node.
589
-
590
- setData(string): set the name of the node
591
- setData(object): set attributes of the node
592
-
593
- Examples:
594
- setData('node1')
595
-
596
- setData({ name: 'node1', id: 1});
597
-
598
- setData({ name: 'node2', id: 2, color: 'green'});
599
-
600
- * This is an internal function; it is not in the docs
601
- * Does not remove existing node values
602
- */
603
- public setData(o: NodeData | null): void {
604
- if (!o) {
605
- return;
606
- } else if (typeof o === "string") {
607
- this.name = o;
608
- } else if (typeof o === "object") {
609
- for (const key in o) {
610
- if (Object.prototype.hasOwnProperty.call(o, key)) {
611
- const value = o[key];
612
-
613
- if (key === "label" || key === "name") {
614
- // You can use the 'label' key instead of 'name'; this is a legacy feature
615
- if (typeof value === "string") {
616
- this.name = value;
617
- }
618
- } else if (key !== "children" && key !== "parent") {
619
- // You can't update the children or the parent using this function
620
- this[key] = value;
621
- }
622
- }
623
- }
624
- }
625
- }
626
-
627
- private _createNode(nodeData?: NodeData): Node {
628
- const nodeClass = this._getNodeClass();
629
- return new nodeClass(nodeData);
630
- }
631
-
632
- private _doRemoveChild(node: Node): void {
633
- this.children.splice(this.getChildIndex(node), 1);
634
- this.tree?.removeNodeFromIndex(node);
635
- }
636
-
637
- private _getNodeClass(): typeof Node {
638
- return this.nodeClass ?? this.tree?.nodeClass ?? Node;
639
- }
640
-
641
- // Load children data from nodeInfo if it has children
642
- private _loadChildrenFromData(nodeInfo: NodeData) {
643
- if (isNodeRecordWithChildren(nodeInfo) && nodeInfo.children.length) {
644
- this.loadFromData(nodeInfo.children);
645
- }
646
- }
647
-
648
- private _setParent(parent: Node): void {
649
- this.parent = parent;
650
- this.tree = parent.tree;
651
- this.tree?.addNodeToIndex(this);
652
- }
653
- }
@@ -1,32 +0,0 @@
1
- import type { DropHint } from "../dragAndDropHandler/types";
2
-
3
- class BorderDropHint implements DropHint {
4
- private _hint?: HTMLElement;
5
-
6
- constructor(element: HTMLElement, scrollLeft: number) {
7
- const div = element.querySelector(":scope > .jqtree-element");
8
-
9
- if (!div) {
10
- this._hint = undefined;
11
- return;
12
- }
13
-
14
- const width = Math.max(element.offsetWidth + scrollLeft - 4, 0);
15
- const height = Math.max(element.clientHeight - 4, 0);
16
-
17
- const hint = document.createElement("span");
18
- hint.className = "jqtree-border";
19
- hint.style.width = `${width}px`;
20
- hint.style.height = `${height}px`;
21
-
22
- this._hint = hint;
23
-
24
- div.append(this._hint);
25
- }
26
-
27
- public remove(): void {
28
- this._hint?.remove();
29
- }
30
- }
31
-
32
- export default BorderDropHint;