While developing contextmenu based extension for Chrome, i'm facing a situation where invoking chrome.contextMenus.onClicked.addListener
in a loop adds action cumulatively for each subcontext menu item.
So, when subcontextmenu is clicked it triggers event listener for all subcontext menus, instead for the context menu which was clicked.
var parent;
chrome.runtime.onInstalled.addListener(() => {
parent = chrome.contextMenus.create({"title": "CCM", "id":"CCM", "contexts":["selection"]});
});
Object.keys(msgs).forEach(function(key) {
chrome.runtime.onInstalled.addListener(() => {
var createCM = chrome.contextMenus.create(
{"title": "subcontextmenu"+key, "id":"scm"+key, "parentId": parent, "contexts":["selection"]});
});
chrome.contextMenus.onClicked.addListener(function(info,tab){openAction(info,tab,JSON.stringify(msgs[key]['msg']));}
);
});
In the above example, msgs
is a JSON object containing message to be displayed when each subcontextmenu is clicked. Also, the msgs
JSON context is bound to change dynamically. So, we can't tweak openAction
to hardcode the numbers and associate the messages.
Hope my question is clear. Any help for clearing this confusion will be a great time saver for me.
Use one listener for onInstalled and onClicked (it provides menuItemId in its parameter).
chrome.runtime.onInstalled.addListener(() => {
chrome.contextMenus.create({title: 'CCM', id: 'CCM', contexts: ['selection']});
Object.keys(msgs).forEach(key => {
chrome.contextMenus.create({
title: 'subcontextmenu' + key,
id: 'scm' + key,
parentId: 'CCM',
contexts: ['selection'],
});
});
});
chrome.contextMenus.onClicked.addListener((info, tab) => {
openAction(info, tab, JSON.stringify(msgs[info.menuItemId].msg));
});