+2019-01-11 Matt Baker <mattbaker@apple.com>
+
+ Web Inspector: REGRESSION: deleting an audit puts selection in a selected but invisible state
+ https://bugs.webkit.org/show_bug.cgi?id=192917
+ <rdar://problem/46875285>
+
+ Reviewed by Devin Rousso.
+
+ SelectionController should not be notified of removed children until the
+ child items have been removed from the TreeOutline. Doing so at this stage
+ is unsafe, since this method checks `this.selectedTreeElement`, which could
+ return the adjusted index from the SelectionController before anything has
+ actually been removed from the TreeOutline.
+
+ The number of calls to SelectionController.prototype.didRemoveItems is also
+ reduced somewhat, since we're no longer calling it for every TreeElement.
+
+ * UserInterface/Views/TreeOutline.js:
+ (WI.TreeOutline.prototype.removeChildAtIndex):
+ (WI.TreeOutline.prototype.removeChildren):
+ (WI.TreeOutline.prototype._forgetTreeElement):
+ (WI.TreeOutline.prototype._indexesForSubtree): Added.
+
2019-01-10 Devin Rousso <drousso@apple.com>
Web Inspector: Audit: allow audits to be enabled/disabled
treeOutline._forgetChildrenRecursive(child);
}
+ let removedIndexes = this._indexesForSubtree(child);
+
if (child.previousSibling)
child.previousSibling.nextSibling = child.nextSibling;
if (child.nextSibling)
child.nextSibling = null;
child.previousSibling = null;
- if (treeOutline)
+ if (treeOutline) {
+ treeOutline._selectionController.didRemoveItems(removedIndexes);
treeOutline.dispatchEventToListeners(WI.TreeOutline.Event.ElementRemoved, {element: child});
+ }
}
removeChild(child, suppressOnDeselect, suppressSelectSibling)
treeOutline._forgetChildrenRecursive(child);
}
+ let removedIndexes = treeOutline._indexesForSubtree(child);
+
child._detach();
child.treeOutline = null;
child.parent = null;
child.nextSibling = null;
child.previousSibling = null;
- if (treeOutline)
- treeOutline.dispatchEventToListeners(WI.TreeOutline.Event.ElementRemoved, {element: child});
-
this.children.shift();
+
+ if (treeOutline) {
+ treeOutline._selectionController.didRemoveItems(removedIndexes);
+ treeOutline.dispatchEventToListeners(WI.TreeOutline.Event.ElementRemoved, {element: child});
+ }
}
}
this.selectedTreeElement = null;
}
if (this._knownTreeElements[element.identifier]) {
- let index = this._indexOfTreeElement(element);
- if (index >= 0)
- this._selectionController.didRemoveItems(new WI.IndexSet([index]));
-
this._knownTreeElements[element.identifier].remove(element, true);
this._cachedNumberOfDescendents--;
}
this.dispatchEventToListeners(WI.TreeOutline.Event.SelectionDidChange, {selectedByUser});
}
+
+ _indexesForSubtree(treeElement)
+ {
+ let treeOutline = treeElement.treeOutline;
+ if (!treeOutline)
+ return new WI.IndexSet;
+
+ let firstChild = treeElement.children[0];
+ if (!firstChild)
+ return new WI.IndexSet;
+
+ let startIndex = treeOutline._indexOfTreeElement(firstChild);
+ let endIndex = startIndex;
+
+ const skipUnrevealed = false;
+ const stayWithin = treeElement;
+ const dontPopulate = true;
+
+ let current = firstChild;
+ while (current = current.traverseNextTreeElement(skipUnrevealed, stayWithin, dontPopulate))
+ endIndex++;
+
+ // Include the index of the subtree's root, unless it's the TreeOutline root.
+ if (!treeElement.root)
+ startIndex--;
+
+ let count = endIndex - startIndex + 1;
+
+ let indexes = new WI.IndexSet;
+ indexes.addRange(startIndex, count);
+
+ return indexes;
+ }
};
WI.TreeOutline._styleElement = null;