I am relative newbie with web extensions. My idea is that I want to create a web extension that inputs an integer through a popup when the user enters an entertaining website. When this limit runs out, I want to block the site for a given time depending on the time of day.
So far, I have created this manifest.json file:
{
"manifest_version": 3,
"name": "Entertainment Time Tracker",
"version": "1.0.0",
"description": "Tracks time spent on entertaining websites and allows the user to set time limits for each session.",
"permissions": [
"activeTab", "<all_urls>", "declerativeNetRequest", "tabs", "notifications", "http://*/*", "https://*/*"
],
"background": {
"service_worker": "background.js"
},
"action": {
"default_popup": "popup.html"
}
}
Then I got the following code from ChatGPT:
// The URLs of the entertaining websites to track
const ENTERTAINMENT_URLS = [
"https://www.youtube.com",
"https://www.netflix.com",
"https://tv.nrk.no/",
"https://www.discoveryplus.com/no/",
"https://www.disneyplus.com/",
"https://www.hbo.com/",
"https://www.hbo.no/",
];
// The current session start time
let sessionStartTime = null;
// The total time spent on entertaining websites in the current session
let sessionTimeSpent = 0;
// The interval ID for the time checker
let checkIntervalID = null;
// The time limit for the current session, in minutes
let sessionTimeLimit = null;
// Check the time spent on entertaining websites and update the UI
function checkTime() {
// Calculate the time spent in the current session
const timeElapsed = Date.now() - sessionStartTime;
sessionTimeSpent += timeElapsed;
// Update the UI with the time spent in the current session
updateUI(sessionTimeSpent);
// Check if the time limit has been reached
if (sessionTimeSpent >= sessionTimeLimit * 60 * 1000) {
// Stop the time checker
clearInterval(checkIntervalID);
// Show an alert to the user that the time limit has been reached
alert(`You have reached the time limit of ${sessionTimeLimit} minutes for this session.`);
// Change the site to show clouds and a 404 error
switch (window.location.hostname) {
case "www.youtube.com":
document.head.innerHTML = generateSTYLES();
document.body.innerHTML = generateHTML("YOUTUBE");
}
// Reset the session start time, time spent, and time limit
sessionStartTime = null;
sessionTimeSpent = 0;
sessionTimeLimit = null;
}
}
// Initialize the time tracker
function initialize() {
// Get the current tab
browser.tabs.query({ active: true, currentWindow: true }).then((tabs) => {
const currentTab = tabs[0];
// Check if the current tab is an entertaining website to track
if (isTrackedWebsite(currentTab.url)) {
// Show the popup
showPopup();
// Set the session start time
sessionStartTime = Date.now();
// Start the time checker
checkIntervalID = setInterval(checkTime, 60 * 1000);
// Show the time limit setting form
showSettingForm();
}
});
}
// Check if the given URL is an entertaining website to track
function isTrackedWebsite(url) {
return ENTERTAINMENT_URLS.some((trackedUrl) => url.startsWith(trackedUrl));
}
// Show the popup
function showPopup() {
// Create the popup HTML
const popupHtml = `
<form>
<label>Enter an integer: <input type="number" name="integer" min="1" max="100" required /></label>
<input type="submit" value="Submit" />
</form>
`;
// Show the popup
browser.windows.create({
type: "popup",
url: "data:text/html;charset=utf-8," + encodeURI(popupHtml),
});
}
// Show the time limit setting form
function showSettingForm() {
// Get the time limit setting form
const form = document.getElementById("setting-form");
// Show the form
form.style.display = "block";
// Add an event listener for the submit event on the form
form.addEventListener("submit", (event) => {
// Prevent the form from submitting and reloading the page
event.preventDefault();
// TODO: Handle the form submission here
});
}
initialize();
Obviously, it is lacking some essential features. For instance the "updateUI" function is not implemented. I also have two functions ("generateSTYLES" and "generateHTML") that creates a loading screen for websites that are "blocked".
My main problems with the scripts:
So, I would love help in general on improvements to the scripts and answers/help with the questions above. Also, should I make a separate html file or include it in the js-file?
You miss how web extensions work.
Web extensions are made of 3 main contexts:
The popup is what you see when you click your extension icon in the browser toolbar.
The background script works as background API for your extension.
The content script is a kind of JS script that you inject in the target pages. This is what you actually need.
First of all, you should create 1 separate script for the 3 contexts. Additionally, in your manifest.json you should define on which pages/entertainment websites you want to inject your content script. Here is an example:
"content_scripts": [
{
"matches": [ "http://siebelgcs.invensys.com/serviceoui_enu/*" ],
"run_at": "document_end",
"js": [
"lib/require.js",
"lib/require-cs.js",
"lib/require-cfg.js",
"app/main.js"
],
"css": [
"css/content.css",
"css/controls.css",
"css/activityInStatus.css"
]
}
],
The content script should then be able to block the website. For example you can append a new div to the page that disappears when the user enters the time in your popup. The communication between your content script and your popup you should use the runtime message API: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/sendMessage
I would read Mozilla documentation on the topic, they have such good information there.