All the features of the extension are implemented through context.js, which is invoked whenever the toolbar popup is displayed.
The script first gets the 'identity-list' div from context.html.
let div = document.getElementById("identity-list");
It then checks whether the contextual identities feature is turned on in the browser. If it's not on, information on how to activate it is added to the popup.
if (browser.contextualIdentities === undefined) {
div.innerText = 'browser.contextualIdentities not available. Check that the privacy.userContext.enabled pref is set to true, and reload the add-on.';
} else {
Firefox installs with the contextual identity feature turned off, it's turned on when an extension using the contextualIdentities API is installed. However, it's still possible for the user to turn the feature off, using an option on the preferences page (about:preferences), hence the need for the check.
The script now uses contextualIdentities.query to determine whether there are any contextual identities defined in the browser. If there are none, a message is added to the popup and the script stops.
browser.contextualIdentities.query({})
.then((identities) => {
if (!identities.length) {
div.innerText = 'No identities returned from the API.';
return;
}
If there are contextual identities present—Firefox comes with four default identities—the script loops through each one adding its name, styled in its chosen color, to the <div>
element. The function createOptions()
then adds the options to "create" or "close all" to the <div>
before it's added to the popup.
for (const identity of identities) {
const row = document.createElement('div');
const span = document.createElement('span');
span.className = 'identity';
span.innerText = identity.name;
span.style = `color: ${identity.color}`;
console.log(identity);
row.appendChild(span);
createOptions(row, identity);
div.appendChild(row);
}
});
}
function createOptions(node, identity) {
for (const option of ['Create', 'Close All']) {
const a = document.createElement('a');
a.href = '#';
a.innerText = option;
a.dataset.action = option.toLowerCase().replace(' ', '-');
a.dataset.identity = identity.cookieStoreId;
a.addEventListener('click', eventHandler);
node.appendChild(a);
}
}
The script now waits for the user to select an option in the popup.
function eventHandler(event) {
If the user clicks the option to create a tab for an identity, one is opened using tabs.create by passing the identity's cookie store ID.
if (event.target.dataset.action === "create") {
browser.tabs.create({
url: "about:blank",
cookieStoreId: event.target.dataset.identity,
});
}
If the user selects the option to close all tabs for the identity, the script performs a tabs.query for all tabs that are using the identity's cookie store. The script then passes this list of tabs to tabs.remove
.
if (event.target.dataset.action === 'close-all') {
browser.tabs.query({
cookieStoreId: event.target.dataset.identity
}).then((tabs) => {
browser.tabs.remove(tabs.map((i) => i.id));
});
}
event.preventDefault();
}