Fix the cyclic reference in menu delegate (#11967)
* Fix the cyclic reference in menu delegate * Fix menu tests due to delegate change
This commit is contained in:
parent
e1b81b8a62
commit
dc62e51ba4
6 changed files with 61 additions and 43 deletions
|
@ -11,36 +11,39 @@ let groupIdIndex = 0
|
|||
|
||||
Object.setPrototypeOf(Menu.prototype, EventEmitter.prototype)
|
||||
|
||||
// Menu Delegate.
|
||||
// This object should hold no reference to |Menu| to avoid cyclic reference.
|
||||
const delegate = {
|
||||
isCommandIdChecked: (menu, id) => menu.commandsMap[id] ? menu.commandsMap[id].checked : undefined,
|
||||
isCommandIdEnabled: (menu, id) => menu.commandsMap[id] ? menu.commandsMap[id].enabled : undefined,
|
||||
isCommandIdVisible: (menu, id) => menu.commandsMap[id] ? menu.commandsMap[id].visible : undefined,
|
||||
getAcceleratorForCommandId: (menu, id, useDefaultAccelerator) => {
|
||||
const command = menu.commandsMap[id]
|
||||
if (!command) return
|
||||
if (command.accelerator) return command.accelerator
|
||||
if (useDefaultAccelerator) return command.getDefaultRoleAccelerator()
|
||||
},
|
||||
executeCommand: (menu, event, id) => {
|
||||
const command = menu.commandsMap[id]
|
||||
if (!command) return
|
||||
command.click(event, BrowserWindow.getFocusedWindow(), webContents.getFocusedWebContents())
|
||||
},
|
||||
menuWillShow: (menu) => {
|
||||
// Ensure radio groups have at least one menu item seleted
|
||||
for (const id in menu.groupsMap) {
|
||||
const found = menu.groupsMap[id].find(item => item.checked) || null
|
||||
if (!found) v8Util.setHiddenValue(menu.groupsMap[id][0], 'checked', true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Instance Methods */
|
||||
|
||||
Menu.prototype._init = function () {
|
||||
this.commandsMap = {}
|
||||
this.groupsMap = {}
|
||||
this.items = []
|
||||
this.delegate = {
|
||||
isCommandIdChecked: id => this.commandsMap[id] ? this.commandsMap[id].checked : undefined,
|
||||
isCommandIdEnabled: id => this.commandsMap[id] ? this.commandsMap[id].enabled : undefined,
|
||||
isCommandIdVisible: id => this.commandsMap[id] ? this.commandsMap[id].visible : undefined,
|
||||
getAcceleratorForCommandId: (id, useDefaultAccelerator) => {
|
||||
const command = this.commandsMap[id]
|
||||
if (!command) return
|
||||
if (command.accelerator) return command.accelerator
|
||||
if (useDefaultAccelerator) return command.getDefaultRoleAccelerator()
|
||||
},
|
||||
getIconForCommandId: id => this.commandsMap[id] ? this.commandsMap[id].icon : undefined,
|
||||
executeCommand: (event, id) => {
|
||||
const command = this.commandsMap[id]
|
||||
if (!command) return
|
||||
command.click(event, BrowserWindow.getFocusedWindow(), webContents.getFocusedWebContents())
|
||||
},
|
||||
menuWillShow: () => {
|
||||
// Ensure radio groups have at least one menu item seleted
|
||||
for (const id in this.groupsMap) {
|
||||
const found = this.groupsMap[id].find(item => item.checked) || null
|
||||
if (!found) v8Util.setHiddenValue(this.groupsMap[id][0], 'checked', true)
|
||||
}
|
||||
}
|
||||
}
|
||||
this.delegate = delegate
|
||||
}
|
||||
|
||||
Menu.prototype.popup = function (window, x, y, positioningItem) {
|
||||
|
@ -150,7 +153,7 @@ Menu.prototype.insert = function (pos, item) {
|
|||
}
|
||||
|
||||
Menu.prototype._callMenuWillShow = function () {
|
||||
if (this.delegate) this.delegate.menuWillShow()
|
||||
if (this.delegate) this.delegate.menuWillShow(this)
|
||||
this.items.forEach(item => {
|
||||
if (item.submenu) item.submenu._callMenuWillShow()
|
||||
})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue