I made a Chrome extension that, when you click the icon, background.js, executes the content script and changes from the "off" icon to the "on" icon.
The problem is, when I disable the extension, and then re-enable, the content script isn't loaded, but the icon is still showing as "on" when I want it to default to "off" so the user knows they need to re-click to activate.
Here is my background.js script:
var turnedOff = true;
var loadScript = true;
chrome.runtime.onStartup.addListener(function () {
chrome.browserAction.setIcon({path:"red.png"});
});
chrome.browserAction.onClicked.addListener(function (tabId, changeInfo, tab) {
if (loadScript == true) {
loadScript = false;
chrome.browserAction.setIcon({path:"green.png"});
chrome.tabs.query( {} ,function (tabs) {
for (var i = 0; i < tabs.length; i++) {
chrome.tabs.executeScript(tabs[i].id, {file: "content.js"});
}
});
}
else if (turnedOff == true) {
turnedOff = false;
chrome.browserAction.setIcon({path:"green.png"});
chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
chrome.tabs.sendMessage(tabs[0].id, {action: "On"}, function(response) {});
});
}
else if (turnedOff == false) {
turnedOff = true;
chrome.browserAction.setIcon({path:"red.png"});
chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
chrome.tabs.sendMessage(tabs[0].id, {action: "Off"}, function(response) {});
});
}
});
And here is my manifest.json:
{
"background": {
"scripts": [ "background.js", "jquery-3.1.1.min.js" ],
"persistent": false
},
"browser_action": {
"name" : "hjfdsfhdks"
},
"icons" : {
"16" : "red.png",
"48" : "red.png",
"128" : "red.png"
},
"description": "Replace Facebook color-background posts with Kanye West quotes to match the bold, brazen, attention-grabbing aesthetic.",
"manifest_version": 2,
"name": "Ye'sbook",
"permissions": [ "<all_urls>" ],
"update_url": "https://clients2.google.com/service/update2/crx",
"version": "1.2",
"web_accessible_resources": [ "images/*.png" ]
}
Pardon if it doesn't look very clean, I am just trying to get it to work before refactoring and am new to Chrome extensions.
Worth noting: background.js reloads properly when closing down Chrome entirely, but not on re-enabling. Also, the reason I have my content script loading in background as opposed to having manifest.json handle is, I want this event to take place immediately upon clicking as opposed to only having the content script load on the page refresh.
Related
I'm trying to send a message from the background script to the content script and it doesn't work, tried multiple solutions I found but none of them work.
I checked that the background and content scripts both work correctly.
I tried to use chrome.runtime\extention and also with message and request...
hope you could tell me what I'm doing wrong.
manifest:
{
"manifest_version": 2,
"name": "ChangeLang",
"description": "change written text lang",
"version": "1.3",
"permissions": ["storage", "contextMenus", "activeTab", "tabs"],
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"browser_action": {
"name": "Click to change the icon's color"
},
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["changelang.js"]
}],
"background": {
"scripts": ["background.js"]
}
}
background.js:
chrome.browserAction.onClicked.addListener(function(info, tab) {
alert("click"); // this alert works
chrome.tabs.sendMessage(tab.id, {
"functiontoInvoke": "change"
});
alert("click"); // this alert doesn't works
});
content.js:
function changeLang() {
// do something
}
chrome.runtime.onMessage.addListener(function(message, sender, callback) {
alert("msg"); // never worked
if (message.functiontoInvoke == "change") {
changeLang();
}
});
I think your code setup should look like this:
chrome.browserAction.onClicked.addListener(function(info, tab) {
alert("click"); // this alert works
chrome.tabs.sendMessage(tab.id, {
"functiontoInvoke": "change"
}, function(response) {
response.yourFunc();
});
alert("click"); // this alert doesn't works
});
chrome.runtime.onMessage.addListener(function(message, sender, callback) {
alert("msg"); // never worked
if (message.functiontoInvoke == "change") {
callback({yourFunc: changeLang()});
}
});
My extension checks for broken images on a website. Everything works fine if I open an URL at a time but if I open several URLs from one site, the summary in popup.html is always the same as the active tab (it's not updated for each site).
I don't know how to refer to the actual URL of the analysis and avoid the "active tab". Any ideas?
Manifest.json
{
"name": "Test",
"permissions": ["activeTab", "declarativeContent", "storage","tabs"],
"version": "1.0.0",
"description": "Test",
"background": {
"scripts": ["background.js"],
"persistent": false
},
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*", "https://www.google.com/_/chrome/newtab*"],
"exclude_globs": ["*#*"],
"js": ["jquery-3.4.1.min.js", "content.js"]
}
],
"web_accessible_resources": ["popup.html"],
"browser_action": {
"default_icon": {
"16": "images/ico.png",
"32": "images/ico.png",
"48": "images/ico.png",
"128": "images/ico.png"
}
},
"manifest_version": 2
}
Content.js
chrome.runtime.onMessage.addListener((msg, sender, response) => {
if (msg.subject === 'DOMInfo') {
var domInfo = {
images: number_images
};
response(domInfo);
}
});
Popup.js
window.addEventListener('DOMContentLoaded', () => {
chrome.tabs.query({
active: true,
currentWindow: true
}, tabs => {
chrome.tabs.sendMessage(
tabs[0].id,
{subject: 'DOMInfo'},
setDOMInfo);
});
});
I'm pretty sure is the tabs[0].id that causes the problem but I'm not sure how I can refer to the current URL that run the content.js script and make sure the popup.html gets the analysis from this URL. Any ideas?
In the background.js I had no problem referring the sender tab:
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse)
{
chrome.tabs.query({active:true, windowType:"normal", currentWindow: true},function(d){
var tabId = sender.tab.id;
....
Assuming popup.html is loaded into an iframe inside the web pages by your content script, you need chrome.tabs.getCurrent that returns the tab where this code is running so each iframe will find its own tab:
chrome.tabs.getCurrent(tab => {
chrome.tabs.sendMessage(tab.id, {subject: 'DOMInfo'}, callback);
});
P.S. When using sender.tab.id you don't need chrome.tabs.query - you already have the id.
I'm working on migrating my Chrome extension into a Firefox addon. Honestly didn't think it would be that hard, but I've been trying to fix an issue of the background not wanting to send a message to the content script. (And yes, I've read everything online, but it just won't send the message inside an onUpdated listener)
EDIT
When I tried to put following line into the browserAction.onClicked listener it works, but it does not work in onUpdated?
browser.browserAction.onClicked.addListener(function(tab) {
browser.tabs.sendMessage(tab.id, {action: "isInstalled"});
});
END EDIT
And yes, the content script IS loaded, checked with an alert for the hostname.
Here's the code I used in the Chrome extension (background):
chrome.tabs.query({active: true, currentWindow: true}, ([tab]) => {
chrome.tabs.sendMessage(tab.id, {
action: 'isInstalled'
});
});
Now here's what I have tried in Firefox addon (background):
var gettingActiveTab = browser.tabs.query({active: true, currentWindow: true});
gettingActiveTab.then((tabs) => {
browser.tabs.sendMessage(tabs[0].id, {greeting: "hello"});
});
Which is inside the browser.tabs.onUpdated listener as follows:
browser.tabs.onUpdated.addListener(function(tabId, changeInfo, tabInfo){
if(changeInfo.status === "complete"){
...
}
});
I also tried this, as I thought it would work: (yes tabId is correct).
browser.tabs.sendMessage(tabId, {action: "isInstalled"});
Now here's the onMessage listener on content script
browser.runtime.onMessage.addListener(function(request, sender) {
if(request.action == "isInstalled"){
alert("received");
var isInstalledNode = document.createElement('div');
isInstalledNode.id = 'extension-is-installed';
document.body.appendChild(isInstalledNode);
}
});
I keep getting the following error: "Error: Could not establish connection. Receiving end does not exist." which makes absolutely no sense for me.. Can anyone see the problem?
By the way, here's the manifest file:
{
"name": "Addon name",
"version": "1.3.0",
"manifest_version": 2,
"description": "...",
"icons": {
"48": "assets/images/icon_48_active.png",
"96": "assets/images/icon_96_active.png"
},
"browser_action": {
"default_title": "Name"
},
"background": {
"scripts":["background.js"]
},
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*"],
"js": ["contentscript.js"]
}
],
"permissions": [
"cookies", "tabs", "http://*/*", "https://*/*"
],
"web_accessible_resources": [
"modal.html", "assets/images/*"
]
}
I am trying to build an omnibox extension. Essentially I want this extension to pull up a url, then wait for that url to load, then execute some simple javascript.
Not sure if it's appreciated to put long blocks of code in questions, please feel free to yell at me if not.
manifest.json:
{
"manifest_version": 2,
"name": "AutoATR",
"version": "0.1",
"omnibox": { "keyword" : "atr" },
"icons": {
"16": "package.png"
},
"background": {
"persistent": true,
"scripts": ["background.js"]
}
}
background.js:
function resetDefaultSuggestion() {
chrome.omnibox.setDefaultSuggestion({
description: 'atr: Placeholder: %s'
});
}
resetDefaultSuggestion();
function navigate(url) {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs)
{
chrome.tabs.update(tabs[0].id, {url: url});
});
}
function finder(theID) {
document.getElementById('theElement').value=theID
document.getElementsByClassName('btn')[1].click()
}
chrome.omnibox.onInputEntered.addListener(function() {
// Navigate to URL
navigate("https://theURL.com");
});
// **** Would like to wait for just this tab to load.
// Then Execute finder(). ****
You can use manifest for your task:
change location in background script location of tab to your pathURL and in manifest.json add next code :
"content_scripts": [{
"matches": ["http://pathURL"],
"js": ["js/script.js"]
}]
js/script.js will be loaded after your browser tab path will match with "http://pathURL" pattern.
I will be very grateful to you for your help!
I looked through a lot of similar topics, but these answers did not help me.
I create the expansion for google chrome, and I have to make a click on the icon open a new window with textarea, in this text area I have to write a message and send it to first user on list.
My manifest.json:
{
"name": "Linkedin Chrome Extension",
"version": "1.0",
"manifest_version": 2,
"description": "This extension send message to Likedin users",
"minimum_chrome_version": "26",
"offline_enabled": true,
"icons": {
"16": "img/Spider-16.png",
"48": "img/Spider-48.png",
"128": "img/Spider-128.png" },
"content_scripts": [
{
"js": [
"js/jquery-3.2.0.min.js",
"js/content.js"
],
"matches": [
"https://www.linkedin.com/*",
"<all_urls>"
],
"run_at":
"document_idle",
"all_frames": false
}
],
"background": {
"persistent": false,
"scripts": [
"js/background.js"
]
},
"web_accessible_resources": ["js/main.js", "index.html"],
"permissions": [
"storage",
"<all_urls>",
"tabs",
"activeTab",
"https://www.linkedin.com/*",
"*://*/*",
"notifications"
],
"browser_action": { // broser elements
"default_title": "Linkedin Extension"
},
"externally_connectable": {
"matches": ["https://www.linkedin.com/*"]
}
}
background.js
chrome.browserAction.onClicked.addListener(function (tab) {
// if (tab.url.indexOf('https://www.linkedin.com') == -1) {
// alert('Please go to Linkedin.com, and run this extensions');
// }else{
chrome.tabs.create({
url: chrome.runtime.getURL('index.html'),
active: false
}, function (tab) {
chrome.windows.create({
tabId: tab.id,
type: 'popup',
focused: true,
width: 625,
height: 400,
top: 50
});
});
chrome.tabs.executeScript(null, {file: "js/jquery.js"});
chrome.tabs.executeScript(null, {file: "js/content.js"});
// chrome.tabs.executeScript(null, {file: "js/main.js"});
});
chrome.runtime.onMessage.addListener(function (message_from_content, sender, sendResponse) {
if (message_from_content == 'start'){
chrome.tabs.executeScript(null, {file: "js/main.js"});
console.log(message_from_content);
}
});
content.js
document.getElementById('btnStart').onclick = function () {
var text = document.getElementById('text').value;
// var message = text.replace( '{name}', 'nick');
setTimeout(function () {
chrome.storage.local.set({
'msg': text
});
}, 1000);
};
document.addEventListener('click', function () {
chrome.runtime.sendMessage('start', function (response) {
});
}, false);
main.js
setTimeout(function () {
getData();
}, 1000);
function getData(){
chrome.storage.local.get(['msg'], function (result) {
var text_of_message = result.msg;
//alert(m);
handler(text_of_message);
});
}
var list = $("#results-list").find('.result');
function handler(message) {
$.each(list, function (key, value) {
if (key == 0){
var users_name = $(value).find('.name').find('a').text(); // get name of users
var new_message = message.replace( '{name}', users_name);
$(value).find('.action-trigger').find('li').click(); //get button for open dropdown
$(value).find('.send-message').click(); //click button for send message
$("#subject").val("we are the best IT company in the world");
$("#message-body-content").val(new_message);
}
});
}
I try get some message if button "btnStart" click, and open file main.js, but I get error in console:
Unchecked runtime.lastError while running tabs.executeScript: Cannot access contents of url "chrome-extension://mkeifaecfbamfcillngajldbnaedpepg/index.html". Extension manifest must request permission to access this host.
at chrome-extension://mkeifaecfbamfcillngajldbnaedpepg/js/background.js:33:21
If you now the solution of this problem plese help, and sorry for my English.