I have this code to change my icon, but it only works when I click on it. How can I have the icon change as soon as the web page loads?
document.addEventListener('DOMContentLoaded', function () {
chrome.browserAction.setIcon({path: 'different_icon.png'});
});
You'll need to pass a message to the background page and change the icon there. For example, your manifest file would have this content script:
"content_scripts": [
{
"matches" : ["<all_urls>"],
"js" : ["content.js"],
"run_at": "document_end"
}
],
As you can see, it runs when the document is done loading. Your content script passes a message to the background page:
chrome.runtime.sendMessage({changeIcon: true});
And finally, your backgound page receives the message and changes the icon:
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.changeIcon) {
chrome.browserAction.setIcon({path: 'different_icon.png'});
}
}
);
Related
I created an extension for Google Chrome which runs a small userscript for designated web-page and makes some requests via background.js to the chrome APIs (such chrome.tabs and others).
now, I'm testing it locally in "Developer mode" like this:
I edit my userscript.js and background.js;
then I go to chrome://extensions tab in Google Chrome and manually reload (CTR+R) my extension from local D:\my-extension folder.
finally, I switch to the tab with designated web-page and reload it to see the changes.
the problem is:
since I'm a beginner, a lot of changes have to be done to my userscript.js and background.js before my extension and userscript start working as expected.
so, this process involves a lot of monotonous switching between extensions and page tabs while testing.
the idea is:
it would be nice to add a button or a shortcut key on the page where the userscript is being tested and attach a sort of 'update_extension_and_reload_page' function to it in my userscript, so that evey time when I click this button it will call extension update from the local folder D:\my-extension then followed by page reload. (another alternative would be to assign such 'update_extension_and_reload_page' function to extension's browser_action icon.)
now, I'm just interested:
is there any sort of 'chrome.extesion.update' method, so that I could make a request to it from my userscript.js via background.js and call automatic reload of the extension (in "Developer mode") without need to go to the chrome://extensions tab.
The extension can reload itself, by calling chrome.runtime.reload(), so it's a matter of triggering the extension to do it.
The code below attaches the following functionality to the browser-action button:
Keeps track of the active tab.
Reloads the extension.
Reloads the active tab.
manifest.json
...
"browser_action": {
"default_title": "Reload"
// "default_icon": {
// "19": "img/icon19.png",
// "38": "img/icon38.png"
// },
},
...
background.js
chrome.browserAction.onClicked.addListener(function (tab) {
localStorage.tabToReload = tab.id;
chrome.runtime.reload();
});
function reloadTab() {
var tabID = localStorage.tabToReload;
if (tabID) {
chrome.tabs.reload(parseInt(tabID));
delete(localStorage.tabToReload);
}
}
reloadTab();
...
See, also, this answer on how to automate the re-loading process.
is this what you are looking for?
https://chrome.google.com/webstore/detail/extensions-reloader/fimgfedafeadlieiabdeeaodndnlbhid
Credit goes go
How do I auto-reload a Chrome extension I'm developing?
slightly modified the ExpertSystem's code above to call reload of extension followed by reload of tab where the content script (userscript.js) is being performed, all triggered by #reload-btn button (in case the browser_action icon is occupied with popup.html).
manifest.json
...
"background":{ "scripts": ["background.js"]},
"content_scripts" : [{
"matches" : ["https://stackoverflow.com/*"],
"css": ["userscript.css"],
"js": ["jquery-latest.min.js", "userscript.js"],
"run_at":"document_end"
}],
"web_accessible_resources": ["jquery-latest.min.map"],
"permissions": ["tabs"],
"browser_action": {
"default_icon": "icon19.png",
"default_title": "My Extension Title",
"default_popup": "popup.html"
}
...
userscript.css
...
#reload-btn { position: fixed; top: 0; right: 0; } /* or any other position on the page */
...
userscript.js
...
$("body").prepend("<button id='reload-btn'>reload extension + page reload</button>"); // some shortcut key can be additionally assigned to this button
$("#reload-btn").on("click", function() {
chrome.runtime.sendMessage("please, reload me");
});
...
background.js
...
chrome.runtime.onMessage.addListener(
function(message, sender) {
if (message == "please, reload me"){
localStorage.tabToReload = sender.tab.id;
chrome.runtime.reload();
}
});
function reloadTab() {
var tabID = localStorage.tabToReload;
if (tabID) {
chrome.tabs.reload(parseInt(tabID));
delete(localStorage.tabToReload);
}
}
reloadTab();
...
I created a Chrome extension that works as expected except that it only executes when I load a page that matches the conditions in the manifest. I have tried for hours to make it execute by clicking on the extension icon to no avail.
The closest I have been able to what I want is that I have been able to make the extension icon click to run the code, but then it does not run it on the loaded page. It runs it on the extension's space instead of the page DOM.
In the current state my code only runs when a page in the specified domain opens. I want to run it only when it matches that rule, but only when I click the extension icon.
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"
},
"content_scripts": [{
"js": ["contentscript.js"],
"matches": ["http://mydomain.com/*"]
}]
}
contentscript.js
if (document.getElementsByName("returnURL")){
alert("\nThe Response URL on this form is:\n\n" + document.getElementsByName("returnURL")[0].value);
}
As i see you want to run code when
User has clicked on Browser Action ICON and
URL pattern is a match
If so, you have use
Background pages in conjunction with Tabs API.
Demonstration
This is a sample demonstration of your use case and you can put all your code and assign permissions for all match URL(s).
manifest.json
Registered Background Page, Browser Action and Permissions for Target Pages.
{
"name": "Get Response URL",
"version": "1.0",
"manifest_version": 2,
"browser_action": {
"name": "Click to get URL"
},
"background":{
"scripts":["background.js"]
},
"permissions":["https://www.google.co.in/*"] //Put All your URL here
}
background.js
Put all Your Target Matching URL in a series of if conditions here
chrome.browserAction.onClicked.addListener(function (tab) { //Fired when User Clicks ICON
if (tab.url.indexOf("https://www.google.co.in/") != -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
alert("Code Executed ... ");
Output
When you browse to https://www.google.co.in/ and after click of browser action you see Alert in the page.
References
Tabs API
Background Pages
use browserAction API ,see here
the onClick events may help you. also see these exsamples from google :
I'm writing a simple Chrome extension that displays a JavaScript alert saying "Hello World". In this example I have specified that the extension will only run for google.com (by putting this in the permissions property within manifest.json).
Even after everything in the target page has loaded, the alert doesn't appear. Here is my script so far:
File: manifest.json
{
"name": "Hello",
"version": "1.0",
"description": "Says hello to Google",
"permissions": ["http://*.google.com/"]
"browser_action": {
"popup": "Hello.html"
}
}
File: Hello.html
<script language="Javascript">
alert("Hello World");
</script>
You are adding a browser action popup, which adds a button to the top-right of your browser. (It's probably invisible because you haven't specified an image for it. There should be some empty space to the right of your address bar; try clicking it to see your Hello.html in a popup.)
What you want is a content script. Content scripts can get injected into every page that Chrome loads. You can use the matches and exclude_matches sub-items in your manifest file to specify which pages get your injected script.
{
"name": "Hello",
"version": "1.0",
"description": "Says hello to Google",
"permissions": ["tabs", "*://*.google.com/*"],
"content_scripts": [
{
"matches": ["*://*.google.com/*"],
"js": ["hello.js"]
}
]
}
Make sure you rename Hello.html to hello.js (and get rid of the <script> tags).
Note also that I changed your http://*.google.com/ to *://*.google.com/* so that it will apply to Google over HTTP and HTTPS (and the trailing * ensures that it will apply to all pages on google.com, not just the main page).
I came across this answer trying to find a way to only enable the icon on certain pages this is how I did it. Docs
background.js
chrome.runtime.onInstalled.addListener(function() {
chrome.tabs.onActivated.addListener(async info => {
const tab = await chrome.tabs.get(info.tabId);
const isGithub = tab.url.startsWith('https://github.com/');
isGithub
? chrome.action.enable(tab.tabId)
: chrome.action.disable(tab.tabId);
});
});
make sure to add tabs permission in manifest
First of all there are 2 types of extensions:
1. Browser Action - which work for multiple websites or almost all websites
2. Page Action - which work for specific websites or webpages [which is needed
in our case]
Follow these steps to show your extension only on google:
Step 1: Go to manifest.json file and add the below code snippet
"background":{
"scripts":["background.js"],
"persistent":false
}
***also make sure you have page action not browser action**
"page_action" : { "default_popup":"your_popup.html" }
Step 2: Now add permissions in manifest:
"permissions":["declarativeContent"]
Step 3: Now create background.js in root folder of extension and add the
below code in it, this will let the extension to work only on
urls that contain google.com
// When the extension is installed or upgraded ...
chrome.runtime.onInstalled.addListener(function() {
// Replace all rules ...
chrome.declarativeContent.onPageChanged.removeRules(undefined,
function() {
// With a new rule ...
chrome.declarativeContent.onPageChanged.addRules([
{
// That fires when a page's URL contains a 'g' ...
conditions: [
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { urlContains: 'google.com' },
})
],
// And shows the extension's page action.
actions: [ new chrome.declarativeContent.ShowPageAction() ]
}
]);
});
});
Step 4: Now reload your extension, you'll find that your extension will work
only for google.com
Hope this solved your query, If Yes, then Upvote the answer Thanks!
I'm trying to write a trivial Chrome pageAction extension to change all anchors on a page from one domain to another... but I can't quite seem to get it to work, and I'm having trouble debugging it.
Am I misunderstanding how this kind of extension needs to be built? Or am I just misusing the API?
manifest.json:
{
"name": "theirs2ours",
"version": "1.0",
"description": "Changes all 'their' URLs to 'our' URLs.",
"background_page": "background.html",
"permissions": [
"tabs"
],
"page_action": {
"default_icon": "cookie.png",
"default_title": "theirs2ours"
},
"content_scripts": [
{
"matches": ["http://*/*"],
"js": ["content.js"]
}
]
}
background.html:
<html>
<head>
<script type='text/javascript'>
chrome.tabs.onSelectionChanged.addListener(function(tabId) {
chrome.pageAction.show(tabId);
});
chrome.tabs.getSelected(null, function(tab) {
chrome.pageAction.show(tab.id);
});
chrome.pageAction.onClicked.addListener(function(tab) {
chrome.tabs.sendRequest(tab.id, {}, null);
});
</script>
</head>
<body>
</body>
</html>
content.js:
var transform = function() {
var theirs = 'http://www.yourdomain.com';
var ours = 'http://sf.ourdomain.com';
var anchors = document.getElementsByTagName('a');
for (var a in anchors) {
var link = anchors[a];
var href = link.href;
if (href.indexOf('/') == 0) link.href = ours + href;
else if (href.indexOf(theirs) == 0) link.href = href.replace(theirs, ours);
}
};
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
transform();
});
I think this is not the way to do the extension you want.
First of all, I assume you want to replace the anchors when you click the page action button.
The manifest you have injects content.js on every page, no matter if you click or not the page action button.
I suggest you remove the content_scripts field from your manifest, and inject content.js manually, with
chrome.tabs.executeScript(tabId, {file:'content.js'})
You should do this in the page action's click listener.
By the way, in that listener you are sending a request to the content script, but it hasn't a listener to listen to such request message. In this extension you won't need to use senRequest.
You're not requesting permission to run content scripts on these pages. The matches for content scripts determines what pages they are executed in but you still need to request permission to inject scripts in to these pages.
"permissions": [
"tabs",
"http://*/*"
]
this is my manifest.json file
{
"name": "My First Extension",
"version": "1.0",
"description": "The first extension that I made.",
"background_page": "background.html",
"page_action":
{
"default_icon": "icon.png"
},
"permissions" : [
"tabs"
]
}
This is the background.html
<html>
<head>
<script>
// Called when the url of a tab changes.
function checkForValidUrl(tabId, changeInfo, tab) {
// If the letter 'page' is found in the tab's URL...
if (tab.url.indexOf('google') > -1) {
// ... show the page action.
chrome.pageAction.show(tabId);
}
};
// Listen for any changes to the URL of any tab.
chrome.tabs.onUpdated.addListener(checkForValidUrl);
chrome.pageAction.onClicked.addListener(function(tab)
{
tab.url = 'www.bing.com';
console.log('I am clicked');
}
);
</script>
</head>
</html>
when i click on the page action icon , i want to redirect the page to Bing.com, but this click event is not working for me.
Thanks
If you want to redirect a tab you need to use:
chrome.tabs.update(tab.id, {url: "http://www.bing.com"});
You also need to check for status of the page as checkForValidUrl will be executed twice for every page:
function checkForValidUrl(tabId, changeInfo, tab) {
if(changeInfo.status === "loading") {
//...
}
});
Have u tried using javascripts window.location function instead? e.g:
window.location="http://www.bing.com";
If that doesn't work then it's probably a problem with your event listener I would have thought.