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

Unified Diff: ui/webui/resources/js/cr/ui/focus_grid.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: ui/webui/resources/js/cr/ui/focus_grid.js
diff --git a/ui/webui/resources/js/cr/ui/focus_grid.js b/ui/webui/resources/js/cr/ui/focus_grid.js
index 2e76ca10c03009f2d5d72e5a781989e1754a00f4..7752ddf9b58186c4fe2e81b7820d62fbd0498c44 100644
--- a/ui/webui/resources/js/cr/ui/focus_grid.js
+++ b/ui/webui/resources/js/cr/ui/focus_grid.js
@@ -18,7 +18,7 @@ cr.define('cr.ui', function() {
* focusable [focused] focusable (row: 1, col: 1)
* focusable focusable focusable
*
- * And pressing right at this point would move the focus to:
+ * And pressing right or tab at this point would move the focus to:
*
* focusable focusable focusable
* focusable focusable [focused] (row: 1, col: 2)
@@ -26,7 +26,6 @@ cr.define('cr.ui', function() {
*
* @param {Node=} opt_boundary Ignore focus events outside this node.
* @param {cr.ui.FocusRow.Observer=} opt_observer An observer of rows.
- * @implements {cr.ui.FocusRow.Delegate}
* @constructor
*/
function FocusGrid(opt_boundary, opt_observer) {
@@ -38,8 +37,45 @@ cr.define('cr.ui', function() {
/** @type {!Array.<!cr.ui.FocusRow>} */
this.rows = [];
+
+ /** @private {!EventTracker} */
+ this.eventTracker_ = new EventTracker;
+ this.eventTracker_.add(cr.doc, 'keydown', this.onKeydown_.bind(this));
+
+ /** @private {cr.ui.FocusRow.Delegate} */
+ this.delegate_ = new FocusGrid.RowDelegate(this);
}
+ /**
+ * Row delegate to overwrite the behavior of a mouse click to deselect any row
+ * that wasn't clicked.
+ * @param {cr.ui.FocusGrid} focusGrid
+ * @implements {cr.ui.FocusRow.Delegate}
+ */
+ FocusGrid.RowDelegate = function(focusGrid) {
+ /** @private {cr.ui.FocusGrid} */
+ this.focusGrid_ = focusGrid;
+ };
+ FocusGrid.RowDelegate.prototype = {
+ /** @override */
+ onKeydown: function(row, e) { return false; },
+
+ /** @override */
+ onMousedown: function(row, e) {
+ // Only care about left mouse click.
+ if (e.button)
+ return false;
+
+ // Focus the clicked row, unfocus all others.
+ var rows = this.focusGrid_.rows;
+ for (var i = 0; i < rows.length; ++i)
+ rows[i].onFocusIdChange(rows[i].getElementId(e.target));
+
+ e.preventDefault();
+ return true;
+ },
+ };
+
FocusGrid.prototype = {
/**
* Unregisters event handlers and removes all |this.rows|.
@@ -51,63 +87,85 @@ cr.define('cr.ui', function() {
/**
* @param {EventTarget} target A target item to find in this grid.
- * @return {?{row: number, col: number}} A position or null if not found.
+ * @return {?{row: number, elementId: string}} A position or null if not
+ * found.
*/
getPositionForTarget: function(target) {
for (var i = 0; i < this.rows.length; ++i) {
- for (var j = 0; j < this.rows[i].items.length; ++j) {
- if (target == this.rows[i].items[j])
- return {row: i, col: j};
- }
+ var elementId = this.rows[i].getElementId(target);
+ if (elementId)
+ return { row: i, elementId: elementId };
}
return null;
},
- /** @override */
- onKeydown: function(keyRow, e) {
- var rowIndex = this.rows.indexOf(keyRow);
- assert(rowIndex >= 0);
+ /**
+ * Handles keyboard shortcuts to move up/down in the grid.
+ * @param {Event} e The key event.
+ */
+ onKeydown_: function(e) {
+ var pos = this.getPositionForTarget(e.target);
+ if (!pos)
+ return;
var row = -1;
if (e.keyIdentifier == 'Up')
- row = rowIndex - 1;
+ row = pos.row - 1;
else if (e.keyIdentifier == 'Down')
- row = rowIndex + 1;
+ row = pos.row + 1;
else if (e.keyIdentifier == 'PageUp')
row = 0;
else if (e.keyIdentifier == 'PageDown')
row = this.rows.length - 1;
if (!this.rows[row])
- return false;
+ return;
- var colIndex = keyRow.items.indexOf(e.target);
- var col = Math.min(colIndex, this.rows[row].items.length - 1);
-
- this.rows[row].focusIndex(col);
+ // Allow a grid to remember the elementId if a column is missing from a
+ // row. The elementId is reset if the column focus changed while the row
+ // was focused.
+ if (!this.rememberedId || this.rows[pos.row].focusChanged())
+ this.rememberedId = pos.elementId;
+ this.rows[row].setFocusId(this.rememberedId);
+ this.rows[row].trackFocus();
e.preventDefault();
- return true;
},
- /** @override */
- onMousedown: function(row, e) {
- return false;
+ /**
+ * Create a new FocusRow for this grid and return it.
+ * This row will need to be added to the grid using addRow.
+ * @return {cr.ui.FocusRow} The row that was added to the grid.
+ */
+ createRow: function() {
+ return new cr.ui.FocusRow(this.boundary_, this.delegate_, this.observer_);
},
/**
- * @param {!Array.<!NodeList|!Array.<!Element>>} grid A 2D array of nodes.
+ * Add a FocusRow to this grid. This needs to be called AFTER adding columns
+ * to the row. This is so that TAB focus can be properly enabled in the
+ * columns.
+ * @param {cr.ui.FocusRow} row The row that needs to be added to this grid.
*/
- setGrid: function(grid) {
- this.destroy();
-
- this.rows = grid.map(function(row) {
- return new cr.ui.FocusRow(row, this.boundary_, this, this.observer_);
- }, this);
+ addRow: function(row) {
+ if (this.rows.length == 0) {
+ // Focus the first row.
+ row.setInitialFocus(true);
+ }
+ else {
+ if (row.getElementId(document.activeElement)) {
+ // Update focus if the current row is active.
+ this.rows[0].setInitialFocus(false);
+ row.setInitialFocus(true);
+ } else {
+ // Make sure initial focus is false if the row isn't active.
+ row.setInitialFocus(false);
+ }
+ }
- if (!this.getPositionForTarget(document.activeElement) && this.rows[0])
- this.rows[0].activeIndex = 0;
+ // Add the row after its initial focus is set.
+ this.rows.push(row);
},
};

Powered by Google App Engine
This is Rietveld 408576698