9

There are only four methods for chrome.contextMenus:

create
update
remove
removeAll

I am wondering how do I check whether one menu is already created?

I tried this:

try {
  chrome.contextMenus.update("byname", {});
} catch (e) {
 // doesn't exist
}

But it seems the error cannot be caught (but shown in the console).

Thanks for any kind of tips!

AGamePlayer
  • 7,404
  • 19
  • 62
  • 119
  • It seems that your `catch` didn't work because the `.update()` call is async and you can only get your error status from inside a callback, as per [chrome.contextMenu.create() docs](https://developer.chrome.com/extensions/contextMenus#method-create): "Note that if an error occurs during creation, you may not find out until the creation callback fires (the details will be in chrome.runtime.lastError)." – Dimitry K Jul 07 '17 at 11:07

2 Answers2

3

Each chrome.contextMenus.create call returns an unique identifier. Store these identifiers in an array or hash to keep track of them.

Rob W
  • 341,306
  • 83
  • 791
  • 678
  • Thanks, but how do I find whether a ID is already binded to a contextMenuItem? For example, when the user clicks a button in my option page, he can create a customized context menu item, but if the user open two option pages and click twice the button, it will create two context menu items. I think the important thing is to check whether the item was already existed, if it was, then there's no need to create a new one. But the current problem for me is I don't know how to check that. Thanks! – AGamePlayer Dec 07 '12 at 06:27
  • @AwQiruiGuo You can share IDs with the background page (`chrome.runtime.getBackgroundPage()`](http://developer.chrome.com/extensions/runtime.html#method-getBackgroundPage) (if you're using event pages) or [`chrome.extension.getBackgroundPage()`](http://developer.chrome.com/extensions/extension.html#method-getBackgroundPage). – Rob W Dec 07 '12 at 10:16
  • yes. I know that. My question is just simple, how do I know whether a ID is already created? For example. I create a new item and the system returns me a ID 5, then when I create another one, I want to check whether #5 is already existed. – AGamePlayer Dec 08 '12 at 00:46
  • @AwQiruiGuo Example for a single entry: http://stackoverflow.com/questions/13202896/creating-dynamic-context-menu-in-chrome-extension-is-failing/13673942#13673942. If you need multiple contextmenu entries, store the IDs in an array (add using `push`, remove using `.indexOf` and `.splice`). – Rob W Dec 08 '12 at 08:44
  • 7
    That doenst answer the question. Op asked for a possibility to do `if(chrome.contextMenus.exists(id))`. Saving every id every created is no good solution especially since you can remove entries of the context menu again – Fuzzyma Sep 27 '16 at 12:42
  • @Fuzzyma The API does not offer a way to list all menu entries, so this is the best you can get. Delete the ID from your array/dictionary when you remove the menu item if you worry about removal of menu items. – Rob W Sep 27 '16 at 17:58
0

This is a direct solution to anyone having the op's problem, based on the suggestion by Rob W. The idea is to maintain your own list of existing context menu id's.

By using these wrapper functions to maintain context menu entries, also the removal and updates are being kept track of (addressing Fuzzyma's comment).

Usage works like Chrome's own methods, eg. createContextMenu({id: "something"}, onclick). It works for me.

let contextMenus =  {}

// method to create context menu and keep track of its existence
function createContextMenu() {
  if (arguments[0] && arguments[0].id) {
    // TODO: not sure if this will work properly, is creation synchronous or asynchrounous?
    // take in to account calll back and the runtime error?
    chrome.contextMenus[arguments[0].id] = chrome.contextMenus.create.apply(null, arguments);
  }
}

function updateContextMenu() {
  if (arguments[0] && contextMenus[arguments[0]]) {
    chrome.contextMenus.update.apply(mull, arguments);
  }

}

function removeContextMenu() {
  if (arguments[0] && contextMenus[arguments[0]]) {
    chrome.contextMenus.remove.apply(null, arguments);
    contextMenus[arguments[0]] = undefined;
  }
}

function contextMenuExists(id) {
  return !!contextMenus[id];
}
Thor Galle
  • 68
  • 7