Hi i've been looking at lots of tutorials and can't find anything it might be my poor google skills but I hoped the answer was quick and simple.
The Plan
The aim is to make an extension which will append any website using javascript.
Current State
I current have the javascript append coded and basic manifesto created
document.body.innerHTML += '<div id="adBar" style="background-color: #933131; width: 150px; height: 400px; position: fixed; left: 10px; top: 25%;"></div>'
The Problem
I can't find anywhere how to create a chrome extension which would allow this script to run in the background on every page, I can only find how to make a pop-up on click.
I hope this is clear and simple. All help is appreciated!
You need to set matches to <all_urls> (also you can add a button to the extension to trigger it). Here is my full example:
Extension Buttons
My Extension
├── manifest.json
├── background.js
├── content.js
├── jquery-2.2.0.min.js
├── icon.png
manifest.json
{
"manifest_version": 2,
"name": "My Extension",
"version": "0.1",
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": ["jquery-2.2.0.min.js","content.js"]
}
],
"browser_action": {
"default_icon": "icon.png"
},
"background": {
"scripts": ["background.js"]
},
"icons": {
"16": "icon.png",
"48": "icon.png",
"128": "icon.png"
}
}
background.js
chrome.browserAction.onClicked.addListener(function(tab) {
// Send a message to the active tab
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
var activeTab = tabs[0];
chrome.tabs.sendMessage(activeTab.id, {"message": "clicked_browser_action"});
});
});
content.js
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if( request.message === "clicked_browser_action" ) {
//YOUR CODE GOES HERE
}
}
);
Basically I added a button to the extension that calls the content.js once it is pressed. The listener is on background.js.
You can wrap the code in content scripts and use "all_urls" for match patterns.
manifest.json
{
"name": "Test",
"version": "1.0",
"description": "Test",
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": [
"content.js"
],
"run_at": "document_end",
"all_frames": true
}
],
"manifest_version": 2
}
content.js
document.body.innerHTML += '<div id="adBar" style="background-color: #933131; width: 150px; height: 400px; position: fixed; left: 10px; top: 25%;"></div>'
Related
I'm opening a chrome extension programmatically from the background script with the following code:
background.js
chrome.windows.getLastFocused().then((window) => {
const width = 600 + 100;
const height = 400 + 100;
const left = window.width - width;
chrome.windows.create({url: "./index.html", type: "popup", height: height, width: width, left: left, focused: true});
});
This works perfectly fine for ./index.html, but not for any other path like ./approvals.html although this page exists.
Navigating in the extension with a link from index.html to approvals.html works smooth, but directly opening the extension with this path results in ERR_FILE_NOT_FOUND.
I think it might be related to some missing permissions, following my manifest.json:
{
"name": "Chrome React Extension",
"description": "The power of React for building interactive Chrome extensions",
"version": "1.0",
"manifest_version": 3,
"action": {
"default_popup": "index.html",
"default_title": "Open the popup"
},
"permissions": [
"storage"
],
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"]
}
],
"background": {
"service_worker": "background.js"
}
}
Any help is really appreciated!
Creating chrome extension which opens link in new tab and trying to click the button on newly opened tab -
I am able to open new tab using the extension but the content script is not executing on new tab.
Manifest File
{
"manifest_version": 2,
"name": " New Tab Launcher",
"description": "Create the tab and button click ",
"version": "1.0",
"icons": {
"16": "icon.png",
"48": "icon.png",
"128": "icon.png"
},
"browser_action": {
"default_popup": "popup.html"
},
"permissions": [
"activeTab",
"tabs"
],
"content_scripts": [
{
"matches": [
"http://*/*", "https://*/*"
],
"js": [
"jquery-3.6.0.slim.min.js","contentScript.js"
],
"run_at": "document_end"
}
]
}
popup.js
document.addEventListener('DOMContentLoaded', function() {
var checkPageButton = document.getElementById('addMeetingUrl');
checkPageButton.addEventListener('click', function() {
chrome.tabs.create({'url': "youtube.com"});
}, false);
}, false);
contentScript.js
alert("This is test");
$(document).load(function (e) {
alert("Testing content script" +$('#logo').text());
});
In above the first alert come successfully by next script does not launch.
I have tried Removing the $(document).load and adding $(document).ready both are not working for me.
#logo could be added to the DOM after the load and ready events are fired.
Check with the debugger if I've stated is true.
If so you will need to use MutationObserver.
Try removing "run at" as it will default to "document_idle" which is usually safer option
My extension checks for broken images on a website. Everything works fine if I open an URL at a time but if I open several URLs from one site, the summary in popup.html is always the same as the active tab (it's not updated for each site).
I don't know how to refer to the actual URL of the analysis and avoid the "active tab". Any ideas?
Manifest.json
{
"name": "Test",
"permissions": ["activeTab", "declarativeContent", "storage","tabs"],
"version": "1.0.0",
"description": "Test",
"background": {
"scripts": ["background.js"],
"persistent": false
},
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*", "https://www.google.com/_/chrome/newtab*"],
"exclude_globs": ["*#*"],
"js": ["jquery-3.4.1.min.js", "content.js"]
}
],
"web_accessible_resources": ["popup.html"],
"browser_action": {
"default_icon": {
"16": "images/ico.png",
"32": "images/ico.png",
"48": "images/ico.png",
"128": "images/ico.png"
}
},
"manifest_version": 2
}
Content.js
chrome.runtime.onMessage.addListener((msg, sender, response) => {
if (msg.subject === 'DOMInfo') {
var domInfo = {
images: number_images
};
response(domInfo);
}
});
Popup.js
window.addEventListener('DOMContentLoaded', () => {
chrome.tabs.query({
active: true,
currentWindow: true
}, tabs => {
chrome.tabs.sendMessage(
tabs[0].id,
{subject: 'DOMInfo'},
setDOMInfo);
});
});
I'm pretty sure is the tabs[0].id that causes the problem but I'm not sure how I can refer to the current URL that run the content.js script and make sure the popup.html gets the analysis from this URL. Any ideas?
In the background.js I had no problem referring the sender tab:
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse)
{
chrome.tabs.query({active:true, windowType:"normal", currentWindow: true},function(d){
var tabId = sender.tab.id;
....
Assuming popup.html is loaded into an iframe inside the web pages by your content script, you need chrome.tabs.getCurrent that returns the tab where this code is running so each iframe will find its own tab:
chrome.tabs.getCurrent(tab => {
chrome.tabs.sendMessage(tab.id, {subject: 'DOMInfo'}, callback);
});
P.S. When using sender.tab.id you don't need chrome.tabs.query - you already have the id.
I cannot understand why this isn't working.
I have checked the google extension dev docs, checked some sample code.
Checked other stackoverflow Question/Answers without any positive feedback/results from testing.
This extension is very simple
It displays a popup with an input text field and a button
on clicking it will send a message to the content script via postMessage to update the document.getElementsByTagName("video")[0].playbackRate
this will adjust youtubes or other supported (future venture) Video
Playback Speed beyond or lower than the default of 0.25, 0.50, 1, 1.25, 1.50, 2 or to an exact value like 1.4390
Easier and faster than using said console + devtools, etc..which speeds up the initial setup...
please help :)
manifest.json
{
"manifest_version": 2,
"name": "Youtube Playback",
"version": "1.0",
"description": "Manage Playback Speed With Any Value",
"homepage_url": "https://github.com/DeanVanGreunen",
"permissions": [
"tabs",
"activeTab"
],
"browser_action": {
"icon": "icon.png",
"default_icon": "icon.png",
"title": "Youtube Playback",
"default_title": "Youtube Playback",
"popup": "popup.html",
"default_popup": "popup.html"
},
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": ["content.js"]
}
]
}
popup.html
<script>
function setPlaybackSpeed(speed){
chrome.tabs.query({currentWindow: true, active: true}, function (tabs){
var activeTab = tabs[0];
chrome.tabs.sendMessage(activeTab.id, {action: "setPlaybackSpeed", "speed": speed});
});
}
</script>
<div>
<input id="text_playbackspeed" type="text" style="" placeholder="1" value="1"/>
<button id="btn_updateplaybackspeed" style="">Update</button>
</div>
content.js
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if( request.action === "setPlaybackSpeed" ) {
document.getElementsByTagName("video")[0].playbackRate = request.playback_speed;
}
return true;
}
);
Here is the working solution (its being a while however here you go, I forgot to update this thread)
Overview
This extension is very simple
It displays a popup with an input text field and a button
on clicking it will send a message to the content script
via postMessage to update the document.getElementsByTagName("video")[0].playbackRate
this will adjust youtubes or other supported (future venture) Video Playback
Speed beyond or lower than the default of 0.25, 0.50, 1, 1.25, 1.50, 2 or up a max of 4 times the original speed by using 4
an exact value like 1.4390
Easier and faster than using said console + devtools, etc..which speeds up the initial setup...
Project Repo Hosted on Github at:
https://github.com/DeanVanGreunen/YT_SpeedMeUpExtension
Or get the latest release via:
https://github.com/DeanVanGreunen/YT_SpeedMeUpExtension/releases/
Or see latest updated Files below:
manifest.json
{
"manifest_version": 2,
"name": "Youtube Playback",
"version": "1.0",
"description": "Manage Playback Speed With Any Value",
"homepage_url": "https://keybase.io/DeanVanGreunen",
"repo_url": "https://github.com/DeanVanGreunen/YT_SpeedMeUpExtension",
"permissions": [
"tabs",
"activeTab"
],
"icons": {
"128": "icon.png"
},
"browser_action": {
"default_icon": {
"128": "icon.png"
},
"default_title": "Youtube Playback",
"default_popup": "popup.html"
},
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": ["content.js"]
}
]
}
popup.html
<style>
#text_playbackspeed {
padding: 2px;
margin-bottom: 4px;
}
#leButtons, #findsMe {
padding: 4px 8px;
text-align: center;
margin:0px auto;
}
#findsMe img{
display: block;
margin: 0 auto;
width: 69px;
height: 69px;
}
</style>
<div>
<input id="text_playbackspeed" type="text" style="" placeholder="1" value="1"/>
<div id="leButtons">
<button id="btn_updateplaybackspeed_minus" style="">-1</button>
<button id="btn_updateplaybackspeed" style="">Update</button>
<button id="btn_updateplaybackspeed_add" style="">+1</button>
</div>
</div>
<div id="findsMe">
<img src="https://avatars0.githubusercontent.com/u/22296075" alt="The Developer" />
<a target="_blank" href="https://keybase.io/DeanVanGreunen">Find me</a>
</div>
<script type="text/javascript" src="popup.js"></script>
popup.js
function setPlaybackSpeed(speed){
chrome.tabs.query({currentWindow: true, active: true}, function (tabs){
var activeTab = tabs[0];
chrome.tabs.sendMessage(activeTab.id, {action: "setPlaybackSpeed", "speed": speed});
});
}
function getPlaybackSpeed(){
chrome.tabs.query({currentWindow: true, active: true}, function (tabs){
var activeTab = tabs[0];
chrome.tabs.sendMessage(activeTab.id, {action: "getPlaybackSpeed"});
});
}
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if(sender.tab){
if( request.action == "returnPlaybackSpeed" ) {
document.getElementById('text_playbackspeed').value = request.speed;
}
}
}
);
document.getElementById('btn_updateplaybackspeed_minus').addEventListener('click', function(event) {
var num = parseFloat(document.getElementById('text_playbackspeed').value)-1;
document.getElementById('text_playbackspeed').value = num;
});
document.getElementById('btn_updateplaybackspeed_add').addEventListener('click', function(event) {
var num = parseFloat(document.getElementById('text_playbackspeed').value)+1;
document.getElementById('text_playbackspeed').value = num;
});
document.getElementById('btn_updateplaybackspeed').addEventListener('click', function(event) {
setPlaybackSpeed(document.getElementById('text_playbackspeed').value);
});
getPlaybackSpeed();
content.js
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if(!sender.tab){
if( request.action == "getPlaybackSpeed" ) {
chrome.runtime.sendMessage({action: "returnPlaybackSpeed", speed: document.getElementsByTagName("video")[0].playbackRate}, function(){});
} else if( request.action == "setPlaybackSpeed" ) {
document.getElementsByTagName("video")[0].playbackRate = request.speed;
}
}
}
);
icon.png
i can't figure out how to make it work. My script works by itself. but doesn't work with background.js. I want my google extension to work only if the user clicks on it's icon, so I have created the file background.js and putted the code:
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(null, {file: "change_content.js"});
});
my manifest.json here:
{
"manifest_version": 2,
"name": "Name",
"description": "change content.",
"version": "3.0",
"browser_action": {
"default_icon": "icon.png"
},
"content_scripts": [
{
"matches": ["http://*/*"],
"js": ["change_content.js"]
}
],
"background": {
"scripts": ["background.js"],
"persistent": false
},
"permissions": [
"tabs", "http://*/*"
]
}
and here is the change_content.js:
var oldSource = document.documentElement.innerHTML;
document.body.innerHTML = changeContent(oldSource);
function changeContent(source){
.....
}
The reason you are having the issue where change_content.js is executing before you press the button is because thats how content scripts work. If you include a content script in your manifest.json it will load and execute that script. Try removing the "content_scripts" section from the manifest and you should see it work as it should.
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(null, {file: "change_content.js"});
});
I've got a feeling the error lies in you using "null" as it might be searching for a tab with the tabId - null, you should try doing this instead?
chrome.tabs.executeScript({file: "change_content.js"});