mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-10-13 01:54:52 +08:00
DevTools: navigate, expand Console objects via keyboard
With experiment enabled: - Use Arrow keys to expand ObjectPropertiesSections in Console Bug: 865674 Change-Id: Ia85969eb7b8f282e2403ab2a5d140821f2e977e6 Reviewed-on: https://chromium-review.googlesource.com/c/1239441 Commit-Queue: Erik Luo <luoe@chromium.org> Reviewed-by: Joel Einbinder <einbinder@chromium.org> Cr-Original-Commit-Position: refs/heads/master@{#597671} Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src Cr-Mirrored-Commit: c4c8bf57e8cae49003ca59ed29901feb91b0dc45
This commit is contained in:
@@ -45,6 +45,8 @@ Console.ConsoleViewMessage = class {
|
||||
this._repeatCount = 1;
|
||||
this._closeGroupDecorationCount = 0;
|
||||
this._nestingLevel = nestingLevel;
|
||||
/** @type {!Array<!ObjectUI.ObjectPropertiesSection>} */
|
||||
this._focusableChildren = [];
|
||||
|
||||
/** @type {?DataGrid.DataGrid} */
|
||||
this._dataGrid = null;
|
||||
@@ -608,6 +610,7 @@ Console.ConsoleViewMessage = class {
|
||||
const section = new ObjectUI.ObjectPropertiesSection(obj, titleElement, this._linkifier);
|
||||
section.element.classList.add('console-view-object-properties-section');
|
||||
section.enableContextMenu();
|
||||
this._focusableChildren.push(section);
|
||||
return section.element;
|
||||
}
|
||||
|
||||
@@ -1034,6 +1037,15 @@ Console.ConsoleViewMessage = class {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {number}
|
||||
*/
|
||||
_focusedChildIndex() {
|
||||
if (!this._focusableChildren.length)
|
||||
return -1;
|
||||
return this._focusableChildren.findIndex(child => child.element.hasFocus());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!Event} event
|
||||
*/
|
||||
@@ -1050,15 +1062,65 @@ Console.ConsoleViewMessage = class {
|
||||
*/
|
||||
maybeHandleOnKeyDown(event) {
|
||||
// Handle trace expansion.
|
||||
if (this._expandTrace) {
|
||||
const focusedChildIndex = this._focusedChildIndex();
|
||||
const isWrapperFocused = focusedChildIndex === -1;
|
||||
if (this._expandTrace && isWrapperFocused) {
|
||||
if ((event.key === 'ArrowLeft' && this._traceExpanded) || (event.key === 'ArrowRight' && !this._traceExpanded)) {
|
||||
this._expandTrace(!this._traceExpanded);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (!this._focusableChildren.length)
|
||||
return false;
|
||||
|
||||
if (event.key === 'ArrowLeft') {
|
||||
this._element.focus();
|
||||
return true;
|
||||
}
|
||||
if (event.key === 'ArrowRight') {
|
||||
if (isWrapperFocused) {
|
||||
this._focusChild(0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (event.key === 'ArrowUp') {
|
||||
if (focusedChildIndex === 0) {
|
||||
this._element.focus();
|
||||
return true;
|
||||
} else if (focusedChildIndex > 0) {
|
||||
this._focusChild(focusedChildIndex - 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (event.key === 'ArrowDown') {
|
||||
if (isWrapperFocused) {
|
||||
this._focusChild(0);
|
||||
return true;
|
||||
} else if (focusedChildIndex < this._focusableChildren.length - 1) {
|
||||
this._focusChild(focusedChildIndex + 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} index
|
||||
*/
|
||||
_focusChild(index) {
|
||||
const section = this._focusableChildren[index];
|
||||
if (!section.objectTreeElement().selected)
|
||||
section.objectTreeElement().select();
|
||||
section.focus();
|
||||
}
|
||||
|
||||
focusLastChildOrSelf() {
|
||||
if (this._focusableChildren.length)
|
||||
this._focusChild(this._focusableChildren.length - 1);
|
||||
else if (this._element)
|
||||
this._element.focus();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {!Element}
|
||||
*/
|
||||
@@ -1557,9 +1619,12 @@ Console.ConsoleGroupViewMessage = class extends Console.ConsoleViewMessage {
|
||||
* @param {!Event} event
|
||||
*/
|
||||
maybeHandleOnKeyDown(event) {
|
||||
if ((event.key === 'ArrowLeft' && !this._collapsed) || (event.key === 'ArrowRight' && this._collapsed)) {
|
||||
this._setCollapsed(!this._collapsed);
|
||||
return true;
|
||||
const focusedChildIndex = this._focusedChildIndex();
|
||||
if (focusedChildIndex === -1) {
|
||||
if ((event.key === 'ArrowLeft' && !this._collapsed) || (event.key === 'ArrowRight' && this._collapsed)) {
|
||||
this._setCollapsed(!this._collapsed);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return super.maybeHandleOnKeyDown(event);
|
||||
}
|
||||
|
||||
@@ -171,16 +171,21 @@ Console.ConsoleViewport = class {
|
||||
_onKeyDown(event) {
|
||||
if (UI.isEditing() || !this._itemCount || event.shiftKey)
|
||||
return;
|
||||
let isArrowUp = false;
|
||||
switch (event.key) {
|
||||
case 'ArrowUp':
|
||||
this._virtualSelectedIndex--;
|
||||
if (this._virtualSelectedIndex < 0)
|
||||
this._virtualSelectedIndex = this._itemCount - 1;
|
||||
if (this._virtualSelectedIndex > 0) {
|
||||
isArrowUp = true;
|
||||
this._virtualSelectedIndex--;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 'ArrowDown':
|
||||
this._virtualSelectedIndex++;
|
||||
if (this._virtualSelectedIndex >= this._itemCount)
|
||||
this._virtualSelectedIndex = 0;
|
||||
if (this._virtualSelectedIndex < this._itemCount - 1)
|
||||
this._virtualSelectedIndex++;
|
||||
else
|
||||
return;
|
||||
break;
|
||||
case 'Home':
|
||||
this._virtualSelectedIndex = 0;
|
||||
@@ -193,20 +198,27 @@ Console.ConsoleViewport = class {
|
||||
}
|
||||
event.consume(true);
|
||||
this.scrollItemIntoView(this._virtualSelectedIndex);
|
||||
this._updateFocusedItem();
|
||||
this._updateFocusedItem(isArrowUp);
|
||||
}
|
||||
|
||||
_updateFocusedItem() {
|
||||
/**
|
||||
* @param {boolean=} focusLastChild
|
||||
*/
|
||||
_updateFocusedItem(focusLastChild) {
|
||||
const selectedElement = this.renderedElementAt(this._virtualSelectedIndex);
|
||||
const changed = this._lastSelectedElement !== selectedElement;
|
||||
const containerHasFocus = this._contentElement === this.element.ownerDocument.deepActiveElement();
|
||||
if (this._lastSelectedElement && changed)
|
||||
this._lastSelectedElement.classList.remove('console-selected');
|
||||
if (selectedElement && (changed || containerHasFocus)) {
|
||||
if (selectedElement && (changed || containerHasFocus) && this.element.hasFocus()) {
|
||||
selectedElement.classList.add('console-selected');
|
||||
// Do not focus the message if something within holds focus (e.g. object).
|
||||
if (!selectedElement.hasFocus())
|
||||
focusWithoutScroll(selectedElement);
|
||||
if (!selectedElement.hasFocus()) {
|
||||
if (focusLastChild)
|
||||
this._renderedItems[this._virtualSelectedIndex - this._firstActiveIndex].focusLastChildOrSelf();
|
||||
else
|
||||
focusWithoutScroll(selectedElement);
|
||||
}
|
||||
}
|
||||
if (this._itemCount && !this._contentElement.hasFocus())
|
||||
this._contentElement.tabIndex = 0;
|
||||
|
||||
@@ -441,6 +441,13 @@ ConsoleTestRunner.waitForRemoteObjectsConsoleMessages = function(callback) {
|
||||
TestRunner.deprecatedRunAfterPendingDispatches(callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {!Promise}
|
||||
*/
|
||||
ConsoleTestRunner.waitForRemoteObjectsConsoleMessagesPromise = function() {
|
||||
return new Promise(resolve => ConsoleTestRunner.waitForRemoteObjectsConsoleMessages(resolve));
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {!Promise}
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user