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 14 matching lines...) Expand all Loading... |
25 * Element for which menu is being shown. | 25 * Element for which menu is being shown. |
26 */ | 26 */ |
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 this.addEventListener('mouseup', this.handleMouseUp_, true); |
35 | 36 |
36 this.classList.add('decorated'); | 37 this.classList.add('decorated'); |
37 this.setAttribute('role', 'menu'); | 38 this.setAttribute('role', 'menu'); |
38 this.hidden = true; // Hide the menu by default. | 39 this.hidden = true; // Hide the menu by default. |
39 | 40 |
40 // Decorate the children as menu items. | 41 // Decorate the children as menu items. |
41 var menuItems = this.menuItems; | 42 var menuItems = this.menuItems; |
42 for (var i = 0, menuItem; menuItem = menuItems[i]; i++) { | 43 for (var i = 0, menuItem; menuItem = menuItems[i]; i++) { |
43 cr.ui.decorate(menuItem, MenuItem); | 44 cr.ui.decorate(menuItem, MenuItem); |
44 } | 45 } |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 | 107 |
107 /** | 108 /** |
108 * Handles mouseout events and deselects any selected item. | 109 * Handles mouseout events and deselects any selected item. |
109 * @param {Event} e The mouseout event. | 110 * @param {Event} e The mouseout event. |
110 * @private | 111 * @private |
111 */ | 112 */ |
112 handleMouseOut_: function(e) { | 113 handleMouseOut_: function(e) { |
113 this.selectedItem = null; | 114 this.selectedItem = null; |
114 }, | 115 }, |
115 | 116 |
| 117 /** |
| 118 * If there's a mouseup that happens quickly in about the same position, |
| 119 * stop it from propagating to items. This is to prevent accidentally |
| 120 * selecting a menu item that's created under the mouse cursor. |
| 121 * @param {Event} e A mouseup event on the menu (in capturing phase). |
| 122 * @private |
| 123 */ |
| 124 handleMouseUp_: function(e) { |
| 125 assert(this.contains(/** @type {Element} */(e.target))); |
| 126 |
| 127 if (!this.trustEvent_(e) || Date.now() - this.shown_.time > 200) |
| 128 return; |
| 129 |
| 130 var pos = this.shown_.mouseDownPos; |
| 131 if (!pos || Math.abs(pos.x - e.screenX) + Math.abs(pos.y - e.screenY) > 4) |
| 132 return; |
| 133 |
| 134 e.preventDefault(); |
| 135 e.stopPropagation(); |
| 136 }, |
| 137 |
| 138 /** |
| 139 * @param {!Event} e |
| 140 * @return {boolean} Whether |e| can be trusted. |
| 141 * @private |
| 142 * @suppress {checkTypes} |
| 143 */ |
| 144 trustEvent_: function(e) { |
| 145 return e.isTrusted || e.isTrustedForTesting; |
| 146 }, |
| 147 |
116 get menuItems() { | 148 get menuItems() { |
117 return this.querySelectorAll(this.menuItemSelector || '*'); | 149 return this.querySelectorAll(this.menuItemSelector || '*'); |
118 }, | 150 }, |
119 | 151 |
120 /** | 152 /** |
121 * The selected menu item or null if none. | 153 * The selected menu item or null if none. |
122 * @type {cr.ui.MenuItem} | 154 * @type {cr.ui.MenuItem} |
123 */ | 155 */ |
124 get selectedItem() { | 156 get selectedItem() { |
125 return this.menuItems[this.selectedIndex]; | 157 return this.menuItems[this.selectedIndex]; |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 if (item.command) | 263 if (item.command) |
232 item.command.execute(contextElement); | 264 item.command.execute(contextElement); |
233 } | 265 } |
234 } | 266 } |
235 return true; | 267 return true; |
236 } | 268 } |
237 | 269 |
238 return false; | 270 return false; |
239 }, | 271 }, |
240 | 272 |
| 273 hide: function() { |
| 274 this.hidden = true; |
| 275 delete this.shown_; |
| 276 }, |
| 277 |
| 278 /** @param {{x: number, y: number}=} opt_mouseDownPos */ |
| 279 show: function(opt_mouseDownPos) { |
| 280 this.shown_ = {mouseDownPos: opt_mouseDownPos, time: Date.now()}; |
| 281 this.hidden = false; |
| 282 }, |
| 283 |
241 /** | 284 /** |
242 * Updates menu items command according to context. | 285 * Updates menu items command according to context. |
243 * @param {Node=} node Node for which to actuate commands state. | 286 * @param {Node=} node Node for which to actuate commands state. |
244 */ | 287 */ |
245 updateCommands: function(node) { | 288 updateCommands: function(node) { |
246 var menuItems = this.menuItems; | 289 var menuItems = this.menuItems; |
247 | 290 |
248 for (var i = 0, menuItem; menuItem = menuItems[i]; i++) { | 291 for (var i = 0, menuItem; menuItem = menuItems[i]; i++) { |
249 if (!menuItem.isSeparator()) | 292 if (!menuItem.isSeparator()) |
250 menuItem.updateCommand(node); | 293 menuItem.updateCommand(node); |
(...skipping 22 matching lines...) Expand all Loading... |
273 /** | 316 /** |
274 * Selector for children which are menu items. | 317 * Selector for children which are menu items. |
275 */ | 318 */ |
276 cr.defineProperty(Menu, 'menuItemSelector', cr.PropertyKind.ATTR); | 319 cr.defineProperty(Menu, 'menuItemSelector', cr.PropertyKind.ATTR); |
277 | 320 |
278 // Export | 321 // Export |
279 return { | 322 return { |
280 Menu: Menu | 323 Menu: Menu |
281 }; | 324 }; |
282 }); | 325 }); |
OLD | NEW |