Context menus in Chrome extensions - javascript

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?

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

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)

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(function() {
chrome.contextMenus.create({
"title": 'Search Google for "%s"',
"contexts": ["selection"],
"id": "myContextMenuId"
});
});
chrome.contextMenus.onClicked.addListener(function(info, tab) {
chrome.tabs.create({
url: "http://www.google.com/search?q=" + encodeURIComponent(info.selectionText)
});
})
And manifest.json:
{
"manifest_version": 2,
"name": "App name",
"version": "1.0",
"permissions": ["contextMenus"],
"background": {
"scripts": ["background.js"],
"persistent": false
}
}

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",
"persistent": false
}
}

Related

Chrome Console/Extensions: Visit a URL and click a button. Rinse and repeat for a different URL

INITIAL QUESTION:
Is it possible to run javascript from Chrome's Console that will:
Navigate to a given URL
Click a button
I'd like to repeat the above steps for hundreds of URLs.
I'm sure if I get the two steps working iterating over a number of URLs will be fairly straightforward.
So, I've made Console persistent between page refreshes, so that's a good start...but it seems the Click event it not being triggered.
The clicking command works fine if I manually navigate to the URL then run it via Console, but not as a whole piece of code.
Here's the code I have so far:
function f() {
window.location.href = "https://mywebsite.com/post";
document.querySelector('.post_like_button_class').click();
}
f();
EDIT:
One of the commenters below suggested using Chrome Extensions to achieve that. This is what I have written so far:
manifest.json
{
"name": "Getting Started Example",
"version": "1.0",
"description": "Build an Extension!",
"browser_action": {
"default_icon": "images/get_started32.png",
"default_title": "Your title"
},
"background": {
"scripts": ["background.js"],
"persistent": false
},
"manifest_version": 2
}
background.js
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.create({ url: "https://www.google.com" });
});
Now...how do I then carry out the second part of my task? I'm a bit stuck.
Click a button:
document.querySelector('.post_like_button_class').click();
After some further digging, here's one way to do it:
manifest.json
{
"name": "Getting Started Example",
"version": "1.0",
"description": "Build an Extension!",
"permissions": [ "*://*/*"
],
"browser_action": {
"default_icon": "images/get_started32.png",
"default_title": "Your title"
},
"background": {
"scripts": ["background.js"],
"persistent": true
},
"manifest_version": 2
}
background.js
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.update({ url: "https://www.instagram.com/p/Bk6AGDQFqvn/" });
});
chrome.tabs.onUpdated.addListener( function (tabId, changeInfo, tab) {
if (changeInfo.status == 'complete' && tab.active) {
chrome.tabs.executeScript(null,
{code:" <INSERT YOUR JS CODE HERE> "});
}
})

"else if" condition not working in Chrome extension

I'm trying to set different actions for a Chrome extension based on the type of selection. Maybe I'm reading the documentation wrong, but I can't figure out what isn't working here.
manifest.json
{
"background": {
"scripts": [ "background2.js" ]
},
"description": "Creates a context menu option which copies the selected address into a new Gmail compose window.",
"manifest_version": 2,
"name": "New Gmail Window",
"permissions": [ "tabs", "contextMenus" ],
"version": "0.1"
}
background.js
chrome.contextMenus.create({
title: "Send a New Email",
contexts:["link", "selection"],
onclick: checkType,
});
function checkType(info,tab) {
if (info.linkUrl.substring(0, 7) === "mailto:") { //The "if" works as expected //
chrome.windows.create({
url:"https://mail.google.com/mail/?ui=2&view=cm&fs=1&tf=1&shva=1&to=" +info.linkUrl.substr(7),
width:640,
height:700,
focused:true,
type:"popup",
});
console.log("The linked emails work");
}
else if (info.selectionText.containsNode('a',false)) { //I want to look for an <a> tag that isn't working
console.log("this worked");
}
else console.log("nothing to send");
}
Thanks for any help.

Chrome Extension - Context Menu On Specific Pages

I am wondering if it is possible to show the following context menu item only if it is on specific pages.
I think it has something to do with documentUrlPatterns (Which can be seen here as of typing this) but I am not sure how to implement it with the following code:
manifest.json
{
"name": "App Name",
"version": "1.0",
"manifest_version": 2,
"description": "Description",
"permissions": [
"contextMenus",
"tabs"
],
"background": {
"scripts": ["script.js"]
}
}
script.js
function getword(info,tab) {
chrome.tabs.create({
url: "http://www.google.com/search?q=" + info.selectionText,
})
}
chrome.contextMenus.create({
title: "Search: %s",
contexts:["selection"],
onclick: getword,
});
It would be great if you could provide a demo which will only work on specific sites of your choice (For instance, any directory of Stack Overflow and any directory of Google).
PS. The above code allows users to make a selection on any site and provides a button (In the context menu) which will search for what the user has selected on http://www.google.com/search?q= {Selection}
I have stripped down your code to demonstrate selective context menu option display.
manifest.json
{
"name": "zambrey",
"version": "1.0",
"manifest_version": 2,
"description": "Description",
"permissions": [
"contextMenus"
],
"background": {
"scripts": ["trial.js"]
}
}
trial.js
var showForPages = ["https://www.google.com/","*://github.com/zambrey/*","http://www.nytimes.com/"];
chrome.contextMenus.create({
"title": "zambrey",
"documentUrlPatterns":showForPages
});
Be sure to check out http://developer.chrome.com/extensions/match_patterns.html for more details on url pattern syntax.
Also refer to this http://developer.chrome.com/extensions/examples/api/contextMenus/basic.zip sample for more complex context menus.
I believe you want the "permissions" option in the manifest.json:
"permissions": [
"http://stackoverflow.com/*"
]
http://developer.chrome.com/extensions/declare_permissions.html

