WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
Bug 191977
Web Inspector: Table selection should be handled by a SelectionController
https://bugs.webkit.org/show_bug.cgi?id=191977
Summary
Web Inspector: Table selection should be handled by a SelectionController
Matt Baker
Reported
2018-11-26 12:36:58 PST
Summary: Table selection should be handled by a SelectionController. This is a step toward adding multiple-selection to TreeOutline in
https://webkit.org/b/191483
. Notes: The controller and its delegate (a Table or TreeOutline): class SelectionController { constructor(delegate) get allowsMultipleSelection() set allowsMultipleSelection(flag) get lastSelectedItem() get selectedItems() get numberOfItems() hasSelectedItem(index) selectItem(index, extendSelection = false) deselectItem(index) selectAll() deselectAll() removeSelectedItems() clear() didInsertItem(index); didRemoveItem(index); handleKeyDown(event) handleItemMouseDown(index, event) } class SelectionControllerDelegate { // Required selectionControllerNumberOfItems(controller) selectionControllerNextSelectableIndex(controller, index) selectionControllerPreviousSelectableIndex(controller, index) // Optional selectionControllerSelectionDidChange(controller, deselectedItems, selectedItems) }
Attachments
Patch
(34.17 KB, patch)
2018-11-26 13:00 PST
,
Matt Baker
no flags
Details
Formatted Diff
Diff
Archive of layout-test-results from ews102 for mac-sierra
(2.51 MB, application/zip)
2018-11-26 14:02 PST
,
EWS Watchlist
no flags
Details
Archive of layout-test-results from ews105 for mac-sierra-wk2
(3.49 MB, application/zip)
2018-11-26 14:14 PST
,
EWS Watchlist
no flags
Details
Archive of layout-test-results from ews115 for mac-sierra
(2.21 MB, application/zip)
2018-11-26 14:55 PST
,
EWS Watchlist
no flags
Details
Patch
(36.96 KB, patch)
2018-11-27 08:40 PST
,
Matt Baker
no flags
Details
Formatted Diff
Diff
Patch
(36.99 KB, patch)
2018-11-27 10:31 PST
,
Matt Baker
no flags
Details
Formatted Diff
Diff
Show Obsolete
(2)
View All
Add attachment
proposed patch, testcase, etc.
Radar WebKit Bug Importer
Comment 1
2018-11-26 12:37:29 PST
<
rdar://problem/46253093
>
Matt Baker
Comment 2
2018-11-26 13:00:55 PST
Created
attachment 355667
[details]
Patch
EWS Watchlist
Comment 3
2018-11-26 14:02:06 PST
Comment on
attachment 355667
[details]
Patch
Attachment 355667
[details]
did not pass mac-ews (mac): Output:
https://webkit-queues.webkit.org/results/10157964
New failing tests: inspector/table/table-remove-rows.html
EWS Watchlist
Comment 4
2018-11-26 14:02:08 PST
Created
attachment 355673
[details]
Archive of layout-test-results from ews102 for mac-sierra The attached test failures were seen while running run-webkit-tests on the mac-ews. Bot: ews102 Port: mac-sierra Platform: Mac OS X 10.12.6
EWS Watchlist
Comment 5
2018-11-26 14:14:04 PST
Comment on
attachment 355667
[details]
Patch
Attachment 355667
[details]
did not pass mac-wk2-ews (mac-wk2): Output:
https://webkit-queues.webkit.org/results/10157983
New failing tests: inspector/table/table-remove-rows.html
EWS Watchlist
Comment 6
2018-11-26 14:14:05 PST
Created
attachment 355674
[details]
Archive of layout-test-results from ews105 for mac-sierra-wk2 The attached test failures were seen while running run-webkit-tests on the mac-wk2-ews. Bot: ews105 Port: mac-sierra-wk2 Platform: Mac OS X 10.12.6
EWS Watchlist
Comment 7
2018-11-26 14:55:46 PST
Comment on
attachment 355667
[details]
Patch
Attachment 355667
[details]
did not pass mac-debug-ews (mac): Output:
https://webkit-queues.webkit.org/results/10158190
New failing tests: inspector/table/table-remove-rows.html
EWS Watchlist
Comment 8
2018-11-26 14:55:47 PST
Created
attachment 355678
[details]
Archive of layout-test-results from ews115 for mac-sierra The attached test failures were seen while running run-webkit-tests on the mac-debug-ews. Bot: ews115 Port: mac-sierra Platform: Mac OS X 10.12.6
Matt Baker
Comment 9
2018-11-26 15:12:15 PST
Comment on
attachment 355667
[details]
Patch r-. Need to fix Table.prototype._removeRows.
Devin Rousso
Comment 10
2018-11-26 15:21:28 PST
Comment on
attachment 355667
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=355667&action=review
r-, due to test failures (as discussed offline), and the lack of handling item addition/removal (e.g. `didInsertItem` and `didRemoveItem`) Otherwise, looks good! Was there a reason you decided on going forward with an index-based approach vs an object-based approach, like we discussed before Thanksgiving? I think the object-based approach will be much more flexible for `WI.TreeOutline` and would likely require far less work to implement vs an index-based approach.
> Source/WebInspectorUI/UserInterface/Controllers/SelectionController.js:33 > + this._delegate = delegate;
NIT: would this really be considered a delegate? Perhaps "view" or something else like that to better explain that this is the "controlled object"?
> Source/WebInspectorUI/UserInterface/Controllers/SelectionController.js:42 > + console.assert(this._delegate.selectionControllerNextSelectableIndex, "SelectionController delegate must implement selectionControllerNextSelectableIndex.");
`selectionControllerPreviousSelectableIndex`?
> Source/WebInspectorUI/UserInterface/Controllers/SelectionController.js:70 > + get lastSelectedItem() { return this._lastSelectedIndex; } > + get selectedItems() { return this._selectedIndexes; }
Style: put all one-line getters at the top of the Public section
> Source/WebInspectorUI/UserInterface/Controllers/SelectionController.js:149 > + this._lastSelectedIndex = newSelectedItems.lastIndex;
Should we also treat the last index as the anchor for shift-selection? This seems to be how Finder does it.
> Source/WebInspectorUI/UserInterface/Controllers/SelectionController.js:187 > + clear()
NIT: I'd prefer `reset`, as `clear` is too similar to "clear selection or "deselect all" in my mind
> Source/WebInspectorUI/UserInterface/Controllers/SelectionController.js:197 > + return false;
Is there a reason this function needs to return a boolean?
> Source/WebInspectorUI/UserInterface/Controllers/SelectionController.js:223 > + if (event.commandOrControlKey) {
Nice!
> Source/WebInspectorUI/UserInterface/Controllers/SelectionController.js:359 > + let deselectedItems = oldSelectedIndexes.difference(indexes); > + let selectedItems = indexes.difference(oldSelectedIndexes); > + this._delegate.selectionControllerSelectionDidChange(this, deselectedItems, selectedItems);
I like this new approach!
> Source/WebInspectorUI/UserInterface/Views/Table.js:347 > + if (!oldSelectedItems.equals(this._selectionController.selectedItems))
Why is this check needed?
> Source/WebInspectorUI/UserInterface/Views/Table.js:594 > + if (index === this.numberOfRows - 1)
NIT: for sanity's sake, we should either add an assert or change this to be a `>=`
> Source/WebInspectorUI/UserInterface/Views/Table.js:601 > + if (index === 0)
NIT: for sanity's sake, we should either add an assert or change this to be a `<=`
> Source/WebInspectorUI/UserInterface/Views/Table.js:1244 > + this._selectionController.handleKeyDown(event);
This won't call `revealRow` when moving Up/Down. I think that's an issue if we try to go Up/Down without a previous selection, as the item to select may be outside what's been cached. Perhaps there should be a `selectionControllerRevealIndex` delegate call?
Matt Baker
Comment 11
2018-11-27 08:38:15 PST
Comment on
attachment 355667
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=355667&action=review
>> Source/WebInspectorUI/UserInterface/Controllers/SelectionController.js:33 >> + this._delegate = delegate; > > NIT: would this really be considered a delegate? Perhaps "view" or something else like that to better explain that this is the "controlled object"?
In practice it's a view, but delegate is very general which I like here.
>> Source/WebInspectorUI/UserInterface/Controllers/SelectionController.js:70 >> + get selectedItems() { return this._selectedIndexes; } > > Style: put all one-line getters at the top of the Public section
I'll change it here, but in general I don't think this should be a hard and fast rule. Sometimes it makes sense to group properties semantically.
>> Source/WebInspectorUI/UserInterface/Controllers/SelectionController.js:149 >> + this._lastSelectedIndex = newSelectedItems.lastIndex; > > Should we also treat the last index as the anchor for shift-selection? This seems to be how Finder does it.
Nice observation. In fact, it looks like Finder only does this in the absence of an existing shift-selection anchor; I'll match that behavior.
>> Source/WebInspectorUI/UserInterface/Controllers/SelectionController.js:187 >> + clear() > > NIT: I'd prefer `reset`, as `clear` is too similar to "clear selection or "deselect all" in my mind
`reset` is better.
>> Source/WebInspectorUI/UserInterface/Controllers/SelectionController.js:197 >> + return false; > > Is there a reason this function needs to return a boolean?
There is. TreeOutline will use the return value. I should have added the return value in that patch, but let's just keep this.
>> Source/WebInspectorUI/UserInterface/Views/Table.js:1244 >> + this._selectionController.handleKeyDown(event); > > This won't call `revealRow` when moving Up/Down. I think that's an issue if we try to go Up/Down without a previous selection, as the item to select may be outside what's been cached. > > Perhaps there should be a `selectionControllerRevealIndex` delegate call?
Great catch. We can resolve this in Table, without extending the delegate: selectionControllerSelectionDidChange(controller, deselectedItems, selectedItems) { if (deselectedItems.size) this._toggleSelectedRowStyle(deselectedItems, false); if (selectedItems.size) this._toggleSelectedRowStyle(selectedItems, true); + if (selectedItems.size === 1) { + let rowIndex = selectedItems.firstIndex; + if (!this._isRowVisible(rowIndex)) + this.revealRow(rowIndex); + } if (this._delegate.tableSelectionDidChange) this._delegate.tableSelectionDidChange(this); }
Matt Baker
Comment 12
2018-11-27 08:40:46 PST
Created
attachment 355735
[details]
Patch
Matt Baker
Comment 13
2018-11-27 08:47:34 PST
(In reply to Devin Rousso from
comment #10
)
> Comment on
attachment 355667
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=355667&action=review
> > r-, due to test failures (as discussed offline), and the lack of handling > item addition/removal (e.g. `didInsertItem` and `didRemoveItem`) > > Otherwise, looks good! Was there a reason you decided on going forward with > an index-based approach vs an object-based approach, like we discussed > before Thanksgiving? I think the object-based approach will be much more > flexible for `WI.TreeOutline` and would likely require far less work to > implement vs an index-based approach.
An object-based approach has the advantage of being slightly simpler, in that `didRemoveItem` and `didInsertItem` aren't needed to keep SelectionController's stored indexes in synch with the view. This has the consequence that the selected items are no longer in order, however, which is an issue for copying rows from Table. The index-based approach was also complete, and I didn't want to rock the boat at the 11th hour. ;)
Devin Rousso
Comment 14
2018-11-27 09:08:38 PST
(In reply to Matt Baker from
comment #13
)
> The index-based approach was also complete, and I didn't want to rock the boat at the 11th hour. ;)
No worries! Was just wondering :) I think an object-based approach will be more flexible, but in the spirit of getting things done, this works just as well =D
Devin Rousso
Comment 15
2018-11-27 09:29:27 PST
Comment on
attachment 355735
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=355735&action=review
> Source/WebInspectorUI/UserInterface/Controllers/SelectionController.js:42 > + console.assert(this._delegate.selectionControllerNextSelectableIndex, "SelectionController delegate must implement selectionControllerNextSelectableIndex.");
`selectionControllerPreviousSelectableIndex`?
> Source/WebInspectorUI/UserInterface/Controllers/SelectionController.js:195 > + didRemoveItem(index)
What happened to `didInsertItem`? Don't we need to do effectively the same logic but instead add one to each index?
> Source/WebInspectorUI/UserInterface/Controllers/SelectionController.js:200 > + while (index = this._selectedIndexes.indexGreaterThan(index)) {
So this is relying on the falsey nature of `NaN` to return when there is no greater index?
> Source/WebInspectorUI/UserInterface/Controllers/SelectionController.js:225 > + }
There should be a default return value after this.
Matt Baker
Comment 16
2018-11-27 10:31:19 PST
Created
attachment 355747
[details]
Patch
Matt Baker
Comment 17
2018-11-27 10:33:15 PST
Comment on
attachment 355735
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=355735&action=review
>> Source/WebInspectorUI/UserInterface/Controllers/SelectionController.js:195 >> + didRemoveItem(index) > > What happened to `didInsertItem`? Don't we need to do effectively the same logic but instead add one to each index?
Individual items aren't inserted into Table, only removed. TreeOutline inserts individual items, so it will be added in
https://webkit.org/b/191483
.
>> Source/WebInspectorUI/UserInterface/Controllers/SelectionController.js:200 >> + while (index = this._selectedIndexes.indexGreaterThan(index)) { > > So this is relying on the falsey nature of `NaN` to return when there is no greater index?
Yep.
Devin Rousso
Comment 18
2018-11-27 10:59:36 PST
Comment on
attachment 355747
[details]
Patch r=me, nice work :)
WebKit Commit Bot
Comment 19
2018-11-27 11:41:24 PST
Comment on
attachment 355747
[details]
Patch Clearing flags on attachment: 355747 Committed
r238563
: <
https://trac.webkit.org/changeset/238563
>
WebKit Commit Bot
Comment 20
2018-11-27 11:41:26 PST
All reviewed patches have been landed. Closing bug.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug