coriandres coriandres - 1 month ago 8
HTML Question

Chrome extension: Modifying the content of a webpage

I'm trying to make a simple Chrome Extension where I will 'block' the content of the website Reddit by replacing it with a short text. This is what I have so far:

manifest.json

{
"manifest_version": 2,

"name": "BlockIt",
"description": "Block Reddit, increase productivity!",
"version": "1.0",

"browser_action": {
"default_icon": "icon.png",
"default_title": "BlockIt"
},

"permissions": [
"storage", "tabs",
"http://www.reddit.com/*"
],

"content_scripts": [
{
"matches": [ "*://reddit.com/*" ],
"js": ["content-script.js"]
}
]
}


popup.html

<!doctype html>
<html>
<head>
<style>
body {
font-family: Verdana, Arial, Helvetica, Tahoma, sans-serif;
background-color:#EFF7FF;
margin: 5px 5px 5px 5px;
width: 110px;
height: 100%;
text-align:center;
}
</style>
<!--Scripts-->
<script src="popup.js"></script>
<script src="content-script.js"></script>
</head>
<body>
<h2>BlockIt!</h2>
<div id="en"><label for="enable">Enable BlockIt</label> <input id="enable" type="checkbox" style="vertical-align:middle; position:relative; bottom: 1px;"/>
</div>
</body>
</html>


popup.js

document.addEventListener('DOMContentLoaded', function () {
document.querySelector('#enable').addEventListener('change', changeHandler);
});

function changeHandler() {
if (enable.checked) {
chrome.storage.sync.set({ 'enable': true }, function () { });
}
}


content-script.js

var content = document.getElementsByTagName("body");
var text = "BlockIt enabled (to disable, click on the icon).";
//TODO: replace content with text


I'm having two major issues right now: I'm not sure how I should go about in modifying the content of the webpage and replace it with the
text
above, and I'm not sure how to inject
content-script.js
when the checkbox in
popup.html
is checked. How do I go about in approaching this?

Answer

One possibility would be to use chrome.storage.sync.get() to get the enabled status at the time the content-script.j is injected into the page:

content-script.js:

chrome.storage.sync.get({enable:false}, items=> {
    if(items.enable) {
        document.body.textContent="BlockIt enabled (to disable, click on the icon).";
    }
});

This is not reversible for the current page. Given that your users will probably expect the block to be reversible without having to reload the page, you might want to consider a different method of accomplishing your block than to replace all of the content.

In addition, this will only replace the <body> for pages which are loaded after the block is enabled. It will not affect pages which are already loaded. You will probably want to use chrome.tabs.query() to get a list of tabs which are currently showing reddit.com. You will then need to inject the script again using chrome.tabs.executeScript().

Something like:

//This requires the "tabs" permission.
//Execute after you have stored the data to chrome.storage.sync (e.g. in the callback)
chrome.tabs.query({url:"*://reddit.com/*"},tabs=>{
    tabs.forEach(tab=>{
        chrome.tabs.executeScript(tab.id,{file:"content-script.js"});
    });
});