Get selected text in a chrome extension

I wanna make an extension that takes the selected text and searches it in google translate
but I can't figure out how to get the selected text.
Here is my manifest.json
{
"manifest_version": 2,
"name": "Saeed Translate",
"version": "1",
"description": "Saeed Translate for Chrome",
"icons": {
"16": "icon.png"
},
"content_scripts": [ {
"all_frames": true,
"js": [ "content_script.js" ],
"matches": [ "http://*/*", "https://*/*" ],
"run_at": "document_start"
} ],
"background": {
"scripts": ["background.js"]
},
"permissions": [
"contextMenus",
"background",
"tabs"
]
}
and my background.js file
var text = "http://translate.google.com/#auto/fa/";
function onRequest(request, sender, sendResponse) {
text = "http://translate.google.com/#auto/fa/";
text = text + request.action.toString();
sendResponse({});
};
chrome.extension.onRequest.addListener(onRequest);
chrome.contextMenus.onClicked.addListener(function(tab) {
chrome.tabs.create({url:text});
});
chrome.contextMenus.create({title:"Translate '%s'",contexts: ["selection"]});
and my content_script.js file
var sel = window.getSelection();
var selectedText = sel.toString();
chrome.extension.sendRequest({action: selectedText}, function(response) {
console.log('Start action sent');
});
How do I get the selected text?
You are making it a bit more complicated than it really is. You don't need to use a message between the content script and background page because the contextMenus.create method already can capture selected text. Try adjusting your creations script to something like:
chrome.contextMenus.create({title:"Translate '%s'",contexts: ["all"], "onclick": onRequest});
Then adjust your function to simply get the info.selectionText:
function onRequest(info, tab) {
var selection = info.selectionText;
//do something with the selection
};
Please note if you want to remotely access an external site like google translate you may need to adjust your permissions settings.
I would note - this is no longer valid response if you are moving to manifest version 3. Manifest version 3 adds the concept of "service workers". https://developer.chrome.com/docs/extensions/mv3/intro/mv3-migration/
You have to update several things, but the basic concept is the same.
manifest.json
"name": "Name of Extension",
"version": "1.0",
"manifest_version": 3,
"description": "Description of Extension",
"permissions": [
"contextMenus",
"tabs",
"activeTab"
],
"background": {
"service_worker": "background.js",
"type": "module"
},
background.js
//Setting up the function to open the new tab
function newTab(info,tab)
{
const { menuItemId } = info
if (menuItemId === 'anyNameWillDo'){
chrome.tabs.create({
url: "http://translate.google.com/#auto/fa/" + info.selectionText.trim()
})}};
//create context menu options. the 'on click' command is no longer valid in manifest version 3
chrome.contextMenus.create({
title: "Title of Option",
id: "anyNameWillDo",
contexts: ["selection"]
});
//This tells the context menu what function to run when the option is selected
chrome.contextMenus.onClicked.addListener(newTab);

Chrome-extension: Append functions to right click menu

How would I append functions to the right click menu in the browser? E.g something appended to the right click menu which does function dosomething() which is located in my extension.
I made simple extenstion using the contextMenu API - link Hope this works well as an example.
manifest.json -
{
"manifest_version": 2,
...
...
"permissions": [
"contextMenus",
"tabs"],
...
...
"background": {
"page": "background.html",
"scripts": ["main.js"]
}
}
main.js -
searchUrbanDict = function(word){
var query = word.selectionText;
chrome.tabs.create({url: "http://www.urbandictionary.com/define.php?term=" + query});
};
chrome.contextMenus.create({
title: "Search in UrbanDictionary",
contexts:["selection"], // ContextType
onclick: searchUrbanDict // A callback function
});
For more information on different context types - link
Found out how, using the contextmenu API https://developer.chrome.com/docs/extensions/reference/contextMenus/
Anurag-Sharma's answer updated for manifest v3:
manifest.json -
{
"name": "terapeak",
"description": "easy way to research ebay products",
"version": "1.0",
"manifest_version": 3,
"permissions": [
"contextMenus",
"tabs"
],
"background": {
"service_worker": "main.js"
}
}
main.js
searchTerapeak = function(word){
var query = word.selectionText;
chrome.tabs.create({url: "https://www.ebay.com/sh/research?dayRange=365&sorting=-avgsalesprice&tabName=SOLD&keywords="
+ query}); };
chrome.contextMenus.removeAll(function() {
chrome.contextMenus.create({
id: "1",
title: "Terapeak this!",
contexts:["selection"], // ContextType
}); })
chrome.contextMenus.onClicked.addListener(searchTerapeak);
Why you need to removeAll each time: Why does chrome.contextMenus create multiple entries?

Categories

Resources