diff options
author | sameerasw <[email protected]> | 2025-04-10 14:27:39 +0530 |
---|---|---|
committer | sameerasw <[email protected]> | 2025-04-10 14:27:42 +0530 |
commit | 7f45e1729c777de8f37e2f98bd58957a13d7027b (patch) | |
tree | 4d7dd2d6e58fd84fe55d28e72cdf0712938885a9 /popup/popup.js | |
parent | 01226d8f74a1353d075fe4816fe167375ea8e178 (diff) |
Added whitelist and blacklist toggle for forcing themes
Diffstat (limited to 'popup/popup.js')
-rw-r--r-- | popup/popup.js | 141 |
1 files changed, 123 insertions, 18 deletions
diff --git a/popup/popup.js b/popup/popup.js index a71eb4f..d81ed7d 100644 --- a/popup/popup.js +++ b/popup/popup.js @@ -13,9 +13,13 @@ new (class ExtensionPopup { autoUpdateSwitch = document.getElementById("auto-update"); lastFetchedTime = document.getElementById("last-fetched-time"); forceStylingSwitch = document.getElementById("force-styling"); + whitelistModeSwitch = document.getElementById("whitelist-mode"); + whitelistModeLabel = document.getElementById("whitelist-mode-label"); skipForceThemingSwitch = document.getElementById("skip-force-theming"); + siteToggleLabel = document.getElementById("site-toggle-label"); skipForceThemingList = []; reloadButton = document.getElementById("reload"); + modeIndicator = document.getElementById("mode-indicator"); constructor() { if (logging) console.log("Initializing ExtensionPopup"); @@ -45,6 +49,11 @@ new (class ExtensionPopup { ); this.reloadButton.addEventListener("click", this.reloadPage.bind(this)); + this.whitelistModeSwitch.addEventListener( + "change", + this.handleWhitelistModeChange.bind(this) + ); + // Setup auto-update and display last fetched time this.setupAutoUpdate(); this.displayLastFetchedTime(); @@ -97,9 +106,18 @@ new (class ExtensionPopup { this.globalSettings.enableStyling ?? true; this.autoUpdateSwitch.checked = this.globalSettings.autoUpdate ?? false; this.forceStylingSwitch.checked = this.globalSettings.forceStyling ?? false; - this.skipForceThemingSwitch.checked = this.skipForceThemingList.includes( + this.whitelistModeSwitch.checked = + this.globalSettings.whitelistMode ?? false; + + this.updateModeLabels(); + + // In whitelist mode, checked means "include this site" + // In blacklist mode, checked means "skip this site" + const isInList = this.skipForceThemingList.includes( this.currentSiteHostname ); + this.skipForceThemingSwitch.checked = isInList; + this.loadCurrentSiteFeatures(); } @@ -131,6 +149,7 @@ new (class ExtensionPopup { this.globalSettings.enableStyling = this.enableStylingSwitch.checked; this.globalSettings.autoUpdate = this.autoUpdateSwitch.checked; this.globalSettings.forceStyling = this.forceStylingSwitch.checked; + this.globalSettings.whitelistMode = this.whitelistModeSwitch.checked; browser.storage.local .set({ @@ -180,14 +199,20 @@ new (class ExtensionPopup { const index = this.skipForceThemingList.indexOf(this.currentSiteHostname); if (isChecked && index === -1) { + // Add to the list (whitelist: include, blacklist: skip) this.skipForceThemingList.push(this.currentSiteHostname); } else if (!isChecked && index !== -1) { + // Remove from the list (whitelist: exclude, blacklist: include) this.skipForceThemingList.splice(index, 1); } - browser.storage.local.set({ - [SKIP_FORCE_THEMING_KEY]: this.skipForceThemingList, - }); + browser.storage.local + .set({ + [SKIP_FORCE_THEMING_KEY]: this.skipForceThemingList, + }) + .then(() => { + this.updateActiveTabStyling(); + }); } async loadCurrentSiteFeatures() { @@ -335,34 +360,51 @@ new (class ExtensionPopup { const hostname = url.hostname; try { - await browser.tabs.removeCSS(tab.id, { - code: "/* Placeholder for removing CSS */", - }); - } catch (error) {} + // Try to remove any existing CSS first + try { + await browser.tabs.removeCSS(tab.id, { + code: "/* Placeholder for removing CSS */", + }); + } catch (error) { + // Ignore errors as they may occur if no CSS was previously applied + } - if (!this.shouldApplyCSS(hostname)) return; + if (!this.shouldApplyCSS(hostname)) return; - try { const stylesData = await browser.storage.local.get("styles"); const styles = stylesData.styles?.website || {}; - let siteKey = null; + // First try to find a direct match for a CSS file + let bestMatch = null; + let bestMatchLength = 0; + for (const site of Object.keys(styles)) { const siteName = site.replace(/\.css$/, ""); if (siteName.startsWith("+")) { const baseSiteName = siteName.slice(1); - if (hostname.endsWith(baseSiteName)) { - siteKey = site; - break; + if ( + hostname.endsWith(baseSiteName) && + baseSiteName.length > bestMatchLength + ) { + bestMatch = site; + bestMatchLength = baseSiteName.length; } } else if (hostname === siteName || hostname === `www.${siteName}`) { - siteKey = site; + // Exact match has priority + bestMatch = site; break; + } else if ( + hostname.endsWith(siteName) && + siteName.length > bestMatchLength + ) { + bestMatch = site; + bestMatchLength = siteName.length; } } - if (siteKey && styles[siteKey]) { - const features = styles[siteKey]; + // If we found a direct match, use it + if (bestMatch) { + const features = styles[bestMatch]; const siteStorageKey = `${this.BROWSER_STORAGE_KEY}.${hostname}`; const siteData = await browser.storage.local.get(siteStorageKey); const featureSettings = siteData[siteStorageKey] || {}; @@ -376,7 +418,36 @@ new (class ExtensionPopup { if (combinedCSS) { await browser.tabs.insertCSS(tab.id, { code: combinedCSS }); - console.info(`Applied CSS to ${hostname}`); + console.info(`Applied CSS to ${hostname} (direct match)`); + } + } else if (this.globalSettings.forceStyling) { + // Otherwise check for forced styling + const isInList = this.skipForceThemingList.includes(hostname); + const isWhitelistMode = this.globalSettings.whitelistMode; + + // Determine if we should apply forced styling + const shouldApplyForcedStyling = + (isWhitelistMode && isInList) || (!isWhitelistMode && !isInList); + + if (shouldApplyForcedStyling && styles["example.com.css"]) { + const features = styles["example.com.css"]; + const siteStorageKey = `${this.BROWSER_STORAGE_KEY}.${hostname}`; + const siteData = await browser.storage.local.get(siteStorageKey); + const featureSettings = siteData[siteStorageKey] || {}; + + 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 forced CSS to ${hostname}`); + } + } else { + console.info(`Skipping forced styling for ${hostname}`); } } } catch (error) { @@ -434,4 +505,38 @@ new (class ExtensionPopup { } } } + + handleWhitelistModeChange() { + this.updateModeLabels(); + this.saveSettings(); + } + + updateModeIndicator() { + if (this.whitelistModeSwitch.checked) { + this.modeIndicator.textContent = + "In Whitelist Mode (apply only to listed sites)"; + } else { + this.modeIndicator.textContent = + "In Blacklist Mode (apply to all except listed sites)"; + } + } + + updateSiteToggleLabel() { + // Update the label based on the current mode + if (this.whitelistModeSwitch.checked) { + this.siteToggleLabel.textContent = "Enable for this Site"; + } else { + this.siteToggleLabel.textContent = "Skip Forcing for this Site"; + } + } + + updateModeLabels() { + if (this.whitelistModeSwitch.checked) { + this.whitelistModeLabel.textContent = "Whitelist Mode"; + this.siteToggleLabel.textContent = "Enable for this Site"; + } else { + this.whitelistModeLabel.textContent = "Blacklist Mode"; + this.siteToggleLabel.textContent = "Skip Forcing for this Site"; + } + } })(); |