tree-element 0.1.1 → 0.3.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 (155) hide show
  1. package/README.md +43 -31
  2. package/lib/animation.d.ts +2 -2
  3. package/lib/animation.d.ts.map +1 -1
  4. package/lib/animation.js +16 -12
  5. package/lib/animation.js.map +1 -1
  6. package/lib/classNames.d.ts.map +1 -1
  7. package/lib/classNames.js +2 -2
  8. package/lib/classNames.js.map +1 -1
  9. package/lib/dataLoader.d.ts +1 -0
  10. package/lib/dataLoader.d.ts.map +1 -1
  11. package/lib/dataLoader.js +22 -20
  12. package/lib/dataLoader.js.map +1 -1
  13. package/lib/dragAndDropHandler/binarySearch.js +3 -3
  14. package/lib/dragAndDropHandler/binarySearch.js.map +1 -1
  15. package/lib/dragAndDropHandler/dragElement.d.ts.map +1 -1
  16. package/lib/dragAndDropHandler/dragElement.js +11 -13
  17. package/lib/dragAndDropHandler/dragElement.js.map +1 -1
  18. package/lib/dragAndDropHandler/generateHitAreas.d.ts.map +1 -1
  19. package/lib/dragAndDropHandler/generateHitAreas.js +25 -25
  20. package/lib/dragAndDropHandler/generateHitAreas.js.map +1 -1
  21. package/lib/dragAndDropHandler/index.d.ts.map +1 -1
  22. package/lib/dragAndDropHandler/index.js +125 -158
  23. package/lib/dragAndDropHandler/index.js.map +1 -1
  24. package/lib/dragAndDropHandler/iterateVisibleNodes.d.ts.map +1 -1
  25. package/lib/dragAndDropHandler/iterateVisibleNodes.js +23 -22
  26. package/lib/dragAndDropHandler/iterateVisibleNodes.js.map +1 -1
  27. package/lib/dragAndDropHandler/types.d.ts.map +1 -1
  28. package/lib/elementsRenderer.d.ts +20 -7
  29. package/lib/elementsRenderer.d.ts.map +1 -1
  30. package/lib/elementsRenderer.js +195 -136
  31. package/lib/elementsRenderer.js.map +1 -1
  32. package/lib/events.d.ts +44 -11
  33. package/lib/events.d.ts.map +1 -1
  34. package/lib/index.d.ts +36 -13
  35. package/lib/index.d.ts.map +1 -1
  36. package/lib/index.js +386 -349
  37. package/lib/index.js.map +1 -1
  38. package/lib/keyHandler.d.ts +13 -8
  39. package/lib/keyHandler.d.ts.map +1 -1
  40. package/lib/keyHandler.js +106 -51
  41. package/lib/keyHandler.js.map +1 -1
  42. package/lib/methodTypes.d.ts +3 -3
  43. package/lib/methodTypes.d.ts.map +1 -1
  44. package/lib/mouseHandler.d.ts +1 -1
  45. package/lib/mouseHandler.d.ts.map +1 -1
  46. package/lib/mouseHandler.js +36 -49
  47. package/lib/mouseHandler.js.map +1 -1
  48. package/lib/mouseUtils.d.ts.map +1 -1
  49. package/lib/mouseUtils.js +2 -2
  50. package/lib/mouseUtils.js.map +1 -1
  51. package/lib/node.d.ts +47 -16
  52. package/lib/node.d.ts.map +1 -1
  53. package/lib/node.js +169 -171
  54. package/lib/node.js.map +1 -1
  55. package/lib/nodeElement/borderDropHint.d.ts.map +1 -1
  56. package/lib/nodeElement/borderDropHint.js +4 -5
  57. package/lib/nodeElement/borderDropHint.js.map +1 -1
  58. package/lib/nodeElement/folderElement.d.ts +8 -5
  59. package/lib/nodeElement/folderElement.d.ts.map +1 -1
  60. package/lib/nodeElement/folderElement.js +75 -67
  61. package/lib/nodeElement/folderElement.js.map +1 -1
  62. package/lib/nodeElement/ghostDropHint.d.ts.map +1 -1
  63. package/lib/nodeElement/ghostDropHint.js +13 -13
  64. package/lib/nodeElement/ghostDropHint.js.map +1 -1
  65. package/lib/nodeElement/index.d.ts +2 -1
  66. package/lib/nodeElement/index.d.ts.map +1 -1
  67. package/lib/nodeElement/index.js +38 -30
  68. package/lib/nodeElement/index.js.map +1 -1
  69. package/lib/nodeUtils.d.ts.map +1 -1
  70. package/lib/nodeUtils.js +1 -1
  71. package/lib/nodeUtils.js.map +1 -1
  72. package/lib/options.d.ts +19 -3
  73. package/lib/options.d.ts.map +1 -1
  74. package/lib/positionUtils.js +3 -3
  75. package/lib/positionUtils.js.map +1 -1
  76. package/lib/requestUrl.d.ts +1 -1
  77. package/lib/requestUrl.d.ts.map +1 -1
  78. package/lib/requestUrl.js +6 -17
  79. package/lib/requestUrl.js.map +1 -1
  80. package/lib/saveStateHandler.d.ts.map +1 -1
  81. package/lib/saveStateHandler.js +59 -89
  82. package/lib/saveStateHandler.js.map +1 -1
  83. package/lib/scrollHandler/containerScrollParent.d.ts.map +1 -1
  84. package/lib/scrollHandler/containerScrollParent.js +11 -18
  85. package/lib/scrollHandler/containerScrollParent.js.map +1 -1
  86. package/lib/scrollHandler/createScrollParent.d.ts.map +1 -1
  87. package/lib/scrollHandler/createScrollParent.js +12 -13
  88. package/lib/scrollHandler/createScrollParent.js.map +1 -1
  89. package/lib/scrollHandler/documentScrollParent.d.ts.map +1 -1
  90. package/lib/scrollHandler/documentScrollParent.js +18 -27
  91. package/lib/scrollHandler/documentScrollParent.js.map +1 -1
  92. package/lib/scrollHandler/scrollParent.d.ts.map +1 -1
  93. package/lib/scrollHandler/scrollParent.js +30 -34
  94. package/lib/scrollHandler/scrollParent.js.map +1 -1
  95. package/lib/scrollHandler.d.ts.map +1 -1
  96. package/lib/scrollHandler.js +11 -14
  97. package/lib/scrollHandler.js.map +1 -1
  98. package/lib/selectNodeHandler.d.ts +4 -2
  99. package/lib/selectNodeHandler.d.ts.map +1 -1
  100. package/lib/selectNodeHandler.js +64 -83
  101. package/lib/selectNodeHandler.js.map +1 -1
  102. package/lib/setDefaultOptions.d.ts.map +1 -1
  103. package/lib/setDefaultOptions.js +34 -38
  104. package/lib/setDefaultOptions.js.map +1 -1
  105. package/lib/triggerCustomEvent.d.ts.map +1 -1
  106. package/lib/triggerCustomEvent.js +2 -2
  107. package/lib/triggerCustomEvent.js.map +1 -1
  108. package/lib/util.d.ts.map +1 -1
  109. package/lib/util.js +2 -2
  110. package/lib/util.js.map +1 -1
  111. package/lib/version.d.ts +1 -1
  112. package/lib/version.js +1 -1
  113. package/lib/version.js.map +1 -1
  114. package/package.json +43 -32
  115. package/src/animation.ts +14 -12
  116. package/src/classNames.ts +52 -52
  117. package/src/dataLoader.ts +79 -71
  118. package/src/dragAndDropHandler/binarySearch.ts +17 -17
  119. package/src/dragAndDropHandler/dragElement.ts +51 -50
  120. package/src/dragAndDropHandler/generateHitAreas.ts +156 -161
  121. package/src/dragAndDropHandler/index.ts +334 -348
  122. package/src/dragAndDropHandler/iterateVisibleNodes.ts +61 -63
  123. package/src/dragAndDropHandler/types.ts +5 -5
  124. package/src/elementsRenderer.ts +377 -294
  125. package/src/events.ts +241 -208
  126. package/src/header.txt +1 -1
  127. package/src/index.ts +259 -229
  128. package/src/keyHandler.ts +179 -115
  129. package/src/methodTypes.ts +7 -10
  130. package/src/mouseHandler.ts +316 -316
  131. package/src/mouseUtils.ts +14 -14
  132. package/src/node.ts +773 -771
  133. package/src/nodeElement/borderDropHint.ts +25 -25
  134. package/src/nodeElement/folderElement.ts +116 -102
  135. package/src/nodeElement/ghostDropHint.ts +64 -62
  136. package/src/nodeElement/index.ts +81 -73
  137. package/src/nodeUtils.ts +5 -5
  138. package/src/options.ts +25 -5
  139. package/src/requestUrl.ts +7 -14
  140. package/src/saveStateHandler.ts +191 -207
  141. package/src/scrollHandler/containerScrollParent.ts +40 -49
  142. package/src/scrollHandler/createScrollParent.ts +26 -27
  143. package/src/scrollHandler/documentScrollParent.ts +66 -72
  144. package/src/scrollHandler/scrollParent.ts +90 -86
  145. package/src/scrollHandler.ts +45 -45
  146. package/src/selectNodeHandler.ts +171 -165
  147. package/src/setDefaultOptions.ts +44 -32
  148. package/src/triggerCustomEvent.ts +7 -3
  149. package/src/util.ts +2 -3
  150. package/src/version.ts +1 -1
  151. package/tree_element.css +87 -69
  152. package/tree_element.debug.js +3866 -3831
  153. package/tree_element.debug.js.map +1 -1
  154. package/tree_element.js +2 -2
  155. package/tree_element.js.map +1 -1
