Chrome extension that replaces images with other images - javascript

how can I do a Chrome extension that replaces images with other images?
Here's my manifest.json code so far:
{
"name": "HaramB",
"version": "69.0.420.666",
"manifest_version": 2,
"description": "This is HaramB's own extension!",
"browser_action": {
"default_icon": "images/icon.png",
"default_popup": "popup.html",
"default_title": "HaramB"
},
"permissions": [
"activeTab",
"https://ajax.googleapis.com/"
],
"icons": {
"128": "images/icon.png"
},
"web_accessible_resources": [
"images/nicolas.jpg"
],
"content_scripts": [{
"matches": ["http://*/*", "https://*/*"],
"js": ["onPage.js"],
"css": ["onPage.css"]
}]
}
And here's my onPage.js code:
var picture = "images/nicolas.jpg";
document.getElementsByTagName("img").setAttribute("src", picture);
Dont't care about the popup.html or the onPage.css files.
It's the onPage.js file i want it to do it with, if it's not possible, tell me.

document.getElementsByTagName() returns an Array of elements. This means you need to loop through the array and call the methods you want on them individually, like so:
var picture = "images/nicolas.jpg",
images = document.getElementsByTagName("img");
for (var i = 0; i < images.length; i++) {
images[i].setAttribute("src", picture);
};
Note: it is preferable to use images[i].src = ... to using setAttribute as detailed in this question

Related

Chrome extension only works in dev tools

I have created a chrome extension that will append an index to the beginning of search results on google but so far I have only been successful in getting the right output if I inspect element then refresh the page. If I regularly refresh the page it is as if the code was not run.
manifest.json:
{
"manifest_version": 2,
"name": "number nodes for accessibility",
"version": "0.1.0",
"description": "numbering of anchor tags for accessibility",
"permissions": ["activeTab", "<all_urls>", "file:///*"],
"browser_action": {
"default_icon": "128.png"
},
"background": {
"scripts": ["background.js"],
"persistent": false
},
"content_scripts": [{
"matches":["<all_urls>"],
"css": ["number.css"],
"js": ["jquery-3.4.1.js","number.js"]
}]
}
background.js
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript({
file: 'number.js'
});
});
number.js
$(document).ready(()=>{
var a = $("div.v0nnCb")
var links=[];
for (let index = 0; index < a.length; index++) {
const element = a[index].innerHTML;
a[index].innerHTML = "("+index+"): "+element;
links.push(a[index].baseURI)
}
console.log(links)
})

Chrome extension - collect HTMLcollection from file

I'm creating a in house chrome extension which collects data from a webpage (broke links etc for SEO) but i'm having issues. My original script injected the js onpage which was great as it had a box and collected what was needed, the only issue was it wasn't a Popup box so it didn't close correctly etc. I now have a script which on load pulls all dom data and a script which display and manipulates the data. The only issue I have is collecting the data from the file.
Manifest.json
{
"name": "",
"version": "1.2.4",
"manifest_version": 2,
"description": "",
"homepage_url": "",
"background": {
"scripts": [
"background.js",
"Returndocdata.js"
],
"persistent": true
},
"browser_action": {
"default_title": ""
},
"icons": { "16": "icon16.png" },
"permissions": [
"https://*/*",
"http://*/*",
"tabs"
],
"content_scripts": [
{
"matches": ["*://*/*"],
"run_at": "document_start",
"js": ["Returndocdata.js"]
}
]
}
background.js
chrome.browserAction.onClicked.addListener(function(tab, info) {
chrome.tabs.executeScript({file: 'Returndocdata.js'});
});
chrome.browserAction.onClicked.addListener(function(tab, info) {
chrome.browserAction.setPopup({popup: "inject.html"})
});
inject.html
<div id = "ContactDetails">
<input type="text" name="lname">
</div>
<script src="inject.js"></script>
Returndocdata.js
var all = document.getElementsByTagName("*");
console.log(all);
inject.js
this is the file that needs the returndocdata.js data, i need a way to grab that data and pull it into this keeping the formatting (the htmlcollection)
This works if I include the script in the header but due to it not being ran on the web page itself it only returns data from the popup extension.
It's most likely a small thing
Ta

Why Dynamically loading resources using html imports does not require an entry in web_accessible_resources?

