diff options
| author | sameerasw <[email protected]> | 2025-04-29 23:16:03 +0530 | 
|---|---|---|
| committer | sameerasw <[email protected]> | 2025-04-29 23:16:03 +0530 | 
| commit | 615120cfe55c2b823dc7696437ad2c55795161d8 (patch) | |
| tree | d5112e2aeafcb45c0b65c7b8274d543e8ccab931 | |
| parent | 76c2fbe1b5c63a9f6ad74a5a726f9a308b1ab9db (diff) | |
New icon - dynamic icon - version update to 2.0.0
| -rw-r--r-- | assets/images/logo-off.png | bin | 0 -> 8466 bytes | |||
| -rw-r--r-- | assets/images/logo-off_48.png | bin | 0 -> 1324 bytes | |||
| -rw-r--r-- | assets/images/logo-off_96.png | bin | 0 -> 2554 bytes | |||
| -rw-r--r-- | assets/images/logo.png | bin | 168763 -> 21411 bytes | |||
| -rw-r--r-- | assets/images/logo_48.png | bin | 4984 -> 3054 bytes | |||
| -rw-r--r-- | assets/images/logo_96.png | bin | 13741 -> 6333 bytes | |||
| -rw-r--r-- | background.js | 247 | ||||
| -rw-r--r-- | data-viewer/data-viewer.html | 2 | ||||
| -rw-r--r-- | manifest.json | 8 | ||||
| -rw-r--r-- | popup/popup.html | 2 | 
10 files changed, 255 insertions, 4 deletions
diff --git a/assets/images/logo-off.png b/assets/images/logo-off.png Binary files differnew file mode 100644 index 0000000..3ee5eda --- /dev/null +++ b/assets/images/logo-off.png diff --git a/assets/images/logo-off_48.png b/assets/images/logo-off_48.png Binary files differnew file mode 100644 index 0000000..d502afc --- /dev/null +++ b/assets/images/logo-off_48.png diff --git a/assets/images/logo-off_96.png b/assets/images/logo-off_96.png Binary files differnew file mode 100644 index 0000000..095a910 --- /dev/null +++ b/assets/images/logo-off_96.png diff --git a/assets/images/logo.png b/assets/images/logo.png Binary files differindex 1e56728..ad65e4f 100644 --- a/assets/images/logo.png +++ b/assets/images/logo.png diff --git a/assets/images/logo_48.png b/assets/images/logo_48.png Binary files differindex d083002..44a945f 100644 --- a/assets/images/logo_48.png +++ b/assets/images/logo_48.png diff --git a/assets/images/logo_96.png b/assets/images/logo_96.png Binary files differindex 9b402a6..d71f36c 100644 --- a/assets/images/logo_96.png +++ b/assets/images/logo_96.png diff --git a/background.js b/background.js index 2696887..60fd68e 100644 --- a/background.js +++ b/background.js @@ -6,6 +6,18 @@ let logging = true; // Enable logging for debugging  // Create a cache for pre-processed CSS to speed up repeated visits  const cssCache = new Map();  const activeTabs = new Map(); +// Cache for styling state to avoid repeated storage lookups +const stylingStateCache = new Map(); + +// Icon states for the browser action +const ICON_ON = { +  48: "assets/images/logo_48.png", +  96: "assets/images/logo_96.png", +}; +const ICON_OFF = { +  48: "assets/images/logo-off_48.png", +  96: "assets/images/logo-off_96.png", +};  // Default settings to use when values are missing  const DEFAULT_SETTINGS = { @@ -36,6 +48,181 @@ function ensureDefaultSettings(settings = {}) {    return result;  } +// Determine if styling should be applied to a hostname +// This is the centralized logic for both CSS application and icon updates +async function shouldApplyStyling(hostname) { +  try { +    // Check if we already have the answer cached +    const cacheKey = `styling:${hostname}`; +    if (stylingStateCache.has(cacheKey)) { +      return stylingStateCache.get(cacheKey); +    } + +    const normalizedHostname = normalizeHostname(hostname); + +    // Get global settings - this is an unavoidable storage lookup +    const settingsData = await browser.storage.local.get(BROWSER_STORAGE_KEY); +    const settings = ensureDefaultSettings( +      settingsData[BROWSER_STORAGE_KEY] || {} +    ); + +    // If styling is globally disabled, styling is disabled +    if (!settings.enableStyling) { +      stylingStateCache.set(cacheKey, false); +      return false; +    } + +    // Check if we have a specific style for this site +    let hasSpecificStyle = false; + +    // Check for exact match first +    if ( +      cssCache.has(normalizedHostname) || +      cssCache.has(`www.${normalizedHostname}`) +    ) { +      hasSpecificStyle = true; +    } else { +      // Check for wildcard and TLD matches +      for (const cachedSite of cssCache.keys()) { +        // Wildcard match +        if (cachedSite.startsWith("+")) { +          const baseSite = cachedSite.slice(1); +          if ( +            normalizedHostname === baseSite || +            normalizedHostname.endsWith(`.${baseSite}`) +          ) { +            hasSpecificStyle = true; +            break; +          } +        } +        // TLD suffix match +        else if (cachedSite.startsWith("-")) { +          const baseSite = cachedSite.slice(1); +          const cachedDomain = baseSite.split(".").slice(0, -1).join("."); +          const hostParts = normalizedHostname.split("."); +          const hostDomain = +            hostParts.length > 1 +              ? hostParts.slice(0, -1).join(".") +              : normalizedHostname; + +          if (cachedDomain && hostDomain && hostDomain === cachedDomain) { +            hasSpecificStyle = true; +            break; +          } +        } +        // Subdomain match +        else if ( +          normalizedHostname !== cachedSite && +          normalizedHostname.endsWith(`.${cachedSite}`) && +          !cachedSite.startsWith("-") +        ) { +          hasSpecificStyle = true; +          break; +        } +      } +    } + +    // If we have a specific style, check blacklist/whitelist for regular styling +    if (hasSpecificStyle) { +      // Get skip styling list - only do this lookup if we have a specific style +      const skipStyleListData = await browser.storage.local.get( +        SKIP_THEMING_KEY +      ); +      const skipStyleList = skipStyleListData[SKIP_THEMING_KEY] || []; + +      // In whitelist mode: only apply if site is in the list +      // In blacklist mode: apply unless site is in the list +      const styleMode = settings.whitelistStyleMode || false; + +      if (styleMode) { +        // Whitelist mode +        const shouldApply = skipStyleList.includes(normalizedHostname); +        stylingStateCache.set(cacheKey, shouldApply); +        return shouldApply; +      } else { +        // Blacklist mode +        const shouldApply = !skipStyleList.includes(normalizedHostname); +        stylingStateCache.set(cacheKey, shouldApply); +        return shouldApply; +      } +    } + +    // If no specific style, check if we should apply forced styling +    if (settings.forceStyling) { +      // Get skip force list - only do this lookup if force styling is enabled +      const skipForceListData = await browser.storage.local.get( +        SKIP_FORCE_THEMING_KEY +      ); +      const skipForceList = skipForceListData[SKIP_FORCE_THEMING_KEY] || []; +      const isWhitelistMode = settings.whitelistMode || false; + +      // In whitelist mode: only apply if site is in the list +      // In blacklist mode: apply unless site is in the list +      if (isWhitelistMode) { +        const shouldApply = skipForceList.includes(normalizedHostname); +        stylingStateCache.set(cacheKey, shouldApply); +        return shouldApply; +      } else { +        const shouldApply = !skipForceList.includes(normalizedHostname); +        stylingStateCache.set(cacheKey, shouldApply); +        return shouldApply; +      } +    } + +    // No styling applies +    stylingStateCache.set(cacheKey, false); +    return false; +  } catch (error) { +    console.error("Error determining styling state:", error); +    return false; +  } +} + +// Update the icon based on whether styling is active for the current tab +async function updateIconForTab(tabId, url) { +  try { +    if (!url) { +      const tab = await browser.tabs.get(tabId); +      url = tab.url; +    } + +    // Non-HTTP URLs don't get styling +    if (!url || !url.startsWith("http")) { +      setIcon(tabId, false); +      return; +    } + +    const urlObj = new URL(url); +    const hostname = urlObj.hostname; + +    // Determine if we should apply styling using the centralized logic +    const isStylingEnabled = await shouldApplyStyling(hostname); + +    // Update the icon based on whether styling is enabled for this site +    setIcon(tabId, isStylingEnabled); + +    if (logging) +      console.log( +        `Icon updated for ${hostname}: styling ${ +          isStylingEnabled ? "ON" : "OFF" +        }` +      ); +  } catch (error) { +    console.error("Error updating icon:", error); +    // Default to off icon in case of error +    setIcon(tabId, false); +  } +} + +// Set the icon to either on or off state +function setIcon(tabId, isEnabled) { +  const iconSet = isEnabled ? ICON_ON : ICON_OFF; +  browser.browserAction.setIcon({ +    path: iconSet, +    tabId: tabId, +  }); +} +  // Preload styles for faster injection  async function preloadStyles() {    try { @@ -89,6 +276,9 @@ browser.webNavigation.onBeforeNavigate.addListener((details) => {      const url = new URL(details.url);      const normalizedHostname = normalizeHostname(url.hostname);      prepareStylesForUrl(normalizedHostname, details.tabId); + +    // Update icon for this tab +    updateIconForTab(details.tabId, details.url);    }  }); @@ -131,6 +321,11 @@ browser.runtime.onMessage.addListener(async (message, sender) => {      return true;    } +  // Update the icon when the content script reports ready +  if (message.action === "contentScriptReady" && sender.tab) { +    updateIconForTab(sender.tab.id, sender.tab.url); +  } +    return false;  }); @@ -303,6 +498,12 @@ async function applyCSSToTab(tab) {        (styleMode && !skipStyleList.includes(hostname))      ) {        console.log("DEBUG: Styling is disabled, exiting early"); +      // Make sure the icon is updated to reflect the disabled state +      setIcon(tab.id, false); + +      // Clear the cache entry to ensure we don't have stale data +      const cacheKey = `styling:${hostname}`; +      stylingStateCache.set(cacheKey, false);        return;      } @@ -465,8 +666,16 @@ async function applyCSSToTab(tab) {      } else {        console.log("DEBUG: Force styling is disabled, no styles applied");      } + +    // After successfully applying CSS, update the icon to ON state +    // and update the styling state cache +    const cacheKey = `styling:${hostname}`; +    stylingStateCache.set(cacheKey, true); +    setIcon(tab.id, true);    } catch (error) {      console.error(`DEBUG ERROR: Error applying CSS:`, error); +    // If there's an error, make sure the icon is OFF +    setIcon(tab.id, false);    }  } @@ -559,8 +768,40 @@ async function applyCSS(tabId, hostname, features) {    } else {      console.log(`DEBUG: No CSS to inject after filtering features`);    } + +  // Update the icon based on our current state +  setIcon(tabId, stylingStateCache.get(`styling:${hostname}`) || false);  } +// Also update icons when tabs are updated +browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => { +  if (changeInfo.status === "complete") { +    updateIconForTab(tabId, tab.url); +  } +}); + +// Update the icon when a tab becomes active +browser.tabs.onActivated.addListener((activeInfo) => { +  updateIconForTab(activeInfo.tabId); +}); + +// Clear cache on settings changes +browser.storage.onChanged.addListener((changes, areaName) => { +  if (areaName === "local") { +    if ( +      changes[BROWSER_STORAGE_KEY] || +      changes[SKIP_THEMING_KEY] || +      changes[SKIP_FORCE_THEMING_KEY] +    ) { +      // Clear the styling state cache when relevant settings change +      stylingStateCache.clear(); + +      if (logging) +        console.log("Cleared styling state cache due to settings change"); +    } +  } +}); +  let autoUpdateInterval;  function startAutoUpdate() { @@ -653,6 +894,12 @@ async function initializeExtension() {    if (validatedSettings.autoUpdate) {      startAutoUpdate();    } + +  // Update icons for all tabs on extension startup +  const tabs = await browser.tabs.query({}); +  for (const tab of tabs) { +    updateIconForTab(tab.id, tab.url); +  }  }  // Listen for specific navigation events to apply CSS as early as possible diff --git a/data-viewer/data-viewer.html b/data-viewer/data-viewer.html index b0d4a5f..716942d 100644 --- a/data-viewer/data-viewer.html +++ b/data-viewer/data-viewer.html @@ -16,7 +16,7 @@          <header class="app-header">              <div id="header-container">                  <div class="logo-container"> -                    <img src="../assets/images/logo_48.png" alt="ZenInternet Logo" class="logo-img"> +                    <img src="../assets/images/logo.png" alt="ZenInternet Logo" class="logo-img">                      <h1 class="app-title">Zen Internet Settings</h1>                  </div>                  <div class="miniheader"> diff --git a/manifest.json b/manifest.json index aeb6de8..320eb23 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@  {    "manifest_version": 2,    "name": "Zen Internet", -  "version": "1.9.2", +  "version": "2.0.0",    "description": "Make the internet feel native and elegant. Zen Internet is a browser extension that enhances your browsing experience by providing a clean and minimalistic interface with transparency and a focus on content. Customize the features in the addon popup.",    "browser_specific_settings": {      "gecko": { @@ -23,7 +23,11 @@    ],    "browser_action": {      "default_popup": "popup/popup.html", -    "default_title": "Zen Internet" +    "default_title": "Zen Internet", +    "default_icon": { +      "48": "assets/images/logo_48.png", +      "96": "assets/images/logo_96.png" +    }    },    "background": {      "scripts": ["background.js"], diff --git a/popup/popup.html b/popup/popup.html index bc5b92b..ae497bc 100644 --- a/popup/popup.html +++ b/popup/popup.html @@ -14,7 +14,7 @@      <header class="app-header">        <div id="header-container">          <div class="logo-container"> -          <img src="../assets/images/logo_48.png" alt="ZenInternet Logo" class="logo-img"> +          <img src="../assets/images/logo.png" alt="ZenInternet Logo" class="logo-img">            <h1 class="app-title">Zen Internet</h1>          </div>          <div class="miniheader">  | 
