wunderbaum 0.5.2 → 0.5.4
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/dist/wunderbaum.css +5 -4
- package/dist/wunderbaum.css.map +1 -1
- package/dist/wunderbaum.d.ts +25 -30
- package/dist/wunderbaum.esm.js +245 -190
- package/dist/wunderbaum.esm.min.js +24 -24
- package/dist/wunderbaum.esm.min.js.map +1 -1
- package/dist/wunderbaum.umd.js +245 -190
- package/dist/wunderbaum.umd.min.js +29 -29
- package/dist/wunderbaum.umd.min.js.map +1 -1
- package/package.json +8 -6
- package/src/common.ts +2 -2
- package/src/debounce.ts +1 -0
- package/src/types.ts +21 -21
- package/src/util.ts +28 -27
- package/src/wb_ext_dnd.ts +57 -21
- package/src/wb_ext_filter.ts +20 -18
- package/src/wb_ext_keynav.ts +8 -8
- package/src/wb_ext_logger.ts +3 -2
- package/src/wb_node.ts +97 -98
- package/src/wunderbaum.scss +5 -4
- package/src/wunderbaum.ts +59 -70
package/src/common.ts
CHANGED
|
@@ -193,7 +193,7 @@ function unflattenSource(source: any): void {
|
|
|
193
193
|
);
|
|
194
194
|
}
|
|
195
195
|
// Inverse keyMap:
|
|
196
|
-
|
|
196
|
+
const longToShort: any = {};
|
|
197
197
|
if (_keyMap) {
|
|
198
198
|
for (const [key, value] of Object.entries(_keyMap)) {
|
|
199
199
|
longToShort[<string>value] = key;
|
|
@@ -277,7 +277,7 @@ export function inflateSourceData(source: any): void {
|
|
|
277
277
|
delete source._positional;
|
|
278
278
|
|
|
279
279
|
function _iter(childList: any[]) {
|
|
280
|
-
for (
|
|
280
|
+
for (const node of childList) {
|
|
281
281
|
// Expand short alias names
|
|
282
282
|
if (_keyMap) {
|
|
283
283
|
// Iterate over a list of names, because we modify inside the loop:
|
package/src/debounce.ts
CHANGED
package/src/types.ts
CHANGED
|
@@ -731,7 +731,7 @@ export type EditOptionsType = {
|
|
|
731
731
|
| Promise<any>;
|
|
732
732
|
};
|
|
733
733
|
|
|
734
|
-
export type GridOptionsType =
|
|
734
|
+
export type GridOptionsType = object;
|
|
735
735
|
|
|
736
736
|
/* -----------------------------------------------------------------------------
|
|
737
737
|
* wb_ext_dnd
|
|
@@ -761,7 +761,7 @@ export type DndOptionsType = {
|
|
|
761
761
|
* Expand nodes after n milliseconds of hovering
|
|
762
762
|
* @default 1500
|
|
763
763
|
*/
|
|
764
|
-
autoExpandMS
|
|
764
|
+
autoExpandMS?: 1500;
|
|
765
765
|
// /**
|
|
766
766
|
// * Additional offset for drop-marker with hitMode = "before"/"after"
|
|
767
767
|
// * @default
|
|
@@ -782,12 +782,12 @@ export type DndOptionsType = {
|
|
|
782
782
|
* true: Drag multiple (i.e. selected) nodes. Also a callback() is allowed
|
|
783
783
|
* @default false
|
|
784
784
|
*/
|
|
785
|
-
multiSource
|
|
785
|
+
multiSource?: false;
|
|
786
786
|
/**
|
|
787
787
|
* Restrict the possible cursor shapes and modifier operations (can also be set in the dragStart event)
|
|
788
788
|
* @default "all"
|
|
789
789
|
*/
|
|
790
|
-
effectAllowed
|
|
790
|
+
effectAllowed?: "all";
|
|
791
791
|
// /**
|
|
792
792
|
// * 'copy'|'link'|'move'|'auto'(calculate from `effectAllowed`+modifier keys) or callback(node, data) that returns such string.
|
|
793
793
|
// * @default
|
|
@@ -797,52 +797,52 @@ export type DndOptionsType = {
|
|
|
797
797
|
* Default dropEffect ('copy', 'link', or 'move') when no modifier is pressed (overide in drag, dragOver).
|
|
798
798
|
* @default "move"
|
|
799
799
|
*/
|
|
800
|
-
dropEffectDefault
|
|
800
|
+
dropEffectDefault?: string;
|
|
801
801
|
/**
|
|
802
802
|
* Prevent dropping nodes from different Wunderbaum trees
|
|
803
803
|
* @default false
|
|
804
804
|
*/
|
|
805
|
-
preventForeignNodes
|
|
805
|
+
preventForeignNodes?: boolean;
|
|
806
806
|
/**
|
|
807
807
|
* Prevent dropping items on unloaded lazy Wunderbaum tree nodes
|
|
808
808
|
* @default true
|
|
809
809
|
*/
|
|
810
|
-
preventLazyParents
|
|
810
|
+
preventLazyParents?: boolean;
|
|
811
811
|
/**
|
|
812
812
|
* Prevent dropping items other than Wunderbaum tree nodes
|
|
813
813
|
* @default false
|
|
814
814
|
*/
|
|
815
|
-
preventNonNodes
|
|
815
|
+
preventNonNodes?: boolean;
|
|
816
816
|
/**
|
|
817
817
|
* Prevent dropping nodes on own descendants
|
|
818
818
|
* @default true
|
|
819
819
|
*/
|
|
820
|
-
preventRecursion
|
|
820
|
+
preventRecursion?: boolean;
|
|
821
821
|
/**
|
|
822
822
|
* Prevent dropping nodes under same direct parent
|
|
823
823
|
* @default false
|
|
824
824
|
*/
|
|
825
|
-
preventSameParent
|
|
825
|
+
preventSameParent?: false;
|
|
826
826
|
/**
|
|
827
827
|
* Prevent dropping nodes 'before self', etc. (move only)
|
|
828
828
|
* @default true
|
|
829
829
|
*/
|
|
830
|
-
preventVoidMoves
|
|
830
|
+
preventVoidMoves?: boolean;
|
|
831
831
|
/**
|
|
832
832
|
* Serialize Node Data to datatransfer object
|
|
833
833
|
* @default true
|
|
834
834
|
*/
|
|
835
|
-
serializeClipboardData
|
|
835
|
+
serializeClipboardData?: boolean | ((nodeData: WbNodeData) => string);
|
|
836
836
|
/**
|
|
837
837
|
* Enable auto-scrolling while dragging
|
|
838
838
|
* @default true
|
|
839
839
|
*/
|
|
840
|
-
scroll
|
|
840
|
+
scroll?: boolean;
|
|
841
841
|
/**
|
|
842
842
|
* Active top/bottom margin in pixel
|
|
843
843
|
* @default 20
|
|
844
844
|
*/
|
|
845
|
-
scrollSensitivity
|
|
845
|
+
scrollSensitivity?: 20;
|
|
846
846
|
// /**
|
|
847
847
|
// * Scroll events every N microseconds
|
|
848
848
|
// * @default 50
|
|
@@ -852,7 +852,7 @@ export type DndOptionsType = {
|
|
|
852
852
|
* Pixel per event
|
|
853
853
|
* @default 5
|
|
854
854
|
*/
|
|
855
|
-
scrollSpeed
|
|
855
|
+
scrollSpeed?: 5;
|
|
856
856
|
// /**
|
|
857
857
|
// * Allow dragging of nodes to different IE windows
|
|
858
858
|
// * @default false
|
|
@@ -862,23 +862,23 @@ export type DndOptionsType = {
|
|
|
862
862
|
* Optional callback passed to `toDict` on dragStart @since 2.38
|
|
863
863
|
* @default null
|
|
864
864
|
*/
|
|
865
|
-
sourceCopyHook
|
|
865
|
+
sourceCopyHook?: null;
|
|
866
866
|
// Events (drag support)
|
|
867
867
|
/**
|
|
868
868
|
* Callback(sourceNode, data), return true, to enable dnd drag
|
|
869
869
|
* @default null
|
|
870
870
|
*/
|
|
871
|
-
dragStart
|
|
871
|
+
dragStart?: null | ((e: WbNodeEventType & { event: DragEvent }) => boolean);
|
|
872
872
|
/**
|
|
873
873
|
* Callback(sourceNode, data)
|
|
874
874
|
* @default null
|
|
875
875
|
*/
|
|
876
|
-
drag
|
|
876
|
+
drag?: null | ((e: WbNodeEventType & { event: DragEvent }) => void);
|
|
877
877
|
/**
|
|
878
878
|
* Callback(sourceNode, data)
|
|
879
879
|
* @default null
|
|
880
880
|
*/
|
|
881
|
-
dragEnd
|
|
881
|
+
dragEnd?: null | ((e: WbNodeEventType & { event: DragEvent }) => void);
|
|
882
882
|
// Events (drop support)
|
|
883
883
|
/**
|
|
884
884
|
* Callback(targetNode, data), return true, to enable dnd drop
|
|
@@ -889,7 +889,7 @@ export type DndOptionsType = {
|
|
|
889
889
|
* Callback(targetNode, data)
|
|
890
890
|
* @default null
|
|
891
891
|
*/
|
|
892
|
-
dragOver
|
|
892
|
+
dragOver?: null | ((e: WbNodeEventType & { event: DragEvent }) => void);
|
|
893
893
|
/**
|
|
894
894
|
* Callback(targetNode, data), return false to prevent autoExpand
|
|
895
895
|
* @default null
|
|
@@ -913,5 +913,5 @@ export type DndOptionsType = {
|
|
|
913
913
|
* Callback(targetNode, data)
|
|
914
914
|
* @default null
|
|
915
915
|
*/
|
|
916
|
-
dragLeave
|
|
916
|
+
dragLeave?: null;
|
|
917
917
|
};
|
package/src/util.ts
CHANGED
|
@@ -137,8 +137,8 @@ export function each(
|
|
|
137
137
|
// accept `null` or `undefined`
|
|
138
138
|
return obj;
|
|
139
139
|
}
|
|
140
|
-
|
|
141
|
-
|
|
140
|
+
const length = obj.length;
|
|
141
|
+
let i = 0;
|
|
142
142
|
|
|
143
143
|
if (typeof length === "number") {
|
|
144
144
|
for (; i < length; i++) {
|
|
@@ -147,7 +147,7 @@ export function each(
|
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
149
|
} else {
|
|
150
|
-
for (
|
|
150
|
+
for (const k in obj) {
|
|
151
151
|
if (callback.call(obj[i], k, obj[k]) === false) {
|
|
152
152
|
break;
|
|
153
153
|
}
|
|
@@ -256,11 +256,13 @@ export function getValueFromElem(elem: HTMLElement, coerce = false): any {
|
|
|
256
256
|
value = input.valueAsNumber;
|
|
257
257
|
break;
|
|
258
258
|
case "radio":
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
259
|
+
{
|
|
260
|
+
const name = input.name;
|
|
261
|
+
const checked = input.parentElement!.querySelector(
|
|
262
|
+
`input[name="${name}"]:checked`
|
|
263
|
+
);
|
|
264
|
+
value = checked ? (<HTMLInputElement>checked).value : undefined;
|
|
265
|
+
}
|
|
264
266
|
break;
|
|
265
267
|
case "text":
|
|
266
268
|
default:
|
|
@@ -438,9 +440,9 @@ export function eventTargetFromSelector(
|
|
|
438
440
|
* ```
|
|
439
441
|
*/
|
|
440
442
|
export function eventToString(event: Event): string {
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
443
|
+
const key = (<KeyboardEvent>event).key;
|
|
444
|
+
const et = event.type;
|
|
445
|
+
const s = [];
|
|
444
446
|
|
|
445
447
|
if ((<KeyboardEvent>event).altKey) {
|
|
446
448
|
s.push("Alt");
|
|
@@ -479,11 +481,11 @@ export function eventToString(event: Event): string {
|
|
|
479
481
|
// TODO: support deep merge --> https://stackoverflow.com/a/42740894
|
|
480
482
|
export function extend(...args: any[]) {
|
|
481
483
|
for (let i = 1; i < args.length; i++) {
|
|
482
|
-
|
|
484
|
+
const arg = args[i];
|
|
483
485
|
if (arg == null) {
|
|
484
486
|
continue;
|
|
485
487
|
}
|
|
486
|
-
for (
|
|
488
|
+
for (const key in arg) {
|
|
487
489
|
if (Object.prototype.hasOwnProperty.call(arg, key)) {
|
|
488
490
|
args[0][key] = arg[key];
|
|
489
491
|
}
|
|
@@ -604,18 +606,17 @@ export function overrideMethod(
|
|
|
604
606
|
handler: FunctionType,
|
|
605
607
|
ctx?: any
|
|
606
608
|
) {
|
|
607
|
-
let prevSuper: FunctionType,
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
};
|
|
609
|
+
let prevSuper: FunctionType, prevSuperApply: FunctionType;
|
|
610
|
+
const self = ctx || instance;
|
|
611
|
+
const prevFunc = instance[methodName];
|
|
612
|
+
const _super = (...args: any[]) => {
|
|
613
|
+
return prevFunc.apply(self, args);
|
|
614
|
+
};
|
|
615
|
+
const _superApply = (argsArray: any[]) => {
|
|
616
|
+
return prevFunc.apply(self, argsArray);
|
|
617
|
+
};
|
|
617
618
|
|
|
618
|
-
|
|
619
|
+
const wrapper = (...args: any[]) => {
|
|
619
620
|
try {
|
|
620
621
|
prevSuper = self._super;
|
|
621
622
|
prevSuperApply = self._superApply;
|
|
@@ -717,7 +718,7 @@ export function getOption(
|
|
|
717
718
|
[ext, name] = name.split(".");
|
|
718
719
|
opts = opts[ext];
|
|
719
720
|
}
|
|
720
|
-
|
|
721
|
+
const value = opts ? opts[name] : null;
|
|
721
722
|
// Use value from value options dict, fallback do default
|
|
722
723
|
return value ?? defaultValue;
|
|
723
724
|
}
|
|
@@ -728,7 +729,7 @@ export function toSet(val: any): Set<string> {
|
|
|
728
729
|
return val;
|
|
729
730
|
}
|
|
730
731
|
if (typeof val === "string") {
|
|
731
|
-
|
|
732
|
+
const set = new Set<string>();
|
|
732
733
|
for (const c of val.split(" ")) {
|
|
733
734
|
set.add(c.trim());
|
|
734
735
|
}
|
|
@@ -812,7 +813,7 @@ export function adaptiveThrottle(
|
|
|
812
813
|
try {
|
|
813
814
|
callback.apply(this, useArgs);
|
|
814
815
|
} catch (error) {
|
|
815
|
-
console.error(error);
|
|
816
|
+
console.error(error); // eslint-disable-line no-console
|
|
816
817
|
}
|
|
817
818
|
const elap = Date.now() - start;
|
|
818
819
|
|
package/src/wb_ext_dnd.ts
CHANGED
|
@@ -123,7 +123,9 @@ export class DndExtension extends WunderbaumExtension<DndOptionsType> {
|
|
|
123
123
|
throw new Error("Unsupported drop region definition: " + res);
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
/**
|
|
126
|
+
/**
|
|
127
|
+
* Calculates the drop region based on the drag event and the allowed drop regions.
|
|
128
|
+
*/
|
|
127
129
|
protected _calcDropRegion(
|
|
128
130
|
e: DragEvent,
|
|
129
131
|
allowed: DropRegionTypeSet | null
|
|
@@ -154,9 +156,9 @@ export class DndExtension extends WunderbaumExtension<DndOptionsType> {
|
|
|
154
156
|
const sp = this.tree.element; // scroll parent
|
|
155
157
|
const scrollTop = sp.scrollTop;
|
|
156
158
|
if (this.currentScrollDir < 0) {
|
|
157
|
-
sp.scrollTop = Math.max(0, scrollTop - dndOpts.scrollSpeed);
|
|
159
|
+
sp.scrollTop = Math.max(0, scrollTop - dndOpts.scrollSpeed!);
|
|
158
160
|
} else if (this.currentScrollDir > 0) {
|
|
159
|
-
sp.scrollTop = scrollTop + dndOpts.scrollSpeed
|
|
161
|
+
sp.scrollTop = scrollTop + dndOpts.scrollSpeed!;
|
|
160
162
|
}
|
|
161
163
|
}
|
|
162
164
|
}
|
|
@@ -181,14 +183,14 @@ export class DndExtension extends WunderbaumExtension<DndOptionsType> {
|
|
|
181
183
|
if (
|
|
182
184
|
scrollTop > 0 &&
|
|
183
185
|
viewportY > 0 &&
|
|
184
|
-
viewportY <= sensitivity + headerHeight
|
|
186
|
+
viewportY <= sensitivity! + headerHeight
|
|
185
187
|
) {
|
|
186
188
|
// Mouse in top 20px area: scroll up
|
|
187
189
|
// sp.scrollTop = Math.max(0, scrollTop - dndOpts.scrollSpeed);
|
|
188
190
|
this.currentScrollDir = -1;
|
|
189
191
|
} else if (
|
|
190
192
|
scrollTop < sp.scrollHeight - height &&
|
|
191
|
-
viewportY >= height - sensitivity
|
|
193
|
+
viewportY >= height - sensitivity!
|
|
192
194
|
) {
|
|
193
195
|
// Mouse in bottom 20px area: scroll down
|
|
194
196
|
// sp.scrollTop = scrollTop + dndOpts.scrollSpeed;
|
|
@@ -220,7 +222,7 @@ export class DndExtension extends WunderbaumExtension<DndOptionsType> {
|
|
|
220
222
|
// --- dragstart ---
|
|
221
223
|
if (e.type === "dragstart") {
|
|
222
224
|
// Set a default definition of allowed effects
|
|
223
|
-
e.dataTransfer!.effectAllowed = dndOpts.effectAllowed
|
|
225
|
+
e.dataTransfer!.effectAllowed = dndOpts.effectAllowed!; //"copyMove"; // "all";
|
|
224
226
|
if (srcNode.isEditing()) {
|
|
225
227
|
srcNode.logDebug("Prevented dragging node in edit mode.");
|
|
226
228
|
e.preventDefault();
|
|
@@ -232,7 +234,7 @@ export class DndExtension extends WunderbaumExtension<DndOptionsType> {
|
|
|
232
234
|
e.preventDefault();
|
|
233
235
|
return false;
|
|
234
236
|
}
|
|
235
|
-
|
|
237
|
+
const nodeData = srcNode.toDict(true, (n: any) => {
|
|
236
238
|
// We don't want to re-use the key on drop:
|
|
237
239
|
n._org_key = n.key;
|
|
238
240
|
delete n.key;
|
|
@@ -240,12 +242,14 @@ export class DndExtension extends WunderbaumExtension<DndOptionsType> {
|
|
|
240
242
|
nodeData._treeId = srcNode.tree.id;
|
|
241
243
|
|
|
242
244
|
if (dndOpts.serializeClipboardData) {
|
|
243
|
-
if (typeof dndOpts.serializeClipboardData === "function")
|
|
245
|
+
if (typeof dndOpts.serializeClipboardData === "function") {
|
|
244
246
|
e.dataTransfer!.setData(
|
|
245
247
|
nodeMimeType,
|
|
246
248
|
dndOpts.serializeClipboardData(nodeData)
|
|
247
249
|
);
|
|
248
|
-
else
|
|
250
|
+
} else {
|
|
251
|
+
e.dataTransfer!.setData(nodeMimeType, JSON.stringify(nodeData));
|
|
252
|
+
}
|
|
249
253
|
}
|
|
250
254
|
// e.dataTransfer!.setData("text/html", $(node.span).html());
|
|
251
255
|
e.dataTransfer!.setData("text/plain", srcNode.title);
|
|
@@ -258,7 +262,9 @@ export class DndExtension extends WunderbaumExtension<DndOptionsType> {
|
|
|
258
262
|
|
|
259
263
|
// --- drag ---
|
|
260
264
|
} else if (e.type === "drag") {
|
|
261
|
-
if (dndOpts.drag)
|
|
265
|
+
if (dndOpts.drag) {
|
|
266
|
+
srcNode._callEvent("dnd.drag", { event: e });
|
|
267
|
+
}
|
|
262
268
|
// --- dragend ---
|
|
263
269
|
} else if (e.type === "dragend") {
|
|
264
270
|
srcNode.setClass("wb-drag-source", false);
|
|
@@ -266,11 +272,37 @@ export class DndExtension extends WunderbaumExtension<DndOptionsType> {
|
|
|
266
272
|
if (this.lastTargetNode) {
|
|
267
273
|
this._leaveNode();
|
|
268
274
|
}
|
|
269
|
-
if (dndOpts.dragEnd)
|
|
275
|
+
if (dndOpts.dragEnd) {
|
|
276
|
+
srcNode._callEvent("dnd.dragEnd", { event: e });
|
|
277
|
+
}
|
|
270
278
|
}
|
|
271
279
|
return true;
|
|
272
280
|
}
|
|
273
281
|
|
|
282
|
+
/* Don't allow void operation ('drop on self').*/
|
|
283
|
+
private _isVoidDrop(
|
|
284
|
+
targetNode: WunderbaumNode,
|
|
285
|
+
srcNode: WunderbaumNode | null,
|
|
286
|
+
dropRegion: DropRegionType | false
|
|
287
|
+
): boolean {
|
|
288
|
+
this.tree.logDebug(
|
|
289
|
+
`_isVoidDrop: ${srcNode} -> ${dropRegion} ${targetNode}`
|
|
290
|
+
);
|
|
291
|
+
// TODO: should be checked on move only
|
|
292
|
+
if (!this.treeOpts.dnd.preventVoidMoves || !srcNode) {
|
|
293
|
+
return false;
|
|
294
|
+
}
|
|
295
|
+
if (
|
|
296
|
+
(dropRegion === "before" && targetNode === srcNode.getNextSibling()) ||
|
|
297
|
+
(dropRegion === "after" && targetNode === srcNode.getPrevSibling())
|
|
298
|
+
) {
|
|
299
|
+
this.tree.logDebug("Prevented before/after self");
|
|
300
|
+
return true;
|
|
301
|
+
}
|
|
302
|
+
// Don't allow dropping nodes on own parent (or self)
|
|
303
|
+
return srcNode === targetNode || srcNode.parent === targetNode;
|
|
304
|
+
}
|
|
305
|
+
|
|
274
306
|
protected onDropEvent(e: DragEvent) {
|
|
275
307
|
// const isLink = event.dataTransfer.types.includes("text/uri-list");
|
|
276
308
|
const srcNode = this.srcNode;
|
|
@@ -278,6 +310,7 @@ export class DndExtension extends WunderbaumExtension<DndOptionsType> {
|
|
|
278
310
|
const targetNode = Wunderbaum.getNode(e)!;
|
|
279
311
|
const dndOpts: DndOptionsType = this.treeOpts.dnd;
|
|
280
312
|
const dt = e.dataTransfer!;
|
|
313
|
+
const dropRegion = this._calcDropRegion(e, this.lastAllowedDropRegions);
|
|
281
314
|
|
|
282
315
|
if (!targetNode) {
|
|
283
316
|
this._leaveNode();
|
|
@@ -294,7 +327,8 @@ export class DndExtension extends WunderbaumExtension<DndOptionsType> {
|
|
|
294
327
|
", de: " +
|
|
295
328
|
dt?.dropEffect,
|
|
296
329
|
", cy: " + e.offsetY,
|
|
297
|
-
", r: " +
|
|
330
|
+
", r: " + dropRegion,
|
|
331
|
+
", srcNode: " + srcNode,
|
|
298
332
|
e
|
|
299
333
|
);
|
|
300
334
|
}
|
|
@@ -320,17 +354,16 @@ export class DndExtension extends WunderbaumExtension<DndOptionsType> {
|
|
|
320
354
|
// Prevent dropping items other than Wunderbaum tree nodes:
|
|
321
355
|
(dndOpts.preventNonNodes && !srcNode) ||
|
|
322
356
|
// Prevent dropping nodes on own descendants:
|
|
323
|
-
(dndOpts.preventRecursion &&
|
|
324
|
-
srcNode &&
|
|
325
|
-
srcNode.isAncestorOf(targetNode)) ||
|
|
357
|
+
(dndOpts.preventRecursion && srcNode?.isAncestorOf(targetNode)) ||
|
|
326
358
|
// Prevent dropping nodes under same direct parent:
|
|
327
359
|
(dndOpts.preventSameParent &&
|
|
328
360
|
srcNode &&
|
|
329
361
|
targetNode.parent === srcNode.parent) ||
|
|
330
|
-
// Don't allow void operation ('drop on self'): TODO: should be
|
|
362
|
+
// Don't allow void operation ('drop on self'): TODO: should be checked on move only
|
|
331
363
|
(dndOpts.preventVoidMoves && targetNode === srcNode)
|
|
332
364
|
) {
|
|
333
365
|
dt.dropEffect = "none";
|
|
366
|
+
this.tree.log("Prevented drop operation");
|
|
334
367
|
return true; // Prevent drop operation
|
|
335
368
|
}
|
|
336
369
|
|
|
@@ -354,23 +387,25 @@ export class DndExtension extends WunderbaumExtension<DndOptionsType> {
|
|
|
354
387
|
const viewportY = e.clientY - this.tree.element.offsetTop;
|
|
355
388
|
this.autoScroll(viewportY);
|
|
356
389
|
|
|
357
|
-
if (dndOpts.dragOver)
|
|
390
|
+
if (dndOpts.dragOver) {
|
|
391
|
+
targetNode._callEvent("dnd.dragOver", { event: e });
|
|
392
|
+
}
|
|
358
393
|
|
|
359
394
|
const region = this._calcDropRegion(e, this.lastAllowedDropRegions);
|
|
360
395
|
|
|
361
396
|
this.lastDropRegion = region;
|
|
362
397
|
|
|
363
398
|
if (
|
|
364
|
-
dndOpts.autoExpandMS > 0 &&
|
|
399
|
+
dndOpts.autoExpandMS! > 0 &&
|
|
365
400
|
targetNode.isExpandable(true) &&
|
|
366
401
|
!targetNode._isLoading &&
|
|
367
|
-
Date.now() - this.lastEnterStamp > dndOpts.autoExpandMS &&
|
|
402
|
+
Date.now() - this.lastEnterStamp > dndOpts.autoExpandMS! &&
|
|
368
403
|
targetNode._callEvent("dnd.dragExpand", { event: e }) !== false
|
|
369
404
|
) {
|
|
370
405
|
targetNode.setExpanded();
|
|
371
406
|
}
|
|
372
407
|
|
|
373
|
-
if (!region) {
|
|
408
|
+
if (!region || this._isVoidDrop(targetNode, srcNode, region)) {
|
|
374
409
|
return; // We already rejected in dragenter
|
|
375
410
|
}
|
|
376
411
|
targetNode.setClass("wb-drop-over", region === "over");
|
|
@@ -386,8 +421,9 @@ export class DndExtension extends WunderbaumExtension<DndOptionsType> {
|
|
|
386
421
|
} else if (e.type === "dragleave") {
|
|
387
422
|
// NOTE: we cannot trust this event, since it is always fired,
|
|
388
423
|
// Instead we remove the marker on dragenter
|
|
389
|
-
if (dndOpts.dragLeave)
|
|
424
|
+
if (dndOpts.dragLeave) {
|
|
390
425
|
targetNode._callEvent("dnd.dragLeave", { event: e });
|
|
426
|
+
}
|
|
391
427
|
// --- drop ---
|
|
392
428
|
} else if (e.type === "drop") {
|
|
393
429
|
e.stopPropagation(); // prevent browser from opening links?
|
package/src/wb_ext_filter.ts
CHANGED
|
@@ -91,15 +91,15 @@ export class FilterExtension extends WunderbaumExtension<FilterOptionsType> {
|
|
|
91
91
|
) {
|
|
92
92
|
let match,
|
|
93
93
|
temp,
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
94
|
+
count = 0;
|
|
95
|
+
const start = Date.now();
|
|
96
|
+
const tree = this.tree;
|
|
97
|
+
const treeOpts = tree.options;
|
|
98
|
+
// escapeTitles = treeOpts.escapeTitles,
|
|
99
|
+
const prevAutoCollapse = treeOpts.autoCollapse;
|
|
100
|
+
const opts = extend({}, treeOpts.filter, _opts);
|
|
101
|
+
const hideMode = opts.mode === "hide";
|
|
102
|
+
const leavesOnly = !!opts.leavesOnly && !branchMode;
|
|
103
103
|
|
|
104
104
|
// Default to 'match title substring (case insensitive)'
|
|
105
105
|
if (typeof filter === "string") {
|
|
@@ -128,16 +128,16 @@ export class FilterExtension extends WunderbaumExtension<FilterOptionsType> {
|
|
|
128
128
|
} else {
|
|
129
129
|
match = escapeRegex(filter); // make sure a '.' is treated literally
|
|
130
130
|
}
|
|
131
|
-
|
|
132
|
-
|
|
131
|
+
const re = new RegExp(match, "i");
|
|
132
|
+
const reHighlight = new RegExp(escapeRegex(filter), "gi");
|
|
133
133
|
filter = (node: WunderbaumNode) => {
|
|
134
134
|
if (!node.title) {
|
|
135
135
|
return false;
|
|
136
136
|
}
|
|
137
137
|
// let text = escapeTitles ? node.title : extractHtmlText(node.title);
|
|
138
|
-
|
|
138
|
+
const text = node.title;
|
|
139
139
|
// `.match` instead of `.test` to get the capture groups
|
|
140
|
-
|
|
140
|
+
const res = text.match(re);
|
|
141
141
|
|
|
142
142
|
if (res && opts.highlight) {
|
|
143
143
|
// if (escapeTitles) {
|
|
@@ -171,6 +171,7 @@ export class FilterExtension extends WunderbaumExtension<FilterOptionsType> {
|
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
tree.filterMode = opts.mode;
|
|
174
|
+
// eslint-disable-next-line prefer-rest-params, prefer-spread
|
|
174
175
|
this.lastFilterArgs = arguments;
|
|
175
176
|
|
|
176
177
|
tree.element.classList.toggle("wb-ext-filter-hide", !!hideMode);
|
|
@@ -268,12 +269,13 @@ export class FilterExtension extends WunderbaumExtension<FilterOptionsType> {
|
|
|
268
269
|
* [ext-filter] Re-apply current filter.
|
|
269
270
|
*/
|
|
270
271
|
updateFilter() {
|
|
271
|
-
|
|
272
|
+
const tree = this.tree;
|
|
272
273
|
if (
|
|
273
274
|
tree.filterMode &&
|
|
274
275
|
this.lastFilterArgs &&
|
|
275
276
|
tree.options.filter?.autoApply
|
|
276
277
|
) {
|
|
278
|
+
// eslint-disable-next-line prefer-spread
|
|
277
279
|
this._applyFilterNoUpdate.apply(this, <any>this.lastFilterArgs);
|
|
278
280
|
} else {
|
|
279
281
|
tree.logWarn("updateFilter(): no filter active.");
|
|
@@ -284,7 +286,7 @@ export class FilterExtension extends WunderbaumExtension<FilterOptionsType> {
|
|
|
284
286
|
* [ext-filter] Reset the filter.
|
|
285
287
|
*/
|
|
286
288
|
clearFilter() {
|
|
287
|
-
|
|
289
|
+
const tree = this.tree;
|
|
288
290
|
// statusNode = tree.root.findDirectChild(KEY_NODATA),
|
|
289
291
|
// escapeTitles = tree.options.escapeTitles;
|
|
290
292
|
tree.enableUpdate(false);
|
|
@@ -341,14 +343,14 @@ function _markFuzzyMatchedChars(
|
|
|
341
343
|
matches: RegExpMatchArray,
|
|
342
344
|
escapeTitles = true
|
|
343
345
|
) {
|
|
344
|
-
|
|
346
|
+
const matchingIndices = [];
|
|
345
347
|
// get the indices of matched characters (Iterate through `RegExpMatchArray`)
|
|
346
348
|
for (
|
|
347
349
|
let _matchingArrIdx = 1;
|
|
348
350
|
_matchingArrIdx < matches.length;
|
|
349
351
|
_matchingArrIdx++
|
|
350
352
|
) {
|
|
351
|
-
|
|
353
|
+
const _mIdx: number =
|
|
352
354
|
// get matching char index by cumulatively adding
|
|
353
355
|
// the matched group length
|
|
354
356
|
matches[_matchingArrIdx].length +
|
|
@@ -357,7 +359,7 @@ function _markFuzzyMatchedChars(
|
|
|
357
359
|
matchingIndices.push(_mIdx);
|
|
358
360
|
}
|
|
359
361
|
// Map each `text` char to its position and store in `textPoses`.
|
|
360
|
-
|
|
362
|
+
const textPoses = text.split("");
|
|
361
363
|
if (escapeTitles) {
|
|
362
364
|
// If escaping the title, then wrap the matching char within exotic chars
|
|
363
365
|
matchingIndices.forEach(function (v) {
|
package/src/wb_ext_keynav.ts
CHANGED
|
@@ -41,13 +41,13 @@ export class KeynavExtension extends WunderbaumExtension<any> {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
onKeyEvent(data: any): boolean | undefined {
|
|
44
|
-
const event = data.event
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
44
|
+
const event = data.event;
|
|
45
|
+
const tree = this.tree;
|
|
46
|
+
const opts = data.options;
|
|
47
|
+
const activate = !event.ctrlKey || opts.autoActivate;
|
|
48
|
+
const curInput = this._getEmbeddedInputElem(event.target);
|
|
49
|
+
const inputHasFocus = curInput && this._isCurInputFocused();
|
|
50
|
+
const navModeOption = opts.navigationModeOption as NavModeEnum;
|
|
51
51
|
// isCellEditMode = tree.navMode === NavigationMode.cellEdit;
|
|
52
52
|
|
|
53
53
|
let focusNode,
|
|
@@ -125,7 +125,7 @@ export class KeynavExtension extends WunderbaumExtension<any> {
|
|
|
125
125
|
}
|
|
126
126
|
tree.lastQuicksearchTime = stamp;
|
|
127
127
|
tree.lastQuicksearchTerm += eventName;
|
|
128
|
-
|
|
128
|
+
const matchNode = tree.findNextNode(
|
|
129
129
|
tree.lastQuicksearchTerm,
|
|
130
130
|
tree.getActiveNode()
|
|
131
131
|
);
|
package/src/wb_ext_logger.ts
CHANGED
|
@@ -33,12 +33,13 @@ export class LoggerExtension extends WunderbaumExtension<any> {
|
|
|
33
33
|
const prefix = this.prefix;
|
|
34
34
|
|
|
35
35
|
overrideMethod(tree, "callEvent", function (name, extra) {
|
|
36
|
+
/* eslint-disable prefer-rest-params */
|
|
36
37
|
if (ignoreEvents.has(name)) {
|
|
37
38
|
return (<any>tree)._superApply(arguments);
|
|
38
39
|
}
|
|
39
40
|
const start = Date.now();
|
|
40
41
|
const res = (<any>tree)._superApply(arguments);
|
|
41
|
-
|
|
42
|
+
tree.logDebug(
|
|
42
43
|
`${prefix}: callEvent('${name}') took ${Date.now() - start} ms.`,
|
|
43
44
|
arguments[1]
|
|
44
45
|
);
|
|
@@ -49,7 +50,7 @@ export class LoggerExtension extends WunderbaumExtension<any> {
|
|
|
49
50
|
|
|
50
51
|
onKeyEvent(data: any): boolean | undefined {
|
|
51
52
|
// this.tree.logInfo("onKeyEvent", eventToString(data.event), data);
|
|
52
|
-
|
|
53
|
+
this.tree.logDebug(`${this.prefix}: onKeyEvent()`, data);
|
|
53
54
|
return;
|
|
54
55
|
}
|
|
55
56
|
}
|