Selectively include javascript file dependent on website - javascript

I'm trying to build a Chrome Extension that will work with two websites, we'll call them website1.com and website2.com. Depending on what website we are on I would like to include a different JS file that will store all the logic (In this example I have called it code-for-website-1.js (there would also be another JS for website2.com).
I'm having a problem figuring out how I can only include code-for-website-1.js when I am on website1.com and code-for-website-2.js when I am on code-for-website-2.js.
Here is my manifest:
{
"name": "My Chrome Extension",
"version": "1.0",
"description": "Extension description",
"manifest_version": 2,
"permissions": ["tabs", "http://www.website1.com", "http://www.website2.com"],
"content_scripts": [
{
"matches": ["http://www.website1.com"],
"js": ["jquery.js", "code-for-website-1.js"]
}
]
}
I tried to use one controller.js that would use the following command:
if (onWebsite1 == true){
chrome.tabs.executeScript(null, { file: "code-for-website-1.js" });
} else {
chrome.tabs.executeScript(null, { file: "code-for-website-2.js" });
}
With this I just get the error:
Uncaught TypeError: Cannot call method 'executeScript' of undefined

in the manifest according to the documentation you can add multiple objects to the content_script array
example
"content_scripts": [
{
"matches": ["http://www.website1.com/*"],
"js": ["script_for_website1.js"]
},
{
"matches":["http://www.website2.com/*"],
"js":["script_for_website2.js"]
}
]

Related

Chrome extension simple audio

I would like to play a simple "alarm" in chrome extension but i have and error in console: "GET chrome-extension://invalid/ net::ERR_FAILED chrome-extension://invalid/:1"
My simple code is:
var asdasd = '<span id="audio"></span>';
$('body').append(asdasd);
var srcaudio = chrome.extension.getURL('alert2.mp3');
$('#audio').html('<audio autoplay><source src="'+srcaudio+'"></audio>');
And my manifest is:
{
"manifest_version": 2,
"name": "test",
"description": "test",
"version": "1.0",
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*"],
"js": ["jquery.js","myscript.js"]
}
]
}
So i tried to do this in my own extension.
As wOxxOm said, you probably need web_asseible_resources. For me the css/js/fonts are in the assets package. I dunno where you placed it.
"web_accessible_resources": [
"assets/css/*",
"assets/js/*",
"assets/fonts/*"
]
Secondly, extension.getUrl() is deprecated, so use runtime.getUrl() instead, as for the url try to use "./alert2.mp3" or "~/alert2.mp3" if the direct path isn't working

document.addEventListener not working in Chrome Extension

I'm trying to create a chrome extension which simply alerts "Foo" whenever a new DOM node is inserted during a page load. The following code does not work:
manifest.json:
{
"name": "test",
"description": "test",
"version": "2.0",
"manifest_version": 1,
"permissions": [
"activeTab"
],
"content_scripts": [
{
"run_at": "document_start",
"matches": ["https://www.facebook.com/*"],
"js": ["test.js"]
}]
}
test.js:
function nodeInsertedCallback(event) {
alert("Foo");
});
document.addEventListener('DOMNodeInserted', nodeInsertedCallback);
When test.js is simply:
alert("Foo");
The alert is shown, indicating it's not an issue with the manifest or with the extension itself.
There is a syntax error on the third line. But I also suggest wrapping your code into an IFFE. Giving you an end result like:
(function() {
function nodeInsertedCallback(event) {
alert("Foo");
});
document.addEventListener('DOMNodeInserted', nodeInsertedCallback);
}).call(this)

Using JQuery in a content script

I am trying to use JQuery in my content script but The chrome console spits this out "Uncaught ReferenceError: $ is not defined ". I can successfully use JQuery in my background script so I'm not exactly sure whats up.
Here's the manifest file:
{
"name": "Something",
"version": "1.0",
"description": "SOmething",
"background": {
"scripts": ["background.js", "jquery.js"],
"persistent": true
},
"browser_action": {
"default_icon": "favicon.png",
"default_popup": "popup.html"
},
"permissions": [
"declarativeContent",
"http://localhost/",
"http://*/*",
"https://localhost/",
"https://*/*",
"tabs"
],
"icons": {
"48": "icon-48p.png"
},
"content_scripts": [{
"matches": [
"http://*/*",
"https://*/*"
],
"js": ["content.js", "jquery.js"]
}],
"web_accessible_resources": ["button.PNG", "jquery.js"],
"manifest_version": 2
}
Here's the content script:
var btn = document.createElement("input");
btn.id = "btn";
btn.type = "image";
btn.setAttribute("src", chrome.extension.getURL("button.PNG"));
btn.onclick = function() {
alert("Currently under development");
};
btn.className = "";
if (window.location.href.indexOf("mysite") > -1) {
$('#pageContainer').append('<ol><li>CATS</li><ol>'); //Fails here
}
if (window.location.href.indexOf("myother") > -1) {
document.getElementById("maindiv").appendChild(btn); //works
}
Edit: JQuery is in the project and it does work in background.js. The question is how do I get it working within my content script? I've specified in the manifest that I want jquery injected along with content.js.
Make jQuery the first content script listed in thecontent_scripts -> js array. Like:
"content_scripts": [{
"matches": [
"http://*/*",
"https://*/*"
],
"js": ["jquery.js", "content.js"]
}],
Your content script is trying to access jquery before it's loaded. The way your manifest is set up now, jQuery still should be loaded however. To verify this, type something like window.jQuery into the console on the content script page and make sure that it is defined.
As berrberr pointed out, you have to load jquery before your content.js script as follows
"js": ["jquery.js","content.js"]
or you can achieve the same in Pure JS using appendChild().
Also a note: If you are manipulating DOM elements, try injecting your script at document_end

