wunderbaum 0.5.1 → 0.5.3

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.
@@ -395,7 +395,7 @@ div.wunderbaum {
395
395
  overflow: hidden;
396
396
  height: var(--wb-row-inner-height);
397
397
  line-height: var(--wb-row-inner-height);
398
- padding: 0 val(--wb-col-padding-x);
398
+ padding: 0 var(--wb-col-padding-x);
399
399
  border-right: 1px solid var(--wb-grid-color);
400
400
  white-space: nowrap;
401
401
 
@@ -416,10 +416,16 @@ div.wunderbaum {
416
416
  i.wb-indent {
417
417
  height: var(--wb-icon-outer-height);
418
418
  width: var(--wb-icon-outer-width);
419
- padding: var(--wb-icon-padding) var(--wb-icon-padding-x);
419
+ padding: var(--wb-icon-padding-y) var(--wb-icon-padding-x);
420
420
  display: inline-block;
421
421
  }
422
422
 
423
+ i.wb-expander,
424
+ i.wb-icon {
425
+ background-repeat: no-repeat;
426
+ background-size: contain;
427
+ }
428
+
423
429
  /* Fix Bootstrap Icon alignment */
424
430
  i.bi::before {
425
431
  vertical-align: baseline;
@@ -629,7 +635,7 @@ div.wunderbaum {
629
635
  // content: url(../docs/assets/drop_marker_16x32.png);
630
636
  content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAMAAABA3o1rAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACKUExURe/v9/f39+//7+f35+f/79bW5wgIawwYd97e55Tnpc731rjA2d7350LOY1LWa7Xvvf///wAQcyAze97e773vxnuczgA5pQBCpdb33rXvxu//9whjxgBaxlKU1oOz5ABz3gB73tbn99bW1rXe/wCM9xiU997v/97e3gCc/xil/9bv/wic/+/3/wAAALM9X5QAAAAudFJOU////////////////////////////////////////////////////////////wCCj3NVAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAqUlEQVQoU6WQ2w6CMAxA54agsCHq1HlFBREv/f/fs1tHAoaoiedlbXrWtGXwhV8FNqAXuAi4DwkShmE0cgGIcSwCCgkSkrAxpEonot0DhQxJptFsbnOpdNdgsFh6VtYwyqzTmG+oijDY7hr22E4qY7QybeGQe46nsxP0Wwc3Q1GWl+qKec8MlqKubxX+xzV7tkDuD1+3d+heigT2zGx/hCMUeUj4wL8CwAsW1kqCTugMCwAAAABJRU5ErkJggg==);
631
637
  left: 0; //-$icon-outer-width;
632
- top: calc(($row-outer-height - --wb-icon-height) / 2);
638
+ top: calc(($row-outer-height - var(--wb-icon-height)) / 2);
633
639
  }
634
640
  }
635
641
  }
@@ -652,13 +658,13 @@ div.wunderbaum {
652
658
  content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAAQCAMAAACROYkbAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACNUExURe/v9/f39+//7+f35+f/79bW5wgIawwYd97e55Tnpc731rjA2d7350LOY1LWa7Xvvf///wAQcyAze97e773vxgAAAHuczgA5pQBCpdb33rXvxu//9whjxgBaxlKU1oOz5ABz3gB73tbn99bW1rXe/wCM9xiU997v/97e3gCc/xil/9bv/wic/+/3/wAAAParqS4AAAAvdFJOU/////////////////////////////////////////////////////////////8AWqU49wAAAAlwSFlzAAAOwwAADsMBx2+oZAAAALlJREFUOE/FktsSgiAQhglMS8WstKLzQTM77Ps/XguL16I208cFyzB8/LPAYCC/ErARzcCFx23pBgnGfjAxBYhpKDwq3SBB5DeGWCYz0SUDClIkmgeLpV7HMiNDbrbbYbBaWzbaoKTaJiHfQe5oYLA/NBwxTiyVyqTSghYwox4MTmfL5XozgqxjAtODoizv1QPXPXqgKer6WeH9+Iw9XgF5ve15/Q+6/SQSsE+q8yMcocoREgzg3wKAL4vrpBIKREShAAAAAElFTkSuQmCC);
653
659
  left: 0; // $icon-outer-width * 1.5;
654
660
  top: calc(
655
- ($row-outer-height - --wb-icon-height) / 2 - $row-outer-height / 2
661
+ ($row-outer-height - var(--wb-icon-height)) / 2 - $row-outer-height / 2
656
662
  );
657
663
  }
658
664
 
659
665
  div.wb-row.wb-drop-target.wb-drop-after .wb-node .wb-icon::after {
660
666
  top: calc(
661
- ($row-outer-height - --wb-icon-height) / 2 + $row-outer-height / 2
667
+ ($row-outer-height - var(--wb-icon-height)) / 2 + $row-outer-height / 2
662
668
  );
663
669
  }
664
670
 
@@ -791,6 +797,7 @@ div.wunderbaum {
791
797
 
792
798
  i.wb-icon {
793
799
  position: relative;
800
+
794
801
  > span.wb-badge {
795
802
  position: absolute;
796
803
  display: inline-block;
@@ -806,6 +813,7 @@ i.wb-icon {
806
813
  white-space: nowrap;
807
814
  // vertical-align: baseline;
808
815
  border-radius: 0.5rem;
816
+ pointer-events: none;
809
817
  }
810
818
  }
811
819
 
package/src/wunderbaum.ts CHANGED
@@ -105,7 +105,7 @@ export class Wunderbaum {
105
105
  public readonly data: { [key: string]: any } = {};
106
106
 
107
107
  protected readonly _updateViewportThrottled: (...args: any) => void;
108
- protected extensionList: WunderbaumExtension[] = [];
108
+ protected extensionList: WunderbaumExtension<any>[] = [];
109
109
  protected extensions: ExtensionsDict = {};
110
110
 
111
111
  /** Merged options from constructor args and tree- and extension defaults. */
@@ -166,7 +166,7 @@ export class Wunderbaum {
166
166
  protected lastClickTime = 0;
167
167
 
168
168
  constructor(options: WunderbaumOptions) {
169
- let opts = (this.options = util.extend(
169
+ const opts = (this.options = util.extend(
170
170
  {
171
171
  id: null,
172
172
  source: null, // URL for GET/PUT, Ajax options, or callback
@@ -220,7 +220,7 @@ export class Wunderbaum {
220
220
  } catch (error) {
221
221
  // We re-raise in the reject handler, but Chrome resets the stack
222
222
  // frame then, so we log it here:
223
- console.error("Exception inside `init(e)` event:", error);
223
+ this.logError("Exception inside `init(e)` event:", error);
224
224
  }
225
225
  })
226
226
  .catch((err) => {
@@ -436,7 +436,9 @@ export class Wunderbaum {
436
436
  }
437
437
 
438
438
  if (info.region === NodeRegion.expander) {
439
- node.setExpanded(!node.isExpanded());
439
+ node.setExpanded(!node.isExpanded(), {
440
+ scrollIntoView: options.scrollIntoViewOnExpandClick !== false,
441
+ });
440
442
  } else if (info.region === NodeRegion.checkbox) {
441
443
  node.toggleSelected();
442
444
  }
@@ -522,7 +524,7 @@ export class Wunderbaum {
522
524
  el = document.querySelectorAll(".wunderbaum")[el]; // el was an integer: return nth element
523
525
  } else if (typeof el === "string") {
524
526
  // Search all trees for matching ID
525
- for (let treeElem of document.querySelectorAll(".wunderbaum")) {
527
+ for (const treeElem of document.querySelectorAll(".wunderbaum")) {
526
528
  const tree = (<any>treeElem)._wb_tree;
527
529
  if (tree && tree.id === el) {
528
530
  return tree;
@@ -596,7 +598,7 @@ export class Wunderbaum {
596
598
  }
597
599
 
598
600
  /** @internal */
599
- protected _registerExtension(extension: WunderbaumExtension): void {
601
+ protected _registerExtension(extension: WunderbaumExtension<any>): void {
600
602
  this.extensionList.push(extension);
601
603
  this.extensions[extension.id] = extension;
602
604
  // this.extensionMap.set(extension.id, extension);
@@ -604,7 +606,7 @@ export class Wunderbaum {
604
606
 
605
607
  /** Called on tree (re)init after markup is created, before loading. */
606
608
  protected _initExtensions(): void {
607
- for (let ext of this.extensionList) {
609
+ for (const ext of this.extensionList) {
608
610
  ext.init();
609
611
  }
610
612
  }
@@ -617,9 +619,9 @@ export class Wunderbaum {
617
619
  `Missing or duplicate key: '${key}'.`
618
620
  );
619
621
  this.keyMap.set(key, node);
620
- let rk = node.refKey;
622
+ const rk = node.refKey;
621
623
  if (rk) {
622
- let rks = this.refKeyMap.get(rk); // Set of nodes with this refKey
624
+ const rks = this.refKeyMap.get(rk); // Set of nodes with this refKey
623
625
  if (rks) {
624
626
  rks.add(node);
625
627
  } else {
@@ -647,15 +649,18 @@ export class Wunderbaum {
647
649
  }
648
650
 
649
651
  /** Call all hook methods of all registered extensions.*/
650
- protected _callHook(hook: keyof WunderbaumExtension, data: any = {}): any {
652
+ protected _callHook(
653
+ hook: keyof WunderbaumExtension<any>,
654
+ data: any = {}
655
+ ): any {
651
656
  let res;
652
- let d = util.extend(
657
+ const d = util.extend(
653
658
  {},
654
659
  { tree: this, options: this.options, result: undefined },
655
660
  data
656
661
  );
657
662
 
658
- for (let ext of this.extensionList) {
663
+ for (const ext of this.extensionList) {
659
664
  res = (<any>ext[hook]).call(ext, d);
660
665
  if (res === false) {
661
666
  break;
@@ -974,8 +979,9 @@ export class Wunderbaum {
974
979
  this.clear();
975
980
  this.resizeObserver.disconnect();
976
981
  this.element.innerHTML = "";
982
+
977
983
  // Remove all event handlers
978
- this.element.outerHTML = this.element.outerHTML;
984
+ this.element.outerHTML = this.element.outerHTML; // eslint-disable-line
979
985
  }
980
986
 
981
987
  /**
@@ -1186,10 +1192,10 @@ export class Wunderbaum {
1186
1192
  startNode?: WunderbaumNode | null
1187
1193
  ): WunderbaumNode | null {
1188
1194
  //, visibleOnly) {
1189
- let res: WunderbaumNode | null = null,
1190
- firstNode = this.getFirstChild()!;
1195
+ let res: WunderbaumNode | null = null;
1196
+ const firstNode = this.getFirstChild()!;
1191
1197
 
1192
- let matcher =
1198
+ const matcher =
1193
1199
  typeof match === "string" ? makeNodeTitleStartMatcher(match) : match;
1194
1200
  startNode = startNode || firstNode;
1195
1201
 
@@ -1286,13 +1292,15 @@ export class Wunderbaum {
1286
1292
  res = this._getNextNodeInView(node);
1287
1293
  break;
1288
1294
  case "pageDown":
1289
- const bottomNode = this.getLowestVpNode();
1290
- // this.logDebug(`${where}(${node}) -> ${bottomNode}`);
1295
+ {
1296
+ const bottomNode = this.getLowestVpNode();
1297
+ // this.logDebug(`${where}(${node}) -> ${bottomNode}`);
1291
1298
 
1292
- if (node._rowIdx! < bottomNode._rowIdx!) {
1293
- res = bottomNode;
1294
- } else {
1295
- res = this._getNextNodeInView(node, pageSize);
1299
+ if (node._rowIdx! < bottomNode._rowIdx!) {
1300
+ res = bottomNode;
1301
+ } else {
1302
+ res = this._getNextNodeInView(node, pageSize);
1303
+ }
1296
1304
  }
1297
1305
  break;
1298
1306
  case "pageUp":
@@ -1322,7 +1330,7 @@ export class Wunderbaum {
1322
1330
  name_cb?: NodeStringCallback,
1323
1331
  connectors?: string[]
1324
1332
  ): IterableIterator<string> {
1325
- return this.root.format_iter(name_cb, connectors);
1333
+ yield* this.root.format_iter(name_cb, connectors);
1326
1334
  }
1327
1335
 
1328
1336
  /**
@@ -1387,22 +1395,22 @@ export class Wunderbaum {
1387
1395
  * TYPE: 'title' | 'prefix' | 'expander' | 'checkbox' | 'icon' | undefined
1388
1396
  */
1389
1397
  static getEventInfo(event: Event): WbEventInfo {
1390
- let target = <Element>event.target,
1391
- cl = target.classList,
1392
- parentCol = target.closest("span.wb-col") as HTMLSpanElement,
1393
- node = Wunderbaum.getNode(target),
1394
- tree = node ? node.tree : Wunderbaum.getTree(event),
1395
- res: WbEventInfo = {
1396
- event: <MouseEvent>event,
1397
- canonicalName: util.eventToString(event),
1398
- tree: tree!,
1399
- node: node,
1400
- region: NodeRegion.unknown,
1401
- colDef: undefined,
1402
- colIdx: -1,
1403
- colId: undefined,
1404
- colElem: parentCol,
1405
- };
1398
+ const target = <Element>event.target;
1399
+ const cl = target.classList;
1400
+ const parentCol = target.closest("span.wb-col") as HTMLSpanElement;
1401
+ const node = Wunderbaum.getNode(target);
1402
+ const tree = node ? node.tree : Wunderbaum.getTree(event);
1403
+ const res: WbEventInfo = {
1404
+ event: <MouseEvent>event,
1405
+ canonicalName: util.eventToString(event),
1406
+ tree: tree!,
1407
+ node: node,
1408
+ region: NodeRegion.unknown,
1409
+ colDef: undefined,
1410
+ colIdx: -1,
1411
+ colId: undefined,
1412
+ colElem: parentCol,
1413
+ };
1406
1414
 
1407
1415
  if (cl.contains("wb-title")) {
1408
1416
  res.region = NodeRegion.title;
@@ -1430,7 +1438,7 @@ export class Wunderbaum {
1430
1438
  } else {
1431
1439
  // Somewhere near the title
1432
1440
  if (event.type !== "mousemove" && !(event instanceof KeyboardEvent)) {
1433
- console.warn("getEventInfo(): not found", event, res);
1441
+ tree?.logWarn("getEventInfo(): not found", event, res);
1434
1442
  }
1435
1443
  return res;
1436
1444
  }
@@ -1460,7 +1468,7 @@ export class Wunderbaum {
1460
1468
  * Return true if any node is currently beeing loaded, i.e. a Ajax request is pending.
1461
1469
  */
1462
1470
  isLoading(): boolean {
1463
- var res = false;
1471
+ let res = false;
1464
1472
 
1465
1473
  this.root.visit((n) => {
1466
1474
  // also visit rootNode
@@ -1480,31 +1488,28 @@ export class Wunderbaum {
1480
1488
  /** Log to console if opts.debugLevel >= 4 */
1481
1489
  logDebug(...args: any[]) {
1482
1490
  if (this.options.debugLevel! >= 4) {
1483
- Array.prototype.unshift.call(args, this.toString());
1484
- console.log.apply(console, args);
1491
+ console.log(this.toString(), ...args); // eslint-disable-line no-console
1485
1492
  }
1486
1493
  }
1487
1494
 
1488
1495
  /** Log error to console. */
1489
1496
  logError(...args: any[]) {
1490
1497
  if (this.options.debugLevel! >= 1) {
1491
- Array.prototype.unshift.call(args, this.toString());
1492
- console.error.apply(console, args);
1498
+ console.error(this.toString(), ...args); // eslint-disable-line no-console
1493
1499
  }
1494
1500
  }
1495
1501
 
1496
1502
  /** Log to console if opts.debugLevel >= 3 */
1497
1503
  logInfo(...args: any[]) {
1498
1504
  if (this.options.debugLevel! >= 3) {
1499
- Array.prototype.unshift.call(args, this.toString());
1500
- console.info.apply(console, args);
1505
+ console.info(this.toString(), ...args); // eslint-disable-line no-console
1501
1506
  }
1502
1507
  }
1503
1508
 
1504
1509
  /** @internal */
1505
1510
  logTime(label: string): string {
1506
1511
  if (this.options.debugLevel! >= 4) {
1507
- console.time(this + ": " + label);
1512
+ console.time(this + ": " + label); // eslint-disable-line no-console
1508
1513
  }
1509
1514
  return label;
1510
1515
  }
@@ -1512,15 +1517,14 @@ export class Wunderbaum {
1512
1517
  /** @internal */
1513
1518
  logTimeEnd(label: string): void {
1514
1519
  if (this.options.debugLevel! >= 4) {
1515
- console.timeEnd(this + ": " + label);
1520
+ console.timeEnd(this + ": " + label); // eslint-disable-line no-console
1516
1521
  }
1517
1522
  }
1518
1523
 
1519
1524
  /** Log to console if opts.debugLevel >= 2 */
1520
1525
  logWarn(...args: any[]) {
1521
1526
  if (this.options.debugLevel! >= 2) {
1522
- Array.prototype.unshift.call(args, this.toString());
1523
- console.warn.apply(console, args);
1527
+ console.warn(this.toString(), ...args); // eslint-disable-line no-console
1524
1528
  }
1525
1529
  }
1526
1530
 
@@ -1625,9 +1629,9 @@ export class Wunderbaum {
1625
1629
 
1626
1630
  // Update `wb-active` class for all headers
1627
1631
  if (this.hasHeader()) {
1628
- for (let rowDiv of this.headerElement.children) {
1632
+ for (const rowDiv of this.headerElement.children) {
1629
1633
  let i = 0;
1630
- for (let colDiv of rowDiv.children) {
1634
+ for (const colDiv of rowDiv.children) {
1631
1635
  (colDiv as HTMLElement).classList.toggle("wb-active", i++ === colIdx);
1632
1636
  }
1633
1637
  }
@@ -1636,9 +1640,9 @@ export class Wunderbaum {
1636
1640
  this.activeNode?.update(ChangeType.status);
1637
1641
 
1638
1642
  // Update `wb-active` class for all cell spans
1639
- for (let rowDiv of this.nodeListElement.children) {
1643
+ for (const rowDiv of this.nodeListElement.children) {
1640
1644
  let i = 0;
1641
- for (let colDiv of rowDiv.children) {
1645
+ for (const colDiv of rowDiv.children) {
1642
1646
  (colDiv as HTMLElement).classList.toggle("wb-active", i++ === colIdx);
1643
1647
  }
1644
1648
  }
@@ -1662,15 +1666,6 @@ export class Wunderbaum {
1662
1666
  }
1663
1667
  }
1664
1668
 
1665
- /**
1666
- * @deprecated since v0.3.6: use `update()` instead.
1667
- */
1668
- setModified(change: ChangeType, ...args: any[]): void {
1669
- this.logWarn("setModified() is deprecated: use update() instead.");
1670
- // @ts-ignore
1671
- // (!) TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
1672
- return this.update.call(this, change, ...args);
1673
- }
1674
1669
  /**
1675
1670
  * Schedule an update request to reflect a tree change.
1676
1671
  * The render operation is async and debounced unless the `immediate` option
@@ -1852,7 +1847,7 @@ export class Wunderbaum {
1852
1847
  util.extend(this.types, types);
1853
1848
  }
1854
1849
  // Convert `TYPE.classes` to a Set
1855
- for (let t of Object.values(this.types) as any) {
1850
+ for (const t of Object.values(this.types) as any) {
1856
1851
  if (t.classes) {
1857
1852
  t.classes = util.toSet(t.classes);
1858
1853
  }
@@ -1895,7 +1890,7 @@ export class Wunderbaum {
1895
1890
  const defaultMinWidth = 4;
1896
1891
  const vpWidth = this.element.clientWidth;
1897
1892
  // Shorten last column width to avoid h-scrollbar
1898
- const FIX_ADJUST_LAST_COL = 2;
1893
+ const FIX_ADJUST_LAST_COL = 0; // 2;
1899
1894
  const columns = this.columns;
1900
1895
  const col0 = columns[0];
1901
1896
 
@@ -1915,9 +1910,9 @@ export class Wunderbaum {
1915
1910
  }
1916
1911
  // Gather width definitions
1917
1912
  this._columnsById = {};
1918
- for (let col of columns) {
1913
+ for (const col of columns) {
1919
1914
  this._columnsById[<string>col.id] = col;
1920
- let cw = col.width;
1915
+ const cw = col.width;
1921
1916
  if (col.id === "*" && col !== col0) {
1922
1917
  throw new Error(
1923
1918
  `Column id '*' must be defined only once: '${col.title}'.`
@@ -1932,7 +1927,7 @@ export class Wunderbaum {
1932
1927
  totalWeight += cw;
1933
1928
  } else if (typeof cw === "string" && cw.endsWith("px")) {
1934
1929
  col._weight = 0;
1935
- let px = parseFloat(cw.slice(0, -2));
1930
+ const px = parseFloat(cw.slice(0, -2));
1936
1931
  if (col._widthPx != px) {
1937
1932
  modified = true;
1938
1933
  col._widthPx = px;
@@ -1948,7 +1943,7 @@ export class Wunderbaum {
1948
1943
  const restPx = Math.max(0, vpWidth - fixedWidth);
1949
1944
  let ofsPx = 0;
1950
1945
 
1951
- for (let col of columns) {
1946
+ for (const col of columns) {
1952
1947
  let minWidth: number;
1953
1948
 
1954
1949
  if (col._weight) {
@@ -2086,19 +2081,17 @@ export class Wunderbaum {
2086
2081
  // this.log("_updateViewportImmediately(): scroll only.");
2087
2082
  } else {
2088
2083
  this.log("_updateViewportImmediately():", pending);
2089
- let height = this.listContainerElement.clientHeight;
2090
- // We cannot get the height for absolute positioned parent, so look at first col
2091
- // let headerHeight = this.headerElement.clientHeight
2092
- // let headerHeight = this.headerElement.children[0].children[0].clientHeight;
2093
- // const headerHeight = this.options.headerHeightPx;
2094
- const headerHeight = this.headerElement.clientHeight; // May be 0
2095
- const wantHeight =
2096
- this.element.clientHeight - headerHeight - FIX_ADJUST_HEIGHT;
2097
-
2098
- if (Math.abs(height - wantHeight) > 1.0) {
2099
- // this.log("resize", height, wantHeight);
2100
- this.listContainerElement.style.height = wantHeight + "px";
2101
- height = wantHeight;
2084
+ if (this.options.adjustHeight !== false) {
2085
+ let height = this.listContainerElement.clientHeight;
2086
+ const headerHeight = this.headerElement.clientHeight; // May be 0
2087
+ const wantHeight =
2088
+ this.element.clientHeight - headerHeight - FIX_ADJUST_HEIGHT;
2089
+
2090
+ if (Math.abs(height - wantHeight) > 1.0) {
2091
+ // this.log("resize", height, wantHeight);
2092
+ this.listContainerElement.style.height = wantHeight + "px";
2093
+ height = wantHeight;
2094
+ }
2102
2095
  }
2103
2096
  // console.profile(`_updateViewportImmediately()`)
2104
2097
 
@@ -2294,10 +2287,9 @@ export class Wunderbaum {
2294
2287
  stopNode: WunderbaumNode,
2295
2288
  siblingOfs = 0,
2296
2289
  skipFirstNode = options.includeSelf === false,
2297
- includeHidden = !!options.includeHidden,
2298
- checkFilter = !includeHidden && this.filterMode === "hide",
2299
2290
  node: WunderbaumNode = options.start || this.root.children![0];
2300
-
2291
+ const includeHidden = !!options.includeHidden;
2292
+ const checkFilter = !includeHidden && this.filterMode === "hide";
2301
2293
  parent = node.parent;
2302
2294
  while (parent) {
2303
2295
  // visit siblings
@@ -2378,8 +2370,8 @@ export class Wunderbaum {
2378
2370
  let children,
2379
2371
  idx,
2380
2372
  parent,
2381
- includeHidden = !!options.includeHidden,
2382
2373
  node = options.start || this.root.children![0];
2374
+ const includeHidden = !!options.includeHidden;
2383
2375
 
2384
2376
  if (options.includeSelf !== false) {
2385
2377
  if (callback(node) === false) {