| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 cr.define('cr.ui', function() { | 5 cr.define('cr.ui', function() { |
| 6 | 6 |
| 7 /** @const */ var MenuItem = cr.ui.MenuItem; | 7 /** @const */ var MenuItem = cr.ui.MenuItem; |
| 8 | 8 |
| 9 /** | 9 /** |
| 10 * Creates a new menu element. Menu dispatches all commands on the element it | 10 * Creates a new menu element. Menu dispatches all commands on the element it |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 contextElement: null, | 27 contextElement: null, |
| 28 | 28 |
| 29 /** | 29 /** |
| 30 * Initializes the menu element. | 30 * Initializes the menu element. |
| 31 */ | 31 */ |
| 32 decorate: function() { | 32 decorate: function() { |
| 33 this.addEventListener('mouseover', this.handleMouseOver_); | 33 this.addEventListener('mouseover', this.handleMouseOver_); |
| 34 this.addEventListener('mouseout', this.handleMouseOut_); | 34 this.addEventListener('mouseout', this.handleMouseOut_); |
| 35 | 35 |
| 36 this.classList.add('decorated'); | 36 this.classList.add('decorated'); |
| 37 this.setAttribute('role', 'menu'); |
| 37 this.hidden = true; // Hide the menu by default. | 38 this.hidden = true; // Hide the menu by default. |
| 38 | 39 |
| 39 // Decorate the children as menu items. | 40 // Decorate the children as menu items. |
| 40 var children = this.children; | 41 var children = this.children; |
| 41 for (var i = 0, child; child = children[i]; i++) { | 42 for (var i = 0, child; child = children[i]; i++) { |
| 42 cr.ui.decorate(child, MenuItem); | 43 cr.ui.decorate(child, MenuItem); |
| 43 } | 44 } |
| 44 }, | 45 }, |
| 45 | 46 |
| 46 /** | 47 /** |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 */ | 118 */ |
| 118 get selectedItem() { | 119 get selectedItem() { |
| 119 return this.children[this.selectedIndex]; | 120 return this.children[this.selectedIndex]; |
| 120 }, | 121 }, |
| 121 set selectedItem(item) { | 122 set selectedItem(item) { |
| 122 var index = Array.prototype.indexOf.call(this.children, item); | 123 var index = Array.prototype.indexOf.call(this.children, item); |
| 123 this.selectedIndex = index; | 124 this.selectedIndex = index; |
| 124 }, | 125 }, |
| 125 | 126 |
| 126 /** | 127 /** |
| 128 * Focuses the selected item. If selectedIndex is invalid, set it to 0 |
| 129 * first. |
| 130 */ |
| 131 focusSelectedItem: function() { |
| 132 if (this.selectedIndex < 0 || |
| 133 this.selectedIndex > this.children.length) { |
| 134 this.selectedIndex = 0; |
| 135 } |
| 136 |
| 137 if (this.selectedItem) |
| 138 this.selectedItem.focus(); |
| 139 }, |
| 140 |
| 141 /** |
| 127 * Menu length | 142 * Menu length |
| 128 */ | 143 */ |
| 129 get length() { | 144 get length() { |
| 130 return this.children.length; | 145 return this.children.length; |
| 131 }, | 146 }, |
| 132 | 147 |
| 133 /** | 148 /** |
| 134 * This is the function that handles keyboard navigation. This is usually | 149 * This is the function that handles keyboard navigation. This is usually |
| 135 * called by the element responsible for managing the menu. | 150 * called by the element responsible for managing the menu. |
| 136 * @param {Event} e The keydown event object. | 151 * @param {Event} e The keydown event object. |
| (...skipping 29 matching lines...) Expand all Loading... |
| 166 if (item && !item.isSeparator() && !item.hidden && !item.disabled) | 181 if (item && !item.isSeparator() && !item.hidden && !item.disabled) |
| 167 break; | 182 break; |
| 168 } | 183 } |
| 169 if (item && !item.disabled) | 184 if (item && !item.disabled) |
| 170 self.selectedIndex = i; | 185 self.selectedIndex = i; |
| 171 } | 186 } |
| 172 | 187 |
| 173 switch (e.keyIdentifier) { | 188 switch (e.keyIdentifier) { |
| 174 case 'Down': | 189 case 'Down': |
| 175 selectNextAvailable(1); | 190 selectNextAvailable(1); |
| 191 this.focusSelectedItem(); |
| 176 return true; | 192 return true; |
| 177 case 'Up': | 193 case 'Up': |
| 178 selectNextAvailable(-1); | 194 selectNextAvailable(-1); |
| 195 this.focusSelectedItem(); |
| 179 return true; | 196 return true; |
| 180 case 'Enter': | 197 case 'Enter': |
| 181 case 'U+0020': // Space | 198 case 'U+0020': // Space |
| 182 if (item) { | 199 if (item) { |
| 183 if (cr.dispatchSimpleEvent(item, 'activate', true, true)) { | 200 var activationEvent = cr.doc.createEvent('Event'); |
| 201 activationEvent.initEvent('activate', true, true); |
| 202 activationEvent.originalEvent = e; |
| 203 if (item.dispatchEvent(activationEvent)) { |
| 184 if (item.command) | 204 if (item.command) |
| 185 item.command.execute(); | 205 item.command.execute(); |
| 186 } | 206 } |
| 187 } | 207 } |
| 188 return true; | 208 return true; |
| 189 } | 209 } |
| 190 | 210 |
| 191 return false; | 211 return false; |
| 192 }, | 212 }, |
| 193 | 213 |
| 194 /** | 214 /** |
| 195 * Updates menu items command according to context. | 215 * Updates menu items command according to context. |
| 196 * @param {Node=} node Node for which to actuate commands state. | 216 * @param {Node=} node Node for which to actuate commands state. |
| 197 */ | 217 */ |
| 198 updateCommands: function(node) { | 218 updateCommands: function(node) { |
| 199 var children = this.children; | 219 var children = this.children; |
| 200 | 220 |
| 201 for (var i = 0, child; child = children[i]; i++) | 221 for (var i = 0, child; child = children[i]; i++) |
| 202 child.updateCommand(node); | 222 child.updateCommand(node); |
| 203 } | 223 } |
| 204 }; | 224 }; |
| 205 | 225 |
| 206 function selectedIndexChanged(selectedIndex, oldSelectedIndex) { | 226 function selectedIndexChanged(selectedIndex, oldSelectedIndex) { |
| 207 var oldSelectedItem = this.children[oldSelectedIndex]; | 227 var oldSelectedItem = this.children[oldSelectedIndex]; |
| 208 if (oldSelectedItem) | 228 if (oldSelectedItem) { |
| 209 oldSelectedItem.selected = false; | 229 oldSelectedItem.selected = false; |
| 230 oldSelectedItem.blur(); |
| 231 } |
| 210 var item = this.selectedItem; | 232 var item = this.selectedItem; |
| 211 if (item) | 233 if (item) |
| 212 item.selected = true; | 234 item.selected = true; |
| 213 } | 235 } |
| 214 | 236 |
| 215 /** | 237 /** |
| 216 * The selected menu item. | 238 * The selected menu item. |
| 217 * @type {number} | 239 * @type {number} |
| 218 */ | 240 */ |
| 219 cr.defineProperty(Menu, 'selectedIndex', cr.PropertyKind.JS, | 241 cr.defineProperty(Menu, 'selectedIndex', cr.PropertyKind.JS, |
| 220 selectedIndexChanged); | 242 selectedIndexChanged); |
| 221 | 243 |
| 222 // Export | 244 // Export |
| 223 return { | 245 return { |
| 224 Menu: Menu | 246 Menu: Menu |
| 225 }; | 247 }; |
| 226 }); | 248 }); |
| OLD | NEW |