Chrome extension message passing between content and background - javascript

I've been testing this for a few good hours, I've also taken a, known to work at the time, example. See here:
https://stackoverflow.com/a/27829709/2430488
Its just not working for me or I'm not sure how to test. I'm opening the developer tools, and also the extension developer tools, but nothing is being logged in either window.
The code I'm using:
manifest.json
{
"manifest_version": 2,
"name": "Some test",
"description": "https://stackoverflow.com/questions/27823740",
"version": "0",
"background": {
"scripts": [
"background.js"
]
},
"permissions": ["tabs", "<all_urls>"],
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["cont.js"]
}
]
}
cont.js
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
if (msg.message && (msg.message == "DIMENSION")) {
var dimension = getPageDiemension(document.documentElement);
console.log('Dimension:', dimension);
sendResponse(dimension);
}
return true;
});
getPageDiemension = function(currentDom){
return {
x: 0,
y: 0,
w: currentDom.scrollWidth,
h: currentDom.scrollHeight
}
}
background.js
getPageDimension = function (){
chrome.tabs.query({active: true, highlighted: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, { message: "DIMENSION" }, function(response){
if (response !== null) console.log('Response:', response);
else console.log('Response is null');
});
});
};
Please help, I really am not sure what I'm doing wrong, I've been looking at the documentation for the last few hours but I can't understand why is not working.
Thank you.

As rsanchez mentions, your background defines a function getPageDimension.
It is then never called, so your extension does exactly nothing. There doesn't seem to be any error, you just never do anything.
You need to bind a call to getPageDimension to some event, e.g. clicking a Browser Action.

Related

How to activate/deactivate chrome extension with keyboard shortcut (development)

