Chromium Code Reviews| 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..47d2e8e3a7ee0ffb3a1b4b529e4cf46235d00c19 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,73 @@ 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; |
|
tommycli
2017/06/22 21:45:31
Hmm... how can nextItem be null or undefined in th
dpapad
2017/06/22 23:22:48
It can happen because the gridSize can be larger t
tommycli
2017/06/22 23:25:32
Ah gotcha. Could be worth adding an explanation co
dpapad
2017/06/22 23:47:55
Done.
|
| + } |
| + } 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); |
| } |
| }); |