I'm trying to create a Firefox addon that adds a context menu item when right-clicking on pages.
I'm using the instructions on this MDN page:
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Context_menu_items
As per the instructions I've written a manifest.json to include the contextMenus permission:
{
"manifest_version": 2,
"name": "TestAddon",
"version": "0.1",
"description": "Test",
"icons": {
"48": "icons/icon-48.png"
},
"permissions": ["contextMenus"],
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["background-script.js"]
}
],
"browser_specific_settings": {
"gecko": {
"id": "sitetimelimiter#example.com",
"update_url": "https://example.com/updates.json"
}
}
}
...and in background-script.js I've written the code using the guidelines on that MDN article, with a few extra log lines for debugging:
console.log('mark 1');
browser.contextMenus.create({
id: "test-item",
title: "Test context-menu item",
contexts: ["all"],
}, onCreated);
console.log('mark 2');
browser.contextMenus.onClicked.addListener((info, tab) => {
switch (info.menuItemId) {
case "test-item":
alert("Test worked!");
break
}
});
console.log('mark 3');
As far as I can tell all of that is in line with the MDN doc.
When I go to about:debugging and click "Load Temporary Add-on..." to test the addon, it loads the addon without any errors.
But when I load a test page in the browser and right-click the page, the test item hasn't been added to the context menu.
Looking at the console, I can see that "mark 1" is shown, but "mark 2" and "mark 3" never get logged.
This seems to indicate a problem in this section here:
browser.contextMenus.create({
id: "timer-reset",
title: "Reset page timer",
contexts: ["all"],
}, onCreated);
...but I've triple-checked and that syntax seems to line up perfectly with the MDN doc.
I've also seen other MDN docs that instruct me to use browser.menus.create() instead of browser.contextMenus.create(), but I get the same results regardless of whether I use .menus or .contextMenus
What am I missing?
The issue is that you are trying to access browser.contextMenus in the content scripts. They are only available in a background script.
From MDN page you linked to:
You can then add (and update or delete) the context menu items in your extension's background script.
So you need to move that part of the code into a background script, in manifest.json:
"background": {
"scripts": ["background.js"]
}
Related
I am building a Chrome extension and I set up a context menu which will show up and check the items (images or text) that the user selects from a table in the extension's popup.
This is my code for creating the context menu in popup.js's window.onload:
chrome.contextMenus.removeAll();
chrome.contextMenus.create( {title: "Toggle Selected",
documentUrlPatterns: [ "chrome-extension://*/popup.html"],
contexts:["selection"], onclick: toggleselected} );
This is the function that gets called on the context menu's onclick - also in popup.js (simplified version):
function toggleselected(info, tab)
{
var selection = window.getSelection(),
q0 = document.querySelectorAll("[id^='id0']"),
q1 = document.querySelectorAll("[id^='id1']");
for (var i = 0; i < somearray.length; i++)
{
if (selection.containsNode(q1[i], true))
{
somearray[i].checked = !somearray[i].checked;
q0[i].checked = !q0[i].checked;
}
}
updatesomearrayinfo();
}
And this is my manifest.json file (again, simplified version):
{
"manifest_version": 2,
"name": "Extension Name",
"version": "1.0",
"description": "Random description",
"browser_action":
{
"default_icon":
{
"16": "icon16.png",
"32": "icon32.png",
"48": "icon48.png",
"128": "icon128.png"
},
"default_popup": "popup.html"
},
"background":
{
"scripts": ["somescript.js"],
"persistent": true
},
"permissions": ["contextMenus", "tabs", "downloads", "<all_urls>"]
}
Everything works fine and the context menu correctly shows up when needed ... except that it doesn't have the extension's own icon next to it, but the default Chrome extension icon (the grey one). What can be done to correct this behavior? The icons in my manifest are ok, one of them (the 16x16 pixels, I believe) is correctly shown on my extension button, and apart from others usually doing the whole context menu thing from event pages, using chrome.runtime.onInstalled, contextMenus.onClicked.addListener and other listeners (which I am reluctant to use, since I specifically need to work with the variables from popup.js - e.g. somearray and queries on popup's elements), I don't seem to be doing anything different than things done by other extensions or the code samples in the answers here on StackOverflow. And they all get their own extension icons shown, apparently without doing anything special.
EDIT: Also, does anyone knows why the context menu for a selection is triggered only when the selection contains more than one specific item (an image, in my case)?
I'm trying to create my first Edge extension after being forced to use the browser for a while and finding that I actually quite like it.
My extension just shows a new context menu entry on the page. The extension loads in Edge and appears in the extensions pane along with the meta data (description, version etc) but the context menu itself doesn't show when I right click the page.
Any one familiar with Edge extensions know why? Here's the code.
index.js
browser.contextMenus.create({
id: "MyMenu",
title: "My Context Item",
contexts: ['page']
});
browser.contextMenus.onClicked.addListener(function(info, tab) {
if (info.menuItemId == "MyMenu") {
Code goes here;
}
});
manifest.json
{
"manifest_version": 2,
"name": "MyMenu",
"version": "1.0.0",
"description": "My Menu.",
"author": "Oliver Marshall",
"permissions": ["contextMenus"],
"background": {
"scripts": ["index.js"],
"persistent": true
}
}
It's fairly boilerplate stuff, in fact it is boilerplate stuff.
Turns out that while the extension loads, context menu handlers appear to require a restart of the browser for the menu item to be created.
After reloading Edge, and re-enabling the extension, the context menu is showing.
Whenever my chrome extension icon is clicked, I want to run a script that would make certain changes to the current webpage.
I have tried using content_scripts in my manifest and it worked but the problem is , the script runs even if I did not clicked on the icon.
I have found that, I need to use background script.In my background.js file I have added
chrome.browserAction.onClicked.addListener(function(tab) {
alert();
});
and it is not working.
Here is my manifest file.
{
"manifest_version": 2,
"name": "Reveal Password",
"description": "Reveals password in password input field",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png"
},
"background": {
"scripts": ["background.js"]
}
}
Plus I want to execute the script that I made that manipulates the current web page too.
Use chrome.tabs.executeScript() to execute code in a tab like this:
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript({
code: 'alert("Hello")'
});
});
Instead of code, you could also use a file which contains the code :
chrome.tabs.executeScript(null, {file: "content_script.js"});
NOTE : You need activeTab permissions to execute code in an active tab
"permissions": [
"activeTab"
]
I have a working extension that allows me to check market prices of steam items.
You basically click the extension and then a prompt box opens and the item is inputted there.
It then opens up a new windows with the search query, displaying the market prices.
I would like to tweak it by displaying the list of items as a popup from the extension, like the default popup.
For that I need to know some stuff:
1) How do I call that popup function within the js code?
2) How do I open it so that it shows only what I need? like this, instead of showing the whole site.
Here are the codes:
manifest:
"manifest_version": 2,
"name": "CS:GO checker",
"description": "This extension checks market prices",
"version": "1.1337",
"permissions": [
"http://steamcommunity.com/market/"
],
"browser_action": {
"default_icon": "icon.png"
},
"background": {
"scripts": ["popup.js"],
"persistent": false
}
popup.js:
function test ()
{
var userInput=prompt("Please enter your item below:");
if (userInput!=null)
{
newwindow=window.open("http://steamcommunity.com/market/search?q="+userInput,userInput,'height=800,width=670');
if (window.focus) {newwindow.focus()}
return false;
}
}
chrome.browserAction.onClicked.addListener(test);
Thanks in advance!
edit: I forgot to mention that I'm very new to javascript, so if you have an answer, try to explain it very carefully to me that I could understand.
I'm trying a simple Chrome Extension example which should enable me change the background color of any open youtube tabs to red. What I've noticed is that the background of the page is only turned red if I'm on the actual page i.e. it is the active tab.
Code:
function getYouTubeTabs() {
queryInfo = {
'url': '*://www.youtube.com/*'
};
chrome.tabs.query(queryInfo, function (result) {
for (i = 0; i < result.length; i++) {
chrome.tabs.executeScript(result[i].id, {
code: 'document.body.style.backgroundColor="red"'
});
}
});
}
This is the code I have, I might be missing something. Not sure if executeScript could be used on 'non-active' tabs. Thanks in advance.
EDIT
manifest.json
{
"manifest_version": 2,
"name": "First menu item",
"description": "Testing Context Menus",
"version": "1.0",
"permissions": [
"contextMenus", "tabs", "activeTab"
],
"icons": {
"16": "myicon.png",
"128": "myicon2.png"
},
"background": {
"scripts": ["background.js"]
}
}
The activeTab permission, allows you to call tabs.executeScript or tabs.insertCSS on that tab.
On the contrary, in order to be able to programmatically inject code into an non-active tab, besides the tabs permission, your extension must have cross-origin permissions for the page.
So, you need to modify your manifest's permissions section like this:
"permissions": [
...
"*://www.youtube.com/*"
],
Adding "persistent": false in the background section should work fine as well (and is the preferred way).