Chrome Extension error tab.url

I'm essentially just trying to get the current tab url if they're on youtube.com. I keep getting an error from the script.
Error:
Uncaught TypeError: Cannot call method 'getSelected' of undefined
Manifest
{
"name": "YouTube Fix",
"version": "0.0.1",
"manifest_version": 2,
"description": "Fix some of the annoying little things in YouTube.",
"icons": {
"16": "icon.png",
"48": "icon.png",
"128": "icon.png"
},
"content_scripts": [{
"matches": ["http://www.youtube.com/*"],
"js": ["background.js"],
"run_at": "document_start"
}],
"permissions": ["tabs"]
}
Background.js
//this is what is giving me the error:
chrome.tabs.getSelected(null, function (tab) {
myFunction(tab.url);
});
function myFunction(tablink) {
if (tablink == "http://www.youtube.com") {
window.location = "http://www.youtube.com/feed/subscriptions/u";
}
document.getElementById("comments-textarea").disabled = false;
}
The following forks fine, no need for chrome.tabs.getSelected(null, function (tab) {}),because your page always runs for "matches": ["http://www.youtube.com/*"],;
More over add this condition to your code if(document.getElementById("comments-textarea") != null){
Working background.js
if (window.location == "http://www.youtube.com") {
window.location = "http://www.youtube.com/feed/subscriptions/u";
}
if (document.getElementById("comments-textarea") != null) {
document.getElementById("comments-textarea").disabled = false;
}
manifest.json
{
"name": "YouTube Fix",
"version": "0.0.1",
"manifest_version": 2,
"description": "Fix some of the annoying little things in YouTube.",
"content_scripts": [{
"matches": ["http://www.youtube.com/*"],
"js": ["background.js"],
"run_at": "document_start"
}],
"permissions": ["tabs"]
}
Let me know if you need more information.
You're running background.js as a content script rather than a background or event page, and https://developer.chrome.com/extensions/content_scripts.html says that "content scripts have some limitations. They cannot … Use chrome.* APIs (except for parts of chrome.extension)"
Instead, you should put something like
"background": {
"scripts": ["background.js"],
"persistent": false
},
into your manifest. See https://developer.chrome.com/extensions/event_pages.html for more details.
Quoted from here: https://groups.google.com/a/chromium.org/forum/?fromgroups=#!topic/chromium-extensions/A5bMuwCfBkQ
chrome.tabs.getSelected() is deprecated. The following page explains
how to use chrome.tabs.query instead:
http://code.google.com/chrome/extensions/whats_new.html#16 The relevant bit of text is:
"""
The methods getAllInWindow() and getSelected() have been deprecated.
To get details about all tabs in the specified window, use
chrome.tabs.query() with the argument {'windowId': windowID}. To get
the tab that is selected in the specified window, use
chrome.tabs.query() with the argument {'active': true}.
"""
chrome.tabs.getSelected is deprecated. Use chrome.tabs.query instead:
chrome.tabs.query({
"active": true
}, function(tab){
console.log(tab[0]); //selected tab
});
Also, content scripts can not access chrome.tabs APIs. Do this:
chrome.extension.getBackgroundPage().chrome.tabs.query(...
(This might not work. Not tested.)

Chrome extension: load different content scripts

I want to load a different content script depending on the page and tab that is currently selected. Right now, I have three content scripts. I want to use two of them for one page and the third one for another page.
Belonging to page 1:
content_script.js
load_content_script.js
Belonging to page2:
newtab_content_script.js
right now my manifest looks like this
{
"name": "A plugin for AdData express. Generate an instant excel document from the brands you check mark.",
"version": "1.0",
"background_page": "background.html",
"permissions": [
"cookies",
"tabs",
"http://*/*", "https://", "*", "http://*/*", "https://*/*",
"http://www.addataexpress.com", "http://www.addataexpress.com/*"
],
"content_scripts": [
{
"matches": ["<all_urls>","http://*/*","https://*/*"],
"js": ["load_content_script.js", "content_script.js", "newtab_content_script.js", "jquery.min.js", "json.js"]
}
],
"browser_action": {
"name": "AdData Express Plugin",
"default_icon": "icon.png",
"js": "jquery.min.js",
"popup": "popup.html"
}
}
how would I structure this in the manifest or elsewhere?
Just in the interest of completeness, the way you'd do this from the manifest is to have as many matches blocks under "content_scripts" as needed:
"content_scripts": [
{
"matches": ["http://www.google.com/*"],
"css": ["mygooglestyles.css"],
"js": ["jquery.js", "mygooglescript.js"]
},
{
"matches": ["http://www.yahoo.com/*"],
"css": ["myyahoostyles.css"],
"js": ["jquery.js", "myyahooscript.js"]
}
],
Rather than using content scripts that are bound to URL expressions specified in the manifest, you should use executeScript, which lets you programmatically decide when to inject a JS snippet or file:
// background.js
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
// there are other status stages you may prefer to inject after
if (changeInfo.status === "complete") {
const url = new URL(tab.url);
if (url.hostname === "www.stackoverflow.com") {
// this is the line which injects the script
chrome.tabs.executeScript(tabId, {file: "content_script.js"});
}
}
});
Make sure to add tabs permission to manifest.json:
{
// ...settings omitted...
"permissions": [
"tabs", // add me
]
}
you should use Programmatic injection
chrome.tabs.executeScript(null, {file: "content_script.js"});

Categories

Resources