I’m writing an extension that uses a content script that gets executed in a given tab with the user preses the browserAction icon button.
The desired behavour I’m looking for is as follows:
First press - Executes content script and triggers a function (showing a div for example)
Second press - Sends a message to content script and triggers a function (hides the div for example)
Third press shows the div… and so on.
At the moment, every press of the button executes a new script.
I have an idea of how to achieve my desied outcome but it seems a bit overkill and I’m wondering if anone has faced a similar challenge and if there’s a more elegant way.
My current idea:
Query for all tabs and keep track of open and closed tabs with event listeners
Wite tab id’s to an object to keep track of them i.e {tabID1: {status: false}, tabID2: {status: true}}
When the user presses the button, check if tabID1.status is false, if so execute script and send initial toggle message
2nd press - Again, check tab.id.status and if the extension is running (div is visible), send a message to hide the div.
Actually you can define new property on the window object and then check it’s value.
So your content script code could look something like this:
(() => {
// when running first time, `_myDivNode` is not defined
if (window._myDivNode) return removeSelf();
// create your div
const divNode = document.createElement('div');
document.body.appendChild(divNode);
// and save it to the window
window._myDivNode = divNode;
function removeSelf() {
window._myDivNode.remove(); // removing your previous div
window._myDivNode = null; // and resetting value
}
})();
I’m doing this in my Save my Password extension (you can unzip it and check the source).
Yes it’s a arrow function, and if you wrap it with braces, you can immediately invoke it. It’s called IIFE:
EDIT:
The reason I use it here is that you get an error if you use const in your code and run your content script again - it would complain that you are trying to re-define a const.
For this simple case yes, but if you use IIFE you can easily make it async and then use await inside (which is not possible in the top level block). Also you can break execution with return .