- Revision
- 238602
- Author
- [email protected]
- Date
- 2018-11-27 22:49:34 -0800 (Tue, 27 Nov 2018)
Log Message
Web Inspector: Elements tab should allow selecting/deleting multiple DOM nodes
https://bugs.webkit.org/show_bug.cgi?id=192059
<rdar://problem/46294827>
Reviewed by Devin Rousso.
Enable multiple DOM node selection in the DOMTreeContentView.
* UserInterface/Controllers/SelectionController.js:
(WI.SelectionController):
(WI.SelectionController.prototype.get allowsEmptySelection):
(WI.SelectionController.prototype.set allowsEmptySelection):
Allow clients to control whether the last selected item can be deselected.
(WI.SelectionController.prototype.deselectItem):
(WI.SelectionController.prototype.didInsertItem):
Rewritten to prevent infinite loop.
(WI.SelectionController.prototype.didRemoveItem):
(WI.SelectionController.prototype._updateSelectedItems):
(WI.SelectionController.prototype._adjustIndexesAfter): Deleted.
* UserInterface/Views/DOMTreeContentView.js:
(WI.DOMTreeContentView):
* UserInterface/Views/DOMTreeElement.js:
(WI.DOMTreeElement.prototype.updateSelectionArea):
* UserInterface/Views/DOMTreeOutline.js:
(WI.DOMTreeOutline.prototype.updateSelection):
Updating the selection area DOM element should not assume that only one
TreeElement is selected at a time.
* UserInterface/Views/TreeOutline.js:
(WI.TreeOutline.prototype.get allowsEmptySelection):
(WI.TreeOutline.prototype.set allowsEmptySelection):
(WI.TreeOutline.prototype.set selectedTreeElement):
(WI.TreeOutline.prototype.get selectedTreeElements):
(WI.TreeOutline.prototype._treeKeyDown):
* UserInterface/Views/TreeOutlineGroup.js:
(WI.TreeOutlineGroup):
(WI.TreeOutlineGroup.prototype._removeConflictingTreeSelections):
Eliminate use of `TreeElement.prototype.deselect`.
Modified Paths
Diff
Modified: trunk/Source/WebInspectorUI/ChangeLog (238601 => 238602)
--- trunk/Source/WebInspectorUI/ChangeLog 2018-11-28 04:48:30 UTC (rev 238601)
+++ trunk/Source/WebInspectorUI/ChangeLog 2018-11-28 06:49:34 UTC (rev 238602)
@@ -1,5 +1,49 @@
2018-11-27 Matt Baker <[email protected]>
+ Web Inspector: Elements tab should allow selecting/deleting multiple DOM nodes
+ https://bugs.webkit.org/show_bug.cgi?id=192059
+ <rdar://problem/46294827>
+
+ Reviewed by Devin Rousso.
+
+ Enable multiple DOM node selection in the DOMTreeContentView.
+
+ * UserInterface/Controllers/SelectionController.js:
+ (WI.SelectionController):
+ (WI.SelectionController.prototype.get allowsEmptySelection):
+ (WI.SelectionController.prototype.set allowsEmptySelection):
+ Allow clients to control whether the last selected item can be deselected.
+ (WI.SelectionController.prototype.deselectItem):
+ (WI.SelectionController.prototype.didInsertItem):
+ Rewritten to prevent infinite loop.
+ (WI.SelectionController.prototype.didRemoveItem):
+ (WI.SelectionController.prototype._updateSelectedItems):
+ (WI.SelectionController.prototype._adjustIndexesAfter): Deleted.
+
+ * UserInterface/Views/DOMTreeContentView.js:
+ (WI.DOMTreeContentView):
+
+ * UserInterface/Views/DOMTreeElement.js:
+ (WI.DOMTreeElement.prototype.updateSelectionArea):
+ * UserInterface/Views/DOMTreeOutline.js:
+ (WI.DOMTreeOutline.prototype.updateSelection):
+ Updating the selection area DOM element should not assume that only one
+ TreeElement is selected at a time.
+
+ * UserInterface/Views/TreeOutline.js:
+ (WI.TreeOutline.prototype.get allowsEmptySelection):
+ (WI.TreeOutline.prototype.set allowsEmptySelection):
+ (WI.TreeOutline.prototype.set selectedTreeElement):
+ (WI.TreeOutline.prototype.get selectedTreeElements):
+ (WI.TreeOutline.prototype._treeKeyDown):
+
+ * UserInterface/Views/TreeOutlineGroup.js:
+ (WI.TreeOutlineGroup):
+ (WI.TreeOutlineGroup.prototype._removeConflictingTreeSelections):
+ Eliminate use of `TreeElement.prototype.deselect`.
+
+2018-11-27 Matt Baker <[email protected]>
+
Web Inspector: TreeOutline should re-use multiple-selection logic from Table
https://bugs.webkit.org/show_bug.cgi?id=191483
<rdar://problem/45953305>
Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/SelectionController.js (238601 => 238602)
--- trunk/Source/WebInspectorUI/UserInterface/Controllers/SelectionController.js 2018-11-28 04:48:30 UTC (rev 238601)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/SelectionController.js 2018-11-28 06:49:34 UTC (rev 238602)
@@ -32,6 +32,7 @@
console.assert(delegate);
this._delegate = delegate;
+ this._allowsEmptySelection = true;
this._allowsMultipleSelection = false;
this._lastSelectedIndex = NaN;
this._shiftAnchorIndex = NaN;
@@ -48,6 +49,9 @@
get lastSelectedItem() { return this._lastSelectedIndex; }
get selectedItems() { return this._selectedIndexes; }
+ get allowsEmptySelection() { return this._allowsEmptySelection; }
+ set allowsEmptySelection(flag) { this._allowsEmptySelection = flag; }
+
get allowsMultipleSelection()
{
return this._allowsMultipleSelection;
@@ -105,6 +109,9 @@
if (!this.hasSelectedItem(index))
return;
+ if (!this._allowsEmptySelection && this._selectedIndexes.size === 1)
+ return;
+
let newSelectedItems = this._selectedIndexes.copy();
newSelectedItems.delete(index);
@@ -194,7 +201,13 @@
didInsertItem(index)
{
- this._adjustIndexesAfter(index - 1, 1);
+ let current = this._selectedIndexes.lastIndex;
+ while (current >= index) {
+ this._selectedIndexes.delete(index);
+ this._selectedIndexes.add(index + 1);
+
+ current = this._selectedIndexes.indexLessThan(current);
+ }
}
didRemoveItem(index)
@@ -202,7 +215,10 @@
if (this.hasSelectedItem(index))
this.deselectItem(index);
- this._adjustIndexesAfter(index, -1);
+ while (index = this._selectedIndexes.indexGreaterThan(index)) {
+ this._selectedIndexes.delete(index);
+ this._selectedIndexes.add(index - 1);
+ }
}
handleKeyDown(event)
@@ -374,12 +390,4 @@
let selectedItems = indexes.difference(oldSelectedIndexes);
this._delegate.selectionControllerSelectionDidChange(this, deselectedItems, selectedItems);
}
-
- _adjustIndexesAfter(index, delta)
- {
- while (index = this._selectedIndexes.indexGreaterThan(index)) {
- this._selectedIndexes.delete(index);
- this._selectedIndexes.add(index + delta);
- }
- }
};
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/DOMTreeContentView.js (238601 => 238602)
--- trunk/Source/WebInspectorUI/UserInterface/Views/DOMTreeContentView.js 2018-11-28 04:48:30 UTC (rev 238601)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/DOMTreeContentView.js 2018-11-28 06:49:34 UTC (rev 238602)
@@ -64,6 +64,8 @@
this.element.addEventListener("click", this._mouseWasClicked.bind(this), false);
this._domTreeOutline = new WI.DOMTreeOutline(true, true, true);
+ this._domTreeOutline.allowsEmptySelection = false;
+ this._domTreeOutline.allowsMultipleSelection = true;
this._domTreeOutline.addEventListener(WI.TreeOutline.Event.ElementAdded, this._domTreeElementAdded, this);
this._domTreeOutline.addEventListener(WI.DOMTreeOutline.Event.SelectedNodeChanged, this._selectedNodeDidChange, this);
this._domTreeOutline.wireToDomAgent();
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/DOMTreeElement.js (238601 => 238602)
--- trunk/Source/WebInspectorUI/UserInterface/Views/DOMTreeElement.js 2018-11-28 04:48:30 UTC (rev 238601)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/DOMTreeElement.js 2018-11-28 06:49:34 UTC (rev 238602)
@@ -367,7 +367,7 @@
return;
// If there's no reason to have a selection area, remove the DOM element.
- let indicatesTreeOutlineState = this.treeOutline && (this.treeOutline.dragOverTreeElement === this || this.treeOutline.selectedTreeElement === this || this._animatingHighlight);
+ let indicatesTreeOutlineState = this.treeOutline && (this.treeOutline.dragOverTreeElement === this || this.selected || this._animatingHighlight);
if (!this.hovered && !this.pseudoClassesEnabled && !indicatesTreeOutlineState) {
if (this._selectionElement) {
this._selectionElement.remove();
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/DOMTreeOutline.js (238601 => 238602)
--- trunk/Source/WebInspectorUI/UserInterface/Views/DOMTreeOutline.js 2018-11-28 04:48:30 UTC (rev 238601)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/DOMTreeOutline.js 2018-11-28 06:49:34 UTC (rev 238602)
@@ -191,8 +191,9 @@
// and those used to show forced pseudo class indicators, but this should be okay.
// The hovered element will update when user moves the mouse, and indicators don't need the
// selection area height to be accurate since they use ::before to place the indicator.
- if (this.selectedTreeElement)
- this.selectedTreeElement.updateSelectionArea();
+ let selectedTreeElements = this.selectedTreeElements;
+ for (let treeElement of selectedTreeElements)
+ treeElement.updateSelectionArea();
}
_selectedNodeChanged()
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TreeOutline.js (238601 => 238602)
--- trunk/Source/WebInspectorUI/UserInterface/Views/TreeOutline.js 2018-11-28 04:48:30 UTC (rev 238601)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TreeOutline.js 2018-11-28 06:49:34 UTC (rev 238602)
@@ -81,6 +81,16 @@
// Public
+ get allowsEmptySelection()
+ {
+ return this._selectionController.allowsEmptySelection;
+ }
+
+ set allowsEmptySelection(flag)
+ {
+ this._selectionController.allowsEmptySelection = flag;
+ }
+
get allowsMultipleSelection()
{
return this._selectionController.allowsMultipleSelection;
@@ -99,10 +109,29 @@
set selectedTreeElement(treeElement)
{
- let index = this._indexOfTreeElement(treeElement);
- this._selectionController.selectItem(index);
+ if (treeElement) {
+ let index = this._indexOfTreeElement(treeElement);
+ this._selectionController.selectItem(index);
+ } else
+ this._selectionController.deselectAll();
}
+ get selectedTreeElements()
+ {
+ if (this.allowsMultipleSelection) {
+ let treeElements = [];
+ for (let index of this._selectionController.selectedItems)
+ treeElements.push(this._treeElementAtIndex(index));
+ return treeElements;
+ }
+
+ let selectedTreeElement = this.selectedTreeElement;
+ if (selectedTreeElement)
+ return [selectedTreeElement];
+
+ return [];
+ }
+
get hidden()
{
return this._hidden;
@@ -607,8 +636,10 @@
}
}
} else if (event.keyCode === 8 /* Backspace */ || event.keyCode === 46 /* Delete */) {
- if (this.selectedTreeElement.ondelete)
- handled = this.selectedTreeElement.ondelete();
+ for (let treeElement of this.selectedTreeElements) {
+ if (treeElement.ondelete && treeElement.ondelete())
+ handled = true;
+ }
if (!handled && this.treeOutline.ondelete)
handled = this.treeOutline.ondelete(this.selectedTreeElement);
} else if (isEnterKey(event)) {
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TreeOutlineGroup.js (238601 => 238602)
--- trunk/Source/WebInspectorUI/UserInterface/Views/TreeOutlineGroup.js 2018-11-28 04:48:30 UTC (rev 238601)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TreeOutlineGroup.js 2018-11-28 06:49:34 UTC (rev 238602)
@@ -87,8 +87,7 @@
if (selectedTreeOutline === treeOutline)
continue;
- if (treeOutline.selectedTreeElement)
- treeOutline.selectedTreeElement.deselect();
+ treeOutline.selectedTreeElement = null;
}
}
};