Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2011 Google Inc. All Rights Reserved. | 2 * Copyright (C) 2011 Google Inc. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 62 this._contextMenuElement.addEventListener('mouseup', e => e.consume(), false ); | 62 this._contextMenuElement.addEventListener('mouseup', e => e.consume(), false ); |
| 63 this._contextMenuElement.addEventListener('keydown', this._menuKeyDown.bind( this), false); | 63 this._contextMenuElement.addEventListener('keydown', this._menuKeyDown.bind( this), false); |
| 64 | 64 |
| 65 for (var i = 0; i < this._items.length; ++i) | 65 for (var i = 0; i < this._items.length; ++i) |
| 66 this._contextMenuElement.appendChild(this._createMenuItem(this._items[i])) ; | 66 this._contextMenuElement.appendChild(this._createMenuItem(this._items[i])) ; |
| 67 | 67 |
| 68 this._glassPane.show(document); | 68 this._glassPane.show(document); |
| 69 this._focus(); | 69 this._focus(); |
| 70 | 70 |
| 71 if (!this._parentMenu) { | 71 if (!this._parentMenu) { |
| 72 this._onBodyMouseDown = event => this._discardMenu(true, event); | 72 this._onBodyMouseDown = event => { |
| 73 this.discard(); | |
| 74 event.consume(true); | |
| 75 }; | |
| 73 this._document.body.addEventListener('mousedown', this._onBodyMouseDown, f alse); | 76 this._document.body.addEventListener('mousedown', this._onBodyMouseDown, f alse); |
| 74 } | 77 } |
| 75 } | 78 } |
| 76 | 79 |
| 77 discard() { | 80 discard() { |
| 78 this._discardMenu(true); | 81 if (this._subMenu) |
| 82 this._subMenu._discardSubMenus(); | |
|
dgozman
2017/04/18 18:40:20
You removed this method.
einbinder
2017/04/18 23:47:02
Fixed
| |
| 83 if (this._focusRestorer) | |
| 84 this._focusRestorer.restore(); | |
| 85 if (this._glassPane) { | |
| 86 this._glassPane.hide(); | |
| 87 delete this._glassPane; | |
| 88 if (this._onBodyMouseDown) { | |
| 89 this._document.body.removeEventListener('mousedown', this._onBodyMouseDo wn, false); | |
| 90 delete this._onBodyMouseDown; | |
| 91 } | |
| 92 } | |
| 93 if (this._parentMenu) | |
| 94 delete this._parentMenu._subMenu; | |
| 79 } | 95 } |
| 80 | 96 |
| 81 _createMenuItem(item) { | 97 _createMenuItem(item) { |
| 82 if (item.type === 'separator') | 98 if (item.type === 'separator') |
| 83 return this._createSeparator(); | 99 return this._createSeparator(); |
| 84 | 100 |
| 85 if (item.type === 'subMenu') | 101 if (item.type === 'subMenu') |
| 86 return this._createSubMenu(item); | 102 return this._createSubMenu(item); |
| 87 | 103 |
| 88 var menuItemElement = createElementWithClass('div', 'soft-context-menu-item' ); | 104 var menuItemElement = createElementWithClass('div', 'soft-context-menu-item' ); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 149 _menuItemMouseDown(event) { | 165 _menuItemMouseDown(event) { |
| 150 // Do not let separator's mouse down hit menu's handler - we need to receive mouse up! | 166 // Do not let separator's mouse down hit menu's handler - we need to receive mouse up! |
| 151 event.consume(true); | 167 event.consume(true); |
| 152 } | 168 } |
| 153 | 169 |
| 154 _menuItemMouseUp(event) { | 170 _menuItemMouseUp(event) { |
| 155 this._triggerAction(event.target, event); | 171 this._triggerAction(event.target, event); |
| 156 event.consume(); | 172 event.consume(); |
| 157 } | 173 } |
| 158 | 174 |
| 175 /** | |
| 176 * @return {!UI.SoftContextMenu} | |
| 177 */ | |
| 178 _root() { | |
| 179 var root = this; | |
| 180 while (root._parentMenu) | |
| 181 root = root._parentMenu; | |
| 182 return root; | |
| 183 } | |
| 184 | |
| 159 _focus() { | 185 _focus() { |
|
dgozman
2017/04/18 18:40:20
Does anyone call this? Inline into show?
einbinder
2017/04/18 23:47:02
Inlined.
| |
| 160 this._contextMenuElement.focus(); | 186 this._focusRestorer = new UI.ElementFocusRestorer(this._contextMenuElement); |
| 161 } | 187 } |
| 162 | 188 |
| 163 _triggerAction(menuItemElement, event) { | 189 _triggerAction(menuItemElement, event) { |
| 164 if (!menuItemElement._subItems) { | 190 if (!menuItemElement._subItems) { |
| 165 this._discardMenu(true, event); | 191 this._root().discard(); |
| 192 event.consume(true); | |
| 166 if (typeof menuItemElement._actionId !== 'undefined') { | 193 if (typeof menuItemElement._actionId !== 'undefined') { |
| 167 this._itemSelectedCallback(menuItemElement._actionId); | 194 this._itemSelectedCallback(menuItemElement._actionId); |
| 168 delete menuItemElement._actionId; | 195 delete menuItemElement._actionId; |
| 169 } | 196 } |
| 170 return; | 197 return; |
| 171 } | 198 } |
| 172 | 199 |
| 173 this._showSubMenu(menuItemElement); | 200 this._showSubMenu(menuItemElement); |
| 174 event.consume(); | 201 event.consume(); |
| 175 } | 202 } |
| 176 | 203 |
| 177 _showSubMenu(menuItemElement) { | 204 _showSubMenu(menuItemElement) { |
| 178 if (menuItemElement._subMenuTimer) { | 205 if (menuItemElement._subMenuTimer) { |
| 179 clearTimeout(menuItemElement._subMenuTimer); | 206 clearTimeout(menuItemElement._subMenuTimer); |
| 180 delete menuItemElement._subMenuTimer; | 207 delete menuItemElement._subMenuTimer; |
| 181 } | 208 } |
| 182 if (this._subMenu) | 209 if (this._subMenu) |
| 183 return; | 210 return; |
| 184 | 211 |
| 185 this._subMenu = new UI.SoftContextMenu(menuItemElement._subItems, this._item SelectedCallback, this); | 212 this._subMenu = new UI.SoftContextMenu(menuItemElement._subItems, this._item SelectedCallback, this); |
| 186 var anchorBox = menuItemElement.boxInWindow(); | 213 var anchorBox = menuItemElement.boxInWindow(); |
| 187 // Adjust for padding. | 214 // Adjust for padding. |
| 188 anchorBox.y -= 5; | 215 anchorBox.y -= 5; |
| 189 anchorBox.x += 3; | 216 anchorBox.x += 3; |
| 190 anchorBox.width -= 6; | 217 anchorBox.width -= 6; |
| 191 anchorBox.height += 10; | 218 anchorBox.height += 10; |
| 192 this._subMenu.show(this._document, anchorBox); | 219 this._subMenu.show(this._document, anchorBox); |
| 193 } | 220 } |
| 194 | 221 |
| 195 _hideSubMenu() { | |
| 196 if (!this._subMenu) | |
| 197 return; | |
| 198 this._subMenu._discardSubMenus(); | |
| 199 this._focus(); | |
| 200 } | |
| 201 | |
| 202 _menuItemMouseOver(event) { | 222 _menuItemMouseOver(event) { |
| 203 this._highlightMenuItem(event.target, true); | 223 this._highlightMenuItem(event.target, true); |
| 204 } | 224 } |
| 205 | 225 |
| 206 _menuItemMouseLeave(event) { | 226 _menuItemMouseLeave(event) { |
| 207 if (!this._subMenu || !event.relatedTarget) { | 227 if (!this._subMenu || !event.relatedTarget) { |
| 208 this._highlightMenuItem(null, true); | 228 this._highlightMenuItem(null, true); |
| 209 return; | 229 return; |
| 210 } | 230 } |
| 211 | 231 |
| 212 var relatedTarget = event.relatedTarget; | 232 var relatedTarget = event.relatedTarget; |
| 213 if (relatedTarget === this._contextMenuElement) | 233 if (relatedTarget === this._contextMenuElement) |
| 214 this._highlightMenuItem(null, true); | 234 this._highlightMenuItem(null, true); |
| 215 } | 235 } |
| 216 | 236 |
| 217 /** | 237 /** |
| 218 * @param {?Element} menuItemElement | 238 * @param {?Element} menuItemElement |
| 219 * @param {boolean} scheduleSubMenu | 239 * @param {boolean} scheduleSubMenu |
| 220 */ | 240 */ |
| 221 _highlightMenuItem(menuItemElement, scheduleSubMenu) { | 241 _highlightMenuItem(menuItemElement, scheduleSubMenu) { |
| 222 if (this._highlightedMenuItemElement === menuItemElement) | 242 if (this._highlightedMenuItemElement === menuItemElement) |
| 223 return; | 243 return; |
| 224 | 244 |
| 225 this._hideSubMenu(); | 245 if (this._subMenu) |
| 246 this._subMenu.discard(); | |
| 226 if (this._highlightedMenuItemElement) { | 247 if (this._highlightedMenuItemElement) { |
| 227 this._highlightedMenuItemElement.classList.remove('force-white-icons'); | 248 this._highlightedMenuItemElement.classList.remove('force-white-icons'); |
| 228 this._highlightedMenuItemElement.classList.remove('soft-context-menu-item- mouse-over'); | 249 this._highlightedMenuItemElement.classList.remove('soft-context-menu-item- mouse-over'); |
| 229 if (this._highlightedMenuItemElement._subItems && this._highlightedMenuIte mElement._subMenuTimer) { | 250 if (this._highlightedMenuItemElement._subItems && this._highlightedMenuIte mElement._subMenuTimer) { |
| 230 clearTimeout(this._highlightedMenuItemElement._subMenuTimer); | 251 clearTimeout(this._highlightedMenuItemElement._subMenuTimer); |
| 231 delete this._highlightedMenuItemElement._subMenuTimer; | 252 delete this._highlightedMenuItemElement._subMenuTimer; |
| 232 } | 253 } |
| 233 } | 254 } |
| 234 this._highlightedMenuItemElement = menuItemElement; | 255 this._highlightedMenuItemElement = menuItemElement; |
| 235 if (this._highlightedMenuItemElement) { | 256 if (this._highlightedMenuItemElement) { |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 266 switch (event.key) { | 287 switch (event.key) { |
| 267 case 'ArrowUp': | 288 case 'ArrowUp': |
| 268 this._highlightPrevious(); | 289 this._highlightPrevious(); |
| 269 break; | 290 break; |
| 270 case 'ArrowDown': | 291 case 'ArrowDown': |
| 271 this._highlightNext(); | 292 this._highlightNext(); |
| 272 break; | 293 break; |
| 273 case 'ArrowLeft': | 294 case 'ArrowLeft': |
| 274 if (this._parentMenu) { | 295 if (this._parentMenu) { |
| 275 this._highlightMenuItem(null, false); | 296 this._highlightMenuItem(null, false); |
| 276 this._parentMenu._hideSubMenu(); | 297 this.discard(); |
| 277 } | 298 } |
| 278 break; | 299 break; |
| 279 case 'ArrowRight': | 300 case 'ArrowRight': |
| 280 if (!this._highlightedMenuItemElement) | 301 if (!this._highlightedMenuItemElement) |
| 281 break; | 302 break; |
| 282 if (this._highlightedMenuItemElement._subItems) { | 303 if (this._highlightedMenuItemElement._subItems) { |
| 283 this._showSubMenu(this._highlightedMenuItemElement); | 304 this._showSubMenu(this._highlightedMenuItemElement); |
| 284 this._subMenu._focus(); | |
| 285 this._subMenu._highlightNext(); | 305 this._subMenu._highlightNext(); |
| 286 } | 306 } |
| 287 break; | 307 break; |
| 288 case 'Escape': | 308 case 'Escape': |
| 289 this._discardMenu(false, event); | 309 this.discard(); |
| 290 break; | 310 break; |
| 291 case 'Enter': | 311 case 'Enter': |
| 292 if (!isEnterKey(event)) | 312 if (!isEnterKey(event)) |
| 293 break; | 313 break; |
| 294 // Fall through | 314 // Fall through |
| 295 case ' ': // Space | 315 case ' ': // Space |
| 296 if (this._highlightedMenuItemElement) | 316 if (this._highlightedMenuItemElement) |
| 297 this._triggerAction(this._highlightedMenuItemElement, event); | 317 this._triggerAction(this._highlightedMenuItemElement, event); |
| 298 if (this._highlightedMenuItemElement._subItems) { | 318 if (this._highlightedMenuItemElement._subItems) { |
| 299 this._subMenu._focus(); | 319 this._subMenu._focus(); |
|
dgozman
2017/04/18 18:40:20
Let's double-check this.
| |
| 300 this._subMenu._highlightNext(); | 320 this._subMenu._highlightNext(); |
| 301 } | 321 } |
| 302 break; | 322 break; |
| 303 } | 323 } |
| 304 event.consume(true); | 324 event.consume(true); |
| 305 } | 325 } |
| 306 | |
| 307 /** | |
| 308 * @param {boolean} closeParentMenus | |
| 309 * @param {!Event=} event | |
| 310 */ | |
| 311 _discardMenu(closeParentMenus, event) { | |
| 312 if (this._subMenu && !closeParentMenus) | |
| 313 return; | |
| 314 | |
| 315 this._discardSubMenus(); | |
| 316 | |
| 317 if (this._parentMenu) { | |
| 318 if (closeParentMenus) | |
| 319 this._parentMenu._discardMenu(closeParentMenus, event); | |
| 320 else | |
| 321 this._parentMenu._focus(); | |
| 322 } | |
| 323 | |
| 324 if (event) | |
| 325 event.consume(true); | |
| 326 } | |
| 327 | |
| 328 _discardSubMenus() { | |
| 329 if (this._subMenu) | |
| 330 this._subMenu._discardSubMenus(); | |
| 331 if (this._glassPane) { | |
| 332 this._glassPane.hide(); | |
| 333 delete this._glassPane; | |
| 334 if (this._onBodyMouseDown) { | |
| 335 this._document.body.removeEventListener('mousedown', this._onBodyMouseDo wn, false); | |
| 336 delete this._onBodyMouseDown; | |
| 337 } | |
| 338 } | |
| 339 if (this._parentMenu) | |
| 340 delete this._parentMenu._subMenu; | |
| 341 } | |
| 342 }; | 326 }; |
| OLD | NEW |