Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2037)

Unified Diff: chrome/browser/resources/downloads/downloads.js

Issue 807593005: Make downloads list keyboard shortcuts more consistent. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix tests Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/downloads/downloads.js
diff --git a/chrome/browser/resources/downloads/downloads.js b/chrome/browser/resources/downloads/downloads.js
index fd7ccc9e6dee71dd48d02317fc2fb38d95c60fa6..8bc2c6f780eedb4e081412cc3854318f37254e25 100644
--- a/chrome/browser/resources/downloads/downloads.js
+++ b/chrome/browser/resources/downloads/downloads.js
@@ -77,6 +77,48 @@ function createButton(onclick, value) {
}
///////////////////////////////////////////////////////////////////////////////
+// DownloadFocusObserver:
+
+/**
+ * @constructor
+ * @implements {cr.ui.FocusRow.Observer}
+ */
+function DownloadFocusObserver() {}
+
+DownloadFocusObserver.prototype = {
+ /** @override */
+ onActivate: function(row) {},
+
+ /** @override */
+ onDeactivate: function(row) {},
+
+ /**
+ * @param {Element} item The row item to find a a row element for.
+ * @return {Element} |row|'s "active" element.
+ * @override
+ */
+ getRowElement: function(item) {
+ return findAncestorByClass(item, 'download');
+ },
+
+ /** @override */
+ onElementIdMiss: function(row, expectedId) {
+ // These are at the same level visually, so focus the first available one if
+ // it exists.
+ var remaining = ['show', 'retry', 'pause', 'resume', 'remove', 'cancel'];
+ if (remaining.indexOf(expectedId) > -1) {
+ for (var i = 0; i < remaining.length; ++i) {
+ if (row.elementIds.indexOf(remaining[i]) > -1)
+ return remaining[i];
+ }
+ }
+
+ // Select the first item that is focusable if nothing else worked.
+ return row.elementIds[0];
+ },
+};
+
+///////////////////////////////////////////////////////////////////////////////
// Downloads
/**
* Class to hold all the information about the visible downloads.
@@ -91,6 +133,8 @@ function Downloads() {
this.node_ = $('downloads-display');
this.summary_ = $('downloads-summary-text');
this.searchText_ = '';
+ this.focusGrid_ = new cr.ui.FocusGrid(this.node_,
+ new DownloadFocusObserver());
// Keep track of the dates of the newest and oldest downloads so that we
// know where to insert them.
@@ -176,6 +220,77 @@ Downloads.prototype.updateResults = function() {
if (loadTimeData.getBoolean('allow_deleting_history'))
$('clear-all').hidden = !hasDownloads || this.searchText_.length > 0;
+
+ this.rebuildFocusGrid_();
+};
+
+/**
+ * Determines if element should be focusable.
+ * @param {!Element} element
+ * @return {bool}
+ * @private
+ */
+Downloads.shouldFocus_ = function(element) {
+ if (!element)
+ return false;
+
+ // Hidden elements are not focusable.
+ var style = window.getComputedStyle(element);
+ if (style.visibility == 'hidden' || style.display == 'none')
+ return false;
+
+ // Verify that all ancestors are focusable.
+ if (element.parentElement)
+ return Downloads.shouldFocus_(element.parentElement);
+
+ return true;
+};
+
+/**
+ * Will add an element to |focusRow| if it can be focused.
+ * @param {cr.ui.FocusRow} focusRow The row to add the element to.
+ * @param {Element} element The element to add.
+ * @param {string} elementId The elementId used for selecting in a grid.
+ * @private
+ */
+Downloads.prototype.addRowElement_ = function(focusRow, element, elementId) {
+ if (Downloads.shouldFocus_(element))
+ focusRow.setFocusableElementId(element, elementId);
+};
+
+/**
+ * Rebuild the focusGrid_ using the elements that each download will have.
+ * @private
+ */
+Downloads.prototype.rebuildFocusGrid_ = function() {
+ this.focusGrid_.destroy();
+
+ // Keys for downloads are in the reverse order of what is displayed.
+ var keys = Object.keys(this.downloads_);
+ for (var i = keys.length - 1; i >= 0; --i) {
+ var node = this.downloads_[keys[i]];
+ var focusRow = this.focusGrid_.createRow();
+
+ // Add all clickable elements as a row into the grid.
+ this.addRowElement_(focusRow, node.nodeFileLink_, 'name');
+ this.addRowElement_(focusRow, node.nodeURL_, 'url');
+ this.addRowElement_(focusRow, node.controlShow_, 'show');
+ this.addRowElement_(focusRow, node.controlRetry_, 'retry');
+ this.addRowElement_(focusRow, node.controlPause_, 'pause');
+ this.addRowElement_(focusRow, node.controlResume_, 'resume');
+ this.addRowElement_(focusRow, node.controlRemove_, 'remove');
+ this.addRowElement_(focusRow, node.controlCancel_, 'cancel');
+
+ // These buttons are mutually exclusive, but they are visually the same.
+ this.addRowElement_(focusRow, node.malwareSave_, 'save');
+ this.addRowElement_(focusRow, node.dangerSave_, 'save');
+ this.addRowElement_(focusRow, node.malwareDiscard_, 'discard');
+ this.addRowElement_(focusRow, node.dangerDiscard_, 'discard');
+
+ this.addRowElement_(focusRow, node.controlByExtensionLink_, 'extension');
+
+ this.focusGrid_.addRow(focusRow);
+ }
};
/**

Powered by Google App Engine
This is Rietveld 408576698