@limble/limble-tree 1.0.0-alpha.1 → 1.0.0-beta.1
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/README.md +450 -17
- package/esm2020/lib/components/branch/branch.component.mjs +7 -15
- package/esm2020/lib/components/dropzone/dropzone.component.mjs +2 -2
- package/esm2020/lib/components/root/root.component.mjs +3 -4
- package/esm2020/lib/core/branch-options.interface.mjs +1 -1
- package/esm2020/lib/core/configuration/configuration.mjs +1 -1
- package/esm2020/lib/core/configuration/tree-options.interface.mjs +1 -1
- package/esm2020/lib/core/index.mjs +1 -2
- package/esm2020/lib/core/relationship.interface.mjs +1 -1
- package/esm2020/lib/core/tree-branch/branch-controller.mjs +99 -0
- package/esm2020/lib/core/tree-branch/tree-branch.mjs +260 -106
- package/esm2020/lib/core/tree-node-base.mjs +10 -9
- package/esm2020/lib/core/tree-root/root-controller.mjs +42 -0
- package/esm2020/lib/core/tree-root/tree-root.mjs +138 -27
- package/esm2020/lib/core/tree-service/tree.service.mjs +7 -1
- package/esm2020/lib/events/drag/drag-end-event.mjs +9 -7
- package/esm2020/lib/events/drag/drag-start-event.mjs +2 -4
- package/esm2020/lib/events/drag/drop-event.mjs +2 -4
- package/esm2020/lib/events/general/destruction-event.mjs +10 -0
- package/esm2020/lib/events/general/index.mjs +2 -0
- package/esm2020/lib/events/index.mjs +2 -1
- package/esm2020/lib/events/relational/graft-event.mjs +2 -4
- package/esm2020/lib/events/relational/prune-event.mjs +2 -4
- package/esm2020/lib/events/relational/relational-tree-event.interface.mjs +1 -1
- package/esm2020/lib/extras/collapse/collapse.mjs +2 -2
- package/esm2020/lib/extras/collapse/collapse.module.mjs +2 -1
- package/esm2020/lib/extras/collapse/collapse.service.mjs +26 -1
- package/esm2020/lib/extras/drag-and-drop/drag-and-drop.mjs +6 -10
- package/esm2020/lib/extras/drag-and-drop/drag-and-drop.module.mjs +5 -1
- package/esm2020/lib/extras/drag-and-drop/drag-and-drop.service.mjs +21 -5
- package/esm2020/lib/extras/drag-and-drop/draggable.directive.mjs +7 -7
- package/esm2020/lib/extras/drag-and-drop/dragover-no-change-detect.mjs +10 -11
- package/esm2020/lib/extras/drag-and-drop/dropzone-renderer.mjs +9 -7
- package/esm2020/lib/legacy/legacy-component-obj.interface.mjs +1 -1
- package/esm2020/lib/legacy/legacy-tree-data.interface.mjs +1 -1
- package/esm2020/lib/legacy/legacy-tree-options.interface.mjs +1 -1
- package/esm2020/lib/legacy/legacy-tree.mjs +30 -30
- package/esm2020/lib/legacy/limble-tree-root/limble-tree-root.component.mjs +1 -1
- package/esm2020/lib/limble-tree.module.mjs +6 -2
- package/esm2020/lib/structure/branchable.interface.mjs +1 -1
- package/esm2020/lib/structure/component-container.interface.mjs +2 -0
- package/esm2020/lib/structure/index.mjs +2 -5
- package/esm2020/lib/structure/tree-branch-node.interface.mjs +1 -1
- package/esm2020/lib/structure/tree-event.interface.mjs +1 -1
- package/esm2020/lib/structure/tree-node.interface.mjs +1 -1
- package/esm2020/lib/structure/tree-relationship.interface.mjs +1 -1
- package/fesm2015/limble-limble-tree.mjs +821 -376
- package/fesm2015/limble-limble-tree.mjs.map +1 -1
- package/fesm2020/limble-limble-tree.mjs +819 -372
- package/fesm2020/limble-limble-tree.mjs.map +1 -1
- package/lib/core/branch-options.interface.d.ts +1 -1
- package/lib/core/configuration/configuration.d.ts +2 -2
- package/lib/core/configuration/tree-options.interface.d.ts +48 -29
- package/lib/core/index.d.ts +0 -1
- package/lib/core/relationship.interface.d.ts +2 -3
- package/lib/core/tree-branch/branch-controller.d.ts +25 -0
- package/lib/core/tree-branch/tree-branch.d.ts +199 -24
- package/lib/core/tree-node-base.d.ts +4 -5
- package/lib/core/tree-root/root-controller.d.ts +19 -0
- package/lib/core/tree-root/tree-root.d.ts +109 -14
- package/lib/core/tree-service/tree.service.d.ts +8 -2
- package/lib/events/drag/drag-end-event.d.ts +15 -13
- package/lib/events/drag/drag-start-event.d.ts +6 -5
- package/lib/events/drag/drop-event.d.ts +7 -10
- package/lib/events/general/destruction-event.d.ts +8 -0
- package/lib/events/general/index.d.ts +1 -0
- package/lib/events/index.d.ts +1 -0
- package/lib/events/relational/graft-event.d.ts +5 -6
- package/lib/events/relational/prune-event.d.ts +5 -6
- package/lib/events/relational/relational-tree-event.interface.d.ts +5 -1
- package/lib/extras/collapse/collapse.module.d.ts +1 -0
- package/lib/extras/collapse/collapse.service.d.ts +25 -0
- package/lib/extras/drag-and-drop/drag-and-drop.d.ts +2 -3
- package/lib/extras/drag-and-drop/drag-and-drop.module.d.ts +4 -0
- package/lib/extras/drag-and-drop/drag-and-drop.service.d.ts +22 -3
- package/lib/extras/drag-and-drop/draggable.directive.d.ts +4 -5
- package/lib/extras/drag-and-drop/dragover-no-change-detect.d.ts +7 -3
- package/lib/legacy/legacy-component-obj.interface.d.ts +1 -1
- package/lib/legacy/legacy-tree-data.interface.d.ts +1 -1
- package/lib/legacy/legacy-tree-options.interface.d.ts +2 -2
- package/lib/legacy/legacy-tree.d.ts +4 -4
- package/lib/legacy/limble-tree-root/limble-tree-root.component.d.ts +4 -4
- package/lib/limble-tree.module.d.ts +4 -0
- package/lib/structure/branchable.interface.d.ts +0 -1
- package/lib/structure/component-container.interface.d.ts +8 -0
- package/lib/structure/index.d.ts +1 -4
- package/lib/structure/tree-branch-node.interface.d.ts +3 -3
- package/lib/structure/tree-event.interface.d.ts +3 -3
- package/lib/structure/tree-node.interface.d.ts +11 -6
- package/lib/structure/tree-relationship.interface.d.ts +2 -2
- package/package.json +1 -1
- package/esm2020/lib/structure/container-tree-node.interface.mjs +0 -2
- package/esm2020/lib/structure/content-container.interface.mjs +0 -2
- package/esm2020/lib/structure/event-conduit.interface.mjs +0 -2
- package/esm2020/lib/structure/tree-root.node.interface.mjs +0 -2
- package/lib/structure/container-tree-node.interface.d.ts +0 -3
- package/lib/structure/content-container.interface.d.ts +0 -3
- package/lib/structure/event-conduit.interface.d.ts +0 -6
- package/lib/structure/tree-root.node.interface.d.ts +0 -2
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable, NgModule, EventEmitter, Directive,
|
|
3
|
-
import { BehaviorSubject,
|
|
2
|
+
import { Injectable, NgModule, EventEmitter, Directive, Output, Component, Input, NgZone, ViewContainerRef, ViewChild, ViewChildren, createComponent, EnvironmentInjector, HostListener } from '@angular/core';
|
|
3
|
+
import { BehaviorSubject, fromEvent, merge, map, Subject, filter, first } from 'rxjs';
|
|
4
4
|
import * as i1 from '@angular/common';
|
|
5
5
|
import { CommonModule } from '@angular/common';
|
|
6
|
-
import { throttleTime } from 'rxjs/operators';
|
|
7
6
|
|
|
8
7
|
class TreeCollapser {
|
|
9
8
|
constructor() {
|
|
@@ -27,7 +26,7 @@ class TreeCollapser {
|
|
|
27
26
|
branch.graftTo(treeBranch);
|
|
28
27
|
});
|
|
29
28
|
this.tempStorage.delete(treeBranch);
|
|
30
|
-
treeBranch.
|
|
29
|
+
treeBranch.detectChanges();
|
|
31
30
|
}
|
|
32
31
|
isCollapsed(treeBranch) {
|
|
33
32
|
return this.tempStorage.has(treeBranch);
|
|
@@ -39,13 +38,38 @@ class TreeCollapser {
|
|
|
39
38
|
}
|
|
40
39
|
const treeCollapser = new TreeCollapser();
|
|
41
40
|
|
|
41
|
+
/** A service that collapses and expands tree branches */
|
|
42
42
|
class TreeCollapseService {
|
|
43
|
+
/**
|
|
44
|
+
* Causes a TreeBranch to collapse, temporarily pruning all of its children
|
|
45
|
+
* from the tree.
|
|
46
|
+
*
|
|
47
|
+
* @param treeBranch - The branch to collapse.
|
|
48
|
+
*/
|
|
43
49
|
collapse(treeBranch) {
|
|
44
50
|
treeCollapser.collapse(treeBranch);
|
|
45
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Causes a TreeBranch to expand, restoring all of its children which were
|
|
54
|
+
* previously pruned by a call to `collapse()`.
|
|
55
|
+
*
|
|
56
|
+
* @param treeBranch - The branch to expand.
|
|
57
|
+
*/
|
|
46
58
|
expand(treeBranch) {
|
|
47
59
|
treeCollapser.expand(treeBranch);
|
|
48
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Determines whether a TreeBranch currently has any children which are
|
|
63
|
+
* pruned from the tree due to a call to the `collapse()` method.
|
|
64
|
+
*
|
|
65
|
+
* @remarks
|
|
66
|
+
* Child branches which are pruned manually from the tree, rather than
|
|
67
|
+
* through the `collapse()` method, will not be considered.
|
|
68
|
+
*
|
|
69
|
+
* @param treeBranch - The branch to check.
|
|
70
|
+
*
|
|
71
|
+
* @returns `true` if the branch is currently collapsed; `false` if it is not.
|
|
72
|
+
*/
|
|
49
73
|
isCollapsed(treeBranch) {
|
|
50
74
|
return treeCollapser.isCollapsed(treeBranch);
|
|
51
75
|
}
|
|
@@ -56,6 +80,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
|
|
|
56
80
|
type: Injectable
|
|
57
81
|
}] });
|
|
58
82
|
|
|
83
|
+
/** A module containing the entities which provide collapse functionality */
|
|
59
84
|
class TreeCollapseModule {
|
|
60
85
|
}
|
|
61
86
|
TreeCollapseModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: TreeCollapseModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
@@ -68,66 +93,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
|
|
|
68
93
|
}]
|
|
69
94
|
}] });
|
|
70
95
|
|
|
71
|
-
class Configuration {
|
|
72
|
-
constructor() {
|
|
73
|
-
this.configStorage = new Map();
|
|
74
|
-
this.configStorage = new Map();
|
|
75
|
-
}
|
|
76
|
-
setConfig(root, options) {
|
|
77
|
-
this.configStorage.set(root, options);
|
|
78
|
-
}
|
|
79
|
-
getConfig(root) {
|
|
80
|
-
return this.configStorage.get(root);
|
|
81
|
-
}
|
|
82
|
-
delete(root) {
|
|
83
|
-
this.configStorage.delete(root);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
const config = new Configuration();
|
|
87
|
-
|
|
88
|
-
class TreeError extends Error {
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
class DragEndEvent {
|
|
92
|
-
constructor(source, endpoints) {
|
|
93
|
-
this._source = source;
|
|
94
|
-
this._oldParent = endpoints.oldParent;
|
|
95
|
-
this._oldIndex = endpoints.oldIndex;
|
|
96
|
-
this._newParent = endpoints.newParent;
|
|
97
|
-
this._newIndex = endpoints.newIndex;
|
|
98
|
-
}
|
|
99
|
-
type() {
|
|
100
|
-
return "drag end";
|
|
101
|
-
}
|
|
102
|
-
source() {
|
|
103
|
-
return this._source;
|
|
104
|
-
}
|
|
105
|
-
newIndex() {
|
|
106
|
-
return this._newIndex;
|
|
107
|
-
}
|
|
108
|
-
newParent() {
|
|
109
|
-
return this._newParent;
|
|
110
|
-
}
|
|
111
|
-
oldIndex() {
|
|
112
|
-
return this._oldIndex;
|
|
113
|
-
}
|
|
114
|
-
oldParent() {
|
|
115
|
-
return this._oldParent;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
class DragStartEvent {
|
|
120
|
-
constructor(source) {
|
|
121
|
-
this._source = source;
|
|
122
|
-
}
|
|
123
|
-
type() {
|
|
124
|
-
return "drag start";
|
|
125
|
-
}
|
|
126
|
-
source() {
|
|
127
|
-
return this._source;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
96
|
function assert(condition) {
|
|
132
97
|
if (condition) {
|
|
133
98
|
return;
|
|
@@ -180,120 +145,20 @@ class DragState {
|
|
|
180
145
|
}
|
|
181
146
|
const dragState = new DragState();
|
|
182
147
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
}
|
|
189
|
-
type() {
|
|
190
|
-
return "drag end";
|
|
191
|
-
}
|
|
192
|
-
source() {
|
|
193
|
-
return this._source;
|
|
194
|
-
}
|
|
195
|
-
index() {
|
|
196
|
-
return this._index;
|
|
197
|
-
}
|
|
198
|
-
parent() {
|
|
199
|
-
return this._parent;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
class DragAndDrop {
|
|
204
|
-
constructor() {
|
|
205
|
-
this.dragAborted$ = new Subject();
|
|
206
|
-
}
|
|
207
|
-
dragStart(treeBranch, event) {
|
|
208
|
-
if (!this.draggingAllowed(treeBranch)) {
|
|
209
|
-
event.preventDefault();
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
treeBranch.dispatch(new DragStartEvent(treeBranch));
|
|
213
|
-
this.setDragEffects(treeBranch, event);
|
|
214
|
-
this.watchForDragend(treeBranch, event);
|
|
215
|
-
// We have to do a setTimeout because DOM changes are not allowed during a
|
|
216
|
-
// dragstart event.
|
|
217
|
-
setTimeout(() => {
|
|
218
|
-
dragState.starting(treeBranch);
|
|
219
|
-
treeBranch.prune();
|
|
220
|
-
dragState.dragging();
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
drop(parent, index) {
|
|
224
|
-
const treeBranch = dragState.getDragData();
|
|
225
|
-
if (treeBranch === undefined) {
|
|
226
|
-
throw new TreeError("Cannot get dragged branch");
|
|
227
|
-
}
|
|
228
|
-
this.graftDraggedBranch(treeBranch, parent, index);
|
|
229
|
-
treeBranch.dispatch(new DropEvent(treeBranch, parent, index));
|
|
230
|
-
}
|
|
231
|
-
getDragImageOffsets(event, element) {
|
|
232
|
-
const bounds = element.getBoundingClientRect();
|
|
233
|
-
const xOffset = event.clientX - bounds.left;
|
|
234
|
-
const yOffset = event.clientY - bounds.top;
|
|
235
|
-
return [xOffset, yOffset];
|
|
236
|
-
}
|
|
237
|
-
setDragEffects(treeBranch, event) {
|
|
238
|
-
const dataTransfer = event.dataTransfer;
|
|
239
|
-
if (!(dataTransfer instanceof DataTransfer)) {
|
|
240
|
-
throw new Error("bad drag event");
|
|
241
|
-
}
|
|
242
|
-
const nativeElement = treeBranch.getContents().location.nativeElement;
|
|
243
|
-
const [xOffset, yOffset] = this.getDragImageOffsets(event, nativeElement);
|
|
244
|
-
dataTransfer.setDragImage(nativeElement, xOffset, yOffset);
|
|
245
|
-
}
|
|
246
|
-
watchForDragend(treeBranch, event) {
|
|
247
|
-
var _a;
|
|
248
|
-
const oldParent = treeBranch.parent();
|
|
249
|
-
const oldIndex = treeBranch.index();
|
|
250
|
-
if (oldParent === undefined || oldIndex === undefined) {
|
|
251
|
-
throw new Error("branch must have a parent");
|
|
252
|
-
}
|
|
253
|
-
(_a = event.target) === null || _a === void 0 ? void 0 : _a.addEventListener("dragend", (dragend) => {
|
|
254
|
-
if (dragState.state() !== DragStates.Dropped) {
|
|
255
|
-
//The drag ended but a drop never occurred, so put the dragged branch back where it started.
|
|
256
|
-
this.dragAborted$.next(dragend);
|
|
257
|
-
this.graftDraggedBranch(treeBranch, oldParent, oldIndex);
|
|
258
|
-
}
|
|
259
|
-
dragState.restart();
|
|
260
|
-
const newParent = treeBranch.parent();
|
|
261
|
-
assert(newParent !== undefined);
|
|
262
|
-
const newIndex = treeBranch.index();
|
|
263
|
-
assert(newIndex !== undefined);
|
|
264
|
-
treeBranch.dispatch(new DragEndEvent(treeBranch, {
|
|
265
|
-
oldParent,
|
|
266
|
-
oldIndex,
|
|
267
|
-
newParent,
|
|
268
|
-
newIndex
|
|
269
|
-
}));
|
|
270
|
-
}, { once: true });
|
|
271
|
-
}
|
|
272
|
-
draggingAllowed(treeBranch) {
|
|
273
|
-
var _a, _b;
|
|
274
|
-
const allowDragging = (_b = (_a = config.getConfig(treeBranch.root())) === null || _a === void 0 ? void 0 : _a.allowDragging) !== null && _b !== void 0 ? _b : (() => true);
|
|
275
|
-
return allowDragging(treeBranch);
|
|
276
|
-
}
|
|
277
|
-
graftDraggedBranch(treeBranch, parent, index) {
|
|
278
|
-
treeBranch.graftTo(parent, index);
|
|
279
|
-
treeBranch.getContents().location.nativeElement.style.display = "block";
|
|
280
|
-
dragState.dropped();
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
const dragAndDrop = new DragAndDrop();
|
|
284
|
-
|
|
148
|
+
/**
|
|
149
|
+
* Works just like Angular's built-in `(dragover)` event binding, but is much
|
|
150
|
+
* more performant. It throttles the event to a configurable rate (default once
|
|
151
|
+
* every 25ms) and runs outside of Angular's change detection.
|
|
152
|
+
*/
|
|
285
153
|
class DragoverNoChangeDetectDirective {
|
|
286
154
|
constructor(ngZone, el) {
|
|
287
155
|
this.ngZone = ngZone;
|
|
288
156
|
this.el = el;
|
|
289
157
|
this.dragoverNoChangeDetect = new EventEmitter();
|
|
290
|
-
this.dragoverEventThrottle = 25;
|
|
291
158
|
}
|
|
292
159
|
ngOnInit() {
|
|
293
160
|
this.ngZone.runOutsideAngular(() => {
|
|
294
|
-
this.eventSubscription = fromEvent(this.el.nativeElement, "dragover")
|
|
295
|
-
.pipe(throttleTime(this.dragoverEventThrottle))
|
|
296
|
-
.subscribe(($event) => {
|
|
161
|
+
this.eventSubscription = fromEvent(this.el.nativeElement, "dragover").subscribe(($event) => {
|
|
297
162
|
this.dragoverNoChangeDetect.emit($event);
|
|
298
163
|
});
|
|
299
164
|
});
|
|
@@ -305,16 +170,14 @@ class DragoverNoChangeDetectDirective {
|
|
|
305
170
|
}
|
|
306
171
|
}
|
|
307
172
|
DragoverNoChangeDetectDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: DragoverNoChangeDetectDirective, deps: [{ token: i0.NgZone }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
308
|
-
DragoverNoChangeDetectDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.12", type: DragoverNoChangeDetectDirective, isStandalone: true, selector: "[dragoverNoChangeDetect]",
|
|
173
|
+
DragoverNoChangeDetectDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.12", type: DragoverNoChangeDetectDirective, isStandalone: true, selector: "[dragoverNoChangeDetect]", outputs: { dragoverNoChangeDetect: "dragoverNoChangeDetect" }, ngImport: i0 });
|
|
309
174
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: DragoverNoChangeDetectDirective, decorators: [{
|
|
310
175
|
type: Directive,
|
|
311
176
|
args: [{
|
|
312
177
|
standalone: true,
|
|
313
178
|
selector: "[dragoverNoChangeDetect]"
|
|
314
179
|
}]
|
|
315
|
-
}], ctorParameters: function () { return [{ type: i0.NgZone }, { type: i0.ElementRef }]; }, propDecorators: {
|
|
316
|
-
type: Input
|
|
317
|
-
}], dragoverNoChangeDetect: [{
|
|
180
|
+
}], ctorParameters: function () { return [{ type: i0.NgZone }, { type: i0.ElementRef }]; }, propDecorators: { dragoverNoChangeDetect: [{
|
|
318
181
|
type: Output
|
|
319
182
|
}] } });
|
|
320
183
|
|
|
@@ -338,10 +201,10 @@ class DropzoneComponent {
|
|
|
338
201
|
}
|
|
339
202
|
}
|
|
340
203
|
DropzoneComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: DropzoneComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
341
|
-
DropzoneComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: DropzoneComponent, isStandalone: true, selector: "dropzone", inputs: { placement: "placement" }, outputs: { dropped: "dropped" }, ngImport: i0, template: "<div\n class=\"dropzone\"\n [ngClass]=\"{ active: active }\"\n (dragenter)=\"dragenterHandler()\"\n (dragleave)=\"dragleaveHandler()\"\n (dragoverNoChangeDetect)=\"dragoverHandler($event)\"\n (drop)=\"dropHandler($event)\"\n></div>\n", styles: [".dropzone{border-radius:8px;border:1px dashed #727374;background-color:#ededed;height:
|
|
204
|
+
DropzoneComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: DropzoneComponent, isStandalone: true, selector: "dropzone", inputs: { placement: "placement" }, outputs: { dropped: "dropped" }, ngImport: i0, template: "<div\n class=\"dropzone\"\n [ngClass]=\"{ active: active }\"\n (dragenter)=\"dragenterHandler()\"\n (dragleave)=\"dragleaveHandler()\"\n (dragoverNoChangeDetect)=\"dragoverHandler($event)\"\n (drop)=\"dropHandler($event)\"\n></div>\n", styles: [".dropzone{border-radius:8px;border:1px dashed #727374;background-color:#ededed;height:36px;margin:8px 0;transition:height .3s ease-out;animation:animation .3s ease-out}.dropzone.active{border-color:#289e49;border-width:2px;background-color:#d0e8d6;height:72px}@keyframes animation{0%{height:0px;opacity:0}to{height:36px;opacity:1}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: DragoverNoChangeDetectDirective, selector: "[dragoverNoChangeDetect]", outputs: ["dragoverNoChangeDetect"] }] });
|
|
342
205
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: DropzoneComponent, decorators: [{
|
|
343
206
|
type: Component,
|
|
344
|
-
args: [{ standalone: true, selector: "dropzone", imports: [CommonModule, DragoverNoChangeDetectDirective], template: "<div\n class=\"dropzone\"\n [ngClass]=\"{ active: active }\"\n (dragenter)=\"dragenterHandler()\"\n (dragleave)=\"dragleaveHandler()\"\n (dragoverNoChangeDetect)=\"dragoverHandler($event)\"\n (drop)=\"dropHandler($event)\"\n></div>\n", styles: [".dropzone{border-radius:8px;border:1px dashed #727374;background-color:#ededed;height:
|
|
207
|
+
args: [{ standalone: true, selector: "dropzone", imports: [CommonModule, DragoverNoChangeDetectDirective], template: "<div\n class=\"dropzone\"\n [ngClass]=\"{ active: active }\"\n (dragenter)=\"dragenterHandler()\"\n (dragleave)=\"dragleaveHandler()\"\n (dragoverNoChangeDetect)=\"dragoverHandler($event)\"\n (drop)=\"dropHandler($event)\"\n></div>\n", styles: [".dropzone{border-radius:8px;border:1px dashed #727374;background-color:#ededed;height:36px;margin:8px 0;transition:height .3s ease-out;animation:animation .3s ease-out}.dropzone.active{border-color:#289e49;border-width:2px;background-color:#d0e8d6;height:72px}@keyframes animation{0%{height:0px;opacity:0}to{height:36px;opacity:1}}\n"] }]
|
|
345
208
|
}], propDecorators: { placement: [{
|
|
346
209
|
type: Input
|
|
347
210
|
}], dropped: [{
|
|
@@ -361,22 +224,14 @@ class BranchComponent {
|
|
|
361
224
|
this.showLateralDropzone = false;
|
|
362
225
|
}
|
|
363
226
|
ngAfterViewInit() {
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
}
|
|
367
|
-
if (this.contentToHost === undefined) {
|
|
368
|
-
throw new TreeError("'content' is a required input");
|
|
369
|
-
}
|
|
227
|
+
assert(this.contentContainer !== undefined);
|
|
228
|
+
assert(this.contentToHost !== undefined);
|
|
370
229
|
this.hostedContent = this.contentContainer.createComponent(this.contentToHost);
|
|
371
230
|
this.contentCreated.emit(this.hostedContent.instance);
|
|
372
|
-
|
|
373
|
-
throw new Error("querylist not defined");
|
|
374
|
-
}
|
|
231
|
+
assert(this.dropzones !== undefined);
|
|
375
232
|
const inner = this.dropzones.get(0);
|
|
376
233
|
const lateral = this.dropzones.get(1);
|
|
377
|
-
|
|
378
|
-
throw new Error("dropzones not defined");
|
|
379
|
-
}
|
|
234
|
+
assert(inner !== undefined && lateral !== undefined);
|
|
380
235
|
merge(inner.dropped.pipe(map(() => "inner")), lateral.dropped.pipe(map(() => "lateral"))).subscribe(this.dropped);
|
|
381
236
|
this.hostedContent.changeDetectorRef.detectChanges();
|
|
382
237
|
}
|
|
@@ -405,7 +260,7 @@ class BranchComponent {
|
|
|
405
260
|
}
|
|
406
261
|
}
|
|
407
262
|
BranchComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BranchComponent, deps: [{ token: i0.ApplicationRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
408
|
-
BranchComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: BranchComponent, isStandalone: true, selector: "branch", inputs: { contentToHost: "contentToHost" }, outputs: { contentCreated: "contentCreated", showDropzones: "showDropzones", dropped: "dropped" }, viewQueries: [{ propertyName: "branchesContainer", first: true, predicate: ["branchesContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "contentContainer", first: true, predicate: ["contentContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "dropzones", predicate: DropzoneComponent, descendants: true }], ngImport: i0, template: "<div class=\"content\" (dragoverNoChangeDetect)=\"dragoverHandler($event)\">\n <div #contentContainer></div>\n</div>\n<div class=\"branches-container\">\n <dropzone placement=\"inner\" [hidden]=\"!showInnerDropzone\"></dropzone>\n <div #branchesContainer></div>\n</div>\n<dropzone placement=\"lateral\" [hidden]=\"!showLateralDropzone\"></dropzone>\n", styles: [".branches-container{margin-left:16px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DropzoneComponent, selector: "dropzone", inputs: ["placement"], outputs: ["dropped"] }, { kind: "directive", type: DragoverNoChangeDetectDirective, selector: "[dragoverNoChangeDetect]",
|
|
263
|
+
BranchComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: BranchComponent, isStandalone: true, selector: "branch", inputs: { contentToHost: "contentToHost" }, outputs: { contentCreated: "contentCreated", showDropzones: "showDropzones", dropped: "dropped" }, viewQueries: [{ propertyName: "branchesContainer", first: true, predicate: ["branchesContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "contentContainer", first: true, predicate: ["contentContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "dropzones", predicate: DropzoneComponent, descendants: true }], ngImport: i0, template: "<div class=\"content\" (dragoverNoChangeDetect)=\"dragoverHandler($event)\">\n <div #contentContainer></div>\n</div>\n<div class=\"branches-container\">\n <dropzone placement=\"inner\" [hidden]=\"!showInnerDropzone\"></dropzone>\n <div #branchesContainer></div>\n</div>\n<dropzone placement=\"lateral\" [hidden]=\"!showLateralDropzone\"></dropzone>\n", styles: [".branches-container{margin-left:16px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DropzoneComponent, selector: "dropzone", inputs: ["placement"], outputs: ["dropped"] }, { kind: "directive", type: DragoverNoChangeDetectDirective, selector: "[dragoverNoChangeDetect]", outputs: ["dragoverNoChangeDetect"] }] });
|
|
409
264
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BranchComponent, decorators: [{
|
|
410
265
|
type: Component,
|
|
411
266
|
args: [{ standalone: true, selector: "branch", imports: [CommonModule, DropzoneComponent, DragoverNoChangeDetectDirective], template: "<div class=\"content\" (dragoverNoChangeDetect)=\"dragoverHandler($event)\">\n <div #contentContainer></div>\n</div>\n<div class=\"branches-container\">\n <dropzone placement=\"inner\" [hidden]=\"!showInnerDropzone\"></dropzone>\n <div #branchesContainer></div>\n</div>\n<dropzone placement=\"lateral\" [hidden]=\"!showLateralDropzone\"></dropzone>\n", styles: [".branches-container{margin-left:16px}\n"] }]
|
|
@@ -428,6 +283,163 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
|
|
|
428
283
|
type: Output
|
|
429
284
|
}] } });
|
|
430
285
|
|
|
286
|
+
class Configuration {
|
|
287
|
+
constructor() {
|
|
288
|
+
this.configStorage = new Map();
|
|
289
|
+
this.configStorage = new Map();
|
|
290
|
+
}
|
|
291
|
+
setConfig(root, options) {
|
|
292
|
+
this.configStorage.set(root, options);
|
|
293
|
+
}
|
|
294
|
+
getConfig(root) {
|
|
295
|
+
return this.configStorage.get(root);
|
|
296
|
+
}
|
|
297
|
+
delete(root) {
|
|
298
|
+
this.configStorage.delete(root);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
const config = new Configuration();
|
|
302
|
+
|
|
303
|
+
class TreeError extends Error {
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/** Emitted when a drag-and-drop operation has completed */
|
|
307
|
+
class DragEndEvent {
|
|
308
|
+
constructor(source, endpoints) {
|
|
309
|
+
this._source = source;
|
|
310
|
+
this._oldParent = endpoints.oldParent;
|
|
311
|
+
this._oldIndex = endpoints.oldIndex;
|
|
312
|
+
this._newParent = endpoints.newParent;
|
|
313
|
+
this._newIndex = endpoints.newIndex;
|
|
314
|
+
}
|
|
315
|
+
/** @returns The new index of the dropped branch */
|
|
316
|
+
newIndex() {
|
|
317
|
+
return this._newIndex;
|
|
318
|
+
}
|
|
319
|
+
/** @returns The new parent of the dropped branch */
|
|
320
|
+
newParent() {
|
|
321
|
+
return this._newParent;
|
|
322
|
+
}
|
|
323
|
+
/** @returns The index of the dropped branch before it was dragged */
|
|
324
|
+
oldIndex() {
|
|
325
|
+
return this._oldIndex;
|
|
326
|
+
}
|
|
327
|
+
/** @returns The parent of the dropped branch before it was dragged */
|
|
328
|
+
oldParent() {
|
|
329
|
+
return this._oldParent;
|
|
330
|
+
}
|
|
331
|
+
source() {
|
|
332
|
+
return this._source;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/** Emitted when a TreeBranch begins being dragged */
|
|
337
|
+
class DragStartEvent {
|
|
338
|
+
constructor(source) {
|
|
339
|
+
this._source = source;
|
|
340
|
+
}
|
|
341
|
+
source() {
|
|
342
|
+
return this._source;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/** Emitted when a TreeBranch is dropped into a valid Dropzone */
|
|
347
|
+
class DropEvent {
|
|
348
|
+
constructor(source, parent, index) {
|
|
349
|
+
this._source = source;
|
|
350
|
+
this._parent = parent;
|
|
351
|
+
this._index = index;
|
|
352
|
+
}
|
|
353
|
+
source() {
|
|
354
|
+
return this._source;
|
|
355
|
+
}
|
|
356
|
+
index() {
|
|
357
|
+
return this._index;
|
|
358
|
+
}
|
|
359
|
+
parent() {
|
|
360
|
+
return this._parent;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
class DragAndDrop {
|
|
365
|
+
constructor() {
|
|
366
|
+
this.dragAborted$ = new Subject();
|
|
367
|
+
}
|
|
368
|
+
dragStart(treeBranch, event) {
|
|
369
|
+
if (!this.draggingAllowed(treeBranch)) {
|
|
370
|
+
event.preventDefault();
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
treeBranch.dispatch(new DragStartEvent(treeBranch));
|
|
374
|
+
this.setDragEffects(treeBranch, event);
|
|
375
|
+
this.watchForDragend(treeBranch, event);
|
|
376
|
+
// We have to do a setTimeout because DOM changes are not allowed during a
|
|
377
|
+
// dragstart event.
|
|
378
|
+
setTimeout(() => {
|
|
379
|
+
dragState.starting(treeBranch);
|
|
380
|
+
treeBranch.prune();
|
|
381
|
+
dragState.dragging();
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
drop(parent, index) {
|
|
385
|
+
const treeBranch = dragState.getDragData();
|
|
386
|
+
if (treeBranch === undefined) {
|
|
387
|
+
throw new TreeError("Cannot get dragged branch");
|
|
388
|
+
}
|
|
389
|
+
this.graftDraggedBranch(treeBranch, parent, index);
|
|
390
|
+
treeBranch.dispatch(new DropEvent(treeBranch, parent, index));
|
|
391
|
+
}
|
|
392
|
+
getDragImageOffsets(event, element) {
|
|
393
|
+
const bounds = element.getBoundingClientRect();
|
|
394
|
+
const xOffset = event.clientX - bounds.left;
|
|
395
|
+
const yOffset = event.clientY - bounds.top;
|
|
396
|
+
return [xOffset, yOffset];
|
|
397
|
+
}
|
|
398
|
+
setDragEffects(treeBranch, event) {
|
|
399
|
+
const dataTransfer = event.dataTransfer;
|
|
400
|
+
assert(dataTransfer instanceof DataTransfer);
|
|
401
|
+
const nativeElement = treeBranch.getNativeElement();
|
|
402
|
+
const [xOffset, yOffset] = this.getDragImageOffsets(event, nativeElement);
|
|
403
|
+
dataTransfer.setDragImage(nativeElement, xOffset, yOffset);
|
|
404
|
+
}
|
|
405
|
+
watchForDragend(treeBranch, event) {
|
|
406
|
+
var _a;
|
|
407
|
+
const oldParent = treeBranch.parent();
|
|
408
|
+
const oldIndex = treeBranch.index();
|
|
409
|
+
assert(oldParent !== undefined && oldIndex !== undefined);
|
|
410
|
+
(_a = event.target) === null || _a === void 0 ? void 0 : _a.addEventListener("dragend", (dragend) => {
|
|
411
|
+
if (dragState.state() !== DragStates.Dropped) {
|
|
412
|
+
//The drag ended but a drop never occurred, so put the dragged branch back where it started.
|
|
413
|
+
this.dragAborted$.next(dragend);
|
|
414
|
+
this.graftDraggedBranch(treeBranch, oldParent, oldIndex);
|
|
415
|
+
}
|
|
416
|
+
dragState.restart();
|
|
417
|
+
const newParent = treeBranch.parent();
|
|
418
|
+
assert(newParent !== undefined);
|
|
419
|
+
const newIndex = treeBranch.index();
|
|
420
|
+
assert(newIndex !== undefined);
|
|
421
|
+
treeBranch.dispatch(new DragEndEvent(treeBranch, {
|
|
422
|
+
oldParent,
|
|
423
|
+
oldIndex,
|
|
424
|
+
newParent,
|
|
425
|
+
newIndex
|
|
426
|
+
}));
|
|
427
|
+
}, { once: true });
|
|
428
|
+
}
|
|
429
|
+
draggingAllowed(treeBranch) {
|
|
430
|
+
var _a, _b, _c;
|
|
431
|
+
const allowDragging = (_c = (_b = (_a = config.getConfig(treeBranch.root())) === null || _a === void 0 ? void 0 : _a.dragAndDrop) === null || _b === void 0 ? void 0 : _b.allowDragging) !== null && _c !== void 0 ? _c : (() => true);
|
|
432
|
+
return allowDragging(treeBranch);
|
|
433
|
+
}
|
|
434
|
+
graftDraggedBranch(treeBranch, parent, index) {
|
|
435
|
+
treeBranch.graftTo(parent, index);
|
|
436
|
+
treeBranch.getNativeElement().style.display = "block";
|
|
437
|
+
dragState.dropped();
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
const dragAndDrop = new DragAndDrop();
|
|
441
|
+
|
|
442
|
+
/** Emits when a branch is grafted to another tree node */
|
|
431
443
|
class GraftEvent {
|
|
432
444
|
constructor(source, relationship) {
|
|
433
445
|
this._source = source;
|
|
@@ -438,9 +450,6 @@ class GraftEvent {
|
|
|
438
450
|
child() {
|
|
439
451
|
return this._child;
|
|
440
452
|
}
|
|
441
|
-
type() {
|
|
442
|
-
return "graft";
|
|
443
|
-
}
|
|
444
453
|
index() {
|
|
445
454
|
return this._index;
|
|
446
455
|
}
|
|
@@ -452,6 +461,7 @@ class GraftEvent {
|
|
|
452
461
|
}
|
|
453
462
|
}
|
|
454
463
|
|
|
464
|
+
/** Emitted when a branch is pruned from its parent branch */
|
|
455
465
|
class PruneEvent {
|
|
456
466
|
constructor(source, relationship) {
|
|
457
467
|
this._source = source;
|
|
@@ -462,9 +472,6 @@ class PruneEvent {
|
|
|
462
472
|
child() {
|
|
463
473
|
return this._child;
|
|
464
474
|
}
|
|
465
|
-
type() {
|
|
466
|
-
return "prune";
|
|
467
|
-
}
|
|
468
475
|
index() {
|
|
469
476
|
return this._index;
|
|
470
477
|
}
|
|
@@ -478,6 +485,7 @@ class PruneEvent {
|
|
|
478
485
|
|
|
479
486
|
class TreeNodeBase {
|
|
480
487
|
constructor() {
|
|
488
|
+
this.destroyed = false;
|
|
481
489
|
this._branches = [];
|
|
482
490
|
this.events$ = new Subject();
|
|
483
491
|
this.subscriptions = [
|
|
@@ -492,17 +500,14 @@ class TreeNodeBase {
|
|
|
492
500
|
branches() {
|
|
493
501
|
return [...this._branches];
|
|
494
502
|
}
|
|
495
|
-
deleteBranch(index) {
|
|
496
|
-
if (index === undefined) {
|
|
497
|
-
this._branches.pop();
|
|
498
|
-
return;
|
|
499
|
-
}
|
|
500
|
-
this._branches.splice(index, 1);
|
|
501
|
-
}
|
|
502
503
|
destroy() {
|
|
504
|
+
this.branches().forEach((branch) => {
|
|
505
|
+
branch.destroy();
|
|
506
|
+
});
|
|
503
507
|
this.subscriptions.forEach((sub) => {
|
|
504
508
|
sub.unsubscribe();
|
|
505
509
|
});
|
|
510
|
+
this.destroyed = true;
|
|
506
511
|
}
|
|
507
512
|
dispatch(event) {
|
|
508
513
|
this.events$.next(event);
|
|
@@ -513,6 +518,9 @@ class TreeNodeBase {
|
|
|
513
518
|
getBranch(index) {
|
|
514
519
|
return this._branches[index];
|
|
515
520
|
}
|
|
521
|
+
isDestroyed() {
|
|
522
|
+
return this.destroyed;
|
|
523
|
+
}
|
|
516
524
|
plot() {
|
|
517
525
|
return new Map(this.branches().map((branch, index) => [index, branch.plot()]));
|
|
518
526
|
}
|
|
@@ -523,7 +531,7 @@ class TreeNodeBase {
|
|
|
523
531
|
}
|
|
524
532
|
deregisterChildRelationship(child) {
|
|
525
533
|
const index = this.branches().findIndex((branch) => branch === child);
|
|
526
|
-
this.
|
|
534
|
+
this._branches.splice(index, 1);
|
|
527
535
|
}
|
|
528
536
|
graftsToSelf() {
|
|
529
537
|
return this.events().pipe(filter((event) => event instanceof GraftEvent), filter((event) => event.parent().events() === this.events$));
|
|
@@ -540,6 +548,16 @@ class TreeNodeBase {
|
|
|
540
548
|
}
|
|
541
549
|
}
|
|
542
550
|
|
|
551
|
+
/** Emitted when a node is destroyed */
|
|
552
|
+
class DestructionEvent {
|
|
553
|
+
constructor(source) {
|
|
554
|
+
this._source = source;
|
|
555
|
+
}
|
|
556
|
+
source() {
|
|
557
|
+
return this._source;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
543
561
|
class RootComponent {
|
|
544
562
|
constructor() {
|
|
545
563
|
this.branchesContainer = undefined;
|
|
@@ -550,9 +568,7 @@ class RootComponent {
|
|
|
550
568
|
}
|
|
551
569
|
ngAfterViewInit() {
|
|
552
570
|
this.afterViewInit.emit();
|
|
553
|
-
|
|
554
|
-
throw new Error("dropzone is not defined");
|
|
555
|
-
}
|
|
571
|
+
assert(this.dropzone !== undefined);
|
|
556
572
|
this.dropzone.dropped.subscribe(this.dropped);
|
|
557
573
|
}
|
|
558
574
|
}
|
|
@@ -573,71 +589,225 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
|
|
|
573
589
|
type: Output
|
|
574
590
|
}] } });
|
|
575
591
|
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
592
|
+
/**
|
|
593
|
+
* A wrapper around the BranchComponent that helps instantiate it and handles its events.
|
|
594
|
+
*/
|
|
595
|
+
class RootController {
|
|
596
|
+
constructor(treeRoot, viewContainerRef) {
|
|
597
|
+
this.treeRoot = treeRoot;
|
|
598
|
+
this.rootComponentRef = viewContainerRef.createComponent(RootComponent);
|
|
582
599
|
const viewInitSub = this.rootComponentRef.instance.afterViewInit.subscribe(() => {
|
|
583
600
|
const dropzone = this.rootComponentRef.instance.dropzone;
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
}
|
|
587
|
-
dropzoneRenderer.registerDropzone(dropzone, this);
|
|
601
|
+
assert(dropzone !== undefined);
|
|
602
|
+
dropzoneRenderer.registerDropzone(dropzone, this.treeRoot);
|
|
588
603
|
});
|
|
589
604
|
const droppedSub = this.rootComponentRef.instance.dropped.subscribe(() => {
|
|
590
|
-
dropzoneRenderer.handleDrop(this, "inner");
|
|
605
|
+
dropzoneRenderer.handleDrop(this.treeRoot, "inner");
|
|
591
606
|
});
|
|
592
607
|
this.instanceSubscriptions = [viewInitSub, droppedSub];
|
|
608
|
+
}
|
|
609
|
+
destroy() {
|
|
610
|
+
this.instanceSubscriptions.forEach((sub) => {
|
|
611
|
+
sub.unsubscribe();
|
|
612
|
+
});
|
|
613
|
+
}
|
|
614
|
+
detectChanges() {
|
|
593
615
|
this.rootComponentRef.changeDetectorRef.detectChanges();
|
|
594
616
|
}
|
|
617
|
+
getBranchesContainer() {
|
|
618
|
+
return this.rootComponentRef.instance.branchesContainer;
|
|
619
|
+
}
|
|
620
|
+
getComponentInstance() {
|
|
621
|
+
return this.rootComponentRef.instance;
|
|
622
|
+
}
|
|
623
|
+
getHostView() {
|
|
624
|
+
return this.rootComponentRef.hostView;
|
|
625
|
+
}
|
|
626
|
+
getNativeElement() {
|
|
627
|
+
return this.rootComponentRef.location.nativeElement;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
/**
|
|
632
|
+
* Represents the base of the tree. It renders a very simple container for child
|
|
633
|
+
* branches. It has methods for creating and accessing those branches. It emits
|
|
634
|
+
* events when things happen in the tree.
|
|
635
|
+
*/
|
|
636
|
+
class TreeRoot {
|
|
637
|
+
constructor(viewContainerRef) {
|
|
638
|
+
this.viewContainerRef = viewContainerRef;
|
|
639
|
+
this.treeNodeBase = new TreeNodeBase();
|
|
640
|
+
this.rootController = new RootController(this, viewContainerRef);
|
|
641
|
+
this.detectChanges();
|
|
642
|
+
}
|
|
643
|
+
/** @returns All child branches as an array of TreeBranch instances */
|
|
595
644
|
branches() {
|
|
596
645
|
return this.treeNodeBase.branches();
|
|
597
646
|
}
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
647
|
+
/**
|
|
648
|
+
* Recursively destroys all branches of the tree, as well as itself.
|
|
649
|
+
*
|
|
650
|
+
* @remarks
|
|
651
|
+
* This releases all resources held or consumed by the tree.
|
|
652
|
+
*
|
|
653
|
+
* It is important to call this method when a tree is discarded, otherwise
|
|
654
|
+
* the tree will remain in memory and continue to consume resources.
|
|
655
|
+
*/
|
|
601
656
|
destroy() {
|
|
657
|
+
if (this.isDestroyed()) {
|
|
658
|
+
throw new TreeError("Cannot destroy a destroyed tree root");
|
|
659
|
+
}
|
|
602
660
|
dropzoneRenderer.clearTreeFromRegistry(this);
|
|
603
|
-
this.branches().forEach((branch) => {
|
|
604
|
-
branch.destroy();
|
|
605
|
-
});
|
|
606
661
|
this.treeNodeBase.destroy();
|
|
607
|
-
this.
|
|
608
|
-
sub.unsubscribe();
|
|
609
|
-
});
|
|
662
|
+
this.rootController.destroy();
|
|
610
663
|
this.viewContainerRef.clear();
|
|
611
664
|
config.delete(this);
|
|
612
|
-
|
|
665
|
+
this.dispatch(new DestructionEvent(this));
|
|
666
|
+
}
|
|
667
|
+
/** Run Angular change detection on the root of the tree */
|
|
668
|
+
detectChanges() {
|
|
669
|
+
this.rootController.detectChanges();
|
|
670
|
+
}
|
|
671
|
+
/**
|
|
672
|
+
* Emits the specified TreeEvent.
|
|
673
|
+
*
|
|
674
|
+
* @remarks
|
|
675
|
+
* Caution: It is not recommended to manually emit TreeEvents that are already
|
|
676
|
+
* provided by the library. For example, it is not recommended to emit a
|
|
677
|
+
* `GraftEvent`, `DestructionEvent`, etc. These events may be used by the tree,
|
|
678
|
+
* and emitting them manually may cause unexpected behavior. Instead, we
|
|
679
|
+
* recommend implementing the TreeEvent interface with your own custom events
|
|
680
|
+
* and dispatching those.
|
|
681
|
+
*
|
|
682
|
+
* @param event - The TreeEvent that will be emitted.
|
|
683
|
+
*/
|
|
613
684
|
dispatch(event) {
|
|
614
685
|
this.treeNodeBase.dispatch(event);
|
|
615
686
|
}
|
|
687
|
+
/**
|
|
688
|
+
* @returns
|
|
689
|
+
* An observable that emits TreeEvents whenever an event is dispatched
|
|
690
|
+
* in the root or any of its descendant branches.
|
|
691
|
+
*/
|
|
616
692
|
events() {
|
|
617
693
|
return this.treeNodeBase.events();
|
|
618
694
|
}
|
|
695
|
+
/**
|
|
696
|
+
* @returns
|
|
697
|
+
* The child branch at the specified index, or undefined if there is
|
|
698
|
+
* no child branch at the specified index.
|
|
699
|
+
*/
|
|
619
700
|
getBranch(index) {
|
|
620
701
|
return this.treeNodeBase.getBranch(index);
|
|
621
702
|
}
|
|
622
|
-
|
|
623
|
-
|
|
703
|
+
/** @returns The ViewContainerRef in which child branches are rendered */
|
|
704
|
+
getBranchesContainer() {
|
|
705
|
+
if (this.isDestroyed()) {
|
|
706
|
+
throw new TreeError("Cannot get branches container from a destroyed tree root");
|
|
707
|
+
}
|
|
708
|
+
return this.rootController.getBranchesContainer();
|
|
709
|
+
}
|
|
710
|
+
/**
|
|
711
|
+
* Retrieves the RootComponent.
|
|
712
|
+
*
|
|
713
|
+
* @remarks
|
|
714
|
+
* The RootComponent holds the BranchesContainer, as well as a single Dropzone
|
|
715
|
+
* for drag-and-drop operations.
|
|
716
|
+
*
|
|
717
|
+
* @returns The instance of RootComponent that is rendered by this class.
|
|
718
|
+
*/
|
|
719
|
+
getComponentInstance() {
|
|
720
|
+
if (this.isDestroyed()) {
|
|
721
|
+
throw new TreeError("Cannot get component instance from a destroyed tree root");
|
|
722
|
+
}
|
|
723
|
+
return this.rootController.getComponentInstance();
|
|
724
|
+
}
|
|
725
|
+
/** @returns The Host View in which the RootComponent is rendered */
|
|
726
|
+
getHostView() {
|
|
727
|
+
if (this.isDestroyed()) {
|
|
728
|
+
throw new TreeError("Cannot get component host view from a destroyed tree root");
|
|
729
|
+
}
|
|
730
|
+
return this.rootController.getHostView();
|
|
624
731
|
}
|
|
732
|
+
/** @returns The RootComponent as a native HTML Element */
|
|
733
|
+
getNativeElement() {
|
|
734
|
+
if (this.isDestroyed()) {
|
|
735
|
+
throw new TreeError("Cannot get native element from a destroyed tree root");
|
|
736
|
+
}
|
|
737
|
+
return this.rootController.getNativeElement();
|
|
738
|
+
}
|
|
739
|
+
/**
|
|
740
|
+
* Appends a new child branch to this branch. The child branch will render
|
|
741
|
+
* the specified component according to the (optional) configuration parameter.
|
|
742
|
+
*
|
|
743
|
+
* @param component - The component to render in the new child branch.
|
|
744
|
+
* @param options - Configuration options for the new child branch.
|
|
745
|
+
*
|
|
746
|
+
* @returns
|
|
747
|
+
* The newly-created child branch.
|
|
748
|
+
*/
|
|
625
749
|
grow(component, options) {
|
|
750
|
+
if (this.isDestroyed()) {
|
|
751
|
+
throw new TreeError("Cannot grow a branch on a destroyed tree root");
|
|
752
|
+
}
|
|
626
753
|
return new TreeBranch(this, Object.assign({ component }, options));
|
|
627
754
|
}
|
|
755
|
+
/** @returns `true` if the tree is destroyed, `false` otherwise */
|
|
756
|
+
isDestroyed() {
|
|
757
|
+
return this.treeNodeBase.isDestroyed();
|
|
758
|
+
}
|
|
759
|
+
/**
|
|
760
|
+
* Provides a model describing the shape of the tree.
|
|
761
|
+
*
|
|
762
|
+
* @returns A multi-dimensional Map which describes the shape of the tree.
|
|
763
|
+
*
|
|
764
|
+
* @example
|
|
765
|
+
* For example, an empty tree will return an empty Map. A tree with a single
|
|
766
|
+
* branch will return a Map with a single entry, where the key is the index
|
|
767
|
+
* of the branch (zero) and the value is an empty Map. A Tree like this:
|
|
768
|
+
*
|
|
769
|
+
* ```
|
|
770
|
+
* ---Branch-------Branch
|
|
771
|
+
* /
|
|
772
|
+
* Root-------Branch
|
|
773
|
+
* \
|
|
774
|
+
* ---Branch
|
|
775
|
+
* ```
|
|
776
|
+
* Will return a Map of matching shape:
|
|
777
|
+
* ```
|
|
778
|
+
* Map {
|
|
779
|
+
* 0: Map { 0: Map {}},
|
|
780
|
+
* 1: Map {},
|
|
781
|
+
* 2: Map {}
|
|
782
|
+
* }
|
|
783
|
+
* ```
|
|
784
|
+
*/
|
|
628
785
|
plot() {
|
|
629
786
|
return this.treeNodeBase.plot();
|
|
630
787
|
}
|
|
788
|
+
/** @returns Itself */
|
|
631
789
|
root() {
|
|
632
790
|
return this;
|
|
633
791
|
}
|
|
792
|
+
/**
|
|
793
|
+
* Traverses the tree in depth-first pre-order, executing the provided
|
|
794
|
+
* callback function on each node. Traversal includes the Root.
|
|
795
|
+
*
|
|
796
|
+
* @param callback - A function to execute on each node.
|
|
797
|
+
*/
|
|
634
798
|
traverse(callback) {
|
|
635
799
|
callback(this);
|
|
636
800
|
this.treeNodeBase.traverse(callback);
|
|
637
801
|
}
|
|
638
802
|
}
|
|
639
803
|
|
|
804
|
+
/** Responsible for the creation of new trees. */
|
|
640
805
|
class TreeService {
|
|
806
|
+
/**
|
|
807
|
+
* Creates a new, empty tree structure inside the provided container.
|
|
808
|
+
*
|
|
809
|
+
* @returns A `TreeRoot` representing the base of the new tree.
|
|
810
|
+
*/
|
|
641
811
|
createEmptyTree(container, options = {}) {
|
|
642
812
|
container.clear();
|
|
643
813
|
const root = new TreeRoot(container);
|
|
@@ -652,29 +822,127 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
|
|
|
652
822
|
args: [{ providedIn: "root" }]
|
|
653
823
|
}] });
|
|
654
824
|
|
|
825
|
+
/**
|
|
826
|
+
* A wrapper around the BranchComponent that helps instantiate it and handles its events.
|
|
827
|
+
*/
|
|
828
|
+
class BranchController {
|
|
829
|
+
constructor(treeBranch, parentBranchesContainer) {
|
|
830
|
+
this.treeBranch = treeBranch;
|
|
831
|
+
this.outputBindingSubscriptions = [];
|
|
832
|
+
this.branchComponentRef = createComponent(BranchComponent, {
|
|
833
|
+
environmentInjector: parentBranchesContainer.injector.get(EnvironmentInjector)
|
|
834
|
+
});
|
|
835
|
+
this.branchComponentRef.instance.contentToHost =
|
|
836
|
+
this.treeBranch.branchOptions.component;
|
|
837
|
+
this.instanceSubscriptions = this.getInstanceSubscriptions(this.branchComponentRef.instance);
|
|
838
|
+
}
|
|
839
|
+
destroy() {
|
|
840
|
+
this.instanceSubscriptions.forEach((sub) => {
|
|
841
|
+
sub.unsubscribe();
|
|
842
|
+
});
|
|
843
|
+
this.outputBindingSubscriptions.forEach((sub) => {
|
|
844
|
+
sub.unsubscribe();
|
|
845
|
+
});
|
|
846
|
+
}
|
|
847
|
+
detectChanges() {
|
|
848
|
+
this.branchComponentRef.changeDetectorRef.detectChanges();
|
|
849
|
+
}
|
|
850
|
+
getBranchesContainer() {
|
|
851
|
+
return this.branchComponentRef.instance.branchesContainer;
|
|
852
|
+
}
|
|
853
|
+
getComponentInstance() {
|
|
854
|
+
return this.branchComponentRef.instance;
|
|
855
|
+
}
|
|
856
|
+
getHostView() {
|
|
857
|
+
return this.branchComponentRef.hostView;
|
|
858
|
+
}
|
|
859
|
+
getNativeElement() {
|
|
860
|
+
return this.branchComponentRef.location.nativeElement;
|
|
861
|
+
}
|
|
862
|
+
getUserlandComponentRef() {
|
|
863
|
+
return this.branchComponentRef.instance.getHostedContent();
|
|
864
|
+
}
|
|
865
|
+
getContentCreatedSub(instance) {
|
|
866
|
+
return instance.contentCreated.subscribe((userlandComponentInstance) => {
|
|
867
|
+
var _a, _b;
|
|
868
|
+
const component = userlandComponentInstance;
|
|
869
|
+
Object.entries((_a = this.treeBranch.branchOptions.inputBindings) !== null && _a !== void 0 ? _a : {}).forEach(([key, value]) => {
|
|
870
|
+
component[key] = value;
|
|
871
|
+
});
|
|
872
|
+
Object.entries((_b = this.treeBranch.branchOptions.outputBindings) !== null && _b !== void 0 ? _b : {}).forEach(([key, value]) => {
|
|
873
|
+
this.outputBindingSubscriptions.push(component[key].subscribe(value));
|
|
874
|
+
});
|
|
875
|
+
component.treeBranch = this.treeBranch;
|
|
876
|
+
const dropzones = instance.dropzones;
|
|
877
|
+
assert(dropzones !== undefined);
|
|
878
|
+
dropzoneRenderer.registerDropzones(dropzones, this.treeBranch);
|
|
879
|
+
});
|
|
880
|
+
}
|
|
881
|
+
getInstanceSubscriptions(instance) {
|
|
882
|
+
const droppedSub = instance.dropped.subscribe((placement) => {
|
|
883
|
+
dropzoneRenderer.handleDrop(this.treeBranch, placement);
|
|
884
|
+
});
|
|
885
|
+
return [
|
|
886
|
+
this.getContentCreatedSub(instance),
|
|
887
|
+
this.getShowLowerZonesSub(instance),
|
|
888
|
+
this.getShowUpperZonesSub(instance),
|
|
889
|
+
droppedSub
|
|
890
|
+
];
|
|
891
|
+
}
|
|
892
|
+
getShowLowerZonesSub(instance) {
|
|
893
|
+
return instance.showDropzones
|
|
894
|
+
.pipe(filter((direction) => direction === "lower"))
|
|
895
|
+
.subscribe(() => {
|
|
896
|
+
const currentDropzoneDisplayed = dropzoneRenderer.getCurrentDisplay();
|
|
897
|
+
if ((currentDropzoneDisplayed === null || currentDropzoneDisplayed === void 0 ? void 0 : currentDropzoneDisplayed.treeBranch) === this.treeBranch &&
|
|
898
|
+
currentDropzoneDisplayed.direction === "lower") {
|
|
899
|
+
return;
|
|
900
|
+
}
|
|
901
|
+
dropzoneRenderer.showLowerZones(this.treeBranch);
|
|
902
|
+
instance.triggerChangeDetection();
|
|
903
|
+
});
|
|
904
|
+
}
|
|
905
|
+
getShowUpperZonesSub(instance) {
|
|
906
|
+
return instance.showDropzones
|
|
907
|
+
.pipe(filter((direction) => direction === "upper"))
|
|
908
|
+
.subscribe(() => {
|
|
909
|
+
const currentDropzoneDisplayed = dropzoneRenderer.getCurrentDisplay();
|
|
910
|
+
if ((currentDropzoneDisplayed === null || currentDropzoneDisplayed === void 0 ? void 0 : currentDropzoneDisplayed.treeBranch) === this.treeBranch &&
|
|
911
|
+
currentDropzoneDisplayed.direction === "upper") {
|
|
912
|
+
return;
|
|
913
|
+
}
|
|
914
|
+
dropzoneRenderer.showUpperZones(this.treeBranch);
|
|
915
|
+
instance.triggerChangeDetection();
|
|
916
|
+
});
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
/** Represents a standard node in a tree. Renders a BranchComponent.
|
|
921
|
+
*
|
|
922
|
+
* @remarks
|
|
923
|
+
* This class renders a branch component, which does the following:
|
|
924
|
+
* 1. Renders a component provided by the user
|
|
925
|
+
* 2. Provides a container in which child branches may be rendered
|
|
926
|
+
* 3. Contains two Dropzones: one for dropping branches below this branch (as a
|
|
927
|
+
* sibling), and one for dropping branches as a first child of this branch.
|
|
928
|
+
*/
|
|
655
929
|
class TreeBranch {
|
|
656
930
|
constructor(parent, branchOptions) {
|
|
657
931
|
this.branchOptions = branchOptions;
|
|
658
932
|
this.detachedView = null;
|
|
659
933
|
this.treeNodeBase = new TreeNodeBase();
|
|
660
|
-
|
|
661
|
-
const parentBranchesContainer = parent.getContents().instance.branchesContainer;
|
|
934
|
+
const parentBranchesContainer = parent.getBranchesContainer();
|
|
662
935
|
assert(parentBranchesContainer !== undefined);
|
|
663
|
-
this.
|
|
664
|
-
environmentInjector: parentBranchesContainer.injector.get(EnvironmentInjector)
|
|
665
|
-
});
|
|
666
|
-
this.contents.instance.contentToHost = this.userlandComponent;
|
|
936
|
+
this.branchController = new BranchController(this, parentBranchesContainer);
|
|
667
937
|
this.setIndentation(parent);
|
|
668
|
-
this.outputBindingSubscriptions = [];
|
|
669
|
-
this.instanceSubscriptions = this.getInstanceSubscriptions();
|
|
670
938
|
if (parent instanceof TreeBranch &&
|
|
671
|
-
parent.branchOptions.
|
|
939
|
+
parent.branchOptions.defaultCollapsed === true) {
|
|
672
940
|
treeCollapser.storePrecollapsedNode(parent, this);
|
|
673
|
-
this.detachedView = this.
|
|
941
|
+
this.detachedView = this.branchController.getHostView();
|
|
674
942
|
}
|
|
675
943
|
else {
|
|
676
|
-
parentBranchesContainer.insert(this.
|
|
677
|
-
this.
|
|
944
|
+
parentBranchesContainer.insert(this.branchController.getHostView());
|
|
945
|
+
this.detectChanges();
|
|
678
946
|
this._parent = parent;
|
|
679
947
|
this.dispatch(new GraftEvent(this, {
|
|
680
948
|
parent: this._parent,
|
|
@@ -683,51 +951,128 @@ class TreeBranch {
|
|
|
683
951
|
}));
|
|
684
952
|
}
|
|
685
953
|
}
|
|
954
|
+
/** @returns All child branches as an array of TreeBranch instances, in order. */
|
|
686
955
|
branches() {
|
|
687
956
|
return this.treeNodeBase.branches();
|
|
688
957
|
}
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
958
|
+
/**
|
|
959
|
+
* Recursively destroys all descendant branches, as well as itself. This
|
|
960
|
+
* releases all resources held or consumed by this branch and its descendants.
|
|
961
|
+
*
|
|
962
|
+
* @remarks
|
|
963
|
+
* It is important to call this method when a branch is discarded, otherwise
|
|
964
|
+
* the branch will remain in memory and continue to consume resources.
|
|
965
|
+
*/
|
|
692
966
|
destroy() {
|
|
693
|
-
if (
|
|
694
|
-
|
|
695
|
-
dropzoneRenderer.clearTreeFromRegistry(this);
|
|
696
|
-
}
|
|
697
|
-
this.branches().forEach((branch) => {
|
|
698
|
-
branch.destroy();
|
|
699
|
-
});
|
|
700
|
-
const parent = this._parent;
|
|
701
|
-
const index = this.index();
|
|
702
|
-
if (index !== undefined && parent !== undefined) {
|
|
703
|
-
const container = parent.getContents().instance.branchesContainer;
|
|
704
|
-
assert(container !== undefined);
|
|
705
|
-
container.remove(index);
|
|
706
|
-
parent.deleteBranch(index);
|
|
967
|
+
if (this.isDestroyed()) {
|
|
968
|
+
throw new TreeError("Cannot destroy a destroyed tree branch");
|
|
707
969
|
}
|
|
970
|
+
this.prune();
|
|
971
|
+
treeCollapser.expand(this);
|
|
972
|
+
dropzoneRenderer.clearTreeFromRegistry(this);
|
|
973
|
+
this.branchController.getHostView().destroy();
|
|
708
974
|
this.treeNodeBase.destroy();
|
|
709
|
-
this.
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
}
|
|
975
|
+
this.branchController.destroy();
|
|
976
|
+
this.dispatch(new DestructionEvent(this));
|
|
977
|
+
}
|
|
978
|
+
/** Run Angular change detection on this branch */
|
|
979
|
+
detectChanges() {
|
|
980
|
+
this.branchController.detectChanges();
|
|
981
|
+
}
|
|
982
|
+
/**
|
|
983
|
+
* Emits the specified TreeEvent.
|
|
984
|
+
*
|
|
985
|
+
* @remarks
|
|
986
|
+
* Caution: It is not recommended to manually emit TreeEvents that are already
|
|
987
|
+
* provided by the library. For example, it is not recommended to emit a
|
|
988
|
+
* `GraftEvent`, `DestructionEvent`, etc. These events may be used by the tree,
|
|
989
|
+
* and emitting them manually may cause unexpected behavior. Instead, we
|
|
990
|
+
* recommend implementing the TreeEvent interface with your own custom events
|
|
991
|
+
* and dispatching those.
|
|
992
|
+
*
|
|
993
|
+
* @param event - The TreeEvent that will be emitted.
|
|
994
|
+
*/
|
|
716
995
|
dispatch(event) {
|
|
717
996
|
var _a;
|
|
718
997
|
this.treeNodeBase.dispatch(event);
|
|
719
998
|
(_a = this._parent) === null || _a === void 0 ? void 0 : _a.dispatch(event);
|
|
720
999
|
}
|
|
1000
|
+
/**
|
|
1001
|
+
* @returns
|
|
1002
|
+
* An observable that emits TreeEvents whenever an event is dispatched
|
|
1003
|
+
* in this branch or any of its descendant branches.
|
|
1004
|
+
*/
|
|
721
1005
|
events() {
|
|
722
1006
|
return this.treeNodeBase.events();
|
|
723
1007
|
}
|
|
1008
|
+
/**
|
|
1009
|
+
* @param index - The index of the child branch to retrieve.
|
|
1010
|
+
*
|
|
1011
|
+
* @returns
|
|
1012
|
+
* The child branch at the specified index, or undefined if there is
|
|
1013
|
+
* no child branch at the specified index.
|
|
1014
|
+
*/
|
|
724
1015
|
getBranch(index) {
|
|
725
1016
|
return this.treeNodeBase.getBranch(index);
|
|
726
1017
|
}
|
|
727
|
-
|
|
728
|
-
|
|
1018
|
+
/** @returns The ViewContainerRef in which child branches are rendered */
|
|
1019
|
+
getBranchesContainer() {
|
|
1020
|
+
if (this.isDestroyed()) {
|
|
1021
|
+
throw new TreeError("Cannot get branches container from a destroyed tree branch");
|
|
1022
|
+
}
|
|
1023
|
+
return this.branchController.getBranchesContainer();
|
|
1024
|
+
}
|
|
1025
|
+
/** @returns The instance of BranchComponent that is rendered by this class. */
|
|
1026
|
+
getComponentInstance() {
|
|
1027
|
+
if (this.isDestroyed()) {
|
|
1028
|
+
throw new TreeError("Cannot get component instance from a destroyed tree branch");
|
|
1029
|
+
}
|
|
1030
|
+
return this.branchController.getComponentInstance();
|
|
1031
|
+
}
|
|
1032
|
+
/** @returns The Host View in which the BranchComponent is rendered */
|
|
1033
|
+
getHostView() {
|
|
1034
|
+
if (this.isDestroyed()) {
|
|
1035
|
+
throw new TreeError("Cannot get component host view from a destroyed tree branch");
|
|
1036
|
+
}
|
|
1037
|
+
return this.branchController.getHostView();
|
|
729
1038
|
}
|
|
1039
|
+
/** @returns The BranchComponent as a native HTML Element */
|
|
1040
|
+
getNativeElement() {
|
|
1041
|
+
if (this.isDestroyed()) {
|
|
1042
|
+
throw new TreeError("Cannot get native element from a destroyed tree branch");
|
|
1043
|
+
}
|
|
1044
|
+
return this.branchController.getNativeElement();
|
|
1045
|
+
}
|
|
1046
|
+
/**
|
|
1047
|
+
* @returns
|
|
1048
|
+
* A ComponentRef containing the instance of the user-provided
|
|
1049
|
+
* component which is rendered by this branch.
|
|
1050
|
+
*/
|
|
1051
|
+
getUserlandComponentRef() {
|
|
1052
|
+
if (this.isDestroyed()) {
|
|
1053
|
+
throw new TreeError("Cannot get userland component from a destroyed tree branch");
|
|
1054
|
+
}
|
|
1055
|
+
return this.branchController.getUserlandComponentRef();
|
|
1056
|
+
}
|
|
1057
|
+
/**
|
|
1058
|
+
* Attaches a branch to a new parent node.
|
|
1059
|
+
*
|
|
1060
|
+
* @remarks
|
|
1061
|
+
* If not already pruned, this method prunes (removes) this branch from its
|
|
1062
|
+
* current position in the tree; then grafts (reattaches) it as a child of the
|
|
1063
|
+
* specified parent branch at the specified index. If no index is specified,
|
|
1064
|
+
* the branch is appended as the last child of the parent. This causes this
|
|
1065
|
+
* branch's associated BranchComponent to be re-rendered in the DOM at the
|
|
1066
|
+
* new location.
|
|
1067
|
+
*
|
|
1068
|
+
* @param newParent - The new parent branch unto which this branch will be grafted.
|
|
1069
|
+
* @param index - The index at which this branch will be grafted. If not specified,
|
|
1070
|
+
* this branch will be appended as the last child of the new parent.
|
|
1071
|
+
*
|
|
1072
|
+
* @returns The index at which this branch was grafted.
|
|
1073
|
+
*/
|
|
730
1074
|
graftTo(newParent, index) {
|
|
1075
|
+
this.checkGraftLocationValidity(newParent, index);
|
|
731
1076
|
const ownIndex = this.index();
|
|
732
1077
|
if (ownIndex !== undefined) {
|
|
733
1078
|
this.prune();
|
|
@@ -742,9 +1087,35 @@ class TreeBranch {
|
|
|
742
1087
|
}));
|
|
743
1088
|
return newIndex;
|
|
744
1089
|
}
|
|
1090
|
+
/**
|
|
1091
|
+
* Appends a new child branch to this branch. The child branch will render
|
|
1092
|
+
* the specified component according to the (optional) configuration parameter.
|
|
1093
|
+
*
|
|
1094
|
+
* @param component - The component to render in the new child branch.
|
|
1095
|
+
* @param options - Configuration options for the new child branch.
|
|
1096
|
+
*
|
|
1097
|
+
* @returns
|
|
1098
|
+
* The newly-created child branch.
|
|
1099
|
+
*/
|
|
745
1100
|
grow(component, options) {
|
|
1101
|
+
if (this.isDestroyed()) {
|
|
1102
|
+
throw new TreeError("Cannot grow a branch on a destroyed tree branch");
|
|
1103
|
+
}
|
|
746
1104
|
return new TreeBranch(this, Object.assign({ component }, options));
|
|
747
1105
|
}
|
|
1106
|
+
/**
|
|
1107
|
+
* Determines this branch's index in relation to its sibling branches.
|
|
1108
|
+
*
|
|
1109
|
+
* @remarks
|
|
1110
|
+
* For example, if it is the first child of its parent, this method will return
|
|
1111
|
+
* 0. If it is the second child of its parent, this method will return 1.
|
|
1112
|
+
*
|
|
1113
|
+
* If this branch has no parent, (eg, if this branch has been pruned) this
|
|
1114
|
+
* method will return undefined.
|
|
1115
|
+
*
|
|
1116
|
+
* @returns
|
|
1117
|
+
* The index of this branch in relation to its sibling branches, or undefined.
|
|
1118
|
+
*/
|
|
748
1119
|
index() {
|
|
749
1120
|
if (!this._parent) {
|
|
750
1121
|
return undefined;
|
|
@@ -755,16 +1126,77 @@ class TreeBranch {
|
|
|
755
1126
|
assert(index >= 0);
|
|
756
1127
|
return index;
|
|
757
1128
|
}
|
|
1129
|
+
/** @returns `true` if the branch is destroyed, `false` otherwise */
|
|
1130
|
+
isDestroyed() {
|
|
1131
|
+
return this.treeNodeBase.isDestroyed();
|
|
1132
|
+
}
|
|
1133
|
+
/**
|
|
1134
|
+
* @returns
|
|
1135
|
+
* The data that was passed into the `branchOptions`' `meta` property
|
|
1136
|
+
* at construction.
|
|
1137
|
+
*/
|
|
758
1138
|
meta() {
|
|
759
1139
|
var _a;
|
|
760
1140
|
return (_a = this.branchOptions.meta) !== null && _a !== void 0 ? _a : {};
|
|
761
1141
|
}
|
|
1142
|
+
/**
|
|
1143
|
+
* @returns
|
|
1144
|
+
* This branch's parent node (which may be a TreeBranch or TreeRoot).
|
|
1145
|
+
* If this branch has no parent, (eg, if this branch has been pruned) this
|
|
1146
|
+
* method will return undefined.
|
|
1147
|
+
*/
|
|
762
1148
|
parent() {
|
|
763
1149
|
return this._parent;
|
|
764
1150
|
}
|
|
1151
|
+
/**
|
|
1152
|
+
* Provides a model describing this branch's descendants.
|
|
1153
|
+
*
|
|
1154
|
+
* @returns
|
|
1155
|
+
* A multi-dimensional Map which describes the shape of this branch's
|
|
1156
|
+
* descendants.
|
|
1157
|
+
*
|
|
1158
|
+
* @example
|
|
1159
|
+
* A branch with no children will return an empty Map. A branch with
|
|
1160
|
+
* a single child will return a Map with a single entry, where the key is the index
|
|
1161
|
+
* of the branch (zero) and the value is an empty Map. A Tree like this:
|
|
1162
|
+
*
|
|
1163
|
+
* ```
|
|
1164
|
+
* ---Branch-------Branch
|
|
1165
|
+
* /
|
|
1166
|
+
* Branch-------Branch
|
|
1167
|
+
* \
|
|
1168
|
+
* ---Branch
|
|
1169
|
+
* ```
|
|
1170
|
+
* Will return a Map of matching shape:
|
|
1171
|
+
* ```
|
|
1172
|
+
* Map {
|
|
1173
|
+
* 0: Map { 0: Map {}},
|
|
1174
|
+
* 1: Map {},
|
|
1175
|
+
* 2: Map {}
|
|
1176
|
+
* }
|
|
1177
|
+
* ```
|
|
1178
|
+
*/
|
|
765
1179
|
plot() {
|
|
766
1180
|
return this.treeNodeBase.plot();
|
|
767
1181
|
}
|
|
1182
|
+
/**
|
|
1183
|
+
* Calculates the branch's position in the tree relative to the Root.
|
|
1184
|
+
*
|
|
1185
|
+
* @remarks
|
|
1186
|
+
* The position is described as an array of numbers, where each number
|
|
1187
|
+
* represents the index of the branch at that level of the tree.
|
|
1188
|
+
*
|
|
1189
|
+
* For example, if this branch is the first child of the Root, this method
|
|
1190
|
+
* will return [0]. If this branch is the second child of the first child
|
|
1191
|
+
* of the Root, this method will return [0, 1].
|
|
1192
|
+
*
|
|
1193
|
+
* If the branch is not related to a TreeRoot, (such as when it has been
|
|
1194
|
+
* pruned,) this method will throw an error.
|
|
1195
|
+
*
|
|
1196
|
+
* @returns
|
|
1197
|
+
* An array of numbers which describe the branch's position in the tree
|
|
1198
|
+
* relative to the Root.
|
|
1199
|
+
*/
|
|
768
1200
|
position() {
|
|
769
1201
|
const index = this.index();
|
|
770
1202
|
if (index === undefined) {
|
|
@@ -776,12 +1208,28 @@ class TreeBranch {
|
|
|
776
1208
|
}
|
|
777
1209
|
return [index];
|
|
778
1210
|
}
|
|
1211
|
+
/**
|
|
1212
|
+
* Removes a branch from its tree without destroying it.
|
|
1213
|
+
*
|
|
1214
|
+
* @remarks
|
|
1215
|
+
* Removes this branch from its parent and detaches its associated
|
|
1216
|
+
* BranchComponent from the DOM. This puts the branch in a "pruned" state,
|
|
1217
|
+
* which may affect the behavior of other methods.
|
|
1218
|
+
*
|
|
1219
|
+
* A pruned branch can be reattached to any other node using the `graftTo` method.
|
|
1220
|
+
*
|
|
1221
|
+
* @returns
|
|
1222
|
+
* Itself, or undefined if it is already in a pruned state.
|
|
1223
|
+
*/
|
|
779
1224
|
prune() {
|
|
1225
|
+
if (this.isDestroyed()) {
|
|
1226
|
+
throw new TreeError("Cannot prune a destroyed tree branch");
|
|
1227
|
+
}
|
|
780
1228
|
const parent = this._parent;
|
|
781
1229
|
const index = this.index();
|
|
782
1230
|
if (index === undefined || parent === undefined)
|
|
783
1231
|
return;
|
|
784
|
-
const container = parent.
|
|
1232
|
+
const container = parent.getBranchesContainer();
|
|
785
1233
|
assert(container !== undefined);
|
|
786
1234
|
this.detachedView = container.detach(index);
|
|
787
1235
|
assert(this.detachedView !== null);
|
|
@@ -794,84 +1242,56 @@ class TreeBranch {
|
|
|
794
1242
|
this._parent = undefined;
|
|
795
1243
|
return this;
|
|
796
1244
|
}
|
|
1245
|
+
/**
|
|
1246
|
+
* Get the root of the tree to which this Branch is attached.
|
|
1247
|
+
*
|
|
1248
|
+
* @returns
|
|
1249
|
+
* The TreeRoot of the tree this branch is in. If this branch is
|
|
1250
|
+
* does not have a root (such as when it has been pruned) this method will
|
|
1251
|
+
* return undefined.
|
|
1252
|
+
*/
|
|
797
1253
|
root() {
|
|
798
1254
|
const parent = this.parent();
|
|
799
|
-
if (parent === undefined) {
|
|
800
|
-
return undefined;
|
|
801
|
-
}
|
|
802
1255
|
if (parent instanceof TreeBranch) {
|
|
803
1256
|
return parent.root();
|
|
804
1257
|
}
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
1258
|
+
assert(parent instanceof TreeRoot || parent === undefined);
|
|
1259
|
+
return parent;
|
|
1260
|
+
}
|
|
1261
|
+
/**
|
|
1262
|
+
* Traverses this branch's descendants in depth-first pre-order, executing
|
|
1263
|
+
* the provided callback function on each node. Traversal includes this branch.
|
|
1264
|
+
*
|
|
1265
|
+
* @param callback - A function to execute on each node.
|
|
1266
|
+
*/
|
|
810
1267
|
traverse(callback) {
|
|
811
1268
|
callback(this);
|
|
812
1269
|
this.treeNodeBase.traverse(callback);
|
|
813
1270
|
}
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
}
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
if (
|
|
827
|
-
throw new
|
|
828
|
-
}
|
|
829
|
-
dropzoneRenderer.registerDropzones(dropzones, this);
|
|
830
|
-
});
|
|
831
|
-
}
|
|
832
|
-
getInstanceSubscriptions() {
|
|
833
|
-
const droppedSub = this.contents.instance.dropped.subscribe((placement) => {
|
|
834
|
-
dropzoneRenderer.handleDrop(this, placement);
|
|
835
|
-
});
|
|
836
|
-
return [
|
|
837
|
-
this.getContentCreatedSub(),
|
|
838
|
-
this.getShowLowerZonesSub(),
|
|
839
|
-
this.getShowUpperZonesSub(),
|
|
840
|
-
droppedSub
|
|
841
|
-
];
|
|
842
|
-
}
|
|
843
|
-
getShowLowerZonesSub() {
|
|
844
|
-
const instance = this.contents.instance;
|
|
845
|
-
return instance.showDropzones
|
|
846
|
-
.pipe(filter((direction) => direction === "lower"))
|
|
847
|
-
.subscribe(() => {
|
|
848
|
-
const currentDropzoneDisplayed = dropzoneRenderer.getCurrentDisplay();
|
|
849
|
-
if ((currentDropzoneDisplayed === null || currentDropzoneDisplayed === void 0 ? void 0 : currentDropzoneDisplayed.treeBranch) === this &&
|
|
850
|
-
currentDropzoneDisplayed.direction === "lower") {
|
|
851
|
-
return;
|
|
1271
|
+
checkGraftLocationValidity(newParent, index) {
|
|
1272
|
+
if (this.isDestroyed()) {
|
|
1273
|
+
throw new TreeError("Cannot graft a destroyed tree branch");
|
|
1274
|
+
}
|
|
1275
|
+
if (newParent.isDestroyed()) {
|
|
1276
|
+
throw new TreeError("Cannot graft to a destroyed tree branch");
|
|
1277
|
+
}
|
|
1278
|
+
if (typeof index === "number" &&
|
|
1279
|
+
this.indexIsOutOfRange(newParent, index)) {
|
|
1280
|
+
throw new TreeError(`Cannot graft branch at index ${index} of the parent. Out of range.`);
|
|
1281
|
+
}
|
|
1282
|
+
this.traverse((node) => {
|
|
1283
|
+
if (node === newParent) {
|
|
1284
|
+
throw new TreeError("Cannot graft a branch to itself or any of its own descendants");
|
|
852
1285
|
}
|
|
853
|
-
dropzoneRenderer.showLowerZones(this);
|
|
854
|
-
instance.triggerChangeDetection();
|
|
855
1286
|
});
|
|
856
1287
|
}
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
return instance.showDropzones
|
|
860
|
-
.pipe(filter((direction) => direction === "upper"))
|
|
861
|
-
.subscribe(() => {
|
|
862
|
-
const currentDropzoneDisplayed = dropzoneRenderer.getCurrentDisplay();
|
|
863
|
-
if ((currentDropzoneDisplayed === null || currentDropzoneDisplayed === void 0 ? void 0 : currentDropzoneDisplayed.treeBranch) === this &&
|
|
864
|
-
currentDropzoneDisplayed.direction === "upper") {
|
|
865
|
-
return;
|
|
866
|
-
}
|
|
867
|
-
dropzoneRenderer.showUpperZones(this);
|
|
868
|
-
instance.triggerChangeDetection();
|
|
869
|
-
});
|
|
1288
|
+
indexIsOutOfRange(parent, index) {
|
|
1289
|
+
return index < 0 || index > parent.branches().length;
|
|
870
1290
|
}
|
|
871
1291
|
reattachView(index) {
|
|
872
1292
|
assert(this._parent !== undefined);
|
|
873
1293
|
assert(this.detachedView !== null);
|
|
874
|
-
const container = this._parent.
|
|
1294
|
+
const container = this._parent.getBranchesContainer();
|
|
875
1295
|
assert(container !== undefined);
|
|
876
1296
|
this.detachedView.reattach();
|
|
877
1297
|
container.insert(this.detachedView, index);
|
|
@@ -882,7 +1302,8 @@ class TreeBranch {
|
|
|
882
1302
|
const root = parent.root();
|
|
883
1303
|
assert(root !== undefined);
|
|
884
1304
|
const options = config.getConfig(root);
|
|
885
|
-
const branchesContainerEl = this.
|
|
1305
|
+
const branchesContainerEl = this.branchController
|
|
1306
|
+
.getNativeElement()
|
|
886
1307
|
.getElementsByClassName("branches-container")
|
|
887
1308
|
.item(0);
|
|
888
1309
|
assert(branchesContainerEl instanceof HTMLElement);
|
|
@@ -923,7 +1344,7 @@ class DropzoneRenderer {
|
|
|
923
1344
|
if (this.currentDisplay === null)
|
|
924
1345
|
return;
|
|
925
1346
|
for (const branch of this.registry.values()) {
|
|
926
|
-
const instance = branch.
|
|
1347
|
+
const instance = branch.getComponentInstance();
|
|
927
1348
|
instance.showInnerDropzone = false;
|
|
928
1349
|
if (instance instanceof BranchComponent) {
|
|
929
1350
|
instance.showLateralDropzone = false;
|
|
@@ -1020,26 +1441,26 @@ class DropzoneRenderer {
|
|
|
1020
1441
|
}
|
|
1021
1442
|
}
|
|
1022
1443
|
nestingAllowed(treeNode) {
|
|
1023
|
-
var _a, _b;
|
|
1444
|
+
var _a, _b, _c;
|
|
1024
1445
|
if (treeNode instanceof TreeRoot) {
|
|
1025
1446
|
return true;
|
|
1026
1447
|
}
|
|
1027
1448
|
if (treeNode instanceof TreeBranch) {
|
|
1028
|
-
const allowNesting = (_b = (_a = config.getConfig(treeNode.root())) === null || _a === void 0 ? void 0 : _a.allowNesting) !== null &&
|
|
1449
|
+
const allowNesting = (_c = (_b = (_a = config.getConfig(treeNode.root())) === null || _a === void 0 ? void 0 : _a.dragAndDrop) === null || _b === void 0 ? void 0 : _b.allowNesting) !== null && _c !== void 0 ? _c : (() => true);
|
|
1029
1450
|
return allowNesting(treeNode);
|
|
1030
1451
|
}
|
|
1031
1452
|
throw new Error("unsupported treeNode type");
|
|
1032
1453
|
}
|
|
1033
1454
|
dropAllowed(parent, index) {
|
|
1034
|
-
var _a, _b, _c, _d;
|
|
1455
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1035
1456
|
const sourceNode = dragState.getDragData();
|
|
1036
1457
|
assert(sourceNode instanceof TreeBranch);
|
|
1037
1458
|
if (parent instanceof TreeRoot) {
|
|
1038
|
-
const allowDrop = (_b = (_a = config.getConfig(parent)) === null || _a === void 0 ? void 0 : _a.allowDrop) !== null &&
|
|
1459
|
+
const allowDrop = (_c = (_b = (_a = config.getConfig(parent)) === null || _a === void 0 ? void 0 : _a.dragAndDrop) === null || _b === void 0 ? void 0 : _b.allowDrop) !== null && _c !== void 0 ? _c : (() => true);
|
|
1039
1460
|
return allowDrop(sourceNode, parent, index);
|
|
1040
1461
|
}
|
|
1041
1462
|
if (parent instanceof TreeBranch) {
|
|
1042
|
-
const allowDrop = (
|
|
1463
|
+
const allowDrop = (_f = (_e = (_d = config.getConfig(parent.root())) === null || _d === void 0 ? void 0 : _d.dragAndDrop) === null || _e === void 0 ? void 0 : _e.allowDrop) !== null && _f !== void 0 ? _f : (() => true);
|
|
1043
1464
|
return allowDrop(sourceNode, parent, index);
|
|
1044
1465
|
}
|
|
1045
1466
|
throw new Error("unsupported treeNode type");
|
|
@@ -1047,31 +1468,48 @@ class DropzoneRenderer {
|
|
|
1047
1468
|
showInnerZone(treeNode) {
|
|
1048
1469
|
if (!this.nestingAllowed(treeNode) || !this.dropAllowed(treeNode, 0))
|
|
1049
1470
|
return;
|
|
1050
|
-
treeNode.
|
|
1471
|
+
treeNode.getComponentInstance().showInnerDropzone = true;
|
|
1051
1472
|
}
|
|
1052
1473
|
showLateralZone(treeBranch) {
|
|
1053
1474
|
const index = treeBranch.index();
|
|
1054
1475
|
assert(index !== undefined);
|
|
1055
1476
|
if (!this.dropAllowed(treeBranch.parent(), index + 1))
|
|
1056
1477
|
return;
|
|
1057
|
-
treeBranch.
|
|
1478
|
+
treeBranch.getComponentInstance().showLateralDropzone = true;
|
|
1058
1479
|
}
|
|
1059
1480
|
}
|
|
1060
1481
|
const dropzoneRenderer = new DropzoneRenderer();
|
|
1061
1482
|
|
|
1062
1483
|
class TreeDragAndDropService {
|
|
1484
|
+
/** Hides all Dropzones */
|
|
1063
1485
|
clearDropzones() {
|
|
1064
1486
|
dropzoneRenderer.clearCurrentDisplay();
|
|
1065
1487
|
}
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1488
|
+
/**
|
|
1489
|
+
* @returns An object that indicates which dropzones are currently being displayed.
|
|
1490
|
+
* If no dropzones are being displayed, then null is returned.
|
|
1491
|
+
*/
|
|
1069
1492
|
getCurrentlyDisplayedDropzoneFamily() {
|
|
1070
1493
|
return dropzoneRenderer.getCurrentDisplay();
|
|
1071
1494
|
}
|
|
1495
|
+
/**
|
|
1496
|
+
* Causes the dropzone of the TreeRoot to be displayed.
|
|
1497
|
+
*
|
|
1498
|
+
* @remarks
|
|
1499
|
+
* This is a useful function when you want to show the dropzone of a TreeRoot
|
|
1500
|
+
* that has no child branches.
|
|
1501
|
+
*
|
|
1502
|
+
* @param root - The TreeRoot whose dropzone you want to show.
|
|
1503
|
+
*/
|
|
1072
1504
|
showRootDropzone(root) {
|
|
1073
1505
|
dropzoneRenderer.showLowerZones(root);
|
|
1074
1506
|
}
|
|
1507
|
+
/**
|
|
1508
|
+
* @returns An observable that emits a number whenever the drag state changes.
|
|
1509
|
+
*
|
|
1510
|
+
* @remarks
|
|
1511
|
+
* See the `DragStates` enum for a list of possible states.
|
|
1512
|
+
*/
|
|
1075
1513
|
state() {
|
|
1076
1514
|
return dragState.events();
|
|
1077
1515
|
}
|
|
@@ -1082,19 +1520,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
|
|
|
1082
1520
|
type: Injectable
|
|
1083
1521
|
}] });
|
|
1084
1522
|
|
|
1523
|
+
/** Makes an TreeBranch draggable when the host element is dragged */
|
|
1085
1524
|
class DraggableDirective {
|
|
1086
|
-
constructor(
|
|
1087
|
-
this.dragAndDropService = dragAndDropService;
|
|
1525
|
+
constructor(renderer, hostElement) {
|
|
1088
1526
|
renderer.setAttribute(hostElement.nativeElement, "draggable", "true");
|
|
1089
1527
|
renderer.setStyle(hostElement.nativeElement, "cursor", "grab");
|
|
1090
1528
|
}
|
|
1091
1529
|
onDragstart(event) {
|
|
1092
1530
|
if (this.limbleTreeDraggable === undefined)
|
|
1093
1531
|
return;
|
|
1094
|
-
|
|
1532
|
+
dragAndDrop.dragStart(this.limbleTreeDraggable, event);
|
|
1095
1533
|
}
|
|
1096
1534
|
}
|
|
1097
|
-
DraggableDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: DraggableDirective, deps: [{ token:
|
|
1535
|
+
DraggableDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: DraggableDirective, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
1098
1536
|
DraggableDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.12", type: DraggableDirective, isStandalone: true, selector: "[limbleTreeDraggable]", inputs: { limbleTreeDraggable: "limbleTreeDraggable" }, host: { listeners: { "dragstart": "onDragstart($event)" } }, ngImport: i0 });
|
|
1099
1537
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: DraggableDirective, decorators: [{
|
|
1100
1538
|
type: Directive,
|
|
@@ -1102,13 +1540,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
|
|
|
1102
1540
|
selector: "[limbleTreeDraggable]",
|
|
1103
1541
|
standalone: true
|
|
1104
1542
|
}]
|
|
1105
|
-
}], ctorParameters: function () { return [{ type:
|
|
1543
|
+
}], ctorParameters: function () { return [{ type: i0.Renderer2 }, { type: i0.ElementRef }]; }, propDecorators: { limbleTreeDraggable: [{
|
|
1106
1544
|
type: Input
|
|
1107
1545
|
}], onDragstart: [{
|
|
1108
1546
|
type: HostListener,
|
|
1109
1547
|
args: ["dragstart", ["$event"]]
|
|
1110
1548
|
}] } });
|
|
1111
1549
|
|
|
1550
|
+
/**
|
|
1551
|
+
* An Angular module containing all of the entities which provide Drag-And-Drop
|
|
1552
|
+
* functionality.
|
|
1553
|
+
*/
|
|
1112
1554
|
class TreeDragAndDropModule {
|
|
1113
1555
|
}
|
|
1114
1556
|
TreeDragAndDropModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: TreeDragAndDropModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
@@ -1140,32 +1582,34 @@ class LegacyTree {
|
|
|
1140
1582
|
upgradeOptions(legacyOptions) {
|
|
1141
1583
|
return {
|
|
1142
1584
|
indentation: legacyOptions.indent,
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1585
|
+
dragAndDrop: {
|
|
1586
|
+
allowNesting: (branch) => {
|
|
1587
|
+
if (legacyOptions.listMode === true) {
|
|
1588
|
+
return false;
|
|
1589
|
+
}
|
|
1590
|
+
if (legacyOptions.allowNesting === undefined) {
|
|
1591
|
+
return true;
|
|
1592
|
+
}
|
|
1593
|
+
if (typeof legacyOptions.allowNesting === "boolean") {
|
|
1594
|
+
return legacyOptions.allowNesting;
|
|
1595
|
+
}
|
|
1596
|
+
return legacyOptions.allowNesting(branch);
|
|
1597
|
+
},
|
|
1598
|
+
allowDragging: (branch) => {
|
|
1599
|
+
if (legacyOptions.allowDragging === undefined) {
|
|
1600
|
+
return true;
|
|
1601
|
+
}
|
|
1602
|
+
if (typeof legacyOptions.allowDragging === "boolean") {
|
|
1603
|
+
return legacyOptions.allowDragging;
|
|
1604
|
+
}
|
|
1605
|
+
return legacyOptions.allowDragging(branch);
|
|
1606
|
+
},
|
|
1607
|
+
allowDrop: (source, parent, index) => {
|
|
1608
|
+
if (legacyOptions.allowDrop === undefined) {
|
|
1609
|
+
return true;
|
|
1610
|
+
}
|
|
1611
|
+
return legacyOptions.allowDrop(source, parent, index);
|
|
1146
1612
|
}
|
|
1147
|
-
if (legacyOptions.allowNesting === undefined) {
|
|
1148
|
-
return true;
|
|
1149
|
-
}
|
|
1150
|
-
if (typeof legacyOptions.allowNesting === "boolean") {
|
|
1151
|
-
return legacyOptions.allowNesting;
|
|
1152
|
-
}
|
|
1153
|
-
return legacyOptions.allowNesting(branch);
|
|
1154
|
-
},
|
|
1155
|
-
allowDragging: (branch) => {
|
|
1156
|
-
if (legacyOptions.allowDragging === undefined) {
|
|
1157
|
-
return true;
|
|
1158
|
-
}
|
|
1159
|
-
if (typeof legacyOptions.allowDragging === "boolean") {
|
|
1160
|
-
return legacyOptions.allowDragging;
|
|
1161
|
-
}
|
|
1162
|
-
return legacyOptions.allowDragging(branch);
|
|
1163
|
-
},
|
|
1164
|
-
allowDrop: (source, parent, index) => {
|
|
1165
|
-
if (legacyOptions.allowDrop === undefined) {
|
|
1166
|
-
return true;
|
|
1167
|
-
}
|
|
1168
|
-
return legacyOptions.allowDrop(source, parent, index);
|
|
1169
1613
|
}
|
|
1170
1614
|
};
|
|
1171
1615
|
}
|
|
@@ -1177,9 +1621,6 @@ class LegacyTree {
|
|
|
1177
1621
|
}
|
|
1178
1622
|
const bindings = ((_g = (_e = (_d = node.component) === null || _d === void 0 ? void 0 : _d.bindings) !== null && _e !== void 0 ? _e : (_f = options.defaultComponent) === null || _f === void 0 ? void 0 : _f.bindings) !== null && _g !== void 0 ? _g : {});
|
|
1179
1623
|
const nodeData = node;
|
|
1180
|
-
delete nodeData.nodes;
|
|
1181
|
-
delete nodeData.collapsed;
|
|
1182
|
-
delete nodeData.component;
|
|
1183
1624
|
const branch = parent.grow(component, {
|
|
1184
1625
|
inputBindings: bindings,
|
|
1185
1626
|
meta: { nodeData }
|
|
@@ -1283,6 +1724,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
|
|
|
1283
1724
|
}]
|
|
1284
1725
|
}] });
|
|
1285
1726
|
|
|
1727
|
+
/**
|
|
1728
|
+
* Import this Angular module into your application to gain access to the
|
|
1729
|
+
* components, directives, and services provided by Limble Tree.
|
|
1730
|
+
*/
|
|
1286
1731
|
class LimbleTreeModule {
|
|
1287
1732
|
}
|
|
1288
1733
|
LimbleTreeModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: LimbleTreeModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
@@ -1306,5 +1751,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
|
|
|
1306
1751
|
* Generated bundle index. Do not edit.
|
|
1307
1752
|
*/
|
|
1308
1753
|
|
|
1309
|
-
export { DragEndEvent, DragStartEvent, DraggableDirective, DragoverNoChangeDetectDirective, DropEvent, GraftEvent, LegacyTree, LimbleTreeLegacyModule, LimbleTreeModule, LimbleTreeRootComponent, PruneEvent, TreeBranch, TreeCollapseModule, TreeCollapseService, TreeDragAndDropModule, TreeDragAndDropService, TreeError, TreeRoot, TreeService
|
|
1754
|
+
export { DestructionEvent, DragEndEvent, DragStartEvent, DraggableDirective, DragoverNoChangeDetectDirective, DropEvent, GraftEvent, LegacyTree, LimbleTreeLegacyModule, LimbleTreeModule, LimbleTreeRootComponent, PruneEvent, TreeBranch, TreeCollapseModule, TreeCollapseService, TreeDragAndDropModule, TreeDragAndDropService, TreeError, TreeRoot, TreeService };
|
|
1310
1755
|
//# sourceMappingURL=limble-limble-tree.mjs.map
|