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

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

Issue 2820153003: [MD Bookmarks] Add keyboard navigation to sidebar. (Closed)
Patch Set: 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
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 cdca80866605f6c672c20a96a3b318ed0449ee5d..24aca68b557c8fffc35d48d7bbabbd1768a2a47b 100644
--- a/chrome/browser/resources/md_bookmarks/folder_node.js
+++ b/chrome/browser/resources/md_bookmarks/folder_node.js
@@ -7,6 +7,7 @@ Polymer({
behaviors: [
bookmarks.StoreClient,
+ Polymer.IronA11yKeysBehavior,
],
properties: {
@@ -20,6 +21,11 @@ Polymer({
observer: 'depthChanged_',
},
+ focusable: {
+ type: Boolean,
+ value: false,
+ },
+
/** @type {BookmarkNode} */
item_: Object,
@@ -41,6 +47,10 @@ Polymer({
},
},
+ listeners: {
+ 'keydown': 'onKeydown_',
+ },
+
/** @override */
attached: function() {
this.watch('item_', function(state) {
@@ -57,6 +67,14 @@ Polymer({
});
this.updateFromStore();
+
+ if (this.selectedFolder_ == this.itemId)
+ this.fire('folder-node-focus-changed', this);
+ },
+
+ /** @return {HTMLElement} */
+ getFocusTarget: function() {
+ return this.$.container;
},
/** @return {HTMLElement} */
@@ -65,8 +83,110 @@ Polymer({
},
/** @return {boolean} */
- isPositiveDepth_: function() {
- return this.depth >= 0;
+ isPositiveDepth_: function(depth) {
+ return depth >= 0;
+ },
+
+ /**
+ * @private
+ * @param {!Event} e
+ */
+ onKeydown_: function(e) {
+ var direction = 0;
+ var handled = true;
+ if (this.keyboardEventMatchesKeys(e, 'up')) {
tsergeant 2017/04/19 01:42:16 Seems like overkill to use IronA11yKeysBehavior ju
calamity 2017/04/19 04:51:02 Done.
+ direction = -1;
+ } else if (this.keyboardEventMatchesKeys(e, 'down')) {
+ direction = 1;
+ } else {
+ handled = false;
+ }
+
tsergeant 2017/04/19 01:42:16 Is left/right going to be handled here too? Maybe
calamity 2017/04/19 04:51:02 Yeah. It's in a follow-up.
+ if (direction) {
+ handled =
+ this.changeKeyboardSelection_(direction, this.root.activeElement);
+ }
+
+ if (!handled)
+ return;
+
+ e.preventDefault();
+ e.stopPropagation();
+ },
+
+ /**
+ * @private
+ * @param {number} direction
+ * @return {boolean} Whether the event should be treated as handled.
+ */
+ changeKeyboardSelection_: function(direction, currentFocus) {
+ var isCurrentlyFocused = currentFocus == this.$.container;
+
+ // Get the next folder node. If there is no next element, the event will
+ // bubble to the parent node which will handle it.
+ var newFocusFolderNode = this.getNextVisibleFolderNode_(
+ direction == -1, isCurrentlyFocused ? this : currentFocus);
+
+ if (!newFocusFolderNode || newFocusFolderNode.itemId != ROOT_NODE_ID) {
tsergeant 2017/04/19 01:42:16 This can be simplified a little bit: if (!newFocu
calamity 2017/04/19 04:51:02 Done.
+ if (newFocusFolderNode) {
+ this.fire('folder-node-focus-changed', newFocusFolderNode);
+ newFocusFolderNode.getFocusTarget().focus();
+ } else {
+ // If there is no newly focused node, allow the event to bubble.
+ return false;
+ }
+ }
+ return true;
+ },
+
+ /**
+ * Returns the next or previous visible bookmark node relative to |current|.
+ * @private
+ * @param {boolean} reverse
+ * @param {BookmarksFolderNodeElement} current Either this node, or an
+ * immediate child.
+ * @return {HTMLElement|null} Returns null
tsergeant 2017/04/19 01:42:16 Returns null...when?
calamity 2017/04/19 04:51:02 Done.
+ */
+ getNextVisibleFolderNode_: function(reverse, current) {
+ var newFocus = null;
+ var children =
+ Array.from(this.root.querySelectorAll('bookmarks-folder-node'));
+
+ // The current node's successor can only be its first child.
+ if (this == current) {
+ if (!reverse && children.length && !this.isClosed_)
+ newFocus = children[0];
+
+ return newFocus;
+ }
+
+ var index = children.indexOf(current);
+ 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 ? this : 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;
+ },
+
+ /**
+ * @private
+ * @return {BookmarksFolderNodeElement}
+ */
+ getLastVisibleDescendant_: function() {
+ var children =
+ Array.from(this.root.querySelectorAll('bookmarks-folder-node'));
+
+ if (this.isClosed_ || children.length == 0)
+ return this;
+
+ return children.pop().getLastVisibleDescendant_();
},
/**
@@ -140,4 +260,8 @@ Polymer({
isRootFolder_: function() {
return this.depth == 0;
},
+
+ getTabIndex_: function(focusable) {
+ return focusable ? 0 : -1;
+ },
});

Powered by Google App Engine
This is Rietveld 408576698