diff options
author | jamiewalch@google.com <jamiewalch@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-08 22:56:18 +0000 |
---|---|---|
committer | jamiewalch@google.com <jamiewalch@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-08 22:56:18 +0000 |
commit | 966fa2ba0fada66a1a1ce094f51ff64447a3aa05 (patch) | |
tree | 3492ea3751288f7b0c35dd6e8e5efd6f590f7946 /remoting | |
parent | 09e3349c85a8da7ffcedbd9e337678a8257fa432 (diff) | |
download | chromium_src-966fa2ba0fada66a1a1ce094f51ff64447a3aa05.zip chromium_src-966fa2ba0fada66a1a1ce094f51ff64447a3aa05.tar.gz chromium_src-966fa2ba0fada66a1a1ce094f51ff64447a3aa05.tar.bz2 |
Improve keyboard navigation.
* Ensure all hyperlinks are selectable (have hrefs).
* Ensure that the selected element has a visual indicator.
* Added keyboard navigation to the host list.
BUG=126200
TEST=Manual
Review URL: https://chromiumcodereview.appspot.com/10375057
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@135937 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting')
-rw-r--r-- | remoting/webapp/host_table_entry.js | 74 | ||||
-rw-r--r-- | remoting/webapp/jscompiler_hacks.js | 5 | ||||
-rw-r--r-- | remoting/webapp/main.css | 13 | ||||
-rw-r--r-- | remoting/webapp/main.html | 2 |
4 files changed, 84 insertions, 10 deletions
diff --git a/remoting/webapp/host_table_entry.js b/remoting/webapp/host_table_entry.js index 9ea7fb3..ed1669f 100644 --- a/remoting/webapp/host_table_entry.js +++ b/remoting/webapp/host_table_entry.js @@ -82,18 +82,20 @@ remoting.HostTableEntry.prototype.create = function(host, onRename, onDelete) { // Create the host rename cell. var editButton = /** @type {HTMLElement} */ document.createElement('img'); editButton.title = chrome.i18n.getMessage(/*i18n-content*/'TOOLTIP_RENAME'); + editButton.src = 'icon_pencil.png'; + editButton.tabIndex = 0; editButton.classList.add('clickable'); editButton.classList.add('host-list-edit'); - editButton.src = 'icon_pencil.png'; editButton.classList.add('host-list-rename-icon'); tableRow.appendChild(editButton); // Create the host delete cell. var deleteButton = /** @type {HTMLElement} */ document.createElement('img'); deleteButton.title = chrome.i18n.getMessage(/*i18n-content*/'TOOLTIP_DELETE'); + deleteButton.src = 'icon_cross.png'; + deleteButton.tabIndex = 0; deleteButton.classList.add('clickable'); deleteButton.classList.add('host-list-edit'); deleteButton.classList.add('host-list-remove-icon'); - deleteButton.src = 'icon_cross.png'; tableRow.appendChild(deleteButton); this.init(host, tableRow, hostNameCell, editButton, onRename, @@ -131,19 +133,38 @@ remoting.HostTableEntry.prototype.init = function( /** @type {remoting.HostTableEntry} */ var that = this; + /** @param {Event} event The click event. */ var beginRename = function(event) { that.beginRename_(); event.stopPropagation(); }; + /** @param {Event} event The keyup event. */ + var beginRenameKeyboard = function(event) { + if (event.which == 13 || event.which == 32) { + that.beginRename_(); + event.stopPropagation(); + } + }; editButton.addEventListener('click', beginRename, true); + editButton.addEventListener('keyup', beginRenameKeyboard, true); + this.registerFocusHandlers_(editButton); + if (opt_deleteButton) { /** @param {Event} event The click event. */ var confirmDelete = function(event) { that.showDeleteConfirmation_(); event.stopPropagation(); }; + /** @param {Event} event The keyup event. */ + var confirmDeleteKeyboard = function(event) { + if (event.which == 13 || event.which == 32) { + that.showDeleteConfirmation_(); + } + }; opt_deleteButton.addEventListener('click', confirmDelete, false); + opt_deleteButton.addEventListener('keyup', confirmDeleteKeyboard, false); + this.registerFocusHandlers_(opt_deleteButton); } this.updateStatus(); }; @@ -303,7 +324,7 @@ remoting.HostTableEntry.prototype.removeEditBox_ = function() { }; /** - * Create the DOM nodes for the hostname part of the table entry. + * Create the DOM nodes and event handlers for the hostname cell. * @return {void} Nothing. * @private */ @@ -311,6 +332,18 @@ remoting.HostTableEntry.prototype.setHostName_ = function() { var hostNameNode = /** @type {HTMLElement} */ document.createElement('span'); if (this.host.status == 'ONLINE') { hostNameNode.innerText = this.host.hostName; + hostNameNode.tabIndex = 0; + this.registerFocusHandlers_(hostNameNode); + /** @type {remoting.HostTableEntry} */ + var that = this; + /** @param {Event} event */ + var onKeyDown = function(event) { + if (that.onConnectReference_ && + (event.which == 13 || event.which == 32)) { + that.onConnectReference_(); + } + }; + hostNameNode.addEventListener('keydown', onKeyDown, false); } else { hostNameNode.innerText = chrome.i18n.getMessage(/*i18n-content*/'OFFLINE', this.host.hostName); @@ -333,3 +366,38 @@ remoting.HostTableEntry.prototype.onKeydown_ = function(event) { this.commitRename_(); } }; + +/** + * Register focus and blur handlers to cause the parent node to be highlighted + * whenever a child link has keyboard focus. Note that this is only necessary + * because Chrome does not yet support the draft CSS Selectors 4 specification + * (http://www.w3.org/TR/selectors4/#subject), which provides a more elegant + * solution to this problem. + * + * @param {HTMLElement} e The element on which to register the event handlers. + * @return {void} Nothing. + * @private + */ +remoting.HostTableEntry.prototype.registerFocusHandlers_ = function(e) { + /** @type {remoting.HostTableEntry} */ + var that = this; + e.addEventListener('focus', function() { that.onFocusChange_(); }, false); + e.addEventListener('blur', function() { that.onFocusChange_(); }, false); +}; + +/** + * Handle a focus change event within this table row. + * @return {void} Nothing. + * @private + */ +remoting.HostTableEntry.prototype.onFocusChange_ = function() { + var element = document.activeElement; + while (element) { + if (element == this.tableRow) { + this.tableRow.classList.add('child-focused'); + return; + } + element = element.parentNode; + } + this.tableRow.classList.remove('child-focused'); +}; diff --git a/remoting/webapp/jscompiler_hacks.js b/remoting/webapp/jscompiler_hacks.js index 1f97590..007bbb3 100644 --- a/remoting/webapp/jscompiler_hacks.js +++ b/remoting/webapp/jscompiler_hacks.js @@ -6,7 +6,10 @@ // WebKit-specific properties and methods. It is used only with JSCompiler // to verify the type-correctness of our code. -/** @type Array.<HTMLElement> */ +/** @type {HTMLElement} */ +Document.prototype.activeElement; + +/** @type {Array.<HTMLElement>} */ Document.prototype.all; /** @type {function(string): void} */ diff --git a/remoting/webapp/main.css b/remoting/webapp/main.css index 2d05b1c..68a94d1 100644 --- a/remoting/webapp/main.css +++ b/remoting/webapp/main.css @@ -11,7 +11,6 @@ tfoot, thead, tr, th, td, button { margin: 0; padding: 0; border: 0; - outline: 0; font-weight: inherit; font-style: inherit; font-size: 100%; @@ -374,19 +373,23 @@ td { vertical-align: middle; } -.host-online.clickable:hover { +.host-online.clickable:hover, +.host-online.clickable.child-focused { background-color: #f2f2f2; } -.host-list-rename-icon, .host-list-remove-icon { +.host-list-rename-icon, +.host-list-remove-icon { opacity: 0; } -.section-row:hover .host-list-rename-icon { +.section-row:hover .host-list-rename-icon, +.section-row.child-focused .host-list-rename-icon { opacity: 0.6; } -.section-row:hover .host-list-remove-icon { +.section-row:hover .host-list-remove-icon, +.section-row.child-focused .host-list-remove-icon { opacity: 0.3; } diff --git a/remoting/webapp/main.html b/remoting/webapp/main.html index 7a2e640..b0c7da5 100644 --- a/remoting/webapp/main.html +++ b/remoting/webapp/main.html @@ -68,7 +68,7 @@ found in the LICENSE file. <div id="top-secondary"> <span id="current-email"></span> <span data-ui-mode="home"> - <a id="sign-out" i18n-content="SIGN_OUT_BUTTON"></a> | + <a id="sign-out" href="#" i18n-content="SIGN_OUT_BUTTON"></a> | <!-- TODO(jamiewalch): Add this back in when we support it. <a id="connection-history" i18n-content="CONNECTION_HISTORY_BUTTON"></a> | |