Cant send message from background script to content script - javascript

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()});
}
});

Related

Popup.html is the same in all tabs (Chrome extension)

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.

How to change text bold using chrome extension?

I am a programming beginner. I would like to develop a simple Chrome extension that allows to bold for dragged content, when I click a button in popup.html. I succeeded to make bold for dragged content, when I click a default icon, but making a button in popup.html with the function required more complex way.
I think that popup.js is necessary to send a message to content.js to trigger the function boldText(). I struggled to use chrome.tabs.sendMessgge or other things to trigger the function, but I failed.
Please give me some advice.
Here is my code:
1. manifest.json
{
"manifest_version": 2,
"name": "test",
"version" : "1.0",
"description": "test",
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["content.js"]
}],
"background": {
"scripts": ["jquery-3.3.1.slim.js", "background.js"]
},
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"permissions": [
"activeTab",
"tabs",
"storage",
"http://*/*",
"https://*/*"
]
}
2. background.js
chrome.browserAction.onClicked.addListener(buttonClicked);
function buttonClicked(tab) {
let msg = {
txt: "hello"
}
chrome.tabs.sendMessage(tab.id, msg);
}
3. content.js
chrome.runtime.onMessage.addListener(gotMessage);
function gotMessage(message, sender, sendResponse) {
if (message.txt === "hello") {
var selection = window.getSelection();
alert(selection);
boldText();
}
}
function boldText() {
document.designMode = "on"; // designMode on for execCommand
document.execCommand('Bold', false);
document.designMode = "off"; // designMode off for execCommand
return false;
}
4. popup.html
<!doctype html>
<html>
<head>
<script src="jquery-3.3.1.slim.js"></script>
<script src="popup.js"></script>
</head>
<body>
<button id="boldButton" value="bold">bold</button>
</body>
</html>

Firefox addon: sendMessage not working in tabs.onUpdated but does in browserAction.onClicked (background.js)

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/*"
]
}

Unchecked runtime.lastError while running tabs.executeScript: Cannot access contents of url

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.

google chrome extension browserAction.onClicked

i can't figure out how to make it work. My script works by itself. but doesn't work with background.js. I want my google extension to work only if the user clicks on it's icon, so I have created the file background.js and putted the code:
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(null, {file: "change_content.js"});
});
my manifest.json here:
{
"manifest_version": 2,
"name": "Name",
"description": "change content.",
"version": "3.0",
"browser_action": {
"default_icon": "icon.png"
},
"content_scripts": [
{
"matches": ["http://*/*"],
"js": ["change_content.js"]
}
],
"background": {
"scripts": ["background.js"],
"persistent": false
},
"permissions": [
"tabs", "http://*/*"
]
}
and here is the change_content.js:
var oldSource = document.documentElement.innerHTML;
document.body.innerHTML = changeContent(oldSource);
function changeContent(source){
.....
}
The reason you are having the issue where change_content.js is executing before you press the button is because thats how content scripts work. If you include a content script in your manifest.json it will load and execute that script. Try removing the "content_scripts" section from the manifest and you should see it work as it should.
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(null, {file: "change_content.js"});
});
I've got a feeling the error lies in you using "null" as it might be searching for a tab with the tabId - null, you should try doing this instead?
chrome.tabs.executeScript({file: "change_content.js"});

Categories

Resources