mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-10-19 13:04:39 +08:00
Enable keyboard navigation of threads pane
This CL makes the threads pane navigable by keyboard. Based on feedback received in [1], I am managing selection within ThreadsSidebarPane and using ListControl's selection to manage focus. Separating the ListControl selection from the currently active thread neccessitated a change to a method in DebuggerTestRunner that changes threads in order to avoid breaking tests. Previously +1'd in the old repo at https://chromium-review.googlesource.com/c/chromium/src/+/1707832 Video of navigation: https://i.imgur.com/A4eWj2u.mp4 [1] https://chromium-review.googlesource.com/c/chromium/src/+/1690089/17#message-3e9e158cce4628b01398d9cf84e37550b55b14c6 Bug: 963183 Change-Id: Ib14f1e4e567f0a70976b587528de8f83c15f0d4a Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/1888991 Commit-Queue: Jack Lynch <jalyn@microsoft.com> Reviewed-by: Lorne Mitchell <lomitch@microsoft.com>
This commit is contained in:
@@ -14,6 +14,8 @@ Sources.ThreadsSidebarPane = class extends UI.VBox {
|
||||
this._items = new UI.ListModel();
|
||||
/** @type {!UI.ListControl<!SDK.DebuggerModel>} */
|
||||
this._list = new UI.ListControl(this._items, this, UI.ListMode.NonViewport);
|
||||
const currentTarget = UI.context.flavor(SDK.Target);
|
||||
this._selectedModel = !!currentTarget ? currentTarget.model(SDK.DebuggerModel) : null;
|
||||
this.contentElement.appendChild(this._list.element);
|
||||
|
||||
UI.context.addFlavorChangeListener(SDK.Target, this._targetFlavorChanged, this);
|
||||
@@ -37,6 +39,14 @@ Sources.ThreadsSidebarPane = class extends UI.VBox {
|
||||
const title = element.createChild('div', 'thread-item-title');
|
||||
const pausedState = element.createChild('div', 'thread-item-paused-state');
|
||||
element.appendChild(UI.Icon.create('smallicon-thick-right-arrow', 'selected-thread-icon'));
|
||||
element.tabIndex = -1;
|
||||
self.onInvokeElement(element, event => {
|
||||
UI.context.setFlavor(SDK.Target, debuggerModel.target());
|
||||
event.consume(true);
|
||||
});
|
||||
const isSelected = UI.context.flavor(SDK.Target) === debuggerModel.target();
|
||||
element.classList.toggle('selected', isSelected);
|
||||
UI.ARIAUtils.setSelected(element, isSelected);
|
||||
|
||||
function updateTitle() {
|
||||
const executionContext = debuggerModel.runtimeModel().defaultExecutionContext();
|
||||
@@ -96,13 +106,14 @@ Sources.ThreadsSidebarPane = class extends UI.VBox {
|
||||
*/
|
||||
selectedItemChanged(from, to, fromElement, toElement) {
|
||||
if (fromElement) {
|
||||
fromElement.classList.remove('selected');
|
||||
fromElement.tabIndex = -1;
|
||||
}
|
||||
if (toElement) {
|
||||
toElement.classList.add('selected');
|
||||
}
|
||||
if (to) {
|
||||
UI.context.setFlavor(SDK.Target, to.target());
|
||||
this.setDefaultFocusedElement(toElement);
|
||||
toElement.tabIndex = 0;
|
||||
if (this.hasFocus()) {
|
||||
toElement.focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,10 +151,18 @@ Sources.ThreadsSidebarPane = class extends UI.VBox {
|
||||
* @param {!Common.Event} event
|
||||
*/
|
||||
_targetFlavorChanged(event) {
|
||||
const hadFocus = this.hasFocus();
|
||||
const target = /** @type {!SDK.Target} */ (event.data);
|
||||
const debuggerModel = target.model(SDK.DebuggerModel);
|
||||
if (debuggerModel) {
|
||||
this._list.selectItem(debuggerModel);
|
||||
this._list.refreshItem(debuggerModel);
|
||||
}
|
||||
if (!!this._selectedModel) {
|
||||
this._list.refreshItem(this._selectedModel);
|
||||
}
|
||||
this._selectedModel = debuggerModel;
|
||||
if (hadFocus) {
|
||||
this.focus();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -21,6 +21,10 @@
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
.thread-item[data-keyboard-focus="true"] {
|
||||
background-color: var(--focus-bg-color);
|
||||
}
|
||||
|
||||
.thread-item-title,
|
||||
.thread-item-paused-state {
|
||||
text-overflow: ellipsis;
|
||||
@@ -44,4 +48,3 @@
|
||||
.thread-item.selected .selected-thread-icon {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
@@ -718,8 +718,7 @@ SourcesTestRunner.waitForExecutionContextInTarget = function(target, callback) {
|
||||
};
|
||||
|
||||
SourcesTestRunner.selectThread = function(target) {
|
||||
const threadsPane = self.runtime.sharedInstance(Sources.ThreadsSidebarPane);
|
||||
threadsPane._list.selectItem(target.model(SDK.DebuggerModel));
|
||||
UI.context.setFlavor(SDK.Target, target);
|
||||
};
|
||||
|
||||
SourcesTestRunner.evaluateOnCurrentCallFrame = function(code) {
|
||||
|
||||
Reference in New Issue
Block a user