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:
Erik Luo
2018-10-08 20:37:46 +00:00
committed by Commit Bot
parent 76fe06cff6
commit 0b8282e795
3 changed files with 99 additions and 15 deletions
+69 -4
View File
@@ -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);
}
+23 -11
View File
@@ -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}
*/