I'm trying to set a keyboard shortcut to active/deactivate my Chrome extension that I'm developing. The Chrome extension just consists of a "content_script" that runs on certain sites. I want it to fully activate/deactivate the extension, like if I were to disable it via Chrome://extensions.
In my search for answers, I saw a lot of suggestions to add "_execute_browser_action" to my manifest.json, but I think this command requires a listener that needs to be set up in background.js (correct me if I'm wrong). I want to avoid a background.js if possible, as I want to keep this extension short and sweet.
Here is my manifest.json:
{
"manifest_version": 2,
"name": "foo",
"description": "foo",
"version": "0.1.0",
"commands": {
"_execute_browser_action": {
"suggested_key": {
"default": "Ctrl+Shift+8"
}
}
},
"content_scripts": [{
"js": ["./dist/bundle.js"],
"matches": [ ...certain sites... ]
}],
"icons": {
"16": "/icons/logo16.png",
"32": "/icons/logo32.png",
"48": "/icons/logo48.png",
"128": "/icons/logo128.png"
}
}
With this manifest.json, the shortcut shows up in Chrome://extensions/shortcuts, but the shortcut does nothing. When I press the combination, nothing happens. Even when I refresh the page, reload extension, re-bundle, restart Chrome, etc.
How should I go about adding this keyboard shortcut?
Also, I'm using Babel/Webpack, if that helps.
I ended up solving my own issue. Updating here in case it helps anyone else.
It turns out a background.js was exactly what I was looking for. My background script sets a chrome.storage API field, triggered by browserAction, which my content_script then ingests to toggle it on/off. Then the page is refreshed to update the page html. (Inspiration taken from here)
background.js:
var x = true
enableBrowserAction()
function disableBrowserAction() {
chrome.storage.local.set({enabled: false})
}
function enableBrowserAction() {
chrome.storage.local.set({enabled: true})
}
function updateState() {
if (x == false) {
x = true
enableBrowserAction()
} else {
x = false
disableBrowserAction()
}
chrome.tabs.reload()
}
chrome.browserAction.onClicked.addListener(updateState)
manifest.json (with only the necessary fields):
{
"manifest_version": 2,
"browser_action": {},
"commands": {
"_execute_browser_action": {
"suggested_key": {
"default": "Ctrl+Shift+8"
}
}
},
"permissions": [
"storage"
],
"background": {
"scripts": ["background.js"]
},
"content_scripts": [{
"js": ["./dist/bundle.js"],
"matches": [ ...certain sites... ]
}]
}
content_script (entry for bundle.js):
import ServiceHandler from './ServiceHandler.js'
chrome.storage.local.get('enabled', data => {
if (data.enabled) {
const sh = new ServiceHandler()
sh.execute()
}
})

When phrase on web page is found, then mute all tabs. Chrome extension, Javascript

I am trying to write Google extension. The problem is i want to mute/turn off sound in tab/all tabs when script find phrase.
Eg.:
You click on random video on Youtube.
When in descibtion is "License granted to YouTube", then mute this tab.
Also it doesnt work when visit a page for a first time i have to reload it. :(
4th day of learning programming.
//smh which turn off sound of all tabs - sometimes work
function turn_Off_Sound() {
chrome.tabs.query({url: []}, function (tabs) {
for (var i = 0; i < tabs.length; i++) {
var mutedInfo = tabs[i].mutedInfo;
if (mutedInfo) chrome.tabs.update(tabs[i].id, {"muted": true});
}
});
};
//trying to find a phrase
var xpathResult = document.evaluate("(//text()[contains(., 'License granted to YouTube')][1])", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
var node = xpathResult.singleNodeValue;
//not found
if (node == null){
alert("Not found.");
}else {
//found
alert("I find it, give me a hug!");
turn_Off_Sound(); //trying to mute tabs
};
{
"manifest_version": 2,
"name": "Mute tabs when find a phrase",
"version": "0.0.1",
"content_scripts": [ {
"js": [ "script.js" ],
"matches": [ "*://*/*"],
"run_at": "document_end"
} ],
"permissions": [
"contextMenus",
"tabs",
"activeTab",
"storage",
"http://www.google.com/",
"https://ajax.googleapis.com/"],
}
}
<html>
<head></head>
<body>
<h1>We're running a Chrome extension!</h1>
<h1>License granted to YouTube</h1>
</body>
</html>
I did a reseach a managed to do this, but it starts so fast, that its find a word on previus page, before page loads. I was creating this for three days, if someone can make it work, even different way, i will appriciate it.
Also i found this today:
search.query(queryInfo: QueryInfo, callback: function);
so its possible to write it just in the background.js, but i dont know how to make it work...
//manidest.json
{
"name": "Learning",
"manifest_version": 2,
"version": "2",
"description": "Mute tabs, when Licence is on page",
"permissions": [
"tabs",
"storage",
"activeTab",
"search",
"*://*/*"
],
"content_scripts": [{
"js": ["contentScript.js"],
"matches": ["*://*/*"]
}],
"background": {
"persistent": true,
"scripts": ["background.js"]
}
}
//contentScript.js
//contentScript.js
//wait until for url change
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.message === 'URL reloaded') {
//text finder
var xpathResult = document.evaluate("(//text()[contains(., 'Licence')])[1]", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
var node=xpathResult.singleNodeValue;
if (node==null){ //text not found
chrome.runtime.sendMessage({message: "Not found"}, (response) => {
alert(response.message);
});
}else{ //text found
chrome.runtime.sendMessage({message: "Found it"}, (response) => {
alert(response.message);
});
};
}
}
);
//background.js
//React on url change
chrome.tabs.onUpdated.addListener(
function(tabId, changeInfo, tab) {
if (changeInfo.url) {
chrome.tabs.sendMessage( tabId, {
message: 'URL reloaded',
url: changeInfo.url
})
}
}
);
//React, when is smh found by contentScript.js or not
chrome.runtime.onMessage.addListener(
(request, sender, sendResponse) => {
//If text is found
if (request.message === "Found it"){
//turn off sound
chrome.tabs.query({url: []}, function (tabs) {
for (var i = 0; i < tabs.length; i++) {
var mutedInfo = tabs[i].mutedInfo;
if (mutedInfo) {
chrome.tabs.update(tabs[i].id, {"muted": true});
}
}
});
sendResponse({message: "I found it, turning off sound."});
//If text not found
}else if (request.message === "Not found"){
//turn on sound
chrome.tabs.query({url: []}, function (tabs) {
for (var i = 0; i < tabs.length; i++) {
var mutedInfo = tabs[i].mutedInfo;
if (mutedInfo) {
chrome.tabs.update(tabs[i].id, {"muted": false});
}
}
});
sendResponse({message: "Not found, turning on sound."});
}
}
);

Setting cookie with Chrome extension and Selenium Webdriver

