wunderbaum 0.12.1 → 0.14.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/dist/wunderbaum.css +40 -11
- package/dist/wunderbaum.css.map +1 -1
- package/dist/wunderbaum.d.ts +648 -306
- package/dist/wunderbaum.esm.js +920 -356
- package/dist/wunderbaum.esm.min.js +27 -27
- package/dist/wunderbaum.esm.min.js.map +1 -1
- package/dist/wunderbaum.umd.js +920 -356
- package/dist/wunderbaum.umd.min.js +31 -31
- package/dist/wunderbaum.umd.min.js.map +1 -1
- package/package.json +3 -2
- package/src/common.ts +49 -6
- package/src/types.ts +182 -33
- package/src/util.ts +75 -15
- package/src/wb_ext_dnd.ts +21 -20
- package/src/wb_ext_edit.ts +2 -2
- package/src/wb_ext_filter.ts +122 -43
- package/src/wb_ext_grid.ts +1 -1
- package/src/wb_extension_base.ts +19 -3
- package/src/wb_node.ts +239 -195
- package/src/wb_options.ts +172 -117
- package/src/wunderbaum.scss +9 -1
- package/src/wunderbaum.ts +574 -126
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wunderbaum",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"title": "A treegrid control.",
|
|
5
5
|
"description": "JavaScript tree/grid/treegrid control.",
|
|
6
6
|
"homepage": "https://github.com/mar10/wunderbaum",
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
"@rollup/plugin-replace": "^6.0.2",
|
|
53
53
|
"@rollup/plugin-terser": "^0.4.4",
|
|
54
54
|
"@rollup/plugin-typescript": "^12.1.2",
|
|
55
|
+
"@types/firebase": "^2.4.32",
|
|
55
56
|
"@types/jest": "^29.5.14",
|
|
56
57
|
"@typescript-eslint/eslint-plugin": "^8.24.0",
|
|
57
58
|
"@typescript-eslint/parser": "^8.24.0",
|
|
@@ -104,7 +105,7 @@
|
|
|
104
105
|
"scripts": {
|
|
105
106
|
"test": "npm run lint && npm run build:js && grunt ci --verbose",
|
|
106
107
|
"api_docs": "typedoc && touch docs/api/.nojekyll && rm docs/unittest/*.*; cp test/unit/*.* docs/unittest",
|
|
107
|
-
"format": "eslint src --fix && prettier src docs/demo -w && npm run lint",
|
|
108
|
+
"format": "eslint src docs/demo --fix && prettier src docs/demo -w && npm run lint",
|
|
108
109
|
"lint": "prettier src docs/demo --check && eslint src docs/demo && tsc -t esnext --moduleResolution node --noEmit src/wunderbaum.ts",
|
|
109
110
|
"build:minjs:umd": "terser build/wunderbaum.umd.js --compress --mangle --source-map \"base='build',url='wunderbaum.umd.min.js.map',filename='wunderbaum.umd.js'\" --output build/wunderbaum.umd.min.js",
|
|
110
111
|
"build:minjs:esm": "terser build/wunderbaum.esm.js --compress --mangle --source-map \"base='build',url='wunderbaum.esm.min.js.map',filename='wunderbaum.esm.js'\" --output build/wunderbaum.esm.min.js",
|
package/src/common.ts
CHANGED
|
@@ -4,7 +4,14 @@
|
|
|
4
4
|
* @VERSION, @DATE (https://github.com/mar10/wunderbaum)
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
ApplyCommandType,
|
|
9
|
+
NavigationType,
|
|
10
|
+
SourceListType,
|
|
11
|
+
SourceObjectType,
|
|
12
|
+
IconMapType,
|
|
13
|
+
MatcherCallback,
|
|
14
|
+
} from "./types";
|
|
8
15
|
import * as util from "./util";
|
|
9
16
|
import { WunderbaumNode } from "./wb_node";
|
|
10
17
|
|
|
@@ -28,13 +35,23 @@ export const RENDER_MAX_PREFETCH = 5;
|
|
|
28
35
|
export const RENDER_MIN_PREFETCH = 5;
|
|
29
36
|
/** Minimum column width if not set otherwise. */
|
|
30
37
|
export const DEFAULT_MIN_COL_WIDTH = 4;
|
|
38
|
+
/**
|
|
39
|
+
* A value for `node.type` that by convention may be used to mark a node as directory.
|
|
40
|
+
* It may be used to sort 'directories' to the top.
|
|
41
|
+
*/
|
|
42
|
+
export const NODE_TYPE_FOLDER = "folder";
|
|
31
43
|
/** Regular expression to detect if a string describes an image URL (in contrast
|
|
32
44
|
* to a class name). Strings are considered image urls if they contain '.' or '/'.
|
|
45
|
+
* `<` is ignored, because it is probably an html tag.
|
|
33
46
|
*/
|
|
34
|
-
export const
|
|
47
|
+
export const TEST_FILE_PATH = /^(?!.*<).*[/.]/;
|
|
48
|
+
/** Regular expression to detect if a string describes an HTML element. */
|
|
49
|
+
export const TEST_HTML = /</;
|
|
35
50
|
// export const RECURSIVE_REQUEST_ERROR = "$recursive_request";
|
|
36
51
|
// export const INVALID_REQUEST_TARGET_ERROR = "$request_target_invalid";
|
|
37
52
|
|
|
53
|
+
/** Currently supported default icon maps. */
|
|
54
|
+
type IconLibrary = "bootstrap" | "fontawesome6";
|
|
38
55
|
/**
|
|
39
56
|
* Default node icons for icon libraries
|
|
40
57
|
*
|
|
@@ -42,7 +59,7 @@ export const TEST_IMG = new RegExp(/\.|\//);
|
|
|
42
59
|
* - 'fontawesome6' {@link https://fontawesome.com/icons}
|
|
43
60
|
*
|
|
44
61
|
*/
|
|
45
|
-
export const
|
|
62
|
+
export const defaultIconMaps: { [key in IconLibrary]: IconMapType } = {
|
|
46
63
|
bootstrap: {
|
|
47
64
|
error: "bi bi-exclamation-triangle",
|
|
48
65
|
// loading: "bi bi-hourglass-split wb-busy",
|
|
@@ -90,7 +107,7 @@ export const iconMaps: { [key: string]: { [key: string]: string } } = {
|
|
|
90
107
|
radioChecked: "fa-solid fa-circle",
|
|
91
108
|
radioUnchecked: "fa-regular fa-circle",
|
|
92
109
|
radioUnknown: "fa-regular fa-circle-question",
|
|
93
|
-
folder: "fa-
|
|
110
|
+
folder: "fa-regular fa-folder-closed",
|
|
94
111
|
folderOpen: "fa-regular fa-folder-open",
|
|
95
112
|
folderLazy: "fa-solid fa-folder-plus",
|
|
96
113
|
doc: "fa-regular fa-file",
|
|
@@ -140,7 +157,24 @@ export const RESERVED_TREE_SOURCE_KEYS: Set<string> = new Set([
|
|
|
140
157
|
// ]);
|
|
141
158
|
|
|
142
159
|
/** Map `KeyEvent.key` to navigation action. */
|
|
143
|
-
export const
|
|
160
|
+
export const KEY_TO_NAVIGATION_MAP: { [key: string]: NavigationType } = {
|
|
161
|
+
ArrowDown: "down",
|
|
162
|
+
ArrowLeft: "left",
|
|
163
|
+
ArrowRight: "right",
|
|
164
|
+
ArrowUp: "up",
|
|
165
|
+
Backspace: "parent",
|
|
166
|
+
End: "lastCol",
|
|
167
|
+
Home: "firstCol",
|
|
168
|
+
"Control+End": "last",
|
|
169
|
+
"Control+Home": "first",
|
|
170
|
+
"Meta+ArrowDown": "last", // macOs
|
|
171
|
+
"Meta+ArrowUp": "first", // macOs
|
|
172
|
+
PageDown: "pageDown",
|
|
173
|
+
PageUp: "pageUp",
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
/** Map `KeyEvent.key` to navigation action. */
|
|
177
|
+
export const KEY_TO_COMMAND_MAP: { [key: string]: ApplyCommandType } = {
|
|
144
178
|
" ": "toggleSelect",
|
|
145
179
|
"+": "expand",
|
|
146
180
|
Add: "expand",
|
|
@@ -197,7 +231,9 @@ export function makeNodeTitleStartMatcher(s: string): MatcherCallback {
|
|
|
197
231
|
};
|
|
198
232
|
}
|
|
199
233
|
|
|
200
|
-
/** Compare two nodes by title (case-insensitive).
|
|
234
|
+
/** Compare two nodes by title (case-insensitive).
|
|
235
|
+
* @deprecated Use `key` option instead of `cmp` in sort methods.
|
|
236
|
+
*/
|
|
201
237
|
export function nodeTitleSorter(a: WunderbaumNode, b: WunderbaumNode): number {
|
|
202
238
|
const x = a.title.toLowerCase();
|
|
203
239
|
const y = b.title.toLowerCase();
|
|
@@ -205,6 +241,13 @@ export function nodeTitleSorter(a: WunderbaumNode, b: WunderbaumNode): number {
|
|
|
205
241
|
return x === y ? 0 : x > y ? 1 : -1;
|
|
206
242
|
}
|
|
207
243
|
|
|
244
|
+
// /** Compare nodes by title (case-insensitive). */
|
|
245
|
+
// export function nodeTitleKeyGetter(
|
|
246
|
+
// node: WunderbaumNode
|
|
247
|
+
// ): string | number | Array<any> {
|
|
248
|
+
// return node.title.toLowerCase();
|
|
249
|
+
// }
|
|
250
|
+
|
|
208
251
|
/**
|
|
209
252
|
* Convert 'flat' to 'nested' format.
|
|
210
253
|
*
|
package/src/types.ts
CHANGED
|
@@ -60,8 +60,13 @@ export type MatcherCallback = (node: WunderbaumNode) => boolean;
|
|
|
60
60
|
export type WbIconBadgeCallback = (
|
|
61
61
|
e: WbIconBadgeEventType
|
|
62
62
|
) => WbIconBadgeEventResultType;
|
|
63
|
-
/**
|
|
63
|
+
/**
|
|
64
|
+
* Passed to `sort()` methods. Should return -1, 0, or 1.
|
|
65
|
+
* @deprecated Use SortKeyCallback instead
|
|
66
|
+
*/
|
|
64
67
|
export type SortCallback = (a: WunderbaumNode, b: WunderbaumNode) => number;
|
|
68
|
+
/** Passed to `sort()` methods. Should return a representation that can be compared using `<`. */
|
|
69
|
+
export type SortKeyCallback = (node: WunderbaumNode) => string | number | any[];
|
|
65
70
|
/** When set as option, called when the value is needed (e.g. `colspan` type definition). */
|
|
66
71
|
export type BoolOptionResolver = (node: WunderbaumNode) => boolean;
|
|
67
72
|
/** When set as option, called when the value is needed (e.g. `icon` type definition). */
|
|
@@ -99,6 +104,12 @@ export type NodeToDictCallback = (
|
|
|
99
104
|
*/
|
|
100
105
|
export type NodeSelectCallback = (node: WunderbaumNode) => boolean | void;
|
|
101
106
|
|
|
107
|
+
/** @internal */
|
|
108
|
+
export type DeprecationOptions = {
|
|
109
|
+
since?: string;
|
|
110
|
+
hint?: string;
|
|
111
|
+
};
|
|
112
|
+
|
|
102
113
|
/**
|
|
103
114
|
* See also {@link WunderbaumNode.getOption|WunderbaumNode.getOption()}
|
|
104
115
|
* to evaluate `node.NAME` setting and `tree.types[node.type].NAME`.
|
|
@@ -163,7 +174,7 @@ export interface WbNodeData {
|
|
|
163
174
|
title: string;
|
|
164
175
|
/** Pass true to set node tooltip to the node's title. Defaults to {@link WunderbaumOptions.tooltip}. */
|
|
165
176
|
tooltip?: TooltipOption;
|
|
166
|
-
/** Inherit shared settings from the matching entry in
|
|
177
|
+
/** Inherit shared settings from the matching entry in `InitWunderbaumOptions.types`. */
|
|
167
178
|
type?: string;
|
|
168
179
|
/** Set to `true` to prevent selection. Defaults to {@link WunderbaumOptions.unselectable}. */
|
|
169
180
|
unselectable?: boolean;
|
|
@@ -173,11 +184,37 @@ export interface WbNodeData {
|
|
|
173
184
|
[key: string]: unknown;
|
|
174
185
|
}
|
|
175
186
|
|
|
187
|
+
/** A plain object (dictionary) that defines node icons. */
|
|
188
|
+
export interface IconMapType {
|
|
189
|
+
error: string;
|
|
190
|
+
loading: string;
|
|
191
|
+
noData: string;
|
|
192
|
+
expanderExpanded: string;
|
|
193
|
+
expanderCollapsed: string;
|
|
194
|
+
expanderLazy: string;
|
|
195
|
+
checkChecked: string;
|
|
196
|
+
checkUnchecked: string;
|
|
197
|
+
checkUnknown: string;
|
|
198
|
+
radioChecked: string;
|
|
199
|
+
radioUnchecked: string;
|
|
200
|
+
radioUnknown: string;
|
|
201
|
+
folder: string;
|
|
202
|
+
folderOpen: string;
|
|
203
|
+
folderLazy: string;
|
|
204
|
+
doc: string;
|
|
205
|
+
colSortable: string;
|
|
206
|
+
colSortAsc: string;
|
|
207
|
+
colSortDesc: string;
|
|
208
|
+
colFilter: string;
|
|
209
|
+
colFilterActive: string;
|
|
210
|
+
colMenu: string;
|
|
211
|
+
[key: string]: string;
|
|
212
|
+
}
|
|
176
213
|
/* -----------------------------------------------------------------------------
|
|
177
214
|
* EVENT CALLBACK TYPES
|
|
178
215
|
* ---------------------------------------------------------------------------*/
|
|
179
216
|
|
|
180
|
-
/**
|
|
217
|
+
/** Retuen value of an event handler that can return `false` to prevent the default action. */
|
|
181
218
|
export type WbCancelableEventResultType = false | void;
|
|
182
219
|
|
|
183
220
|
export interface WbTreeEventType {
|
|
@@ -518,29 +555,43 @@ export interface WbEventInfo {
|
|
|
518
555
|
// export type WbNodeCallbackType = (e: WbNodeEventType) => any;
|
|
519
556
|
// export type WbRenderCallbackType = (e: WbRenderEventType) => void;
|
|
520
557
|
|
|
521
|
-
export type FilterModeType = null | "dim" | "hide";
|
|
558
|
+
export type FilterModeType = null | "mark" | "dim" | "hide";
|
|
522
559
|
export type SelectModeType = "single" | "multi" | "hier";
|
|
560
|
+
|
|
561
|
+
export type NavigationType =
|
|
562
|
+
| "down"
|
|
563
|
+
| "first"
|
|
564
|
+
| "firstCol"
|
|
565
|
+
| "last"
|
|
566
|
+
| "lastCol"
|
|
567
|
+
| "left"
|
|
568
|
+
| "nextMatch"
|
|
569
|
+
| "pageDown"
|
|
570
|
+
| "pageUp"
|
|
571
|
+
| "parent"
|
|
572
|
+
| "prevMatch"
|
|
573
|
+
| "right"
|
|
574
|
+
| "up";
|
|
575
|
+
|
|
523
576
|
export type ApplyCommandType =
|
|
577
|
+
| NavigationType
|
|
524
578
|
| "addChild"
|
|
525
579
|
| "addSibling"
|
|
580
|
+
| "collapse"
|
|
581
|
+
| "collapseAll"
|
|
526
582
|
| "copy"
|
|
527
583
|
| "cut"
|
|
528
|
-
| "
|
|
529
|
-
| "
|
|
584
|
+
| "edit"
|
|
585
|
+
| "expand"
|
|
586
|
+
| "expandAll"
|
|
530
587
|
| "indent"
|
|
531
|
-
| "last"
|
|
532
|
-
| "left"
|
|
533
588
|
| "moveDown"
|
|
534
589
|
| "moveUp"
|
|
535
590
|
| "outdent"
|
|
536
|
-
| "pageDown"
|
|
537
|
-
| "pageUp"
|
|
538
|
-
| "parent"
|
|
539
591
|
| "paste"
|
|
540
592
|
| "remove"
|
|
541
593
|
| "rename"
|
|
542
|
-
| "
|
|
543
|
-
| "up";
|
|
594
|
+
| "toggleSelect";
|
|
544
595
|
|
|
545
596
|
export type NodeFilterResponse = "skip" | "branch" | boolean | void;
|
|
546
597
|
export type NodeFilterCallback = (node: WunderbaumNode) => NodeFilterResponse;
|
|
@@ -607,6 +658,23 @@ export enum NavModeEnum {
|
|
|
607
658
|
row = "row",
|
|
608
659
|
}
|
|
609
660
|
|
|
661
|
+
/** Translatable strings. */
|
|
662
|
+
export type TranslationsType = {
|
|
663
|
+
/** @default "Loading..." */
|
|
664
|
+
loading: string;
|
|
665
|
+
/** @default "Error" */
|
|
666
|
+
loadError: string;
|
|
667
|
+
/** @default "No data" */
|
|
668
|
+
noData: string;
|
|
669
|
+
/** @default " » " */
|
|
670
|
+
breadcrumbDelimiter: string;
|
|
671
|
+
/** @default "Found ${matches} of ${count}" */
|
|
672
|
+
queryResult: string;
|
|
673
|
+
/** @default "No result" */
|
|
674
|
+
noMatch: string;
|
|
675
|
+
/** @default "${match} of ${matches}" */
|
|
676
|
+
matchIndex: string;
|
|
677
|
+
};
|
|
610
678
|
/* -----------------------------------------------------------------------------
|
|
611
679
|
* METHOD OPTIONS TYPES
|
|
612
680
|
* ---------------------------------------------------------------------------*/
|
|
@@ -681,8 +749,7 @@ export interface FilterNodesOptions {
|
|
|
681
749
|
/**Hide expanders if all child nodes are hidden by filter @default false */
|
|
682
750
|
hideExpanders?: boolean;
|
|
683
751
|
/** Highlight matches by wrapping inside `<mark>` tags.
|
|
684
|
-
* Does not work for filter callbacks.
|
|
685
|
-
* @default true
|
|
752
|
+
* Does not work for filter callbacks. @default true
|
|
686
753
|
*/
|
|
687
754
|
highlight?: boolean;
|
|
688
755
|
/** Match end nodes only @default false */
|
|
@@ -693,6 +760,44 @@ export interface FilterNodesOptions {
|
|
|
693
760
|
noData?: boolean | string;
|
|
694
761
|
}
|
|
695
762
|
|
|
763
|
+
/** Possible values for {@link Wunderbaum.getState}. */
|
|
764
|
+
export interface GetStateOptions {
|
|
765
|
+
/** Include the active node's key (and expand its parents). @default true */
|
|
766
|
+
activeKey?: boolean;
|
|
767
|
+
/** Include the expanded keys. @default false */
|
|
768
|
+
expandedKeys?: boolean;
|
|
769
|
+
/** Include the selected keys. @default false */
|
|
770
|
+
selectedKeys?: boolean;
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
/** Possible values for {@link Wunderbaum.setState}. */
|
|
774
|
+
export interface SetStateOptions {
|
|
775
|
+
/** Recursively load lazy nodes as needed. @default false */
|
|
776
|
+
expandLazy?: boolean;
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
/** Used by {@link Wunderbaum.getState} and {@link Wunderbaum.setState}. */
|
|
780
|
+
export interface TreeStateDefinition {
|
|
781
|
+
/** List of expanded node's keys. */
|
|
782
|
+
expandedKeys: Array<string> | undefined;
|
|
783
|
+
/** The active node's key if any. */
|
|
784
|
+
activeKey: string | null;
|
|
785
|
+
/** The active column index if any. */
|
|
786
|
+
activeColIdx: number | null;
|
|
787
|
+
/** List of selected node's keys. */
|
|
788
|
+
selectedKeys: Array<string> | undefined;
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
/** Possible values for {@link Wunderbaum.loadLazyNodes} `options` argument. */
|
|
792
|
+
export interface LoadLazyNodesOptions {
|
|
793
|
+
/** Expand node (otherwise load, but keep collapsed). @default true */
|
|
794
|
+
expand?: boolean;
|
|
795
|
+
/** Force reloading even if already loaded. @default false */
|
|
796
|
+
force?: boolean;
|
|
797
|
+
/** Do not send events. @default false */
|
|
798
|
+
noEvents?: boolean;
|
|
799
|
+
}
|
|
800
|
+
|
|
696
801
|
/** Possible values for {@link WunderbaumNode.makeVisible}. */
|
|
697
802
|
export interface MakeVisibleOptions {
|
|
698
803
|
/** Do not animate expand (currently not implemented). @default false */
|
|
@@ -830,7 +935,17 @@ export interface SetStatusOptions {
|
|
|
830
935
|
}
|
|
831
936
|
|
|
832
937
|
/**
|
|
833
|
-
* Possible values for {@link
|
|
938
|
+
* Possible values for {@link Wunderbaum.reload} `options` argument.
|
|
939
|
+
*/
|
|
940
|
+
export interface ReloadOptions {
|
|
941
|
+
/** Load this source instead. @default initial source (if loaded via ajax) */
|
|
942
|
+
source?: SourceType;
|
|
943
|
+
/** Reactivate currently active node if any. @default true */
|
|
944
|
+
reactivate?: boolean;
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
/**
|
|
948
|
+
* Possible values for {@link WunderbaumNode.resetNativeChildOrder} `options` argument.
|
|
834
949
|
*/
|
|
835
950
|
export interface ResetOrderOptions {
|
|
836
951
|
/** Sort descendants recursively. @default true */
|
|
@@ -842,31 +957,37 @@ export interface ResetOrderOptions {
|
|
|
842
957
|
}
|
|
843
958
|
|
|
844
959
|
/**
|
|
845
|
-
* Possible values for {@link
|
|
960
|
+
* Possible values for {@link Wunderbaum.sort} and {@link WunderbaumNode.sort}
|
|
961
|
+
* `options` argument.
|
|
846
962
|
*/
|
|
847
|
-
export interface
|
|
848
|
-
/** Column ID as defined in `tree.columns` definition. Required if updateColInfo is true.*/
|
|
849
|
-
colId?: string;
|
|
963
|
+
export interface SortOptions {
|
|
850
964
|
/** The name of the node property that will be used for sorting.
|
|
851
|
-
* @
|
|
965
|
+
* Mandatory, unless {@link key} or {@link colId} are given.
|
|
852
966
|
*/
|
|
853
967
|
propName?: string;
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
968
|
+
/** Callback that determines a node representation for comparison.
|
|
969
|
+
* @default {@link common.nodeTitleKeyGetter} */
|
|
970
|
+
key?: SortKeyCallback;
|
|
971
|
+
/** Callback that determines the order. @default {@link common.nodeTitleSorter}
|
|
972
|
+
* @deprecated use {@link key} instead
|
|
973
|
+
*/
|
|
974
|
+
cmp?: SortCallback;
|
|
975
|
+
/** Sort order 'asc' or 'desc'.
|
|
976
|
+
* @default 'asc' (or if `updateColInfo` is true, the rotated status of the
|
|
977
|
+
* column definition.
|
|
978
|
+
* See also {@link WunderbaumOptions.sortFoldersFirst}.
|
|
979
|
+
*/
|
|
857
980
|
order?: SortOrderType;
|
|
981
|
+
/** Sort descendants recursively. @default true */
|
|
982
|
+
deep?: boolean;
|
|
983
|
+
/** Sort string values case insensitive. @default false */
|
|
984
|
+
caseInsensitive?: boolean;
|
|
858
985
|
/**
|
|
859
986
|
* Sort by this property if order is `undefined`.
|
|
860
987
|
* See also {@link WunderbaumNode.resetNativeChildOrder}.
|
|
861
988
|
* @default `_nativeIndex`.
|
|
862
989
|
*/
|
|
863
990
|
nativeOrderPropName?: string;
|
|
864
|
-
/** Sort string values case insensitive. @default false */
|
|
865
|
-
caseInsensitive?: boolean;
|
|
866
|
-
/** Sort descendants recursively. @default true */
|
|
867
|
-
deep?: boolean;
|
|
868
|
-
// /** Rotate sort order (asc -> desc -> none) before sorting. @default false */
|
|
869
|
-
// rotateOrder?: boolean;
|
|
870
991
|
/**
|
|
871
992
|
* Rotate sort order (asc -> desc -> none) before sorting.
|
|
872
993
|
* Update the sort icons in the column header
|
|
@@ -877,8 +998,16 @@ export interface SortByPropertyOptions {
|
|
|
877
998
|
* @default false
|
|
878
999
|
*/
|
|
879
1000
|
updateColInfo?: boolean;
|
|
1001
|
+
/** Column ID as defined in `tree.columns` definition. Required if updateColInfo is true.*/
|
|
1002
|
+
colId?: string;
|
|
880
1003
|
}
|
|
881
1004
|
|
|
1005
|
+
/**
|
|
1006
|
+
* Possible values for {@link WunderbaumNode.sortByProperty} `options` argument.
|
|
1007
|
+
* @deprecated
|
|
1008
|
+
*/
|
|
1009
|
+
export type SortByPropertyOptions = SortOptions;
|
|
1010
|
+
|
|
882
1011
|
/** Options passed to {@link Wunderbaum.visitRows}. */
|
|
883
1012
|
export interface VisitRowsOptions {
|
|
884
1013
|
/** Skip filtered nodes and children of collapsed nodes. @default false */
|
|
@@ -897,6 +1026,19 @@ export interface VisitRowsOptions {
|
|
|
897
1026
|
/* -----------------------------------------------------------------------------
|
|
898
1027
|
* wb_ext_filter
|
|
899
1028
|
* ---------------------------------------------------------------------------*/
|
|
1029
|
+
|
|
1030
|
+
/**
|
|
1031
|
+
* Passed as tree option.filer.connect to configure automatic integration of
|
|
1032
|
+
* filter UI controls. @experimental
|
|
1033
|
+
*/
|
|
1034
|
+
export interface FilterConnectType {
|
|
1035
|
+
inputElem: string | HTMLInputElement | null;
|
|
1036
|
+
modeButton?: string | HTMLButtonElement | null;
|
|
1037
|
+
nextButton?: string | HTMLButtonElement | HTMLAnchorElement | null;
|
|
1038
|
+
prevButton?: string | HTMLButtonElement | HTMLAnchorElement | null;
|
|
1039
|
+
matchInfoElem?: string | HTMLElement | null;
|
|
1040
|
+
}
|
|
1041
|
+
|
|
900
1042
|
/**
|
|
901
1043
|
* Passed as tree options to configure default filtering behavior.
|
|
902
1044
|
*
|
|
@@ -905,10 +1047,12 @@ export interface VisitRowsOptions {
|
|
|
905
1047
|
*/
|
|
906
1048
|
export type FilterOptionsType = {
|
|
907
1049
|
/**
|
|
908
|
-
* Element or selector of
|
|
1050
|
+
* Element or selector of input controls and buttons for filter query strings.
|
|
1051
|
+
* @experimental
|
|
1052
|
+
* @since 0.13
|
|
909
1053
|
* @default null
|
|
910
1054
|
*/
|
|
911
|
-
|
|
1055
|
+
connect?: null | FilterConnectType;
|
|
912
1056
|
/**
|
|
913
1057
|
* Re-apply last filter if lazy data is loaded
|
|
914
1058
|
* @default true
|
|
@@ -1019,6 +1163,7 @@ export type DropEffectAllowedType =
|
|
|
1019
1163
|
|
|
1020
1164
|
export type DropRegionType = "over" | "before" | "after";
|
|
1021
1165
|
export type DropRegionTypeSet = Set<DropRegionType>;
|
|
1166
|
+
export type DropRegionTypeList = Array<DropRegionType>;
|
|
1022
1167
|
// type AllowedDropRegionType =
|
|
1023
1168
|
// | "after"
|
|
1024
1169
|
// | "afterBefore"
|
|
@@ -1044,6 +1189,8 @@ export interface DropEventType extends WbNodeEventType {
|
|
|
1044
1189
|
node: WunderbaumNode;
|
|
1045
1190
|
/** The source node if any. */
|
|
1046
1191
|
sourceNode: WunderbaumNode;
|
|
1192
|
+
/** The DataTransfer object. */
|
|
1193
|
+
dataTransfer: DataTransfer;
|
|
1047
1194
|
}
|
|
1048
1195
|
|
|
1049
1196
|
export type DndOptionsType = {
|
|
@@ -1189,7 +1336,9 @@ export type DndOptionsType = {
|
|
|
1189
1336
|
*/
|
|
1190
1337
|
dragEnter?:
|
|
1191
1338
|
| null
|
|
1192
|
-
| ((
|
|
1339
|
+
| ((
|
|
1340
|
+
e: DropEventType
|
|
1341
|
+
) => DropRegionType | DropRegionTypeSet | DropRegionTypeList | boolean);
|
|
1193
1342
|
/**
|
|
1194
1343
|
* Callback(targetNode, data)
|
|
1195
1344
|
* @default null
|
package/src/util.ts
CHANGED
|
@@ -36,6 +36,8 @@ const ENTITY_MAP: { [key: string]: string } = {
|
|
|
36
36
|
"/": "/",
|
|
37
37
|
};
|
|
38
38
|
|
|
39
|
+
export type NotPromise<T> = T extends Promise<any> ? never : T;
|
|
40
|
+
|
|
39
41
|
export type FunctionType = (...args: any[]) => any;
|
|
40
42
|
export type EventCallbackType = (e: Event) => boolean | void;
|
|
41
43
|
type PromiseCallbackType = (val: any) => void;
|
|
@@ -175,7 +177,7 @@ export function each(
|
|
|
175
177
|
return obj;
|
|
176
178
|
}
|
|
177
179
|
|
|
178
|
-
/** Shortcut for `throw new Error(msg)
|
|
180
|
+
/** Shortcut for `throw new Error(msg)`. */
|
|
179
181
|
export function error(msg: string) {
|
|
180
182
|
throw new Error(msg);
|
|
181
183
|
}
|
|
@@ -424,19 +426,6 @@ export function elemFromSelector<T = HTMLElement>(obj: string | T): T | null {
|
|
|
424
426
|
return obj as T;
|
|
425
427
|
}
|
|
426
428
|
|
|
427
|
-
// /** Return a EventTarget from selector or cast an existing element. */
|
|
428
|
-
// export function eventTargetFromSelector(
|
|
429
|
-
// obj: string | EventTarget
|
|
430
|
-
// ): EventTarget | null {
|
|
431
|
-
// if (!obj) {
|
|
432
|
-
// return null;
|
|
433
|
-
// }
|
|
434
|
-
// if (typeof obj === "string") {
|
|
435
|
-
// return document.querySelector(obj) as EventTarget;
|
|
436
|
-
// }
|
|
437
|
-
// return obj as EventTarget;
|
|
438
|
-
// }
|
|
439
|
-
|
|
440
429
|
/**
|
|
441
430
|
* Return a canonical descriptive string for a keyboard or mouse event.
|
|
442
431
|
*
|
|
@@ -796,6 +785,11 @@ export function toPixel(
|
|
|
796
785
|
throw new Error(`Expected a string like '123px': ${defaults}`);
|
|
797
786
|
}
|
|
798
787
|
|
|
788
|
+
/** Cast any value to <T>. */
|
|
789
|
+
export function unsafeCast<T>(value: any): T {
|
|
790
|
+
return value as T;
|
|
791
|
+
}
|
|
792
|
+
|
|
799
793
|
/** Return the the boolean value of the first non-null element.
|
|
800
794
|
* Example:
|
|
801
795
|
* ```js
|
|
@@ -887,7 +881,7 @@ export function adaptiveThrottle(
|
|
|
887
881
|
const throttledFn = (...args: any[]) => {
|
|
888
882
|
if (waiting) {
|
|
889
883
|
pendingArgs = args;
|
|
890
|
-
// console.log(`adaptiveThrottle()
|
|
884
|
+
// console.log(`adaptiveThrottle() queueing request #${waiting}...`, args);
|
|
891
885
|
waiting += 1;
|
|
892
886
|
} else {
|
|
893
887
|
// Prevent invocations while running or blocking
|
|
@@ -945,3 +939,69 @@ export function adaptiveThrottle(
|
|
|
945
939
|
};
|
|
946
940
|
return throttledFn;
|
|
947
941
|
}
|
|
942
|
+
|
|
943
|
+
/**
|
|
944
|
+
* MurmurHash3 implementation for strings.
|
|
945
|
+
* @param key The input string to hash.
|
|
946
|
+
* @param asString Optional convert result to zero-padded string of 8 characters.
|
|
947
|
+
* @param seed Optional seed value.
|
|
948
|
+
* @returns A 32-bit hash as a number or string.
|
|
949
|
+
*/
|
|
950
|
+
export function murmurHash3(
|
|
951
|
+
key: string,
|
|
952
|
+
asString = true,
|
|
953
|
+
seed: number = 0
|
|
954
|
+
): number | string {
|
|
955
|
+
let h1 = seed;
|
|
956
|
+
const remainder = key.length & 3; // key.length % 4
|
|
957
|
+
const bytes = key.length - remainder;
|
|
958
|
+
const c1 = 0xcc9e2d51;
|
|
959
|
+
const c2 = 0x1b873593;
|
|
960
|
+
|
|
961
|
+
let i = 0;
|
|
962
|
+
while (i < bytes) {
|
|
963
|
+
let k1 =
|
|
964
|
+
(key.charCodeAt(i) & 0xff) |
|
|
965
|
+
((key.charCodeAt(++i) & 0xff) << 8) |
|
|
966
|
+
((key.charCodeAt(++i) & 0xff) << 16) |
|
|
967
|
+
((key.charCodeAt(++i) & 0xff) << 24);
|
|
968
|
+
++i;
|
|
969
|
+
|
|
970
|
+
k1 = Math.imul(k1, c1);
|
|
971
|
+
k1 = (k1 << 15) | (k1 >>> 17);
|
|
972
|
+
k1 = Math.imul(k1, c2);
|
|
973
|
+
|
|
974
|
+
h1 ^= k1;
|
|
975
|
+
h1 = (h1 << 13) | (h1 >>> 19);
|
|
976
|
+
h1 = Math.imul(h1, 5) + 0xe6546b64;
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
let k1 = 0;
|
|
980
|
+
switch (remainder) {
|
|
981
|
+
case 3:
|
|
982
|
+
k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16;
|
|
983
|
+
// fall through
|
|
984
|
+
case 2:
|
|
985
|
+
k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8;
|
|
986
|
+
// fall through
|
|
987
|
+
case 1:
|
|
988
|
+
k1 ^= key.charCodeAt(i) & 0xff;
|
|
989
|
+
k1 = Math.imul(k1, c1);
|
|
990
|
+
k1 = (k1 << 15) | (k1 >>> 17);
|
|
991
|
+
k1 = Math.imul(k1, c2);
|
|
992
|
+
h1 ^= k1;
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
h1 ^= key.length;
|
|
996
|
+
h1 ^= h1 >>> 16;
|
|
997
|
+
h1 = Math.imul(h1, 0x85ebca6b);
|
|
998
|
+
h1 ^= h1 >>> 13;
|
|
999
|
+
h1 = Math.imul(h1, 0xc2b2ae35);
|
|
1000
|
+
h1 ^= h1 >>> 16;
|
|
1001
|
+
|
|
1002
|
+
if (asString) {
|
|
1003
|
+
// Convert to 8 digit hex string
|
|
1004
|
+
return (h1 >>> 0).toString(16).padStart(8, "0");
|
|
1005
|
+
}
|
|
1006
|
+
return h1 >>> 0; // Convert to unsigned 32-bit integer
|
|
1007
|
+
}
|