| 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' : '';
|
| + },
|
| });
|
|
|