I am trying to use a Chrome extension to set a cookie when I get a Selenium Webdriver instance to open a page. I have tried following a variety of ways suggested in different Stack Overflow posts but none of them ever show when I open the page inspector.
Manifest - I made sure to list permissions to any URL:
{
"name": "Test",
"description": "Test",
"version": "2.0",
"manifest_version": 2,
"permissions": ["cookies", "<all_urls>", "background", "tabs", "webRequest", "webRequestBlocking", "http://*/*"],
"background": {
"scripts": ["background.js"],
"persistent": true
} ,
"content_scripts": [
{
"matches": ["*://*/*"],
"js": ["script.js"]
}
]
}
Background JS - I have several attempts to create a cookie and none of them are showing when I inspect the web or background page:
chrome.cookies.set({ url: "https://google.com/", name: "CookieVar0", value: "123" });
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {test: testVar}, function(response) {
console.log("Response connected");
setCookie();
chrome.cookies.set({ url: "http://example.google.com", name: "CookieVar1", value: "123" });
});
});
},
...
function setCookie(){
console.log("Set Cookie");
chrome.cookies.set({"name":"Sample1","url":"http://developer.chrome.com/extensions/cookies.html","value":"Dummy Data"},function (cookie){
console.log(JSON.stringify(cookie));
console.log(chrome.extension.lastError);
console.log(chrome.runtime.lastError);
});
}
Content Script - I've read that you're normally not supposed to try to set cookies form the content script but some posts mentioned it so I tried it anyways:
window.addEventListener('load', loadEvent => {
console.log("Test 321");
// window.customlog = "Updated window!!!";
let window = loadEvent.currentTarget;
window.document.title='You changed me!';
chrome.cookies.set({ url: "http://example.google.com", name: "CookieVar3", value: "123" });
});
So its not a complete answer but something I realized was that no matter what URL you put in the cookie it is going to be filed under the url of the page you are running the extension. So chrome.cookies.set({ url: "https://google.com/", name: "CookieVar0", value: "123" }); was working but it wasn't under "https://google.com/" but "current page url" instead. The one setting "Sample1" was not working until I changed the format to match the one setting CookieVar0 and then it was fine.
So I still can't get it to work as desired everywhere but there is at least some progress. Hope this helps someone!

Chrome Extensions content calls callback to background but parameter is undefined

I'm trying to set up a background script fetching data from content periodically and write it to a file (kind of webpage scraping)
Unfortunately I got stuck at the very beginning:
Background sends a message to content and the callback is called but the parameter is not passed correctly, it's "undefined" whatever I try...
Manifest:
{
"manifest_version": 2,
"name": "Test Extension",
"version": "0.0",
"background": {
"persistent": false,
"scripts": ["background.js"]
},
"content_scripts": [{
"matches" : ["<all_urls>"],
"js": ["content.js"]
}],
"browser_action": {
"default_title": "Test Extension"
},
"permissions": ["activeTab"]
}
content.js
chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
if (msg.text === 'report_back') {
sendResponse({data: "goodbye"});
}
});
background.js
chrome.browserAction.onClicked.addListener(function (tab) {
chrome.tabs.sendMessage(tab.id, {text: 'report_back'}, function(response) {
console.log(response.data);
});
});
If you are getting:
Error in event handler for (unknown): TypeError: Cannot read property 'data' of undefined at ...
I'm guessing you are clicking on the extension icon when you are in a tab like chrome://extensions
Try clicking on it from any other website and it should work.

"else if" condition not working in Chrome extension

I'm trying to set different actions for a Chrome extension based on the type of selection. Maybe I'm reading the documentation wrong, but I can't figure out what isn't working here.
manifest.json
{
"background": {
"scripts": [ "background2.js" ]
},
"description": "Creates a context menu option which copies the selected address into a new Gmail compose window.",
"manifest_version": 2,
"name": "New Gmail Window",
"permissions": [ "tabs", "contextMenus" ],
"version": "0.1"
}
background.js
chrome.contextMenus.create({
title: "Send a New Email",
contexts:["link", "selection"],
onclick: checkType,
});
function checkType(info,tab) {
if (info.linkUrl.substring(0, 7) === "mailto:") { //The "if" works as expected //
chrome.windows.create({
url:"https://mail.google.com/mail/?ui=2&view=cm&fs=1&tf=1&shva=1&to=" +info.linkUrl.substr(7),
width:640,
height:700,
focused:true,
type:"popup",
});
console.log("The linked emails work");
}
else if (info.selectionText.containsNode('a',false)) { //I want to look for an <a> tag that isn't working
console.log("this worked");
}
else console.log("nothing to send");
}
Thanks for any help.

Categories

Resources