Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add contextmenu items to a Chrome extension's browser action button

A G Chrome extension can have a 'browser action'. Usually the ext developer displays the options when you click on it, meaning every action requires 2 clicks, even the default 99%-of-the-time action. Chrome itself adds a context menu with a few options: disable ext, uninstall ext, go to ext homepage etc.

Can I as ext developer add items to that context menu, so I can keep my 1-click-action under the normal/left/primary mouse click?

I know of chrome.contextMenus but that's only for context menus in the page (see property 'contexts').

I can't find it in the Chrome Extension dev guide, but you know more than I.

like image 410
Rudie Avatar asked Oct 19 '13 16:10

Rudie


People also ask

How do I add a context menu to Chrome?

Use the chrome. contextMenus API to add items to Google Chrome's context menu. You can choose what types of objects your context menu additions apply to, such as images, hyperlinks, and pages.


2 Answers

It is now possible, AdBlock chrome extensions has it. Below is working example of "context menu in browser action".

manifest.json:

{
    "name": "Custom context menu in browser action",
    "version": "1",
    "manifest_version": 2,
    "background": {
      "scripts": ["background.js"]
    },
    "browser_action": {
      "default_title": "Some tooltip",
      "default_popup": "popup.html"
    },
    "permissions": [
      "contextMenus"
    ],
    "icons": {
      "16": "icon16.png"
    }
}

background.js:

chrome.contextMenus.removeAll();
chrome.contextMenus.create({
      title: "first",
      contexts: ["browser_action"],
      onclick: function() {
        alert('first');
      }
});

Note that if you use an Event page, you cannot use the onclick attribute; you'll need to add a listener to chrome.contextMenus.onClicked instead.

like image 106
asdjfiasd Avatar answered Oct 29 '22 19:10

asdjfiasd


Example (almost patttern) It also provides a workaround for using a simple onclick listeners (here short property “act”), for now if you use the “Event page” you can not use native onclick

const menuA = [
  { id: 'ItemF', act: (info, tab) => { console.log('Clicked ItemF', info, tab, info.menuItemId); alert('Clicked ItemF') } },
  { id: 'ItemG', act: (info, tab) => { console.log('Clicked ItemG', info, tab, info.menuItemId); alert('Clicked ItemG') } },
  { id: 'ItemH', act: (info, tab) => { console.log('Clicked ItemH', info, tab, info.menuItemId); alert('Clicked ItemH') } },
  { id: 'ItemI', act: (info, tab) => { console.log('Clicked ItemI', info, tab, info.menuItemId); alert('Clicked ItemI') } },
];

const menuB = [
  { id: 'ItemJ', act: (info, tab) => { console.log('Clicked ItemJ', info, tab, info.menuItemId); alert('Clicked ItemJ') } },
  { id: 'ItemK', act: (info, tab) => { console.log('Clicked ItemK', info, tab, info.menuItemId); alert('Clicked ItemK') } },
  { id: 'ItemL', act: (info, tab) => { console.log('Clicked ItemL', info, tab, info.menuItemId); alert('Clicked ItemL') } },
  { id: 'ItemM', act: (info, tab) => { console.log('Clicked ItemM', info, tab, info.menuItemId); alert('Clicked ItemM') } },
];


const rootMenu = [
  //
  // In real practice you must read chrome.contextMenus.ACTION_MENU_TOP_LEVEL_LIMIT
  //
  { id: 'ItemA', act: (info, tab) => { console.log('Clicked ItemA', info, tab, info.menuItemId); alert('Clicked ItemA') }, menu: menuA },
  { id: 'ItemB', act: (info, tab) => { console.log('Clicked ItemB', info, tab, info.menuItemId); alert('Clicked ItemB') }, menu: menuB },
  { id: 'ItemC', act: (info, tab) => { console.log('Clicked ItemC', info, tab, info.menuItemId); alert('Clicked ItemC') } },
  { id: 'ItemD', act: (info, tab) => { console.log('Clicked ItemD', info, tab, info.menuItemId); alert('Clicked ItemD') } },
  { id: 'ItemE', act: (info, tab) => { console.log('Clicked ItemE', info, tab, info.menuItemId); alert('Clicked ItemE') } },
];


const listeners = {};

const contexts = ['browser_action'];

const addMenu = (menu, root = null) => {

  for (let item of menu) {

    let {id, menu, act} = item;

    chrome.contextMenus.create({
      id: id,
      title: chrome.i18n.getMessage(id),
      contexts: contexts,
      parentId: root
    });

    if (act) {
      listeners[id] = act;
    }

    if (menu) {
      addMenu(menu, id);
    }
  }

};

addMenu(rootMenu);

chrome.contextMenus.onClicked.addListener((info, tab) => {
  console.log('Activate „chrome.contextMenus -> onClicked Listener“', info, tab);
  listeners[info.menuItemId] (info, tab);
});

See some example of «chrome extension tree context menu pattern»

like image 20
redisko Avatar answered Oct 29 '22 17:10

redisko