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

Unified Diff: chrome/browser/resources/md_history/lazy_load.crisper.js

Issue 2272553002: MD WebUI: Use arrow keys for navigation in cr-shared-menu, close on tab (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Expand tests Created 4 years, 3 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_history/lazy_load.crisper.js
diff --git a/chrome/browser/resources/md_history/lazy_load.crisper.js b/chrome/browser/resources/md_history/lazy_load.crisper.js
index 29502b017090db42b4004999cd9ec846036c4f53..7a8e44300d89c1d16ffa988f11bca8e0b13a6535 100644
--- a/chrome/browser/resources/md_history/lazy_load.crisper.js
+++ b/chrome/browser/resources/md_history/lazy_load.crisper.js
@@ -1814,6 +1814,182 @@ Polymer({
}
});
+Polymer.IronMenuBehaviorImpl = {
+ properties: {
+ focusedItem: {
+ observer: '_focusedItemChanged',
+ readOnly: true,
+ type: Object
+ },
+ attrForItemTitle: {
+ type: String
+ }
+ },
+ hostAttributes: {
+ role: 'menu',
+ tabindex: '0'
+ },
+ observers: [ '_updateMultiselectable(multi)' ],
+ listeners: {
+ focus: '_onFocus',
+ keydown: '_onKeydown',
+ 'iron-items-changed': '_onIronItemsChanged'
+ },
+ keyBindings: {
+ up: '_onUpKey',
+ down: '_onDownKey',
+ esc: '_onEscKey',
+ 'shift+tab:keydown': '_onShiftTabDown'
+ },
+ attached: function() {
+ this._resetTabindices();
+ },
+ select: function(value) {
+ if (this._defaultFocusAsync) {
+ this.cancelAsync(this._defaultFocusAsync);
+ this._defaultFocusAsync = null;
+ }
+ var item = this._valueToItem(value);
+ if (item && item.hasAttribute('disabled')) return;
+ this._setFocusedItem(item);
+ Polymer.IronMultiSelectableBehaviorImpl.select.apply(this, arguments);
+ },
+ _resetTabindices: function() {
+ var selectedItem = this.multi ? this.selectedItems && this.selectedItems[0] : this.selectedItem;
+ this.items.forEach(function(item) {
+ item.setAttribute('tabindex', item === selectedItem ? '0' : '-1');
+ }, this);
+ },
+ _updateMultiselectable: function(multi) {
+ if (multi) {
+ this.setAttribute('aria-multiselectable', 'true');
+ } else {
+ this.removeAttribute('aria-multiselectable');
+ }
+ },
+ _focusWithKeyboardEvent: function(event) {
+ for (var i = 0, item; item = this.items[i]; i++) {
+ var attr = this.attrForItemTitle || 'textContent';
+ var title = item[attr] || item.getAttribute(attr);
+ if (!item.hasAttribute('disabled') && title && title.trim().charAt(0).toLowerCase() === String.fromCharCode(event.keyCode).toLowerCase()) {
+ this._setFocusedItem(item);
+ break;
+ }
+ }
+ },
+ _focusPrevious: function() {
+ var length = this.items.length;
+ var curFocusIndex = Number(this.indexOf(this.focusedItem));
+ for (var i = 1; i < length + 1; i++) {
+ var item = this.items[(curFocusIndex - i + length) % length];
+ if (!item.hasAttribute('disabled')) {
+ var owner = Polymer.dom(item).getOwnerRoot() || document;
+ this._setFocusedItem(item);
+ if (Polymer.dom(owner).activeElement == item) {
+ return;
+ }
+ }
+ }
+ },
+ _focusNext: function() {
+ var length = this.items.length;
+ var curFocusIndex = Number(this.indexOf(this.focusedItem));
+ for (var i = 1; i < length + 1; i++) {
+ var item = this.items[(curFocusIndex + i) % length];
+ if (!item.hasAttribute('disabled')) {
+ var owner = Polymer.dom(item).getOwnerRoot() || document;
+ this._setFocusedItem(item);
+ if (Polymer.dom(owner).activeElement == item) {
+ return;
+ }
+ }
+ }
+ },
+ _applySelection: function(item, isSelected) {
+ if (isSelected) {
+ item.setAttribute('aria-selected', 'true');
+ } else {
+ item.removeAttribute('aria-selected');
+ }
+ Polymer.IronSelectableBehavior._applySelection.apply(this, arguments);
+ },
+ _focusedItemChanged: function(focusedItem, old) {
+ old && old.setAttribute('tabindex', '-1');
+ if (focusedItem) {
+ focusedItem.setAttribute('tabindex', '0');
+ focusedItem.focus();
+ }
+ },
+ _onIronItemsChanged: function(event) {
+ if (event.detail.addedNodes.length) {
+ this._resetTabindices();
+ }
+ },
+ _onShiftTabDown: function(event) {
+ var oldTabIndex = this.getAttribute('tabindex');
+ Polymer.IronMenuBehaviorImpl._shiftTabPressed = true;
+ this._setFocusedItem(null);
+ this.setAttribute('tabindex', '-1');
+ this.async(function() {
+ this.setAttribute('tabindex', oldTabIndex);
+ Polymer.IronMenuBehaviorImpl._shiftTabPressed = false;
+ }, 1);
+ },
+ _onFocus: function(event) {
+ if (Polymer.IronMenuBehaviorImpl._shiftTabPressed) {
+ return;
+ }
+ var rootTarget = Polymer.dom(event).rootTarget;
+ if (rootTarget !== this && typeof rootTarget.tabIndex !== "undefined" && !this.isLightDescendant(rootTarget)) {
+ return;
+ }
+ this._defaultFocusAsync = this.async(function() {
+ var selectedItem = this.multi ? this.selectedItems && this.selectedItems[0] : this.selectedItem;
+ this._setFocusedItem(null);
+ if (selectedItem) {
+ this._setFocusedItem(selectedItem);
+ } else if (this.items[0]) {
+ this._focusNext();
+ }
+ });
+ },
+ _onUpKey: function(event) {
+ this._focusPrevious();
+ event.detail.keyboardEvent.preventDefault();
+ },
+ _onDownKey: function(event) {
+ this._focusNext();
+ event.detail.keyboardEvent.preventDefault();
+ },
+ _onEscKey: function(event) {
+ this.focusedItem.blur();
+ },
+ _onKeydown: function(event) {
+ if (!this.keyboardEventMatchesKeys(event, 'up down esc')) {
+ this._focusWithKeyboardEvent(event);
+ }
+ event.stopPropagation();
+ },
+ _activateHandler: function(event) {
+ Polymer.IronSelectableBehavior._activateHandler.call(this, event);
+ event.stopPropagation();
+ }
+};
+
+Polymer.IronMenuBehaviorImpl._shiftTabPressed = false;
+
+Polymer.IronMenuBehavior = [ Polymer.IronMultiSelectableBehavior, Polymer.IronA11yKeysBehavior, Polymer.IronMenuBehaviorImpl ];
+
+(function() {
+ Polymer({
+ is: 'paper-listbox',
+ behaviors: [ Polymer.IronMenuBehavior ],
+ hostAttributes: {
+ role: 'listbox'
+ }
+ });
+})();
+
Polymer({
is: 'paper-menu-grow-height-animation',
behaviors: [ Polymer.NeonAnimationBehavior ],
@@ -1889,7 +2065,6 @@ var SLIDE_CUBIC_BEZIER = 'cubic-bezier(0.3, 0.95, 0.5, 1)';
Polymer({
is: 'cr-shared-menu',
- behaviors: [ Polymer.IronA11yKeysBehavior ],
properties: {
menuOpen: {
type: Boolean,
@@ -1945,17 +2120,13 @@ Polymer({
}
}
},
- keyBindings: {
- tab: 'onTabPressed_'
- },
listeners: {
'dropdown.iron-overlay-canceled': 'onOverlayCanceled_'
},
lastAnchor_: null,
- firstFocus_: null,
- lastFocus_: null,
attached: function() {
window.addEventListener('resize', this.closeMenu.bind(this));
+ this.$.menu.addEventListener('keydown', this.onCaptureKeyDown_.bind(this), true);
},
closeMenu: function() {
if (this.root.activeElement == null) {
@@ -1969,26 +2140,19 @@ Polymer({
this.itemData = opt_itemData || null;
this.lastAnchor_ = anchor;
this.$.dropdown.restoreFocusOnClose = true;
- var focusableChildren = Polymer.dom(this).querySelectorAll('[tabindex]:not([disabled]):not([hidden]),' + 'button:not([disabled]):not([hidden])');
- if (focusableChildren.length > 0) {
- this.$.dropdown.focusTarget = focusableChildren[0];
- this.firstFocus_ = focusableChildren[0];
- this.lastFocus_ = focusableChildren[focusableChildren.length - 1];
- }
+ this.$.menu.selected = -1;
this.$.dropdown.positionTarget = anchor;
this.menuOpen = true;
},
toggleMenu: function(anchor, opt_itemData) {
if (anchor == this.lastAnchor_ && this.menuOpen) this.closeMenu(); else this.openMenu(anchor, opt_itemData);
},
- onTabPressed_: function(e) {
- if (!this.firstFocus_ || !this.lastFocus_) return;
- var toFocus;
- var keyEvent = e.detail.keyboardEvent;
- if (keyEvent.shiftKey && keyEvent.target == this.firstFocus_) toFocus = this.lastFocus_; else if (!keyEvent.shiftKey && keyEvent.target == this.lastFocus_) toFocus = this.firstFocus_;
- if (!toFocus) return;
- e.preventDefault();
- toFocus.focus();
+ onCaptureKeyDown_: function(e) {
+ if (Polymer.IronA11yKeysBehavior.keyboardEventMatchesKeys(e, 'tab')) {
+ this.$.dropdown.restoreFocusOnClose = false;
+ this.lastAnchor_.focus();
+ this.closeMenu();
+ }
},
menuOpenChanged_: function() {
if (!this.menuOpen) {
@@ -2789,172 +2953,6 @@ Polymer({
}
});
-Polymer.IronMenuBehaviorImpl = {
- properties: {
- focusedItem: {
- observer: '_focusedItemChanged',
- readOnly: true,
- type: Object
- },
- attrForItemTitle: {
- type: String
- }
- },
- hostAttributes: {
- role: 'menu',
- tabindex: '0'
- },
- observers: [ '_updateMultiselectable(multi)' ],
- listeners: {
- focus: '_onFocus',
- keydown: '_onKeydown',
- 'iron-items-changed': '_onIronItemsChanged'
- },
- keyBindings: {
- up: '_onUpKey',
- down: '_onDownKey',
- esc: '_onEscKey',
- 'shift+tab:keydown': '_onShiftTabDown'
- },
- attached: function() {
- this._resetTabindices();
- },
- select: function(value) {
- if (this._defaultFocusAsync) {
- this.cancelAsync(this._defaultFocusAsync);
- this._defaultFocusAsync = null;
- }
- var item = this._valueToItem(value);
- if (item && item.hasAttribute('disabled')) return;
- this._setFocusedItem(item);
- Polymer.IronMultiSelectableBehaviorImpl.select.apply(this, arguments);
- },
- _resetTabindices: function() {
- var selectedItem = this.multi ? this.selectedItems && this.selectedItems[0] : this.selectedItem;
- this.items.forEach(function(item) {
- item.setAttribute('tabindex', item === selectedItem ? '0' : '-1');
- }, this);
- },
- _updateMultiselectable: function(multi) {
- if (multi) {
- this.setAttribute('aria-multiselectable', 'true');
- } else {
- this.removeAttribute('aria-multiselectable');
- }
- },
- _focusWithKeyboardEvent: function(event) {
- for (var i = 0, item; item = this.items[i]; i++) {
- var attr = this.attrForItemTitle || 'textContent';
- var title = item[attr] || item.getAttribute(attr);
- if (!item.hasAttribute('disabled') && title && title.trim().charAt(0).toLowerCase() === String.fromCharCode(event.keyCode).toLowerCase()) {
- this._setFocusedItem(item);
- break;
- }
- }
- },
- _focusPrevious: function() {
- var length = this.items.length;
- var curFocusIndex = Number(this.indexOf(this.focusedItem));
- for (var i = 1; i < length + 1; i++) {
- var item = this.items[(curFocusIndex - i + length) % length];
- if (!item.hasAttribute('disabled')) {
- var owner = Polymer.dom(item).getOwnerRoot() || document;
- this._setFocusedItem(item);
- if (Polymer.dom(owner).activeElement == item) {
- return;
- }
- }
- }
- },
- _focusNext: function() {
- var length = this.items.length;
- var curFocusIndex = Number(this.indexOf(this.focusedItem));
- for (var i = 1; i < length + 1; i++) {
- var item = this.items[(curFocusIndex + i) % length];
- if (!item.hasAttribute('disabled')) {
- var owner = Polymer.dom(item).getOwnerRoot() || document;
- this._setFocusedItem(item);
- if (Polymer.dom(owner).activeElement == item) {
- return;
- }
- }
- }
- },
- _applySelection: function(item, isSelected) {
- if (isSelected) {
- item.setAttribute('aria-selected', 'true');
- } else {
- item.removeAttribute('aria-selected');
- }
- Polymer.IronSelectableBehavior._applySelection.apply(this, arguments);
- },
- _focusedItemChanged: function(focusedItem, old) {
- old && old.setAttribute('tabindex', '-1');
- if (focusedItem) {
- focusedItem.setAttribute('tabindex', '0');
- focusedItem.focus();
- }
- },
- _onIronItemsChanged: function(event) {
- if (event.detail.addedNodes.length) {
- this._resetTabindices();
- }
- },
- _onShiftTabDown: function(event) {
- var oldTabIndex = this.getAttribute('tabindex');
- Polymer.IronMenuBehaviorImpl._shiftTabPressed = true;
- this._setFocusedItem(null);
- this.setAttribute('tabindex', '-1');
- this.async(function() {
- this.setAttribute('tabindex', oldTabIndex);
- Polymer.IronMenuBehaviorImpl._shiftTabPressed = false;
- }, 1);
- },
- _onFocus: function(event) {
- if (Polymer.IronMenuBehaviorImpl._shiftTabPressed) {
- return;
- }
- var rootTarget = Polymer.dom(event).rootTarget;
- if (rootTarget !== this && typeof rootTarget.tabIndex !== "undefined" && !this.isLightDescendant(rootTarget)) {
- return;
- }
- this._defaultFocusAsync = this.async(function() {
- var selectedItem = this.multi ? this.selectedItems && this.selectedItems[0] : this.selectedItem;
- this._setFocusedItem(null);
- if (selectedItem) {
- this._setFocusedItem(selectedItem);
- } else if (this.items[0]) {
- this._focusNext();
- }
- });
- },
- _onUpKey: function(event) {
- this._focusPrevious();
- event.detail.keyboardEvent.preventDefault();
- },
- _onDownKey: function(event) {
- this._focusNext();
- event.detail.keyboardEvent.preventDefault();
- },
- _onEscKey: function(event) {
- this.focusedItem.blur();
- },
- _onKeydown: function(event) {
- if (!this.keyboardEventMatchesKeys(event, 'up down esc')) {
- this._focusWithKeyboardEvent(event);
- }
- event.stopPropagation();
- },
- _activateHandler: function(event) {
- Polymer.IronSelectableBehavior._activateHandler.call(this, event);
- event.stopPropagation();
- }
-};
-
-Polymer.IronMenuBehaviorImpl._shiftTabPressed = false;
-
-Polymer.IronMenuBehavior = [ Polymer.IronMultiSelectableBehavior, Polymer.IronA11yKeysBehavior, Polymer.IronMenuBehaviorImpl ];
-
Polymer.IronMenubarBehaviorImpl = {
hostAttributes: {
role: 'menubar'

Powered by Google App Engine
This is Rietveld 408576698