summaryrefslogtreecommitdiff
path: root/inject-css.js
diff options
context:
space:
mode:
Diffstat (limited to 'inject-css.js')
-rw-r--r--inject-css.js220
1 files changed, 0 insertions, 220 deletions
diff --git a/inject-css.js b/inject-css.js
deleted file mode 100644
index 27b4ecc..0000000
--- a/inject-css.js
+++ /dev/null
@@ -1,220 +0,0 @@
-import { SKIP_FORCE_THEMING_KEY } from "./shared/constants.js";
-
-let logging = false;
-
-if (logging) console.log("inject-css.js script loaded");
-
-// Run as early as possible in the document lifecycle
-const implementImmediateInjection = () => {
- // Create a style element immediately to avoid any delay - do this before anything else
- const styleElement = document.createElement("style");
- styleElement.id = "zen-internet-styles";
-
- // Set highest priority
- styleElement.setAttribute("data-priority", "highest");
-
- // Add !important to all rules to override any existing styles
- styleElement.innerHTML = `
- /* Prevent FOUC - temporarily hide content until styles are applied */
- body { opacity: 0 !important; transition: opacity 0.1s ease-in !important; }
- `;
-
- // Insert as the first element of head if possible
- if (document.head) {
- document.head.insertBefore(styleElement, document.head.firstChild);
- } else {
- // If head isn't ready yet (very early execution), add to documentElement
- document.documentElement.appendChild(styleElement);
-
- // Set up mutation observer to move it to head when head becomes available
- new MutationObserver((mutations, observer) => {
- if (document.head) {
- if (styleElement.parentNode !== document.head) {
- document.head.insertBefore(styleElement, document.head.firstChild);
- }
- observer.disconnect();
- }
- }).observe(document.documentElement, { childList: true });
- }
-
- return styleElement;
-};
-
-// Create style element immediately
-const styleElement = implementImmediateInjection();
-
-// Function to apply styles immediately when available
-function applyStyles(css) {
- if (!css) return;
-
- // Add the CSS
- try {
- // For immediate application, directly set textContent
- // as this is more reliably applied in early document stages
- styleElement.textContent =
- css.trim() +
- `
-/* Remove FOUC prevention once styles are loaded */
-body { opacity: 1 !important; }`;
-
- // After a very short delay (to ensure CSS application), ensure body is visible
- setTimeout(() => {
- if (document.body) {
- document.body.style.opacity = "1";
- }
- }, 10);
-
- if (logging) console.log("Styles applied:", css.length, "bytes");
- } catch (e) {
- console.error("Error applying styles:", e);
- }
-}
-
-// Listen for style data from background script for immediate injection
-browser.runtime.onMessage.addListener((message) => {
- if (message.action === "applyStyles" && message.css) {
- applyStyles(message.css);
- return true;
- }
-});
-
-// Send hostname to background script as early as possible
-browser.runtime
- .sendMessage({
- action: "contentScriptReady",
- hostname: window.location.hostname,
- url: window.location.href,
- })
- .catch((err) => {
- if (logging) console.log("Background script not ready yet:", err);
- });
-
-// Main function - but we don't wait for this before applying styles
-// This is just a backup in case background script injection fails
-(async () => {
- try {
- const settings = await browser.storage.local.get("transparentZenSettings");
- if (logging) console.log("Settings loaded", settings);
-
- if (!settings.transparentZenSettings?.enableStyling) {
- if (logging) console.log("Styling is disabled");
- return;
- }
-
- if (logging) console.log("Styling is enabled");
-
- // Tell background script we're ready and what page we're on
- browser.runtime.sendMessage({
- action: "contentScriptReady",
- hostname: window.location.hostname,
- });
-
- const data = await browser.storage.local.get("styles");
- if (!data.styles) {
- if (logging) console.log("No styles data available");
- return;
- }
-
- if (logging) console.log("Styles data loaded", data);
-
- const currentUrl = window.location.hostname;
- if (logging) console.log("Current URL hostname", currentUrl);
-
- // Find the best matching CSS file
- let bestMatch = null;
- let bestMatchLength = 0;
-
- for (const key of Object.keys(data.styles?.website || {})) {
- const siteName = key.replace(".css", "");
- if (siteName.startsWith("+")) {
- const baseSiteName = siteName.slice(1);
- if (
- currentUrl.endsWith(baseSiteName) &&
- baseSiteName.length > bestMatchLength
- ) {
- bestMatch = key;
- bestMatchLength = baseSiteName.length;
- }
- } else if (currentUrl === siteName || currentUrl === `www.${siteName}`) {
- // Exact match has priority
- bestMatch = key;
- break;
- } else if (
- currentUrl.endsWith(siteName) &&
- siteName.length > bestMatchLength
- ) {
- bestMatch = key;
- bestMatchLength = siteName.length;
- }
- }
-
- // If a direct match was found, use it
- if (bestMatch) {
- await injectCSS(currentUrl, data.styles.website[bestMatch]);
- return;
- }
-
- // If no direct match was found and force styling is enabled, check whitelist/blacklist mode
- if (settings.transparentZenSettings?.forceStyling) {
- const skipListData = await browser.storage.local.get(
- SKIP_FORCE_THEMING_KEY
- );
- const siteList = skipListData[SKIP_FORCE_THEMING_KEY] || [];
- const isWhitelistMode =
- settings.transparentZenSettings?.whitelistMode || false;
- const siteInList = siteList.includes(currentUrl);
-
- // In whitelist mode: apply only if site is in the list
- // In blacklist mode: apply only if site is NOT in the list
- if (
- (isWhitelistMode && siteInList) ||
- (!isWhitelistMode && !siteInList)
- ) {
- await injectCSS(currentUrl, data.styles.website["example.com.css"]);
- } else {
- if (logging)
- console.log(
- `Styling skipped due to ${
- isWhitelistMode ? "whitelist" : "blacklist"
- } mode settings`
- );
- }
- } else {
- if (logging) console.log("No CSS file found for current site");
- }
- } catch (error) {
- console.error("Error injecting CSS:", error);
- }
-})();
-
-async function injectCSS(hostname, features) {
- if (!features) return;
-
- const siteKey = `transparentZenSettings.${hostname}`;
- const settings = await browser.storage.local.get("transparentZenSettings");
- const globalSettings = settings.transparentZenSettings || {};
- const siteData = await browser.storage.local.get(siteKey);
- const featureSettings = siteData[siteKey] || {};
-
- let combinedCSS = "";
- for (const [feature, css] of Object.entries(features)) {
- // Skip any transparency feature if disableTransparency is enabled globally
- if (
- globalSettings.disableTransparency &&
- feature.toLowerCase().includes("transparency")
- ) {
- if (logging) console.log(`Skipping transparency feature: ${feature}`);
- continue;
- }
-
- // Apply the feature if it's not explicitly disabled
- if (featureSettings[feature] !== false) {
- combinedCSS += css + "\n";
- }
- }
-
- if (combinedCSS) {
- applyStyles(combinedCSS);
- if (logging) console.log(`Injected custom CSS for ${hostname}`);
- }
-}