UserIsCorrupt
UserIsCorrupt

Reputation: 5025

Context menus in Chrome extensions

I've searched and searched and searched for a solution to this but every source I come across seems to assume I already have profound knowledge of Chrome extensions, even Google's help pages

I know the very basics of Chrome extensions and I made one with some basic content scripts. However, now I'm looking to make one that involves context menus.

Let's say when you highlight words and right-click them, you see the option Search '<highlighted words>' on Google and when clicked, it opens http://www.google.com/search?q=<highlighted words> in a new tab. I know this exists in Chrome and I'm sure there have been a billion extensions replicating it, but this is only an example for me to build off of.

How can I do this?

Upvotes: 46

Views: 54005

Answers (4)

anhquan
anhquan

Reputation: 1398

The answer from Bartlomiej Szalach is too old. It will not work on Chrome Version 80.0.3987.163 (April 2020).

According to the documentation,

onclick: A function that is called back when the menu item is clicked. Event pages cannot use this; instead, they should register a listener for contextMenus.onClicked.

The background.js should be modified as follows:

const CONTEXT_MENU_ID = "MY_CONTEXT_MENU";
function getword(info,tab) {
  if (info.menuItemId !== CONTEXT_MENU_ID) {
    return;
  }
  console.log("Word " + info.selectionText + " was clicked.");
  chrome.tabs.create({  
    url: "http://www.google.com/search?q=" + info.selectionText
  });
}
chrome.contextMenus.create({
  title: "Search: %s", 
  contexts:["selection"], 
  id: CONTEXT_MENU_ID
});
chrome.contextMenus.onClicked.addListener(getword)

Upvotes: 33

anthonyjdella
anthonyjdella

Reputation: 623

Manifest v3 is out so to improve on Lucas Mendonca's answer, you just change the manifest.json to:

{
    "manifest_version": 3,
    "name": "App name",
    "version": "1.0",
    "permissions": ["contextMenus"],
    "background": { 
        "service_worker": "background.js"
    }
}

Upvotes: 3

Lucas Mendonca
Lucas Mendonca

Reputation: 436

Improving on ahnquan's answer so chrome.contextMenus.create isn't called on every background script invocation, and also encoding the highlighted text into URI so it doesn't break when it contains special characters, such as ;,/?:@&=+$.

Your background.js will look like:

chrome.runtime.onInstalled.addListener(() =>
    chrome.contextMenus.create({
        title: 'Search Google for "%s"',
        contexts: ["selection"],
        id: "myContextMenuId",
    })
);
    
chrome.contextMenus.onClicked.addListener((info, tab) =>
    chrome.tabs.create({
        url: `https://www.google.com/search?q=${encodeURIComponent(info.selectionText)}` 
    })
);

manifest.json (MV2):

{
    "manifest_version": 2,
    "name": "App name",
    "version": "1.0",
    
    "permissions": ["contextMenus"],
    "background": { 
        "scripts": ["background.js"],
        "persistent": false
    }
}

Upvotes: 15

Bartłomiej Szałach
Bartłomiej Szałach

Reputation: 2453

Script should look like this:

function getword(info,tab) {
  console.log("Word " + info.selectionText + " was clicked.");
  chrome.tabs.create({  
    url: "http://www.google.com/search?q=" + info.selectionText
  });
}
chrome.contextMenus.create({
  title: "Search: %s", 
  contexts:["selection"], 
  onclick: getword
});

And manifest.json:

{
    "name": "App name",
    "version": "1.0",
    "manifest_version": 2,
    "description": "Your description",
    "permissions": [
      "contextMenus"
     ],
    "background": { 
      "scripts": ["script.js"]
    }
}

Here you have how to load extension: http://developer.chrome.com/extensions/getstarted.html

Upvotes: 80

Related Questions