Reputation: 51
I have a chrome extension that injects a js file into a webpage. And also open a popup when clicked in the browser. In the popup there is a button that should change a variable in the js file. But the injected file usually cant communicate with the rest of the extension. How do i change this?
I'm still a bit new to chrome extensions, thank you for your help.
EDIT: Here is what i have so far
Manifest file:
{
"manifest_version": 2,
"name": "Minds Color Extension",
"version": "1",
"content_scripts": [
{
"matches": ["https://www.minds.com/*"],
"js": ["injectedjs.js"],
"css" : ["injectedcss.css"]
}
],
"browser_action": {
"default_icon": {
"19": "icon.png",
"38": "icon.png"
},
"default_title": "Minds Notification page",
"default_popup": "popup.html"
}
}
Popup.html
<!--
<!doctype html>
This page is shown when the extension button is clicked, because the
"browser_action" field in manifest.json contains the "default_popup" key with
value "popup.html".
-->
<html>
<head>
<title>Minds Theme Extension</title>
<style>
html, body {
margin:0;
padding:10;
width: 250px;
}
#blue {
background-color: #337dff;
}
#orange {
background-color: #ff5733;
}
#dark {
background-color: #4a505b;
}
button {
border: none;
color: white;
padding: 10px 27px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
}
#footer {
position: fixed;
bottom: 0;
}
</style>
<!--
- JavaScript and HTML must be in separate files: see our Content Security
- Policy documentation[1] for details and explanation.
-
- [1]: https://developer.chrome.com/extensions/contentSecurityPolicy
-->
<script src="injectedjs.js"></script>
</head>
<body>
<div id="status">
<h2> Pick a theme: </h2>
<a href="blue.html"><button type="button" id="blue" onclick="activeBlue(); run();">Blue</button></a>
<a href="orange.html"><button type="button" id="orange" onclick="activeOrange(); run();">Orange</button></a>
<a href="dark.html"><button type="button" id="dark" onclick="activeDark(); run();">Dark</button></a>
<br />
<div id="footer">
<font size="1"> <a href="mailto:?Subject=Minds%20Support" target="_top">Contact us</a></font>
</div>
</div>
</body>
</html>
Injectedjs.js
// Var block
var blue = 0;
var orange = 0;
var dark = 0;
// Activation block
function activeBlue() {
blue = 1;
}
function activeOrange() {
orange = 1;
}
function activeDark() {
dark = 1;
}
// Resets var block
function reset() {
blue = 0;
orange = 0;
dark = 0;
}
//Changes Minds css (Runs theme)
function run() {
if (blue == 1) {
// Runs code that will change minds to blue.
document.getElementById("mdl-color--white").className = "mdl-color--blue";
}
if (orange == 1) {
// Runs code that will change minds to orange
document.getElementById("mdl-color--white").className = "mdl-color--orange";
}
if (dark == 1) {
// Runs code that will change minds to dark
document.getElementById("mdl-color--white").className = "mdl-color--grey";
}
}
Injectedcss.css has nothing in it. If you need the other files like dark.html i can give them to you but i dont see why you'd need them.
Upvotes: 1
Views: 3331
Reputation: 4508
The big thing to understand is that an injected script interacts with a webpage, but is separate from what happens in your popup (or your background). So while you have injected.js listed as a content script and loaded by popup.html, they actually end up as two separate files.
So the first step will be to create a popup.js. It needs to attach the click listener (“onclick” counts as not separating javascript and html) and use message passing to tell the content script what to do. (I’ve also consolidated your logic a bit.)
["blue","orange","grey"].forEach(addListenerFor);
function addListenerFor(color) {
document.getElementById(color)
.addEventListener(click,turnPage.bind(undefined,color);
}
function turnPage(color) {
chrome.tabs.query({"active": true, "currentWindow": true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {"newClass": "mdl-color--"+color});
});
}
Within the content script, we need to listen for the message and take the appropriate action:
chrome.runtime.onMessage.addListener(changeClass);
function changeClass(message) {
reset();
if ( message.newClass ) {
document.getElementById("mdl-color--white").className = message.newClass;
}
}
Some final thoughts:
css
key from the manifest.conent_scripts
entry.getElementById
to work in popup.js, you need to run the script after the element is present. You could put everything into an onload
call, but it's probably easier to move your script
tag to just before body
closes.Upvotes: 2