wunderbaum 0.0.7 → 0.0.8

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/src/wb_node.ts CHANGED
@@ -9,12 +9,14 @@ import * as util from "./util";
9
9
 
10
10
  import { Wunderbaum } from "./wunderbaum";
11
11
  import {
12
+ AddChildrenOptions,
12
13
  AddNodeType,
13
14
  ApplyCommandType,
14
15
  ChangeType,
15
16
  ColumnEventInfos,
17
+ ExpandAllOptions,
16
18
  MakeVisibleOptions,
17
- MatcherType,
19
+ MatcherCallback,
18
20
  NodeAnyCallback,
19
21
  NodeStatusType,
20
22
  NodeVisitCallback,
@@ -34,6 +36,7 @@ import {
34
36
  TITLE_SPAN_PAD_Y,
35
37
  ROW_HEIGHT,
36
38
  TEST_IMG,
39
+ inflateSourceData,
37
40
  } from "./common";
38
41
  import { Deferred } from "./deferred";
39
42
  import { WbNodeData } from "./wb_options";
@@ -218,49 +221,55 @@ export class WunderbaumNode {
218
221
  /**
219
222
  * Append (or insert) a list of child nodes.
220
223
  *
221
- * Tip: pass `{ before: 0 }` to prepend children
222
- * @param {NodeData[]} nodeData array of child node definitions (also single child accepted)
223
- * @param child node (or key or index of such).
224
- * If omitted, the new children are appended.
224
+ * Tip: pass `{ before: 0 }` to prepend new nodes as first children.
225
+ *
225
226
  * @returns first child added
226
227
  */
227
- addChildren(nodeData: any, options?: any): WunderbaumNode {
228
+ addChildren(
229
+ nodeData: WbNodeData | WbNodeData[],
230
+ options?: AddChildrenOptions
231
+ ): WunderbaumNode {
228
232
  const tree = this.tree;
229
- const level = options ? options.level : this.getLevel();
230
- let insertBefore: WunderbaumNode | string | number = options
231
- ? options.before
232
- : null,
233
- // redraw = options ? options.redraw !== false : true,
234
- nodeList = [];
233
+ let { before = null, applyMinExpanLevel = true, _level } = options ?? {};
234
+ // let { before, loadLazy=true, _level } = options ?? {};
235
+ // const isTopCall = _level == null;
236
+ _level ??= this.getLevel();
237
+ const nodeList = [];
235
238
 
236
239
  try {
237
240
  tree.enableUpdate(false);
238
241
 
239
242
  if (util.isPlainObject(nodeData)) {
240
- nodeData = [nodeData];
243
+ nodeData = [<WbNodeData>nodeData];
241
244
  }
242
- const forceExpand = level < tree.options.minExpandLevel!;
243
- for (let child of nodeData) {
244
- let subChildren = child.children;
245
+ const forceExpand =
246
+ applyMinExpanLevel && _level < tree.options.minExpandLevel!;
247
+ for (let child of <WbNodeData[]>nodeData) {
248
+ const subChildren = child.children;
245
249
  delete child.children;
246
250
 
247
- let n = new WunderbaumNode(tree, this, child);
248
- if (forceExpand && !n.lazy) n.expanded = true;
251
+ const n = new WunderbaumNode(tree, this, child);
252
+ if (forceExpand && !n.isUnloaded()) {
253
+ n.expanded = true;
254
+ }
249
255
  nodeList.push(n);
250
256
  if (subChildren) {
251
- n.addChildren(subChildren, { redraw: false, level: level + 1 });
257
+ n.addChildren(subChildren, { _level: _level + 1 });
252
258
  }
253
259
  }
254
260
 
255
261
  if (!this.children) {
256
262
  this.children = nodeList;
257
- } else if (insertBefore == null || this.children.length === 0) {
263
+ } else if (before == null || this.children.length === 0) {
258
264
  this.children = this.children.concat(nodeList);
259
265
  } else {
260
- // Returns null if insertBefore is not a direct child:
261
- insertBefore = this.findDirectChild(insertBefore)!;
262
- let pos = this.children.indexOf(insertBefore);
263
- util.assert(pos >= 0, "insertBefore must be an existing child");
266
+ // Returns null if before is not a direct child:
267
+ before = this.findDirectChild(before)!;
268
+ let pos = this.children.indexOf(before);
269
+ util.assert(
270
+ pos >= 0,
271
+ `options.before must be a direct child of ${this}`
272
+ );
264
273
  // insert nodeList after children[pos]
265
274
  this.children.splice(pos, 0, ...nodeList);
266
275
  }
@@ -270,10 +279,13 @@ export class WunderbaumNode {
270
279
  // }
271
280
  // this.triggerModifyChild("add", nodeList.length === 1 ? nodeList[0] : null);
272
281
  tree.setModified(ChangeType.structure);
273
- return nodeList[0];
274
282
  } finally {
275
283
  tree.enableUpdate(true);
276
284
  }
285
+ // if(isTopCall && loadLazy){
286
+ // this.logWarn("addChildren(): loadLazy is not yet implemented.")
287
+ // }
288
+ return nodeList[0];
277
289
  }
278
290
 
279
291
  /**
@@ -351,22 +363,99 @@ export class WunderbaumNode {
351
363
  }
352
364
  }
353
365
 
354
- /** Call `setExpanded()` on al child nodes*/
355
- async expandAll(flag: boolean = true) {
356
- this.visit((node) => {
357
- node.setExpanded(flag);
358
- });
366
+ /** Call `setExpanded()` on all descendant nodes. */
367
+ async expandAll(flag: boolean = true, options?: ExpandAllOptions) {
368
+ const tree = this.tree;
369
+ const minExpandLevel = this.tree.options.minExpandLevel;
370
+ let { depth = 99, loadLazy, force } = options ?? {};
371
+
372
+ const expand_opts = {
373
+ scrollIntoView: false,
374
+ force: force,
375
+ loadLazy: loadLazy,
376
+ };
377
+
378
+ // this.logInfo(`expandAll(${flag})`);
379
+ // Expand all direct children in parallel:
380
+ async function _iter(n: WunderbaumNode, level: number | null) {
381
+ // n.logInfo(` _iter(${level})`);
382
+ if (level === 0) {
383
+ return;
384
+ }
385
+ // if (!flag && minExpandLevel && !force && n.getLevel() <= minExpandLevel) {
386
+ // return; // Do not collapse until minExpandLevel
387
+ // }
388
+ const level_1 = level == null ? null : level - 1;
389
+ const promises: Promise<unknown>[] = [];
390
+ n.children?.forEach((cn) => {
391
+ if (flag) {
392
+ if (!cn.expanded && (cn.children || (loadLazy && cn.lazy))) {
393
+ // Node is collapsed and may be expanded (i.e. has children or is lazy)
394
+ // Expanding may be async, so we store the promise.
395
+ // Also the recursion is delayed until expansion finished.
396
+ const p = cn.setExpanded(true, expand_opts);
397
+ promises.push(p);
398
+ p.then(async () => {
399
+ await _iter(cn, level_1);
400
+ });
401
+ } else {
402
+ // We don't expand the node, but still visit descendants.
403
+ // There we may find lazy nodes, so we
404
+ promises.push(_iter(cn, level_1));
405
+ }
406
+ } else {
407
+ // Collapsing is always synchronous, so no promises required
408
+ if (!minExpandLevel || force || cn.getLevel() > minExpandLevel) {
409
+ // Do not collapse until minExpandLevel
410
+ cn.setExpanded(false, expand_opts);
411
+ }
412
+ _iter(cn, level_1); // recursion, even if cn was already collapsed
413
+ }
414
+ });
415
+ return new Promise((resolve) => {
416
+ Promise.all(promises).then(() => {
417
+ resolve(true);
418
+ });
419
+ });
420
+ }
421
+
422
+ const tag = tree.logTime(`${this}.expandAll(${flag})`);
423
+ try {
424
+ tree.enableUpdate(false);
425
+ await _iter(this, depth);
426
+ } finally {
427
+ tree.enableUpdate(true);
428
+ tree.logTimeEnd(tag);
429
+ }
359
430
  }
360
431
 
361
- /**Find all nodes that match condition (excluding self).
432
+ /**
433
+ * Find all descendant nodes that match condition (excluding self).
362
434
  *
363
- * @param {string | function(node)} match title string to search for, or a
364
- * callback function that returns `true` if a node is matched.
435
+ * If `match` is a string, search for exact node title.
436
+ * If `match` is a RegExp expression, apply it to node.title, using
437
+ * [RegExp.test()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test).
438
+ * If `match` is a callback, match all nodes for that the callback(node) returns true.
439
+ *
440
+ * Returns an empty array if no nodes were found.
441
+ *
442
+ * Examples:
443
+ * ```js
444
+ * // Match all node titles that match exactly 'Joe':
445
+ * nodeList = node.findAll("Joe")
446
+ * // Match all node titles that start with 'Joe' case sensitive:
447
+ * nodeList = node.findAll(/^Joe/)
448
+ * // Match all node titles that contain 'oe', case insensitive:
449
+ * nodeList = node.findAll(/oe/i)
450
+ * // Match all nodes with `data.price` >= 99:
451
+ * nodeList = node.findAll((n) => {
452
+ * return n.data.price >= 99;
453
+ * })
454
+ * ```
365
455
  */
366
- findAll(match: string | MatcherType): WunderbaumNode[] {
367
- const matcher = util.isFunction(match)
368
- ? <MatcherType>match
369
- : makeNodeTitleMatcher(<string>match);
456
+ findAll(match: string | RegExp | MatcherCallback): WunderbaumNode[] {
457
+ const matcher =
458
+ typeof match === "function" ? match : makeNodeTitleMatcher(match);
370
459
  const res: WunderbaumNode[] = [];
371
460
  this.visit((n) => {
372
461
  if (matcher(n)) {
@@ -398,15 +487,14 @@ export class WunderbaumNode {
398
487
  return null;
399
488
  }
400
489
 
401
- /**Find first node that matches condition (excluding self).
490
+ /**
491
+ * Find first descendant node that matches condition (excluding self) or null.
402
492
  *
403
- * @param match title string to search for, or a
404
- * callback function that returns `true` if a node is matched.
493
+ * @see {@link WunderbaumNode.findAll} for examples.
405
494
  */
406
- findFirst(match: string | MatcherType): WunderbaumNode | null {
407
- const matcher = util.isFunction(match)
408
- ? <MatcherType>match
409
- : makeNodeTitleMatcher(<string>match);
495
+ findFirst(match: string | RegExp | MatcherCallback): WunderbaumNode | null {
496
+ const matcher =
497
+ typeof match === "function" ? match : makeNodeTitleMatcher(match);
410
498
  let res = null;
411
499
  this.visit((n) => {
412
500
  if (matcher(n)) {
@@ -596,7 +684,8 @@ export class WunderbaumNode {
596
684
  * an expand operation is currently possible.
597
685
  */
598
686
  isExpandable(andCollapsed = false): boolean {
599
- return !!this.children && (!this.expanded || !andCollapsed);
687
+ // return !!this.children && (!this.expanded || !andCollapsed);
688
+ return !!(this.children || this.lazy) && (!this.expanded || !andCollapsed);
600
689
  }
601
690
 
602
691
  /** Return true if this node is currently in edit-title mode. */
@@ -734,6 +823,13 @@ export class WunderbaumNode {
734
823
  source = { children: source };
735
824
  }
736
825
  util.assert(util.isPlainObject(source));
826
+
827
+ const format: string = source.format ?? "nested";
828
+ util.assert(format === "nested" || format === "flat");
829
+
830
+ // Pre-rocess for 'nested' or 'flat' format
831
+ inflateSourceData(source);
832
+
737
833
  util.assert(
738
834
  source.children,
739
835
  "If `source` is an object, it must have a `children` property"
@@ -923,22 +1019,23 @@ export class WunderbaumNode {
923
1019
 
924
1020
  /** Expand all parents and optionally scroll into visible area as neccessary.
925
1021
  * Promise is resolved, when lazy loading and animations are done.
926
- * @param {object} [opts] passed to `setExpanded()`.
1022
+ * @param {object} [options] passed to `setExpanded()`.
927
1023
  * Defaults to {noAnimation: false, noEvents: false, scrollIntoView: true}
928
1024
  */
929
- async makeVisible(opts?: MakeVisibleOptions) {
1025
+ async makeVisible(options?: MakeVisibleOptions) {
930
1026
  let i,
931
1027
  dfd = new Deferred(),
932
1028
  deferreds = [],
933
1029
  parents = this.getParentList(false, false),
934
1030
  len = parents.length,
935
- // effects = !(opts && opts.noAnimation === true),
936
- scroll = !(opts && opts.scrollIntoView === false);
1031
+ noAnimation = util.getOption(options, "noAnimation", false),
1032
+ scroll = util.getOption(options, "scrollIntoView", true);
1033
+ // scroll = !(options && options.scrollIntoView === false);
937
1034
 
938
1035
  // Expand bottom-up, so only the top node is animated
939
1036
  for (i = len - 1; i >= 0; i--) {
940
1037
  // self.debug("pushexpand" + parents[i]);
941
- const seOpts = { noAnimation: opts?.noAnimation };
1038
+ const seOpts = { noAnimation: noAnimation };
942
1039
  deferreds.push(parents[i].setExpanded(true, seOpts));
943
1040
  }
944
1041
  Promise.all(deferreds).then(() => {
@@ -1727,11 +1824,12 @@ export class WunderbaumNode {
1727
1824
  * Expand or collapse this node.
1728
1825
  */
1729
1826
  async setExpanded(flag: boolean = true, options?: SetExpandedOptions) {
1827
+ const { force, scrollIntoView, immediate } = options ?? {};
1730
1828
  if (
1731
1829
  !flag &&
1732
1830
  this.isExpanded() &&
1733
1831
  this.getLevel() <= this.tree.getOption("minExpandLevel") &&
1734
- !util.getOption(options, "force")
1832
+ !force
1735
1833
  ) {
1736
1834
  this.logDebug("Ignored collapse request below expandLevel.");
1737
1835
  return;
@@ -1739,15 +1837,18 @@ export class WunderbaumNode {
1739
1837
  if (!flag === !this.expanded) {
1740
1838
  return; // Nothing to do
1741
1839
  }
1840
+ // this.log("setExpanded()");
1742
1841
  if (flag && this.lazy && this.children == null) {
1743
1842
  await this.loadLazy();
1744
1843
  }
1745
1844
  this.expanded = flag;
1746
- const updateOpts = { immediate: !!util.getOption(options, "immediate") };
1845
+ const updateOpts = { immediate: immediate };
1846
+ // const updateOpts = { immediate: !!util.getOption(options, "immediate") };
1747
1847
  this.tree.setModified(ChangeType.structure, updateOpts);
1748
- if (util.getOption(options, "scrollIntoView") !== false) {
1848
+ if (flag && scrollIntoView !== false) {
1749
1849
  const lastChild = this.getLastChild();
1750
1850
  if (lastChild) {
1851
+ this.tree.updatePendingModifications();
1751
1852
  lastChild.scrollIntoView({ topNode: this });
1752
1853
  }
1753
1854
  }
package/src/wunderbaum.ts CHANGED
@@ -23,8 +23,9 @@ import {
23
23
  ApplyCommandType,
24
24
  ChangeType,
25
25
  ColumnDefinitionList,
26
+ ExpandAllOptions,
26
27
  FilterModeType,
27
- MatcherType,
28
+ MatcherCallback,
28
29
  NavigationOptions,
29
30
  NodeStatusType,
30
31
  NodeTypeDefinitions,
@@ -710,13 +711,13 @@ export class Wunderbaum {
710
711
  /**
711
712
  * Apply a modification (or navigation) operation on the **tree or active node**.
712
713
  */
713
- applyCommand(cmd: ApplyCommandType, opts?: any): any;
714
+ applyCommand(cmd: ApplyCommandType, options?: any): any;
714
715
 
715
716
  /**
716
717
  * Apply a modification (or navigation) operation on a **node**.
717
718
  * @see {@link WunderbaumNode.applyCommand}
718
719
  */
719
- applyCommand(cmd: ApplyCommandType, node: WunderbaumNode, opts?: any): any;
720
+ applyCommand(cmd: ApplyCommandType, node: WunderbaumNode, options?: any): any;
720
721
 
721
722
  /**
722
723
  * Apply a modification or navigation operation.
@@ -737,23 +738,23 @@ export class Wunderbaum {
737
738
  applyCommand(
738
739
  cmd: ApplyCommandType,
739
740
  nodeOrOpts?: WunderbaumNode | any,
740
- opts?: any
741
+ options?: any
741
742
  ): any {
742
743
  let // clipboard,
743
744
  node,
744
745
  refNode;
745
- // opts = $.extend(
746
+ // options = $.extend(
746
747
  // { setActive: true, clipboard: CLIPBOARD },
747
- // opts_
748
+ // options_
748
749
  // );
749
750
  if (nodeOrOpts instanceof WunderbaumNode) {
750
751
  node = nodeOrOpts;
751
752
  } else {
752
753
  node = this.getActiveNode()!;
753
- util.assert(opts === undefined);
754
- opts = nodeOrOpts;
754
+ util.assert(options === undefined);
755
+ options = nodeOrOpts;
755
756
  }
756
- // clipboard = opts.clipboard;
757
+ // clipboard = options.clipboard;
757
758
 
758
759
  switch (cmd) {
759
760
  // Sorting and indentation:
@@ -973,15 +974,8 @@ export class Wunderbaum {
973
974
  }
974
975
 
975
976
  /** Recursively expand all expandable nodes (triggers lazy load id needed). */
976
- async expandAll(flag: boolean = true) {
977
- const tag = this.logTime("expandAll(" + flag + ")");
978
- try {
979
- this.enableUpdate(false);
980
- await this.root.expandAll(flag);
981
- } finally {
982
- this.enableUpdate(true);
983
- this.logTimeEnd(tag);
984
- }
977
+ async expandAll(flag: boolean = true, options?: ExpandAllOptions) {
978
+ await this.root.expandAll(flag, options);
985
979
  }
986
980
 
987
981
  /** Recursively select all nodes. */
@@ -1018,26 +1012,20 @@ export class Wunderbaum {
1018
1012
  }
1019
1013
 
1020
1014
  /**
1021
- * Find all nodes that matches condition.
1022
- *
1023
- * @param match title string to search for, or a
1024
- * callback function that returns `true` if a node is matched.
1015
+ * Find all nodes that match condition.
1025
1016
  *
1026
1017
  * @see {@link WunderbaumNode.findAll}
1027
1018
  */
1028
- findAll(match: string | MatcherType) {
1019
+ findAll(match: string | RegExp | MatcherCallback) {
1029
1020
  return this.root.findAll(match);
1030
1021
  }
1031
1022
 
1032
1023
  /**
1033
1024
  * Find first node that matches condition.
1034
1025
  *
1035
- * @param match title string to search for, or a
1036
- * callback function that returns `true` if a node is matched.
1037
1026
  * @see {@link WunderbaumNode.findFirst}
1038
- *
1039
1027
  */
1040
- findFirst(match: string | MatcherType) {
1028
+ findFirst(match: string | RegExp | MatcherCallback) {
1041
1029
  return this.root.findFirst(match);
1042
1030
  }
1043
1031
 
@@ -1049,8 +1037,8 @@ export class Wunderbaum {
1049
1037
  * @see {@link WunderbaumNode.findFirst}
1050
1038
  *
1051
1039
  */
1052
- findKey(key: string): WunderbaumNode | undefined {
1053
- return this.keyMap.get(key);
1040
+ findKey(key: string): WunderbaumNode | null {
1041
+ return this.keyMap.get(key) || null;
1054
1042
  }
1055
1043
 
1056
1044
  /**
@@ -1058,7 +1046,7 @@ export class Wunderbaum {
1058
1046
  * and wrap-around at the end.
1059
1047
  */
1060
1048
  findNextNode(
1061
- match: string | MatcherType,
1049
+ match: string | MatcherCallback,
1062
1050
  startNode?: WunderbaumNode | null
1063
1051
  ): WunderbaumNode | null {
1064
1052
  //, visibleOnly) {
@@ -1383,13 +1371,13 @@ export class Wunderbaum {
1383
1371
 
1384
1372
  let node;
1385
1373
  WunderbaumNode;
1386
- let opts: ScrollToOptions | undefined;
1374
+ let options: ScrollToOptions | undefined;
1387
1375
 
1388
1376
  if (nodeOrOpts instanceof WunderbaumNode) {
1389
1377
  node = nodeOrOpts;
1390
1378
  } else {
1391
- opts = nodeOrOpts;
1392
- node = opts.node;
1379
+ options = nodeOrOpts;
1380
+ node = options.node;
1393
1381
  }
1394
1382
  util.assert(node && node._rowIdx != null);
1395
1383
 
@@ -1401,7 +1389,7 @@ export class Wunderbaum {
1401
1389
  const vpTop = headerHeight;
1402
1390
  const vpRowTop = rowTop - scrollTop;
1403
1391
  const vpRowBottom = vpRowTop + ROW_HEIGHT;
1404
- const topNode = opts?.topNode;
1392
+ const topNode = options?.topNode;
1405
1393
 
1406
1394
  // this.log( `scrollTo(${node.title}), vpTop:${vpTop}px, scrollTop:${scrollTop}, vpHeight:${vpHeight}, rowTop:${rowTop}, vpRowTop:${vpRowTop}`, nodeOrOpts );
1407
1395
  let newScrollTop: number | null = null;
@@ -1670,11 +1658,13 @@ export class Wunderbaum {
1670
1658
  }
1671
1659
  }
1672
1660
  /** Update column headers and width. */
1673
- updateColumns(opts?: any) {
1674
- opts = Object.assign({ calculateCols: true, updateRows: true }, opts);
1661
+ updateColumns(options?: any) {
1662
+ options = Object.assign({ calculateCols: true, updateRows: true }, options);
1675
1663
  const defaultMinWidth = 4;
1676
1664
  const vpWidth = this.element.clientWidth;
1677
1665
  const isGrid = this.isGrid();
1666
+ // Shorten last column width to avoid h-scrollbar
1667
+ const FIX_ADJUST_LAST_COL = 2;
1678
1668
 
1679
1669
  let totalWidth = 0;
1680
1670
  let totalWeight = 0;
@@ -1686,7 +1676,7 @@ export class Wunderbaum {
1686
1676
  this.setCellNav(false);
1687
1677
  }
1688
1678
 
1689
- if (opts.calculateCols) {
1679
+ if (options.calculateCols) {
1690
1680
  // Gather width definitions
1691
1681
  this._columnsById = {};
1692
1682
  for (let col of this.columns) {
@@ -1736,7 +1726,8 @@ export class Wunderbaum {
1736
1726
  col._ofsPx = ofsPx;
1737
1727
  ofsPx += col._widthPx!;
1738
1728
  }
1739
- totalWidth = ofsPx;
1729
+ this.columns[this.columns.length - 1]._widthPx! -= FIX_ADJUST_LAST_COL;
1730
+ totalWidth = ofsPx - FIX_ADJUST_LAST_COL;
1740
1731
  }
1741
1732
  // if (this.options.fixedCol) {
1742
1733
  // 'position: fixed' requires that the content has the correct size
@@ -1751,7 +1742,7 @@ export class Wunderbaum {
1751
1742
  // util.error("BREAK");
1752
1743
  if (modified) {
1753
1744
  this._renderHeaderMarkup();
1754
- if (opts.updateRows) {
1745
+ if (options.updateRows) {
1755
1746
  this._updateRows();
1756
1747
  }
1757
1748
  }
@@ -1819,6 +1810,9 @@ export class Wunderbaum {
1819
1810
  * @internal
1820
1811
  */
1821
1812
  protected _updateViewportImmediately() {
1813
+ // Shorten container height to avoid v-scrollbar
1814
+ const FIX_ADJUST_HEIGHT = 1;
1815
+
1822
1816
  if (this._disableUpdateCount) {
1823
1817
  this.log(
1824
1818
  `IGNORED _updateViewportImmediately() disable level: ${this._disableUpdateCount}`
@@ -1835,7 +1829,8 @@ export class Wunderbaum {
1835
1829
  // let headerHeight = this.headerElement.children[0].children[0].clientHeight;
1836
1830
  // const headerHeight = this.options.headerHeightPx;
1837
1831
  const headerHeight = this.headerElement.clientHeight; // May be 0
1838
- const wantHeight = this.element.clientHeight - headerHeight;
1832
+ const wantHeight =
1833
+ this.element.clientHeight - headerHeight - FIX_ADJUST_HEIGHT;
1839
1834
 
1840
1835
  if (Math.abs(height - wantHeight) > 1.0) {
1841
1836
  // this.log("resize", height, wantHeight);
@@ -1899,11 +1894,11 @@ export class Wunderbaum {
1899
1894
  * (including upper and lower prefetch)
1900
1895
  * -
1901
1896
  */
1902
- protected _updateRows(opts?: any): boolean {
1897
+ protected _updateRows(options?: any): boolean {
1903
1898
  // const label = this.logTime("_updateRows");
1904
1899
  // this.log("_updateRows", opts)
1905
- opts = Object.assign({ newNodesOnly: false }, opts);
1906
- const newNodesOnly = !!opts.newNodesOnly;
1900
+ options = Object.assign({ newNodesOnly: false }, options);
1901
+ const newNodesOnly = !!options.newNodesOnly;
1907
1902
 
1908
1903
  const row_height = ROW_HEIGHT;
1909
1904
  const vp_height = this.element.clientHeight;
@@ -2013,15 +2008,15 @@ export class Wunderbaum {
2013
2008
  * {start: First tree node, reverse: false, includeSelf: true, includeHidden: false, wrap: false}
2014
2009
  * @returns {boolean} false if iteration was canceled
2015
2010
  */
2016
- visitRows(callback: (node: WunderbaumNode) => any, opts?: any): boolean {
2011
+ visitRows(callback: (node: WunderbaumNode) => any, options?: any): boolean {
2017
2012
  if (!this.root.hasChildren()) {
2018
2013
  return false;
2019
2014
  }
2020
- if (opts && opts.reverse) {
2021
- delete opts.reverse;
2022
- return this._visitRowsUp(callback, opts);
2015
+ if (options && options.reverse) {
2016
+ delete options.reverse;
2017
+ return this._visitRowsUp(callback, options);
2023
2018
  }
2024
- opts = opts || {};
2019
+ options = options || {};
2025
2020
  let i,
2026
2021
  nextIdx,
2027
2022
  parent,
@@ -2029,10 +2024,10 @@ export class Wunderbaum {
2029
2024
  siblings,
2030
2025
  stopNode: WunderbaumNode,
2031
2026
  siblingOfs = 0,
2032
- skipFirstNode = opts.includeSelf === false,
2033
- includeHidden = !!opts.includeHidden,
2027
+ skipFirstNode = options.includeSelf === false,
2028
+ includeHidden = !!options.includeHidden,
2034
2029
  checkFilter = !includeHidden && this.filterMode === "hide",
2035
- node: WunderbaumNode = opts.start || this.root.children![0];
2030
+ node: WunderbaumNode = options.start || this.root.children![0];
2036
2031
 
2037
2032
  parent = node.parent;
2038
2033
  while (parent) {
@@ -2091,11 +2086,11 @@ export class Wunderbaum {
2091
2086
  parent = parent.parent;
2092
2087
  siblingOfs = 1; //
2093
2088
 
2094
- if (!parent && opts.wrap) {
2089
+ if (!parent && options.wrap) {
2095
2090
  this.logDebug("visitRows(): wrap around");
2096
- util.assert(opts.start, "`wrap` option requires `start`");
2097
- stopNode = opts.start;
2098
- opts.wrap = false;
2091
+ util.assert(options.start, "`wrap` option requires `start`");
2092
+ stopNode = options.start;
2093
+ options.wrap = false;
2099
2094
  parent = this.root;
2100
2095
  siblingOfs = 0;
2101
2096
  }