wunderbaum 0.0.1 → 0.0.2
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 +3 -2
- package/dist/wunderbaum.css +1 -1
- package/dist/wunderbaum.d.ts +400 -80
- package/dist/wunderbaum.esm.js +356 -135
- package/dist/wunderbaum.esm.min.js +28 -18
- package/dist/wunderbaum.esm.min.js.map +1 -1
- package/dist/wunderbaum.umd.js +358 -137
- package/dist/wunderbaum.umd.min.js +34 -24
- package/dist/wunderbaum.umd.min.js.map +1 -1
- package/package.json +29 -30
- package/src/common.ts +6 -5
- package/src/drag_observer.ts +169 -0
- package/src/util.ts +47 -13
- package/src/wb_ext_dnd.ts +144 -3
- package/src/wb_ext_filter.ts +35 -35
- package/src/wb_ext_grid.ts +45 -0
- package/src/wb_node.ts +23 -29
- package/src/wb_options.ts +138 -25
- package/src/wunderbaum.scss +20 -1
- package/src/wunderbaum.ts +82 -37
package/src/wb_node.ts
CHANGED
|
@@ -236,7 +236,7 @@ export class WunderbaumNode {
|
|
|
236
236
|
// this.fixSelection3FromEndNodes();
|
|
237
237
|
// }
|
|
238
238
|
// this.triggerModifyChild("add", nodeList.length === 1 ? nodeList[0] : null);
|
|
239
|
-
this.tree.setModified(ChangeType.structure
|
|
239
|
+
this.tree.setModified(ChangeType.structure);
|
|
240
240
|
return nodeList[0];
|
|
241
241
|
} finally {
|
|
242
242
|
this.tree.enableUpdate(true);
|
|
@@ -784,7 +784,7 @@ export class WunderbaumNode {
|
|
|
784
784
|
|
|
785
785
|
if (wasExpanded) {
|
|
786
786
|
this.expanded = true;
|
|
787
|
-
this.tree.
|
|
787
|
+
this.tree.setModified(ChangeType.structure);
|
|
788
788
|
} else {
|
|
789
789
|
this.render(); // Fix expander icon to 'loaded'
|
|
790
790
|
}
|
|
@@ -956,7 +956,7 @@ export class WunderbaumNode {
|
|
|
956
956
|
}, true);
|
|
957
957
|
}
|
|
958
958
|
|
|
959
|
-
tree.
|
|
959
|
+
tree.setModified(ChangeType.structure);
|
|
960
960
|
// TODO: fix selection state
|
|
961
961
|
// TODO: fix active state
|
|
962
962
|
}
|
|
@@ -1035,7 +1035,7 @@ export class WunderbaumNode {
|
|
|
1035
1035
|
if (!this.isRootNode()) {
|
|
1036
1036
|
this.expanded = false;
|
|
1037
1037
|
}
|
|
1038
|
-
this.tree.
|
|
1038
|
+
this.tree.setModified(ChangeType.structure);
|
|
1039
1039
|
}
|
|
1040
1040
|
|
|
1041
1041
|
/** Remove all HTML markup from the DOM. */
|
|
@@ -1194,7 +1194,7 @@ export class WunderbaumNode {
|
|
|
1194
1194
|
ofsTitlePx += ICON_WIDTH;
|
|
1195
1195
|
}
|
|
1196
1196
|
|
|
1197
|
-
if (level > treeOptions.minExpandLevel) {
|
|
1197
|
+
if (treeOptions.minExpandLevel && level > treeOptions.minExpandLevel) {
|
|
1198
1198
|
expanderSpan = document.createElement("i");
|
|
1199
1199
|
nodeElem.appendChild(expanderSpan);
|
|
1200
1200
|
ofsTitlePx += ICON_WIDTH;
|
|
@@ -1214,7 +1214,7 @@ export class WunderbaumNode {
|
|
|
1214
1214
|
// Store the width of leading icons with the node, so we can calculate
|
|
1215
1215
|
// the width of the embedded title span later
|
|
1216
1216
|
(<any>nodeElem)._ofsTitlePx = ofsTitlePx;
|
|
1217
|
-
if (tree.options.dnd
|
|
1217
|
+
if (tree.options.dnd!.dragStart) {
|
|
1218
1218
|
nodeElem.draggable = true;
|
|
1219
1219
|
}
|
|
1220
1220
|
|
|
@@ -1290,10 +1290,11 @@ export class WunderbaumNode {
|
|
|
1290
1290
|
|
|
1291
1291
|
if (this.titleWithHighlight) {
|
|
1292
1292
|
titleSpan.innerHTML = this.titleWithHighlight;
|
|
1293
|
-
} else if (tree.options.escapeTitles) {
|
|
1294
|
-
titleSpan.textContent = this.title;
|
|
1295
1293
|
} else {
|
|
1296
|
-
|
|
1294
|
+
// } else if (tree.options.escapeTitles) {
|
|
1295
|
+
titleSpan.textContent = this.title;
|
|
1296
|
+
// } else {
|
|
1297
|
+
// titleSpan.innerHTML = this.title;
|
|
1297
1298
|
}
|
|
1298
1299
|
// Set the width of the title span, so overflow ellipsis work
|
|
1299
1300
|
if (!treeOptions.skeleton) {
|
|
@@ -1342,7 +1343,7 @@ export class WunderbaumNode {
|
|
|
1342
1343
|
this.expanded = false;
|
|
1343
1344
|
this.lazy = true;
|
|
1344
1345
|
this.children = null;
|
|
1345
|
-
this.tree.
|
|
1346
|
+
this.tree.setModified(ChangeType.structure);
|
|
1346
1347
|
}
|
|
1347
1348
|
|
|
1348
1349
|
/** Convert node (or whole branch) into a plain object.
|
|
@@ -1482,7 +1483,7 @@ export class WunderbaumNode {
|
|
|
1482
1483
|
}) === false
|
|
1483
1484
|
) {
|
|
1484
1485
|
tree.activeNode = null;
|
|
1485
|
-
prev?.
|
|
1486
|
+
prev?.setModified();
|
|
1486
1487
|
return;
|
|
1487
1488
|
}
|
|
1488
1489
|
}
|
|
@@ -1493,8 +1494,8 @@ export class WunderbaumNode {
|
|
|
1493
1494
|
|
|
1494
1495
|
if (prev !== this) {
|
|
1495
1496
|
tree.activeNode = this;
|
|
1496
|
-
prev?.
|
|
1497
|
-
this.
|
|
1497
|
+
prev?.setModified();
|
|
1498
|
+
this.setModified();
|
|
1498
1499
|
}
|
|
1499
1500
|
if (
|
|
1500
1501
|
options &&
|
|
@@ -1510,16 +1511,9 @@ export class WunderbaumNode {
|
|
|
1510
1511
|
this.scrollIntoView();
|
|
1511
1512
|
}
|
|
1512
1513
|
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
}
|
|
1517
|
-
if (type === ChangeType.structure) {
|
|
1518
|
-
this.tree.updateViewport();
|
|
1519
|
-
} else if (this._rowElem) {
|
|
1520
|
-
// otherwise not in viewport, so no need to render
|
|
1521
|
-
this.render();
|
|
1522
|
-
}
|
|
1514
|
+
setModified(change: ChangeType = ChangeType.status) {
|
|
1515
|
+
util.assert(change === ChangeType.status);
|
|
1516
|
+
this.tree.setModified(ChangeType.row, this);
|
|
1523
1517
|
}
|
|
1524
1518
|
|
|
1525
1519
|
async setExpanded(flag: boolean = true, options?: any) {
|
|
@@ -1537,7 +1531,7 @@ export class WunderbaumNode {
|
|
|
1537
1531
|
await this.loadLazy();
|
|
1538
1532
|
}
|
|
1539
1533
|
this.expanded = flag;
|
|
1540
|
-
this.
|
|
1534
|
+
this.tree.setModified(ChangeType.structure);
|
|
1541
1535
|
}
|
|
1542
1536
|
|
|
1543
1537
|
setIcon() {
|
|
@@ -1548,8 +1542,8 @@ export class WunderbaumNode {
|
|
|
1548
1542
|
setFocus(flag: boolean = true, options?: any) {
|
|
1549
1543
|
const prev = this.tree.focusNode;
|
|
1550
1544
|
this.tree.focusNode = this;
|
|
1551
|
-
prev?.
|
|
1552
|
-
this.
|
|
1545
|
+
prev?.setModified();
|
|
1546
|
+
this.setModified();
|
|
1553
1547
|
}
|
|
1554
1548
|
|
|
1555
1549
|
setSelected(flag: boolean = true, options?: any) {
|
|
@@ -1558,7 +1552,7 @@ export class WunderbaumNode {
|
|
|
1558
1552
|
this._callEvent("select", { flag: flag });
|
|
1559
1553
|
}
|
|
1560
1554
|
this.selected = !!flag;
|
|
1561
|
-
this.
|
|
1555
|
+
this.setModified();
|
|
1562
1556
|
}
|
|
1563
1557
|
|
|
1564
1558
|
/** Show node status (ok, loading, error, noData) using styles and a dummy child node.
|
|
@@ -1649,13 +1643,13 @@ export class WunderbaumNode {
|
|
|
1649
1643
|
default:
|
|
1650
1644
|
util.error("invalid node status " + status);
|
|
1651
1645
|
}
|
|
1652
|
-
tree.
|
|
1646
|
+
tree.setModified(ChangeType.structure);
|
|
1653
1647
|
return statusNode;
|
|
1654
1648
|
}
|
|
1655
1649
|
|
|
1656
1650
|
setTitle(title: string): void {
|
|
1657
1651
|
this.title = title;
|
|
1658
|
-
this.
|
|
1652
|
+
this.setModified();
|
|
1659
1653
|
// this.triggerModify("rename"); // TODO
|
|
1660
1654
|
}
|
|
1661
1655
|
|
package/src/wb_options.ts
CHANGED
|
@@ -7,8 +7,10 @@
|
|
|
7
7
|
import {
|
|
8
8
|
BoolOptionResolver,
|
|
9
9
|
NavigationModeOption,
|
|
10
|
-
|
|
10
|
+
WbNodeEventType,
|
|
11
|
+
WbTreeEventType,
|
|
11
12
|
} from "./common";
|
|
13
|
+
import { DndOptionsType } from "./wb_ext_dnd";
|
|
12
14
|
|
|
13
15
|
export interface WbNodeData {
|
|
14
16
|
title: string;
|
|
@@ -16,7 +18,7 @@ export interface WbNodeData {
|
|
|
16
18
|
refKey?: string;
|
|
17
19
|
expanded?: boolean;
|
|
18
20
|
selected?: boolean;
|
|
19
|
-
checkbox?: boolean |
|
|
21
|
+
checkbox?: boolean | string;
|
|
20
22
|
children?: Array<WbNodeData>;
|
|
21
23
|
// ...any?: Any;
|
|
22
24
|
}
|
|
@@ -62,56 +64,167 @@ export interface WunderbaumOptions {
|
|
|
62
64
|
*
|
|
63
65
|
* Default: `{}`.
|
|
64
66
|
*/
|
|
65
|
-
types
|
|
67
|
+
types?: any; //[key: string]: any;
|
|
66
68
|
/**
|
|
67
69
|
* A list of maps that define column headers. If this option is set,
|
|
68
|
-
* Wunderbaum becomes a
|
|
70
|
+
* Wunderbaum becomes a treegrid control instead of a plain tree.
|
|
69
71
|
* Column definitions can be passed as tree option, or be part of a `source`
|
|
70
72
|
* response.
|
|
71
73
|
* Default: `[]` meaning this is a plain tree.
|
|
72
74
|
*/
|
|
73
75
|
columns?: Array<any>;
|
|
74
76
|
/**
|
|
75
|
-
*
|
|
77
|
+
* If true, add a `wb-skeleton` class to all nodes, that will result in a
|
|
78
|
+
* 'glow' effect. Typically used with initial dummy nodes, while loading the
|
|
79
|
+
* real data.
|
|
76
80
|
* Default: false.
|
|
77
81
|
*/
|
|
78
|
-
skeleton
|
|
82
|
+
skeleton?: false;
|
|
79
83
|
/**
|
|
80
|
-
*
|
|
81
|
-
* Default: false.
|
|
84
|
+
* Translation map for some system messages.
|
|
82
85
|
*/
|
|
83
|
-
strings
|
|
86
|
+
strings?: any; //[key: string] string;
|
|
84
87
|
/**
|
|
88
|
+
* 0:quiet, 1:errors, 2:warnings, 3:info, 4:verbose
|
|
89
|
+
* Default: 3 (4 in local debug environment)
|
|
85
90
|
*/
|
|
86
|
-
debugLevel:
|
|
87
|
-
minExpandLevel: 0;
|
|
88
|
-
escapeTitles: true;
|
|
89
|
-
headerHeightPx: 22;
|
|
90
|
-
autoCollapse: false;
|
|
91
|
-
// --- Extensions ---
|
|
92
|
-
dnd: any; // = {};
|
|
93
|
-
filter: any; // = {};
|
|
91
|
+
debugLevel: number;
|
|
94
92
|
/**
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
|
|
98
|
-
|
|
93
|
+
* Number of levels that are forced to be expanded, and have no expander icon.
|
|
94
|
+
* Default: 0
|
|
95
|
+
*/
|
|
96
|
+
minExpandLevel?: number;
|
|
97
|
+
// escapeTitles: boolean;
|
|
98
|
+
/**
|
|
99
|
+
* Height of the header row div.
|
|
100
|
+
* Default: 22
|
|
101
|
+
*/
|
|
102
|
+
headerHeightPx: number;
|
|
103
|
+
/**
|
|
104
|
+
* Height of a node row div.
|
|
105
|
+
* Default: 22
|
|
106
|
+
*/
|
|
107
|
+
rowHeightPx?: number;
|
|
108
|
+
/**
|
|
109
|
+
* Collapse siblings when a node is expanded.
|
|
110
|
+
* Default: false
|
|
111
|
+
*/
|
|
112
|
+
autoCollapse?: boolean;
|
|
113
|
+
/**
|
|
114
|
+
* Default: NavigationModeOption.startRow
|
|
99
115
|
*/
|
|
100
116
|
navigationMode?: NavigationModeOption;
|
|
117
|
+
/**
|
|
118
|
+
* Show/hide header (pass bool or string)
|
|
119
|
+
*/
|
|
120
|
+
header?: boolean | string | null;
|
|
121
|
+
/**
|
|
122
|
+
*
|
|
123
|
+
*/
|
|
124
|
+
showSpinner?: boolean;
|
|
125
|
+
/**
|
|
126
|
+
* Default: true
|
|
127
|
+
*/
|
|
128
|
+
checkbox?: boolean | "radio" | BoolOptionResolver;
|
|
129
|
+
/**
|
|
130
|
+
* Default: 200
|
|
131
|
+
*/
|
|
132
|
+
updateThrottleWait?: number;
|
|
133
|
+
// --- KeyNav ---
|
|
134
|
+
/**
|
|
135
|
+
* Default: true
|
|
136
|
+
*/
|
|
137
|
+
quicksearch?: boolean;
|
|
138
|
+
|
|
139
|
+
// --- Extensions ---
|
|
140
|
+
dnd?: DndOptionsType; // = {};
|
|
141
|
+
filter: any; // = {};
|
|
142
|
+
grid: any; // = {};
|
|
101
143
|
// --- Events ---
|
|
102
144
|
/**
|
|
103
145
|
* Called after initial data was loaded and tree markup was rendered.
|
|
146
|
+
* Check `e.error` for status.
|
|
104
147
|
* @category Callback
|
|
105
148
|
*/
|
|
106
|
-
init?: (e:
|
|
149
|
+
init?: (e: WbTreeEventType) => void;
|
|
107
150
|
/**
|
|
108
|
-
*
|
|
151
|
+
*
|
|
152
|
+
* @category Callback
|
|
153
|
+
*/
|
|
154
|
+
update?: (e: WbTreeEventType) => void;
|
|
155
|
+
/**
|
|
156
|
+
*
|
|
157
|
+
* @category Callback
|
|
158
|
+
*/
|
|
159
|
+
activate?: (e: WbNodeEventType) => void;
|
|
160
|
+
/**
|
|
161
|
+
*
|
|
162
|
+
* @category Callback
|
|
163
|
+
*/
|
|
164
|
+
deactivate?: (e: WbNodeEventType) => void;
|
|
165
|
+
/**
|
|
166
|
+
*
|
|
167
|
+
* @category Callback
|
|
168
|
+
*/
|
|
169
|
+
change?: (e: WbNodeEventType) => void;
|
|
170
|
+
/**
|
|
171
|
+
*
|
|
172
|
+
* @category Callback
|
|
173
|
+
*/
|
|
174
|
+
click?: (e: WbTreeEventType) => void;
|
|
175
|
+
/**
|
|
176
|
+
*
|
|
177
|
+
* @category Callback
|
|
178
|
+
*/
|
|
179
|
+
discard?: (e: WbNodeEventType) => void;
|
|
180
|
+
/**
|
|
181
|
+
*
|
|
182
|
+
* @category Callback
|
|
183
|
+
*/
|
|
184
|
+
error?: (e: WbTreeEventType) => void;
|
|
185
|
+
/**
|
|
186
|
+
*
|
|
187
|
+
* @category Callback
|
|
188
|
+
*/
|
|
189
|
+
enhanceTitle?: (e: WbNodeEventType) => void;
|
|
190
|
+
/**
|
|
191
|
+
*
|
|
192
|
+
* Check `e.flag` for status.
|
|
109
193
|
* @category Callback
|
|
110
194
|
*/
|
|
111
|
-
|
|
195
|
+
focus?: (e: WbTreeEventType) => void;
|
|
196
|
+
/**
|
|
197
|
+
*
|
|
198
|
+
* @category Callback
|
|
199
|
+
*/
|
|
200
|
+
keydown?: (e: WbNodeEventType) => void;
|
|
112
201
|
/**
|
|
113
202
|
* Called after data was loaded from local storage.
|
|
203
|
+
*/
|
|
204
|
+
load?: (e: WbNodeEventType) => void;
|
|
205
|
+
/**
|
|
206
|
+
* @category Callback
|
|
207
|
+
*/
|
|
208
|
+
modifyChild?: (e: WbNodeEventType) => void;
|
|
209
|
+
/**
|
|
210
|
+
*
|
|
211
|
+
* @category Callback
|
|
212
|
+
*/
|
|
213
|
+
receive?: (e: WbNodeEventType) => void;
|
|
214
|
+
/**
|
|
215
|
+
*
|
|
216
|
+
* @category Callback
|
|
217
|
+
*/
|
|
218
|
+
render?: (e: WbNodeEventType) => void;
|
|
219
|
+
/**
|
|
220
|
+
*
|
|
221
|
+
* @category Callback
|
|
222
|
+
*/
|
|
223
|
+
renderStatusNode?: (e: WbNodeEventType) => void;
|
|
224
|
+
/**
|
|
225
|
+
*
|
|
226
|
+
* Check `e.flag` for status.
|
|
114
227
|
* @category Callback
|
|
115
228
|
*/
|
|
116
|
-
|
|
229
|
+
select?: (e: WbNodeEventType) => void;
|
|
117
230
|
}
|
package/src/wunderbaum.scss
CHANGED
|
@@ -177,7 +177,7 @@ div.wunderbaum {
|
|
|
177
177
|
span.wb-col {
|
|
178
178
|
position: absolute;
|
|
179
179
|
display: inline-block;
|
|
180
|
-
text-overflow: ellipsis;
|
|
180
|
+
// text-overflow: ellipsis;
|
|
181
181
|
height: $row-inner-height;
|
|
182
182
|
line-height: $row-inner-height;
|
|
183
183
|
padding: 0 $col-padding-x;
|
|
@@ -185,6 +185,25 @@ div.wunderbaum {
|
|
|
185
185
|
&:last-of-type {
|
|
186
186
|
border-right: none;
|
|
187
187
|
}
|
|
188
|
+
overflow: visible; // allow resizer to overlap next col
|
|
189
|
+
|
|
190
|
+
span.wb-col-title {
|
|
191
|
+
width: 100%;
|
|
192
|
+
overflow: hidden;
|
|
193
|
+
text-overflow: ellipsis;
|
|
194
|
+
}
|
|
195
|
+
span.wb-col-resizer {
|
|
196
|
+
position: absolute;
|
|
197
|
+
top: 0;
|
|
198
|
+
// left: auto;
|
|
199
|
+
right: -1px;
|
|
200
|
+
width: 3px;
|
|
201
|
+
// float: right;
|
|
202
|
+
border: none;
|
|
203
|
+
border-right: 2px solid $border-color;
|
|
204
|
+
height: 100%;
|
|
205
|
+
cursor: col-resize;
|
|
206
|
+
}
|
|
188
207
|
}
|
|
189
208
|
|
|
190
209
|
span.wb-node {
|
package/src/wunderbaum.ts
CHANGED
|
@@ -16,6 +16,7 @@ import { FilterExtension } from "./wb_ext_filter";
|
|
|
16
16
|
import { KeynavExtension } from "./wb_ext_keynav";
|
|
17
17
|
import { LoggerExtension } from "./wb_ext_logger";
|
|
18
18
|
import { DndExtension } from "./wb_ext_dnd";
|
|
19
|
+
import { GridExtension } from "./wb_ext_grid";
|
|
19
20
|
import { ExtensionsDict, WunderbaumExtension } from "./wb_extension_base";
|
|
20
21
|
|
|
21
22
|
import {
|
|
@@ -40,7 +41,7 @@ import { WunderbaumOptions } from "./wb_options";
|
|
|
40
41
|
|
|
41
42
|
// const class_prefix = "wb-";
|
|
42
43
|
// const node_props: string[] = ["title", "key", "refKey"];
|
|
43
|
-
const MAX_CHANGED_NODES = 10;
|
|
44
|
+
// const MAX_CHANGED_NODES = 10;
|
|
44
45
|
|
|
45
46
|
/**
|
|
46
47
|
* A persistent plain object or array.
|
|
@@ -94,6 +95,7 @@ export class Wunderbaum {
|
|
|
94
95
|
protected changedSince = 0;
|
|
95
96
|
protected changes = new Set<ChangeType>();
|
|
96
97
|
protected changedNodes = new Set<WunderbaumNode>();
|
|
98
|
+
protected changeRedrawPending = false;
|
|
97
99
|
|
|
98
100
|
// --- FILTER ---
|
|
99
101
|
public filterMode: FilterModeType = null;
|
|
@@ -125,7 +127,7 @@ export class Wunderbaum {
|
|
|
125
127
|
rowHeightPx: ROW_HEIGHT,
|
|
126
128
|
columns: null,
|
|
127
129
|
types: null,
|
|
128
|
-
escapeTitles: true,
|
|
130
|
+
// escapeTitles: true,
|
|
129
131
|
showSpinner: false,
|
|
130
132
|
checkbox: true,
|
|
131
133
|
minExpandLevel: 0,
|
|
@@ -185,6 +187,7 @@ export class Wunderbaum {
|
|
|
185
187
|
this._registerExtension(new EditExtension(this));
|
|
186
188
|
this._registerExtension(new FilterExtension(this));
|
|
187
189
|
this._registerExtension(new DndExtension(this));
|
|
190
|
+
this._registerExtension(new GridExtension(this));
|
|
188
191
|
this._registerExtension(new LoggerExtension(this));
|
|
189
192
|
|
|
190
193
|
// --- Evaluate options
|
|
@@ -313,10 +316,8 @@ export class Wunderbaum {
|
|
|
313
316
|
.finally(() => {
|
|
314
317
|
this.element.querySelector("progress.spinner")?.remove();
|
|
315
318
|
this.element.classList.remove("wb-initializing");
|
|
316
|
-
// this.updateViewport();
|
|
317
319
|
});
|
|
318
320
|
} else {
|
|
319
|
-
// this.updateViewport();
|
|
320
321
|
readyDeferred.resolve();
|
|
321
322
|
}
|
|
322
323
|
|
|
@@ -328,14 +329,11 @@ export class Wunderbaum {
|
|
|
328
329
|
|
|
329
330
|
// --- Bind listeners
|
|
330
331
|
this.scrollContainer.addEventListener("scroll", (e: Event) => {
|
|
331
|
-
this.
|
|
332
|
+
this.setModified(ChangeType.vscroll);
|
|
332
333
|
});
|
|
333
334
|
|
|
334
|
-
// window.addEventListener("resize", (e: Event) => {
|
|
335
|
-
// this.updateViewport();
|
|
336
|
-
// });
|
|
337
335
|
this.resizeObserver = new ResizeObserver((entries) => {
|
|
338
|
-
this.
|
|
336
|
+
this.setModified(ChangeType.vscroll);
|
|
339
337
|
console.log("ResizeObserver: Size changed", entries);
|
|
340
338
|
});
|
|
341
339
|
this.resizeObserver.observe(this.element);
|
|
@@ -845,7 +843,7 @@ export class Wunderbaum {
|
|
|
845
843
|
// public cellNavMode = false;
|
|
846
844
|
// public lastQuicksearchTime = 0;
|
|
847
845
|
// public lastQuicksearchTerm = "";
|
|
848
|
-
this.
|
|
846
|
+
this.setModified(ChangeType.structure);
|
|
849
847
|
}
|
|
850
848
|
|
|
851
849
|
/**
|
|
@@ -1157,9 +1155,11 @@ export class Wunderbaum {
|
|
|
1157
1155
|
static getEventInfo(event: Event) {
|
|
1158
1156
|
let target = <Element>event.target,
|
|
1159
1157
|
cl = target.classList,
|
|
1160
|
-
parentCol = target.closest(".wb-col"),
|
|
1158
|
+
parentCol = target.closest("span.wb-col") as HTMLSpanElement,
|
|
1161
1159
|
node = Wunderbaum.getNode(target),
|
|
1160
|
+
tree = node ? node.tree : Wunderbaum.getTree(event),
|
|
1162
1161
|
res = {
|
|
1162
|
+
tree: tree,
|
|
1163
1163
|
node: node,
|
|
1164
1164
|
region: NodeRegion.unknown,
|
|
1165
1165
|
colDef: undefined,
|
|
@@ -1189,13 +1189,15 @@ export class Wunderbaum {
|
|
|
1189
1189
|
res.colIdx = idx;
|
|
1190
1190
|
} else {
|
|
1191
1191
|
// Somewhere near the title
|
|
1192
|
-
|
|
1192
|
+
if (event.type !== "mousemove") {
|
|
1193
|
+
console.warn("getEventInfo(): not found", event, res);
|
|
1194
|
+
}
|
|
1193
1195
|
return res;
|
|
1194
1196
|
}
|
|
1195
1197
|
if (res.colIdx === -1) {
|
|
1196
1198
|
res.colIdx = 0;
|
|
1197
1199
|
}
|
|
1198
|
-
res.colDef =
|
|
1200
|
+
res.colDef = tree?.columns[res.colIdx];
|
|
1199
1201
|
res.colDef != null ? (res.colId = (<any>res.colDef).id) : 0;
|
|
1200
1202
|
// this.log("Event", event, res);
|
|
1201
1203
|
return res;
|
|
@@ -1298,6 +1300,7 @@ export class Wunderbaum {
|
|
|
1298
1300
|
let start = opts?.startIdx;
|
|
1299
1301
|
let end = opts?.endIdx;
|
|
1300
1302
|
const obsoleteViewNodes = this.viewNodes;
|
|
1303
|
+
const newNodesOnly = !!util.getOption(opts, "newNodesOnly");
|
|
1301
1304
|
|
|
1302
1305
|
this.viewNodes = new Set();
|
|
1303
1306
|
let viewNodes = this.viewNodes;
|
|
@@ -1322,9 +1325,10 @@ export class Wunderbaum {
|
|
|
1322
1325
|
if (idx < start || idx > end) {
|
|
1323
1326
|
node._callEvent("discard");
|
|
1324
1327
|
node.removeMarkup();
|
|
1325
|
-
} else {
|
|
1326
|
-
// if (!node._rowElem || prevIdx != idx) {
|
|
1328
|
+
} else if (!node._rowElem || !newNodesOnly) {
|
|
1327
1329
|
node.render({ top: top });
|
|
1330
|
+
// }else{
|
|
1331
|
+
// node.log("ignrored render")
|
|
1328
1332
|
}
|
|
1329
1333
|
idx++;
|
|
1330
1334
|
top += height;
|
|
@@ -1352,21 +1356,25 @@ export class Wunderbaum {
|
|
|
1352
1356
|
);
|
|
1353
1357
|
|
|
1354
1358
|
for (let i = 0; i < this.columns.length; i++) {
|
|
1355
|
-
|
|
1356
|
-
|
|
1359
|
+
const col = this.columns[i];
|
|
1360
|
+
const colElem = <HTMLElement>headerRow.children[i];
|
|
1361
|
+
|
|
1357
1362
|
colElem.style.left = col._ofsPx + "px";
|
|
1358
1363
|
colElem.style.width = col._widthPx + "px";
|
|
1359
|
-
colElem.textContent = col.title || col.id;
|
|
1364
|
+
// colElem.textContent = col.title || col.id;
|
|
1365
|
+
const title = util.escapeHtml(col.title || col.id);
|
|
1366
|
+
colElem.innerHTML = `<span class="wb-col-title">${title}</span> <span class="wb-col-resizer"></span>`;
|
|
1367
|
+
// colElem.innerHTML = `${title} <span class="wb-col-resizer"></span>`;
|
|
1360
1368
|
}
|
|
1361
1369
|
}
|
|
1362
1370
|
|
|
1363
1371
|
/**
|
|
1372
|
+
* Make sure that this node is scrolled into the viewport.
|
|
1364
1373
|
*
|
|
1365
1374
|
* @param {boolean | PlainObject} [effects=false] animation options.
|
|
1366
1375
|
* @param {object} [options=null] {topNode: null, effects: ..., parent: ...}
|
|
1367
1376
|
* this node will remain visible in
|
|
1368
1377
|
* any case, even if `this` is outside the scroll pane.
|
|
1369
|
-
* Make sure that a node is scrolled into the viewport.
|
|
1370
1378
|
*/
|
|
1371
1379
|
scrollTo(opts: any) {
|
|
1372
1380
|
const MARGIN = 1;
|
|
@@ -1388,10 +1396,13 @@ export class Wunderbaum {
|
|
|
1388
1396
|
// Node is above viewport
|
|
1389
1397
|
newTop = nodeOfs + MARGIN;
|
|
1390
1398
|
}
|
|
1391
|
-
this.log("scrollTo(" + nodeOfs + "): " + curTop + " => " + newTop, height);
|
|
1392
1399
|
if (newTop != null) {
|
|
1400
|
+
this.log(
|
|
1401
|
+
"scrollTo(" + nodeOfs + "): " + curTop + " => " + newTop,
|
|
1402
|
+
height
|
|
1403
|
+
);
|
|
1393
1404
|
this.scrollContainer.scrollTop = newTop;
|
|
1394
|
-
this.
|
|
1405
|
+
this.setModified(ChangeType.vscroll);
|
|
1395
1406
|
}
|
|
1396
1407
|
}
|
|
1397
1408
|
|
|
@@ -1456,6 +1467,9 @@ export class Wunderbaum {
|
|
|
1456
1467
|
setModified(change: ChangeType, options?: any): void;
|
|
1457
1468
|
|
|
1458
1469
|
/** */
|
|
1470
|
+
setModified(change: ChangeType, node: WunderbaumNode, options?: any): void;
|
|
1471
|
+
|
|
1472
|
+
/* */
|
|
1459
1473
|
setModified(
|
|
1460
1474
|
change: ChangeType,
|
|
1461
1475
|
node?: WunderbaumNode | any,
|
|
@@ -1464,20 +1478,47 @@ export class Wunderbaum {
|
|
|
1464
1478
|
if (!(node instanceof WunderbaumNode)) {
|
|
1465
1479
|
options = node;
|
|
1466
1480
|
}
|
|
1467
|
-
if (
|
|
1468
|
-
|
|
1469
|
-
}
|
|
1470
|
-
this.changes.add(change);
|
|
1471
|
-
if (change === ChangeType.structure) {
|
|
1472
|
-
this.changedNodes.clear();
|
|
1473
|
-
} else if (node && !this.changes.has(ChangeType.structure)) {
|
|
1474
|
-
if (this.changedNodes.size < MAX_CHANGED_NODES) {
|
|
1475
|
-
this.changedNodes.add(node);
|
|
1476
|
-
} else {
|
|
1477
|
-
this.changes.add(ChangeType.structure);
|
|
1478
|
-
this.changedNodes.clear();
|
|
1479
|
-
}
|
|
1481
|
+
if (this._disableUpdate) {
|
|
1482
|
+
return;
|
|
1480
1483
|
}
|
|
1484
|
+
const immediate = !!util.getOption(options, "immediate");
|
|
1485
|
+
|
|
1486
|
+
switch (change) {
|
|
1487
|
+
case ChangeType.any:
|
|
1488
|
+
case ChangeType.structure:
|
|
1489
|
+
case ChangeType.header:
|
|
1490
|
+
this.changeRedrawPending = true;
|
|
1491
|
+
this.updateViewport(immediate);
|
|
1492
|
+
break;
|
|
1493
|
+
case ChangeType.vscroll:
|
|
1494
|
+
this.updateViewport(immediate);
|
|
1495
|
+
break;
|
|
1496
|
+
case ChangeType.row:
|
|
1497
|
+
case ChangeType.status:
|
|
1498
|
+
// Single nodes are immedialtely updated if already inside the viewport
|
|
1499
|
+
// (otherwise we can ignore)
|
|
1500
|
+
if (node._rowElem) {
|
|
1501
|
+
node.render();
|
|
1502
|
+
}
|
|
1503
|
+
break;
|
|
1504
|
+
default:
|
|
1505
|
+
util.error(`Invalid change type ${change}`);
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1508
|
+
// if (!this.changedSince) {
|
|
1509
|
+
// this.changedSince = Date.now();
|
|
1510
|
+
// }
|
|
1511
|
+
// this.changes.add(change);
|
|
1512
|
+
// if (change === ChangeType.structure) {
|
|
1513
|
+
// this.changedNodes.clear();
|
|
1514
|
+
// } else if (node && !this.changes.has(ChangeType.structure)) {
|
|
1515
|
+
// if (this.changedNodes.size < MAX_CHANGED_NODES) {
|
|
1516
|
+
// this.changedNodes.add(node);
|
|
1517
|
+
// } else {
|
|
1518
|
+
// this.changes.add(ChangeType.structure);
|
|
1519
|
+
// this.changedNodes.clear();
|
|
1520
|
+
// }
|
|
1521
|
+
// }
|
|
1481
1522
|
// this.log("setModified(" + change + ")", node);
|
|
1482
1523
|
}
|
|
1483
1524
|
|
|
@@ -1562,13 +1603,16 @@ export class Wunderbaum {
|
|
|
1562
1603
|
if (this._disableUpdate) {
|
|
1563
1604
|
return;
|
|
1564
1605
|
}
|
|
1606
|
+
const newNodesOnly = !this.changeRedrawPending;
|
|
1607
|
+
this.changeRedrawPending = false;
|
|
1608
|
+
|
|
1565
1609
|
let height = this.scrollContainer.clientHeight;
|
|
1566
|
-
// We cannot get the height for
|
|
1610
|
+
// We cannot get the height for absolut positioned parent, so look at first col
|
|
1567
1611
|
// let headerHeight = this.headerElement.clientHeight
|
|
1568
1612
|
// let headerHeight = this.headerElement.children[0].children[0].clientHeight;
|
|
1569
1613
|
const headerHeight = this.options.headerHeightPx;
|
|
1570
|
-
|
|
1571
|
-
|
|
1614
|
+
const wantHeight = this.element.clientHeight - headerHeight;
|
|
1615
|
+
const ofs = this.scrollContainer.scrollTop;
|
|
1572
1616
|
|
|
1573
1617
|
if (Math.abs(height - wantHeight) > 1.0) {
|
|
1574
1618
|
// this.log("resize", height, wantHeight);
|
|
@@ -1580,6 +1624,7 @@ export class Wunderbaum {
|
|
|
1580
1624
|
this.render({
|
|
1581
1625
|
startIdx: Math.max(0, ofs / ROW_HEIGHT - RENDER_MAX_PREFETCH),
|
|
1582
1626
|
endIdx: Math.max(0, (ofs + height) / ROW_HEIGHT + RENDER_MAX_PREFETCH),
|
|
1627
|
+
newNodesOnly: newNodesOnly,
|
|
1583
1628
|
});
|
|
1584
1629
|
this._callEvent("update");
|
|
1585
1630
|
}
|