zotero-plugin-toolkit icon indicating copy to clipboard operation
zotero-plugin-toolkit copied to clipboard

Is it possible to have a dynamic context submenu menu on the collection menu?

Open retorquere opened this issue 1 year ago • 10 comments

I have a submenu that wants to display a variable set of menitems, dependent on the collection that was right-clicked. Is that possible?

retorquere avatar Jan 13 '25 16:01 retorquere

Yes. There is a isHidden property on the argument when creating a menu and by returning a boolean the column is displayed accordingly. Like this:

ztoolkit.Menu.register("collection", {
  "tag": "menu",
  "children": [
    {
      "tag": "menuitem",
      "isHidden": (elem, ev) => {
        return false;
      }
    }
  ]
})

windingwind avatar Jan 13 '25 19:01 windingwind

What are elem and ev?

retorquere avatar Jan 13 '25 20:01 retorquere

It's:

https://github.com/windingwind/zotero-plugin-toolkit/blob/2aa66e34e51ffc6c5bd20d32dda557c8e41f5171/src/managers/menu.ts#L235-L239

windingwind avatar Jan 13 '25 20:01 windingwind

It's called in the event popupshowing of its parent popup, and that's where the ev comes from

windingwind avatar Jan 13 '25 20:01 windingwind

Yes. There is a isHidden property on the argument when creating a menu and by returning a boolean the column is displayed accordingly. Like this:

ztoolkit.Menu.register("collection", {
  "tag": "menu",
  "children": [
    {
      "tag": "menuitem",
      "isHidden": (elem, ev) => {
        return false;
      }
    }
  ]
})

That will allow a set number of menu items to be shown or hidden I think, but I don't know in advance how many there will be, it's dynamic.

retorquere avatar Jan 13 '25 21:01 retorquere

Oh and the label would be dynamic too.

retorquere avatar Jan 13 '25 21:01 retorquere

Yes, you can always set the attributes on the elem

windingwind avatar Jan 13 '25 22:01 windingwind

But a fixed number of items then, correct?

retorquere avatar Jan 13 '25 22:01 retorquere

How do I get the selected collection inside isHidden?

retorquere avatar Jan 15 '25 11:01 retorquere

How do I get the selected collection inside isHidden?

Basically, from the main window's ZoteroPane.

There will be an official replacement to the menu API in the future.

windingwind avatar Feb 14 '25 09:02 windingwind

I need to create a menuitem in the 'item' menu that appears under the menu item with data-l10n-id = 'item-menu-viewAttachment', but only if the item being right-clicked is a PDF. How would I do that?

retorquere avatar Aug 27 '25 13:08 retorquere

ztoolkit.Menu.register("item", {
  tag: "menu",
  children: [
    {
      tag: "menuitem",
      onShowing: (elem, ev) => {
        if (!elem.dataset.l10nID) {
          elem.dataset.l10nID = "item-menu-viewAttachment";
        }
      },
      isHidden: (elem, ev) => {
        const selectedItems =
          Zotero.getActiveZoteroPane().getSelectedItems();
        if (selectedItems.length != 1) return true;
        return !selectedItems[0].isPDFAttachment();
      },
    },
  ],
});

Note that the official menu api is almost there (https://github.com/zotero/zotero/commit/7f9418fe98db90f680d5474c86e65c31a9de6002) and should be available in the next beta. After Zotero 8 is officially released, the api provided by this library will be deprecated.

windingwind avatar Aug 27 '25 14:08 windingwind

I meant whether it is possible to find an existing menuitem with data-l10n-id = 'item-menu-viewAttachment', and create the new menuitem (with its own ID) under it.

retorquere avatar Aug 27 '25 15:08 retorquere

There's no reliable way to insert the menu after this menu item (at least with this lib), as this menu item is dynamically generated. Also, please note that Zotero's official API for menu registration will only allow plugins to insert at the end of popup.

windingwind avatar Aug 27 '25 16:08 windingwind

So insertPosition will be dropped?

retorquere avatar Aug 28 '25 12:08 retorquere

The current implementation in this lib will continue working, while Zotero's official API won't support insertPosition. Plugins are expected to have their menu items under all of Zotero's built-in menu items.

windingwind avatar Aug 28 '25 12:08 windingwind

can isHidden take an async function? I'm currently getting

Type 'Promise<boolean>' is not assignable to type 'boolean'.

133           isHidden: async (elem, ev) => (!Zotero.Prefs.get('fileHandler.pdf') || !(await selectedPDF())),

retorquere avatar Aug 28 '25 13:08 retorquere

Please try [email protected].

windingwind avatar Aug 28 '25 14:08 windingwind

Works, I have the same problem now with commandListener, but since that doesn't return a value, I can wrap it in an async IIFE (but I'd prefer it if it would accept a function returning Promise<void>)

retorquere avatar Aug 28 '25 21:08 retorquere

It does, it accepts a return of any, actually.

windingwind avatar Aug 28 '25 21:08 windingwind

It does. I don't know what I did earlier then.

retorquere avatar Aug 28 '25 21:08 retorquere

Everything works, thanks!

retorquere avatar Aug 29 '25 10:08 retorquere

Ah almost everything. I have added a png icon using a data url, but the icon is not showing. Tips?

retorquere avatar Aug 29 '25 10:08 retorquere

On MacOS the menu icons are not shown on purpose.

If it's not working on other platforms, check the URL: I use it in chrome:// uri. What value are you using for icon?

windingwind avatar Sep 01 '25 09:09 windingwind

On MacOS the menu icons are not shown on purpose.

OK, check.

If it's not working on other platforms, check the URL: I use it in chrome:// uri. What value are you using for icon?

I will wait for feedback from the submitter. I'm on MacOS myself.

retorquere avatar Sep 01 '25 12:09 retorquere

The official menu api is available for test (https://www.zotero.org/support/dev/zotero_8_for_developers#custom_menu_items)

windingwind avatar Sep 04 '25 14:09 windingwind

But I'll stick with the library until 8 is out

retorquere avatar Sep 04 '25 14:09 retorquere

Sure, that's perfectly fine. The lib will discontinue and remove deprecated ones only after the official API is in a stable release for a while (several months).

windingwind avatar Sep 04 '25 16:09 windingwind