Chrome Extension communication via Content Scripts - javascript

I'm trying to listen to events on a webpage by using Chrome Extension app build with React and Redux.
I've setup a content.js file that works as a content script and it can send messages to my React app just fine, the app can see the event properly... but there's an issue - I want to send MouseEvent (or any other Event, for that matter) data to my React app but my React app only recieves
data: {
isTrusted: true
},
type: 'onPageClick',
So as you can see everything from the MouseEvent is gone, except for isTrusted. Do I need any special permission in manifest.json?
Files:
// manifest.json
{
"short_name": "Example Extension",
"name": "Example Extension",
"icons": {
//...
},
"content_security_policy": "...",
"permissions": [
"activeTab",
"tabs",
"contextMenus",
"background"
],
"manifest_version": 2,
"version": "0.0.1",
"browser_action": {
"default_popup": "index.html",
"default_title": "Example Extension"
},
"content_scripts": [
{
"js": [ "content.js"],
"matches": [ "<all_urls>"]
}
],
"background": {
"scripts": ["background.js"]
}
}
// content.js
document.addEventListener('click', (ev) => {
console.log(ev);
chrome.runtime.sendMessage('EXTENSION-ID', {
type: 'onPageClick',
data: ev,
});
});
// fragment of App.js
useEffect(() => {
chrome.runtime.onMessage.addListener((...args) => console.log(args));
}, []);
Is it even possible to send event data? I've been able to send custom JSON objects without any issues, but every field from Event gets removed when sending the message.
Thanks!

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

How to addEventListener to listen for push notifications with Chrome

I have a website that updates automatically when I get a message and sends me a push notification. I am trying to create a chrome extension that can detect when I get that push notification and do something when it happens.
This is what I have so far but it doesn't seem to be outputting to console. Is something wrong or do I need to change something about my manifest?
inject.js
self.addEventListener('push', function(event) {
//I want to do a thing here
if (event.data) {
console.log('This push event has data: ', event.data.text());
} else {
console.log('This push event has no data.');
}
});
manifest.json
{
"name": "Push notifcation detector",
"version": "1.0",
"description": "Do a thing!",
"manifest_version": 2,
"permissions": [
],
"content_scripts": [
{
"matches": [
"https://mywebsite.com/*"
],
"js": [
"./js/inject.js"
],
"all_frames": false,
"run_at": "document_end"
}
],
"web_accessible_resources": [
"images/**/*.png"
],
"browser_action": {
"default_icon": {
"16": "./images/icons/icon.png",
"48": "./images/icons/icon.png"
}
},
"icons": {
"16": "./images/icons/icon.png",
"48": "./images/icons/icon.png",
"128": "./images/icons/icon.png"
}
}
Thanks for any help you can give me!
It looks like you need to run some sort of background page to receive the message. For the dropdowns, as far as I know, Chrome creates and drops the pages when you select and de-select, or when the browser is on the configured page. By default, it's not going to work because the page isn't running constantly.
This may help: https://developer.chrome.com/extensions/background_pages

Get button clicked with chrome extension

I want to know how to detect if a button with a certain id is clicked on a webpage with my chrome extension.
With my code I have an error saying that my element is undefined.
Here is my manifest :
{
"manifest_version": 2,
"name": "app",
"description": "my app",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html",
"default_title": "Changer le background"
},
"permissions": [
"activeTab",
"storage"
]
}
And my popup.js file :
document.addEventListener('DOMContentLoaded', () => {
getCurrentTabUrl((url) => {
document.getElementById('mybutton').addEventListener('click', function() {
var script = "console.log('clicked');";
chrome.tabs.executeScript({code: script});
});
});
});
your popup.js will not load until the user himself will click on the extension's icon... i think you should change your approach and use a content-script like this:
document.getElementById('mybutton').addEventListener('click', function() {
console.log('clicked');
});
you'll need to update your manifest.json for using a content script, something like that:
"content_scripts": [
{
"matches": ["the url of a page for the script", "the url of another page"],
"js": ["your_script.js"]
}
],

Chrome extension long lived connection: retrieve message from background to content

I read this and searched on other places but I can't solve this issue. I am using long-lived connections. I send a message from content script to background and after that I want to send a message from background to content script. However, I am not able to receive messages on the content file for some reason...
Content script:
var port = chrome.runtime.connect({name: "my-channel"});
// receive messages
port.onMessage.addListener(function(msg) {
console.log(msg); // doesn't log anything
});
document.addEventListener('DOMContentLoaded', function () {
document.getElementById('alertButton').addEventListener('click', function() {
// send message
port.postMessage({myProperty: "value"});
});
});
Background:
chrome.runtime.onConnect.addListener(function(port) {
if(port.name == "my-channel"){
port.onMessage.addListener(function(msg) {
// do something
// then send message to the content
port.postMessage({myProperty: "value"});
});
}
});
EDIT: my manifest.json
{
"manifest_version": 2,
"name": "Test extension",
"version": "1.0",
"browser_action": {
"default_popup": "main_ui.html",
"default_title": "Test Extension"
},
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["logic.js"]
}],
"background": {
"scripts": ["background.js"],
"persistent": true
},
"permissions": [
"tabs",
"activeTab"
]
}
solution: I was using an old reference of "port" of when connection happened. The 2nd argument of the listener (that isn't visible there) is actually the port.

Screenshot using chrome.tabs.captureVisibleTab

I'm trying to capture the visible area of a page using chrome.tabs.captureVisibleTab. Here is the code that makes the call:
chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
if (request.name == 'screenshot') {
chrome.tabs.captureVisibleTab(null, null, function(dataUrl) {
sendResponse({ screenshotUrl: dataUrl });
});
}
});
But when I try to capture the tab I get this error:
Unchecked runtime.lastError while running tabs.captureVisibleTab: The 'activeTab' permission is not in effect because this extension has not been in invoked.
Here is my manifest file:
{
"manifest_version": 2,
"name": "Empathy",
"version": "0.1",
"description": "Simulate accessibility issues for websites.",
"browser_action": {
"default_icon": "empathy19.png",
"default_title": "Empathy!"
},
"permissions": [
"activeTab",
"contextMenus",
"desktopCapture",
"tabCapture",
"tts" // Text-to-speech
],
"background": {
"scripts": [
"boot.js"
],
"persistent": false
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": [
"src/helpers.js",
"src/colorblindness.js",
"lib/colorvision.js",
"lib/html2canvas.js"
]
}
]
}
I have active tab permissions
The call is being made from a background script
I'm matching <all_urls>
Why do I get that error?
There are things that talk about <all_urls> as something to match, but what I was missing was the <all_urls> permission. After I added the permission, it worked.

Categories

Resources