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 // <include src="../../assert.js"> | 5 // <include src="../../assert.js"> |
6 | 6 |
7 cr.exportPath('cr.ui'); | 7 cr.exportPath('cr.ui'); |
8 | 8 |
9 /** | 9 /** |
10 * Enum for type of hide. Delayed is used when called by clicking on a | 10 * Enum for type of hide. Delayed is used when called by clicking on a |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 this.hideMenu(hideDelayed ? HideType.DELAYED : HideType.INSTANT); | 147 this.hideMenu(hideDelayed ? HideType.DELAYED : HideType.INSTANT); |
148 break; | 148 break; |
149 case 'scroll': | 149 case 'scroll': |
150 if (!(e.target == this.menu || this.menu.contains(e.target))) | 150 if (!(e.target == this.menu || this.menu.contains(e.target))) |
151 this.hideMenu(); | 151 this.hideMenu(); |
152 break; | 152 break; |
153 case 'popstate': | 153 case 'popstate': |
154 case 'resize': | 154 case 'resize': |
155 this.hideMenu(); | 155 this.hideMenu(); |
156 break; | 156 break; |
| 157 case 'contextmenu': |
| 158 if ((!this.menu || !this.menu.contains(e.target)) && |
| 159 (!this.hideTimestamp_ || Date.now() - this.hideTimestamp_ > 50)) |
| 160 this.showMenu(true); |
| 161 e.preventDefault(); |
| 162 // Don't allow elements further up in the DOM to show their menus. |
| 163 e.stopPropagation(); |
| 164 break; |
157 } | 165 } |
158 }, | 166 }, |
159 | 167 |
160 /** | 168 /** |
161 * Shows the menu. | 169 * Shows the menu. |
162 * @param {boolean} shouldSetFocus Whether to set focus on the | 170 * @param {boolean} shouldSetFocus Whether to set focus on the |
163 * selected menu item. | 171 * selected menu item. |
164 */ | 172 */ |
165 showMenu: function(shouldSetFocus) { | 173 showMenu: function(shouldSetFocus) { |
166 this.hideMenu(); | 174 this.hideMenu(); |
(...skipping 12 matching lines...) Expand all Loading... |
179 | 187 |
180 // When the menu is shown we steal all keyboard events. | 188 // When the menu is shown we steal all keyboard events. |
181 var doc = this.ownerDocument; | 189 var doc = this.ownerDocument; |
182 var win = doc.defaultView; | 190 var win = doc.defaultView; |
183 this.showingEvents_.add(doc, 'keydown', this, true); | 191 this.showingEvents_.add(doc, 'keydown', this, true); |
184 this.showingEvents_.add(doc, 'mousedown', this, true); | 192 this.showingEvents_.add(doc, 'mousedown', this, true); |
185 this.showingEvents_.add(doc, 'focus', this, true); | 193 this.showingEvents_.add(doc, 'focus', this, true); |
186 this.showingEvents_.add(doc, 'scroll', this, true); | 194 this.showingEvents_.add(doc, 'scroll', this, true); |
187 this.showingEvents_.add(win, 'popstate', this); | 195 this.showingEvents_.add(win, 'popstate', this); |
188 this.showingEvents_.add(win, 'resize', this); | 196 this.showingEvents_.add(win, 'resize', this); |
| 197 this.showingEvents_.add(this.menu, 'contextmenu', this); |
189 this.showingEvents_.add(this.menu, 'activate', this); | 198 this.showingEvents_.add(this.menu, 'activate', this); |
190 this.positionMenu_(); | 199 this.positionMenu_(); |
191 | 200 |
192 if (shouldSetFocus) | 201 if (shouldSetFocus) |
193 this.menu.focusSelectedItem(); | 202 this.menu.focusSelectedItem(); |
194 }, | 203 }, |
195 | 204 |
196 /** | 205 /** |
197 * Hides the menu. If your menu can go out of scope, make sure to call this | 206 * Hides the menu. If your menu can go out of scope, make sure to call this |
198 * first. | 207 * first. |
199 * @param {cr.ui.HideType=} opt_hideType Type of hide. | 208 * @param {cr.ui.HideType=} opt_hideType Type of hide. |
200 * default: cr.ui.HideType.INSTANT. | 209 * default: cr.ui.HideType.INSTANT. |
201 */ | 210 */ |
202 hideMenu: function(opt_hideType) { | 211 hideMenu: function(opt_hideType) { |
203 if (!this.isMenuShown()) | 212 if (!this.isMenuShown()) |
204 return; | 213 return; |
205 | 214 |
206 this.removeAttribute('menu-shown'); | 215 this.removeAttribute('menu-shown'); |
207 if (opt_hideType == HideType.DELAYED) | 216 if (opt_hideType == HideType.DELAYED) |
208 this.menu.classList.add('hide-delayed'); | 217 this.menu.classList.add('hide-delayed'); |
209 else | 218 else |
210 this.menu.classList.remove('hide-delayed'); | 219 this.menu.classList.remove('hide-delayed'); |
211 this.menu.hidden = true; | 220 this.menu.hidden = true; |
212 | 221 |
213 this.showingEvents_.removeAll(); | 222 this.showingEvents_.removeAll(); |
214 this.focus(); | 223 this.focus(); |
| 224 |
| 225 // On windows we might hide the menu in a right mouse button up and if |
| 226 // that is the case we wait some short period before we allow the menu |
| 227 // to be shown again. |
| 228 this.hideTimestamp_ = cr.isWindows ? Date.now() : 0; |
215 }, | 229 }, |
216 | 230 |
217 /** | 231 /** |
218 * Whether the menu is shown. | 232 * Whether the menu is shown. |
219 */ | 233 */ |
220 isMenuShown: function() { | 234 isMenuShown: function() { |
221 return this.hasAttribute('menu-shown'); | 235 return this.hasAttribute('menu-shown'); |
222 }, | 236 }, |
223 | 237 |
224 /** | 238 /** |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 'drop-down-arrow-hover', ARROW_WIDTH, ARROW_HEIGHT, opt_hoverColor); | 313 'drop-down-arrow-hover', ARROW_WIDTH, ARROW_HEIGHT, opt_hoverColor); |
300 createDropDownArrowCanvas( | 314 createDropDownArrowCanvas( |
301 'drop-down-arrow-active', ARROW_WIDTH, ARROW_HEIGHT, opt_activeColor); | 315 'drop-down-arrow-active', ARROW_WIDTH, ARROW_HEIGHT, opt_activeColor); |
302 }; | 316 }; |
303 | 317 |
304 // Export | 318 // Export |
305 return { | 319 return { |
306 MenuButton: MenuButton, | 320 MenuButton: MenuButton, |
307 }; | 321 }; |
308 }); | 322 }); |
OLD | NEW |