Service workers: Allow HTTPS pages arrived at via HTTP redirect to use SW
[chromium-blink-merge.git] / third_party / polymer / v1_0 / components-chromium / iron-menu-behavior / iron-menu-behavior-extracted.js
bloba604a0b3df4bf123a6bcb40aee5eef9d5bab0d83
1 /**
2    * `Polymer.IronMenuBehavior` implements accessible menu behavior.
3    *
4    * @demo demo/index.html
5    * @polymerBehavior Polymer.IronMenuBehavior
6    */
7   Polymer.IronMenuBehaviorImpl = {
9     properties: {
11       /**
12        * Returns the currently focused item.
13        *
14        * @attribute focusedItem
15        * @type Object
16        */
17       focusedItem: {
18         observer: '_focusedItemChanged',
19         readOnly: true,
20         type: Object
21       },
23       /**
24        * The attribute to use on menu items to look up the item title. Typing the first
25        * letter of an item when the menu is open focuses that item. If unset, `textContent`
26        * will be used.
27        *
28        * @attribute attrForItemTitle
29        * @type String
30        */
31       attrForItemTitle: {
32         type: String
33       }
34     },
36     hostAttributes: {
37       'role': 'menu',
38       'tabindex': '0'
39     },
41     observers: [
42       '_updateMultiselectable(multi)'
43     ],
45     listeners: {
46       'focus': '_onFocus',
47       'keydown': '_onKeydown'
48     },
50     keyBindings: {
51       'up': '_onUpKey',
52       'down': '_onDownKey',
53       'esc': '_onEscKey',
54       'enter': '_onEnterKey',
55       'shift+tab:keydown': '_onShiftTabDown'
56     },
58     _updateMultiselectable: function(multi) {
59       if (multi) {
60         this.setAttribute('aria-multiselectable', 'true');
61       } else {
62         this.removeAttribute('aria-multiselectable');
63       }
64     },
66     _onShiftTabDown: function() {
67       var oldTabIndex;
69       Polymer.IronMenuBehaviorImpl._shiftTabPressed = true;
71       oldTabIndex = this.getAttribute('tabindex');
73       this.setAttribute('tabindex', '-1');
75       this.async(function() {
76         this.setAttribute('tabindex', oldTabIndex);
77         Polymer.IronMenuBehaviorImpl._shiftTabPressed = false;
78       // Note: polymer/polymer#1305
79       }, 1);
80     },
82     _applySelection: function(item, isSelected) {
83       if (isSelected) {
84         item.setAttribute('aria-selected', 'true');
85       } else {
86         item.removeAttribute('aria-selected');
87       }
89       Polymer.IronSelectableBehavior._applySelection.apply(this, arguments);
90     },
92     _focusedItemChanged: function(focusedItem, old) {
93       old && old.setAttribute('tabindex', '-1');
94       if (focusedItem) {
95         focusedItem.setAttribute('tabindex', '0');
96         focusedItem.focus();
97       }
98     },
100     select: function(value) {
101       if (this._defaultFocusAsync) {
102         this.cancelAsync(this._defaultFocusAsync);
103         this._defaultFocusAsync = null;
104       }
105       var item = this._valueToItem(value);
106       this._setFocusedItem(item);
107       Polymer.IronMultiSelectableBehaviorImpl.select.apply(this, arguments);
108     },
110     _onFocus: function(event) {
111       if (Polymer.IronMenuBehaviorImpl._shiftTabPressed) {
112         return;
113       }
114       // do not focus the menu itself
115       this.blur();
116       // clear the cached focus item
117       this._setFocusedItem(null);
118       this._defaultFocusAsync = this.async(function() {
119         // focus the selected item when the menu receives focus, or the first item
120         // if no item is selected
121         var selectedItem = this.multi ? (this.selectedItems && this.selectedItems[0]) : this.selectedItem;
122         if (selectedItem) {
123           this._setFocusedItem(selectedItem);
124         } else {
125           this._setFocusedItem(this.items[0]);
126         }
127       // async 100ms to wait for `select` to get called from `_itemActivate`
128       }, 100);
129     },
131     _onUpKey: function() {
132       // up and down arrows moves the focus
133       this._focusPrevious();
134     },
136     _onDownKey: function() {
137       this._focusNext();
138     },
140     _onEscKey: function() {
141       // esc blurs the control
142       this.focusedItem.blur();
143     },
145     _onEnterKey: function(event) {
146       // enter activates the item unless it is disabled
147       this._activateFocused(event.detail.keyboardEvent);
148     },
150     _onKeydown: function(event) {
151       if (this.keyboardEventMatchesKeys(event, 'up down esc enter')) {
152         return;
153       }
155       // all other keys focus the menu item starting with that character
156       this._focusWithKeyboardEvent(event);
157     },
159     _focusWithKeyboardEvent: function(event) {
160       for (var i = 0, item; item = this.items[i]; i++) {
161         var attr = this.attrForItemTitle || 'textContent';
162         var title = item[attr] || item.getAttribute(attr);
163         if (title && title.trim().charAt(0).toLowerCase() === String.fromCharCode(event.keyCode).toLowerCase()) {
164           this._setFocusedItem(item);
165           break;
166         }
167       }
168     },
170     _activateFocused: function(event) {
171       if (!this.focusedItem.hasAttribute('disabled')) {
172         this._activateHandler(event);
173       }
174     },
176     _focusPrevious: function() {
177       var length = this.items.length;
178       var index = (Number(this.indexOf(this.focusedItem)) - 1 + length) % length;
179       this._setFocusedItem(this.items[index]);
180     },
182     _focusNext: function() {
183       var index = (Number(this.indexOf(this.focusedItem)) + 1) % this.items.length;
184       this._setFocusedItem(this.items[index]);
185     }
187   };
189   Polymer.IronMenuBehaviorImpl._shiftTabPressed = false;
191   /** @polymerBehavior Polymer.IronMenuBehavior */
192   Polymer.IronMenuBehavior = [
193     Polymer.IronMultiSelectableBehavior,
194     Polymer.IronA11yKeysBehavior,
195     Polymer.IronMenuBehaviorImpl
196   ];