From 7290e4013fc94299236947ddc2422fbab4183d8d Mon Sep 17 00:00:00 2001 From: Aditya Gupta Date: Fri, 23 Jan 2026 18:29:33 +0530 Subject: [PATCH] feat: enhance site detection and popup functionality --- borlander/content.js | 53 +++++++++++++++----------------------- borlander/manifest.json | 37 ++++++++------------------ borlander/popup.html | 57 +++++++++++++++++++++++++++++++++++------ borlander/popup.js | 57 +++++++++++++++++++++++++++++++++-------- 4 files changed, 127 insertions(+), 77 deletions(-) diff --git a/borlander/content.js b/borlander/content.js index e2bcdba..f545804 100644 --- a/borlander/content.js +++ b/borlander/content.js @@ -1,52 +1,41 @@ const domain = window.location.hostname; -chrome.storage.local.get([domain], (result) => { - if (result[domain] !== 'disabled') { - - let siteMatched = false; +chrome.storage.local.get([domain, `${domain}_mode`], (result) => { + if (result[domain] === 'disabled') return; + const forceGlobal = result[`${domain}_mode`] === 'global'; + let siteMatched = false; + if (!forceGlobal) { // 1. SONARR const isSonarr = getComputedStyle(document.documentElement).getPropertyValue('--sonarrBlue').trim() !== "" || document.title.toLowerCase().includes('sonarr'); - - if (isSonarr) { - injectSiteStyle('sites/sonarr.local/styles.css'); - siteMatched = true; - } + if (isSonarr) { injectSiteStyle('sites/sonarr.local/styles.css'); siteMatched = true; } // 2. CHESS.COM - const isChess = domain.includes('chess.com') || !!document.querySelector('.board-layout-main'); - - if (isChess) { - injectSiteStyle('sites/chess.com/styles.css'); - siteMatched = true; + if (!siteMatched && (domain.includes('chess.com') || !!document.querySelector('.board-layout-main'))) { + injectSiteStyle('sites/chess.com/styles.css'); siteMatched = true; } - const isAnilist = domain.includes('anilist.co'); - if (isAnilist) { - injectSiteStyle('sites/anilist.co/styles.css'); - siteMatched = true; + // 3. ANILIST + if (!siteMatched && domain.includes('anilist.co')) { + injectSiteStyle('sites/anilist.co/styles.css'); siteMatched = true; } - // 3. GITEA - const isGitea = !!document.querySelector('meta[content*="gitea"]') || - !!document.querySelector('.ui.footer .item[href*="gitea.com"]') || - domain.includes('gitea'); - - if (isGitea) { - console.log("Borland Theme: Gitea detected."); - injectSiteStyle('sites/gitea.local/styles.css'); - siteMatched = true; + // 4. GITEA + if (!siteMatched && (!!document.querySelector('meta[content*="gitea"]') || domain.includes('gitea'))) { + injectSiteStyle('sites/gitea.local/styles.css'); siteMatched = true; } - // --- GLOBAL FALLBACK --- - // Only inject global styles if NO specific site was matched - if (!siteMatched) { - console.log("Borland Theme: No specific site match. Applying global styles."); - injectSiteStyle('styles.css'); + // 5. GITHUB + if (!siteMatched && domain.includes('github.com')) { + injectSiteStyle('sites/github.com/styles.css'); siteMatched = true; } } + + if (!siteMatched) { + injectSiteStyle('styles.css'); + } }); function injectSiteStyle(path) { diff --git a/borlander/manifest.json b/borlander/manifest.json index ed9c698..622cc87 100644 --- a/borlander/manifest.json +++ b/borlander/manifest.json @@ -5,8 +5,15 @@ "description": "Applies the classic Borland blue and yellow theme to all websites.", "permissions": [ "storage", - "tabs" + "tabs", + "scripting" ], + "host_permissions": [ + "" + ], + "action": { + "default_popup": "popup.html" + }, "content_scripts": [ { "matches": [ @@ -22,38 +29,14 @@ } ], "web_accessible_resources": [ - { - "resources": [ - "styles.css" - ], - "matches": [ - "" - ] - }, - { - "resources": [ - "styles.css", - "sites/sonarr.local/styles.css" - ], - "matches": [ - "" - ] - }, - { - "resources": [ - "sites/github.com/styles.css" - ], - "matches": [ - "https://github.com/*" - ] - }, { "resources": [ "styles.css", "sites/sonarr.local/styles.css", "sites/chess.com/styles.css", "sites/gitea.local/styles.css", - "sites/anilist.co/styles.css" + "sites/anilist.co/styles.css", + "sites/github.com/styles.css" ], "matches": [ "" diff --git a/borlander/popup.html b/borlander/popup.html index bc395a6..9cee213 100644 --- a/borlander/popup.html +++ b/borlander/popup.html @@ -4,27 +4,68 @@

Domain

- +
+ + +
diff --git a/borlander/popup.js b/borlander/popup.js index 97fe43b..31f0bf1 100644 --- a/borlander/popup.js +++ b/borlander/popup.js @@ -1,22 +1,59 @@ -chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { - const url = new URL(tabs[0].url); +chrome.tabs.query({ active: true, currentWindow: true }, async (tabs) => { + if (!tabs[0] || !tabs[0].url) return; + + const activeTab = tabs[0]; + const url = new URL(activeTab.url); const domain = url.hostname; document.getElementById('site-name').textContent = domain; const btn = document.getElementById('toggle-btn'); + const themeBtn = document.getElementById('theme-mode-btn'); - chrome.storage.local.get([domain], (result) => { + let hasSpecificTheme = false; + + try { + // Run detection logic inside the tab to match content.js logic + const detectionResult = await chrome.scripting.executeScript({ + target: { tabId: activeTab.id }, + func: () => { + const domain = window.location.hostname; + const isSonarr = getComputedStyle(document.documentElement).getPropertyValue('--sonarrBlue').trim() !== "" || + document.title.toLowerCase().includes('sonarr'); + const isChess = domain.includes('chess.com') || !!document.querySelector('.board-layout-main'); + const isAnilist = domain.includes('anilist.co'); + const isGitea = !!document.querySelector('meta[content*="gitea"]') || domain.includes('gitea'); + const isGithub = domain.includes('github.com'); + + return isSonarr || isChess || isAnilist || isGitea || isGithub; + } + }); + hasSpecificTheme = detectionResult[0]?.result || false; + } catch (e) { + console.warn("Could not inspect page for site-specific theme:", e); + } + + chrome.storage.local.get([domain, `${domain}_mode`], (result) => { const isDisabled = result[domain] === 'disabled'; - btn.textContent = isDisabled ? "Enable on this site" : "Disable on this site"; + btn.textContent = isDisabled ? "Enable" : "Disable"; btn.onclick = () => { - if (isDisabled) { - chrome.storage.local.remove(domain); - } else { - chrome.storage.local.set({ [domain]: 'disabled' }); - } - chrome.tabs.reload(tabs[0].id); + if (isDisabled) chrome.storage.local.remove(domain); + else chrome.storage.local.set({ [domain]: 'disabled' }); + chrome.tabs.reload(activeTab.id); window.close(); }; + + if (hasSpecificTheme && !isDisabled) { + themeBtn.style.display = 'block'; + const isGlobalMode = result[`${domain}_mode`] === 'global'; + themeBtn.textContent = isGlobalMode ? "Site Theme" : "Static Theme"; + + themeBtn.onclick = () => { + const newMode = isGlobalMode ? 'site' : 'global'; + chrome.storage.local.set({ [`${domain}_mode`]: newMode }); + chrome.tabs.reload(activeTab.id); + window.close(); + }; + } }); }); \ No newline at end of file