wunderbaum 0.6.0 → 0.7.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/README.md CHANGED
@@ -9,24 +9,24 @@
9
9
 
10
10
  <!-- [![Build Status](https://travis-ci.com/mar10/wunderbaum.svg?branch=main)](https://travis-ci.com/github/mar10/wunderbaum) -->
11
11
 
12
+ > A modern tree/treegrid control for the web. <br>
12
13
  > Potential successor of [Fancytree](https://github.com/mar10/fancytree).
13
14
 
14
- **NOTE: Status _beta_. Do not use in production!**
15
+ **Status _beta_:<br>API, Markup, Stylesheet, etc. are still subject to change.**
15
16
 
16
17
  [![Demo](docs/assets/teaser_2.png?raw=true)](https://mar10.github.io/wunderbaum/demo/)
17
18
 
18
- <center>
19
- Supports drag and drop,, editing, filtering, and multi-selection.<br>
20
- Written in TypeScript, transpiled to ES6 (esm & umd).<br>
21
- Performant handling of big data structures.<br>
22
- Provide an object oriented API.<br>
23
- Framework agnostic.<br>
24
- Zero dependencies.<br>
25
- Keyboard support.
26
- </center>
19
+ - Supports drag and drop, editing, filtering, and multi-selection.
20
+ - Written in TypeScript, transpiled to ES6 (esm & umd).
21
+ - Performant handling of big data structures.
22
+ - Provide an object oriented API.
23
+ - Framework agnostic.
24
+ - Zero dependencies.
25
+ - Keyboard support.
27
26
 
28
27
  ### Details
29
28
 
30
29
  - [Online Demo](https://mar10.github.io/wunderbaum/demo/)
31
- - [User Guide](https://mar10.github.io/wunderbaum/)
30
+ - [Documentation](https://mar10.github.io/wunderbaum/)
32
31
  - [API Reference](https://mar10.github.io/wunderbaum/api/index.html)
32
+ - [Quick Start](https://mar10.github.io/wunderbaum/#/tutorial/quick_start)
@@ -257,7 +257,7 @@ declare module "common" {
257
257
  * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license.
258
258
  * @VERSION, @DATE (https://github.com/mar10/wunderbaum)
259
259
  */
260
- import { MatcherCallback } from "types";
260
+ import { MatcherCallback, SourceObjectType } from "types";
261
261
  import { WunderbaumNode } from "wb_node";
262
262
  export const DEFAULT_DEBUGLEVEL = 4;
263
263
  /**
@@ -312,7 +312,16 @@ declare module "common" {
312
312
  export function makeNodeTitleStartMatcher(s: string): MatcherCallback;
313
313
  /** Compare two nodes by title (case-insensitive). */
314
314
  export function nodeTitleSorter(a: WunderbaumNode, b: WunderbaumNode): number;
315
- export function inflateSourceData(source: any): void;
315
+ /**
316
+ * Decompresses the source data by
317
+ * - converting from 'flat' to 'nested' format
318
+ * - expanding short alias names to long names (if defined in _keyMap)
319
+ * - resolving value indexes to value strings (if defined in _valueMap)
320
+ *
321
+ * @param source - The source object to be decompressed.
322
+ * @returns void
323
+ */
324
+ export function decompressSourceData(source: SourceObjectType): void;
316
325
  }
317
326
  declare module "deferred" {
318
327
  /*!
@@ -1201,14 +1210,17 @@ declare module "types" {
1201
1210
  export type SourceListType = Array<WbNodeData>;
1202
1211
  export interface SourceObjectType {
1203
1212
  _format?: "nested" | "flat";
1213
+ _version?: number;
1204
1214
  types?: NodeTypeDefinitionMap;
1205
1215
  columns?: ColumnDefinitionList;
1206
1216
  children: SourceListType;
1207
1217
  _keyMap?: {
1208
1218
  [key: string]: string;
1209
1219
  };
1210
- _typeList?: Array<string>;
1211
1220
  _positional?: Array<string>;
1221
+ _valueMap?: {
1222
+ [key: string]: Array<string>;
1223
+ };
1212
1224
  }
1213
1225
  /** Possible initilization for tree nodes. */
1214
1226
  export type SourceType = string | SourceListType | SourceAjaxType | SourceObjectType;
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * Wunderbaum - util
3
3
  * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license.
4
- * v0.6.0, Wed, 08 Nov 2023 19:58:55 GMT (https://github.com/mar10/wunderbaum)
4
+ * v0.7.0, Sat, 09 Dec 2023 13:47:27 GMT (https://github.com/mar10/wunderbaum)
5
5
  */
6
6
  /** @module util */
7
7
  /** Readable names for `MouseEvent.button` */
@@ -765,7 +765,7 @@ var util = /*#__PURE__*/Object.freeze({
765
765
  /*!
766
766
  * Wunderbaum - types
767
767
  * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license.
768
- * v0.6.0, Wed, 08 Nov 2023 19:58:55 GMT (https://github.com/mar10/wunderbaum)
768
+ * v0.7.0, Sat, 09 Dec 2023 13:47:27 GMT (https://github.com/mar10/wunderbaum)
769
769
  */
770
770
  /**
771
771
  * Possible values for {@link WunderbaumNode.update()} and {@link Wunderbaum.update()}.
@@ -829,7 +829,7 @@ var NavModeEnum;
829
829
  /*!
830
830
  * Wunderbaum - wb_extension_base
831
831
  * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license.
832
- * v0.6.0, Wed, 08 Nov 2023 19:58:55 GMT (https://github.com/mar10/wunderbaum)
832
+ * v0.7.0, Sat, 09 Dec 2023 13:47:27 GMT (https://github.com/mar10/wunderbaum)
833
833
  */
834
834
  class WunderbaumExtension {
835
835
  constructor(tree, id, defaults) {
@@ -1185,7 +1185,7 @@ function throttle(func, wait = 0, options = {}) {
1185
1185
  /*!
1186
1186
  * Wunderbaum - ext-filter
1187
1187
  * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license.
1188
- * v0.6.0, Wed, 08 Nov 2023 19:58:55 GMT (https://github.com/mar10/wunderbaum)
1188
+ * v0.7.0, Sat, 09 Dec 2023 13:47:27 GMT (https://github.com/mar10/wunderbaum)
1189
1189
  */
1190
1190
  const START_MARKER = "\uFFF7";
1191
1191
  const END_MARKER = "\uFFF8";
@@ -1485,7 +1485,7 @@ function _markFuzzyMatchedChars(text, matches, escapeTitles = true) {
1485
1485
  /*!
1486
1486
  * Wunderbaum - ext-keynav
1487
1487
  * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license.
1488
- * v0.6.0, Wed, 08 Nov 2023 19:58:55 GMT (https://github.com/mar10/wunderbaum)
1488
+ * v0.7.0, Sat, 09 Dec 2023 13:47:27 GMT (https://github.com/mar10/wunderbaum)
1489
1489
  */
1490
1490
  const QUICKSEARCH_DELAY = 500;
1491
1491
  class KeynavExtension extends WunderbaumExtension {
@@ -1831,7 +1831,7 @@ class KeynavExtension extends WunderbaumExtension {
1831
1831
  /*!
1832
1832
  * Wunderbaum - ext-logger
1833
1833
  * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license.
1834
- * v0.6.0, Wed, 08 Nov 2023 19:58:55 GMT (https://github.com/mar10/wunderbaum)
1834
+ * v0.7.0, Sat, 09 Dec 2023 13:47:27 GMT (https://github.com/mar10/wunderbaum)
1835
1835
  */
1836
1836
  class LoggerExtension extends WunderbaumExtension {
1837
1837
  constructor(tree) {
@@ -1873,7 +1873,7 @@ class LoggerExtension extends WunderbaumExtension {
1873
1873
  /*!
1874
1874
  * Wunderbaum - common
1875
1875
  * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license.
1876
- * v0.6.0, Wed, 08 Nov 2023 19:58:55 GMT (https://github.com/mar10/wunderbaum)
1876
+ * v0.7.0, Sat, 09 Dec 2023 13:47:27 GMT (https://github.com/mar10/wunderbaum)
1877
1877
  */
1878
1878
  const DEFAULT_DEBUGLEVEL = 3; // Replaced by rollup script
1879
1879
  /**
@@ -1952,6 +1952,7 @@ const RESERVED_TREE_SOURCE_KEYS = new Set([
1952
1952
  "_keyMap",
1953
1953
  "_positional",
1954
1954
  "_typeList",
1955
+ "_valueMap",
1955
1956
  "_version",
1956
1957
  "children",
1957
1958
  "columns",
@@ -2021,18 +2022,34 @@ function nodeTitleSorter(a, b) {
2021
2022
  const y = b.title.toLowerCase();
2022
2023
  return x === y ? 0 : x > y ? 1 : -1;
2023
2024
  }
2025
+ /**
2026
+ * Convert 'flat' to 'nested' format.
2027
+ *
2028
+ * Flat node entry format:
2029
+ * [PARENT_ID, [POSITIONAL_ARGS]]
2030
+ * or
2031
+ * [PARENT_ID, [POSITIONAL_ARGS], {KEY_VALUE_ARGS}]
2032
+ *
2033
+ * 1. Parent-referencing list is converted to a list of nested dicts with
2034
+ * optional `children` properties.
2035
+ * 2. `[POSITIONAL_ARGS]` are added as dict attributes.
2036
+ */
2024
2037
  function unflattenSource(source) {
2025
2038
  var _a, _b, _c;
2026
- const { _format, _keyMap, _positional, children } = source;
2039
+ const { _format, _keyMap = {}, _positional = [], children } = source;
2027
2040
  if (_format !== "flat") {
2028
2041
  throw new Error(`Expected source._format: "flat", but got ${_format}`);
2029
2042
  }
2030
2043
  if (_positional && _positional.includes("children")) {
2031
2044
  throw new Error(`source._positional must not include "children": ${_positional}`);
2032
2045
  }
2033
- // Inverse keyMap:
2034
- const longToShort = {};
2035
- if (_keyMap) {
2046
+ let longToShort = _keyMap;
2047
+ if (_keyMap.t) {
2048
+ // Inverse keyMap was used (pre 0.7.0)
2049
+ // TODO: raise Error on final 1.x release
2050
+ const msg = `source._keyMap maps from long to short since v0.7.0. Flip key/value!`;
2051
+ console.warn(msg); // eslint-disable-line no-console
2052
+ longToShort = {};
2036
2053
  for (const [key, value] of Object.entries(_keyMap)) {
2037
2054
  longToShort[value] = key;
2038
2055
  }
@@ -2043,16 +2060,16 @@ function unflattenSource(source) {
2043
2060
  const indexToNodeMap = {};
2044
2061
  const keyAttrName = (_a = longToShort["key"]) !== null && _a !== void 0 ? _a : "key";
2045
2062
  const childrenAttrName = (_b = longToShort["children"]) !== null && _b !== void 0 ? _b : "children";
2046
- for (const [index, node] of children.entries()) {
2063
+ for (const [index, nodeTuple] of children.entries()) {
2047
2064
  // Node entry format:
2048
2065
  // [PARENT_ID, [POSITIONAL_ARGS]]
2049
2066
  // or
2050
2067
  // [PARENT_ID, [POSITIONAL_ARGS], {KEY_VALUE_ARGS}]
2051
- const [parentId, args, kwargs = {}] = node;
2068
+ const [parentId, args, kwargs = {}] = nodeTuple;
2052
2069
  // Free up some memory as we go
2053
- node[1] = null;
2054
- if (node[2] != null) {
2055
- node[2] = null;
2070
+ nodeTuple[1] = null;
2071
+ if (nodeTuple[2] != null) {
2072
+ nodeTuple[2] = null;
2056
2073
  }
2057
2074
  // console.log("flatten", parentId, args, kwargs)
2058
2075
  // We keep `kwargs` as our new node definition. Then we add all positional
@@ -2090,56 +2107,96 @@ function unflattenSource(source) {
2090
2107
  newChildren.push(kwargs);
2091
2108
  }
2092
2109
  }
2093
- delete source.children;
2094
2110
  source.children = newChildren;
2095
2111
  }
2096
- function inflateSourceData(source) {
2097
- const { _format, _keyMap, _typeList } = source;
2112
+ /**
2113
+ * Decompresses the source data by
2114
+ * - converting from 'flat' to 'nested' format
2115
+ * - expanding short alias names to long names (if defined in _keyMap)
2116
+ * - resolving value indexes to value strings (if defined in _valueMap)
2117
+ *
2118
+ * @param source - The source object to be decompressed.
2119
+ * @returns void
2120
+ */
2121
+ function decompressSourceData(source) {
2122
+ let { _format, _version = 1, _keyMap, _valueMap } = source;
2123
+ assert(_version === 1, `Expected file version 1 instead of ${_version}`);
2124
+ let longToShort = _keyMap;
2125
+ let shortToLong = {};
2126
+ if (longToShort) {
2127
+ for (const [key, value] of Object.entries(longToShort)) {
2128
+ shortToLong[value] = key;
2129
+ }
2130
+ }
2131
+ // Fallback for old format (pre 0.7.0, using _keyMap in reverse direction)
2132
+ // TODO: raise Error on final 1.x release
2133
+ if (longToShort && longToShort.t) {
2134
+ const msg = `source._keyMap maps from long to short since v0.7.0. Flip key/value!`;
2135
+ console.warn(msg); // eslint-disable-line no-console
2136
+ [longToShort, shortToLong] = [shortToLong, longToShort];
2137
+ }
2138
+ // Fallback for old format (pre 0.7.0, using _typeList instead of _valueMap)
2139
+ // TODO: raise Error on final 1.x release
2140
+ if (source._typeList != null) {
2141
+ const msg = `source._typeList is deprecated since v0.7.0: use source._valueMap: {"type": [...]} instead.`;
2142
+ if (_valueMap != null) {
2143
+ throw new Error(msg);
2144
+ }
2145
+ else {
2146
+ console.warn(msg); // eslint-disable-line no-console
2147
+ _valueMap = { type: source._typeList };
2148
+ delete source._typeList;
2149
+ }
2150
+ }
2098
2151
  if (_format === "flat") {
2099
2152
  unflattenSource(source);
2100
2153
  }
2101
2154
  delete source._format;
2102
2155
  delete source._version;
2103
2156
  delete source._keyMap;
2104
- delete source._typeList;
2157
+ delete source._valueMap;
2105
2158
  delete source._positional;
2106
2159
  function _iter(childList) {
2107
2160
  for (const node of childList) {
2108
- // Expand short alias names
2109
- if (_keyMap) {
2110
- // Iterate over a list of names, because we modify inside the loop:
2111
- Object.getOwnPropertyNames(node).forEach((propName) => {
2112
- var _a;
2113
- const long = (_a = _keyMap[propName]) !== null && _a !== void 0 ? _a : propName;
2114
- if (long !== propName) {
2115
- node[long] = node[propName];
2161
+ // Iterate over a list of names, because we modify inside the loop
2162
+ // (for ... of ... does not allow this)
2163
+ Object.getOwnPropertyNames(node).forEach((propName) => {
2164
+ const value = node[propName];
2165
+ // Replace short names with long names if defined in _keyMap
2166
+ let longName = propName;
2167
+ if (_keyMap && shortToLong[propName] != null) {
2168
+ longName = shortToLong[propName];
2169
+ if (longName !== propName) {
2170
+ node[longName] = value;
2116
2171
  delete node[propName];
2117
2172
  }
2118
- });
2119
- }
2120
- // `node` now has long attribute names
2121
- // Resolve node type indexes
2122
- const type = node.type;
2123
- if (_typeList && type != null && typeof type === "number") {
2124
- const newType = _typeList[type];
2125
- if (newType == null) {
2126
- throw new Error(`Expected typeList[${type}] entry in [${_typeList}]`);
2127
2173
  }
2128
- node.type = newType;
2129
- }
2174
+ // Replace type index with type name if defined in _valueMap
2175
+ if (_valueMap &&
2176
+ typeof value === "number" &&
2177
+ _valueMap[longName] != null) {
2178
+ const newValue = _valueMap[longName][value];
2179
+ if (newValue == null) {
2180
+ throw new Error(`Expected valueMap[${longName}][${value}] entry in [${_valueMap[longName]}]`);
2181
+ }
2182
+ node[longName] = newValue;
2183
+ }
2184
+ });
2130
2185
  // Recursion
2131
2186
  if (node.children) {
2132
2187
  _iter(node.children);
2133
2188
  }
2134
2189
  }
2135
2190
  }
2136
- _iter(source.children);
2191
+ if (_keyMap || _valueMap) {
2192
+ _iter(source.children);
2193
+ }
2137
2194
  }
2138
2195
 
2139
2196
  /*!
2140
2197
  * Wunderbaum - ext-dnd
2141
2198
  * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license.
2142
- * v0.6.0, Wed, 08 Nov 2023 19:58:55 GMT (https://github.com/mar10/wunderbaum)
2199
+ * v0.7.0, Sat, 09 Dec 2023 13:47:27 GMT (https://github.com/mar10/wunderbaum)
2143
2200
  */
2144
2201
  const nodeMimeType = "application/x-wunderbaum-node";
2145
2202
  class DndExtension extends WunderbaumExtension {
@@ -2542,6 +2599,7 @@ class DndExtension extends WunderbaumExtension {
2542
2599
  }
2543
2600
  else if (e.type === "drop") {
2544
2601
  e.stopPropagation(); // prevent browser from opening links?
2602
+ e.preventDefault(); // #69 prevent iOS browser from opening links
2545
2603
  this._leaveNode();
2546
2604
  const region = this.lastDropRegion;
2547
2605
  let nodeData = (_a = e.dataTransfer) === null || _a === void 0 ? void 0 : _a.getData(nodeMimeType);
@@ -2562,13 +2620,14 @@ class DndExtension extends WunderbaumExtension {
2562
2620
  });
2563
2621
  }, 10);
2564
2622
  }
2623
+ return false;
2565
2624
  }
2566
2625
  }
2567
2626
 
2568
2627
  /*!
2569
2628
  * Wunderbaum - drag_observer
2570
2629
  * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license.
2571
- * v0.6.0, Wed, 08 Nov 2023 19:58:55 GMT (https://github.com/mar10/wunderbaum)
2630
+ * v0.7.0, Sat, 09 Dec 2023 13:47:27 GMT (https://github.com/mar10/wunderbaum)
2572
2631
  */
2573
2632
  /**
2574
2633
  * Convert mouse- and touch events to 'dragstart', 'drag', and 'dragstop'.
@@ -2704,7 +2763,7 @@ class DragObserver {
2704
2763
  /*!
2705
2764
  * Wunderbaum - ext-grid
2706
2765
  * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license.
2707
- * v0.6.0, Wed, 08 Nov 2023 19:58:55 GMT (https://github.com/mar10/wunderbaum)
2766
+ * v0.7.0, Sat, 09 Dec 2023 13:47:27 GMT (https://github.com/mar10/wunderbaum)
2708
2767
  */
2709
2768
  class GridExtension extends WunderbaumExtension {
2710
2769
  constructor(tree) {
@@ -2741,7 +2800,7 @@ class GridExtension extends WunderbaumExtension {
2741
2800
  /*!
2742
2801
  * Wunderbaum - deferred
2743
2802
  * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license.
2744
- * v0.6.0, Wed, 08 Nov 2023 19:58:55 GMT (https://github.com/mar10/wunderbaum)
2803
+ * v0.7.0, Sat, 09 Dec 2023 13:47:27 GMT (https://github.com/mar10/wunderbaum)
2745
2804
  */
2746
2805
  /**
2747
2806
  * Implement a ES6 Promise, that exposes a resolve() and reject() method.
@@ -2794,7 +2853,7 @@ class Deferred {
2794
2853
  /*!
2795
2854
  * Wunderbaum - wunderbaum_node
2796
2855
  * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license.
2797
- * v0.6.0, Wed, 08 Nov 2023 19:58:55 GMT (https://github.com/mar10/wunderbaum)
2856
+ * v0.7.0, Sat, 09 Dec 2023 13:47:27 GMT (https://github.com/mar10/wunderbaum)
2798
2857
  */
2799
2858
  /** WunderbaumNode properties that can be passed with source data.
2800
2859
  * (Any other source properties will be stored as `node.data.PROP`.)
@@ -3589,7 +3648,7 @@ class WunderbaumNode {
3589
3648
  const format = (_a = source.format) !== null && _a !== void 0 ? _a : "nested";
3590
3649
  assert(format === "nested" || format === "flat", `Expected source.format = 'nested' or 'flat': ${format}`);
3591
3650
  // Pre-rocess for 'nested' or 'flat' format
3592
- inflateSourceData(source);
3651
+ decompressSourceData(source);
3593
3652
  assert(source.children, "If `source` is an object, it must have a `children` property");
3594
3653
  if (source.types) {
3595
3654
  tree.logInfo("Redefine types", source.columns);
@@ -3747,7 +3806,8 @@ class WunderbaumNode {
3747
3806
  return;
3748
3807
  }
3749
3808
  assert(isArray(source) || (source && source.url), "The lazyLoad event must return a node list, `{url: ...}`, or false.");
3750
- await this.load(source); // also calls setStatus('ok')
3809
+ await this.load(source);
3810
+ this.setStatus(NodeStatusType.ok);
3751
3811
  if (wasExpanded) {
3752
3812
  this.expanded = true;
3753
3813
  this.tree.update(ChangeType.structure);
@@ -5126,7 +5186,7 @@ WunderbaumNode.sequence = 0;
5126
5186
  /*!
5127
5187
  * Wunderbaum - ext-edit
5128
5188
  * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license.
5129
- * v0.6.0, Wed, 08 Nov 2023 19:58:55 GMT (https://github.com/mar10/wunderbaum)
5189
+ * v0.7.0, Sat, 09 Dec 2023 13:47:27 GMT (https://github.com/mar10/wunderbaum)
5130
5190
  */
5131
5191
  // const START_MARKER = "\uFFF7";
5132
5192
  class EditExtension extends WunderbaumExtension {
@@ -5426,8 +5486,8 @@ class EditExtension extends WunderbaumExtension {
5426
5486
  * https://github.com/mar10/wunderbaum
5427
5487
  *
5428
5488
  * Released under the MIT license.
5429
- * @version v0.6.0
5430
- * @date Wed, 08 Nov 2023 19:58:55 GMT
5489
+ * @version v0.7.0
5490
+ * @date Sat, 09 Dec 2023 13:47:27 GMT
5431
5491
  */
5432
5492
  // import "./wunderbaum.scss";
5433
5493
  class WbSystemRoot extends WunderbaumNode {
@@ -7560,7 +7620,7 @@ class Wunderbaum {
7560
7620
  }
7561
7621
  Wunderbaum.sequence = 0;
7562
7622
  /** Wunderbaum release version number "MAJOR.MINOR.PATCH". */
7563
- Wunderbaum.version = "v0.6.0"; // Set to semver by 'grunt release'
7623
+ Wunderbaum.version = "v0.7.0"; // Set to semver by 'grunt release'
7564
7624
  /** Expose some useful methods of the util.ts module as `Wunderbaum.util`. */
7565
7625
  Wunderbaum.util = util;
7566
7626