new(class ExtensionPopup { BROWSER_STORAGE_KEY = "transparentZenSettings"; browserStorageSettings = {}; enableStylingSwitch = document.getElementById("enable-styling"); refetchCSSButton = document.getElementById("refetch-css"); websitesList = document.getElementById("websites-list"); currentSiteFeatures = document.getElementById("current-site-toggles"); currentSiteHostname = ""; constructor() { this.loadSettings().then((settings) => { if (settings) { this.browserStorageSettings = settings; this.getCurrentTabInfo().then(() => { this.restoreSettings(); this.bindEvents(); }); } }); this.refetchCSSButton.addEventListener("click", this.refetchCSS.bind(this)); document.getElementById("toggle-websites").addEventListener("click", () => { this.websitesList.classList.toggle("collapsed"); }); this.setupContentScriptInjection(); } async getCurrentTabInfo() { try { const tabs = await browser.tabs.query({ active: true, currentWindow: true }); if (tabs.length > 0) { const url = new URL(tabs[0].url); this.currentSiteHostname = url.hostname; console.info("Current site hostname:", this.currentSiteHostname); } } catch (error) { console.error("Error getting current tab info:", error); } } bindEvents() { this.enableStylingSwitch.addEventListener("change", () => { this.saveSettings(); this.updateActiveTabStyling(); }); this.currentSiteFeatures.addEventListener("change", (event) => { if (event.target.type === 'checkbox') { this.saveSettings(); this.updateActiveTabStyling(); } }); } restoreSettings() { if (this.browserStorageSettings.enableStyling !== undefined) { this.enableStylingSwitch.checked = this.browserStorageSettings.enableStyling; } this.loadCurrentSiteFeatures(); this.loadWebsitesList(); } async loadSettings() { const settings = await browser.storage.local.get(this.BROWSER_STORAGE_KEY); console.info("Settings loaded", settings?.[this.BROWSER_STORAGE_KEY]); return settings?.[this.BROWSER_STORAGE_KEY] || {}; } saveSettings() { this.browserStorageSettings.enableStyling = this.enableStylingSwitch.checked; const featureSettings = {}; this.currentSiteFeatures .querySelectorAll("input[type=checkbox]") .forEach((checkbox) => { const [site, feature] = checkbox.name.split('|'); if (!featureSettings[site]) { featureSettings[site] = {}; } featureSettings[site][feature] = checkbox.checked; }); this.browserStorageSettings.featureSettings = featureSettings; browser.storage.local.set({ [this.BROWSER_STORAGE_KEY]: this.browserStorageSettings, }); console.info("Settings saved", this.browserStorageSettings); } async loadCurrentSiteFeatures() { try { const stylesData = await browser.storage.local.get("styles"); const styles = stylesData.styles?.website || {}; this.currentSiteFeatures.innerHTML = ""; const currentSiteKey = Object.keys(styles).find(site => this.isCurrentSite(site.replace(".css", "")) ); if (!currentSiteKey) { this.currentSiteFeatures.innerHTML = "
No styles available for this site.
"; return; } const features = styles[currentSiteKey]; for (const [feature, css] of Object.entries(features)) { const isChecked = this.browserStorageSettings.featureSettings?.[currentSiteKey]?.[feature] ?? true; const featureToggle = document.createElement("div"); featureToggle.className = "feature-toggle"; featureToggle.innerHTML = ` ${feature} `; this.currentSiteFeatures.appendChild(featureToggle); } } catch (error) { console.error("Error loading current site features:", error); this.currentSiteFeatures.innerHTML = "
Error loading features.
"; } } async loadWebsitesList() { try { const stylesData = await browser.storage.local.get("styles"); const styles = stylesData.styles?.website || {}; this.websitesList.innerHTML = ""; const websites = Object.keys(styles); if (websites.length === 0) { const listItem = document.createElement("li"); listItem.textContent = "No styles available. Click 'Refetch latest styles' to update."; this.websitesList.appendChild(listItem); return; } for (const site of websites) { const displayName = site.replace(/\.css$/, ""); const listItem = document.createElement("li"); listItem.textContent = displayName; this.websitesList.appendChild(listItem); } } catch (error) { console.error("Error loading websites list:", error); this.websitesList.innerHTML = "
  • Error loading websites list. Please try refetching styles.
  • "; } } isCurrentSite(siteName) { if (!this.currentSiteHostname) return false; if (this.currentSiteHostname === siteName) return true; if (this.currentSiteHostname.startsWith("www.")) { const nonWww = this.currentSiteHostname.replace("www.", ""); if (nonWww === siteName) return true; } return false; } async refetchCSS() { this.refetchCSSButton.textContent = "Fetching..."; try { const response = await fetch( "https://github.com/sameerasw/my-internet/raw/refs/heads/experimental/styles.json", { headers: { "Cache-Control": "no-cache", }, } ); if (!response.ok) throw new Error("Failed to fetch styles.json"); const styles = await response.json(); await browser.storage.local.set({ styles }); this.loadCurrentSiteFeatures(); this.loadWebsitesList(); this.updateActiveTabStyling(); this.refetchCSSButton.textContent = "Done!"; setTimeout(() => { this.refetchCSSButton.textContent = "Refetch latest styles"; }, 2000); console.info("All styles refetched and updated from GitHub." + styles); } catch (error) { this.refetchCSSButton.textContent = "Error!"; setTimeout(() => { this.refetchCSSButton.textContent = "Refetch latest styles"; }, 2000); console.error("Error refetching styles:", error); } } setupContentScriptInjection() { browser.tabs.onUpdated.addListener(async (tabId, changeInfo, tab) => { if (changeInfo.status === 'complete') { this.applyCSSToTab(tab); } }); this.updateAllTabs(); } async updateAllTabs() { const tabs = await browser.tabs.query({}); for (const tab of tabs) { this.applyCSSToTab(tab); } } async updateActiveTabStyling() { const tabs = await browser.tabs.query({ active: true, currentWindow: true }); if (tabs.length > 0) { this.applyCSSToTab(tabs[0]); } } async applyCSSToTab(tab) { const url = new URL(tab.url); const hostname = url.hostname; try { await browser.tabs.removeCSS(tab.id, { code: "/* Placeholder for removing CSS */" }); } catch (error) {} if (!this.shouldApplyCSS(hostname)) return; try { const stylesData = await browser.storage.local.get("styles"); const styles = stylesData.styles?.website || {}; let siteKey = null; for (const site of Object.keys(styles)) { const siteName = site.replace(/\.css$/, ""); if (hostname.includes(siteName)) { siteKey = site; break; } } if (siteKey && styles[siteKey]) { const features = styles[siteKey]; const featureSettings = this.browserStorageSettings.featureSettings?.[siteKey] || {}; let combinedCSS = ""; for (const [feature, css] of Object.entries(features)) { if (featureSettings[feature] !== false) { combinedCSS += css + "\n"; } } if (combinedCSS) { await browser.tabs.insertCSS(tab.id, { code: combinedCSS }); console.info(`Applied CSS to ${hostname}`); } } } catch (error) { console.error(`Error applying CSS to ${hostname}:`, error); } } shouldApplyCSS(hostname) { return this.browserStorageSettings.enableStyling !== false; } })();