Loop on content script breaks after first pass - Chrome Extension - javascript

I'm building a Chrome Extension that expands all collapsed text on a a web page.
Heres a snippet of the code:
manifest.json
{
"manifest_version": 2,
"name": "filterq2",
"version": "1.0",
"icons": {
"128": "icon_16.png"
},
"browser_action": {
"default_title": "Preguntas"
},
"background": {
"scripts": ["background.js"],
"persistent": true
},
"content_scripts": [{
"matches": ["https://www.quora.com/*"],
"js": ["contentScript.js"],
"run_at": "document_end"
}],
"permissions": [
"https://*/*",
"http://*/*",
"tabs"
]
}
contentScript.js
function eventFire(el, etype) {
if (el.fireEvent) {
el.fireEvent('on' + etype);
} else {
var evObj = document.createEvent('Events');
evObj.initEvent(etype, true, false);
el.dispatchEvent(evObj);
}
}
var losExpandibles = document.getElementsByClassName("ui_qtext_more_link");
for (var i = 0; i < losExpandibles.length; i++) {
eventFire(losExpandibles[i], 'click');
}
I try to simulate a left click of the mouse on every element with class name: "ui_qtext_more_link" but the for loop breaks after first pass.
But if I run it in the console it works on every element just fine. What am I missing?

Related

Storing items into a list from the values fetched by background script

I am new to extensions. my extension's purpose is to save the URLs of all tabs ever opened on the browser. This is my background script so far:
var URLs = [];
chrome.history.onVisited.addListener(storeURL);
chrome.storage.onChanged.addListener(function (changes, namespace) {
for (let [URL, { oldValue, newValue }] of Object.entries(changes)) {
URLs[URLs.length] = newValue;
}
});
function storeURL(HistoryItem) {
console.log("entered in storeURL function", HistoryItem)
chrome.storage.sync.set({ URL: HistoryItem?.url }, function () {
console.log('URL is set to ' + HistoryItem?.url);
});
}
The problem is that i am able to access the current url in developer tools but its not being stored in URLs.
Note: I want the extension to be autonomous and not popup. my manifest.json:
{
"name": "URL tracker",
"version": "0.0.1",
"manifest_version": 3,
"description": "Stores the browser URLs",
"action": {
"default_popup": "url.html",
"default_icon": "logo-small.png"
},
"background": {
"service_worker": "background.js"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"css": [],
"js": ["content.js"]
}
],
"icons": {
"128": "logo-small.png",
"512": "logo-small-2.png"
},
"permissions": [
"history",
"tabs",
"activeTab",
"storage"
]
}

Chrome.tabs.sendMessage not working for no reason

I am making a chrome extension, and trying to send a message from the chrome extension page to the content.js. I know that in order to that I need to send the message to the bakcground.js and forward it to the content.js by sending it to either a specific tabs. I hvae done that many times and have not had any issues, but this time it just doesn't work.
main.js file (from the extension page):
chrome.runtime.sendMessage({
name: "stop"
})
background.js:
chrome.tabs.query({}, tabs => {
for (let i = 0; i < tabs.length; i++) {
if (tabs[i].status == "complete") {
chrome.tabs.sendMessage(tabs[i].id, { msg: "Hello" })
}
}
})
content.js:
function recieve(msg) {
console.log(msg)
}
chrome.runtime.onMessage.addListener(recieve)
manifest.json:
{
"manifest_version": 2,
"name": "app",
"description": "app description",
"version": "3.0.0",
"icons": {
"19": "./images/icon_19.png",
"128": "./images/icon_128.png",
"150": "./images/icon_150.png"
},
"browser_action": {
"default_title": "title"
},
"permissions": [
"tabs",
"alarms",
"notifications"
],
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": [
"jquery-3.4.1.min.js",
"content.js"
]
}
],
"background": {
"scripts": [
"background.js"
]
}
}

Passing variable from Content.js to Background.js

I'm trying to use a variable I created in content.js in my background.js file.
Currently, when I try to use a variable in my background.js that was created in my content.js, I get a chrome error saying "Unexpected Identifier" (referencing ContentTag1 in background.js)
Do you know how I can do this?
Code from my Background.js File
function appendData(data) {
var mainContainer = document.getElementById("myData");
for (var i = 0; i < data.length; i++) {
if data[i].DBTag == ContentTag1 {
var div = document.createElement("div");
div.innerHTML = 'Name: ' + data[i].Name + ' ' + data[i].Price;
mainContainer.appendChild(div);
}
}
}
Code from my Content Script
var ContentTag1 = "test";
var ContentTag2 = "test";
var ContentTag3 = "test";
Manifest Below:
{
"name": "App",
"version": "1.0",
"description": "Description",
"permissions": [ "activeTab", "declarativeContent", "storage", "http://localhost:3000/brands"],
"background": {
"scripts": [ "js/lib/jquery.min.js", "js/app/background.js"],
"persistent": false
},
"content_scripts": [
{
"matches": [ "https:/somesite*" ],
"css": ["style.css"],
"js": [
"js/lib/jquery.min.js",
"js/app/content.js"
],
"all_frames": false
}
],
"web_accessible_resources": ["content.html",
"content.css",
"css/popup.css"
],
"browser_action": {
"default_popup": "views/popup.html",
"default_icon": {
"16": "images/someimage.png",
"32": "images/someimage.png",
"48": "images/someimage.png",
"128": "images/someimage.png"
}
},
"icons": {
"16": "images/someimage.png",
"32": "images/someimage.png",
"48": "images/someimage.png",
"128": "images/someimage.png"
},
"manifest_version": 2
}
You should send a message from content and add a listener on background
here an answer that show example of that.
Also you may find here the documentation about messaging in chrome extention.

