Skip to content

Commit

Permalink
[Files.app] Make menus accessible
Browse files Browse the repository at this point in the history
This patch make the menus in Files.app accessible by Chromevox.

This patch works:
- Make the menuitems focusable
- Even the elements get lost focus, don't focus to the mainview

BUG=465938
TEST=manually tested

Review URL: https://codereview.chromium.org/1052343004

Cr-Commit-Position: refs/heads/master@{#323897}
  • Loading branch information
yoshikig authored and Commit bot committed Apr 6, 2015
1 parent 2e98c5e commit d1ea561
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 48 deletions.
1 change: 1 addition & 0 deletions ui/file_manager/file_manager/foreground/css/common.css
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ cr-menu.chrome-menu > :not(hr) {
background-position: right 10px center;
background-repeat: no-repeat;
line-height: 32px;
outline: none;
padding: 0 12px;
}

Expand Down
62 changes: 29 additions & 33 deletions ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,19 @@ function FileManagerUI(element, launchParam) {
// Initialize attributes.
this.element.setAttribute('type', this.dialogType_);

// Hack: make menuitems focusable. Since the menuitems in Files.app is not
// button so it doesn't have a tabfocus in nature. It prevents Chromevox from
// speeaching because the opened menu is closed when the non-focusable object
// tries to get the focus.
var menuitems = document.querySelectorAll('cr-menu.chrome-menu > :not(hr)');
for (var i = 0; i < menuitems.length; i++) {
// Make menuitems focusable. The value can be any non-negative value,
// because pressing 'Tab' key on menu is handled and we don't need to mind
// the taborder and the destination of tabfocus.
if (!menuitems[i].hasAttribute('tabindex'))
menuitems[i].setAttribute('tabindex', '0');
}

// Modify UI default behavior.
this.element.addEventListener('click', this.onExternalLinkClick_.bind(this));
this.element.addEventListener('drop', function(e) {
Expand Down Expand Up @@ -301,10 +314,23 @@ FileManagerUI.prototype.initAdditionalUI = function(

// Add handlers.
document.defaultView.addEventListener('resize', this.relayout.bind(this));
document.addEventListener('focusout', this.onFocusOut_.bind(this));

// Set the initial focus.
this.onFocusOut_();
// Set the initial focus. When there is no focus, the active element is the
// <body>.
setTimeout(function() {
if (document.activeElement === document.body) {
var targetElement = null;
if (this.dialogType_ == DialogType.SELECT_SAVEAS_FILE) {
targetElement = this.dialogFooter.filenameInput;
} else if (this.listContainer.currentListType !=
ListContainer.ListType.UNINITIALIZED) {
targetElement = this.listContainer.currentList;
}

if (targetElement)
targetElement.focus();
}
}.bind(this), 0);
};

/**
Expand Down Expand Up @@ -387,36 +413,6 @@ FileManagerUI.prototype.onExternalLinkClick_ = function(event) {
this.dialogFooter.cancelButton.click();
};

/**
* Re-focuses an element.
* @private
*/
FileManagerUI.prototype.onFocusOut_ = function() {
setTimeout(function() {
// When there is no focus, the active element is the <body>
if (document.activeElement !== document.body)
return;

var targetElement;
if (this.dialogType_ == DialogType.SELECT_SAVEAS_FILE) {
targetElement = this.dialogFooter.filenameInput;
} else if (this.listContainer.currentListType !=
ListContainer.ListType.UNINITIALIZED) {
targetElement = this.listContainer.currentList;
} else {
return;
}

// Hack: if the tabIndex is disabled, we can assume a modal dialog is
// shown. Focus to a button on the dialog instead.
if (!targetElement.hasAttribute('tabIndex') || targetElement.tabIndex == -1)
targetElement = document.querySelector('button:not([tabIndex="-1"])');

if (targetElement)
targetElement.focus();
}.bind(this), 0);
};

/**
* Decorates the given splitter element.
* @param {!HTMLElement} splitterElement
Expand Down
2 changes: 1 addition & 1 deletion ui/file_manager/file_manager/main.html
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@
<div id="volume-space-info">
<div id="volume-space-info-contents">
<span id="volume-space-info-label"></span>
<div class="progress-bar">
<div class="progress-bar" aria-hidden="true">
<div class="progress-track" id="volume-space-info-bar"></div>
</div>
</div>
Expand Down
20 changes: 6 additions & 14 deletions ui/file_manager/integration_tests/file_manager/tab_index.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,11 @@ testcase.searchBoxFocus = function() {
// Check that the file list has the focus.
function(result) {
chrome.test.assertTrue(result);
remoteCall.waitForElement(appId, ['#file-list:focus']).then(this.next);
remoteCall.checkNextTabFocus(appId, 'file-list').then(this.next);
},
// Check for errors.
function(element) {
function(result) {
chrome.test.assertTrue(result);
checkIfNoErrorsOccured(this.next);
}
]);
Expand All @@ -67,10 +68,7 @@ testcase.tabindexFocus = function() {
},
// Press the Tab key.
function(element) {
remoteCall.callRemoteTestUtil('getActiveElement',
appId,
[],
this.next);
remoteCall.callRemoteTestUtil('getActiveElement', appId, [], this.next);
}, function(element) {
chrome.test.assertEq('list', element.attributes['class']);
remoteCall.checkNextTabFocus(appId, 'search-button').then(this.next);
Expand Down Expand Up @@ -114,10 +112,7 @@ testcase.tabindexFocusDownloads = function() {
},
// Press the Tab key.
function(element) {
remoteCall.callRemoteTestUtil('getActiveElement',
appId,
[],
this.next);
remoteCall.callRemoteTestUtil('getActiveElement', appId, [], this.next);
}, function(element) {
chrome.test.assertEq('list', element.attributes['class']);
remoteCall.checkNextTabFocus(appId, 'search-button').then(this.next);
Expand Down Expand Up @@ -157,10 +152,7 @@ testcase.tabindexFocusDirectorySelected = function() {
},
// Press the Tab key.
function(element) {
remoteCall.callRemoteTestUtil('getActiveElement',
appId,
[],
this.next);
remoteCall.callRemoteTestUtil('getActiveElement', appId, [], this.next);
}, function(element) {
chrome.test.assertEq('list', element.attributes['class']);
// Select the directory named 'photos'.
Expand Down

0 comments on commit d1ea561

Please sign in to comment.