Added isToggled boolean to tree nodes and toggleIsCollapsed() method to Store
Brian Vaughn committed
Apr 9, 2019 at 18:10 UTC
79827c535bda8ada21a2dca8138b4a218788419e
2 files changed
+47
-5
src/devtools/store.js
+44
-5
@@ -287,16 +287,18 @@ export default class Store extends EventEmitter {
287
let currentElement = ((this._idToElement.get(firstChildID): any): Element);
288
let currentWeight = rootWeight;
289
while (index !== currentWeight) {
290
- for (let i = 0; i < currentElement.children.length; i++) {
290
+ const numChildren = currentElement.children.length;
291
+ for (let i = 0; i < numChildren; i++) {
292
const childID = currentElement.children[i];
293
const child = ((this._idToElement.get(childID): any): Element);
293
- const { weight } = child;
294
- if (index <= currentWeight + weight) {
294
+ const childWeight = child.isCollapsed ? 1 : child.weight;
295
+
296
+ if (index <= currentWeight + childWeight) {
297
currentWeight++;
298
currentElement = child;
299
break;
300
} else {
299
- currentWeight += weight;
301
+ currentWeight += childWeight;
302
}
303
}
304
}
@@ -420,6 +422,28 @@ export default class Store extends EventEmitter {
422
this.emit('isProfiling');
423
}
424
425
+ toggleIsCollapsed(id: number, isCollapsed: boolean): void {
426
+ const element = this.getElementByID(id);
427
+ if (element !== null) {
428
+ element.isCollapsed = isCollapsed;
429
+
430
+ const weightDelta = isCollapsed ? 1 - element.weight : element.weight - 1;
431
+
432
+ this._numElements += weightDelta;
433
+
434
+ let parentElement = this._idToElement.get(element.parentID);
435
+ while (parentElement != null) {
436
+ parentElement.weight += weightDelta;
437
+ parentElement = this._idToElement.get(parentElement.parentID);
438
+ }
439
+
440
+ // The Tree context's search reducer expects an explicit list of ids for nodes that were added or removed.
441
+ // In this case, we can pass it empty arrays since nodes in a collapsed tree are still there (just hidden).
442
+ // Updating the selected search index later may require auto-expanding a collapsed subtree though.
443
+ this.emit('mutated', [[], []]);
444
+ }
445
+ }
446
+
447
_captureScreenshot = throttle(
448
memoize((commitIndex: number) => {
449
this._bridge.send('captureScreenshot', { commitIndex });
@@ -518,6 +542,7 @@ export default class Store extends EventEmitter {
542
depth: -1,
543
displayName: null,
544
id,
545
+ isCollapsed: false,
546
key: null,
547
ownerID: 0,
548
parentID: 0,
@@ -566,6 +591,7 @@ export default class Store extends EventEmitter {
591
depth: parentElement.depth + 1,
592
displayName,
593
id,
594
+ isCollapsed: false,
595
key,
596
ownerID,
597
parentID: parentElement.id,
@@ -715,14 +741,27 @@ export default class Store extends EventEmitter {
741
throw Error(`Unsupported Bridge operation ${operation}`);
742
}
743
718
- this._numElements += weightDelta;
744
+ let isInsideCollapsedSubTree = false;
745
746
while (parentElement != null) {
747
parentElement.weight += weightDelta;
748
+
749
+ // Additions and deletions within a collapsed subtree should not bubble beyond the collapsed parent.
750
+ // Their weight will bubble up when the parent is expanded.
751
+ if (parentElement.isCollapsed) {
752
+ isInsideCollapsedSubTree = true;
753
+ break;
754
+ }
755
+
756
parentElement = ((this._idToElement.get(
757
parentElement.parentID
758
): any): Element);
759
}
760
+
761
+ // Additions and deletions within a collapsed subtree should not affect the overall number of elements.
762
+ if (!isInsideCollapsedSubTree) {
763
+ this._numElements += weightDelta;
764
+ }
765
}
766
767
this._revision++;
src/devtools/views/Components/types.js
+3
@@ -14,6 +14,9 @@ export type Element = {|
14
displayName: string | null,
15
key: number | string | null,
16
17
+ // Should the elements children be visible in the tree?
18
+ isCollapsed: boolean,
19
+
20
// Owner (if available)
21
ownerID: number,
22