@@ -1,19 +1,19 @@
1
1
  import type { ClassNames } from "../classNames";
2
2
  import type {
3
- GetScrollLeft,
4
- GetTree,
5
- OpenNode,
6
- RefreshElements,
7
- TriggerEvent,
3
+ GetScrollLeft,
4
+ GetTree,
5
+ OpenNode,
6
+ RefreshElements,
7
+ TriggerEvent,
8
8
  } from "../methodTypes";
9
9
  import type { PositionInfo } from "../mouseUtils";
10
10
  import type { Node } from "../node";
11
11
  import type NodeElement from "../nodeElement";
12
12
  import type {
13
- DragMethod,
14
- OnCanMove,
15
- OnCanMoveTo,
16
- OnIsMoveHandle,
13
+ DragMethod,
14
+ OnCanMove,
15
+ OnCanMoveTo,
16
+ OnIsMoveHandle,
17
17
  } from "../options";
18
18
  import type { DropHint, HitArea } from "./types";
19
19
 
@@ -23,420 +23,406 @@ import DragElement from "./dragElement";
23
23
  import generateHitAreas from "./generateHitAreas";
24
24
 
25
25
  interface Dimensions {
26
- bottom: number;
27
- left: number;
28
- right: number;
29
- top: number;
26
+ bottom: number;
27
+ left: number;
28
+ right: number;
29
+ top: number;
30
30
  }
