How to use tabs.executeScript with react - javascript

In one of my components, when the component is loaded, I want my extension to inject a script into the current tab that the extension is run on. The script essentially gets the source code and save it as a string.
So, in my componentWillMount I tried to inject the script in the following way...
componentWillMount() {
var result = '';
chrome.tabs.executeScript(null, {
file: './js/scripts/getPageSource.js'
}, function() {
// If you try and inject into an extensions page or the webstore/NTP you'll get an error
if (chrome.runtime.lastError) {
result = 'There was an error injecting script : \n' + chrome.runtime.lastError.message;
}
});
}
The path of my script, ./js/scripts/getPageSource.js is relative to my index.html file that is being used by my react app.
I get the error file is not found, so I changed the path relative to the component, but I still go file not found.
I'm thinking maybe this is not the right way to inject a script into an open tab with react, is there a better way of doing this?
EDIT
Here is my manifest.json file...
{
"name": "Get pages source",
"version": "1.0",
"manifest_version": 2,
"description": "Get pages source from a popup",
"browser_action": {
"default_popup": "src/index.html"
},
"permissions": ["tabs", "<all_urls>"]
}
My path ./js/scripts/getPageSource.js is located inside my src folder being referenced above

Use a path that is relative to your manfest.json file.
MDN states:
In Firefox, relative URLs are resolved relative to the current page URL. In Chrome, these URLs are resolved relative to the add-on's base URL.
From your manifest.json, it looks like your file should be:
file: 'src/js/scripts/getPageSource.js'

Related

Chrome extension service workers stops listening to events after opening popup

I'm developing a chrome extension with MV3.
I've encountered an issue in which when I open the popup when clicking on the extension's icon the service worker background script stops receiving the chrome.tabs.onUpdated events, even after I close the popup. The only way I can make it work again is by reloading the extension.
I will mention that the popup that I'm rendering is a react app, not sure if it has to do with the issue, but when I swap the popup content to a normal HTML with just a button or something it is working as expected
Basically what I'm trying to do in the extension is listen to chrome.tabs.onUpdated event to detect URL changes in the background script, and send a message to a content script in order to save some data to the chrome local storage.
This is the manifest.json -
{
"name": "My Extension",
"description": "Extension POC",
"version": "0.0.0.1",
"manifest_version": 3,
"background": {
"service_worker": "background.js"
},
"permissions": ["tabs", "storage", "activeTab"],
"action": {
"default_popup": "build\\index.html",
"default_title": "Open Pane",
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"]
}
]
}
And this is the background.js -
chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
if (!isPageDoneLoading(changeInfo)) {
return;
}
const url = tab.url;
const ticketId = url.substring(url.lastIndexOf("/") + 1);
if (isTargetURL(url) && !isNaN(ticketId)) {
// Update the ID only if it doesn't equal to the previous one or if null
if (!CURRENT_TICKET_ID || CURRENT_TICKET_ID !== ticketId) {
CURRENT_TICKET_ID = ticketId;
const props = getProperties(ticketId);
chrome.tabs.sendMessage(tabId, { action: {ticketId, props: props} });
}
}
})
Any idea what may be the root cause or how can I resolve the issue?
What React version are you using? In the older React version, part of the create-react-app script creates a file called serviceWorker.js. and a call to it in index.js. When I created a new project with a newer React version, 18.X.X it didn't create this file. I suppose there is some conflict with the service worker of the chrome extension and the one react app created.

`alert` not showing in ManifestV3 background service worker

I am trying to make a chrome extension that alerts you in the tab that you are currently moving or highlighting. I have tried reading the chrome migrating to V.3 documentation and have come up with the following code, however, the alerts never appear. Does anybody know what I need to change or add?
// manifest.json
{
"manifest_version": 3,
"name": "Alert",
"version": "0.1",
"description": "alerts you when doing tab functions",
"permissions": ["tabs", "activeTab"],
"host_permissions": ["<all_urls>"],
"background": {
"service_worker": "background.js"
}
}
//background.js
chrome.tabs.onMoved.addListener(function () {
alert("You moved this tab");
});
chrome.tabs.onHighlighted.addListener(function () {
alert("You highlighted this tab");
});
Working directory:
.
├── background.js
├── manifest.json
alert() method cannot be used outside of the browser environment, you can use console.warn() or console.error() instead. But is not a good solution if you want to show an error message to the extension user, as they would never open the console.
If you would like a more user friendly approach use the following:
chrome.notifications.create({
type: 'basic',
iconUrl: '/images/image_if_any.png',
title: `Notification title`,
message: "Your message",
priority: 1
});
Also add "notifications" to "permissions" in your manifest.json file:
"permissions": [..., "notifications"]
alert is not defined in a service worker per specification so we'll have to use console.log
Also, I was looking in the wrong place for the alert messages. I needed to look at the service worker link in my unpacked extension page.

Can't send data out of executeScript in chrome-extension

