Index: ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector_grid.js |
diff --git a/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector_grid.js b/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector_grid.js |
index 6db2af2a9445fef73f86efafee5c29ba688d3952..f0fc29573be7a1e6009076848f62e38cd6de986d 100644 |
--- a/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector_grid.js |
+++ b/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector_grid.js |
@@ -10,10 +10,6 @@ |
Polymer({ |
is: 'cr-profile-avatar-selector-grid', |
- behaviors: [ |
- Polymer.IronMenubarBehavior, |
- ], |
- |
properties: { |
ignoreModifiedKeyEvents: { |
type: Boolean, |
@@ -21,94 +17,76 @@ Polymer({ |
}, |
}, |
- /** |
- * Handler that is called when left arrow key is pressed. Overrides |
- * IronMenubarBehaviorImpl#_onLeftKey and ignores keys likely to be browser |
- * shortcuts (like Alt+Left for back). |
- * @param {!CustomEvent} event |
- * @private |
- */ |
- _onLeftKey: function(event) { |
- if (this.ignoreModifiedKeyEvents && this.hasKeyModifiers_(event)) |
- return; |
- Polymer.IronMenubarBehaviorImpl._onLeftKey.call(this, event); |
+ listeners: { |
+ keydown: 'onKeyDown_', |
}, |
/** |
- * Handler that is called when right arrow key is pressed. Overrides |
- * IronMenubarBehaviorImpl#_onRightKey and ignores keys likely to be browser |
- * shortcuts (like Alt+Right for forward). |
- * @param {!CustomEvent} event |
+ * @param {!KeyboardEvent} e |
* @private |
*/ |
- _onRightKey: function(event) { |
- if (this.ignoreModifiedKeyEvents && this.hasKeyModifiers_(event)) |
- return; |
- Polymer.IronMenubarBehaviorImpl._onRightKey.call(this, event); |
- }, |
+ onKeyDown_: function(e) { |
+ var items = this.querySelectorAll('.avatar'); |
+ switch (e.key) { |
+ case 'ArrowDown': |
+ case 'ArrowUp': |
+ this.moveFocusRow_(items, e.key); |
+ e.preventDefault(); |
+ return; |
+ case 'ArrowLeft': |
+ case 'ArrowRight': |
+ // Ignores keys likely to be browse shortcuts (like Alt+Left for back). |
+ if (this.ignoreModifiedKeyEvents && hasKeyModifiers(e)) |
+ return; |
- /** |
- * Handler that is called when the up arrow key is pressed. |
- * @param {CustomEvent} event A key combination event. |
- * @private |
- */ |
- _onUpKey: function(event) { |
- this.moveFocusRow_(-1); |
- event.detail.keyboardEvent.preventDefault(); |
- }, |
- |
- /** |
- * Handler that is called when the down arrow key is pressed. |
- * @param {CustomEvent} event A key combination event. |
- * @private |
- */ |
- _onDownKey: function(event) { |
- this.moveFocusRow_(1); |
- event.detail.keyboardEvent.preventDefault(); |
- }, |
- |
- /** |
- * Handler that is called when the esc key is pressed. |
- * @param {CustomEvent} event A key combination event. |
- * @private |
- */ |
- _onEscKey: function(event) { |
- // Override the original behavior by doing nothing. |
- }, |
- |
- /** |
- * @param {!CustomEvent} event |
- * @return {boolean} Whether the key event has modifier keys pressed. |
- */ |
- hasKeyModifiers_: function(event) { |
- return hasKeyModifiers(assertInstanceof(event.detail.keyboardEvent, Event)); |
+ this.moveFocusRow_(items, e.key); |
+ e.preventDefault(); |
+ return; |
+ } |
}, |
/** |
- * Focuses an item on the same column as the currently focused item and on a |
- * row below or above the focus row by the given offset. Focus wraps if |
- * necessary. |
- * @param {number} offset |
+ * Moves focus up/down/left/right according to the given direction. Wraps |
+ * around as necessary. |
+ * @param {!NodeList<!Element>} items |
+ * @param {string} direction Must be on of 'ArrowLeft', 'ArrowRight', |
+ * 'ArrowUp', 'ArrowDown'. |
* @private |
*/ |
- moveFocusRow_: function(offset) { |
- var length = this.items.length; |
+ moveFocusRow_: function(items, direction) { |
+ var offset = |
+ (direction == 'ArrowDown' || direction == 'ArrowRight') ? 1 : -1; |
var style = getComputedStyle(this); |
var avatarSpacing = |
parseInt(style.getPropertyValue('--avatar-spacing'), 10); |
var avatarSize = parseInt(style.getPropertyValue('--avatar-size'), 10); |
var rowSize = Math.floor(this.clientWidth / (avatarSpacing + avatarSize)); |
- var rows = Math.ceil(length / rowSize); |
+ var rows = Math.ceil(items.length / rowSize); |
var gridSize = rows * rowSize; |
- var focusIndex = this.indexOf(this.focusedItem); |
- for (var i = offset; Math.abs(i) <= rows; i += offset) { |
- var item = this.items[(focusIndex + i * rowSize + gridSize) % gridSize]; |
- if (!item) |
- continue; |
- this._setFocusedItem(item); |
- assert(Polymer.dom(item).getOwnerRoot().activeElement == item); |
- return; |
+ var focusIndex = |
+ Array.prototype.slice.call(items).findIndex(function(item) { |
+ return Polymer.dom(item).getOwnerRoot().activeElement == item; |
+ }); |
+ |
+ var nextItem = null; |
+ if (direction == 'ArrowDown' || direction == 'ArrowUp') { |
+ for (var i = offset; Math.abs(i) <= rows; i += offset) { |
+ nextItem = items[(focusIndex + i * rowSize + gridSize) % gridSize]; |
+ if (nextItem) |
+ break; |
+ // This codepath can be hit when |gridSize| is larger than |
+ // |items.length|, which means that there are empty grid spots at the |
+ // end. |
+ } |
+ } else { |
+ var nextIndex = (focusIndex + offset) % items.length; |
+ if (nextIndex < 0) |
+ nextIndex = items.length - 1; |
+ nextItem = items[nextIndex]; |
} |
+ |
+ nextItem.focus(); |
+ assert(Polymer.dom(nextItem).getOwnerRoot().activeElement == nextItem); |
} |
}); |