Files
I2P_in_Private_Browsing_Mod…/context.js
2025-01-14 15:30:04 -05:00

162 lines
4.1 KiB
JavaScript

/**
* @fileoverview I2P Container Context Manager
* Handles container tab creation and management for I2P browsing contexts
*/
// Constants
const UI_STRINGS = {
TITLE_PREFACE: chrome.i18n.getMessage("titlePreface"),
API_ERROR_MESSAGE:
"browser.contextualIdentities not available. Check that the privacy.userContext.enabled pref is set to true, and reload the add-on.",
NO_IDENTITIES_MESSAGE: "No identities returned from the API.",
};
const TAB_ACTIONS = {
NEW_TAB: "new-i2p browser tab",
CLOSE_ALL: "close-all i2p browser tabs",
};
const TAB_OPTIONS = [
{
text: "New I2P Browser Tab",
action: TAB_ACTIONS.NEW_TAB,
},
{
text: "Close All I2P Browser Tabs",
action: TAB_ACTIONS.CLOSE_ALL,
},
];
/**
* Handles browser operation errors
* @param {Error} error - Browser operation error
*/
function handleError(error) {
console.error("Container operation failed:", error);
}
/**
* Creates a new tab in specified container window
* @param {Object} windowInfo - Window information
* @param {string} cookieStoreId - Container identity
*/
async function createContainerTab(windowInfo, cookieStoreId) {
try {
await browser.tabs.create({
windowId: windowInfo.id,
url: "about:blank",
cookieStoreId: cookieStoreId,
});
console.info(`Created container tab in window : ${windowInfo.id}`);
} catch (error) {
handleError(error);
}
}
/**
* Handles container tab operations
* @param {Event} event - UI event
*/
async function handleContainerAction(event) {
event.preventDefault();
const { action, identity } = event.target.dataset;
try {
switch (action) {
case TAB_ACTIONS.NEW_TAB:
const window = await browser.windows.create();
await createContainerTab(window, identity);
break;
case TAB_ACTIONS.CLOSE_ALL:
const tabs = await browser.tabs.query({ cookieStoreId: identity });
await browser.tabs.remove(tabs.map((tab) => tab.id));
break;
default:
console.warn("Unknown container action:", action);
}
} catch (error) {
handleError(error);
}
}
/**
* Creates UI elements for container options
* @param {HTMLElement} parentNode - Container for options
* @param {Object} identity - Container identity
*/
function createContainerOptions(parentNode, identity) {
TAB_OPTIONS.forEach((option) => {
const link = document.createElement("a");
Object.assign(link, {
href: "#",
innerText: option.text,
dataset: {
action: option.action,
identity: identity.cookieStoreId,
},
});
link.addEventListener("click", handleContainerAction);
parentNode.appendChild(link);
});
}
/**
* Creates UI element for container identity
* @param {Object} identity - Container identity
* @returns {HTMLElement}
*/
function createIdentityElement(identity) {
const row = document.createElement("div");
const span = document.createElement("div");
span.className = "identity";
span.innerText = identity.name;
row.appendChild(span);
createContainerOptions(row, identity);
return row;
}
/**
* Initializes container UI
* @param {HTMLElement} containerList - Container list element
*/
async function initializeContainerUI(containerList) {
if (!browser.contextualIdentities) {
containerList.innerText = UI_STRINGS.API_ERROR_MESSAGE;
return;
}
try {
const identities = await browser.contextualIdentities.query({
name: UI_STRINGS.TITLE_PREFACE,
});
if (!identities.length) {
containerList.innerText = UI_STRINGS.NO_IDENTITIES_MESSAGE;
return;
}
identities.forEach((identity) => {
const element = createIdentityElement(identity);
containerList.appendChild(element);
console.debug("Added container identity:", identity.name);
});
} catch (error) {
handleError(error);
containerList.innerText = error.message;
}
}
// Initialize container management
const identityList = document.getElementById("identity-list");
if (identityList) {
initializeContainerUI(identityList);
} else {
console.error("Identity list container not found");
}