refactor bookmarks.js
This commit is contained in:
314
bookmarks.js
314
bookmarks.js
@ -1,142 +1,210 @@
|
||||
async function createI2PToolbar(bookmarkToolbar) {
|
||||
const ibbt = await browser.bookmarks.search("I2P Toolbar");
|
||||
/**
|
||||
* @fileoverview I2P Bookmark Manager
|
||||
* Handles bookmark creation and management for I2P extension toolbar
|
||||
*/
|
||||
|
||||
async function onToolbarCreated(node) {
|
||||
const ibt = await browser.bookmarks.search("I2P Toolbar");
|
||||
await bookmarks(ibt[0]);
|
||||
}
|
||||
|
||||
async function setupDir(ibbt) {
|
||||
if (!ibbt.length) {
|
||||
const createBookmark = await browser.bookmarks.create({
|
||||
title: "I2P Toolbar",
|
||||
parentId: bookmarkToolbar.id,
|
||||
});
|
||||
await onToolbarCreated(createBookmark);
|
||||
}
|
||||
}
|
||||
|
||||
await setupDir(ibbt);
|
||||
}
|
||||
|
||||
async function bookmarks(bookmarkToolbar) {
|
||||
const controlHost = control_host();
|
||||
const controlPort = control_port();
|
||||
|
||||
async function createBookmark({ url, title, parentId }) {
|
||||
const createRhizomeBookmark = await browser.bookmarks.create({
|
||||
url,
|
||||
title,
|
||||
parentId,
|
||||
});
|
||||
console.log("Bookmarked", createRhizomeBookmark);
|
||||
}
|
||||
|
||||
async function createHomeBookmark() {
|
||||
const bookmarkItems = await browser.bookmarks.search({
|
||||
// Constants for bookmark configuration
|
||||
const BOOKMARK_CONFIG = {
|
||||
TOOLBAR_NAME: "I2P Toolbar",
|
||||
DEFAULT_BOOKMARKS: [
|
||||
{
|
||||
title: "I2P Extension Home Page",
|
||||
});
|
||||
if (!bookmarkItems.length) {
|
||||
await createBookmark({
|
||||
url: browser.runtime.getURL("home.html"),
|
||||
title: "I2P Extension Home Page",
|
||||
parentId: bookmarkToolbar.id,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function createTorrentBookmark() {
|
||||
const bookmarkItems = await browser.bookmarks.search({
|
||||
getUrl: () => browser.runtime.getURL("home.html"),
|
||||
},
|
||||
{
|
||||
title: "Bittorrent",
|
||||
});
|
||||
if (!bookmarkItems.length) {
|
||||
await createBookmark({
|
||||
url: `http://${controlHost}:${controlPort}/i2psnark`,
|
||||
title: "Bittorrent",
|
||||
parentId: bookmarkToolbar.id,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function createConsoleBookmark() {
|
||||
const bookmarkItems = await browser.bookmarks.search({
|
||||
title: "I2P Console",
|
||||
});
|
||||
if (!bookmarkItems.length) {
|
||||
await createBookmark({
|
||||
url: `http://${controlHost}:${controlPort}/home`,
|
||||
title: "I2P Console",
|
||||
parentId: bookmarkToolbar.id,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function createMailBookmark() {
|
||||
const bookmarkItems = await browser.bookmarks.search({
|
||||
title: "Web Mail",
|
||||
});
|
||||
if (!bookmarkItems.length) {
|
||||
await createBookmark({
|
||||
url: `http://${controlHost}:${controlPort}/webmail`,
|
||||
title: "Web Mail",
|
||||
parentId: bookmarkToolbar.id,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function createI2PTunnelBookmark() {
|
||||
const bookmarkItems = await browser.bookmarks.search({
|
||||
getUrl: (host, port) => `http://${host}:${port}/i2psnark`,
|
||||
},
|
||||
{
|
||||
title: "Hidden Services Manager",
|
||||
});
|
||||
if (!bookmarkItems.length) {
|
||||
await createBookmark({
|
||||
url: `http://${controlHost}:${controlPort}/i2ptunnel`,
|
||||
title: "Hidden Services Manager",
|
||||
parentId: bookmarkToolbar.id,
|
||||
});
|
||||
getUrl: (host, port) => `http://${host}:${port}/i2ptunnel`,
|
||||
},
|
||||
{
|
||||
title: "Web Mail",
|
||||
getUrl: (host, port) => `http://${host}:${port}/webmail`,
|
||||
},
|
||||
{
|
||||
title: "I2P Console",
|
||||
getUrl: (host, port) => `http://${host}:${port}/home`,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* Bookmark Manager class for handling I2P bookmarks
|
||||
*/
|
||||
class I2PBookmarkManager {
|
||||
constructor() {
|
||||
this.controlHost = control_host();
|
||||
this.controlPort = control_port();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a bookmark with error handling
|
||||
* @param {Object} params Bookmark parameters
|
||||
* @return {Promise<browser.bookmarks.BookmarkTreeNode>}
|
||||
*/
|
||||
async createBookmark({ url, title, parentId }) {
|
||||
try {
|
||||
const bookmark = await browser.bookmarks.create({ url, title, parentId });
|
||||
console.info("Created bookmark:", title);
|
||||
return bookmark;
|
||||
} catch (error) {
|
||||
console.error(`Failed to create bookmark ${title} :`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
await createHomeBookmark();
|
||||
await createTorrentBookmark();
|
||||
await createI2PTunnelBookmark();
|
||||
await createMailBookmark();
|
||||
await createConsoleBookmark();
|
||||
/**
|
||||
* Creates the I2P toolbar folder
|
||||
* @param {browser.bookmarks.BookmarkTreeNode} toolbar Parent toolbar node
|
||||
* @return {Promise<browser.bookmarks.BookmarkTreeNode>}
|
||||
*/
|
||||
async createToolbarFolder(toolbar) {
|
||||
try {
|
||||
const existing = await browser.bookmarks.search(
|
||||
BOOKMARK_CONFIG.TOOLBAR_NAME
|
||||
);
|
||||
if (existing.length) {
|
||||
return existing[0];
|
||||
}
|
||||
|
||||
defaultSettings.bookmarks_state = true;
|
||||
const folder = await this.createBookmark({
|
||||
title: BOOKMARK_CONFIG.TOOLBAR_NAME,
|
||||
parentId: toolbar.id,
|
||||
});
|
||||
|
||||
await this.populateToolbar(folder);
|
||||
return folder;
|
||||
} catch (error) {
|
||||
console.error("Failed to create toolbar folder:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a single default bookmark if it doesn't exist
|
||||
* @param {Object} bookmark Bookmark configuration
|
||||
* @param {string} parentId Parent folder ID
|
||||
*/
|
||||
async createDefaultBookmark(bookmark, parentId) {
|
||||
try {
|
||||
const existing = await browser.bookmarks.search({
|
||||
title: bookmark.title,
|
||||
});
|
||||
if (!existing.length) {
|
||||
await this.createBookmark({
|
||||
url: bookmark.getUrl(this.controlHost, this.controlPort),
|
||||
title: bookmark.title,
|
||||
parentId,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(
|
||||
`Failed to create default bookmark ${bookmark.title}:`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates toolbar with default bookmarks
|
||||
* @param {browser.bookmarks.BookmarkTreeNode} toolbar Toolbar folder node
|
||||
*/
|
||||
async populateToolbar(toolbar) {
|
||||
try {
|
||||
await Promise.all(
|
||||
BOOKMARK_CONFIG.DEFAULT_BOOKMARKS.map((bookmark) =>
|
||||
this.createDefaultBookmark(bookmark, toolbar.id)
|
||||
)
|
||||
);
|
||||
await this.updateBookmarkState(true);
|
||||
} catch (error) {
|
||||
console.error("Failed to populate toolbar:", error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates bookmark state in storage
|
||||
* @param {boolean} state New bookmark state
|
||||
*/
|
||||
async updateBookmarkState(state) {
|
||||
try {
|
||||
await browser.storage.local.set({ bookmarks_state: state });
|
||||
if (typeof defaultSettings !== "undefined") {
|
||||
defaultSettings.bookmarks_state = state;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to update bookmark state:", error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes bookmark setup
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async initialize() {
|
||||
try {
|
||||
const platform = await browser.runtime.getPlatformInfo();
|
||||
if (platform.os === "android") {
|
||||
console.info("Skipping bookmark setup on Android");
|
||||
return;
|
||||
}
|
||||
|
||||
const toolbars = await browser.bookmarks.search({ query: "Toolbar" });
|
||||
if (!toolbars.length) {
|
||||
throw new Error("Browser toolbar not found");
|
||||
}
|
||||
|
||||
await this.createToolbarFolder(toolbars[0]);
|
||||
} catch (error) {
|
||||
console.error("Bookmark initialization failed:", error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if bookmarks need to be initialized
|
||||
* @param {Object} state Current bookmark state
|
||||
*/
|
||||
async checkInitialization(state = {}) {
|
||||
if (!state.bookmarks_state) {
|
||||
await this.initialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function bookmarksSetup() {
|
||||
const gettingInfo = await browser.runtime.getPlatformInfo();
|
||||
if (gettingInfo.os === "android") {
|
||||
// Singleton instance
|
||||
const bookmarkManager = new I2PBookmarkManager();
|
||||
|
||||
/**
|
||||
* Initialize bookmarks system
|
||||
*/
|
||||
async function initializeBookmarks() {
|
||||
if (!browser?.windows) {
|
||||
console.warn("Browser windows API not available");
|
||||
return;
|
||||
}
|
||||
|
||||
const bookmarkToolbar = await browser.bookmarks.search({
|
||||
query: "Toolbar",
|
||||
});
|
||||
|
||||
await createI2PToolbar(bookmarkToolbar[0]);
|
||||
}
|
||||
|
||||
function conditionalBookmarksSetup(obj) {
|
||||
console.log("(bookmarks) state", obj.bookmarks_state);
|
||||
if (obj.bookmarks_state == false) {
|
||||
bookmarksSetup();
|
||||
}
|
||||
if (obj.bookmarks_state == undefined) {
|
||||
bookmarksSetup();
|
||||
try {
|
||||
const state = await browser.storage.local.get("bookmarks_state");
|
||||
await bookmarkManager.checkInitialization(state);
|
||||
} catch (error) {
|
||||
console.error("Failed to initialize bookmarks:", error);
|
||||
await bookmarkManager.initialize();
|
||||
}
|
||||
}
|
||||
|
||||
if (browser != null) {
|
||||
if (browser.windows != undefined) {
|
||||
let gettingStorage = browser.storage.local.get("bookmarks_state");
|
||||
gettingStorage.then(conditionalBookmarksSetup, bookmarksSetup);
|
||||
// Setup event listeners
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const bookmarksButton = document.getElementById("bookmarksButton");
|
||||
if (bookmarksButton) {
|
||||
bookmarksButton.addEventListener("click", () =>
|
||||
bookmarkManager.initialize()
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const bookmarksButton = document.getElementById("bookmarksButton");
|
||||
if (bookmarksButton != null) {
|
||||
bookmarksButton.addEventListener("click", bookmarksSetup);
|
||||
// Initialize if browser API is available
|
||||
if (browser) {
|
||||
initializeBookmarks();
|
||||
}
|
||||
|
71
context.js
71
context.js
@ -5,25 +5,26 @@
|
||||
|
||||
// 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.'
|
||||
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'
|
||||
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: "New I2P Browser Tab",
|
||||
action: TAB_ACTIONS.NEW_TAB,
|
||||
},
|
||||
{
|
||||
text: 'Close All I2P Browser Tabs',
|
||||
action: TAB_ACTIONS.CLOSE_ALL
|
||||
}
|
||||
text: "Close All I2P Browser Tabs",
|
||||
action: TAB_ACTIONS.CLOSE_ALL,
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
@ -31,7 +32,7 @@ const TAB_OPTIONS = [
|
||||
* @param {Error} error - Browser operation error
|
||||
*/
|
||||
function handleError(error) {
|
||||
console.error('Container operation failed:', error);
|
||||
console.error("Container operation failed:", error);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -43,10 +44,10 @@ async function createContainerTab(windowInfo, cookieStoreId) {
|
||||
try {
|
||||
await browser.tabs.create({
|
||||
windowId: windowInfo.id,
|
||||
url: 'about:blank',
|
||||
cookieStoreId: cookieStoreId
|
||||
url: "about:blank",
|
||||
cookieStoreId: cookieStoreId,
|
||||
});
|
||||
console.info(`Created container tab in window: ${windowInfo.id}`);
|
||||
console.info(`Created container tab in window : ${windowInfo.id}`);
|
||||
} catch (error) {
|
||||
handleError(error);
|
||||
}
|
||||
@ -69,11 +70,11 @@ async function handleContainerAction(event) {
|
||||
|
||||
case TAB_ACTIONS.CLOSE_ALL:
|
||||
const tabs = await browser.tabs.query({ cookieStoreId: identity });
|
||||
await browser.tabs.remove(tabs.map(tab => tab.id));
|
||||
await browser.tabs.remove(tabs.map((tab) => tab.id));
|
||||
break;
|
||||
|
||||
default:
|
||||
console.warn('Unknown container action:', action);
|
||||
console.warn("Unknown container action:", action);
|
||||
}
|
||||
} catch (error) {
|
||||
handleError(error);
|
||||
@ -86,18 +87,18 @@ async function handleContainerAction(event) {
|
||||
* @param {Object} identity - Container identity
|
||||
*/
|
||||
function createContainerOptions(parentNode, identity) {
|
||||
TAB_OPTIONS.forEach(option => {
|
||||
const link = document.createElement('a');
|
||||
TAB_OPTIONS.forEach((option) => {
|
||||
const link = document.createElement("a");
|
||||
Object.assign(link, {
|
||||
href: '#',
|
||||
href: "#",
|
||||
innerText: option.text,
|
||||
dataset: {
|
||||
action: option.action,
|
||||
identity: identity.cookieStoreId
|
||||
}
|
||||
identity: identity.cookieStoreId,
|
||||
},
|
||||
});
|
||||
|
||||
link.addEventListener('click', handleContainerAction);
|
||||
|
||||
link.addEventListener("click", handleContainerAction);
|
||||
parentNode.appendChild(link);
|
||||
});
|
||||
}
|
||||
@ -108,15 +109,15 @@ function createContainerOptions(parentNode, identity) {
|
||||
* @returns {HTMLElement}
|
||||
*/
|
||||
function createIdentityElement(identity) {
|
||||
const row = document.createElement('div');
|
||||
const span = document.createElement('div');
|
||||
|
||||
span.className = '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;
|
||||
}
|
||||
|
||||
@ -132,7 +133,7 @@ async function initializeContainerUI(containerList) {
|
||||
|
||||
try {
|
||||
const identities = await browser.contextualIdentities.query({
|
||||
name: UI_STRINGS.TITLE_PREFACE
|
||||
name: UI_STRINGS.TITLE_PREFACE,
|
||||
});
|
||||
|
||||
if (!identities.length) {
|
||||
@ -140,10 +141,10 @@ async function initializeContainerUI(containerList) {
|
||||
return;
|
||||
}
|
||||
|
||||
identities.forEach(identity => {
|
||||
identities.forEach((identity) => {
|
||||
const element = createIdentityElement(identity);
|
||||
containerList.appendChild(element);
|
||||
console.debug('Added container identity:', identity.name);
|
||||
console.debug("Added container identity:", identity.name);
|
||||
});
|
||||
} catch (error) {
|
||||
handleError(error);
|
||||
@ -152,9 +153,9 @@ async function initializeContainerUI(containerList) {
|
||||
}
|
||||
|
||||
// Initialize container management
|
||||
const identityList = document.getElementById('identity-list');
|
||||
const identityList = document.getElementById("identity-list");
|
||||
if (identityList) {
|
||||
initializeContainerUI(identityList);
|
||||
} else {
|
||||
console.error('Identity list container not found');
|
||||
}
|
||||
console.error("Identity list container not found");
|
||||
}
|
||||
|
Reference in New Issue
Block a user