Zotero 8 - likely MenuManager problem
I'm working on a plugin under Zotero 8 - latest dev beta.
When trying to use the new MenuManager API to create a "main/library/item" and "main/library/collection" submenu with menuitems, the submenu item appears in the context menu, but it doesn't have a popup menu associated with it - meaning that hovering over it doesn't do anything.
I reproduced the same behaviour in zotero-better-notes - which has already moved its menu management to the new MenuManager API. The repo doesn't use a context menu, so hasn't yet shown up the bug, but I added some code to its menu.ts file registering all it its menus and the bug appears there too.
The code that I used to register the submenu with child menuitems is this:
```js
Zotero.MenuManager.registerMenu({
menuID: `${config.addonRef}-bugrepro-library-item`,
pluginID: config.addonID,
target: "main/library/item",
menus: [
// Hidden diagnostic item
{
menuType: "menuitem",
l10nID: `${config.addonRef}-bugrepro-diag`,
onCommand() {},
},
// The submenu under test
{
menuType: "submenu",
l10nID: `${config.addonRef}-bugrepro-submenu`,
icon: `chrome://${config.addonRef}/content/icons/favicon.png`,
menus: [
{
menuType: "menuitem",
l10nID: `${config.addonRef}-bugrepro-child1`,
onCommand() {
Zotero.debug("[MenuManager bug repro] child1 clicked");
},
},
{
menuType: "menuitem",
l10nID: `${config.addonRef}-bugrepro-child2`,
onCommand() {
Zotero.debug("[MenuManager bug repro] child2 clicked");
},
},
],
},
],
});
```
This is the resulting DOM tree:
< menu xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" class="zotero-custom-menu-item zotero-custom-menu-L0kxC1JG-1770913655563 menu-iconic" data-l10n-id="BetterNotes-bugrepro-submenu" style="--custom-menu-icon-light: url(chrome://BetterNotes/content/icons/favicon.png); --custom-menu-icon-dark: url(chrome://BetterNotes/content/icons/favicon.png);" data-dynamic-classes="">MenuManager Submenu< /menu>
For other context submenus not created with MenuManager, the submenu has a < menupopup> element in the DOM.
I've been digging into this with an AI agent and after trying a number of things, this is the summary of the diagnosis.
Specifically: _initMenu() is not appending a < menupopup> in the submenu case, despite the code path. But we see it created as < menu> not < menuitem>, and it has the menu-iconic class that MenuManager adds for submenus with icons — so it knows it’s a submenu. So the creation switch is being hit, but the < menupopup> is missing afterwards. That strongly implies: The < menupopup> is created and appended, then later removed/dropped
Likely due to:
- node being moved/cloned by some other part of Zotero’s context menu code after MenuManager appends it
- XUL menu sanitization that strips menupopup children on custom
When trying to use the new MenuManager API to create a "main/library/item" and "main/library/collection" submenu with menuitems, the submenu item appears in the context menu, but it doesn't have a popup menu associated with it - meaning that hovering over it doesn't do anything.
I reproduced the same behaviour in zotero-better-notes - which has already moved its menu management to the new MenuManager API. The repo doesn't use a context menu, so hasn't yet shown up the bug, but I added some code to its menu.ts file registering all it its menus and the bug appears there too.
The code that I used to register the submenu with child menuitems is this:
```js
Zotero.MenuManager.registerMenu({
menuID: `${config.addonRef}-bugrepro-library-item`,
pluginID: config.addonID,
target: "main/library/item",
menus: [
// Hidden diagnostic item
{
menuType: "menuitem",
l10nID: `${config.addonRef}-bugrepro-diag`,
onCommand() {},
},
// The submenu under test
{
menuType: "submenu",
l10nID: `${config.addonRef}-bugrepro-submenu`,
icon: `chrome://${config.addonRef}/content/icons/favicon.png`,
menus: [
{
menuType: "menuitem",
l10nID: `${config.addonRef}-bugrepro-child1`,
onCommand() {
Zotero.debug("[MenuManager bug repro] child1 clicked");
},
},
{
menuType: "menuitem",
l10nID: `${config.addonRef}-bugrepro-child2`,
onCommand() {
Zotero.debug("[MenuManager bug repro] child2 clicked");
},
},
],
},
],
});
```
This is the resulting DOM tree:
< menu xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" class="zotero-custom-menu-item zotero-custom-menu-L0kxC1JG-1770913655563 menu-iconic" data-l10n-id="BetterNotes-bugrepro-submenu" style="--custom-menu-icon-light: url(chrome://BetterNotes/content/icons/favicon.png); --custom-menu-icon-dark: url(chrome://BetterNotes/content/icons/favicon.png);" data-dynamic-classes="">MenuManager Submenu< /menu>
For other context submenus not created with MenuManager, the submenu has a < menupopup> element in the DOM.
I've been digging into this with an AI agent and after trying a number of things, this is the summary of the diagnosis.
Specifically: _initMenu() is not appending a < menupopup> in the submenu case, despite the code path. But we see it created as < menu> not < menuitem>, and it has the menu-iconic class that MenuManager adds for submenus with icons — so it knows it’s a submenu. So the creation switch is being hit, but the < menupopup> is missing afterwards. That strongly implies: The < menupopup> is created and appended, then later removed/dropped
Likely due to:
- node being moved/cloned by some other part of Zotero’s context menu code after MenuManager appends it
- XUL menu sanitization that strips menupopup children on custom
-
dstillman Zotero Teamedited yesterday at 6:36pmPlease post development questions to zotero-dev.
Upgrade Storage