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

Unified Diff: chrome/browser/resources/md_bookmarks/folder_node.js

Issue 2820153003: [MD Bookmarks] Add keyboard navigation to sidebar. (Closed)
Patch Set: address comments Created 3 years, 8 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
« no previous file with comments | « chrome/browser/resources/md_bookmarks/folder_node.html ('k') | chrome/test/data/webui/BUILD.gn » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/resources/md_bookmarks/folder_node.js
diff --git a/chrome/browser/resources/md_bookmarks/folder_node.js b/chrome/browser/resources/md_bookmarks/folder_node.js
index a6b2e938eacf4047277f5fdd4acb9ed91c86848e..94cc5e7a665fea47fdf550a04549d56e42d91e4c 100644
--- a/chrome/browser/resources/md_bookmarks/folder_node.js
+++ b/chrome/browser/resources/md_bookmarks/folder_node.js
@@ -41,6 +41,10 @@ Polymer({
},
},
+ listeners: {
+ 'keydown': 'onKeydown_',
+ },
+
/** @override */
attached: function() {
this.watch('item_', function(state) {
@@ -60,6 +64,11 @@ Polymer({
},
/** @return {HTMLElement} */
+ getFocusTarget: function() {
+ return this.$.container;
+ },
+
+ /** @return {HTMLElement} */
getDropTarget: function() {
return this.$.container;
},
@@ -71,6 +80,131 @@ Polymer({
/**
* @private
+ * @param {!Event} e
+ */
+ onKeydown_: function(e) {
+ var direction = 0;
+ var handled = true;
+ // TODO(calamity): Handle left/right arrow keys.
+ if (e.key == 'ArrowUp') {
+ direction = -1;
+ } else if (e.key == 'ArrowDown') {
+ direction = 1;
+ } else {
+ handled = false;
+ }
+
+ if (direction)
+ this.changeKeyboardSelection_(direction, this.root.activeElement);
+
+ if (!handled)
+ return;
+
+ e.preventDefault();
+ e.stopPropagation();
+ },
+
+ /**
+ * @private
+ * @param {number} direction
+ * @param {!HTMLElement} currentFocus
+ */
+ changeKeyboardSelection_: function(direction, currentFocus) {
+ var newFocusFolderNode = null;
+ var isChildFolderNodeFocused =
+ currentFocus.tagName == 'BOOKMARKS-FOLDER-NODE';
+ var reverse = direction == -1;
+
+ // The current node's successor is its first child when open.
+ if (!isChildFolderNodeFocused && !reverse && !this.isClosed_) {
+ var children = this.getChildFolderNodes_();
+ if (children.length)
+ newFocusFolderNode = children[0];
+ }
+
+ if (isChildFolderNodeFocused) {
+ // Get the next child folder node if a child is focused.
+ if (!newFocusFolderNode) {
+ newFocusFolderNode = this.getNextChild_(
+ reverse,
+ /** @type {!BookmarksFolderNodeElement} */ (currentFocus));
+ }
+
+ // The first child's predecessor is this node.
+ if (!newFocusFolderNode && reverse)
+ newFocusFolderNode = this;
+ }
+
+ // If there is no newly focused node, allow the parent to handle the change.
+ if (!newFocusFolderNode) {
+ if (this.itemId != ROOT_NODE_ID)
+ this.getParentFolderNode_().changeKeyboardSelection_(direction, this);
+
+ return;
+ }
+
+ // The root node is not navigable.
+ if (newFocusFolderNode.itemId != ROOT_NODE_ID) {
+ newFocusFolderNode.selectFolder_();
+ newFocusFolderNode.getFocusTarget().focus();
+ }
+ },
+
+ /**
+ * Returns the next or previous visible bookmark node relative to |child|.
+ * @private
+ * @param {boolean} reverse
+ * @param {!BookmarksFolderNodeElement} child
+ * @return {BookmarksFolderNodeElement|null} Returns null if there is no child
+ * before/after |child|.
+ */
+ getNextChild_: function(reverse, child) {
+ var newFocus = null;
+ var children = this.getChildFolderNodes_();
+
+ var index = children.indexOf(child);
+ assert(index != -1);
+ if (reverse) {
+ // A child node's predecessor is either the previous child's last visible
+ // descendant, or this node, which is its immediate parent.
+ newFocus =
+ index == 0 ? null : children[index - 1].getLastVisibleDescendant_();
+ } else if (index < children.length - 1) {
+ // A successor to a child is the next child.
+ newFocus = children[index + 1];
+ }
+
+ return newFocus;
+ },
+
+ /**
+ * Returns the immediate parent folder node, or null if there is none.
+ * @private
+ * @return {BookmarksFolderNodeElement|null}
+ */
+ getParentFolderNode_: function() {
+ var parentFolderNode = this.parentNode;
+ while (parentFolderNode &&
+ parentFolderNode.tagName != 'BOOKMARKS-FOLDER-NODE') {
+ parentFolderNode = parentFolderNode.parentNode || parentFolderNode.host;
+ }
+ return parentFolderNode || null;
+ },
+
+ /**
+ * @private
+ * @return {BookmarksFolderNodeElement}
+ */
+ getLastVisibleDescendant_: function() {
+ var children = this.getChildFolderNodes_();
+ if (this.isClosed_ || children.length == 0)
+ return this;
+
+ return children.pop().getLastVisibleDescendant_();
+ },
+
+ /**
+ * @private
* @return {string}
*/
getFolderIcon_: function() {
@@ -83,6 +217,14 @@ Polymer({
},
/**
+ * @private
+ * @return {!Array<!BookmarksFolderNodeElement>}
+ */
+ getChildFolderNodes_: function() {
+ return Array.from(this.root.querySelectorAll('bookmarks-folder-node'));
+ },
+
+ /**
* Occurs when the drop down arrow is tapped.
* @private
* @param {!Event} e
@@ -95,6 +237,14 @@ Polymer({
/**
* @private
+ * @param {!Event} e
+ */
+ preventDefault_: function(e) {
+ e.preventDefault();
+ },
+
+ /**
+ * @private
* @param {string} itemId
* @param {string} selectedFolder
* @return {boolean}
@@ -140,4 +290,12 @@ Polymer({
isRootFolder_: function() {
return this.itemId == ROOT_NODE_ID;
},
+
+ /**
+ * @private
+ * @return {string}
+ */
+ getTabIndex_: function() {
+ return this.isSelectedFolder_ ? '0' : '';
+ },
});
« no previous file with comments | « chrome/browser/resources/md_bookmarks/folder_node.html ('k') | chrome/test/data/webui/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698