diff --git a/background.js b/background.js index 2439da5..127e3c1 100644 --- a/background.js +++ b/background.js @@ -107,41 +107,6 @@ chrome.runtime.onInstalled.addListener(async function (detail) { } }); -if (chrome.declarativeNetRequest) { - // In Manifest v3: - // Whenever stored settings change, update the header - // that is sent to BreezeWiki instances to inform them the user has IWB - updateDeclarativeRule(); - chrome.storage.onChanged.addListener(event => updateDeclarativeRule()); -} else { - // In Manifest v2: - // On main frame BreezeWiki requests, update the header - // that is sent to BreezeWiki instances to inform them the user has IWB - chrome.webRequest.onBeforeSendHeaders.addListener(async (details) => - addHeaderToRequest(details), - { - urls: [ - '*://breezewiki.com/*', - '*://antifandom.com/*', - '*://bw.projectsegfau.lt/*', - '*://breeze.hostux.net/*', - '*://breezewiki.pussthecat.org/*', - '*://bw.vern.cc/*', - '*://breezewiki.esmailelbob.xyz/*', - '*://bw.artemislena.eu/*', - '*://bw.hamstro.dev/*', - '*://nerd.whatever.social/*', - '*://breeze.nohost.network/*', - '*://breeze.whateveritworks.org/*' - ], - types: [ - 'main_frame' - ] - }, - ["blocking", "requestHeaders"] - ); -} - function setPowerIcon(status) { const manifestVersion = chrome.runtime.getManifest().manifest_version; if (status === 'on') { @@ -159,20 +124,11 @@ function setPowerIcon(status) { } } -function addHeaderToRequest(details) { - return new Promise((resolve) => { - chrome.storage.local.get(async (localStorage) => { - await chrome.storage.sync.get((syncStorage) => { - const storage = { ...syncStorage, ...localStorage }; - const headerValue = JSON.stringify({ - 'power': storage.power, - 'breezewiki': storage.breezewiki - }); - details.requestHeaders.push({ name: 'x-indie-wiki', value: headerValue }); - resolve({ requestHeaders: details.requestHeaders }); - }); - }); - }); +if (chrome.declarativeNetRequest) { + // Whenever stored settings change, update the header + // that is sent to BreezeWiki instances to inform them the user has IWB + updateDeclarativeRule(); + chrome.storage.onChanged.addListener(event => updateDeclarativeRule()); } function updateDeclarativeRule() { @@ -183,6 +139,24 @@ function updateDeclarativeRule() { 'power': storage.power ?? 'on', 'breezewiki': storage.breezewiki ?? 'off' }); + let urls = [ + "breezewiki.com", + "antifandom.com", + "bw.projectsegfau.lt", + "breeze.hostux.net", + "breezewiki.pussthecat.org", + "bw.vern.cc", + "breezewiki.esmailelbob.xyz", + "bw.artemislena.eu", + "bw.hamstro.dev", + "nerd.whatever.social", + "breeze.nohost.network", + "breeze.whateveritworks.org" + ]; + if (storage.breezewikiCustomHost) { + urls.push(storage.breezewikiCustomHost.replace(/^https?:\/\//, '')); + }; + chrome.declarativeNetRequest.updateDynamicRules({ removeRuleIds: [1], addRules: [ @@ -200,20 +174,7 @@ function updateDeclarativeRule() { ] }, "condition": { - "requestDomains": [ - "breezewiki.com", - "antifandom.com", - "bw.projectsegfau.lt", - "breeze.hostux.net", - "breezewiki.pussthecat.org", - "bw.vern.cc", - "breezewiki.esmailelbob.xyz", - "bw.artemislena.eu", - "bw.hamstro.dev", - "nerd.whatever.social", - "breeze.nohost.network", - "breeze.whateveritworks.org" - ], + "requestDomains": urls, "resourceTypes": [ "main_frame" ] @@ -289,7 +250,11 @@ function redirectToBreezeWiki(storage, eventInfo, url) { chrome.storage.sync.set({ 'breezewikiHost': 'https://breezewiki.com' }); }); } else { - processRedirect(storage.breezewikiHost); + if (storage.breezewikiHost === 'CUSTOM') { + processRedirect(storage.breezewikiCustomHost || 'https://breezewiki.com'); + } else { + processRedirect(storage.breezewikiHost); + } } } } diff --git a/content-banners.js b/content-banners.js index aed4501..acc850d 100644 --- a/content-banners.js +++ b/content-banners.js @@ -42,7 +42,7 @@ async function getData() { return sites; } -function displayRedirectBanner(origin, newUrl, id, destinationName, destinationLanguage, storage) { +function displayRedirectBanner(newUrl, id, destinationName, destinationLanguage, storage) { // Output CSS styleString = ` #indie-wiki-banner { @@ -202,10 +202,9 @@ function displayRedirectBanner(origin, newUrl, id, destinationName, destinationL // Ensure banner isn't already outputted if (!document.querySelector(':root > #indie-wiki-banner')) { document.body.insertAdjacentElement('beforeBegin', banner); - // Increment banner count if (storage.breezewiki === 'on') { - if (currentURL.hostname.match(breezewikiRegex)) { + if (currentURL.hostname.match(breezewikiRegex) || (storage.breezewikiHost === 'CUSTOM' && storage.breezewikiCustomHost.includes(currentURL.hostname))) { chrome.storage.sync.set({ 'countAlerts': (storage.countAlerts ?? 0) + 1 }); } } else { @@ -232,7 +231,7 @@ function main() { if (currentURL.pathname.length > 1) { let origin = currentURL; // If on a BreezeWiki site, convert to Fandom link to match with our list of wikis: - if (currentURL.hostname.match(breezewikiRegex)) { + if (currentURL.hostname.match(breezewikiRegex) || (storage.breezewikiHost === 'CUSTOM' && storage.breezewikiCustomHost.includes(currentURL.hostname))) { origin = String(currentURL.pathname).split('/')[1] + '.fandom.com/wiki/'; if (currentURL.search.includes('?q=')) { origin = origin + currentURL.search.substring(3).split('&')[0]; @@ -296,7 +295,7 @@ function main() { const headElement = document.querySelector('head'); if (headElement) { try { - displayRedirectBanner(origin, newURL, site['id'], site['destination'], site['lang'], storage); + displayRedirectBanner(newURL, site['id'], site['destination'], site['lang'], storage); } finally { mutationInstance.disconnect(); } diff --git a/manifest2.json b/manifest2.json index e2bef4f..848ace9 100644 --- a/manifest2.json +++ b/manifest2.json @@ -5,8 +5,9 @@ "permissions": [ "storage", "webRequest", - "webRequestBlocking", + "declarativeNetRequest", "notifications", + "scripting", "https://*.fandom.com/*", "https://*.fextralife.com/*", "https://breezewiki.com/*", @@ -287,6 +288,7 @@ "run_at": "document_start" } ], + "optional_permissions": ["https://*/*"], "applications": { "gecko": { "id": "{cb31ec5d-c49a-4e5a-b240-16c767444f62}" diff --git a/manifest3.json b/manifest3.json index 7e36c31..96d3585 100644 --- a/manifest3.json +++ b/manifest3.json @@ -6,7 +6,8 @@ "storage", "webRequest", "declarativeNetRequest", - "notifications" + "notifications", + "scripting" ], "icons": { "16": "images/logo-16.png", @@ -42,216 +43,7 @@ "data/sitesZH.json" ], "matches": [ - "https://*.fandom.com/*", - "https://*.fextralife.com/*", - "https://breezewiki.com/*", - "https://antifandom.com/*", - "https://bw.projectsegfau.lt/*", - "https://breeze.hostux.net/*", - "https://breezewiki.pussthecat.org/*", - "https://bw.vern.cc/*", - "https://breezewiki.esmailelbob.xyz/*", - "https://bw.artemislena.eu/*", - "https://bw.hamstro.dev/*", - "https://nerd.whatever.social/*", - "https://breeze.nohost.network/*", - "https://breeze.whateveritworks.org/*", - "https://*.bing.com/*", - "https://search.brave.com/*", - "https://*.duckduckgo.com/*", - "https://*.ecosia.org/*", - "https://*.startpage.com/*", - "https://*.search.yahoo.com/*", - "https://www.google.com/*", - "https://www.google.ad/*", - "https://www.google.ae/*", - "https://www.google.com.af/*", - "https://www.google.com.ag/*", - "https://www.google.com.ai/*", - "https://www.google.al/*", - "https://www.google.am/*", - "https://www.google.co.ao/*", - "https://www.google.com.ar/*", - "https://www.google.as/*", - "https://www.google.at/*", - "https://www.google.com.au/*", - "https://www.google.az/*", - "https://www.google.ba/*", - "https://www.google.com.bd/*", - "https://www.google.be/*", - "https://www.google.bf/*", - "https://www.google.bg/*", - "https://www.google.com.bh/*", - "https://www.google.bi/*", - "https://www.google.bj/*", - "https://www.google.com.bn/*", - "https://www.google.com.bo/*", - "https://www.google.com.br/*", - "https://www.google.bs/*", - "https://www.google.bt/*", - "https://www.google.co.bw/*", - "https://www.google.by/*", - "https://www.google.com.bz/*", - "https://www.google.ca/*", - "https://www.google.cd/*", - "https://www.google.cf/*", - "https://www.google.cg/*", - "https://www.google.ch/*", - "https://www.google.ci/*", - "https://www.google.co.ck/*", - "https://www.google.cl/*", - "https://www.google.cm/*", - "https://www.google.cn/*", - "https://www.google.com.co/*", - "https://www.google.co.cr/*", - "https://www.google.com.cu/*", - "https://www.google.cv/*", - "https://www.google.com.cy/*", - "https://www.google.cz/*", - "https://www.google.de/*", - "https://www.google.dj/*", - "https://www.google.dk/*", - "https://www.google.dm/*", - "https://www.google.com.do/*", - "https://www.google.dz/*", - "https://www.google.com.ec/*", - "https://www.google.ee/*", - "https://www.google.com.eg/*", - "https://www.google.es/*", - "https://www.google.com.et/*", - "https://www.google.fi/*", - "https://www.google.com.fj/*", - "https://www.google.fm/*", - "https://www.google.fr/*", - "https://www.google.ga/*", - "https://www.google.ge/*", - "https://www.google.gg/*", - "https://www.google.com.gh/*", - "https://www.google.com.gi/*", - "https://www.google.gl/*", - "https://www.google.gm/*", - "https://www.google.gr/*", - "https://www.google.com.gt/*", - "https://www.google.gy/*", - "https://www.google.com.hk/*", - "https://www.google.hn/*", - "https://www.google.hr/*", - "https://www.google.ht/*", - "https://www.google.hu/*", - "https://www.google.co.id/*", - "https://www.google.ie/*", - "https://www.google.co.il/*", - "https://www.google.im/*", - "https://www.google.co.in/*", - "https://www.google.iq/*", - "https://www.google.is/*", - "https://www.google.it/*", - "https://www.google.je/*", - "https://www.google.com.jm/*", - "https://www.google.jo/*", - "https://www.google.co.jp/*", - "https://www.google.co.ke/*", - "https://www.google.com.kh/*", - "https://www.google.ki/*", - "https://www.google.kg/*", - "https://www.google.co.kr/*", - "https://www.google.com.kw/*", - "https://www.google.kz/*", - "https://www.google.la/*", - "https://www.google.com.lb/*", - "https://www.google.li/*", - "https://www.google.lk/*", - "https://www.google.co.ls/*", - "https://www.google.lt/*", - "https://www.google.lu/*", - "https://www.google.lv/*", - "https://www.google.com.ly/*", - "https://www.google.co.ma/*", - "https://www.google.md/*", - "https://www.google.me/*", - "https://www.google.mg/*", - "https://www.google.mk/*", - "https://www.google.ml/*", - "https://www.google.com.mm/*", - "https://www.google.mn/*", - "https://www.google.ms/*", - "https://www.google.com.mt/*", - "https://www.google.mu/*", - "https://www.google.mv/*", - "https://www.google.mw/*", - "https://www.google.com.mx/*", - "https://www.google.com.my/*", - "https://www.google.co.mz/*", - "https://www.google.com.na/*", - "https://www.google.com.ng/*", - "https://www.google.com.ni/*", - "https://www.google.ne/*", - "https://www.google.nl/*", - "https://www.google.no/*", - "https://www.google.com.np/*", - "https://www.google.nr/*", - "https://www.google.nu/*", - "https://www.google.co.nz/*", - "https://www.google.com.om/*", - "https://www.google.com.pa/*", - "https://www.google.com.pe/*", - "https://www.google.com.pg/*", - "https://www.google.com.ph/*", - "https://www.google.com.pk/*", - "https://www.google.pl/*", - "https://www.google.pn/*", - "https://www.google.com.pr/*", - "https://www.google.ps/*", - "https://www.google.pt/*", - "https://www.google.com.py/*", - "https://www.google.com.qa/*", - "https://www.google.ro/*", - "https://www.google.ru/*", - "https://www.google.rw/*", - "https://www.google.com.sa/*", - "https://www.google.com.sb/*", - "https://www.google.sc/*", - "https://www.google.se/*", - "https://www.google.com.sg/*", - "https://www.google.sh/*", - "https://www.google.si/*", - "https://www.google.sk/*", - "https://www.google.com.sl/*", - "https://www.google.sn/*", - "https://www.google.so/*", - "https://www.google.sm/*", - "https://www.google.sr/*", - "https://www.google.st/*", - "https://www.google.com.sv/*", - "https://www.google.td/*", - "https://www.google.tg/*", - "https://www.google.co.th/*", - "https://www.google.com.tj/*", - "https://www.google.tl/*", - "https://www.google.tm/*", - "https://www.google.tn/*", - "https://www.google.to/*", - "https://www.google.com.tr/*", - "https://www.google.tt/*", - "https://www.google.com.tw/*", - "https://www.google.co.tz/*", - "https://www.google.com.ua/*", - "https://www.google.co.ug/*", - "https://www.google.co.uk/*", - "https://www.google.com.uy/*", - "https://www.google.co.uz/*", - "https://www.google.com.vc/*", - "https://www.google.co.ve/*", - "https://www.google.vg/*", - "https://www.google.co.vi/*", - "https://www.google.com.vn/*", - "https://www.google.vu/*", - "https://www.google.ws/*", - "https://www.google.rs/*", - "https://www.google.co.za/*", - "https://www.google.co.zm/*", - "https://www.google.co.zw/*", - "https://www.google.cat/*" + "https://*/*" ] } ], @@ -502,5 +294,6 @@ "https://breeze.nohost.network/*", "https://breeze.whateveritworks.org/*" ], + "optional_host_permissions": ["https://*/*"], "manifest_version": 3 } diff --git a/popup.html b/popup.html index 194ecc6..b275611 100644 --- a/popup.html +++ b/popup.html @@ -56,10 +56,6 @@ gap: .5em; } - fieldset+fieldset { - margin-top: 1rem; - } - fieldset>div { margin: 0 .5rem; } @@ -157,7 +153,7 @@ /* CONTENT */ #content { - padding: 1em; + padding: .5em 1em; background-color: #e5f4ff; box-sizing: border-box; } @@ -175,6 +171,10 @@ width: 100%; } + .options label { + display: inline-block; + } + .settingToggle { cursor: pointer; width: fit-content; @@ -190,7 +190,41 @@ #breezewikiHost { display: none; - padding-left: 3em; + padding: 0 0 0 1rem; + } + + #breezewikiHost label { + cursor: default; + } + + #breezewikiHost button { + background: #3174f1; + border: 1px solid #333333; + color: #fff; + border-radius: 5px; + padding: .3em; + font-size: .9em; + } + + #breezewikiHost button:hover { + cursor: pointer; + background: #ffffff; + border: 1px solid#3174f1; + color: #3174f1; + } + + #breezewikiHost label+label { + margin-top: 8px; + } + + #breezewikiCustomHost { + display: none; + } + + #breezewikiCustomHostStatus { + display: block; + padding-top: .4em; + font-size: .9em; } /* SETTINGS BUTTON */ @@ -205,7 +239,7 @@ color: #fff; border-radius: 5px; padding: .4em; - margin: .5em 0 0 0; + margin: .2em 0 0 0; font-size: 1.3em; } @@ -280,7 +314,7 @@
- When using search engines: + On search engines, when you see non-indie results with indie alternatives:
+
diff --git a/popup.js b/popup.js index 84624b7..65c8d3d 100644 --- a/popup.js +++ b/popup.js @@ -93,10 +93,10 @@ async function migrateData() { }); } -function populateBreezewikiHosts(breezewikiHosts, selectedHost) { +function populateBreezewikiHosts(breezewikiHosts, selectedHost, customHostName) { // Populate dropdown selection of hosts const breezewikiHostSelect = document.getElementById('breezewikiHostSelect'); - while (breezewikiHostSelect.childElementCount > 1) { + while (breezewikiHostSelect.firstChild) { // Remove any existing options breezewikiHostSelect.removeChild(breezewikiHostSelect.firstChild); } @@ -111,20 +111,34 @@ function populateBreezewikiHosts(breezewikiHosts, selectedHost) { textContent = textContent.substring(textContent.indexOf('.') + 1); } option.textContent = textContent; - breezewikiHostSelect.prepend(option); - if (option.value === selectedHost) { - breezewikiHostSelect.value = selectedHost; - } + breezewikiHostSelect.appendChild(option); } + + // Add custom BreezeWiki host option: + let customOption = document.createElement('option'); + customOption.value = 'CUSTOM'; + customOption.textContent = 'Custom host...'; + breezewikiHostSelect.appendChild(customOption); + breezewikiHostSelect.value = selectedHost; + + // Set up custom domain input: + if (breezewikiHostSelect.value === 'CUSTOM') { + document.getElementById('breezewikiCustomHost').style.display = 'block'; + } else { + document.getElementById('breezewikiCustomHost').style.display = 'none'; + } + document.getElementById('customBreezewikiHost').value = customHostName.replace(/^https?:\/\//i, ''); } // Populate BreezeWiki dropdown when enabled -async function loadBreezeWikiOptions() { +async function loadBreezewikiOptions() { // Load BreezeWiki options: - chrome.storage.sync.get(['breezewikiHostOptions', 'breezewikiHostFetchTimestamp', 'breezewikiHost'], function (item) { + chrome.storage.sync.get(['breezewikiHostOptions', 'breezewikiHostFetchTimestamp', 'breezewikiHost', 'breezewikiCustomHost'], function (item) { let hostOptions = item.breezewikiHostOptions; let hostFetchTimestamp = item.breezewikiHostFetchTimestamp; let host = item.breezewikiHost; + let customHost = item.breezewikiCustomHost || ''; + // Fetch and cache list of BreezeWiki hosts if first time, // or if it has been 24 hrs since last refresh if (!host || !hostOptions || !hostFetchTimestamp || (Date.now() - 86400000 > hostFetchTimestamp)) { @@ -156,8 +170,7 @@ async function loadBreezeWikiOptions() { } } } - - populateBreezewikiHosts(breezewikiHosts, host); + populateBreezewikiHosts(breezewikiHosts, host, customHost); // Store BreezeWiki host details chrome.storage.sync.set({ 'breezewikiHost': host }); @@ -173,11 +186,11 @@ async function loadBreezeWikiOptions() { }); } else { // If currently selected host is no longer available, select random host: - if (!hostOptions.some(item => item.instance === host)) { + if (host !== 'CUSTOM' && !hostOptions.some(item => item.instance === host)) { host = hostOptions[Math.floor(Math.random() * hostOptions.length)].instance; } - populateBreezewikiHosts(hostOptions, host); + populateBreezewikiHosts(hostOptions, host, customHost); // Store BreezeWiki host details chrome.storage.sync.set({ 'breezewikiHost': host }); @@ -268,7 +281,7 @@ function setBreezeWiki(setting, storeSetting = true) { } else { document.getElementById('breezewikiCheckbox').checked = false; } - var breezewikiHost = document.getElementById('breezewikiHost'); + const breezewikiHost = document.getElementById('breezewikiHost'); if (setting === 'on') { breezewikiHost.style.display = 'block'; chrome.storage.sync.get({ 'breezewikiHost': null }, function (host) { @@ -351,8 +364,6 @@ document.addEventListener('DOMContentLoaded', function () { }); } - loadBreezeWikiOptions(); - // Listener for settings page in new tab: document.getElementById('openSettings').addEventListener('click', function () { chrome.tabs.create({ 'url': chrome.runtime.getURL('settings.html') }); @@ -374,11 +385,11 @@ document.addEventListener('DOMContentLoaded', function () { // Load BreezeWiki options if BreezeWiki is enabled if (item.breezewiki === 'on') { - loadBreezeWikiOptions(); + loadBreezewikiOptions(); } }); - // Add event listeners for setting toggles + // Add event listeners for general setting toggles document.getElementById('powerCheckbox').addEventListener('change', function () { chrome.storage.local.get({ 'power': 'on' }, function (item) { if (item.power === 'on') { @@ -406,20 +417,33 @@ document.addEventListener('DOMContentLoaded', function () { } }); }); + + // Add event listeners for BreezeWiki settings document.getElementById('breezewikiCheckbox').addEventListener('change', function () { chrome.storage.sync.get({ 'breezewiki': 'off' }, function (item) { if (item.breezewiki === 'on') { setBreezeWiki('off'); } else { setBreezeWiki('on'); - loadBreezeWikiOptions(); + loadBreezewikiOptions(); } }); }); - var breezewikiHostSelect = document.getElementById("breezewikiHostSelect"); + const breezewikiHostSelect = document.getElementById('breezewikiHostSelect'); breezewikiHostSelect.addEventListener('change', function () { + if (breezewikiHostSelect.value === 'CUSTOM') { + document.getElementById('breezewikiCustomHost').style.display = 'block'; + } else { + document.getElementById('breezewikiCustomHost').style.display = 'none'; + } chrome.storage.sync.set({ 'breezewikiHost': breezewikiHostSelect.value }); }); + + document.options.addEventListener("submit", function(e) { + e.preventDefault(); + return false; + }); + document.querySelectorAll('[name="defaultWikiAction"]').forEach((el) => { el.addEventListener('change', async function () { chrome.storage.sync.set({ 'defaultWikiAction': document.options.defaultWikiAction.value }) diff --git a/settings.html b/settings.html index ed98783..4a56a0d 100644 --- a/settings.html +++ b/settings.html @@ -187,6 +187,10 @@ width: 100%; } + .options label { + display: inline-block; + } + .settingToggle { width: fit-content; } @@ -208,6 +212,34 @@ cursor: default; } + #breezewikiHost button { + background: #3174f1; + border: 1px solid #333333; + color: #fff; + border-radius: 5px; + padding: .3em; + font-size: .9em; + } + + #breezewikiHost button:hover { + cursor: pointer; + background: #ffffff; + border: 1px solid#3174f1; + color: #3174f1; + } + + #breezewikiHost label+label { + margin-top: 8px; + } + + #breezewikiCustomHost { + display: none; + } + + #breezewikiCustomHostStatus { + font-size: .9em; + } + #legend div, #legend span { padding: 0 0 4px 8px; @@ -554,6 +586,14 @@ BreezeWiki host: +

Individual wiki settings

diff --git a/settings.js b/settings.js index 39f34dc..3b8726c 100644 --- a/settings.js +++ b/settings.js @@ -41,12 +41,12 @@ async function getData() { return sites; } -function populateBreezewikiHosts(breezewikiHosts, selectedHost) { +function populateBreezewikiHosts(breezewikiHosts, selectedHost, customHostName) { // Populate dropdown selection of hosts const breezewikiHostSelect = document.getElementById('breezewikiHostSelect'); while (breezewikiHostSelect.firstChild) { // Remove any existing options - breezewikiHostSelect.removeChild(breezewikiHostSelect.lastChild); + breezewikiHostSelect.removeChild(breezewikiHostSelect.firstChild); } // Add known BreezeWiki domains: @@ -60,19 +60,33 @@ function populateBreezewikiHosts(breezewikiHosts, selectedHost) { } option.textContent = textContent; breezewikiHostSelect.appendChild(option); - if (option.value === selectedHost) { - breezewikiHostSelect.value = selectedHost; - } } + + // Add custom BreezeWiki host option: + let customOption = document.createElement('option'); + customOption.value = 'CUSTOM'; + customOption.textContent = 'Custom host...'; + breezewikiHostSelect.appendChild(customOption); + breezewikiHostSelect.value = selectedHost; + + // Set up custom domain input: + if (breezewikiHostSelect.value === 'CUSTOM') { + document.getElementById('breezewikiCustomHost').style.display = 'block'; + } else { + document.getElementById('breezewikiCustomHost').style.display = 'none'; + } + document.getElementById('customBreezewikiHost').value = customHostName.replace(/^https?:\/\//i, ''); } // Populate BreezeWiki dropdown when enabled -async function loadBreezeWikiOptions() { +async function loadBreezewikiOptions() { // Load BreezeWiki options: - chrome.storage.sync.get(['breezewikiHostOptions', 'breezewikiHostFetchTimestamp', 'breezewikiHost'], function (item) { + chrome.storage.sync.get(['breezewikiHostOptions', 'breezewikiHostFetchTimestamp', 'breezewikiHost', 'breezewikiCustomHost'], function (item) { let hostOptions = item.breezewikiHostOptions; let hostFetchTimestamp = item.breezewikiHostFetchTimestamp; let host = item.breezewikiHost; + let customHost = item.breezewikiCustomHost || ''; + // Fetch and cache list of BreezeWiki hosts if first time, // or if it has been 24 hrs since last refresh if (!host || !hostOptions || !hostFetchTimestamp || (Date.now() - 86400000 > hostFetchTimestamp)) { @@ -104,8 +118,7 @@ async function loadBreezeWikiOptions() { } } } - - populateBreezewikiHosts(breezewikiHosts, host); + populateBreezewikiHosts(breezewikiHosts, host, customHost); // Store BreezeWiki host details chrome.storage.sync.set({ 'breezewikiHost': host }); @@ -121,11 +134,11 @@ async function loadBreezeWikiOptions() { }); } else { // If currently selected host is no longer available, select random host: - if (!hostOptions.some(item => item.instance === host)) { + if (host !== 'CUSTOM' && !hostOptions.some(item => item.instance === host)) { host = hostOptions[Math.floor(Math.random() * hostOptions.length)].instance; } - populateBreezewikiHosts(hostOptions, host); + populateBreezewikiHosts(hostOptions, host, customHost); // Store BreezeWiki host details chrome.storage.sync.set({ 'breezewikiHost': host }); @@ -152,13 +165,6 @@ async function loadOptions(lang) { let defaultWikiAction = storage.defaultWikiAction || null; let defaultSearchAction = storage.defaultSearchAction || null; - // Load BreezeWiki options: - chrome.storage.sync.get(['breezewiki'], function (item) { - if (item.breezewiki === 'on') { - loadBreezeWikiOptions(); - } - }); - // Load defaults for newly added wikis: chrome.storage.sync.get(['defaultWikiAction'], function (item) { if (item.defaultWikiAction === 'disabled') { @@ -557,14 +563,14 @@ function setBreezeWiki(setting, storeSetting = true) { if (storeSetting) { chrome.storage.sync.set({ 'breezewiki': setting }); } - const breezewikiHost = document.getElementById('breezewikiHost'); if (setting === 'on') { document.getElementById('breezewikiCheckbox').checked = true; } else { document.getElementById('breezewikiCheckbox').checked = false; } + const breezewikiHost = document.getElementById('breezewikiHost'); if (setting === 'on') { - breezewikiHost.style.display = 'inline-block'; + breezewikiHost.style.display = 'block'; chrome.storage.sync.get({ 'breezewikiHost': null }, function (host) { if (!host.breezewikiHost) { fetch('https://bw.getindie.wiki/instances.json') @@ -776,6 +782,11 @@ document.addEventListener('DOMContentLoaded', function () { }); chrome.storage.sync.get({ 'breezewiki': 'off' }, function (item) { setBreezeWiki(item.breezewiki, false); + + // Load BreezeWiki options if BreezeWiki is enabled + if (item.breezewiki === 'on') { + loadBreezewikiOptions(); + } }); // Add event listeners for general setting toggles @@ -823,15 +834,64 @@ document.addEventListener('DOMContentLoaded', function () { setBreezeWiki('off'); } else { setBreezeWiki('on'); - loadBreezeWikiOptions(); + loadBreezewikiOptions(); } }); }); const breezewikiHostSelect = document.getElementById('breezewikiHostSelect'); breezewikiHostSelect.addEventListener('change', function () { + if (breezewikiHostSelect.value === 'CUSTOM') { + document.getElementById('breezewikiCustomHost').style.display = 'block'; + document.getElementById('breezewikiCustomHostStatus').innerText = ''; + } else { + document.getElementById('breezewikiCustomHost').style.display = 'none'; + } chrome.storage.sync.set({ 'breezewikiHost': breezewikiHostSelect.value }); }); + function setCustomBreezewikiDomain() { + let breezewikiCustomDomain = document.getElementById('customBreezewikiHost').value; + // Add "https://" if not already present + if (!/^https?:\/\//i.test(breezewikiCustomDomain)) { + breezewikiCustomDomain = 'https://' + breezewikiCustomDomain; + } + // Reduce to just protocal + hostname + breezewikiCustomDomain = new URL(breezewikiCustomDomain); + breezewikiCustomDomain = breezewikiCustomDomain.protocol + "//" + breezewikiCustomDomain.hostname + breezewikiCustomDomain = breezewikiCustomDomain.toString(); + + chrome.permissions.request({ + origins: [breezewikiCustomDomain + '/*'] + }, (granted) => { + // The callback argument will be true if the user granted the permissions. + if (granted) { + chrome.scripting.registerContentScripts([{ + id: 'content-banners', + matches: [breezewikiCustomDomain + '/*'], + js: ['content-banners.js'], + runAt: "document_start" + }]); + chrome.storage.sync.set({ 'breezewikiCustomHost': breezewikiCustomDomain }); + document.getElementById('breezewikiCustomHostStatus').innerText = 'Successfully added'; + } else { + document.getElementById('breezewikiCustomHostStatus').innerText = 'Failed to set host'; + } + }); + } + + document.getElementById('setCustomBreezewikiDomain').addEventListener('click', function () { + setCustomBreezewikiDomain(); + }); + document.getElementById('customBreezewikiHost').onkeyup = function(e) { + if (e.key === 'Enter') { + setCustomBreezewikiDomain(); + } + } + document.options.addEventListener("submit", function(e) { + e.preventDefault(); + return false; + }); + // Add event listeners for default action selections document.querySelectorAll('[name="defaultWikiAction"]').forEach((el) => { el.addEventListener('change', function () {