| 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);
|
| }
|
| });
|
|
|