I am developing one chrome extension which can extract all the meta tags of the current tab. I am using ReactJs as the main development environment and I have placed my chrome related code in its componentWillMount() method.
componentWillMount() {
const code =
"let metas = document.getElementsByTagName('meta');" +
"let newMetas = []" +
"for (let meta of metas) {" +
" newMetas.push({name: meta.name, content: meta.content});" +
"}" +
"newMetas;";
chrome.tabs.executeScript(null, {
code: code
}, function (results) {
console.log(results); // <=== Here I get 'null' value
if (!results) {
return;
}
})}
this is my manifest.json file
{
"manifest_version": 2,
"name": "Northwind",
"description": "Just a simple all with all northwind employees",
"version": "1.0",
"browser_action": {
"default_icon": "./img/ic-logo.png",
"default_popup": "./index.html"
},
"permissions": [
"http://www.amazon.com/",
"tabs"
],
"web_accessible_resources": ["script.js"],
"content_scripts": [{
"matches": ["http://www.amazon.com/*"],
"js": ["app.js"]
}
]
}
app.js is the build file generated by the react.
I have been reading and searching for this but did not get any clues of why it's not working.
Another issue is that when I put console.log('done') in my script, it's not displayed as well so I guess there is some problem with the config as well.
Thanks so much for your help.
When you are using chrome.tabs.executeScript you have to specify host in the permissions field of the manifest.
It is called programmatic injection:
To insert code into a page, your extension must have cross-origin permissions for the page. It also must be able to use the chrome.tabs module. You can get both kinds of permission using the manifest file's permissions field.

Calling API Keys in background and content scripts in WebExtension

I have an API key and secret required for my extension and I've stored them in a file on their own formatted like so.
key.js
var APP_KEY = 'App Key Goes Here';
var APP_SEC = 'App Secret Goes Here';
manifest.json
// manifest.json
{
"manifest_version": 2,
"name": "Trakt for IMDb",
"version": "0.1a",
"background": {
"scripts": [
"js/key.js",
"js/background.js"]
},
"content_scripts": [
{
"js": [
"js/key.js",
"js/main.js"
]
}
]
}
On the popup pages I can just reference this file like <script type="text/javascript" src="../js/key.js"></script> and it calls the 2 variables, but I can't work out how to reference it so my background and content scripts can also access them.
I've tried referencing the key.js file in my manifest.json file as follows
"background": {
"scripts": [
"js/key.js",
"js/background.js"
]
}
But that doesn't work. I'm getting an APP_KEY is not defined
main.js
console.log('Content: ' + APP_KEY);
Is there any way to try do what I'm doing?
This works the way you desire. A single JavaScript file can be used in both background scripts and content scripts to share identical functions or variables.
All the scripts defined in the background key run in the same context. Thus, your variables APP_KEY and APP_SEC, as defined in key.js, are available to your code in background.js.
All the scripts defined in a single js key within a manifest.json file's content_scripts key share a single context. This is what allows you to use things like jQuery with your code. I have not checked to see if there is a separate context created for separate js lists, if the matches key results in both sets being loaded on a particular page, or tab. In addition, I have not checked to see if a single context is shared between the manifest.json file's content_scripts method of loading content scripts and other methods of loading content scripts (e.g. tabs.executeScript‌​()).
The following is a complete extension that has been tested in both Firefox and Google Chrome. In both browsers, the variables defined in key.js are available in both the background and content scripts.
manifest.json:
{
"manifest_version": 2,
"name": "Variables in other files",
"description": "Test availability of variables from anther JavaScript file",
"version": "0.1",
"background": {
"scripts": [
"js/key.js",
"js/background.js"]
},
"content_scripts": [
{
"matches": ["*://*.mozilla.org/*"],
"js": [
"js/key.js",
"js/contentScript.js"
]
}
]
}
js/key.js:
var APP_KEY = 'App Key Goes Here';
var APP_SEC = 'App Secret Goes Here';
js/background.js:
console.log('Background: ' + APP_KEY);
console.log('Background: ' + APP_SEC);
js/contentScript.js:
console.log('Content: ' + APP_KEY);
console.log('Content: ' + APP_SEC);
Console output upon loading extension:
Background: App Key Goes Here
Background: App Secret Goes Here
Console output upon navigating to mozilla.org:
Content: App Key Goes Here
Content: App Secret Goes Here
I am not sure why this did not work for you when you initially tried it. You have stated in a comment that it is working for you now.

Add JS Library to Chrome Extension

I am building a Chrome Extension and I am having trouble adding a JavaScript library to use in my content script.
I am trying to add the Mutation Summary Library. I put the 'mutation_summary.js' file into the extension's directory and I tried to add it by adding 'mutation_summary.js' to the 'manifest.json' file as shown below:
"content_scripts": [
{
"matches": ["http://soundcloud.com/*", "https://soundcloud.com/*"],
"js": ["content_script.js", "mutation_summary.js"]
}
An extension error is thrown when I add it. The errors says "Could not load javascript 'mutation_summary.js' for content script.
Am I adding the javascript library incorrectly?
Thanks
It works perfectly for me. I created an extension with a file called mutation_summary.js which contains console.log('FILE LOADED!'); and it shows up as soon as I load soundcloud.com, maybe you had a typo with the file name?
manifest.json:
{
"name": "Extension",
"version": "1.0",
"manifest_version": 2,
"content_scripts": [
{
"matches": ["http://soundcloud.com/*", "https://soundcloud.com/*"],
"js":["mutation_summary.js"]
}
]
}

Categories