Refactor and document info/display elements
This commit is contained in:
702
info.js
702
info.js
@@ -1,393 +1,333 @@
|
||||
var titlepref = chrome.i18n.getMessage("titlePreface");
|
||||
/**
|
||||
* @fileoverview I2P Browser Information Manager
|
||||
* Handles browser settings, privacy features, and navigation for I2P extension
|
||||
*/
|
||||
|
||||
function checkPeerConnection() {
|
||||
let getting = browser.privacy.network.peerConnectionEnabled.get({});
|
||||
getting.then((got) => {
|
||||
let webrtc = got.value;
|
||||
console.log("(info) checking webrtc", webrtc);
|
||||
if (document.getElementById("enable-web-rtc") !== null)
|
||||
document.getElementById("enable-web-rtc").checked = webrtc;
|
||||
});
|
||||
}
|
||||
|
||||
checkPeerConnection();
|
||||
|
||||
function checkSnowflake() {
|
||||
try {
|
||||
function snowflake(snowflake) {
|
||||
console.log(
|
||||
"(info) snowflake plugin found, leaving WebRTC alone",
|
||||
snowflake
|
||||
);
|
||||
AssurePeerConnection();
|
||||
}
|
||||
var snowflakeInfo = browser.management.get(
|
||||
"{b11bea1f-a888-4332-8d8a-cec2be7d24b9}"
|
||||
);
|
||||
snowflakeInfo.then(snowflake);
|
||||
} catch (err) {
|
||||
console.log("(info) snowflake not found", err);
|
||||
}
|
||||
}
|
||||
|
||||
checkSnowflake();
|
||||
|
||||
function checkHistory() {
|
||||
let getting = browser.storage.local.get("disable_history");
|
||||
getting.then((got) => {
|
||||
let disable_history = got.disable_history;
|
||||
if (disable_history == undefined) {
|
||||
disable_history = false;
|
||||
}
|
||||
console.log("(info) checking history", disable_history);
|
||||
if (document.getElementById("disable-history") !== null)
|
||||
document.getElementById("disable-history").checked = disable_history;
|
||||
});
|
||||
}
|
||||
|
||||
checkHistory();
|
||||
|
||||
function checkReferer() {
|
||||
let getting = browser.storage.local.get("disable_referer");
|
||||
getting.then((got) => {
|
||||
let disable_referer = got.disable_referer;
|
||||
if (disable_referer == undefined) {
|
||||
disable_referer = false;
|
||||
}
|
||||
console.log("(info) checking referer", disable_referer);
|
||||
if (document.getElementById("disable-referer") !== null)
|
||||
document.getElementById("disable-referer").checked = disable_referer;
|
||||
});
|
||||
}
|
||||
|
||||
checkReferer();
|
||||
|
||||
document.addEventListener("click", clickHandler);
|
||||
|
||||
function clickHandler(clickEvent) {
|
||||
const targetId = clickEvent.target.id;
|
||||
|
||||
if (
|
||||
targetId === "window-create-help-panel" ||
|
||||
targetId === "window-create-news-panel"
|
||||
) {
|
||||
const createData = { type: "panel", incognito: true };
|
||||
browser.tabs.create(createData).then(() => {
|
||||
console.log(`The ${targetId.split("-")[2]} panel has been created`);
|
||||
});
|
||||
} else if (targetId === "visit-irc") {
|
||||
browser.sidebarAction.setPanel({ panel: "http://127.0.0.1:7669" });
|
||||
browser.sidebarAction.open();
|
||||
} else if (targetId === "generate-fresh-tunnel") {
|
||||
function refreshIdentity() {
|
||||
console.log("(info) Generating new identity");
|
||||
const Http = new XMLHttpRequest();
|
||||
const url = `http://${controlHost}:${controlPort}`;
|
||||
Http.open("GET", url);
|
||||
Http.send();
|
||||
Http.onreadystatechange = () => {
|
||||
console.log(Http.responseText);
|
||||
};
|
||||
}
|
||||
refreshIdentity();
|
||||
} else if (targetId.startsWith("label-router")) {
|
||||
const listId = `label-${targetId.split("-")[2]}-list`;
|
||||
const list = document.getElementById(listId);
|
||||
|
||||
if (list.style.display !== "none") {
|
||||
console.log(`hiding ${listId}`);
|
||||
list.style.display = "none";
|
||||
} else {
|
||||
console.log(`showing ${listId}`);
|
||||
list.style.display = "block";
|
||||
}
|
||||
} else if (targetId === "search-submit") {
|
||||
console.log("(info) attempting to create search tab");
|
||||
goSearch();
|
||||
} else if (targetId === "url-submit") {
|
||||
console.log("(info) attempting to create search tab");
|
||||
goURL();
|
||||
} else if (targetId === "browser-action") {
|
||||
console.log("(info) showing a browser action");
|
||||
showBrowsing();
|
||||
} else if (targetId === "torrent-action" || targetId === "torrentui-opener") {
|
||||
console.log("(info) showing a torrent action");
|
||||
showTorrentsMenu();
|
||||
} else if (targetId.startsWith("window-visit")) {
|
||||
const page = targetId.split("-")[2];
|
||||
console.log(`attempting to create ${page} tab`);
|
||||
switch (page) {
|
||||
case "homepage":
|
||||
case "help":
|
||||
goHome();
|
||||
break;
|
||||
case "index":
|
||||
goIndex();
|
||||
break;
|
||||
case "torrent":
|
||||
goTorrent();
|
||||
break;
|
||||
case "console":
|
||||
goConsole();
|
||||
break;
|
||||
case "i2ptunnel":
|
||||
goTunnel();
|
||||
break;
|
||||
case "i2p":
|
||||
goHomepage();
|
||||
break;
|
||||
case "susimail":
|
||||
goMail();
|
||||
break;
|
||||
case "snark":
|
||||
goSnark();
|
||||
break;
|
||||
}
|
||||
} else if (targetId === "clear-browser-data") {
|
||||
forgetBrowsingData();
|
||||
} else if (targetId === "enable-web-rtc") {
|
||||
const isWebRTCEnabled = clickEvent.target.checked;
|
||||
browser.runtime.sendMessage({
|
||||
rtc: isWebRTCEnabled ? "enableWebRTC" : "disableWebRTC",
|
||||
});
|
||||
checkPeerConnection();
|
||||
return;
|
||||
} else if (targetId === "disable-history") {
|
||||
const isHistoryEnabled = !clickEvent.target.checked;
|
||||
browser.runtime.sendMessage({
|
||||
history: isHistoryEnabled ? "enableHistory" : "disableHistory",
|
||||
});
|
||||
return;
|
||||
} else if (targetId === "disable-referer") {
|
||||
const isRefererEnabled = !clickEvent.target.checked;
|
||||
browser.runtime.sendMessage({
|
||||
referers: isRefererEnabled ? "enableReferer" : "disableReferer",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
clickEvent.preventDefault();
|
||||
}
|
||||
|
||||
window.onload = function (e) {
|
||||
if (document.getElementById("label-peers-list") != null) {
|
||||
document.getElementById("label-peers-list").style.display = "none";
|
||||
}
|
||||
if (document.getElementById("label-bandwidth-list") != null) {
|
||||
document.getElementById("label-bandwidth-list").style.display = "none";
|
||||
}
|
||||
// Constants
|
||||
const CONFIG = {
|
||||
TITLE_PREFACE: chrome.i18n.getMessage("titlePreface"),
|
||||
ROUTER: {
|
||||
DEFAULT_HOST: "127.0.0.1",
|
||||
DEFAULT_PORT: "7657",
|
||||
},
|
||||
SNOWFLAKE_ID: "{b11bea1f-a888-4332-8d8a-cec2be7d24b9}",
|
||||
UPDATE_INTERVAL: 0.2 * 60 * 1000,
|
||||
IRC_URL: "http://127.0.0.1:7669",
|
||||
};
|
||||
|
||||
function proxyReadiness() {
|
||||
console.log(this.responseText);
|
||||
}
|
||||
const UI_ELEMENTS = {
|
||||
PANELS: {
|
||||
BROWSER: "browserpanel",
|
||||
TORRENT: "torrentpanel",
|
||||
},
|
||||
LISTS: {
|
||||
PEERS: "label-peers-list",
|
||||
BANDWIDTH: "label-bandwidth-list",
|
||||
},
|
||||
};
|
||||
|
||||
var gettingInfo = browser.runtime.getPlatformInfo();
|
||||
gettingInfo.then((got) => {
|
||||
if (got.os != "android") {
|
||||
browser.history.onVisited.addListener(onVisited);
|
||||
}
|
||||
});
|
||||
|
||||
function showBrowsing() {
|
||||
var x = document.getElementById("browserpanel");
|
||||
x.style.display = "block";
|
||||
var y = document.getElementById("torrentpanel");
|
||||
y.style.display = "none";
|
||||
}
|
||||
|
||||
function showTorrentsMenu() {
|
||||
var x = document.getElementById("browserpanel");
|
||||
x.style.display = "none";
|
||||
var y = document.getElementById("torrentpanel");
|
||||
y.style.display = "block";
|
||||
}
|
||||
|
||||
function goHome() {
|
||||
function onTabError() {
|
||||
console.log("(info) Help tab not created");
|
||||
}
|
||||
let createData = {
|
||||
url: "home.html",
|
||||
};
|
||||
console.log("(info) visiting homepage");
|
||||
let creating = browser.tabs.create(createData);
|
||||
creating.then(onTabCreated, onTabError);
|
||||
}
|
||||
|
||||
function goIndex() {
|
||||
function onTabError() {
|
||||
console.log("(info) Help tab not created");
|
||||
}
|
||||
let createData = {
|
||||
url: "index.html",
|
||||
};
|
||||
console.log("(info) visiting help");
|
||||
let creating = browser.tabs.create(createData);
|
||||
creating.then(onTabCreated, onTabError);
|
||||
}
|
||||
|
||||
function goTorrent() {
|
||||
function onTabError() {
|
||||
console.log("(info) Torrent Help tab not created");
|
||||
}
|
||||
let createData = {
|
||||
url: "torrent/index.html",
|
||||
};
|
||||
console.log("(info) visiting torrent help");
|
||||
let creating = browser.tabs.create(createData);
|
||||
creating.then(onTabCreated, onTabError);
|
||||
}
|
||||
|
||||
function goHomepage() {
|
||||
function onTabError() {
|
||||
console.log("(info) i2p-projekt tab not created");
|
||||
}
|
||||
let createData = {
|
||||
url: "http://i2p-projekt.i2p",
|
||||
};
|
||||
console.log("(info) visiting i2p-projekt");
|
||||
let creating = browser.tabs.create(createData);
|
||||
creating.then(onTabCreated, onTabError);
|
||||
}
|
||||
|
||||
function goHelp() {
|
||||
function onTabError() {
|
||||
console.log("(info) Torrent Help tab not created");
|
||||
}
|
||||
let createData = {
|
||||
url: "i2pcontrol/index.html",
|
||||
};
|
||||
console.log("(info) visiting torrent help");
|
||||
let creating = browser.tabs.create(createData);
|
||||
creating.then(onTabCreated, onTabError);
|
||||
}
|
||||
|
||||
function onTabCreated() {
|
||||
console.log("(info) Tab Created");
|
||||
}
|
||||
|
||||
function goSearch() {
|
||||
function onTabError() {
|
||||
console.log("(info) Search tab created");
|
||||
}
|
||||
let createData = {
|
||||
url:
|
||||
"http://cuss2sgthm5wfipnnztrjdvtaczb22hnmr2ohnaqqqz3jf6ubf3a.b32.i2p/yacysearch.html?" +
|
||||
"query=" +
|
||||
document.getElementById("search-query").value,
|
||||
};
|
||||
console.log("(info) visiting legwork");
|
||||
let creating = browser.tabs.create(createData);
|
||||
creating.then(onTabCreated, onTabError);
|
||||
}
|
||||
|
||||
function goURL() {
|
||||
function onTabError() {
|
||||
console.log("(info) Search tab created");
|
||||
}
|
||||
|
||||
function createNewURLTab(context) {
|
||||
console.log("(info) visiting URL");
|
||||
let createData = {
|
||||
url: document.getElementById("url-query").value,
|
||||
cookieStoreId: context[0].cookieStoreId,
|
||||
};
|
||||
let creating = browser.tabs.create(createData);
|
||||
creating.then(onTabCreated, onTabError);
|
||||
}
|
||||
let context = browser.contextualIdentities.query({
|
||||
name: titlepref,
|
||||
});
|
||||
context.then(createNewURLTab, onTabError);
|
||||
}
|
||||
|
||||
function routerAddr() {
|
||||
try {
|
||||
return control_host() + ":" + control_port();
|
||||
} catch {
|
||||
return "127.0.0.1:7657";
|
||||
}
|
||||
}
|
||||
|
||||
function goConsole() {
|
||||
function onTabError() {
|
||||
console.log("(info) Console tab not created");
|
||||
}
|
||||
let createData = {
|
||||
url: "http://" + routerAddr() + "/home",
|
||||
};
|
||||
console.log("(info) visiting router console");
|
||||
let creating = browser.tabs.create(createData);
|
||||
creating.then(onTabCreated, onTabError);
|
||||
}
|
||||
|
||||
function goTunnel() {
|
||||
function onTabError() {
|
||||
console.log("(info) I2PTunnel tab created");
|
||||
}
|
||||
let createData = {
|
||||
url: "http://" + routerAddr() + "/i2ptunnel",
|
||||
};
|
||||
console.log("(info) visiting i2ptunnel");
|
||||
let creating = browser.tabs.create(createData);
|
||||
creating.then(onTabCreated, onTabError);
|
||||
}
|
||||
|
||||
function goMail() {
|
||||
function onTabError() {
|
||||
console.log("(info) Mail tab created");
|
||||
}
|
||||
let createData = {
|
||||
url: "http://" + routerAddr() + "/susimail",
|
||||
};
|
||||
console.log("(info) visiting mail");
|
||||
let creating = browser.tabs.create(createData);
|
||||
creating(onTabCreated, onTabError);
|
||||
}
|
||||
|
||||
function goSnark() {
|
||||
function onTabError() {
|
||||
console.log("(info) Snark tab created");
|
||||
}
|
||||
let createData = {
|
||||
url: "http://" + routerAddr() + "/i2psnark",
|
||||
};
|
||||
console.log("(info) visiting snark");
|
||||
let creating = browser.tabs.create(createData);
|
||||
creating.then(onTabCreated, onTabError);
|
||||
}
|
||||
|
||||
function onVisited(historyItem) {
|
||||
function onCleaned(results) {
|
||||
if (results.length) {
|
||||
console.log("(info) was not removed");
|
||||
} else {
|
||||
console.log("(info) was removed");
|
||||
/**
|
||||
* Privacy Manager for handling browser privacy settings
|
||||
*/
|
||||
class PrivacyManager {
|
||||
/**
|
||||
* Check WebRTC peer connection status
|
||||
*/
|
||||
static async checkPeerConnection() {
|
||||
try {
|
||||
const { value: webrtc } =
|
||||
await browser.privacy.network.peerConnectionEnabled.get({});
|
||||
const webrtcToggle = document.getElementById("enable-web-rtc");
|
||||
if (webrtcToggle) {
|
||||
webrtcToggle.checked = webrtc;
|
||||
}
|
||||
console.info("(info) WebRTC status:", webrtc);
|
||||
} catch (error) {
|
||||
console.error("WebRTC check failed:", error);
|
||||
}
|
||||
}
|
||||
|
||||
function onRemoved() {
|
||||
var searching = browser.history.search({
|
||||
text: historyItem.url,
|
||||
startTime: 0,
|
||||
/**
|
||||
* Check Snowflake plugin status
|
||||
*/
|
||||
static async checkSnowflake() {
|
||||
try {
|
||||
const snowflake = await browser.management.get(CONFIG.SNOWFLAKE_ID);
|
||||
console.info("(info) Snowflake plugin found:", snowflake);
|
||||
await this.assurePeerConnection();
|
||||
} catch (error) {
|
||||
console.info("(info) Snowflake not found:", error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check history settings
|
||||
*/
|
||||
static async checkHistory() {
|
||||
try {
|
||||
const { disable_history = false } = await browser.storage.local.get(
|
||||
"disable_history"
|
||||
);
|
||||
const historyToggle = document.getElementById("disable-history");
|
||||
if (historyToggle) {
|
||||
historyToggle.checked = disable_history;
|
||||
}
|
||||
console.info("(info) History disabled:", disable_history);
|
||||
} catch (error) {
|
||||
console.error("History check failed:", error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check referer settings
|
||||
*/
|
||||
static async checkReferer() {
|
||||
try {
|
||||
const { disable_referer = false } = await browser.storage.local.get(
|
||||
"disable_referer"
|
||||
);
|
||||
const refererToggle = document.getElementById("disable-referer");
|
||||
if (refererToggle) {
|
||||
refererToggle.checked = disable_referer;
|
||||
}
|
||||
console.info("(info) Referer disabled:", disable_referer);
|
||||
} catch (error) {
|
||||
console.error("Referer check failed:", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tab Manager for handling browser navigation
|
||||
*/
|
||||
class TabManager {
|
||||
/**
|
||||
* Create a new browser tab
|
||||
* @param {Object} options Tab creation options
|
||||
* @return {Promise<browser.tabs.Tab>}
|
||||
*/
|
||||
static async createTab(options) {
|
||||
try {
|
||||
const tab = await browser.tabs.create(options);
|
||||
console.info("(info) Tab created:", options.url);
|
||||
return tab;
|
||||
} catch (error) {
|
||||
console.error("Tab creation failed:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a tab in I2P container
|
||||
* @param {string} url Destination URL
|
||||
*/
|
||||
static async createContainerTab(url) {
|
||||
try {
|
||||
const contexts = await browser.contextualIdentities.query({
|
||||
name: CONFIG.TITLE_PREFACE,
|
||||
});
|
||||
|
||||
if (!contexts.length) {
|
||||
throw new Error("No I2P container found");
|
||||
}
|
||||
|
||||
return this.createTab({
|
||||
url,
|
||||
cookieStoreId: contexts[0].cookieStoreId,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Container tab creation failed:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigate to local I2P service
|
||||
* @param {string} path Service path
|
||||
*/
|
||||
static async goToService(path) {
|
||||
try {
|
||||
const routerAddress = await RouterManager.getRouterAddress();
|
||||
await this.createTab({
|
||||
url: `http://${routerAddress}${path}`,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(`Service navigation failed : ${path}`, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Router Manager for I2P router operations
|
||||
*/
|
||||
class RouterManager {
|
||||
/**
|
||||
* Get router address
|
||||
* @return {string}
|
||||
*/
|
||||
static getRouterAddress() {
|
||||
try {
|
||||
return `${control_host()}:${control_port()}`;
|
||||
} catch {
|
||||
return `${CONFIG.ROUTER.DEFAULT_HOST}:${CONFIG.ROUTER.DEFAULT_PORT}`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate new identity
|
||||
*/
|
||||
static async generateNewIdentity() {
|
||||
try {
|
||||
const routerAddress = this.getRouterAddress();
|
||||
const response = await fetch(`http ://${routerAddress}`);
|
||||
console.info("(info) New identity generated");
|
||||
return response;
|
||||
} catch (error) {
|
||||
console.error("Identity generation failed:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* UI Manager for handling interface elements
|
||||
*/
|
||||
class UIManager {
|
||||
/**
|
||||
* Toggle panel visibility
|
||||
* @param {string} showPanel Panel to show
|
||||
* @param {string} hidePanel Panel to hide
|
||||
*/
|
||||
static togglePanels(showPanel, hidePanel) {
|
||||
try {
|
||||
const show = document.getElementById(showPanel);
|
||||
const hide = document.getElementById(hidePanel);
|
||||
|
||||
if (show && hide) {
|
||||
show.style.display = "block";
|
||||
hide.style.display = "none";
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Panel toggle failed:", error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize UI elements
|
||||
*/
|
||||
static initializeUI() {
|
||||
Object.values(UI_ELEMENTS.LISTS).forEach((listId) => {
|
||||
const list = document.getElementById(listId);
|
||||
if (list) {
|
||||
list.style.display = "none";
|
||||
}
|
||||
});
|
||||
searching.then(onCleaned);
|
||||
}
|
||||
if (!history) {
|
||||
if (i2pHost(historyItem)) {
|
||||
var deletingUrl = browser.history.deleteUrl(historyItem.url);
|
||||
}
|
||||
deletingUrl.then(onRemoved);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if (UpdateContents !== undefined) UpdateContents();
|
||||
*/
|
||||
const minutes = 0.2;
|
||||
const interval = minutes * 60 * 1000;
|
||||
/**
|
||||
* Click Handler for UI interactions
|
||||
*/
|
||||
class ClickHandler {
|
||||
/**
|
||||
* Handle click events
|
||||
* @param {MouseEvent} event Click event
|
||||
*/
|
||||
static async handleClick(event) {
|
||||
event.preventDefault();
|
||||
const { id: targetId } = event.target;
|
||||
|
||||
setInterval(function () {
|
||||
if (UpdateContents !== undefined) UpdateContents();
|
||||
}, interval);
|
||||
try {
|
||||
// Panel creation
|
||||
if (targetId.startsWith("window-create-")) {
|
||||
await TabManager.createTab({
|
||||
type: "panel",
|
||||
incognito: true,
|
||||
});
|
||||
}
|
||||
|
||||
// Service navigation
|
||||
else if (targetId.startsWith("window-visit-")) {
|
||||
const service = targetId.split("-")[2];
|
||||
await this.handleServiceNavigation(service);
|
||||
}
|
||||
|
||||
// Settings toggles
|
||||
else if (targetId === "enable-web-rtc") {
|
||||
await this.handleWebRTCToggle(event.target.checked);
|
||||
}
|
||||
|
||||
// Other actions
|
||||
else if (targetId === "generate-fresh-tunnel") {
|
||||
await RouterManager.generateNewIdentity();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Click handling failed:", error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle service navigation
|
||||
* @param {string} service Service identifier
|
||||
*/
|
||||
static async handleServiceNavigation(service) {
|
||||
const serviceMap = {
|
||||
console: "/home",
|
||||
i2ptunnel: "/i2ptunnel",
|
||||
susimail: "/susimail",
|
||||
snark: "/i2psnark",
|
||||
};
|
||||
|
||||
if (serviceMap[service]) {
|
||||
await TabManager.goToService(serviceMap[service]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the information manager
|
||||
*/
|
||||
async function initialize() {
|
||||
try {
|
||||
// Initialize privacy settings
|
||||
await Promise.all([
|
||||
PrivacyManager.checkPeerConnection(),
|
||||
PrivacyManager.checkSnowflake(),
|
||||
PrivacyManager.checkHistory(),
|
||||
PrivacyManager.checkReferer(),
|
||||
]);
|
||||
|
||||
// Initialize UI
|
||||
UIManager.initializeUI();
|
||||
document.addEventListener(
|
||||
"click",
|
||||
ClickHandler.handleClick.bind(ClickHandler)
|
||||
);
|
||||
|
||||
// Set up content updates
|
||||
if (typeof UpdateContents !== "undefined") {
|
||||
setInterval(UpdateContents, CONFIG.UPDATE_INTERVAL);
|
||||
}
|
||||
|
||||
console.info("(info) Information manager initialized");
|
||||
} catch (error) {
|
||||
console.error("Initialization failed:", error);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize if browser API is available
|
||||
if (browser?.windows) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
// Export for testing
|
||||
if (typeof module !== "undefined" && module.exports) {
|
||||
module.exports = {
|
||||
PrivacyManager,
|
||||
TabManager,
|
||||
RouterManager,
|
||||
UIManager,
|
||||
ClickHandler,
|
||||
CONFIG,
|
||||
};
|
||||
}
|
||||
|
245
proxyinfo.js
245
proxyinfo.js
@@ -1,62 +1,205 @@
|
||||
document.addEventListener("DOMContentLoaded", proxyStatus, false);
|
||||
/**
|
||||
* @fileoverview I2P Proxy Status Manager
|
||||
* Handles proxy connectivity checking and UI updates for I2P extension
|
||||
*/
|
||||
|
||||
function proxyStatus() {
|
||||
console.log("(proxyinfo) checking proxy status");
|
||||
fetch("http://proxy.i2p", { cache: "no-store" }).then(
|
||||
proxyStatusSuccess,
|
||||
proxyStatusError
|
||||
);
|
||||
}
|
||||
// Constants
|
||||
const PROXY_CONFIG = {
|
||||
PROXY_URL: "http://proxy.i2p",
|
||||
CONSOLE_URL: "http://127.0.0.1:7657",
|
||||
LOGO_PATH: "/themes/console/light/images/i2plogo.png",
|
||||
FETCH_OPTIONS: { cache: "no-store" },
|
||||
};
|
||||
|
||||
function proxyStatusSuccess(myJson) {
|
||||
console.warn("(proxyinfo)", myJson);
|
||||
contentUpdateById("proxy-check", "proxySuccessStatus");
|
||||
let readyness = document.querySelectorAll(".readyness");
|
||||
if (readyness !== null) {
|
||||
unhide(readyness);
|
||||
const UI_ELEMENTS = {
|
||||
PROXY_STATUS: "proxy-check",
|
||||
READINESS_CLASS: ".readyness",
|
||||
CONSOLE_LINKS: ".application-info",
|
||||
HIDDEN_CLASS: "hidden",
|
||||
};
|
||||
|
||||
const MESSAGE_KEYS = {
|
||||
SUCCESS: "proxySuccessStatus",
|
||||
FAILURE: "proxyFailedStatus",
|
||||
};
|
||||
|
||||
/**
|
||||
* UI Manager for handling element visibility
|
||||
*/
|
||||
class UIManager {
|
||||
/**
|
||||
* Toggle element visibility
|
||||
* @param {Element|NodeList} elements - Elements to modify
|
||||
* @param {boolean} show - Whether to show or hide
|
||||
*/
|
||||
/**
|
||||
* Toggle element visibility with strict null checking
|
||||
* @param {Element|NodeList} elements - Elements to modify
|
||||
* @param {boolean} show - Whether to show or hide
|
||||
*/
|
||||
static toggleVisibility(elements, show) {
|
||||
try {
|
||||
// Validate input
|
||||
if (!elements) {
|
||||
throw new Error("Elements parameter is null or undefined");
|
||||
}
|
||||
|
||||
// Convert to array if NodeList
|
||||
const elementArray =
|
||||
elements instanceof NodeList ? Array.from(elements) : [elements];
|
||||
|
||||
elementArray.forEach((element) => {
|
||||
// Explicit null check for element and style property
|
||||
if (element && element.style !== undefined && element.style !== null) {
|
||||
const action = show ? "remove" : "add";
|
||||
element.classList[action](UI_ELEMENTS.HIDDEN_CLASS);
|
||||
console.debug(`(proxyinfo) ${show ? "showing" : "hiding"} element`);
|
||||
} else {
|
||||
console.warn(
|
||||
"(proxyinfo) Invalid element encountered during visibility toggle"
|
||||
);
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Visibility toggle failed:", error);
|
||||
throw error; // Re-throw for error boundary handling
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update element content by ID
|
||||
* @param {string} elementId - Target element ID
|
||||
* @param {string} messageKey - i18n message key
|
||||
*/
|
||||
static updateContent(elementId, messageKey) {
|
||||
try {
|
||||
const element = document.getElementById(elementId);
|
||||
if (!element) {
|
||||
throw new Error(`Element not found : ${elementId}`);
|
||||
}
|
||||
element.textContent = chrome.i18n.getMessage(messageKey);
|
||||
} catch (error) {
|
||||
console.error("Content update failed:", error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get elements by selector
|
||||
* @param {string} selector - CSS selector
|
||||
* @return {?NodeList}
|
||||
*/
|
||||
static getElements(selector) {
|
||||
try {
|
||||
return document.querySelectorAll(selector);
|
||||
} catch (error) {
|
||||
console.error("Element selection failed:", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function proxyStatusError(error) {
|
||||
console.error("(proxyinfo)", error);
|
||||
contentUpdateById("proxy-check", "proxyFailedStatus");
|
||||
let readyness = document.querySelectorAll(".readyness");
|
||||
if (readyness !== null) {
|
||||
hide(readyness);
|
||||
/**
|
||||
* Proxy Status Manager
|
||||
*/
|
||||
class ProxyStatusManager {
|
||||
/**
|
||||
* Check proxy connectivity
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
static async checkProxyStatus() {
|
||||
console.info("(proxyinfo) Checking proxy status");
|
||||
try {
|
||||
const response = await fetch(
|
||||
PROXY_CONFIG.PROXY_URL,
|
||||
PROXY_CONFIG.FETCH_OPTIONS
|
||||
);
|
||||
await this.handleProxySuccess(response);
|
||||
} catch (error) {
|
||||
await this.handleProxyError(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle successful proxy connection
|
||||
* @param {Response} response - Fetch response
|
||||
*/
|
||||
static async handleProxySuccess(response) {
|
||||
console.info("(proxyinfo) Proxy check successful");
|
||||
UIManager.updateContent(UI_ELEMENTS.PROXY_STATUS, MESSAGE_KEYS.SUCCESS);
|
||||
|
||||
const readinessElements = UIManager.getElements(
|
||||
UI_ELEMENTS.READINESS_CLASS
|
||||
);
|
||||
if (readinessElements) {
|
||||
UIManager.toggleVisibility(readinessElements, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle proxy connection failure
|
||||
* @param {Error} error - Connection error
|
||||
*/
|
||||
static async handleProxyError(error) {
|
||||
console.error("(proxyinfo) Proxy check failed:", error);
|
||||
UIManager.updateContent(UI_ELEMENTS.PROXY_STATUS, MESSAGE_KEYS.FAILURE);
|
||||
|
||||
const readinessElements = UIManager.getElements(
|
||||
UI_ELEMENTS.READINESS_CLASS
|
||||
);
|
||||
if (readinessElements) {
|
||||
UIManager.toggleVisibility(readinessElements, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check console connectivity
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
static async checkConsoleStatus() {
|
||||
const logoUrl = `${PROXY_CONFIG.CONSOLE_URL}${PROXY_CONFIG.LOGO_PATH}`;
|
||||
console.info("(proxyinfo) Checking console status");
|
||||
|
||||
try {
|
||||
await fetch(logoUrl);
|
||||
const consoleLinks = UIManager.getElements(UI_ELEMENTS.CONSOLE_LINKS);
|
||||
if (consoleLinks) {
|
||||
UIManager.toggleVisibility(consoleLinks, true);
|
||||
}
|
||||
console.info("(proxyinfo) Console check successful");
|
||||
} catch (error) {
|
||||
const consoleLinks = UIManager.getElements(UI_ELEMENTS.CONSOLE_LINKS);
|
||||
if (consoleLinks) {
|
||||
UIManager.toggleVisibility(consoleLinks, false);
|
||||
}
|
||||
console.error("(proxyinfo) Console check failed:", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function hide(elements) {
|
||||
console.log("(proxyinfo) hiding", elements);
|
||||
const elems = Array.isArray(elements) ? elements : [elements];
|
||||
elems.forEach((elem) => {
|
||||
if (elem.style) {
|
||||
console.log("(proxyinfo) hiding");
|
||||
elem.classList.add("hidden");
|
||||
}
|
||||
});
|
||||
/**
|
||||
* Initialize proxy status checking
|
||||
*/
|
||||
function initializeProxyChecks() {
|
||||
try {
|
||||
ProxyStatusManager.checkProxyStatus();
|
||||
ProxyStatusManager.checkConsoleStatus();
|
||||
} catch (error) {
|
||||
console.error("Proxy initialization failed:", error);
|
||||
}
|
||||
}
|
||||
|
||||
function unhide(elements) {
|
||||
console.log("(proxyinfo) unhiding", elements);
|
||||
const elems = Array.isArray(elements) ? elements : [elements];
|
||||
elems.forEach((elem) => {
|
||||
if (elem.style) {
|
||||
console.log("(proxyinfo) unhiding");
|
||||
elem.classList.remove("hidden");
|
||||
}
|
||||
});
|
||||
}
|
||||
// Event Listeners
|
||||
document.addEventListener("DOMContentLoaded", initializeProxyChecks, {
|
||||
passive: true,
|
||||
capture: false,
|
||||
});
|
||||
|
||||
//TODO: Don't hard-code this.
|
||||
fetch("http://127.0.0.1:7657/themes/console/light/images/i2plogo.png")
|
||||
.then((myJson) => {
|
||||
console.log("(proxyinfo) img test pass", myJson);
|
||||
var consoleLinks = document.querySelectorAll(".application-info");
|
||||
unhide(consoleLinks);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log("(proxyinfo) img test fail", error);
|
||||
var consoleLinks = document.querySelectorAll(".application-info");
|
||||
hide(consoleLinks);
|
||||
});
|
||||
// Export for testing
|
||||
if (typeof module !== "undefined" && module.exports) {
|
||||
module.exports = {
|
||||
ProxyStatusManager,
|
||||
UIManager,
|
||||
PROXY_CONFIG,
|
||||
UI_ELEMENTS,
|
||||
};
|
||||
}
|
||||
|
Reference in New Issue
Block a user