Is there a way to add a page_action in an extension that already implements browser_action?
I'd like to use the browser_action to display a popup with a list of bookmarks while use the page_action to give the user a way to bookmark the current page and load it in the list.
You can only have one among app, browser_action, page_action and theme in your manifest till date. So, you can not have browser action and page action together.
// Pick one (or none)
"browser_action": {...},
"page_action": {...},
"theme": {...},
"app": {...},
Work Around
Use two different Extensions with cross extension message communication.
References
Manifest File
Related
So I got this piece of code from my extension (I'm currently using webextension polyfill), it successfully creates the context menu and it's accessible when in foo.bar,
The issue is in the browser_action context menu, it's always there, I've specifically declared "page" as context when creating the contextMenu,:
browser.contextMenus.create({
id: "some-id",
title: "context menu message",
documentUrlPatterns: ["*://foo.bar/*"],
contexts: ["page"]
});
According to docs, I should add "browser_action" to make it appear in the browser_action context menu, however I've not included it yet always appear there, even if the current URL doesn't match documentUrlPatterns.
This only happens on chrome based browsers, it works perfectly in firefox.
I wrote a contextual menu-based Chrome extension. It allows me to save a music track being played by the radio as a favorite. I want this menu item to be available only when a tab with a specific matching URL of the radio player is open anywhere (doesn't have to be active or currentWindow). Obviously, the menu item should also be hidden from the menu when this radio player has closed.
documentUrlPatterns on a menu item doesn't work that way - it only shows the item on the matching pages. My goal is to be able to save the favorite without having to switch to the radio tab first.
My guess is that I should listen to tabs.onCreated/onUpdated/onRemoved with the player's url. Perhaps also to onReplaced. But is there a better, more "lazy" way to achieve that?
Use webNavigation API with event filters for the URL. Event filters are registered inside Chrome itself so it wakes up the background script with "persistent": false only when the filter is matching. Note that filters use different syntax, not like normal matching patterns, as you can see in the example below and in each event's documentation.
const filters = {
url: [{
hostEquals: 'www.example.com',
queryContains: 'foo=bar',
}]
};
chrome.webNavigation.onCompleted.addListener(onNavigation, filters);
chrome.webNavigation.onHistoryStateUpdated.addListener(onNavigation, filters);
chrome.webNavigation.onReferenceFragmentUpdated.addListener(onNavigation, filters);
function onNavigation(info) {
console.log(info);
// modify your context menu here
}
manifest.json's should of course have "permissions": ["webNavigation"]
I successfully created my first Chrome extension. It now runs only when the extension icon is clicked instead of on the background, and that is great. However, I would like to add more actions to my extension I have been trying to use an extension popup to run other functions but I can't make it work. It doesn't have to be like that, so I am open for suggestions. I do not want to use context menus. I want people to click on the extension icon and show them a "menu".
Right now my extension only alerts a message when it finds a valid page (from mydomain.com), and it finds a hidden field with the name "returnURL". It alerts the value.
I would like to be able to add the ability to click on the icon but instead show an options menu with multiple options.
Something like this:
Click on the extension icon and show two options
Get Response URL (this option will run the current functionality I have now)
Do something else (So I could have another function to execute on the
loaded page)
...and more options if I needed to add them on future versions of my extension.
How do I modify my extension to do that.
Here is my code:
manifest.json
{
"name": "Get Response URL",
"version": "1.0",
"manifest_version": 2,
"browser_action": {
"default_icon": "mkto_icon.png",
"name": "Click to get URL"
},
"background":{
"scripts":["background.js"]
},
"permissions":["http://mydomain.com/*"]
}
background.js
chrome.browserAction.onClicked.addListener(function (tab) { //Fired when User Clicks ICON
if (tab.url.indexOf("http://mydomain.com/") != -1) { // Inspect whether the place where user clicked matches with our list of URL
chrome.tabs.executeScript(tab.id, {
"file": "contentscript.js"
}, function () { // Execute your code
console.log("Script Executed .. "); // Notification on Completion
});
}
});
contentscript.js
if (document.getElementsByName("returnURL")){
alert("\nThe Response URL on this form is:\n\n" + document.getElementsByName("returnURL")[0].value);
}
I followed the documentation I found on the Google Extensions developer site but I couldn't make it work. Your help is much appreciated.
You cannot have a real menu with a Chrome extension. You can however show an HTML page when the button is clicked (a pop-up). You can style this HTML page in a way that looks similar to a menu:
"browser_action": {
"default_icon": "mkto_icon.png",
"default_title": "Click here to open menu",
"default_popup": "popup.html"
},
Add a file popup.html to you extension and whatever content you want to show up. Scripts loaded by the pop-up page can load content scripts and communicate with them just like the background page.
For reference: browser actions documentation.
I'm not getting how to pass data between content script and page action popup.
I've started with the following simple skeleton, that shows an page action for any page having a minus-dash in title:
Extension manifest (manifest.json):
{
…
"permissions": ["http://example.org/*"],
"background": {"scripts": ["background.js"]},
"page_action": {"default_popup": "popup.html", …},
"content_scripts": {
"matches": ["http://example.org/*"],
"js": ["content.js"]
}
}
Background script (background.js):
chrome.extension.onRequest.addListener(function (msg, sender, respond) {
if (msg && msg.what === "match") {
console.log("Match:", msg.title);
chrome.pageAction.show(sender.tab.id);
}
}
Content script (content.js), checking document titles:
var title = document.title;
if (title.indexOf("-") >= 0) {
chrome.extension.sendRequest({"what": "match", "title": title});
}
Now, in a page action's popup, I want to show matched page's title. Not the last loaded page's title (as would be done by using this answer), but the title of the active tab.
My first though was to send a query to the content script, but according to documentation chrome.extension.sendMessage will send it to all listeners (i.e. all my content scripts on all tabs), without any clear definition on whose response I'll receive back. Also, I can't use chrome.tabs.sendMessage as it requires tabId. Trying to find the current tab using chrome.tabs.getCurrent will return null, as the query comes from non-tab context (from a popup).
I guess I could probably use chrome.tabs.executeScript to communicate, but this just feels dirty.
Still, I believe, this is a basic thing that should be very simple to do and I'm just missing something. Could someone, please, help me, preferably, with an example code?
Update: I've found Mappy example extension and it uses chrome.tabs.onUpdated to keep track of the active tab. This, unfortunately, requires tabs permission. Personally, I'd like to use least privileges possible.
So, is it just unfortunately bad permission system design and I have no choice but to do it this way, or there's any workaround? I'd be happy if chrome.pageAction.onClicked event handler (which provides Tab object that I need) would allow me to show a popup...
I think you need to add the onClick event listener in your popup:
chrome.pageAction.onClicked.addListener(function(tabs.Tab tab) {...});
See documentation here.
Callback of the event listener would provide you the tabId which would surely be the active tab.
There are multiple Problems in your code
chrome.extension.sendRequest in chrome.extension.sendRequest({"what": "match", "title": title}); is deprecated
chrome.pageAction.onClicked will not fire when you have "page_action": {"default_popup": "popup.html", …}, in your manifest.
chrome.extension.sendMessage will send it to all listeners (i.e. all my content scripts on all tabs), is an invalid assumption, it will send to Extension Pages.
I tried to read your question multiple times but couldn't understand what is you want to achieve, could you explain it?
I would like to know if the following is possible - I'm having trouble finding information regarding my question on the web. I was looking into creating a Google Chrome extension to work with a webpage, until I realized that the page was in fact built with flash. Originally I wanted to bind an onClick event for an input on the webpage to display a form (which would be through the extension I'm building).
However, because the page is build in flash I no longer believe that this will be a possibility. So, my next idea was to bind the form's loading to a certain combination of keys (ctrl + d) for example, that the user would click.
For example:
The user is using the flash form with my extension running in the background. The user focuses on an input (text box let's say) and proceeds to click the keys (Ctrl + D). Upon clicking these keys, my extension pops open a web-form. The user types in what he wants in the form and then clicks "Save" - A submit button on my web-form. When the user clicks 'save', the data from the web-form is stored in the clipboard and the form closes. Finally, the focused input is filled in with the data from the clipboard.
Two questions:
Do Google Chrome extensions support key binding like this?
Will I be able to copy input from my generated form (through the extension) and paste it back into the input field on the flash page?
1. Do Google Chrome extensions support key binding like this?
Yes, you can specify custom key board shortcuts catered to platform using chrome.commands API.
You can directly trigger browser action\page action popup page or do any customized functionality by defining a key.
Sample Code of manifest
{
"sample": {
"suggested_key": {
"default": "Ctrl+Shift+S",
"windows": "Ctrl+Shift+P"
},
"description": "Thisismycustomkeyforchromeextension"
},
"_execute_browser_action": {
"suggested_key": {
"windows": "Ctrl+Shift+Y",
"mac": "Command+Shift+Y",
"chromeos": "Ctrl+Shift+U",
"linux": "Ctrl+Shift+J"
}
}
}
However, maximum of 4 keys are supported so far! For further information refer this answer
2. Will I be able to copy input from my generated form (through the extension) and paste it back into the input field on the flash page?
Yes, with combination of content scripts and message passing it is possible.
References
Content Scripts
Background Pages
Message Passing
Commands API