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
});
Related
My Chrome extension mv3 receives messages from webpage and replies to it. Here are the codes in webpage to send message to extension:
chrome.runtime.sendMessage(chromeExtensionId,
{
"Message": "Hello",
"Data":
{
"Name": 'Jason'
}
},
function(response) {
console.log("chrome.runtime.sendMessage", response);
});
and codes in extension's background.js to receive message and reply with true/false:
chrome.runtime.onMessageExternal.addListener(function(message, sender, sendResponse) {
console.log(message, sender));
sendResponse(true);
});
manifest.json:
{
"background": {
"service_worker": "background.js"
},
"action": {
"default_icon": {
"16": "images/logo16.png",
"32": "images/logo32.png"
},
"default_title": "My Extension"
},
"content_scripts": [ {
"all_frames": true,
"match_about_blank": true,
"js": [ "util.js", "contentscript.js" ],
"matches": [ "http://*/*", "https://*/*" ],
"run_at": "document_end"
} ],
"description": " ",
"externally_connectable": {
"matches": [ "https://*.mysite.com/*", "http://*.mysite.com/*" ]
},
"icons": {
"128": "/images/logo128.png",
"16": "/images/logo16.png",
"32": "/images/logo32.png",
"48": "/images/logo48.png"
},
"manifest_version": 3,
"name": "My Extension",
"permissions": ["cookies", "tabs", "proxy", "alarms", "storage", "downloads", "webRequest", "notifications", "nativeMessaging", "clipboardRead", "clipboardWrite", "declarativeNetRequest","declarativeNetRequestFeedback" ],
"host_permissions": ["<all_urls>"],
"version": "4.0.7"
}
Most of the time it works fine.
The only problem is when i set my webpage as startup page of chrome, which means the page is opened immediately when chrome starts, sendMessage does not return and console.log in both sender and receiver sides are not printed. There is no error output in console either. It looks like codes freeze inside sendMessage. What's going on there?
It's a known problem. Chrome intentionally delays extensions at browser startup to show the active tab faster. The workaround is to repeat sendMessage:
send('abcdefgkhgghfg........', {foo: 'bar'}, res => {
console.log('response', res);
});
function send(extensionId, msg, callback, retry = 20) {
const timer = setTimeout(send, 100, extensionId, msg, callback, retry - 1);
chrome.runtime.sendMessage(extensionId, msg, response => {
if (!chrome.runtime.lastError || !retry) {
clearTimeout(timer);
callback(response);
}
});
}
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?
New to making extensions, I origally was attempting to load cookies but realised my EventPage.js didn't seem to be loading - since a basic console.log("Hello") wasn't loading.
I am loading the extension via Chrome "Load unpacked extensions", where manifest,content and background scripts are.
The code attached below is what I've been using to see if I can even get a console log from the event page. Only the content script loads, even If I press a key and that is logged.
CHROME:58
Any suggestions?
Manifest.SON
{
"manifest_version": 2,
"name": "Facebook Extension ",
"version": "1.0",
"description": "",
"permissions": ["storage", "webNavigation", "activeTab", "tabs", "cookies",
"*://*.facebook.com/*"],
"background": [
{
"scripts": ["event_Page.js"],
"persistent" : false
}
],
"content_scripts": [
{
"matches": ["*://*.youtube.com/*"],
"css": ["style.css"],
"js": ["jquery-2.1.0.min.js", "talkToEvent.js"]
}
]
talkToEvent.js
console.log("Hello World!s");
$(document).ready(function() {
console.log("DOM READY!");
$(document.documentElement).keydown(function (e) {
console.log("Key Has Been Pressed!");
chrome.runtime.sendMessage({Message: "getTextFile"}, function (response) {
;
})
})
});
event_Page.js
console.log("Atleast reached background.js")
chrome.runtime.onMessage.addListener (
function (request, sender, sendResponse) {
console.log("Reached Background.js");
if (request.Message == "getTextFile") {
console.log("Entered IF Block");
$.get("http://localhost:63342/Projects/StackOverflow/ChromeEXT/helloWorld1", function(response) {
console.log(response);
// to send back your response to the current tab
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {fileData: response}, function(response) {
;
});
});
})
}
else {
console.log("Did not receive the response!!!")
}
}
);
You have an incorrect manifest.json.
According event pages docs it should be an object, but in your manifest it is an array.
Correct manifest.json:
{
"manifest_version": 2,
"name": "Facebook Extension ",
"version": "1.0",
"description": "",
"permissions": [
"storage",
"webNavigation",
"activeTab",
"tabs",
"cookies",
"*://*.facebook.com/*"
],
"background": {
"scripts": [
"event_Page.js"
],
"persistent": false
},
"content_scripts": [
{
"matches": [
"*://*.youtube.com/*"
],
"css": [
"style.css"
],
"js": [
"jquery-2.1.0.min.js",
"talkToEvent.js"
]
}
]
}
Also fixed missed comma and close bracket.
I need to iterate and click all the elements with the class .star_gray on page, and keep the iteration and clicking going after redirection. Running JavaScript code cannot meet the second requirement, so I plan to write a Chrome Extension.
But I failed to simulate clicking events on web pages via the extension. My project is as below:
manifest.json
{
"manifest_version": 2,
"name": "Check'em All",
"description": "",
"version": "1.0",
"browser_action": {
"default_popup": "popup.html"
},
"background": {
"persistent": true,
"scripts": ["jquery.js", "background.js"]
},
"content_scripts": [{
"matches": ["file:///*"],
"js" : ["popup.js"]
}],
"permissions": [
"tabs",
"http://*/*",
"https://*/*"
]
}
popup.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Check'em All!</title>
</head>
<body>
<h1>Check'em All!</h1>
<button id="check-btn">BUTTON</button>
<script src="http://cdn.bootcss.com/jquery/2.1.4/jquery.min.js"></script>
<script src="popup.js"></script>
</body>
</html>
popup.js
document.addEventListener('DOMContentLoaded', function () {
var btn = document.getElementById('check-btn');
btn.addEventListener('click', injectScript);
});
function injectScript() {
alert('Handler called!');
chrome.tabs.executeScript(null, { file: 'background.js' });
}
background.js
$(document).ready(function(){
$('.star_gray').click();
$('a.btn.page_next').click();
});
With the code above, when I click the button(#check-btn) on the popup, nothing happens.
You can't get access DOM in background page. And per your code, you might need to learn more from Official Tutorial, since it seems you are confused with "popup", "background" and "content".
Assuming you want to trigger the click event for all elements with class ".star_gray" in the content page, the following code trigger those events once you click on browserAction.
manifest.json
{
"name": "Test",
"version": "1.0",
"permissions": [
"tabs"
],
"description": "Test",
"background": {
"persistent": false,
"scripts": [
"background.js"
]
},
"content_scripts": [
{
"matches": [
"*://*/*"
],
"js": [
"jquery.js",
"content.js"
],
"run_at": "document_end",
"all_frames": true
}
],
"browser_action": {
"title": "Test"
},
"manifest_version": 2
}
background.js
chrome.browserAction.onClicked.addListener(function() {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {command: "click"}, function(response) {
console.log(response.result);
});
});
});
content.js
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
$('.star_gray').click();
$('a.btn.page_next').click();
sendResponse({result: "success"});
});
Improving the previous answer by #haibara-ai not to use the tabs permission.
Note that in your case you don't even need to watch for ready() since the script runs only when browser action is triggered which is presumably well after DOMContentLoaded.
manifest.json
{
"name": "Test",
"version": "1.0",
"permissions": [
"activeTab"
],
"description": "Test",
"background": {
"scripts": [
"background.js"
]
},
"browser_action": {
"title": "Test"
},
"manifest_version": 2
}
background.js
var files = [
'jquery.js',
'content.js',
];
chrome.browserAction.onClicked.addListener(function() {
for (var file of files) {
chrome.tabs.executeScript({
file: file,
allFrames: true,
});
}
});
content.js
$('.star_gray').click();
$('a.btn.page_next').click();
Note, however that this only solves the 'simulate clicking events on web pages via the extension' question. It does not mean that 'keep the iteration and clicking going after redirection' will work. It's best you create another question with the details of what exactly you mean by that.
I'm new to chrome extensions and cannot seem to figure out how the background concept works. I am building a counter extension that keeps counting even when the user closes the extension (but not the browser) and wanted to do a simple test to see if I could figure out how to use the background file. Below is my attempt to create a function that activates everytime a user clicks on a tab (outside of my extension) and when they click on 5 tabs, the alert hits. I cannot figure out why this doesn't work.
background.js:
var counter = 0;
chrome.browserAction.onClicked.addListener(function(tab){
counter++;
if (counter == 5) {
alert("Hi");
}
});
manifest.json:
{
"name": "Hello World!",
"description": "My first packaged app.",
"version": "0.1",
"permissions": ["tabs", "http://*/*"],
"manifest_version":2,
"content_scripts": [ {
"js": [ "jquery-1.9.1.js", "myscript.js" ],
"matches": [ "http://*/*", "https://*/*"]
}],
"background": {
"scripts": [
"background.js"
]
},
"browser_action": {
"default_title": "10,000 Hours",
"default_icon": "icon16.png",
"default_popup": "index.html"
},
"icons": {
"16": "icon16.png",
"48": "icon48.png",
"128": "icon128.png"
}
}
It is working for me with following code.
manifest.json
{
"name": "Popping Alert",
"description": "http://stackoverflow.com/questions/15194198/background-js-not-working-chrome-extension",
"background": {
"scripts": [
"background.js"
]
},
"version": "1",
"manifest_version": 2,
"browser_action": {
"default_title": "Click Me"
}
}
background.js
var counter = 0;
chrome.browserAction.onClicked.addListener(function (tab) {
counter++;
if (counter == 5) {
alert("Hey !!! You have clicked five times");
}
});
Can you share your related code or put your problem statement clearly if this does not work?