Without my chrome extension, it appears that I am able to load resources into the document's head that are not specified in web_accessible_resources.
I would like some clarification as to whether this is a bug that will come back to hunt me once it's fixed or a feature in a chrome extension.
Without further ado, this is how I am loading the resources from my content script
function loadRes(res) {
return new Promise(
function(resolve, reject) {
var link = document.createElement('link');
link.setAttribute('rel', 'import');
link.setAttribute('href', res);
link.onload = function() {
resolve(res);
};
document.head.appendChild(link);
});
}
loadRes( "vendor/bower_components/webcomponentsjs/webcomponents-lite.js" )
.then( loadRes("vendor/bower_components/polymer/polymer.html") )
.then(function(){
window.chromeApp = new ChromeApp(options);
});
}
Can anyone explain why doesn't chrome restrict these from loading dynamically?
UPDATE
Here is my manifest file:
{
"name": "Web Notes",
"version": "1.0",
"manifest_version": 2,
"description": "C",
"icons": {"128": "assets/images/ext_icon.png"},
"browser_action": {
"default_icon": "assets/images/ext_icon.png",
"default_title": "C",
"default_popup": "popup.html"
},
"content_scripts": [ {
"js": [
"vendor/bower_components/jquery/dist/jquery.min.js",
"vendor/bower_components/underscore/underscore-min.js",
"vendor/bower_components/backbone/backbone.js",
"vendor/bower_components/pouchdb/dist/pouchdb.js",
"assets/javascripts/collections/asset_collection.js",
"assets/javascripts/helpers/asset_view_helper.js",
"assets/javascripts/models/pouch_db_user.js",
"assets/javascripts/models/node_client.js",
"assets/javascripts/views/chrome_app.js",
"content.js"
],
"css": [
"vendor/bower_components/bootstrap-tagsinput/dist/bootstrap-tagsinput.css",
"vendor/bower_components/bootstrap/dist/css/bootstrap.min.css",
"assets/stylesheets/css/chrome_app.css"
],
"matches": ["file://*", "http://localhost/*.*"]
}],
"web_accessible_resources": [
"vendor/bower_components/jquery/dist/jquery.min.map",
"assets/images/*.*",
"web_components/component/component.html"
]
}

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

Extension can't find class

I'm trying to make an chrome extension with the last.fm & plug.dj API's it used to work until I started embedding my scripts in the extension, and sinds then I can't connect to neither of them. This is the setup script:
function Setup(){
console.log('Setup');
API.addEventListener(API.DJ_ADVANCE, callback);
cache = new LastFMCache();
lastfm = new LastFM({
apiKey: '<key>',
apiSecret: '<secret>',
cache: cache
});
}
with the following in my manifest.json
{
"content_scripts": [ {
"js": [ "jquery.js","lastfm.api.md5.js", "lastfm.api.cache.js", "lastfm.api.js","lastFMLink.js", "script.js"],
"css": [ "LastFMLink.css" ],
"matches": [ "http://plug.dj/*", "http://plug.dj/*/*" ],
"run_at": "document_end"
} ],
"name": "Plug.Dj VS last.Fm",
"description": "Implement information about the artist",
"icons": { "16": "cookie.png", "48": "cookie.png", "128": "cookie.png" },
"permissions": [ "http://plug.dj/*", "http://plug.dj/*/*" ],
"version": "0.0.1",
"web_accessible_resources": [ "lastFMLink.js"],
"manifest_version": 2
}
it errors on the new LastFMCache() and somewhere else in the script where I access the other API. the other scripts get loaded (like lastFMLink.js and lastFMLink.css) and the weir thing is the event listener does work
the setup script get's loaded when pressed on a button and it isn't initialized yet, so normally it isn't erroring due script order.
anyone got any clues what might be going wrong?
This is probabbly not the best option, but I found out that the reason it didn't work was due the fact that content_script run in the background, and don't have access to eachother.
so I changed my manifest.json to:
{
"content_scripts": [ {
"js": ["script.js"],
"css": [ "LastFMLink.css" ],
"matches": [ "http://plug.dj/*", "http://plug.dj/*/*" ],
"run_at": "document_end"
} ],
"name": "Plug.Dj VS last.Fm",
"description": "Implement information about the artist",
"icons": { "16": "cookie.png", "48": "cookie.png", "128": "cookie.png" },
"permissions": [ "http://plug.dj/*", "http://plug.dj/*/*" ],
"version": "0.0.1",
"web_accessible_resources": [ "jquery.js","lastfm.api.md5.js", "lastfm.api.cache.js", "lastfm.api.js","lastFMLink.js","script.js"],
"manifest_version": 2
}
and then I only had to load the scripts and I'm deffenitly sure this isn't the way to do it, but it works for now, but this is now how I load my last.fm scripts (in script.js):
var s = document.createElement('script');
s.src = chrome.extension.getURL("lastFMLink.js");
var s2 = document.createElement('script');
s2.src = chrome.extension.getURL("lastfm.api.md5.js");
var s3 = document.createElement('script');
s3.src = chrome.extension.getURL("lastfm.api.cache.js");
var s4 = document.createElement('script');
s4.src = chrome.extension.getURL("lastfm.api.js");
s.onload = function() {
this.parentNode.removeChild(this);
};
(document.head||document.documentElement).appendChild(s);
(document.head||document.documentElement).appendChild(s2);
(document.head||document.documentElement).appendChild(s3);
(document.head||document.documentElement).appendChild(s4);

Categories

Resources