Commit 5faf3158 authored by rbpotter's avatar rbpotter Committed by Commit Bot

Settings and History: Fix focus issues

The 3 linked bugs are all due to an issue with refocusing a list item
from an element after the last control. In this case, the last control
should be refocused, not the first control.

This case can be identified by the first element in the focus event's
path. This will be the list item itself if focus is coming from outside
the control from an element that is before the list item in the tab
order. It will be the last control if focus is coming from an element
that is after the list item in the tab order.

Bug: 908330, 908323, 908014
Change-Id: Ie2289547470e2f66cd9285d29e9ed1e0ab3207c1
Reviewed-on: https://chromium-review.googlesource.com/c/1351713
Commit-Queue: Rebekah Potter <rbpotter@chromium.org>
Reviewed-by: default avatarScott Chen <scottchen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#611536}
parent 4dcf6114
......@@ -160,16 +160,26 @@ cr.define('md_history', function() {
},
/**
* @param {!Event} e The focus event
* @private
*/
onFocus_: function() {
onFocus_: function(e) {
// Don't change the focus while the mouse is down, as it prevents text
// selection. Not changing focus here is acceptable because the checkbox
// will be focused in onItemClick_() anyway.
if (this.mouseDown_)
return;
if (this.lastFocused && !this.blurred_)
// If focus is being restored from outside the item and the event is fired
// by the list item itself, focus the first control so that the user can
// tab through all the controls. When the user shift-tabs back to the row,
// or focus is restored to the row from a dropdown on the last item, the
// last child item will be focused before the row itself. Since this is
// the desired behavior, do not shift focus to the first item in these
// cases.
const restoreFocusToFirst = this.blurred_ && e.composedPath()[0] === this;
if (this.lastFocused && !restoreFocusToFirst)
this.row_.getEquivalentElement(this.lastFocused).focus();
else
this.row_.getFirstFocusable().focus();
......
......@@ -221,15 +221,24 @@ const FocusRowBehavior = {
/**
* This function gets called when the row itself receives the focus event.
* @param {!Event} e The focus event
* @private
*/
onFocus_: function() {
onFocus_: function(e) {
if (this.mouseFocused_) {
this.mouseFocused_ = false; // Consume and reset flag.
return;
}
if (this.lastFocused && !this.blurred_) {
// If focus is being restored from outside the item and the event is fired
// by the list item itself, focus the first control so that the user can tab
// through all the controls. When the user shift-tabs back to the row, or
// focus is restored to the row from a dropdown on the last item, the last
// child item will be focused before the row itself. Since this is the
// desired behavior, do not shift focus to the first item in these cases.
const restoreFocusToFirst = this.blurred_ && e.composedPath()[0] === this;
if (this.lastFocused && !restoreFocusToFirst) {
this.row_.getEquivalentElement(this.lastFocused).focus();
} else {
const firstFocusable = assert(this.firstControl_);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment