| 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);
|
| + }
|
| };
|
|
|
| /**
|
|
|