Commit 67d5912a authored by Alex Danilo's avatar Alex Danilo Committed by Commit Bot

Change menu button focus on mouse down

When a button on the action bar has focus, clicking on any menu button
fails to grab focus from any existing focus item, leaving the previously
focused button as selected.

Checks for currently focused element. If a button has focus, let the
browser perform the default action which will set the menu button as
the focused element. If the focus is on any other element, leave it
alone (e.g. in the case where a row in the file list has focus, we
don't want to change that due to the menu activation).

Bug: 906566
Tests: browser_test --gtest_filter="*MultiMenu"
Change-Id: I32ab6b5e52771298c13fae51c2b13fba9cf996b7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1935567
Commit-Queue: Alex Danilo <adanilo@chromium.org>
Commit-Queue: Noel Gordon <noel@chromium.org>
Reviewed-by: default avatarNoel Gordon <noel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#719003}
parent e3b4f6e2
...@@ -12,7 +12,7 @@ class QuickViewController { ...@@ -12,7 +12,7 @@ class QuickViewController {
* @param {!MetadataModel} metadataModel File system metadata. * @param {!MetadataModel} metadataModel File system metadata.
* @param {!FileSelectionHandler} selectionHandler * @param {!FileSelectionHandler} selectionHandler
* @param {!ListContainer} listContainer * @param {!ListContainer} listContainer
* @param {!cr.ui.MenuButton} selectionMenuButton * @param {!cr.ui.MultiMenuButton} selectionMenuButton
* @param {!QuickViewModel} quickViewModel * @param {!QuickViewModel} quickViewModel
* @param {!TaskController} taskController * @param {!TaskController} taskController
* @param {!cr.ui.ListSelectionModel} fileListSelectionModel * @param {!cr.ui.ListSelectionModel} fileListSelectionModel
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
class SelectionMenuController { class SelectionMenuController {
/** /**
* @param {!cr.ui.MenuButton} selectionMenuButton * @param {!cr.ui.MultiMenuButton} selectionMenuButton
* @param {!cr.ui.Menu} menu * @param {!cr.ui.Menu} menu
*/ */
constructor(selectionMenuButton, menu) { constructor(selectionMenuButton, menu) {
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
class SortMenuController { class SortMenuController {
/** /**
* @param {!cr.ui.MenuButton} sortButton * @param {!cr.ui.MultiMenuButton} sortButton
* @param {!FilesToggleRipple} toggleRipple * @param {!FilesToggleRipple} toggleRipple
* @param {!FileListModel} fileListModel * @param {!FileListModel} fileListModel
*/ */
......
...@@ -187,11 +187,11 @@ class FileManagerUI { ...@@ -187,11 +187,11 @@ class FileManagerUI {
/** /**
* The button to sort the file list. * The button to sort the file list.
* @type {!cr.ui.MenuButton} * @type {!cr.ui.MultiMenuButton}
* @const * @const
*/ */
this.sortButton = this.sortButton =
util.queryDecoratedElement('#sort-button', cr.ui.MenuButton); util.queryDecoratedElement('#sort-button', cr.ui.MultiMenuButton);
/** /**
* Ripple effect of sort button. * Ripple effect of sort button.
...@@ -227,11 +227,11 @@ class FileManagerUI { ...@@ -227,11 +227,11 @@ class FileManagerUI {
/** /**
* The button to open context menu in the check-select mode. * The button to open context menu in the check-select mode.
* @type {!cr.ui.MenuButton} * @type {!cr.ui.MultiMenuButton}
* @const * @const
*/ */
this.selectionMenuButton = this.selectionMenuButton = util.queryDecoratedElement(
util.queryDecoratedElement('#selection-menu-button', cr.ui.MenuButton); '#selection-menu-button', cr.ui.MultiMenuButton);
/** /**
* Directory tree. * Directory tree.
......
...@@ -321,11 +321,14 @@ cr.define('cr.ui', () => { ...@@ -321,11 +321,14 @@ cr.define('cr.ui', () => {
} else if (e.button == 0) { // Only show the menu when using left } else if (e.button == 0) { // Only show the menu when using left
// mouse button. // mouse button.
this.showMenu(false, {x: e.screenX, y: e.screenY}); this.showMenu(false, {x: e.screenX, y: e.screenY});
// Prevent the button from stealing focus on mousedown unless
// Prevent the button from stealing focus on mousedown. // focus is on another button.
if (!(document.hasFocus() &&
document.activeElement.tagName === 'BUTTON')) {
e.preventDefault(); e.preventDefault();
} }
} }
}
// Hide the focus ring on mouse click. // Hide the focus ring on mouse click.
this.classList.add('using-mouse'); this.classList.add('using-mouse');
......
...@@ -47,6 +47,8 @@ function setUp() { ...@@ -47,6 +47,8 @@ function setUp() {
' <cr-menu-item id="first" class="custom-appearance"></cr-menu-item>', ' <cr-menu-item id="first" class="custom-appearance"></cr-menu-item>',
' <cr-menu-item id="second" class="custom-appearance"></cr-menu-item>', ' <cr-menu-item id="second" class="custom-appearance"></cr-menu-item>',
'</cr-menu>', '</cr-menu>',
'<div id="focus-div" tabindex="1"/>',
'<button id="focus-button" tabindex="2"/>',
].join(''); ].join('');
// Initialize cr.ui.Command with the <command>s. // Initialize cr.ui.Command with the <command>s.
...@@ -71,6 +73,20 @@ function sendMouseOver(targetQuery) { ...@@ -71,6 +73,20 @@ function sendMouseOver(targetQuery) {
return target.dispatchEvent(event); return target.dispatchEvent(event);
} }
/**
* Send a 'mousedown' event to the element target of a query.
* @param {string} targetQuery Query to specify the element.
*/
function sendMouseDown(targetQuery) {
const event = new MouseEvent('mousedown', {
bubbles: true,
composed: true, // Allow the event to bubble past shadow DOM root.
});
const target = document.querySelector(targetQuery);
assertTrue(!!target);
return target.dispatchEvent(event);
}
/** /**
* Send a 'mouseover' event to the element target of a query. * Send a 'mouseover' event to the element target of a query.
* @param {string} targetQuery Query to specify the element. * @param {string} targetQuery Query to specify the element.
...@@ -348,3 +364,33 @@ function testShrinkWindowSizesTopMenu() { ...@@ -348,3 +364,33 @@ function testShrinkWindowSizesTopMenu() {
const shrunkPosition = topMenu.getBoundingClientRect(); const shrunkPosition = topMenu.getBoundingClientRect();
assertTrue(shrunkPosition.bottom < window.innerHeight); assertTrue(shrunkPosition.bottom < window.innerHeight);
} }
/**
* Tests that mousedown the menu button grabs focus.
*/
function testFocusMenuButtonWithMouse() {
// Set focus on a div element.
//* @type {HTMLElement} */
const divElement = document.querySelector('#focus-div');
divElement.focus();
// Send mousedown event to the menu button.
sendMouseDown('#test-menu-button');
// Verify that the previously focused element still has focus.
assertTrue(document.hasFocus() && document.activeElement === divElement);
// Set focus on a button element.
//* @type {HTMLElement} */
const buttonElement = document.querySelector('#focus-button');
buttonElement.focus();
// Send mousedown event to the menu button.
sendMouseDown('#test-menu-button');
// Verify that the previously focused button has lost focus.
assertFalse(document.hasFocus() && document.activeElement === buttonElement);
// Verify the menu button has taken focus.
assertTrue(document.hasFocus() && document.activeElement === menubutton);
}
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