31
31
 
32
32
  interface DragAndDropHandlerParams {
33
- autoEscape?: boolean;
34
- classNames: ClassNames;
35
- getNodeElement: GetNodeElement;
36
- getNodeElementForNode: GetNodeElementForNode;
37
- getScrollLeft: GetScrollLeft;
38
- getTree: GetTree;
39
- onCanMove?: OnCanMove;
40
- onCanMoveTo?: OnCanMoveTo;
41
- onDragMove?: DragMethod;
42
- onDragStop?: DragMethod;
43
- onIsMoveHandle?: OnIsMoveHandle;
44
- openFolderDelay: false | number;
45
- openNode: OpenNode;
46
- refreshElements: RefreshElements;
47
- slide: boolean;
48
- treeElement: HTMLElement;
49
- triggerEvent: TriggerEvent;
33
+ autoEscape?: boolean;
34
+ classNames: ClassNames;
35
+ getNodeElement: GetNodeElement;
36
+ getNodeElementForNode: GetNodeElementForNode;
37
+ getScrollLeft: GetScrollLeft;
38
+ getTree: GetTree;
39
+ onCanMove?: OnCanMove;
40
+ onCanMoveTo?: OnCanMoveTo;
41
+ onDragMove?: DragMethod;
42
+ onDragStop?: DragMethod;
43
+ onIsMoveHandle?: OnIsMoveHandle;
44
+ openFolderDelay: false | number;
45
+ openNode: OpenNode;
46
+ refreshElements: RefreshElements;
47
+ slide: boolean;
48
+ treeElement: HTMLElement;
49
+ triggerEvent: TriggerEvent;
50
50
  }
51
51
  type GetNodeElement = (element: HTMLElement) => NodeElement | null;
52
52
 
53
53
  type GetNodeElementForNode = (node: Node) => NodeElement;
54
54
 
55
55
  export class DragAndDropHandler {
56
- public currentItem: NodeElement | null;
57
- public hitAreas: HitArea[];
58
- public hoveredArea: HitArea | null;
59
- public isDragging: boolean;
60
-
61
- private autoEscape?: boolean;
62
- private classNames: ClassNames;
63
- private dragElement: DragElement | null;
64
- private getNodeElement: GetNodeElement;
65
- private getNodeElementForNode: GetNodeElementForNode;
66
- private getScrollLeft: GetScrollLeft;
67
- private getTree: GetTree;
68
- private onCanMove?: OnCanMove;
69
- private onCanMoveTo?: OnCanMoveTo;
70
- private onDragMove?: DragMethod;
71
- private onDragStop?: DragMethod;
72
- private onIsMoveHandle?: OnIsMoveHandle;
73
- private openFolderDelay: false | number;
74
- private openFolderTimer: null | number;
75
- private openNode: OpenNode;
76
- private previousGhost: DropHint | null;
77
- private refreshElements: RefreshElements;
78
- private slide: boolean;
79
- private treeElement: HTMLElement;
80
- private triggerEvent: TriggerEvent;
81
-
82
- constructor({
83
- autoEscape,
84
- classNames,
85
- getNodeElement,
86
- getNodeElementForNode,
87
- getScrollLeft,
88
- getTree,
89
- onCanMove,
90
- onCanMoveTo,
91
- onDragMove,
92
- onDragStop,
93
- onIsMoveHandle,
94
- openFolderDelay,
95
- openNode,
96
- refreshElements,
97
- slide,
98
- treeElement,
99
- triggerEvent,
100
- }: DragAndDropHandlerParams) {
101
- this.autoEscape = autoEscape;
102
- this.classNames = classNames;
103
- this.getNodeElement = getNodeElement;
104
- this.getNodeElementForNode = getNodeElementForNode;
105
- this.getScrollLeft = getScrollLeft;
106
- this.getTree = getTree;
107
- this.onCanMove = onCanMove;
108
- this.onCanMoveTo = onCanMoveTo;
109
- this.onDragMove = onDragMove;
110
- this.onDragStop = onDragStop;
111
- this.onIsMoveHandle = onIsMoveHandle;
112
- this.openFolderDelay = openFolderDelay;
113
- this.openNode = openNode;
114
- this.refreshElements = refreshElements;
115
- this.slide = slide;
116
- this.treeElement = treeElement;
117
- this.triggerEvent = triggerEvent;
118
-
119
- this.hoveredArea = null;
120
- this.hitAreas = [];
121
- this.isDragging = false;
122
- this.currentItem = null;
123
-
124
- this.dragElement = null;
125
- this.openFolderTimer = null;
126
- this.previousGhost = null;
56
+ public currentItem: NodeElement | null;
57
+ public hitAreas: HitArea[];
58
+ public hoveredArea: HitArea | null;
59
+ public isDragging: boolean;
60
+
61
+ private autoEscape?: boolean;
62
+ private classNames: ClassNames;
63
+ private dragElement: DragElement | null;
64
+ private getNodeElement: GetNodeElement;
65
+ private getNodeElementForNode: GetNodeElementForNode;
66
+ private getScrollLeft: GetScrollLeft;
67
+ private getTree: GetTree;
68
+ private onCanMove?: OnCanMove;
69
+ private onCanMoveTo?: OnCanMoveTo;
70
+ private onDragMove?: DragMethod;
71
+ private onDragStop?: DragMethod;
72
+ private onIsMoveHandle?: OnIsMoveHandle;
73
+ private openFolderDelay: false | number;
74
+ private openFolderTimer: null | number;
75
+ private openNode: OpenNode;
76
+ private previousGhost: DropHint | null;
77
+ private refreshElements: RefreshElements;
78
+ private slide: boolean;
79
+ private treeElement: HTMLElement;
80
+ private triggerEvent: TriggerEvent;
81
+
82
+ constructor({
83
+ autoEscape,
84
+ classNames,
85
+ getNodeElement,
86
+ getNodeElementForNode,
87
+ getScrollLeft,
88
+ getTree,
89
+ onCanMove,
90
+ onCanMoveTo,
91
+ onDragMove,
92
+ onDragStop,
93
+ onIsMoveHandle,
94
+ openFolderDelay,
95
+ openNode,
96
+ refreshElements,
97
+ slide,
98
+ treeElement,
99
+ triggerEvent,
100
+ }: DragAndDropHandlerParams) {
101
+ this.autoEscape = autoEscape;
102
+ this.classNames = classNames;
103
+ this.getNodeElement = getNodeElement;
104
+ this.getNodeElementForNode = getNodeElementForNode;
105
+ this.getScrollLeft = getScrollLeft;
106
+ this.getTree = getTree;
107
+ this.onCanMove = onCanMove;
108
+ this.onCanMoveTo = onCanMoveTo;
109
+ this.onDragMove = onDragMove;
110
+ this.onDragStop = onDragStop;
111
+ this.onIsMoveHandle = onIsMoveHandle;
112
+ this.openFolderDelay = openFolderDelay;
113
+ this.openNode = openNode;
114
+ this.refreshElements = refreshElements;
115
+ this.slide = slide;
116
+ this.treeElement = treeElement;
117
+ this.triggerEvent = triggerEvent;
118
+
119
+ this.hoveredArea = null;
120
+ this.hitAreas = [];
121
+ this.isDragging = false;
122
+ this.currentItem = null;
123
+
124
+ this.dragElement = null;
125
+ this.openFolderTimer = null;
126
+ this.previousGhost = null;
127
+ }
128
+
129
+ public mouseCapture(positionInfo: PositionInfo): boolean | null {
130
+ const element = positionInfo.target;
131
+
132
+ if (!this.mustCaptureElement(element)) {
133
+ return null;
127
134
  }
128
135
 
129
- public mouseCapture(positionInfo: PositionInfo): boolean | null {
130
- const element = positionInfo.target;
131
-
132
- if (!this.mustCaptureElement(element)) {
133
- return null;
134
- }
135
-
136
- if (this.onIsMoveHandle && !this.onIsMoveHandle(element)) {
137
- return null;
138
- }
136
+ if (this.onIsMoveHandle && !this.onIsMoveHandle(element)) {
137
+ return null;
138
+ }
139
139
 
140
- let nodeElement = this.getNodeElement(element);
140
+ let nodeElement = this.getNodeElement(element);
141
141
 
142
- if (nodeElement && this.onCanMove) {
143
- if (!this.onCanMove(nodeElement.node)) {
144
- nodeElement = null;
145
- }
146
- }
147
-
148
- this.currentItem = nodeElement;
149
- return this.currentItem != null;
142
+ if (nodeElement && this.onCanMove && !this.onCanMove(nodeElement.node)) {
143
+ nodeElement = null;
150
144
  }
151
145
 
152
- public mouseDrag(positionInfo: PositionInfo): boolean {
153
- if (!this.currentItem || !this.dragElement) {
154
- return false;
155
- }
146
+ this.currentItem = nodeElement;
147
+ return this.currentItem != null;
148
+ }
156
149
 
157
- this.dragElement.move(positionInfo.pageX, positionInfo.pageY);
150
+ public mouseDrag(positionInfo: PositionInfo): boolean {
151
+ if (!this.currentItem || !this.dragElement) {
152
+ return false;
153
+ }
158
154
 
159
- const area = this.findHoveredArea(
160
- positionInfo.pageX,
161
- positionInfo.pageY,
162
- );
155
+ this.dragElement.move(positionInfo.pageX, positionInfo.pageY);
163
156
 
164
- if (area && this.canMoveToArea(area, this.currentItem)) {
165
- if (!area.node.isFolder()) {
166
- this.stopOpenFolderTimer();
167
- }
157
+ const area = this.findHoveredArea(positionInfo.pageX, positionInfo.pageY);
168
158
 
169
- if (this.hoveredArea !== area) {
170
- this.hoveredArea = area;
159
+ if (area && this.canMoveToArea(area, this.currentItem)) {
160
+ if (!area.node.isFolder()) {
161
+ this.stopOpenFolderTimer();
162
+ }
171
163
 
172
- // If this is a closed folder, start timer to open it
173
- if (this.mustOpenFolderTimer(area)) {
174
- this.startOpenFolderTimer(area.node);
175
- } else {
176
- this.stopOpenFolderTimer();
177
- }
164
+ if (this.hoveredArea !== area) {
165
+ this.hoveredArea = area;
178
166
 
179
- this.updateDropHint();
180
- }
167
+ // If this is a closed folder, start timer to open it
168
+ if (this.mustOpenFolderTimer(area)) {
169
+ this.startOpenFolderTimer(area.node);
181
170
  } else {
182
- this.removeDropHint();
183
- this.stopOpenFolderTimer();
184
- this.hoveredArea = area;
171
+ this.stopOpenFolderTimer();
185
172
  }
186
173
 
187
- if (!area) {
188
- if (this.onDragMove) {
189
- this.onDragMove(
190
- this.currentItem.node,
191
- positionInfo.originalEvent,
192
- );
193
- }
194
- }
174
+ this.updateDropHint();
175
+ }
176
+ } else {
177
+ this.removeDropHint();
178
+ this.stopOpenFolderTimer();
179
+ this.hoveredArea = area;
180
+ }
195
181
 
196
- return true;
182
+ if (!area && this.onDragMove) {
183
+ this.onDragMove(this.currentItem.node, positionInfo.originalEvent);
197
184
  }
198
185
 
199
- public mouseStart(positionInfo: PositionInfo): boolean {
200
- if (!this.currentItem) {
201
- return false;
202
- }
186
+ return true;
187
+ }
203
188
 
204
- this.refresh();
189
+ public mouseStart(positionInfo: PositionInfo): boolean {
190
+ if (!this.currentItem) {
191
+ return false;
192
+ }
205
193
 
206
- const { left, top } = getElementPosition(positionInfo.target);
194
+ this.refresh();
207
195
 
208
- const node = this.currentItem.node;
196
+ const { left, top } = getElementPosition(positionInfo.target);
209
197
 
210
- this.dragElement = new DragElement({
211
- autoEscape: this.autoEscape ?? true,
212
- classNames: this.classNames,
213
- nodeName: node.name,
214
- offsetX: positionInfo.pageX - left,
215
- offsetY: positionInfo.pageY - top,
216
- treeElement: this.treeElement,
217
- });
198
+ const node = this.currentItem.node;
218
199
 
219
- this.isDragging = true;
220
- this.currentItem.element.classList.add(this.classNames.moving);
200
+ this.dragElement = new DragElement({
201
+ autoEscape: this.autoEscape ?? true,
202
+ classNames: this.classNames,
203
+ nodeName: node.name,
204
+ offsetX: positionInfo.pageX - left,
205
+ offsetY: positionInfo.pageY - top,
206
+ treeElement: this.treeElement,
207
+ });
221
208
 
222
- return true;
223
- }
209
+ this.isDragging = true;
210
+ this.currentItem.element.classList.add(this.classNames.moving);
224
211
 
225
- public mouseStop(positionInfo: PositionInfo): boolean {
226
- this.moveItem(positionInfo);
227
- this.clear();
228
- this.removeHover();
229
- this.removeDropHint();
230
- this.removeHitAreas();
212
+ return true;
213
+ }
231
214
 
232
- const currentItem = this.currentItem;
215
+ public mouseStop(positionInfo: PositionInfo): boolean {
216
+ this.moveItem(positionInfo);
217
+ this.clear();
218
+ this.removeHover();
219
+ this.removeDropHint();
220
+ this.removeHitAreas();
233
221
 
234
- if (this.currentItem) {
235
- this.currentItem.element.classList.remove(this.classNames.moving);
236
- this.currentItem = null;
237
- }
222
+ const currentItem = this.currentItem;
238
223
 
239
- this.isDragging = false;
224
+ if (this.currentItem) {
225
+ this.currentItem.element.classList.remove(this.classNames.moving);
226
+ this.currentItem = null;
227
+ }
240
228
 
241
- if (!this.hoveredArea && currentItem) {
242
- if (this.onDragStop) {
243
- this.onDragStop(currentItem.node, positionInfo.originalEvent);
244
- }
245
- }
229
+ this.isDragging = false;
246
230
 
247
- return false;
231
+ if (!this.hoveredArea && currentItem && this.onDragStop) {
232
+ this.onDragStop(currentItem.node, positionInfo.originalEvent);
248
233
  }
249
234
 
250
- public refresh(): void {
251
- this.removeHitAreas();
235
+ return false;
236
+ }
252
237
 
253
- if (this.currentItem) {
254
- const currentNode = this.currentItem.node;
255
- this.generateHitAreas(currentNode);
256
- this.currentItem = this.getNodeElementForNode(currentNode);
238
+ public refresh(): void {
239
+ this.removeHitAreas();
257
240
 
258
- if (this.isDragging) {
259
- this.currentItem.element.classList.add(this.classNames.moving);
260
- }
261
- }
241
+ if (!this.currentItem) {
242
+ return;
262
243
  }
263
244
 
264
- private canMoveToArea(area: HitArea, currentItem: NodeElement): boolean {
265
- if (!this.onCanMoveTo) {
266
- return true;
267
- }
245
+ const currentNode = this.currentItem.node;
246
+ this.generateHitAreas(currentNode);
247
+ this.currentItem = this.getNodeElementForNode(currentNode);
268
248
 
269
- return this.onCanMoveTo(currentItem.node, area.node, area.position);
249
+ if (this.isDragging) {
250
+ this.currentItem.element.classList.add(this.classNames.moving);
270
251
  }
252
+ }
271
253
 
272
- private clear(): void {
273
- if (this.dragElement) {
274
- this.dragElement.remove();
275
- this.dragElement = null;
276
- }
254
+ private canMoveToArea(area: HitArea, currentItem: NodeElement): boolean {
255
+ return this.onCanMoveTo
256
+ ? this.onCanMoveTo(currentItem.node, area.node, area.position)
257
+ : true;
258
+ }
259
+
260
+ private clear(): void {
261
+ if (!this.dragElement) {
262
+ return;
277
263
  }
278
264
 
279
- private findHoveredArea(x: number, y: number): HitArea | null {
280
- const dimensions = this.getTreeDimensions();
265
+ this.dragElement.remove();
266
+ this.dragElement = null;
267
+ }
281
268
 
282
- if (
283
- x < dimensions.left ||
284
- y < dimensions.top ||
285
- x > dimensions.right ||
286
- y > dimensions.bottom
287
- ) {
288
- return null;
289
- }
269
+ private findHoveredArea(x: number, y: number): HitArea | null {
270
+ const dimensions = this.getTreeDimensions();
290
271
 
291
- return binarySearch<HitArea>(this.hitAreas, (area) => {
292
- if (y < area.top) {
293
- return 1;
294
- } else if (y > area.bottom) {
295
- return -1;
296
- } else {
297
- return 0;
298
- }
299
- });
272
+ if (
273
+ x < dimensions.left ||
274
+ y < dimensions.top ||
275
+ x > dimensions.right ||
276
+ y > dimensions.bottom
277
+ ) {
278
+ return null;
300
279
  }
301
280
 
302
- private generateHitAreas(currentNode: Node): void {
303
- const tree = this.getTree();
304
-
305
- if (!tree) {
306
- this.hitAreas = [];
307
- } else {
308
- this.hitAreas = generateHitAreas(
309
- tree,
310
- currentNode,
311
- this.getTreeDimensions().bottom,
312
- );
313
- }
281
+ return binarySearch<HitArea>(this.hitAreas, (area) => {
282
+ if (y < area.top) {
283
+ return 1;
284
+ }
285
+ return y > area.bottom ? -1 : 0;
286
+ });
287
+ }
288
+
289
+ private generateHitAreas(currentNode: Node): void {
290
+ const tree = this.getTree();
291
+
292
+ this.hitAreas = tree
293
+ ? generateHitAreas(tree, currentNode, this.getTreeDimensions().bottom)
294
+ : [];
295
+ }
296
+
297
+ private getTreeDimensions(): Dimensions {
298
+ // Return the dimensions of the tree. Add a margin to the bottom to allow
299
+ // to drag-and-drop after the last element.
300
+ const treePosition = getElementPosition(this.treeElement);
301
+ const left = treePosition.left + this.getScrollLeft();
302
+ const top = treePosition.top;
303
+
304
+ return {
305
+ bottom: top + this.treeElement.clientHeight + 16,
306
+ left,
307
+ right: left + this.treeElement.clientWidth,
308
+ top,
309
+ };
310
+ }
311
+
312
+ /*
313
+ Move the dragged node to the selected position in the tree.
314
+ */
315
+ private moveItem(positionInfo: PositionInfo): void {
316
+ if (!(
317
+ this.currentItem &&
318
+ this.hoveredArea?.position &&
319
+ this.canMoveToArea(this.hoveredArea, this.currentItem)
320
+ )) {
321
+ return;
314
322
  }
315
323
 
316
- private getTreeDimensions(): Dimensions {
317
- // Return the dimensions of the tree. Add a margin to the bottom to allow
318
- // to drag-and-drop after the last element.
319
- const treePosition = getElementPosition(this.treeElement);
320
- const left = treePosition.left + this.getScrollLeft();
321
- const top = treePosition.top;
322
-
323
- return {
324
- bottom: top + this.treeElement.clientHeight + 16,
325
- left,
326
- right: left + this.treeElement.clientWidth,
327
- top,
328
- };
324
+ const movedNode = this.currentItem.node;
325
+ const targetNode = this.hoveredArea.node;
326
+ const position = this.hoveredArea.position;
327
+ const previousParent = movedNode.parent;
328
+
329
+ if (position === "inside") {
330
+ this.hoveredArea.node.is_open = true;
329
331
  }
330
332
 
331
- /* Move the dragged node to the selected position in the tree. */
332
- private moveItem(positionInfo: PositionInfo): void {
333
- if (
334
- this.currentItem &&
335
- this.hoveredArea?.position &&
336
- this.canMoveToArea(this.hoveredArea, this.currentItem)
337
- ) {
338
- const movedNode = this.currentItem.node;
339
- const targetNode = this.hoveredArea.node;
340
- const position = this.hoveredArea.position;
341
- const previousParent = movedNode.parent;
342
-
343
- if (position === "inside") {
344
- this.hoveredArea.node.is_open = true;
345
- }
346
-
347
- const doMove = (): void => {
348
- const tree = this.getTree();
349
-
350
- if (tree) {
351
- tree.moveNode(movedNode, targetNode, position);
352
-
353
- this.treeElement.textContent = "";
354
- this.refreshElements(null);
355
- }
356
- };
357
-
358
- if (this.triggerEvent("tree.move", {
359
- moveInfo: {
360
- doMove,
361
- movedNode,
362
- originalEvent: positionInfo.originalEvent,
363
- position,
364
- previousParent,
365
- targetNode,
366
- },
367
- })) {
368
- doMove();
369
- }
370
- }
333
+ const doMove = (): void => {
334
+ const tree = this.getTree();
335
+
336
+ if (!tree) {
337
+ return;
338
+ }
339
+
340
+ tree.moveNode(movedNode, targetNode, position);
341
+
342
+ this.treeElement.textContent = "";
343
+ this.refreshElements(null);
344
+ };
345
+
346
+ if (
347
+ this.triggerEvent("tree.move", {
348
+ moveInfo: {
349
+ doMove,
350
+ movedNode,
351
+ originalEvent: positionInfo.originalEvent,
352
+ position,
353
+ previousParent,
354
+ targetNode,
355
+ },
356
+ })
357
+ ) {
358
+ doMove();
371
359
  }
360
+ }
372
361
 
373
- private mustCaptureElement(element: HTMLElement): boolean {
374
- const nodeName = element.nodeName;
362
+ private mustCaptureElement(element: HTMLElement): boolean {
363
+ const nodeName = element.nodeName;
375
364
 
376
- return (
377
- nodeName !== "INPUT" &&
378
- nodeName !== "SELECT" &&
379
- nodeName !== "TEXTAREA"
380
- );
381
- }
365
+ return (
366
+ nodeName !== "INPUT" && nodeName !== "SELECT" && nodeName !== "TEXTAREA"
367
+ );
368
+ }
382
369
 
383
- private mustOpenFolderTimer(area: HitArea): boolean {
384
- const node = area.node;
370
+ private mustOpenFolderTimer(area: HitArea): boolean {
371
+ const node = area.node;
385
372
 
386
- return node.isFolder() && !node.is_open && area.position === "inside";
387
- }
373
+ return node.isFolder() && !node.is_open && area.position === "inside";
374
+ }
388
375
 
389
- private removeDropHint(): void {
390
- if (this.previousGhost) {
391
- this.previousGhost.remove();
392
- }
376
+ private removeDropHint(): void {
377
+ if (this.previousGhost) {
378
+ this.previousGhost.remove();
393
379
  }
380
+ }
394
381
 
395
- private removeHitAreas(): void {
396
- this.hitAreas = [];
397
- }
382
+ private removeHitAreas(): void {
383
+ this.hitAreas = [];
384
+ }
398
385
 
399
- private removeHover(): void {
400
- this.hoveredArea = null;
401
- }
386
+ private removeHover(): void {
387
+ this.hoveredArea = null;
388
+ }
402
389
 
403
- private startOpenFolderTimer(folder: Node): void {
404
- const openFolder = (): void => {
405
- void this.openNode(folder, this.slide).then(() => {
406
- this.refresh();
407
- this.updateDropHint();
408
- });
409
- };
390
+ private startOpenFolderTimer(folder: Node): void {
391
+ const openFolder = (): void => {
392
+ void this.openNode(folder, this.slide).then(() => {
393
+ this.refresh();
394
+ this.updateDropHint();
395
+ });
396
+ };
410
397
 
411
- this.stopOpenFolderTimer();
398
+ this.stopOpenFolderTimer();
412
399
 
413
- const openFolderDelay = this.openFolderDelay;
400
+ const openFolderDelay = this.openFolderDelay;
414
401
 
415
- if (openFolderDelay !== false) {
416
- this.openFolderTimer = window.setTimeout(
417
- openFolder,
418
- openFolderDelay,
419
- );
420
- }
402
+ if (openFolderDelay !== false) {
403
+ this.openFolderTimer = window.setTimeout(openFolder, openFolderDelay);
421
404
  }
405
+ }
422
406
 
423
- private stopOpenFolderTimer(): void {
424
- if (this.openFolderTimer) {
425
- clearTimeout(this.openFolderTimer);
426
- this.openFolderTimer = null;
427
- }
407
+ private stopOpenFolderTimer(): void {
408
+ if (!this.openFolderTimer) {
409
+ return;
428
410
  }
429
411
 
430
- private updateDropHint(): void {
431
- if (!this.hoveredArea) {
432
- return;
433
- }
434
-
435
- // remove previous drop hint
436
- this.removeDropHint();
412
+ clearTimeout(this.openFolderTimer);
413
+ this.openFolderTimer = null;
414
+ }
437
415
 
438
- // add new drop hint
439
- const nodeElement = this.getNodeElementForNode(this.hoveredArea.node);
440
- this.previousGhost = nodeElement.addDropHint(this.hoveredArea.position);
416
+ private updateDropHint(): void {
417
+ if (!this.hoveredArea) {
418
+ return;
441
419
  }
420
+
421
+ // remove previous drop hint
422
+ this.removeDropHint();
423
+
424
+ // add new drop hint
425
+ const nodeElement = this.getNodeElementForNode(this.hoveredArea.node);
426
+ this.previousGhost = nodeElement.addDropHint(this.hoveredArea.position);
427
+ }
442
428
  }