wunderbaum 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +1 -7
- package/dist/wunderbaum.css +3 -3
- package/dist/wunderbaum.d.ts +190 -101
- package/dist/wunderbaum.esm.js +422 -206
- package/dist/wunderbaum.esm.min.js +35 -35
- package/dist/wunderbaum.esm.min.js.map +1 -1
- package/dist/wunderbaum.umd.js +422 -206
- package/dist/wunderbaum.umd.min.js +44 -44
- package/dist/wunderbaum.umd.min.js.map +1 -1
- package/package.json +1 -1
- package/src/common.ts +9 -1
- package/src/deferred.ts +1 -1
- package/src/drag_observer.ts +1 -1
- package/src/types.ts +99 -70
- package/src/util.ts +61 -10
- package/src/wb_ext_dnd.ts +27 -7
- package/src/wb_ext_edit.ts +3 -3
- package/src/wb_ext_filter.ts +1 -1
- package/src/wb_ext_grid.ts +1 -1
- package/src/wb_ext_keynav.ts +1 -1
- package/src/wb_ext_logger.ts +1 -1
- package/src/wb_extension_base.ts +1 -1
- package/src/wb_node.ts +130 -30
- package/src/wb_options.ts +9 -3
- package/src/wunderbaum.scss +6 -3
- package/src/wunderbaum.ts +199 -143
package/src/types.ts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Wunderbaum - types
|
|
3
|
-
* Copyright (c) 2021-
|
|
3
|
+
* Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license.
|
|
4
4
|
* @VERSION, @DATE (https://github.com/mar10/wunderbaum)
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { WunderbaumNode } from "./wb_node";
|
|
8
8
|
import { Wunderbaum } from "./wunderbaum";
|
|
9
9
|
|
|
10
|
-
/** Passed to find... methods. Should return true if node matches. */
|
|
10
|
+
/** Passed to `find...()` methods. Should return true if node matches. */
|
|
11
11
|
export type MatcherCallback = (node: WunderbaumNode) => boolean;
|
|
12
|
+
/** Passed to `sortChildren()` methods. Should return -1, 0, or 1. */
|
|
13
|
+
export type SortCallback = (a: WunderbaumNode, b: WunderbaumNode) => number;
|
|
12
14
|
/** When set as option, called when the value is needed (e.g. `colspan` type definition). */
|
|
13
15
|
export type BoolOptionResolver = (node: WunderbaumNode) => boolean;
|
|
14
16
|
/** When set as option, called when the value is needed (e.g. `icon` type definition). */
|
|
@@ -33,9 +35,11 @@ export interface WbTreeEventType {
|
|
|
33
35
|
type: string;
|
|
34
36
|
/** The affected tree instance. */
|
|
35
37
|
tree: Wunderbaum;
|
|
36
|
-
/** Exposed utility module methods
|
|
38
|
+
/** Exposed utility module methods
|
|
39
|
+
* (see [API docs](https://mar10.github.io/wunderbaum/api/modules/util.html)).
|
|
40
|
+
*/
|
|
37
41
|
util: any;
|
|
38
|
-
/** Originating HTML event
|
|
42
|
+
/** Originating HTML event if any (e.g. `click`). */
|
|
39
43
|
event?: Event;
|
|
40
44
|
// [key: string]: unknown;
|
|
41
45
|
}
|
|
@@ -238,51 +242,61 @@ export interface WbEventInfo {
|
|
|
238
242
|
|
|
239
243
|
export type FilterModeType = null | "dim" | "hide";
|
|
240
244
|
export type ApplyCommandType =
|
|
241
|
-
| "moveUp"
|
|
242
|
-
| "moveDown"
|
|
243
|
-
| "indent"
|
|
244
|
-
| "outdent"
|
|
245
|
-
| "remove"
|
|
246
|
-
| "rename"
|
|
247
245
|
| "addChild"
|
|
248
246
|
| "addSibling"
|
|
249
|
-
| "cut"
|
|
250
247
|
| "copy"
|
|
251
|
-
| "
|
|
248
|
+
| "cut"
|
|
252
249
|
| "down"
|
|
253
250
|
| "first"
|
|
251
|
+
| "indent"
|
|
254
252
|
| "last"
|
|
255
253
|
| "left"
|
|
254
|
+
| "moveDown"
|
|
255
|
+
| "moveUp"
|
|
256
|
+
| "outdent"
|
|
256
257
|
| "pageDown"
|
|
257
258
|
| "pageUp"
|
|
258
259
|
| "parent"
|
|
260
|
+
| "paste"
|
|
261
|
+
| "remove"
|
|
262
|
+
| "rename"
|
|
259
263
|
| "right"
|
|
260
264
|
| "up";
|
|
261
265
|
|
|
262
266
|
export type NodeFilterResponse = "skip" | "branch" | boolean | void;
|
|
263
267
|
export type NodeFilterCallback = (node: WunderbaumNode) => NodeFilterResponse;
|
|
264
|
-
export type AddNodeType = "before" | "after" | "prependChild" | "appendChild";
|
|
265
|
-
export type DndModeType = "before" | "after" | "over";
|
|
266
268
|
|
|
267
|
-
/**
|
|
269
|
+
/**
|
|
270
|
+
* Possible values for {@link WunderbaumNode.setModified()} and {@link Wunderbaum.setModified()}.
|
|
271
|
+
*/
|
|
268
272
|
export enum ChangeType {
|
|
269
273
|
/** Re-render the whole viewport, headers, and all rows. */
|
|
270
274
|
any = "any",
|
|
271
|
-
/**
|
|
275
|
+
/** A node's title, icon, columns, or status have changed. Update the existing row markup. */
|
|
272
276
|
data = "data",
|
|
273
|
-
/**
|
|
274
|
-
|
|
275
|
-
/**
|
|
277
|
+
/** The `tree.columns` definition has changed beyond simple width adjustments. */
|
|
278
|
+
colStructure = "colStructure",
|
|
279
|
+
/** The viewport/window was resized. Adjust layout attributes for all elements. */
|
|
280
|
+
resize = "resize",
|
|
281
|
+
/** A node's definition has changed beyond status and data. Re-render the whole row's markup. */
|
|
276
282
|
row = "row",
|
|
277
|
-
/**
|
|
283
|
+
/** Nodes have been added, removed, etc. Update markup. */
|
|
278
284
|
structure = "structure",
|
|
279
|
-
/** Update current row's classes, to reflect active, selected, ... */
|
|
285
|
+
/** A node's status has changed. Update current row's classes, to reflect active, selected, ... */
|
|
280
286
|
status = "status",
|
|
281
|
-
/** Update the 'top' property of all rows. */
|
|
282
|
-
|
|
287
|
+
/** Vertical scroll event. Update the 'top' property of all rows. */
|
|
288
|
+
scroll = "scroll",
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/* Internal use. */
|
|
292
|
+
export enum RenderFlag {
|
|
293
|
+
clearMarkup = "clearMarkup",
|
|
294
|
+
header = "header",
|
|
295
|
+
redraw = "redraw",
|
|
296
|
+
scroll = "scroll",
|
|
283
297
|
}
|
|
284
298
|
|
|
285
|
-
/** Possible values for
|
|
299
|
+
/** Possible values for {@link WunderbaumNode.setStatus()}. */
|
|
286
300
|
export enum NodeStatusType {
|
|
287
301
|
ok = "ok",
|
|
288
302
|
loading = "loading",
|
|
@@ -368,22 +382,31 @@ export interface MakeVisibleOptions {
|
|
|
368
382
|
|
|
369
383
|
/** Possible values for {@link Wunderbaum.navigate()}. */
|
|
370
384
|
export interface NavigateOptions {
|
|
385
|
+
/** Activate the new node (otherwise focus only). @default true */
|
|
371
386
|
activate?: boolean;
|
|
387
|
+
/** Originating event (e.g. KeyboardEvent) if any. */
|
|
372
388
|
event?: Event;
|
|
373
389
|
}
|
|
374
390
|
|
|
375
391
|
/** Possible values for {@link WunderbaumNode.render()}. */
|
|
376
392
|
export interface RenderOptions {
|
|
393
|
+
/** Which parts need update? @default ChangeType.data */
|
|
377
394
|
change?: ChangeType;
|
|
395
|
+
/** Where to append a new node. @default 'last' */
|
|
378
396
|
after?: any;
|
|
397
|
+
/** @internal. @default false */
|
|
379
398
|
isNew?: boolean;
|
|
399
|
+
/** @internal. @default false */
|
|
380
400
|
preventScroll?: boolean;
|
|
401
|
+
/** @internal. @default false */
|
|
381
402
|
isDataChange?: boolean;
|
|
403
|
+
/** @internal. @default false */
|
|
382
404
|
top?: number;
|
|
405
|
+
/** @internal. @default true */
|
|
383
406
|
resizeCols?: boolean;
|
|
384
407
|
}
|
|
385
408
|
|
|
386
|
-
/** Possible values for {@link scrollIntoView()}. */
|
|
409
|
+
/** Possible values for {@link scrollIntoView()} `options` argument. */
|
|
387
410
|
export interface ScrollIntoViewOptions {
|
|
388
411
|
/** Do not animate (currently not implemented). @default false */
|
|
389
412
|
noAnimation?: boolean;
|
|
@@ -395,13 +418,13 @@ export interface ScrollIntoViewOptions {
|
|
|
395
418
|
ofsY?: number;
|
|
396
419
|
}
|
|
397
420
|
|
|
398
|
-
/** Possible values for {@link Wunderbaum.scrollTo()}. */
|
|
421
|
+
/** Possible values for {@link Wunderbaum.scrollTo()} `options` argument. */
|
|
399
422
|
export interface ScrollToOptions extends ScrollIntoViewOptions {
|
|
400
423
|
/** Which node to scroll into the viewport.*/
|
|
401
424
|
node: WunderbaumNode;
|
|
402
425
|
}
|
|
403
426
|
|
|
404
|
-
/** Possible values for
|
|
427
|
+
/** Possible values for {@link WunderbaumNode.setActive()} `options` argument. */
|
|
405
428
|
export interface SetActiveOptions {
|
|
406
429
|
/** Generate (de)activate event, even if node already has this status (default: false). */
|
|
407
430
|
retrigger?: boolean;
|
|
@@ -417,7 +440,7 @@ export interface SetActiveOptions {
|
|
|
417
440
|
colIdx?: number;
|
|
418
441
|
}
|
|
419
442
|
|
|
420
|
-
/** Possible values for
|
|
443
|
+
/** Possible values for {@link WunderbaumNode.setExpanded()} `options` argument. */
|
|
421
444
|
export interface SetExpandedOptions {
|
|
422
445
|
/** Ignore {@link minExpandLevel}. @default false */
|
|
423
446
|
force?: boolean;
|
|
@@ -431,15 +454,15 @@ export interface SetExpandedOptions {
|
|
|
431
454
|
scrollIntoView?: boolean;
|
|
432
455
|
}
|
|
433
456
|
|
|
434
|
-
/** Possible values for
|
|
457
|
+
/** Possible values for {@link WunderbaumNode.setModified()} `options` argument. */
|
|
435
458
|
export interface SetModifiedOptions {
|
|
436
459
|
/** Force immediate redraw instead of throttled/async mode. @default false */
|
|
437
460
|
immediate?: boolean;
|
|
438
|
-
/** Remove HTML markup of all rendered nodes before redraw. @default false */
|
|
439
|
-
removeMarkup?: boolean;
|
|
461
|
+
// /** Remove HTML markup of all rendered nodes before redraw. @default false */
|
|
462
|
+
// removeMarkup?: boolean;
|
|
440
463
|
}
|
|
441
464
|
|
|
442
|
-
/** Possible values for
|
|
465
|
+
/** Possible values for {@link WunderbaumNode.setSelected()} `options` argument. */
|
|
443
466
|
export interface SetSelectedOptions {
|
|
444
467
|
/** Ignore restrictions. @default false */
|
|
445
468
|
force?: boolean;
|
|
@@ -447,7 +470,7 @@ export interface SetSelectedOptions {
|
|
|
447
470
|
noEvents?: boolean;
|
|
448
471
|
}
|
|
449
472
|
|
|
450
|
-
/** Possible values for
|
|
473
|
+
/** Possible values for {@link WunderbaumNode.setStatus()} `options` argument. */
|
|
451
474
|
export interface SetStatusOptions {
|
|
452
475
|
/** Displayed as status node title. */
|
|
453
476
|
message?: string;
|
|
@@ -455,25 +478,31 @@ export interface SetStatusOptions {
|
|
|
455
478
|
details?: string;
|
|
456
479
|
}
|
|
457
480
|
|
|
458
|
-
/**
|
|
459
|
-
export interface UpdateColumnsOptions {
|
|
460
|
-
calculateCols?: boolean;
|
|
461
|
-
updateRows?: boolean;
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
/** Possible values for {@link Wunderbaum.visitRows()} and {@link Wunderbaum.visitRowsUp()}. */
|
|
481
|
+
/** Options passed to {@link Wunderbaum.visitRows()}. */
|
|
465
482
|
export interface VisitRowsOptions {
|
|
466
|
-
|
|
467
|
-
includeSelf?: boolean;
|
|
483
|
+
/** Skip filtered nodes and children of collapsed nodes. @default false */
|
|
468
484
|
includeHidden?: boolean;
|
|
469
|
-
|
|
485
|
+
/** Return the start node as first result. @default true */
|
|
486
|
+
includeSelf?: boolean;
|
|
487
|
+
/** Traverse in opposite direction, i.e. bottom up. @default false */
|
|
488
|
+
reverse?: boolean;
|
|
489
|
+
/** Start traversal at this node @default first (topmost) tree node */
|
|
470
490
|
start?: WunderbaumNode | null;
|
|
491
|
+
/** Wrap around at last node and continue at the top,
|
|
492
|
+
* until the start node is reached again @default false */
|
|
493
|
+
wrap?: boolean;
|
|
471
494
|
}
|
|
472
495
|
|
|
473
496
|
/* -----------------------------------------------------------------------------
|
|
474
497
|
* wb_ext_dnd
|
|
475
498
|
* ---------------------------------------------------------------------------*/
|
|
476
499
|
|
|
500
|
+
export type InsertNodeType =
|
|
501
|
+
| "before"
|
|
502
|
+
| "after"
|
|
503
|
+
| "prependChild"
|
|
504
|
+
| "appendChild";
|
|
505
|
+
// export type DndModeType = "before" | "after" | "over";
|
|
477
506
|
export type DropRegionType = "over" | "before" | "after";
|
|
478
507
|
export type DropRegionTypeSet = Set<DropRegionType>;
|
|
479
508
|
// type AllowedDropRegionType =
|
|
@@ -490,140 +519,140 @@ export type DropRegionTypeSet = Set<DropRegionType>;
|
|
|
490
519
|
export type DndOptionsType = {
|
|
491
520
|
/**
|
|
492
521
|
* Expand nodes after n milliseconds of hovering
|
|
493
|
-
*
|
|
522
|
+
* @default 1500
|
|
494
523
|
*/
|
|
495
524
|
autoExpandMS: 1500;
|
|
496
525
|
// /**
|
|
497
526
|
// * Additional offset for drop-marker with hitMode = "before"/"after"
|
|
498
|
-
// *
|
|
527
|
+
// * @default
|
|
499
528
|
// */
|
|
500
529
|
// dropMarkerInsertOffsetX: -16;
|
|
501
530
|
// /**
|
|
502
531
|
// * Absolute position offset for .fancytree-drop-marker relatively to ..fancytree-title (icon/img near a node accepting drop)
|
|
503
|
-
// *
|
|
532
|
+
// * @default
|
|
504
533
|
// */
|
|
505
534
|
// dropMarkerOffsetX: -24;
|
|
506
535
|
// /**
|
|
507
536
|
// * Root Container used for drop marker (could be a shadow root)
|
|
508
537
|
// * (#1021 `document.body` is not available yet)
|
|
509
|
-
// *
|
|
538
|
+
// * @default
|
|
510
539
|
// */
|
|
511
540
|
// dropMarkerParent: "body";
|
|
512
541
|
/**
|
|
513
542
|
* true: Drag multiple (i.e. selected) nodes. Also a callback() is allowed
|
|
514
|
-
*
|
|
543
|
+
* @default false
|
|
515
544
|
*/
|
|
516
545
|
multiSource: false;
|
|
517
546
|
/**
|
|
518
547
|
* Restrict the possible cursor shapes and modifier operations (can also be set in the dragStart event)
|
|
519
|
-
*
|
|
548
|
+
* @default "all"
|
|
520
549
|
*/
|
|
521
550
|
effectAllowed: "all";
|
|
522
551
|
// /**
|
|
523
552
|
// * 'copy'|'link'|'move'|'auto'(calculate from `effectAllowed`+modifier keys) or callback(node, data) that returns such string.
|
|
524
|
-
// *
|
|
553
|
+
// * @default
|
|
525
554
|
// */
|
|
526
555
|
// dropEffect: "auto";
|
|
527
556
|
/**
|
|
528
557
|
* Default dropEffect ('copy', 'link', or 'move') when no modifier is pressed (overide in dragDrag, dragOver).
|
|
529
|
-
*
|
|
558
|
+
* @default "move"
|
|
530
559
|
*/
|
|
531
560
|
dropEffectDefault: string;
|
|
532
561
|
/**
|
|
533
562
|
* Prevent dropping nodes from different Wunderbaum trees
|
|
534
|
-
*
|
|
563
|
+
* @default false
|
|
535
564
|
*/
|
|
536
565
|
preventForeignNodes: boolean;
|
|
537
566
|
/**
|
|
538
567
|
* Prevent dropping items on unloaded lazy Wunderbaum tree nodes
|
|
539
|
-
*
|
|
568
|
+
* @default true
|
|
540
569
|
*/
|
|
541
570
|
preventLazyParents: boolean;
|
|
542
571
|
/**
|
|
543
572
|
* Prevent dropping items other than Wunderbaum tree nodes
|
|
544
|
-
*
|
|
573
|
+
* @default false
|
|
545
574
|
*/
|
|
546
575
|
preventNonNodes: boolean;
|
|
547
576
|
/**
|
|
548
577
|
* Prevent dropping nodes on own descendants
|
|
549
|
-
*
|
|
578
|
+
* @default true
|
|
550
579
|
*/
|
|
551
580
|
preventRecursion: boolean;
|
|
552
581
|
/**
|
|
553
582
|
* Prevent dropping nodes under same direct parent
|
|
554
|
-
*
|
|
583
|
+
* @default false
|
|
555
584
|
*/
|
|
556
585
|
preventSameParent: false;
|
|
557
586
|
/**
|
|
558
587
|
* Prevent dropping nodes 'before self', etc. (move only)
|
|
559
|
-
*
|
|
588
|
+
* @default true
|
|
560
589
|
*/
|
|
561
590
|
preventVoidMoves: boolean;
|
|
562
591
|
/**
|
|
563
592
|
* Enable auto-scrolling while dragging
|
|
564
|
-
*
|
|
593
|
+
* @default true
|
|
565
594
|
*/
|
|
566
595
|
scroll: boolean;
|
|
567
596
|
/**
|
|
568
597
|
* Active top/bottom margin in pixel
|
|
569
|
-
*
|
|
598
|
+
* @default 20
|
|
570
599
|
*/
|
|
571
600
|
scrollSensitivity: 20;
|
|
572
601
|
/**
|
|
573
602
|
* Pixel per event
|
|
574
|
-
*
|
|
603
|
+
* @default 5
|
|
575
604
|
*/
|
|
576
605
|
scrollSpeed: 5;
|
|
577
606
|
// /**
|
|
578
607
|
// * Allow dragging of nodes to different IE windows
|
|
579
|
-
// *
|
|
608
|
+
// * @default false
|
|
580
609
|
// */
|
|
581
610
|
// setTextTypeJson: boolean;
|
|
582
611
|
/**
|
|
583
612
|
* Optional callback passed to `toDict` on dragStart @since 2.38
|
|
584
|
-
*
|
|
613
|
+
* @default null
|
|
585
614
|
*/
|
|
586
615
|
sourceCopyHook: null;
|
|
587
616
|
// Events (drag support)
|
|
588
617
|
/**
|
|
589
618
|
* Callback(sourceNode, data), return true, to enable dnd drag
|
|
590
|
-
*
|
|
619
|
+
* @default null
|
|
591
620
|
*/
|
|
592
621
|
dragStart?: WbNodeEventType;
|
|
593
622
|
/**
|
|
594
623
|
* Callback(sourceNode, data)
|
|
595
|
-
*
|
|
624
|
+
* @default null
|
|
596
625
|
*/
|
|
597
626
|
dragDrag: null;
|
|
598
627
|
/**
|
|
599
628
|
* Callback(sourceNode, data)
|
|
600
|
-
*
|
|
629
|
+
* @default null
|
|
601
630
|
*/
|
|
602
631
|
dragEnd: null;
|
|
603
632
|
// Events (drop support)
|
|
604
633
|
/**
|
|
605
634
|
* Callback(targetNode, data), return true, to enable dnd drop
|
|
606
|
-
*
|
|
635
|
+
* @default null
|
|
607
636
|
*/
|
|
608
637
|
dragEnter: null;
|
|
609
638
|
/**
|
|
610
639
|
* Callback(targetNode, data)
|
|
611
|
-
*
|
|
640
|
+
* @default null
|
|
612
641
|
*/
|
|
613
642
|
dragOver: null;
|
|
614
643
|
/**
|
|
615
644
|
* Callback(targetNode, data), return false to prevent autoExpand
|
|
616
|
-
*
|
|
645
|
+
* @default null
|
|
617
646
|
*/
|
|
618
647
|
dragExpand: null;
|
|
619
648
|
/**
|
|
620
649
|
* Callback(targetNode, data)
|
|
621
|
-
*
|
|
650
|
+
* @default null
|
|
622
651
|
*/
|
|
623
652
|
dragDrop: null;
|
|
624
653
|
/**
|
|
625
654
|
* Callback(targetNode, data)
|
|
626
|
-
*
|
|
655
|
+
* @default null
|
|
627
656
|
*/
|
|
628
657
|
dragLeave: null;
|
|
629
658
|
};
|
package/src/util.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Wunderbaum - util
|
|
3
|
-
* Copyright (c) 2021-
|
|
3
|
+
* Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license.
|
|
4
4
|
* @VERSION, @DATE (https://github.com/mar10/wunderbaum)
|
|
5
5
|
*/
|
|
6
6
|
/** @module util */
|
|
@@ -202,17 +202,19 @@ export function extractHtmlText(s: string) {
|
|
|
202
202
|
* the element is checked, unchecked, or indeterminate.
|
|
203
203
|
* For datetime input control a numerical value is assumed, etc.
|
|
204
204
|
*
|
|
205
|
-
* Common use case: store the new user input in
|
|
205
|
+
* Common use case: store the new user input in a `change` event handler:
|
|
206
206
|
*
|
|
207
207
|
* ```ts
|
|
208
208
|
* change: (e) => {
|
|
209
|
+
* const tree = e.tree;
|
|
210
|
+
* const node = e.node;
|
|
209
211
|
* // Read the value from the input control that triggered the change event:
|
|
210
|
-
* let value =
|
|
211
|
-
* //
|
|
212
|
-
*
|
|
212
|
+
* let value = tree.getValueFromElem(e.element);
|
|
213
|
+
* // and store it to the node model (assuming the column id matches the property name)
|
|
214
|
+
* node.data[e.info.colId] = value;
|
|
213
215
|
* },
|
|
214
216
|
* ```
|
|
215
|
-
* @param elem `<input>` or `<select>` element Also a parent `span.wb-col` is accepted.
|
|
217
|
+
* @param elem `<input>` or `<select>` element. Also a parent `span.wb-col` is accepted.
|
|
216
218
|
* @param coerce pass true to convert date/time inputs to `Date`.
|
|
217
219
|
* @returns the value
|
|
218
220
|
*/
|
|
@@ -280,6 +282,23 @@ export function getValueFromElem(elem: HTMLElement, coerce = false): any {
|
|
|
280
282
|
* value is truethy, falsy, or `null`.
|
|
281
283
|
* For datetime input control a numerical value is assumed, etc.
|
|
282
284
|
*
|
|
285
|
+
* Common use case: update embedded input controls in a `render` event handler:
|
|
286
|
+
*
|
|
287
|
+
* ```ts
|
|
288
|
+
* render: (e) => {
|
|
289
|
+
* // e.node.log(e.type, e, e.node.data);
|
|
290
|
+
*
|
|
291
|
+
* for (const col of Object.values(e.renderColInfosById)) {
|
|
292
|
+
* switch (col.id) {
|
|
293
|
+
* default:
|
|
294
|
+
* // Assumption: we named column.id === node.data.NAME
|
|
295
|
+
* util.setValueToElem(col.elem, e.node.data[col.id]);
|
|
296
|
+
* break;
|
|
297
|
+
* }
|
|
298
|
+
* }
|
|
299
|
+
* },
|
|
300
|
+
* ```
|
|
301
|
+
*
|
|
283
302
|
* @param elem `<input>` or `<select>` element Also a parent `span.wb-col` is accepted.
|
|
284
303
|
* @param value a value that matches the target element.
|
|
285
304
|
*/
|
|
@@ -313,7 +332,6 @@ export function setValueToElem(elem: HTMLElement, value: any): void {
|
|
|
313
332
|
case "datetime":
|
|
314
333
|
case "datetime-local":
|
|
315
334
|
input.valueAsDate = new Date(value);
|
|
316
|
-
// input.valueAsDate = value; // breaks in Edge?
|
|
317
335
|
break;
|
|
318
336
|
case "number":
|
|
319
337
|
case "range":
|
|
@@ -324,7 +342,7 @@ export function setValueToElem(elem: HTMLElement, value: any): void {
|
|
|
324
342
|
}
|
|
325
343
|
break;
|
|
326
344
|
case "radio":
|
|
327
|
-
error(
|
|
345
|
+
error(`Not yet implemented: ${type}`);
|
|
328
346
|
// const name = input.name;
|
|
329
347
|
// const checked = input.parentElement!.querySelector(
|
|
330
348
|
// `input[name="${name}"]:checked`
|
|
@@ -350,7 +368,7 @@ export function setValueToElem(elem: HTMLElement, value: any): void {
|
|
|
350
368
|
}
|
|
351
369
|
}
|
|
352
370
|
|
|
353
|
-
/** Show/hide element by setting the `display`style to 'none'. */
|
|
371
|
+
/** Show/hide element by setting the `display` style to 'none'. */
|
|
354
372
|
export function setElemDisplay(elem: string | Element, flag: boolean): void {
|
|
355
373
|
const style = (<HTMLElement>elemFromSelector(elem)).style;
|
|
356
374
|
if (flag) {
|
|
@@ -401,7 +419,23 @@ export function eventTargetFromSelector(
|
|
|
401
419
|
* The result also contains a prefix for modifiers if any, for example
|
|
402
420
|
* `"x"`, `"F2"`, `"Control+Home"`, or `"Shift+clickright"`.
|
|
403
421
|
* This is especially useful in `switch` statements, to make sure that modifier
|
|
404
|
-
* keys are considered and handled correctly
|
|
422
|
+
* keys are considered and handled correctly:
|
|
423
|
+
* ```ts
|
|
424
|
+
* const eventName = util.eventToString(e);
|
|
425
|
+
* switch (eventName) {
|
|
426
|
+
* case "+":
|
|
427
|
+
* case "Add":
|
|
428
|
+
* ...
|
|
429
|
+
* break;
|
|
430
|
+
* case "Enter":
|
|
431
|
+
* case "End":
|
|
432
|
+
* case "Control+End":
|
|
433
|
+
* case "Meta+ArrowDown":
|
|
434
|
+
* case "PageDown":
|
|
435
|
+
* ...
|
|
436
|
+
* break;
|
|
437
|
+
* }
|
|
438
|
+
* ```
|
|
405
439
|
*/
|
|
406
440
|
export function eventToString(event: Event): string {
|
|
407
441
|
let key = (<KeyboardEvent>event).key,
|
|
@@ -706,6 +740,23 @@ export function toSet(val: any): Set<string> {
|
|
|
706
740
|
throw new Error("Cannot convert to Set<string>: " + val);
|
|
707
741
|
}
|
|
708
742
|
|
|
743
|
+
// /** Check if a string is contained in an Array or Set. */
|
|
744
|
+
// export function isAnyOf(s: string, items: Array<string>|Set<string>): boolean {
|
|
745
|
+
// return Array.prototype.includes.call(items, s)
|
|
746
|
+
// }
|
|
747
|
+
|
|
748
|
+
// /** Check if an Array or Set has at least one matching entry. */
|
|
749
|
+
// export function hasAnyOf(container: Array<string>|Set<string>, items: Array<string>): boolean {
|
|
750
|
+
// if (Array.isArray(container)) {
|
|
751
|
+
// return container.some(v => )
|
|
752
|
+
// }
|
|
753
|
+
// return container.some(v => {})
|
|
754
|
+
// // const container = toSet(items);
|
|
755
|
+
// // const itemSet = toSet(items);
|
|
756
|
+
// // Array.prototype.includes
|
|
757
|
+
// // throw new Error("Cannot convert to Set<string>: " + val);
|
|
758
|
+
// }
|
|
759
|
+
|
|
709
760
|
/** Return a canonical string representation for an object's type (e.g. 'array', 'number', ...). */
|
|
710
761
|
export function type(obj: any): string {
|
|
711
762
|
return Object.prototype.toString
|
package/src/wb_ext_dnd.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Wunderbaum - ext-dnd
|
|
3
|
-
* Copyright (c) 2021-
|
|
3
|
+
* Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license.
|
|
4
4
|
* @VERSION, @DATE (https://github.com/mar10/wunderbaum)
|
|
5
5
|
*/
|
|
6
6
|
import * as util from "./util";
|
|
@@ -137,7 +137,7 @@ export class DndExtension extends WunderbaumExtension {
|
|
|
137
137
|
// Only 'before' and 'after':
|
|
138
138
|
return dy > ROW_HEIGHT / 2 ? "after" : "before";
|
|
139
139
|
}
|
|
140
|
-
return "over";
|
|
140
|
+
// return "over";
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
/* Implement auto scrolling when drag cursor is in top/bottom area of scroll parent. */
|
|
@@ -225,6 +225,8 @@ export class DndExtension extends WunderbaumExtension {
|
|
|
225
225
|
|
|
226
226
|
protected onDropEvent(e: DragEvent) {
|
|
227
227
|
// const isLink = event.dataTransfer.types.includes("text/uri-list");
|
|
228
|
+
const srcNode = this.srcNode;
|
|
229
|
+
const srcTree = srcNode ? srcNode.tree : null;
|
|
228
230
|
const targetNode = Wunderbaum.getNode(e)!;
|
|
229
231
|
const dndOpts = this.treeOpts.dnd;
|
|
230
232
|
const dt = e.dataTransfer!;
|
|
@@ -233,7 +235,7 @@ export class DndExtension extends WunderbaumExtension {
|
|
|
233
235
|
this._leaveNode();
|
|
234
236
|
return;
|
|
235
237
|
}
|
|
236
|
-
if (
|
|
238
|
+
if (!["dragenter", "dragover", "dragleave"].includes(e.type)) {
|
|
237
239
|
this.tree.logDebug(
|
|
238
240
|
"onDropEvent." +
|
|
239
241
|
e.type +
|
|
@@ -261,13 +263,29 @@ export class DndExtension extends WunderbaumExtension {
|
|
|
261
263
|
this.lastEnterStamp = Date.now();
|
|
262
264
|
|
|
263
265
|
if (
|
|
264
|
-
// Don't
|
|
265
|
-
|
|
266
|
-
|
|
266
|
+
// Don't drop on status node:
|
|
267
|
+
targetNode.isStatusNode() ||
|
|
268
|
+
// Prevent dropping nodes from different Wunderbaum trees:
|
|
269
|
+
(dndOpts.preventForeignNodes && targetNode.tree !== srcTree) ||
|
|
270
|
+
// Prevent dropping items on unloaded lazy Wunderbaum tree nodes:
|
|
271
|
+
(dndOpts.preventLazyParents && !targetNode.isLoaded()) ||
|
|
272
|
+
// Prevent dropping items other than Wunderbaum tree nodes:
|
|
273
|
+
(dndOpts.preventNonNodes && !srcNode) ||
|
|
274
|
+
// Prevent dropping nodes on own descendants:
|
|
275
|
+
(dndOpts.preventRecursion &&
|
|
276
|
+
srcNode &&
|
|
277
|
+
srcNode.isAncestorOf(targetNode)) ||
|
|
278
|
+
// Prevent dropping nodes under same direct parent:
|
|
279
|
+
(dndOpts.preventSameParent &&
|
|
280
|
+
srcNode &&
|
|
281
|
+
targetNode.parent === srcNode.parent) ||
|
|
282
|
+
// Don't allow void operation ('drop on self'): TODO: should be checke onn move only
|
|
283
|
+
(dndOpts.preventVoidMoves && targetNode === srcNode)
|
|
267
284
|
) {
|
|
268
285
|
dt.dropEffect = "none";
|
|
269
286
|
return true; // Prevent drop operation
|
|
270
287
|
}
|
|
288
|
+
|
|
271
289
|
// User may return a set of regions (or `false` to prevent drop)
|
|
272
290
|
let regionSet = targetNode._callEvent("dnd.dragEnter", { event: e });
|
|
273
291
|
//
|
|
@@ -321,9 +339,11 @@ export class DndExtension extends WunderbaumExtension {
|
|
|
321
339
|
} else if (e.type === "drop") {
|
|
322
340
|
e.stopPropagation(); // prevent browser from opening links?
|
|
323
341
|
this._leaveNode();
|
|
342
|
+
const region = this.lastDropRegion;
|
|
324
343
|
targetNode._callEvent("dnd.drop", {
|
|
325
344
|
event: e,
|
|
326
|
-
region:
|
|
345
|
+
region: region,
|
|
346
|
+
defaultDropMode: region === "over" ? "appendChild" : region,
|
|
327
347
|
sourceNode: this.srcNode,
|
|
328
348
|
});
|
|
329
349
|
}
|
package/src/wb_ext_edit.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Wunderbaum - ext-edit
|
|
3
|
-
* Copyright (c) 2021-
|
|
3
|
+
* Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license.
|
|
4
4
|
* @VERSION, @DATE (https://github.com/mar10/wunderbaum)
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
} from "./util";
|
|
18
18
|
import { debounce } from "./debounce";
|
|
19
19
|
import { WunderbaumNode } from "./wb_node";
|
|
20
|
-
import {
|
|
20
|
+
import { InsertNodeType } from "./types";
|
|
21
21
|
import { WbNodeData } from "./wb_options";
|
|
22
22
|
|
|
23
23
|
// const START_MARKER = "\uFFF7";
|
|
@@ -310,7 +310,7 @@ export class EditExtension extends WunderbaumExtension {
|
|
|
310
310
|
* Create a new child or sibling node and start edit mode.
|
|
311
311
|
*/
|
|
312
312
|
createNode(
|
|
313
|
-
mode:
|
|
313
|
+
mode: InsertNodeType = "after",
|
|
314
314
|
node?: WunderbaumNode | null,
|
|
315
315
|
init?: string | WbNodeData
|
|
316
316
|
) {
|
package/src/wb_ext_filter.ts
CHANGED
package/src/wb_ext_grid.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Wunderbaum - ext-grid
|
|
3
|
-
* Copyright (c) 2021-
|
|
3
|
+
* Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license.
|
|
4
4
|
* @VERSION, @DATE (https://github.com/mar10/wunderbaum)
|
|
5
5
|
*/
|
|
6
6
|
import { Wunderbaum } from "./wunderbaum";
|
package/src/wb_ext_keynav.ts
CHANGED
package/src/wb_ext_logger.ts
CHANGED