How to add submenu to right click context menu

54 views
Skip to first unread message

maie...@gmail.com

unread,
May 24, 2024, 8:48:42 AMMay 24
to zotero-dev
Hi,

I'm trying to convert an older plugin to a bootstrapped version. I've used the make-it-red template and this works so for, but I can't see how I would add a group of items / a submenu to the right click context menu. Is that documented somewhere?

Best,
Denis

Alain Borel

unread,
May 25, 2024, 3:25:17 AMMay 25
to zotero-dev
I had to search for this myself, looking into other people's code and playing with JQuery.

Check the addToWindow(window) function in
(that's as simple as I was able to make it).

XY Wong

unread,
May 28, 2024, 5:07:22 AMMay 28
to zotero-dev
To clarify, it's nothing to do with JQuery; the menus are defined as XUL elements (menupopup, menuitem, etc.), see https://devdoc.net/web/developer.mozilla.org/en-US/docs/XUL/menupopup.html

You can find the relevant menu elements of Zotero's main window in chrome/content/zotero/zoteroPane.xhtml in Zotero's GitHub repo.

maie...@gmail.com

unread,
May 28, 2024, 5:18:52 AMMay 28
to zotero-dev
Thanks for the hints and for the link to documentation. In the meantime I've figured it out by looking at how other plugins do that. The trick is that it's essentially a two-step process, first I needed to add a menu to the itemmenu, then add a popup to this menu. There I could finally add the individual sub items/commands.

For future reference, this here seems to work:

```
// let's add a submenu
let my_submenu = doc.createElementNS(XUL_NS, 'menu');
my_submenu.id = 'my_submenu';
my_submenu.setAttribute('type', 'menu');
my_submenu.setAttribute('class', 'menuitem-iconic');
my_submenu.setAttribute('data-l10n-id', 'my_submenu');
doc.getElementById('zotero-itemmenu').appendChild(my_submenu);
this.storeAddedElement(my_submenu);

// let's a popup to the submenu
let my_popup = my_submenu.appendChild(doc.createElementNS(XUL_NS, 'menupopup'));
my_popup.id = 'my_popup';
this.storeAddedElement(my_popup);

// finally we can add our menu items to the popup
let submenuitem = doc.createElementNS(XUL_NS, 'menuitem');
submenuitem.id = 'submenuitem';
submenuitem.setAttribute('type', 'command');
submenuitem.setAttribute('class', 'menuitem');
submenuitem.setAttribute('data-l10n-id', 'my-submenu-item');
submenuitem.addEventListener('command', () => {
// do something
this.whatever();
});
my_popup.appendChild(submenuitem);
this.storeAddedElement(submenuitem);

// add another item in the popup
let submenuitem2 = doc.createElementNS(XUL_NS, 'menuitem');
submenuitem2.id = 'submenuitem2';
submenuitem2.setAttribute('type', 'command');
submenuitem2.setAttribute('class', 'menuitem');
submenuitem2.setAttribute('data-l10n-id', 'my-submenu-item2');
submenuitem2.addEventListener('command', () => {
// do something
this.whatever();
});
my_popup.appendChild(submenuitem2);
this.storeAddedElement(submenuitem2);
```

Is that approach ok or am I making some fundamental mistakes?

XY Wong

unread,
May 28, 2024, 5:36:54 AMMay 28
to zotero-dev
You are doing it right and it will work. however:

1. All the elem.setAttribute('type', '...'); won't do anything here. can remove
2. It's recommended to prefix your elements' id and data-l10n-id with a unique string of your plugin, e.g. plugin name, to prevent potential conflicts with other plugins. For example, my_submenu can be PLUGIN_NAME_my_submenu 
Reply all
Reply to author
Forward
0 new messages