Fix keyboard focus loss when using JS profiler filter buttons
The focus, exclude, and reset buttons for filtering the functions in a
profile each become disabled once used, causing focus to be lost.
Fixed by focusing one of the remaining, enabled toolbar items. For most
cases this is the reset button. When the reset button itself is used
focus now goes to the combo box used to sort functions.
After changing focus data-keyboard-focus was still not being set. This
was due to focus changing in response to a click handler triggered by
the keyboard event, a scenario likely to exist in other tools as well.
Fixed by updating the helper utility for tracking keyboard focus to
account for keyup events in addition to keydown events. Since keyup
fires at the end of the keyboard interaction, it extends the scope of
events covered to include the triggered click event.
Before: https://imgur.com/a/yxyv0i4
After: https://imgur.com/a/cHpwVvs
Bug: 1054107
Change-Id: Ic3e323b06c534cabfbde00f147baa904db6ccefa
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2065068
Reviewed-by: John Emau <John.Emau@microsoft.com>
Reviewed-by: Jose Leal <joselea@microsoft.com>
Commit-Queue: Tony Ross <tross@microsoft.com>
diff --git a/front_end/profiler/ProfileView.js b/front_end/profiler/ProfileView.js
index 37ed9b3..8402c5e 100644
--- a/front_end/profiler/ProfileView.js
+++ b/front_end/profiler/ProfileView.js
@@ -411,6 +411,7 @@
}
this.resetButton.setEnabled(true);
+ this.resetButton.element.focus();
this.profileDataGridTree.focus(this.dataGrid.selectedNode);
this.refresh();
this.refreshVisibleData();
@@ -427,9 +428,11 @@
return;
}
+ this.resetButton.setEnabled(true);
+ this.resetButton.element.focus();
+
selectedNode.deselect();
- this.resetButton.setEnabled(true);
this.profileDataGridTree.exclude(selectedNode);
this.refresh();
this.refreshVisibleData();
@@ -440,6 +443,7 @@
* @param {!Common.EventTarget.EventTargetEvent} event
*/
_resetClicked(event) {
+ this.viewSelectComboBox.selectElement().focus();
this.resetButton.setEnabled(false);
this.profileDataGridTree.restore();
this._linkifier.reset();
diff --git a/front_end/ui/UIUtils.js b/front_end/ui/UIUtils.js
index 85ee473..9ff0622 100644
--- a/front_end/ui/UIUtils.js
+++ b/front_end/ui/UIUtils.js
@@ -1229,6 +1229,11 @@
LongClickController.TIME_MS = 200;
+function _trackKeyboardFocus() {
+ UI._keyboardFocus = true;
+ document.defaultView.requestAnimationFrame(() => void(UI._keyboardFocus = false));
+}
+
/**
* @param {!Document} document
* @param {!Common.Settings.Setting} themeSetting
@@ -1238,10 +1243,12 @@
document.defaultView.addEventListener('focus', _windowFocused.bind(UI, document), false);
document.defaultView.addEventListener('blur', _windowBlurred.bind(UI, document), false);
document.addEventListener('focus', focusChanged.bind(UI), true);
- document.addEventListener('keydown', event => {
- UI._keyboardFocus = true;
- document.defaultView.requestAnimationFrame(() => void(UI._keyboardFocus = false));
- }, true);
+
+ // Track which focus changes occur due to keyboard input.
+ // When focus changes from tab navigation (keydown).
+ // When focus() is called in keyboard initiated click events (keyup).
+ document.addEventListener('keydown', _trackKeyboardFocus, true);
+ document.addEventListener('keyup', _trackKeyboardFocus, true);
if (!self.UI.themeSupport) {
self.UI.themeSupport = new ThemeSupport(themeSetting);