Chrome Extension - run content script every time new page loads

I am trying to create a chrome extension that injects some content into product pages on a particular site. Currently my content.js only runs if I manually refresh the tab on a matching page. I need it to run automatically every time the user navigates to a matching page.
manifest.json
{
"manifest_version": 2,
"name": "My Test",
"version": "1.0",
"description": "My Test POC",
"icons": {
"128": "/images/128x128_elevated_b_icon_purp.png",
"48": "/images/48x48_elevated_b_icon_purp.png",
"16": "/images/16x16_elevated_b_icon_purp.png"
},
"page_action": {
"default_icon": "/images/16x16_elevated_b_icon_purp.png",
"default_title": "My Test"
},
"background": {
"scripts": ["/scripts/eventPage.js"],
"persistent": true
},
"content_scripts": [
{
"matches": ["https://www.tesco.com/groceries/en-GB/products/*"],
"run_at": "document_idle",
"js": ["/scripts/libs/jquery.min.js", "/scripts/content.js"],
"css": ["content.css"]
}
],
"permissions": [
"tabs",
"https://www.tesco.com/groceries/en-GB/products/*"
]
}
eventPage.js
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if(request.todo == "showPageAction") {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.pageAction.show(sender.tab.id);
alert('eventPage.js');
});
}
});
content.js
chrome.runtime.sendMessage({todo: "showPageAction"});
alert('content.js');
$(document).ready(function() {
var productName = $('head title').text().replace(' - Tesco Groceries', '');
console.log('Product Name: ' + productName);
//Do stuff
});

Manipulate DOM in chrome extension

I am trying to learn about chrome extensions but I am not able to understand how to manipulate DOM of a page using content_scripts.
manifest.json
{
"name": "First",
"version": "1.0",
"manifest_version": 2,
"description": "First extension",
"background": {
"scripts": ["test.js"]
},
"page_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"content_scripts": [ {
"js": [ "jquery.min.js", "popup1.js" ],
"matches": [ "http://*/*", "https://*/*" ]
} ],
"permissions" : [
"tabs",
"http://*/*"
]
}
test.js
function check(tab_id, data, tab){
if(tab.url.indexOf("google") > -1){
chrome.pageAction.show(tab_id);
}
};
chrome.tabs.onUpdated.addListener(check);
popup1.js
function myfunc(){
var x = $('#options option:selected').text();
$("body").append('Test');
alert(x);
//window.close();
}
$(document).ready(function(){
$('#options').change(myfunc);
});
The above code/extension works fine because myfunc gets called but it doesn't inject Test into the body of google.com.
So, where am I going wrong in accessing/manipulating the DOM.
If you want to play with browser tab DOM on event of popup. In this case you have to pass a message to content script from background script, or inject JavaScript into content script : have a look
manifest.json
{
"name": "First",
"version": "1.0",
"manifest_version": 2,
"description": "First extension",
"background": {
"scripts": ["test.js"]
},
"page_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"content_scripts": [ {
"js": [ "jquery.min.js", "content_script.js" ],
"matches": [ "http://*/*", "https://*/*" ]
} ],
"permissions" : [
"tabs",
"http://*/*"
]
}
content_script.js
function myfunc(){
var x = $('#options option:selected').text();
$("body").append('<div style="width:200px; height:200px; border: 1px solid red;"></div>');
}
$(document).ready(myfunc);
Now you will get A box with red border at the bottom of the page.
popup.js
function myfunc(){
var x = $('#options option:selected').text();
chrome.extension.sendMessage({sel_text: x});
}
$(document).ready(function(){
$('#options').change(myfunc);
});
test.js (used in background)
chrome.extension.onMessage.addListener(
function(request, sender, sendResponse) {
appendTextToBody(request.sel_text);
});
function appendTextToBody(text) {
chrome.tabs.getSelected(null, function(tab) {
chrome.tabs.executeScript(tab.id, {"code" : '$("body").append("Test : "'+text+');'}) ;
});
}
function check(tab_id, data, tab){
if(tab.url.indexOf("google") > -1){
chrome.pageAction.show(tab_id);
}
};
chrome.tabs.onUpdated.addListener(check);

Categories

Resources