Add search engine toggling / Search engine filtering fixes / Disabling SearNGX+Whoogle

More details at https://github.com/KevinPayravi/indie-wiki-buddy/pull/648
pull/650/head
Kevin Payravi 2024-04-22 22:18:42 -07:00 committed by GitHub
parent 635e62f963
commit 3a75724520
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 539 additions and 291 deletions

View File

@ -4,9 +4,29 @@ if (typeof importScripts !== 'undefined') {
let cachedStorage = {};
function getLocalStorageData() {
// Wrap the extensionAPI.storage.sync.get method in a promise
// Needed for Firefox manifest v2
return new Promise((resolve, reject) => {
extensionAPI.storage.local.get(null, (items) => {
resolve(items);
});
});
}
function getSyncStorageData() {
// Wrap the extensionAPI.storage.sync.get method in a promise
// Needed for Firefox manifest v2
return new Promise((resolve, reject) => {
extensionAPI.storage.sync.get(null, (items) => {
resolve(items);
});
});
}
async function updateCachedStorage() {
let localStorage = await chrome.storage.local.get();
let syncStorage = await chrome.storage.sync.get();
let localStorage = await getLocalStorageData();
let syncStorage = await getSyncStorageData();
cachedStorage = {...localStorage, ...syncStorage};
}
@ -21,11 +41,11 @@ async function getCachedStorage() {
updateCachedStorage();
// Capture web requests
chrome.webRequest.onBeforeSendHeaders.addListener(
extensionAPI.webRequest.onBeforeSendHeaders.addListener(
async (event) => {
if (event.documentLifecycle !== 'prerender') {
if (event.frameType === 'sub_frame') {
let tabInfo = await chrome.tabs.get(event.tabId);
let tabInfo = await extensionAPI.tabs.get(event.tabId);
main(tabInfo.url, event.tabId);
} else {
main(event.url, event.tabId);
@ -36,45 +56,46 @@ chrome.webRequest.onBeforeSendHeaders.addListener(
);
// Listen for user turning extension on or off, to update icon
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
extensionAPI.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
if (msg.action === 'updateIcon') {
setPowerIcon(msg.value);
} else if (msg.action === 'getStorage') {
getCachedStorage().then((res) => {
sendResponse(res)
sendResponse(res);
return res;
});
return true;
}
});
// Listen for browser starting, to set initial icon state
chrome.runtime.onStartup.addListener(() => {
chrome.storage.local.get({ 'power': 'on' }, (item) => {
extensionAPI.runtime.onStartup.addListener(() => {
extensionAPI.storage.local.get({ 'power': 'on' }, (item) => {
setPowerIcon(item.power);
});
});
// Listen for changes to stored data, and updated our cached data
chrome.storage.onChanged.addListener(() => {
extensionAPI.storage.onChanged.addListener(() => {
updateCachedStorage();
})
// Listen for extension installed/updating
chrome.runtime.onInstalled.addListener(async (detail) => {
extensionAPI.runtime.onInstalled.addListener(async (detail) => {
// Set initial icon state
chrome.storage.local.get({ 'power': 'on' }, (item) => {
extensionAPI.storage.local.get({ 'power': 'on' }, (item) => {
setPowerIcon(item.power);
});
// If new install, open settings with starter guide
if (detail.reason === 'install') {
chrome.tabs.create({ url: 'pages/settings/index.html?newinstall=true' });
extensionAPI.tabs.create({ url: 'pages/settings/index.html?newinstall=true' });
}
// If update, open changelog if setting is enabled
chrome.storage.sync.get({ 'openChangelog': 'off' }, (item) => {
extensionAPI.storage.sync.get({ 'openChangelog': 'off' }, (item) => {
if (item.openChangelog === 'on' && detail.reason === 'update') {
chrome.tabs.create({ url: 'https://getindie.wiki/changelog/?updated=true', active: false });
extensionAPI.tabs.create({ url: 'https://getindie.wiki/changelog/?updated=true', active: false });
}
});
@ -85,18 +106,18 @@ chrome.runtime.onInstalled.addListener(async (detail) => {
});
function setPowerIcon(status) {
const manifestVersion = chrome.runtime.getManifest().manifest_version;
const manifestVersion = extensionAPI.runtime.getManifest().manifest_version;
if (status === 'on') {
if (manifestVersion === 2) {
chrome.browserAction.setIcon({ path: "/images/logo-128.png" });
extensionAPI.browserAction.setIcon({ path: "/images/logo-128.png" });
} else {
chrome.action.setIcon({ path: "/images/logo-128.png" });
extensionAPI.action.setIcon({ path: "/images/logo-128.png" });
}
} else {
if (manifestVersion === 2) {
chrome.browserAction.setIcon({ path: "/images/logo-off.png" });
extensionAPI.browserAction.setIcon({ path: "/images/logo-off.png" });
} else {
chrome.action.setIcon({ path: "/images/logo-off.png" });
extensionAPI.action.setIcon({ path: "/images/logo-off.png" });
}
}
}
@ -111,25 +132,25 @@ function redirectToBreezeWiki(storage, tabId, url) {
// Perform redirect
if (article) {
chrome.tabs.update(tabId, { url: host + '/' + subdomain + '/wiki/' + article });
extensionAPI.tabs.update(tabId, { url: host + '/' + subdomain + '/wiki/' + article });
} else {
chrome.tabs.update(tabId, { url: host + '/' + subdomain });
extensionAPI.tabs.update(tabId, { url: host + '/' + subdomain });
}
// Increase BreezeWiki stat count
chrome.storage.sync.set({ 'countBreezeWiki': (storage.countBreezeWiki ?? 0) + 1 });
extensionAPI.storage.sync.set({ 'countBreezeWiki': (storage.countBreezeWiki ?? 0) + 1 });
if ((storage.notifications ?? 'on') === 'on') {
// Notify that user is being redirected to BreezeWiki
let notifID = 'independent-wiki-redirector-notification-' + Math.floor(Math.random() * 1E16);
chrome.notifications.create(notifID, {
extensionAPI.notifications.create(notifID, {
"type": "basic",
"iconUrl": 'images/logo-48.png',
"title": "You've been redirected to BreezeWiki!",
"message": "Indie Wiki Buddy has sent you to BreezeWiki for a cleaner, ad-free experience on Fandom."
});
// Self-clear notification after 6 seconds
setTimeout(() => { chrome.notifications.clear(notifID); }, 6000);
setTimeout(() => { extensionAPI.notifications.clear(notifID); }, 6000);
}
}
@ -143,7 +164,7 @@ function redirectToBreezeWiki(storage, tabId, url) {
throw new Error('Indie Wiki Buddy failed to get BreezeWiki data.');
}).then((breezewikiHosts) => {
breezewikiHosts = breezewikiHosts.filter(host =>
chrome.runtime.getManifest().version.localeCompare(host.iwb_version,
extensionAPI.runtime.getManifest().version.localeCompare(host.iwb_version,
undefined,
{ numeric: true, sensitivity: 'base' }
) >= 0
@ -151,21 +172,21 @@ function redirectToBreezeWiki(storage, tabId, url) {
// Check if BreezeWiki's main site is available
let breezewikiMain = breezewikiHosts.filter(host => host.instance === 'https://breezewiki.com');
if (breezewikiMain.length > 0) {
chrome.storage.sync.set({ 'breezewikiHost': breezewikiMain[0].instance });
extensionAPI.storage.sync.set({ 'breezewikiHost': breezewikiMain[0].instance });
} else {
// If BreezeWiki.com is not available, set to a random mirror
try {
chrome.storage.sync.set({ 'breezewikiHost': breezewikiHosts[Math.floor(Math.random() * breezewikiHosts.length)].instance });
extensionAPI.storage.sync.set({ 'breezewikiHost': breezewikiHosts[Math.floor(Math.random() * breezewikiHosts.length)].instance });
} catch (e) {
console.log('Indie Wiki Buddy failed to get BreezeWiki data: ' + e);
}
}
chrome.storage.sync.set({ 'breezewikiHostOptions': breezewikiHosts });
chrome.storage.sync.set({ 'breezewikiHostFetchTimestamp': Date.now() });
extensionAPI.storage.sync.set({ 'breezewikiHostOptions': breezewikiHosts });
extensionAPI.storage.sync.set({ 'breezewikiHostFetchTimestamp': Date.now() });
processRedirect(host);
}).catch((e) => {
console.log('Indie Wiki Buddy failed to get BreezeWiki data: ' + e);
chrome.storage.sync.set({ 'breezewikiHost': 'https://breezewiki.com' });
extensionAPI.storage.sync.set({ 'breezewikiHost': 'https://breezewiki.com' });
});
} else {
if (storage.breezewikiHost === 'CUSTOM') {
@ -195,23 +216,23 @@ async function main(url, tabId) {
let newURL = commonFunctionGetNewURL(url, matchingSite);
// Perform redirect
chrome.tabs.update(tabId, { url: newURL });
extensionAPI.tabs.update(tabId, { url: newURL });
// Increase redirect count
chrome.storage.sync.set({ 'countRedirects': (storage.countRedirects ?? 0) + 1 });
extensionAPI.storage.sync.set({ 'countRedirects': (storage.countRedirects ?? 0) + 1 });
// Notify if enabled
if ((storage.notifications ?? 'on') === 'on') {
// Notify that user is being redirected
let notifID = 'independent-wiki-redirector-notification-' + Math.floor(Math.random() * 1E16);
chrome.notifications.create(notifID, {
extensionAPI.notifications.create(notifID, {
"type": "basic",
"iconUrl": 'images/logo-48.png',
"title": "You've been redirected!",
"message": "Indie Wiki Buddy has sent you from " + matchingSite['origin'] + " to " + matchingSite['destination']
});
// Self-clear notification after 6 seconds
setTimeout(() => { chrome.notifications.clear(notifID); }, 6000);
setTimeout(() => { extensionAPI.notifications.clear(notifID); }, 6000);
}
} else if ((storage.breezewiki ?? 'off') === 'on' || (storage.breezewiki ?? 'off') === 'redirect') {
redirectToBreezeWiki(storage, tabId, url);

View File

@ -46,6 +46,11 @@ a:visited {
color: var(--text-link-color);
}
fieldset hr {
color: var(--base-color-outline-light);
background-color: var(--base-color-outline-light);
margin: 2px;
}
hr {
height: 1px;
border: none;
@ -197,6 +202,9 @@ select {
.options label {
display: inline-block;
}
.searchEngineToggles label {
white-space: nowrap;
}
.settingToggle {
width: fit-content;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 B

After

Width:  |  Height:  |  Size: 152 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 735 B

After

Width:  |  Height:  |  Size: 649 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 879 B

After

Width:  |  Height:  |  Size: 779 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 967 B

After

Width:  |  Height:  |  Size: 962 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 B

After

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 241 B

After

Width:  |  Height:  |  Size: 235 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 729 B

After

Width:  |  Height:  |  Size: 728 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 793 B

After

Width:  |  Height:  |  Size: 782 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 868 B

After

Width:  |  Height:  |  Size: 786 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1004 B

After

Width:  |  Height:  |  Size: 789 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 329 B

After

Width:  |  Height:  |  Size: 320 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 327 B

After

Width:  |  Height:  |  Size: 317 B

BIN
images/toggle-banner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 499 B

After

Width:  |  Height:  |  Size: 492 B

BIN
images/toggle-move-up.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 348 B

After

Width:  |  Height:  |  Size: 336 B

BIN
images/toggles.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 774 B

View File

@ -1,23 +1,23 @@
// Set setting toggle values on-load:
chrome.storage.local.get({ 'power': 'on' }, (item) => {
extensionAPI.storage.local.get({ 'power': 'on' }, (item) => {
setPower(item.power, false);
});
chrome.storage.sync.get({ 'notifications': 'on' }, (item) => {
extensionAPI.storage.sync.get({ 'notifications': 'on' }, (item) => {
setNotifications(item.notifications, false);
});
chrome.storage.sync.get({ 'hiddenResultsBanner': 'on' }, (item) => {
extensionAPI.storage.sync.get({ 'hiddenResultsBanner': 'on' }, (item) => {
setHiddenResultsBanner(item.hiddenResultsBanner, false);
});
chrome.storage.sync.get({ 'crossLanguage': 'off' }, (item) => {
extensionAPI.storage.sync.get({ 'crossLanguage': 'off' }, (item) => {
setCrossLanguage(item.crossLanguage, false);
});
chrome.storage.sync.get({ 'reorderResults': 'on' }, (item) => {
extensionAPI.storage.sync.get({ 'reorderResults': 'on' }, (item) => {
setReorder(item.reorderResults, false);
});
chrome.storage.sync.get({ 'openChangelog': 'off' }, (item) => {
extensionAPI.storage.sync.get({ 'openChangelog': 'off' }, (item) => {
setOpenChangelog(item.openChangelog, false);
});
chrome.storage.sync.get({ 'breezewiki': 'off' }, (item) => {
extensionAPI.storage.sync.get({ 'breezewiki': 'off' }, (item) => {
// Account for legacy 'on' setting for BreezeWiki
if (item.breezewiki === 'on') {
setBreezeWiki('redirect');
@ -33,7 +33,7 @@ chrome.storage.sync.get({ 'breezewiki': 'off' }, (item) => {
// Add event listener for power toggle
document.getElementById('powerCheckbox').addEventListener('change', () => {
chrome.storage.local.get({ 'power': 'on' }, (item) => {
extensionAPI.storage.local.get({ 'power': 'on' }, (item) => {
if (item.power === 'on') {
setPower('off');
} else {
@ -42,10 +42,49 @@ document.getElementById('powerCheckbox').addEventListener('change', () => {
});
});
// Event listeners for toggling search engines
const searchEngineToggles = document.querySelectorAll('.searchEngineToggles label');
searchEngineToggles.forEach((engine) => {
let engineInput = engine.querySelector('input');
let engineName = engineInput.getAttribute('data-search-engine');
engine.addEventListener('change', () => {
if (engineInput.checked) {
extensionAPI.storage.sync.get({'searchEngineToggles': {}}, (settings) => {
settings.searchEngineToggles[engineName] = 'on';
extensionAPI.storage.sync.set({
'searchEngineToggles': settings.searchEngineToggles
});
});
engineInput.checked = true;
} else {
extensionAPI.storage.sync.get( { 'searchEngineToggles': {} }, (settings) => {
settings.searchEngineToggles[engineName] = 'off';
extensionAPI.storage.sync.set({
'searchEngineToggles': settings.searchEngineToggles
});
});
engineInput.checked = false;
}
});
});
document.querySelectorAll('.searchEngineToggles input').forEach((el) => {
const searchEngineName = el.getAttribute('data-search-engine');
extensionAPI.storage.sync.get({
'searchEngineToggles': {}
}, (settings) => {
if (settings.searchEngineToggles[searchEngineName] === 'on' || !settings.searchEngineToggles.hasOwnProperty(searchEngineName)) {
el.checked = true;
} else {
el.checked = false;
}
});
});
// Set notifications setting
function setNotifications(setting, storeSetting = true) {
if (storeSetting) {
chrome.storage.sync.set({ 'notifications': setting });
extensionAPI.storage.sync.set({ 'notifications': setting });
}
const notificationsIcon = document.getElementById('notificationsIcon');
if (setting === 'on') {
@ -60,22 +99,19 @@ function setNotifications(setting, storeSetting = true) {
// Set search results hidden banner setting
function setHiddenResultsBanner(setting, storeSetting = true) {
if (storeSetting) {
chrome.storage.sync.set({ 'hiddenResultsBanner': setting });
extensionAPI.storage.sync.set({ 'hiddenResultsBanner': setting });
}
const hiddenResultsBannerIcon = document.getElementById('hiddenResultsBannerIcon');
if (setting === 'on') {
document.getElementById('hiddenResultsBannerCheckbox').checked = true;
hiddenResultsBannerIcon.innerText = '🔔';
} else {
document.getElementById('hiddenResultsBannerCheckbox').checked = false;
hiddenResultsBannerIcon.innerText = '🔕';
}
}
// Set cross-language setting
function setCrossLanguage(setting, storeSetting = true) {
if (storeSetting) {
chrome.storage.sync.set({ 'crossLanguage': setting });
extensionAPI.storage.sync.set({ 'crossLanguage': setting });
}
const crossLanguageIcon = document.getElementById('crossLanguageIcon');
@ -91,7 +127,7 @@ function setCrossLanguage(setting, storeSetting = true) {
// Set re-order setting
function setReorder(setting, storeSetting = true) {
if (storeSetting) {
chrome.storage.sync.set({ 'reorderResults': setting });
extensionAPI.storage.sync.set({ 'reorderResults': setting });
}
if (setting === 'on') {
@ -104,7 +140,7 @@ function setReorder(setting, storeSetting = true) {
// Set open changelog setting
function setOpenChangelog(setting, storeSetting = true) {
if (storeSetting) {
chrome.storage.sync.set({ 'openChangelog': setting });
extensionAPI.storage.sync.set({ 'openChangelog': setting });
}
const openChangelogIcon = document.getElementById('openChangelogIcon');
@ -119,7 +155,7 @@ function setOpenChangelog(setting, storeSetting = true) {
// Event listeners for general setting toggles
document.getElementById('notificationsCheckbox').addEventListener('change', () => {
chrome.storage.sync.get({ 'notifications': 'on' }, (item) => {
extensionAPI.storage.sync.get({ 'notifications': 'on' }, (item) => {
if (item.notifications === 'on') {
setNotifications('off');
} else {
@ -128,7 +164,7 @@ document.getElementById('notificationsCheckbox').addEventListener('change', () =
});
});
document.getElementById('hiddenResultsBannerCheckbox').addEventListener('change', () => {
chrome.storage.sync.get({ 'hiddenResultsBanner': 'on' }, (item) => {
extensionAPI.storage.sync.get({ 'hiddenResultsBanner': 'on' }, (item) => {
if (item.hiddenResultsBanner === 'on') {
setHiddenResultsBanner('off');
} else {
@ -137,7 +173,7 @@ document.getElementById('hiddenResultsBannerCheckbox').addEventListener('change'
});
});
document.getElementById('crossLanguageCheckbox').addEventListener('change', () => {
chrome.storage.sync.get({ 'crossLanguage': 'off' }, (item) => {
extensionAPI.storage.sync.get({ 'crossLanguage': 'off' }, (item) => {
if (item.crossLanguage === 'on') {
setCrossLanguage('off');
} else {
@ -146,7 +182,7 @@ document.getElementById('crossLanguageCheckbox').addEventListener('change', () =
});
});
document.getElementById('reorderResultsCheckbox').addEventListener('change', () => {
chrome.storage.sync.get({ 'reorderResults': 'on' }, (item) => {
extensionAPI.storage.sync.get({ 'reorderResults': 'on' }, (item) => {
if (item.reorderResults === 'on') {
setReorder('off');
} else {
@ -155,7 +191,7 @@ document.getElementById('reorderResultsCheckbox').addEventListener('change', ()
});
});
document.getElementById('openChangelogCheckbox').addEventListener('change', () => {
chrome.storage.sync.get({ 'openChangelog': 'off' }, (item) => {
extensionAPI.storage.sync.get({ 'openChangelog': 'off' }, (item) => {
if (item.openChangelog === 'on') {
setOpenChangelog('off');
} else {
@ -166,7 +202,7 @@ document.getElementById('openChangelogCheckbox').addEventListener('change', () =
document.querySelectorAll('[name="breezewikiSetting"]').forEach((el) => {
el.addEventListener('change', async () => {
const settingValue = document.options.breezewikiSetting.value;
chrome.storage.sync.set({ 'breezewiki': settingValue });
extensionAPI.storage.sync.set({ 'breezewiki': settingValue });
setBreezeWiki(settingValue);
if (settingValue !== 'off') {
loadBreezewikiOptions();
@ -183,7 +219,7 @@ function setBreezeWiki(setting, storeSetting = true) {
// Store BreezeWiki setting
if (storeSetting) {
chrome.storage.sync.set({ 'breezewiki': setting });
extensionAPI.storage.sync.set({ 'breezewiki': setting });
}
// Set BreezeWiki value on radio group
@ -193,7 +229,7 @@ function setBreezeWiki(setting, storeSetting = true) {
const breezewikiHost = document.getElementById('breezewikiHost');
if (setting !== 'off') {
breezewikiHost.style.display = 'block';
chrome.storage.sync.get({ 'breezewikiHost': null }, (host) => {
extensionAPI.storage.sync.get({ 'breezewikiHost': null }, (host) => {
if (!host.breezewikiHost) {
fetch('https://bw.getindie.wiki/instances.json')
.then((response) => {
@ -203,7 +239,7 @@ function setBreezeWiki(setting, storeSetting = true) {
throw new Error('Indie Wiki Buddy failed to get BreezeWiki data.');
}).then((breezewikiHosts) => {
breezewikiHosts = breezewikiHosts.filter(host =>
chrome.runtime.getManifest().version.localeCompare(host.iwb_version,
extensionAPI.runtime.getManifest().version.localeCompare(host.iwb_version,
undefined,
{ numeric: true, sensitivity: 'base' }
) >= 0
@ -220,16 +256,16 @@ function setBreezeWiki(setting, storeSetting = true) {
console.log('Indie Wiki Buddy failed to get BreezeWiki data: ' + e);
}
}
chrome.storage.sync.set({ 'breezewikiHost': host.breezewikiHost });
chrome.storage.sync.set({ 'breezewikiHostOptions': breezewikiHosts });
chrome.storage.sync.set({ 'breezewikiHostFetchTimestamp': Date.now() });
extensionAPI.storage.sync.set({ 'breezewikiHost': host.breezewikiHost });
extensionAPI.storage.sync.set({ 'breezewikiHostOptions': breezewikiHosts });
extensionAPI.storage.sync.set({ 'breezewikiHostFetchTimestamp': Date.now() });
document.getElementById('breezewikiHostSelect').value = host.breezewikiHost;
}).catch((e) => {
console.log('Indie Wiki Buddy failed to get BreezeWiki data: ' + e);
// If fetch fails and no host is set, default to breezewiki.com:
if (!host) {
chrome.storage.sync.set({ 'breezewikiHost': 'https://breezewiki.com' });
extensionAPI.storage.sync.set({ 'breezewikiHost': 'https://breezewiki.com' });
}
});
} else {
@ -281,7 +317,7 @@ function populateBreezewikiHosts(breezewikiHosts, selectedHost, customHostName)
// Populate BreezeWiki dropdown when enabled
async function loadBreezewikiOptions() {
// Load BreezeWiki options:
chrome.storage.sync.get(['breezewikiHostOptions', 'breezewikiHostFetchTimestamp', 'breezewikiHost', 'breezewikiCustomHost'], (item) => {
extensionAPI.storage.sync.get(['breezewikiHostOptions', 'breezewikiHostFetchTimestamp', 'breezewikiHost', 'breezewikiCustomHost'], (item) => {
let hostOptions = item.breezewikiHostOptions;
let hostFetchTimestamp = item.breezewikiHostFetchTimestamp;
let host = item.breezewikiHost;
@ -298,7 +334,7 @@ async function loadBreezewikiOptions() {
throw new Error('Indie Wiki Buddy failed to get BreezeWiki data.');
}).then((breezewikiHosts) => {
breezewikiHosts = breezewikiHosts.filter(host =>
chrome.runtime.getManifest().version.localeCompare(host.iwb_version,
extensionAPI.runtime.getManifest().version.localeCompare(host.iwb_version,
undefined,
{ numeric: true, sensitivity: 'base' }
) >= 0
@ -321,15 +357,15 @@ async function loadBreezewikiOptions() {
populateBreezewikiHosts(breezewikiHosts, host, customHost);
// Store BreezeWiki host details
chrome.storage.sync.set({ 'breezewikiHost': host });
chrome.storage.sync.set({ 'breezewikiHostOptions': breezewikiHosts });
chrome.storage.sync.set({ 'breezewikiHostFetchTimestamp': Date.now() });
extensionAPI.storage.sync.set({ 'breezewikiHost': host });
extensionAPI.storage.sync.set({ 'breezewikiHostOptions': breezewikiHosts });
extensionAPI.storage.sync.set({ 'breezewikiHostFetchTimestamp': Date.now() });
}).catch((e) => {
console.log('Indie Wiki Buddy failed to get BreezeWiki data: ' + e);
// If fetch fails and no host is set, default to breezewiki.com:
if (!host) {
chrome.storage.sync.set({ 'breezewikiHost': 'https://breezewiki.com' });
extensionAPI.storage.sync.set({ 'breezewikiHost': 'https://breezewiki.com' });
}
});
} else {
@ -341,7 +377,7 @@ async function loadBreezewikiOptions() {
populateBreezewikiHosts(hostOptions, host, customHost);
// Store BreezeWiki host details
chrome.storage.sync.set({ 'breezewikiHost': host });
extensionAPI.storage.sync.set({ 'breezewikiHost': host });
}
});
}
}

View File

@ -40,11 +40,11 @@
</p>
<h2>Global settings help</h2>
<p>
There are several global settings:
There are several general settings:
</p>
<ul>
<li>
<b><span aria-hidden="true">🔋</span> Extension is on/off</b>
<b><span aria-hidden="true">🔋</span> Extension is on / off</b>
<br />
Enable/disable all Indie Wiki Buddy functionality at the click of a button.
</li>
@ -61,18 +61,6 @@
settings to ensure that your browser is allowed to send notifications.
</li>
<br />
<li>
<b><span aria-hidden="true">🔔</span> On search engines, show banner when non-indie results are hidden</b>
<br />
When this option is enabled, a banner will be inserted at the top of search engine results when Indie Wiki
Buddy
has hidden results from Fandom, Fextralife, or Neoseeker wikis.
This banner also lets you re-show the hidden results if you wish.
<br />
<br />
If you don't want to see any indication that results have been hidden, disable this option.
</li>
<br />
<li>
<b><span aria-hidden="true">🌐</span> Redirect non-English Fandom wikis to
indie English wikis there is no same-lang wiki</b>
@ -87,19 +75,49 @@
</li>
<br />
<li>
<b><img src="../../images/toggle-replace.png" height="12" alt="" /> Move indie wiki results to the top of
search results on Google</b>
<b><span aria-hidden="true">📁</span> Open changelog when Indie Wiki Buddy is updated</b>
<br />
By default, Indie Wiki Buddy will re-order the results page on Google to move indie wiki results to the top,
if they are further down the first page of results. This allows you to find the pages you're looking for
quicker.
Enable this option to have Indie Wiki Buddy's <a href="https://getindie.wiki/changelog/">changelog</a>
opened in a new tab whenever it updates, so you can stay up-to-date on the latest changes.
</li>
</ul>
<p>
You can also configure your settings for filtering results in search engines:
</p>
<ul>
<li>
<b><img src="../../images/toggles.png" height="12" alt="" /> Toggle filtering per search engine</b>
<br />
By default, filtering is enabled for all search engines.
When enabled, filtering is done based on the user's selected settings for each wiki.
The default filtering option for all wikis is to replace Fandom and Fextralife search results,
but you can opt to hide them entirely.
<br /><br />
The current supported search engines are
Google, Bing, DuckDuckGo, Brave, Ecosia, Kagi, Qwant, Startpage, Yahoo!, and Yandex.
</li>
<br />
<li>
<b><span aria-hidden="true">📁</span> Open changelog when Indie Wiki Buddy is updated</b>
<b><img src="../../images/toggle-banner.png" height="12" alt="" /> On search engines, show banner when non-indie results are hidden</b>
<br />
By default, when Indie Wiki Buddy is updated, the <a href="https://getindie.wiki/changelog/">changelog</a>
will be opened in a new tab. Unchecking this option will disable opening the changelog.
When this option is enabled,
a banner will be inserted at the top of search engine results when Indie Wiki Buddy
has hidden results from Fandom, Fextralife, or Neoseeker wikis.
This banner also lets you re-show the hidden results if you wish.
<br />
<br />
If you don't want to see any indication that results have been hidden, disable this option.
</li>
<br />
<li>
<b><img src="../../images/toggle-move-up.png" height="12" alt="" /> On Google, move indie wiki results to the top of
search results</b>
<br />
By default, Indie Wiki Buddy will re-order the results page on Google to move indie wiki results to the top,
if they are further down the first page of results. This allows you to find the pages you're looking for on indie wikis
quicker.
<br /><br />
This feature is currently only available for Google, as it can be complex to maintain reliably.
</li>
</ul>

View File

@ -103,14 +103,6 @@
redirections
</label>
</div>
<div class="settingToggle">
<label>
<input id="hiddenResultsBannerCheckbox" type="checkbox" />
<span id="hiddenResultsBannerIcon" aria-hidden="true"></span>
On search engines, show banner when
non-indie results are hidden
</label>
</div>
<div class="settingToggle">
<label>
<input id="crossLanguageCheckbox" type="checkbox" />
@ -121,17 +113,71 @@
</div>
<div class="settingToggle">
<label>
<input id="reorderResultsCheckbox" type="checkbox" />
<img src="../../images/toggle-replace.png" height="12" alt="" />
Move indie wiki results to the top of
search results on Google
<input id="openChangelogCheckbox" type="checkbox" />
<span id="openChangelogIcon" aria-hidden="true"></span>
Open changelog when Indie Wiki Buddy is updated
</label>
</div>
</fieldset>
<fieldset id="generalSettings">
<legend><span aria-hidden="true">🔍</span> Search engine filtering </legend>
<div class="settingToggle searchEngineToggles">
<label>
<input id="googleCheckbox" data-search-engine="google" type="checkbox" />
Google
</label>
<label>
<input id="bingCheckbox" data-search-engine="bing" type="checkbox" />
Bing
</label>
<label>
<input id="duckduckgoCheckbox" data-search-engine="duckduckgo" type="checkbox" />
DuckDuckGo
</label>
<label>
<input id="braveCheckbox" data-search-engine="brave" type="checkbox" />
Brave
</label>
<label>
<input id="ecosiaCheckbox" data-search-engine="ecosia" type="checkbox" />
Ecosia
</label>
<label>
<input id="kagiCheckbox" data-search-engine="kagi" type="checkbox" />
Kagi
</label>
<label>
<input id="qwantCheckbox" data-search-engine="qwant" type="checkbox" />
Qwant
</label>
<label>
<input id="startpageCheckbox" data-search-engine="startpage" type="checkbox" />
Startpage
</label>
<label>
<input id="yahooCheckbox" data-search-engine="yahoo" type="checkbox" />
Yahoo
</label>
<label>
<input id="yandexCheckbox" data-search-engine="yandex" type="checkbox" />
Yandex
</label>
</div>
<hr>
<div class="settingToggle">
<label>
<input id="hiddenResultsBannerCheckbox" type="checkbox" />
<img src="../../images/toggle-banner.png" height="12" alt="" />
On search engines, show banner when
non-indie results are hidden
</label>
</div>
<div class="settingToggle">
<label>
<input id="openChangelogCheckbox" type="checkbox" />
<span id="openChangelogIcon" aria-hidden="true"></span>
Open changelog when Indie Wiki Buddy is updated
<input id="reorderResultsCheckbox" type="checkbox" />
<img src="../../images/toggle-move-up.png" height="12" alt="" />
On Google, move indie wiki results to the top of
search results
</label>
</div>
</fieldset>

View File

@ -1,11 +1,11 @@
// Set power setting
function setPower(setting) {
chrome.storage.local.set({ 'power': setting });
extensionAPI.storage.local.set({ 'power': setting });
var powerImage = document.getElementById('powerImage');
powerImage.src = '../../images/power-' + setting + '.png';
powerImage.alt = 'Indie Wiki Buddy is ' + setting;
chrome.runtime.sendMessage({
extensionAPI.runtime.sendMessage({
action: 'updateIcon',
value: setting
});
@ -18,7 +18,7 @@ async function migrateData() {
// Set power setting
function setPower(setting, storeSetting = true) {
if (storeSetting) {
chrome.storage.local.set({ 'power': setting });
extensionAPI.storage.local.set({ 'power': setting });
}
var powerImage = document.getElementById('powerImage');
powerImage.src = '../../images/power-' + setting + '.png';
@ -29,14 +29,14 @@ function setPower(setting, storeSetting = true) {
document.getElementById('powerCheckbox').checked = false;
}
chrome.runtime.sendMessage({
extensionAPI.runtime.sendMessage({
action: 'updateIcon',
value: setting
});
}
// Set default action setting
chrome.storage.sync.get(['defaultWikiAction'], (item) => {
extensionAPI.storage.sync.get(['defaultWikiAction'], (item) => {
if (item.defaultWikiAction === 'disabled') {
document.options.defaultWikiAction.value = 'disabled';
} else if (item.defaultWikiAction === 'redirect') {
@ -46,7 +46,7 @@ chrome.storage.sync.get(['defaultWikiAction'], (item) => {
}
});
// Set default search engine setting
chrome.storage.sync.get(['defaultSearchAction'], (item) => {
extensionAPI.storage.sync.get(['defaultSearchAction'], (item) => {
if (item.defaultSearchAction === 'disabled') {
document.options.defaultSearchAction.value = 'disabled';
} else if (item.defaultSearchAction === 'hide') {
@ -61,12 +61,12 @@ document.addEventListener('DOMContentLoaded', () => {
// If running Opera, show note about search engine access
if (navigator.userAgent.match(/OPR\//)) {
const notificationBannerOpera = document.getElementById('notificationBannerOpera');
chrome.storage.local.get({ 'hideOperaPermissionsNote': false }, (item) => {
extensionAPI.storage.local.get({ 'hideOperaPermissionsNote': false }, (item) => {
if (!item.hideOperaPermissionsNote) {
notificationBannerOpera.style.display = 'block';
document.getElementById('operaPermsHideLink').addEventListener('click', () => {
chrome.storage.local.set({ 'hideOperaPermissionsNote': true });
extensionAPI.storage.local.set({ 'hideOperaPermissionsNote': true });
notificationBannerOpera.style.display = 'none';
});
}
@ -75,11 +75,11 @@ document.addEventListener('DOMContentLoaded', () => {
// Listener for settings links:
document.getElementById('openSettingsButton').addEventListener('click', () => {
chrome.tabs.create({ 'url': chrome.runtime.getURL('pages/settings/index.html') });
extensionAPI.tabs.create({ 'url': extensionAPI.runtime.getURL('pages/settings/index.html') });
window.close();
});
document.getElementById('openSettingsLink').addEventListener('click', () => {
chrome.tabs.create({ 'url': chrome.runtime.getURL('pages/settings/index.html') });
extensionAPI.tabs.create({ 'url': extensionAPI.runtime.getURL('pages/settings/index.html') });
window.close();
});
@ -91,7 +91,7 @@ document.addEventListener('DOMContentLoaded', () => {
} else {
document.getElementById('breezewikiCustomHost').style.display = 'none';
}
chrome.storage.sync.set({ 'breezewikiHost': breezewikiHostSelect.value });
extensionAPI.storage.sync.set({ 'breezewikiHost': breezewikiHostSelect.value });
});
document.options.addEventListener("submit", function (e) {
@ -101,26 +101,26 @@ document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('[name="defaultWikiAction"]').forEach((el) => {
el.addEventListener('change', async () => {
chrome.storage.sync.set({ 'defaultWikiAction': document.options.defaultWikiAction.value })
extensionAPI.storage.sync.set({ 'defaultWikiAction': document.options.defaultWikiAction.value })
let wikiSettings = {};
sites = await commonFunctionGetSiteDataByDestination();
sites.forEach((site) => {
wikiSettings[site.id] = document.options.defaultWikiAction.value;
});
chrome.storage.sync.set({ 'wikiSettings': await commonFunctionCompressJSON(wikiSettings) });
extensionAPI.storage.sync.set({ 'wikiSettings': await commonFunctionCompressJSON(wikiSettings) });
});
});
document.querySelectorAll('[name="defaultSearchAction"]').forEach((el) => {
el.addEventListener('change', async () => {
chrome.storage.sync.set({ 'defaultSearchAction': document.options.defaultSearchAction.value })
extensionAPI.storage.sync.set({ 'defaultSearchAction': document.options.defaultSearchAction.value })
let searchEngineSettings = {};
sites = await commonFunctionGetSiteDataByDestination();
sites.forEach((site) => {
searchEngineSettings[site.id] = document.options.defaultSearchAction.value;
});
chrome.storage.sync.set({ 'searchEngineSettings': await commonFunctionCompressJSON(searchEngineSettings) });
extensionAPI.storage.sync.set({ 'searchEngineSettings': await commonFunctionCompressJSON(searchEngineSettings) });
});
});
});

View File

@ -94,14 +94,6 @@
redirections
</label>
</div>
<div class="settingToggle">
<label>
<input id="hiddenResultsBannerCheckbox" type="checkbox" />
<span id="hiddenResultsBannerIcon" aria-hidden="true"></span>
On search engines, show banner when
non-indie results are hidden
</label>
</div>
<div class="settingToggle">
<label>
<input id="crossLanguageCheckbox" type="checkbox" />
@ -112,17 +104,71 @@
</div>
<div class="settingToggle">
<label>
<input id="reorderResultsCheckbox" type="checkbox" />
<img src="../../images/toggle-replace.png" height="12" alt="" />
Move indie wiki results to the top of
search results on Google
<input id="openChangelogCheckbox" type="checkbox" />
<span id="openChangelogIcon" aria-hidden="true"></span>
Open changelog when Indie Wiki Buddy is updated
</label>
</div>
</fieldset>
<fieldset id="generalSettings">
<legend><span aria-hidden="true">🔍</span> Search engine filtering </legend>
<div class="settingToggle searchEngineToggles">
<label>
<input id="googleCheckbox" data-search-engine="google" type="checkbox" />
Google
</label>
<label>
<input id="bingCheckbox" data-search-engine="bing" type="checkbox" />
Bing
</label>
<label>
<input id="duckduckgoCheckbox" data-search-engine="duckduckgo" type="checkbox" />
DuckDuckGo
</label>
<label>
<input id="braveCheckbox" data-search-engine="brave" type="checkbox" />
Brave
</label>
<label>
<input id="ecosiaCheckbox" data-search-engine="ecosia" type="checkbox" />
Ecosia
</label>
<label>
<input id="kagiCheckbox" data-search-engine="kagi" type="checkbox" />
Kagi
</label>
<label>
<input id="qwantCheckbox" data-search-engine="qwant" type="checkbox" />
Qwant
</label>
<label>
<input id="startpageCheckbox" data-search-engine="startpage" type="checkbox" />
Startpage
</label>
<label>
<input id="yahooCheckbox" data-search-engine="yahoo" type="checkbox" />
Yahoo
</label>
<label>
<input id="yandexCheckbox" data-search-engine="yandex" type="checkbox" />
Yandex
</label>
</div>
<hr>
<div class="settingToggle">
<label>
<input id="hiddenResultsBannerCheckbox" type="checkbox" />
<img src="../../images/toggle-banner.png" height="12" alt="" />
On search engines, show banner when
non-indie results are hidden
</label>
</div>
<div class="settingToggle">
<label>
<input id="openChangelogCheckbox" type="checkbox" />
<span id="openChangelogIcon" aria-hidden="true"></span>
Open changelog when Indie Wiki Buddy is updated
<input id="reorderResultsCheckbox" type="checkbox" />
<img src="../../images/toggle-move-up.png" height="12" alt="" />
On Google, move indie wiki results to the top of
search results
</label>
</div>
</fieldset>
@ -166,7 +212,11 @@
</label>
</div>
</fieldset>
<fieldset id="customSearchEngines">
<!--
Custom search engines are currently disabled
due to content scripts being unregistered on-update.
-->
<!-- <fieldset id="customSearchEngines">
<legend>
<span aria-hidden="true">🔍</span> Custom search engines
</legend>
@ -181,7 +231,7 @@
<button id="addCustomSearchEngine">Add</button>
</div>
</div>
</fieldset>
</fieldset> -->
<h2>Individual wiki settings</h2>
<fieldset id="legend">
<legend>
@ -350,6 +400,7 @@
</div>
</body>
<script type="text/javascript" src="../../scripts/common-functions.js"></script>
<script type="text/javascript" src="../../scripts/common-search-permissions.js"></script>
<script type="text/javascript" src="../common-page-functions.js"></script>
<script type="text/javascript" src="settings.js"></script>

View File

@ -35,8 +35,8 @@ async function loadOptions(lang, textFilter = '') {
site.destination_base_url.toLowerCase().includes(textFilter))
));
chrome.storage.local.get((localStorage) => {
chrome.storage.sync.get(async (syncStorage) => {
extensionAPI.storage.local.get((localStorage) => {
extensionAPI.storage.sync.get(async (syncStorage) => {
const storage = { ...syncStorage, ...localStorage };
let wikiSettings = await commonFunctionDecompressJSON(storage.wikiSettings || {});
let searchEngineSettings = await commonFunctionDecompressJSON(storage.searchEngineSettings || {});
@ -44,7 +44,7 @@ async function loadOptions(lang, textFilter = '') {
let defaultSearchAction = storage.defaultSearchAction || null;
// Load defaults for newly added wikis:
chrome.storage.sync.get(['defaultWikiAction'], (item) => {
extensionAPI.storage.sync.get(['defaultWikiAction'], (item) => {
if (item.defaultWikiAction === 'disabled') {
document.options.defaultWikiAction.value = 'disabled';
} else if (item.defaultWikiAction === 'redirect') {
@ -53,7 +53,7 @@ async function loadOptions(lang, textFilter = '') {
document.options.defaultWikiAction.value = 'alert';
}
});
chrome.storage.sync.get(['defaultSearchAction'], (item) => {
extensionAPI.storage.sync.get(['defaultSearchAction'], (item) => {
if (item.defaultSearchAction === 'disabled') {
document.options.defaultSearchAction.value = 'disabled';
} else if (item.defaultSearchAction === 'hide') {
@ -180,51 +180,51 @@ async function loadOptions(lang, textFilter = '') {
// Add listeners for when user clicks control:
inputDisabled.addEventListener('click', (input) => {
chrome.storage.sync.get({ 'wikiSettings': {} }, async (response) => {
extensionAPI.storage.sync.get({ 'wikiSettings': {} }, async (response) => {
let wikiSettings = await commonFunctionDecompressJSON(response.wikiSettings);
var key = input.target.getAttribute('data-wiki-key');
wikiSettings[key] = 'disabled';
chrome.storage.sync.set({ 'wikiSettings': await commonFunctionCompressJSON(wikiSettings) });
extensionAPI.storage.sync.set({ 'wikiSettings': await commonFunctionCompressJSON(wikiSettings) });
});
});
inputAlert.addEventListener('click', (input) => {
chrome.storage.sync.get({ 'wikiSettings': {} }, async (response) => {
extensionAPI.storage.sync.get({ 'wikiSettings': {} }, async (response) => {
let wikiSettings = await commonFunctionDecompressJSON(response.wikiSettings);
var key = input.target.getAttribute('data-wiki-key');
wikiSettings[key] = 'alert';
chrome.storage.sync.set({ 'wikiSettings': await commonFunctionCompressJSON(wikiSettings) });
extensionAPI.storage.sync.set({ 'wikiSettings': await commonFunctionCompressJSON(wikiSettings) });
});
});
inputRedirect.addEventListener('click', (input) => {
chrome.storage.sync.get({ 'wikiSettings': {} }, async (response) => {
extensionAPI.storage.sync.get({ 'wikiSettings': {} }, async (response) => {
let wikiSettings = await commonFunctionDecompressJSON(response.wikiSettings);
var key = input.target.getAttribute('data-wiki-key');
wikiSettings[key] = 'redirect';
chrome.storage.sync.set({ 'wikiSettings': await commonFunctionCompressJSON(wikiSettings) });
extensionAPI.storage.sync.set({ 'wikiSettings': await commonFunctionCompressJSON(wikiSettings) });
});
});
inputSearchEngineDisabled.addEventListener('click', (input) => {
chrome.storage.sync.get({ 'searchEngineSettings': {} }, async (response) => {
extensionAPI.storage.sync.get({ 'searchEngineSettings': {} }, async (response) => {
let searchEngineSettings = await commonFunctionDecompressJSON(response.searchEngineSettings);
var key = input.target.getAttribute('data-wiki-key');
searchEngineSettings[key] = 'disabled';
chrome.storage.sync.set({ 'searchEngineSettings': await commonFunctionCompressJSON(searchEngineSettings) });
extensionAPI.storage.sync.set({ 'searchEngineSettings': await commonFunctionCompressJSON(searchEngineSettings) });
});
});
inputSearchEngineReplace.addEventListener('click', (input) => {
chrome.storage.sync.get({ 'searchEngineSettings': {} }, async (response) => {
extensionAPI.storage.sync.get({ 'searchEngineSettings': {} }, async (response) => {
let searchEngineSettings = await commonFunctionDecompressJSON(response.searchEngineSettings);
var key = input.target.getAttribute('data-wiki-key');
searchEngineSettings[key] = 'replace';
chrome.storage.sync.set({ 'searchEngineSettings': await commonFunctionCompressJSON(searchEngineSettings) });
extensionAPI.storage.sync.set({ 'searchEngineSettings': await commonFunctionCompressJSON(searchEngineSettings) });
});
});
inputSearchEngineHide.addEventListener('click', (input) => {
chrome.storage.sync.get({ 'searchEngineSettings': {} }, async (response) => {
extensionAPI.storage.sync.get({ 'searchEngineSettings': {} }, async (response) => {
let searchEngineSettings = await commonFunctionDecompressJSON(response.searchEngineSettings);
var key = input.target.getAttribute('data-wiki-key');
searchEngineSettings[key] = 'hide';
chrome.storage.sync.set({ 'searchEngineSettings': await commonFunctionCompressJSON(searchEngineSettings) });
extensionAPI.storage.sync.set({ 'searchEngineSettings': await commonFunctionCompressJSON(searchEngineSettings) });
});
});
@ -319,7 +319,7 @@ async function loadOptions(lang, textFilter = '') {
toggles[i].checked = true;
wikiSettings[toggles[i].getAttribute('data-wiki-key')] = 'redirect';
}
chrome.storage.sync.set({ 'wikiSettings': await commonFunctionCompressJSON(wikiSettings) });
extensionAPI.storage.sync.set({ 'wikiSettings': await commonFunctionCompressJSON(wikiSettings) });
});
const setAllAlert = document.getElementById('setAllAlert');
@ -329,7 +329,7 @@ async function loadOptions(lang, textFilter = '') {
toggles[i].checked = true;
wikiSettings[toggles[i].getAttribute('data-wiki-key')] = 'alert';
}
chrome.storage.sync.set({ 'wikiSettings': await commonFunctionCompressJSON(wikiSettings) });
extensionAPI.storage.sync.set({ 'wikiSettings': await commonFunctionCompressJSON(wikiSettings) });
});
const setAllDisabled = document.getElementById('setAllDisabled');
@ -339,7 +339,7 @@ async function loadOptions(lang, textFilter = '') {
toggles[i].checked = true;
wikiSettings[toggles[i].getAttribute('data-wiki-key')] = 'disabled';
}
chrome.storage.sync.set({ 'wikiSettings': await commonFunctionCompressJSON(wikiSettings) });
extensionAPI.storage.sync.set({ 'wikiSettings': await commonFunctionCompressJSON(wikiSettings) });
});
const setAllSearchEngineDisabled = document.getElementById('setAllSearchEngineDisabled');
@ -349,7 +349,7 @@ async function loadOptions(lang, textFilter = '') {
toggles[i].checked = true;
searchEngineSettings[toggles[i].getAttribute('data-wiki-key')] = 'disabled';
}
chrome.storage.sync.set({ 'searchEngineSettings': await commonFunctionCompressJSON(searchEngineSettings) });
extensionAPI.storage.sync.set({ 'searchEngineSettings': await commonFunctionCompressJSON(searchEngineSettings) });
});
const setAllSearchEngineHide = document.getElementById('setAllSearchEngineHide');
@ -359,7 +359,7 @@ async function loadOptions(lang, textFilter = '') {
toggles[i].checked = true;
searchEngineSettings[toggles[i].getAttribute('data-wiki-key')] = 'hide';
}
chrome.storage.sync.set({ 'searchEngineSettings': await commonFunctionCompressJSON(searchEngineSettings) });
extensionAPI.storage.sync.set({ 'searchEngineSettings': await commonFunctionCompressJSON(searchEngineSettings) });
});
const setAllSearchEngineReplace = document.getElementById('setAllSearchEngineReplace');
@ -369,7 +369,7 @@ async function loadOptions(lang, textFilter = '') {
toggles[i].checked = true;
searchEngineSettings[toggles[i].getAttribute('data-wiki-key')] = 'replace';
}
chrome.storage.sync.set({ 'searchEngineSettings': await commonFunctionCompressJSON(searchEngineSettings) });
extensionAPI.storage.sync.set({ 'searchEngineSettings': await commonFunctionCompressJSON(searchEngineSettings) });
});
});
});
@ -396,13 +396,23 @@ function displayCustomSearchEngine(customSearchEngineHostname, customSearchEngin
customSearchEngineDeleteButton.addEventListener('click', () => {
listItem.remove();
chrome.storage.sync.get({ 'customSearchEngines': {} }, (item) => {
extensionAPI.storage.sync.get({ 'customSearchEngines': {} }, (item) => {
let customSearchEngines = item.customSearchEngines;
delete customSearchEngines[customSearchEngineHostname];
chrome.storage.sync.set({ 'customSearchEngines': customSearchEngines });
extensionAPI.storage.sync.set({ 'customSearchEngines': customSearchEngines });
});
chrome.scripting.unregisterContentScripts({ ids: [`content-search-filtering-${customSearchEngineHostname}`] });
let customSearchEngine = customSearchEngineHostname;
// Add "https://" if not already present
if (!customSearchEngine.includes('://')) {
customSearchEngine = 'https://' + customSearchEngine;
}
customSearchEngine = new URL(customSearchEngine);
extensionAPI.permissions.remove({
origins: [ `${customSearchEngine}*` ]
});
extensionAPI.scripting.unregisterContentScripts({ ids: [`content-search-filtering-${customSearchEngineHostname}`] });
});
listItem.appendChild(customSearchEngineHostnameLabel);
@ -415,7 +425,7 @@ function displayCustomSearchEngine(customSearchEngineHostname, customSearchEngin
// Set power setting
function setPower(setting, storeSetting = true) {
if (storeSetting) {
chrome.storage.local.set({ 'power': setting });
extensionAPI.storage.local.set({ 'power': setting });
}
const powerText = document.getElementById('powerText');
powerText.textContent = 'Extension is ' + setting;
@ -428,7 +438,7 @@ function setPower(setting, storeSetting = true) {
powerIcon.innerText = '🪫';
}
chrome.runtime.sendMessage({
extensionAPI.runtime.sendMessage({
action: 'updateIcon',
value: setting
});
@ -448,12 +458,12 @@ document.addEventListener('DOMContentLoaded', () => {
// If running Opera, show note about search engine access
if (navigator.userAgent.match(/OPR\//)) {
const notificationBannerOpera = document.getElementById('notificationBannerOpera');
chrome.storage.local.get({ 'hideOperaPermissionsNote': false }, (item) => {
extensionAPI.storage.local.get({ 'hideOperaPermissionsNote': false }, (item) => {
if (!item.hideOperaPermissionsNote) {
notificationBannerOpera.style.display = 'block';
document.getElementById('operaPermsHideLink').addEventListener('click', () => {
chrome.storage.local.set({ 'hideOperaPermissionsNote': true });
extensionAPI.storage.local.set({ 'hideOperaPermissionsNote': true });
notificationBannerOpera.style.display = 'none';
});
}
@ -462,13 +472,13 @@ document.addEventListener('DOMContentLoaded', () => {
// Count number of times settings have been opened
// Purposefully using local storage instead of sync
chrome.storage.local.get({ 'countSettingsOpened': 0 }, (item) => {
extensionAPI.storage.local.get({ 'countSettingsOpened': 0 }, (item) => {
const countSettingsOpened = item.countSettingsOpened;
chrome.storage.local.set({ 'countSettingsOpened': countSettingsOpened + 1 });
extensionAPI.storage.local.set({ 'countSettingsOpened': countSettingsOpened + 1 });
// Show review reminder every 5 opens,
// and if the banner hasn't been previously dismissed
chrome.storage.local.get({ 'hideReviewReminder': false }, (item) => {
extensionAPI.storage.local.get({ 'hideReviewReminder': false }, (item) => {
if (!item.hideReviewReminder && ((countSettingsOpened - 1) % 5 === 0)) {
const notificationBannerReview = document.getElementById('notificationBannerReview');
@ -477,13 +487,13 @@ document.addEventListener('DOMContentLoaded', () => {
// Disable future review reminders if user clicks links:
document.getElementById('reviewReminderChromeLink').addEventListener('click', () => {
chrome.storage.local.set({ 'hideReviewReminder': true });
extensionAPI.storage.local.set({ 'hideReviewReminder': true });
});
document.getElementById('reviewReminderFirefoxLink').addEventListener('click', () => {
chrome.storage.local.set({ 'hideReviewReminder': true });
extensionAPI.storage.local.set({ 'hideReviewReminder': true });
});
document.getElementById('reviewReminderHideLink').addEventListener('click', () => {
chrome.storage.local.set({ 'hideReviewReminder': true });
extensionAPI.storage.local.set({ 'hideReviewReminder': true });
notificationBannerReview.style.display = 'none';
});
}
@ -491,11 +501,11 @@ document.addEventListener('DOMContentLoaded', () => {
});
// Adding version to popup:
const version = chrome.runtime.getManifest().version;
const version = extensionAPI.runtime.getManifest().version;
document.getElementById('version').textContent = 'v' + version;
// Get user's last set language
chrome.storage.sync.get({ 'lang': 'EN' }, (item) => {
extensionAPI.storage.sync.get({ 'lang': 'EN' }, (item) => {
langSelect.value = item.lang;
const filterInput = document.getElementById('filterInput').value;
loadOptions(item.lang, filterInput);
@ -503,7 +513,7 @@ document.addEventListener('DOMContentLoaded', () => {
// Add event listener for language select
const langSelect = document.getElementById("langSelect");
langSelect.addEventListener('change', () => {
chrome.storage.sync.set({ 'lang': langSelect.value });
extensionAPI.storage.sync.set({ 'lang': langSelect.value });
const filterInput = document.getElementById('filterInput').value;
loadOptions(langSelect.value, filterInput);
});
@ -517,7 +527,7 @@ document.addEventListener('DOMContentLoaded', () => {
} else {
document.getElementById('breezewikiCustomHost').style.display = 'none';
}
chrome.storage.sync.set({ 'breezewikiHost': breezewikiHostSelect.value });
extensionAPI.storage.sync.set({ 'breezewikiHost': breezewikiHostSelect.value });
});
function setCustomBreezewikiDomain() {
@ -531,18 +541,18 @@ document.addEventListener('DOMContentLoaded', () => {
breezewikiCustomDomain = breezewikiCustomDomain.protocol + "//" + breezewikiCustomDomain.hostname
breezewikiCustomDomain = breezewikiCustomDomain.toString();
chrome.permissions.request({
extensionAPI.permissions.request({
origins: [breezewikiCustomDomain + '/*']
}, (granted) => {
// The callback argument will be true if the user granted the permissions.
if (granted) {
chrome.scripting.registerContentScripts([{
extensionAPI.scripting.registerContentScripts([{
id: 'content-banners',
matches: [breezewikiCustomDomain + '/*'],
js: ['/scripts/common-functions.js', '/scripts/content-banners.js', '/scripts/content-breezewiki.js'],
runAt: "document_idle"
}]);
chrome.storage.sync.set({ 'breezewikiCustomHost': breezewikiCustomDomain });
extensionAPI.storage.sync.set({ 'breezewikiCustomHost': breezewikiCustomDomain });
document.getElementById('breezewikiCustomHostStatus').innerText = 'Successfully added';
} else {
document.getElementById('breezewikiCustomHostStatus').innerText = 'Failed to set host';
@ -581,25 +591,29 @@ document.addEventListener('DOMContentLoaded', () => {
}
}
chrome.permissions.request({
extensionAPI.permissions.request({
origins: [ `${customSearchEngine}*` ]
}, (granted) => {
// Callback is true if the user granted the permissions.
if (!granted) return;
chrome.scripting.registerContentScripts([{
id: `content-search-filtering-${customSearchEngine.hostname}`,
matches: [customSearchEngine + '*'],
js: [ '/scripts/common-functions.js', '/scripts/content-search-filtering.js' ],
runAt: "document_start"
}]);
try {
extensionAPI.scripting.registerContentScripts([{
id: `content-search-filtering-${customSearchEngine.hostname}`,
matches: [customSearchEngine + '*'],
js: [ '/scripts/common-functions.js', '/scripts/content-search-filtering.js' ],
runAt: "document_start"
}]);
} catch(e) {
(`Could not register content script for ${customSearchEngine}.`)
}
let customSearchEnginePreset = document.getElementById('newCustomSearchEnginePreset').value;
chrome.storage.sync.get({ 'customSearchEngines': {} }, (item) => {
extensionAPI.storage.sync.get({ 'customSearchEngines': {} }, (item) => {
let customSearchEngines = item.customSearchEngines;
customSearchEngines[customSearchEngine.hostname] = customSearchEnginePreset;
chrome.storage.sync.set({ 'customSearchEngines': customSearchEngines });
extensionAPI.storage.sync.set({ 'customSearchEngines': customSearchEngines });
});
displayCustomSearchEngine(customSearchEngine.hostname, customSearchEnginePreset);
@ -608,16 +622,20 @@ document.addEventListener('DOMContentLoaded', () => {
});
}
document.getElementById('addCustomSearchEngine').addEventListener('click', () => {
addCustomSearchEngine();
});
document.getElementById('newCustomSearchEngineDomain').onkeyup = function(e) {
if (e.key === 'Enter') {
addCustomSearchEngine();
}
}
///////////////////////////////////////////////////////////////
// Custom search engines are currently disabled
// due to content scripts being unregistered on-update.
///////////////////////////////////////////////////////////////
// document.getElementById('addCustomSearchEngine').addEventListener('click', () => {
// addCustomSearchEngine();
// });
// document.getElementById('newCustomSearchEngineDomain').onkeyup = function(e) {
// if (e.key === 'Enter') {
// addCustomSearchEngine();
// }
// }
chrome.storage.sync.get({ 'customSearchEngines': {} }, (item) => {
extensionAPI.storage.sync.get({ 'customSearchEngines': {} }, (item) => {
Object.keys(item.customSearchEngines).forEach((key) => {
displayCustomSearchEngine(key, item.customSearchEngines[key]);
});
@ -626,12 +644,12 @@ document.addEventListener('DOMContentLoaded', () => {
// Add event listeners for default action selections
document.querySelectorAll('[name="defaultWikiAction"]').forEach((el) => {
el.addEventListener('change', () => {
chrome.storage.sync.set({ 'defaultWikiAction': document.options.defaultWikiAction.value })
extensionAPI.storage.sync.set({ 'defaultWikiAction': document.options.defaultWikiAction.value })
});
});
document.querySelectorAll('[name="defaultSearchAction"]').forEach((el) => {
el.addEventListener('change', () => {
chrome.storage.sync.set({ 'defaultSearchAction': document.options.defaultSearchAction.value })
extensionAPI.storage.sync.set({ 'defaultSearchAction': document.options.defaultSearchAction.value })
});
});
@ -642,19 +660,19 @@ document.addEventListener('DOMContentLoaded', () => {
});
// Get and display stat counts
chrome.storage.sync.get({ 'countAlerts': 0 }, (item) => {
extensionAPI.storage.sync.get({ 'countAlerts': 0 }, (item) => {
var key = Object.keys(item)[0];
document.getElementById('countAlerts').textContent = item[key];
});
chrome.storage.sync.get({ 'countRedirects': 0 }, (item) => {
extensionAPI.storage.sync.get({ 'countRedirects': 0 }, (item) => {
var key = Object.keys(item)[0];
document.getElementById('countRedirects').textContent = item[key];
});
chrome.storage.sync.get({ 'countSearchFilters': 0 }, (item) => {
extensionAPI.storage.sync.get({ 'countSearchFilters': 0 }, (item) => {
var key = Object.keys(item)[0];
document.getElementById('countSearchFilters').textContent = item[key];
});
chrome.storage.sync.get({ 'countBreezeWiki': 0 }, (item) => {
extensionAPI.storage.sync.get({ 'countBreezeWiki': 0 }, (item) => {
var key = Object.keys(item)[0];
document.getElementById('countBreezeWiki').textContent = item[key];
});

View File

@ -1,5 +1,6 @@
var LANGS = ["DE", "EN", "ES", "FI", "FR", "HU", "IT", "JA", "LZH", "KO", "PL", "PT", "RU", "TH", "TOK", "UK", "ZH"];
var BASE64REGEX = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;
const extensionAPI = typeof browser === "undefined" ? chrome : browser;
function b64decode(str) {
const binary_string = atob(str);
@ -61,7 +62,7 @@ async function commonFunctionGetSiteDataByDestination() {
var sites = [];
let promises = [];
for (let i = 0; i < LANGS.length; i++) {
promises.push(fetch(chrome.runtime.getURL('data/sites' + LANGS[i] + '.json'))
promises.push(fetch(extensionAPI.runtime.getURL('data/sites' + LANGS[i] + '.json'))
.then((resp) => resp.json())
.then((jsonData) => {
jsonData.forEach((site) => site.language = LANGS[i]);
@ -77,7 +78,7 @@ async function populateSiteDataByOrigin() {
let sites = [];
let promises = [];
for (let i = 0; i < LANGS.length; i++) {
promises.push(fetch(chrome.runtime.getURL('data/sites' + LANGS[i] + '.json'))
promises.push(fetch(extensionAPI.runtime.getURL('data/sites' + LANGS[i] + '.json'))
.then((resp) => resp.json())
.then((jsonData) => {
jsonData.forEach((site) => {
@ -211,7 +212,7 @@ function commonFunctionGetNewURL(originURL, matchingSite) {
// Temporary function to migrate user data to IWB version 3.0+
async function commonFunctionMigrateToV3() {
await chrome.storage.sync.get(async (storage) => {
await extensionAPI.storage.sync.get(async (storage) => {
if (!storage.v3migration) {
let defaultWikiAction = storage.defaultWikiAction || 'alert';
let defaultSearchAction = storage.defaultSearchAction || 'replace';
@ -221,7 +222,7 @@ async function commonFunctionMigrateToV3() {
if (storage.defaultActionSettings && storage.defaultActionSettings['EN']) {
defaultWikiAction = storage.defaultActionSettings['EN'];
}
chrome.storage.sync.set({ 'defaultWikiAction': defaultWikiAction });
extensionAPI.storage.sync.set({ 'defaultWikiAction': defaultWikiAction });
}
if (!storage.defaultSearchAction) {
if (storage.defaultSearchFilterSettings && storage.defaultSearchFilterSettings['EN']) {
@ -231,12 +232,12 @@ async function commonFunctionMigrateToV3() {
defaultSearchAction = 'replace';
}
}
chrome.storage.sync.set({ 'defaultSearchAction': defaultSearchAction });
extensionAPI.storage.sync.set({ 'defaultSearchAction': defaultSearchAction });
}
// Remove old objects:
chrome.storage.sync.remove('defaultActionSettings');
chrome.storage.sync.remove('defaultSearchFilterSettings');
extensionAPI.storage.sync.remove('defaultActionSettings');
extensionAPI.storage.sync.remove('defaultSearchFilterSettings');
// Migrate wiki settings to new searchEngineSettings and wikiSettings objects
sites = await commonFunctionGetSiteDataByOrigin();
@ -262,14 +263,14 @@ async function commonFunctionMigrateToV3() {
}
});
chrome.storage.sync.set({ 'searchEngineSettings': await commonFunctionCompressJSON(searchEngineSettings) });
chrome.storage.sync.set({ 'wikiSettings': await commonFunctionCompressJSON(wikiSettings) });
extensionAPI.storage.sync.set({ 'searchEngineSettings': await commonFunctionCompressJSON(searchEngineSettings) });
extensionAPI.storage.sync.set({ 'wikiSettings': await commonFunctionCompressJSON(wikiSettings) });
// Remove old object:
chrome.storage.sync.remove('siteSettings');
extensionAPI.storage.sync.remove('siteSettings');
// Mark v3 migration as complete:
chrome.storage.sync.set({ 'v3migration': 'done' });
extensionAPI.storage.sync.set({ 'v3migration': 'done' });
}
});
}

View File

@ -102,7 +102,7 @@ function processBreezeWikiBanner(storage) {
throw new Error('Indie Wiki Buddy failed to get BreezeWiki data.');
}).then((breezewikiHosts) => {
breezewikiHosts = breezewikiHosts.filter(host =>
chrome.runtime.getManifest().version.localeCompare(host.iwb_version,
extensionAPI.runtime.getManifest().version.localeCompare(host.iwb_version,
undefined,
{ numeric: true, sensitivity: 'base' }
) >= 0
@ -110,21 +110,21 @@ function processBreezeWikiBanner(storage) {
// Check if BreezeWiki's main site is available
let breezewikiMain = breezewikiHosts.filter(host => host.instance === 'https://breezewiki.com');
if (breezewikiMain.length > 0) {
chrome.storage.sync.set({ 'breezewikiHost': breezewikiMain[0].instance });
extensionAPI.storage.sync.set({ 'breezewikiHost': breezewikiMain[0].instance });
} else {
// If BreezeWiki.com is not available, set to a random mirror
try {
chrome.storage.sync.set({ 'breezewikiHost': breezewikiHosts[Math.floor(Math.random() * breezewikiHosts.length)].instance });
extensionAPI.storage.sync.set({ 'breezewikiHost': breezewikiHosts[Math.floor(Math.random() * breezewikiHosts.length)].instance });
} catch (e) {
console.log('Indie Wiki Buddy failed to get BreezeWiki data: ' + e);
}
}
chrome.storage.sync.set({ 'breezewikiHostOptions': breezewikiHosts });
chrome.storage.sync.set({ 'breezewikiHostFetchTimestamp': Date.now() });
extensionAPI.storage.sync.set({ 'breezewikiHostOptions': breezewikiHosts });
extensionAPI.storage.sync.set({ 'breezewikiHostFetchTimestamp': Date.now() });
breezewikiHost = host;
}).catch((e) => {
console.log('Indie Wiki Buddy failed to get BreezeWiki data: ' + e);
chrome.storage.sync.set({ 'breezewikiHost': 'https://breezewiki.com' });
extensionAPI.storage.sync.set({ 'breezewikiHost': 'https://breezewiki.com' });
});
} else {
if (storage.breezewikiHost === 'CUSTOM') {
@ -198,10 +198,10 @@ function displayRedirectBanner(newUrl, id, destinationName, destinationLanguage,
bannerRestoreLink.textContent = '⎌ Restore banner';
bannerControls.appendChild(bannerRestoreLink);
bannerRestoreLink.onclick = function (e) {
chrome.storage.sync.get({ 'wikiSettings': {} }, async (response) => {
extensionAPI.storage.sync.get({ 'wikiSettings': {} }, async (response) => {
let wikiSettings = await commonFunctionDecompressJSON(response.wikiSettings);
wikiSettings[id] = 'alert';
chrome.storage.sync.set({ 'wikiSettings': await commonFunctionCompressJSON(wikiSettings) });
extensionAPI.storage.sync.set({ 'wikiSettings': await commonFunctionCompressJSON(wikiSettings) });
e.target.textContent = '✓ Banner restored';
e.target.classList.add('indie-wiki-banner-disabled');
bannerControls.querySelector('.indie-wiki-banner-redirect').textContent = '↪ Auto redirect this wiki';
@ -220,10 +220,10 @@ function displayRedirectBanner(newUrl, id, destinationName, destinationLanguage,
bannerDisableLink.textContent = '✕ Disable banner for this wiki';
bannerControls.appendChild(bannerDisableLink);
bannerDisableLink.onclick = function (e) {
chrome.storage.sync.get({ 'wikiSettings': {} }, async (response) => {
extensionAPI.storage.sync.get({ 'wikiSettings': {} }, async (response) => {
let wikiSettings = await commonFunctionDecompressJSON(response.wikiSettings);
wikiSettings[id] = 'disabled';
chrome.storage.sync.set({ 'wikiSettings': await commonFunctionCompressJSON(wikiSettings) });
extensionAPI.storage.sync.set({ 'wikiSettings': await commonFunctionCompressJSON(wikiSettings) });
e.target.textContent = '✓ Banner disabled';
e.target.classList.add('indie-wiki-banner-disabled');
bannerControls.querySelector('.indie-wiki-banner-restore').textContent = '⎌ Restore banner';
@ -240,10 +240,10 @@ function displayRedirectBanner(newUrl, id, destinationName, destinationLanguage,
bannerRedirectLink.textContent = '↪ Auto redirect this wiki';
bannerControls.appendChild(bannerRedirectLink);
bannerRedirectLink.onclick = function (e) {
chrome.storage.sync.get({ 'wikiSettings': {} }, async (response) => {
extensionAPI.storage.sync.get({ 'wikiSettings': {} }, async (response) => {
let wikiSettings = await commonFunctionDecompressJSON(response.wikiSettings);
wikiSettings[id] = 'redirect';
chrome.storage.sync.set({ 'wikiSettings': await commonFunctionCompressJSON(wikiSettings) });
extensionAPI.storage.sync.set({ 'wikiSettings': await commonFunctionCompressJSON(wikiSettings) });
e.target.textContent = '✓ Redirect enabled';
e.target.classList.add('indie-wiki-banner-disabled');
bannerControls.querySelector('.indie-wiki-banner-disable').classList.add('indie-wiki-banner-hidden');
@ -290,10 +290,10 @@ function displayRedirectBanner(newUrl, id, destinationName, destinationLanguage,
// Increment banner count
if (storage.breezewiki === 'on') {
if (currentURL.hostname.match(breezewikiRegex) || (storage.breezewikiHost === 'CUSTOM' && storage.breezewikiCustomHost?.includes(currentURL.hostname))) {
chrome.storage.sync.set({ 'countAlerts': (storage.countAlerts ?? 0) + 1 });
extensionAPI.storage.sync.set({ 'countAlerts': (storage.countAlerts ?? 0) + 1 });
}
} else {
chrome.storage.sync.set({ 'countAlerts': (storage.countAlerts ?? 0) + 1 });
extensionAPI.storage.sync.set({ 'countAlerts': (storage.countAlerts ?? 0) + 1 });
}
// Hide duplicative indie wiki notice on BreezeWiki instances
@ -315,7 +315,7 @@ function displayRedirectBanner(newUrl, id, destinationName, destinationLanguage,
}
function main() {
chrome.runtime.sendMessage({action: 'getStorage'}).then((storage) => {
extensionAPI.runtime.sendMessage({action: 'getStorage'}, (storage) => {
// Check if extension is on:
if ((storage.power ?? 'on') === 'on') {
// Check if there is a pathname, to ensure we're looking at an article

View File

@ -9,13 +9,18 @@ function base64Decode(text) {
// Function to create an observer to watch for mutations on search pages
// This is used for search engines that paginate via JavaScript,
// or overwrite their results and remove IWB's elements
function addDOMChangeObserver(callback) {
function addDOMChangeObserver(callback, searchEngine, storage) {
const config = {
attributes: false,
childList: true,
subtree: true
}
const domObserver = new MutationObserver(callback);
const wrappedCallback = (mutations, observer) => {
callback(searchEngine, storage, mutations, observer);
};
const domObserver = new MutationObserver(wrappedCallback);
domObserver.observe(document.body, config);
}
@ -183,7 +188,7 @@ function replaceSearchResults(searchResultContainer, site, link) {
indieResultFavicon.alt = '';
indieResultFavicon.width = '12';
indieResultFavicon.height = '12';
indieResultFavicon.src = chrome.runtime.getURL('favicons/' + site.language.toLowerCase() + '/' + site.destination_icon);
indieResultFavicon.src = extensionAPI.runtime.getURL('favicons/' + site.language.toLowerCase() + '/' + site.destination_icon);
indieResultFaviconContainer.append(indieResultFavicon);
let indieResultText = document.createElement('span');
if (originArticle && originArticle !== site['origin_main_page']) {
@ -388,7 +393,7 @@ function findClosestElement(target, elements) {
return closestElement;
}
async function _filterSearchResult(matchingSite, searchResult, searchEngine, countFiltered, storage, reorderedHrefs) {
async function filterSearchResult(matchingSite, searchResult, searchEngine, countFiltered, storage, reorderedHrefs) {
// Get user's settings for the wiki
let id = matchingSite['id'];
let searchFilterSetting = 'replace';
@ -447,10 +452,10 @@ async function _filterSearchResult(matchingSite, searchResult, searchEngine, cou
}
break;
case 'startpage':
searchResultContainer = searchResult.closest('div.w-gl__result');
searchResultContainer = searchResult.closest('div.result, div.w-gl__result');
break;
case 'yandex':
searchResultContainer = searchResult.closest('.serp-item, .MMOrganicSnippet, .viewer-snippet');
searchResultContainer = searchResult.closest('li[data-cid], .serp-item, .MMOrganicSnippet, .viewer-snippet');
break;
case 'yahoo':
searchResultContainer = searchResult.closest('#web > ol > li div.itm .exp, #web > ol > li div.algo, #web > ol > li, section.algo');
@ -459,11 +464,11 @@ async function _filterSearchResult(matchingSite, searchResult, searchEngine, cou
searchResultContainer = searchResult.closest('div.search-result, div.__srgi');
break;
case 'searxng':
searchResultContainer = searchResult.closest('article');
break;
searchResultContainer = searchResult.closest('article');
break;
case 'whoogle':
searchResultContainer = searchResult.closest('#main>div>div, details>div>div>div>div>div>div.has-favicon');
break;
searchResultContainer = searchResult.closest('#main>div>div, details>div>div>div>div>div>div.has-favicon');
break;
default:
}
@ -492,7 +497,7 @@ async function _filterSearchResult(matchingSite, searchResult, searchEngine, cou
return countFiltered;
}
async function _reorderDestinationSearchResult(resultsFirstChild, searchResult) {
async function reorderDestinationSearchResult(resultsFirstChild, searchResult) {
// Find containing element for the search result
const closestJsController = searchResult.closest('div[jscontroller]');
const closestDataDiv = searchResult.closest('div[data-hveid].g') || searchResult.closest('div[data-hveid]');
@ -560,7 +565,7 @@ async function reorderSearchResults(searchResults, searchEngine, storage) {
console.debug('Indie Wiki Buddy is not re-ordering results, as an indie wiki is already the first result.');
break;
} else {
await _reorderDestinationSearchResult(resultsFirstChild, searchResult);
await reorderDestinationSearchResult(resultsFirstChild, searchResult);
reorderedHrefs.push(searchResultLink);
}
}
@ -579,7 +584,7 @@ async function filterSearchResults(searchResults, searchEngine, storage, reorder
for (const searchResult of searchResults) {
try {
// Check that result isn't within another result
if (!searchResult.closest('.iwb-detected')) {
if (!searchResult.closest('.iwb-detected') || !searchResult.closest('.iwb-detected')?.querySelector('.iwb-new-link')) {
searchResultLink = searchResult.href || '';
if (!searchResultLink) {
@ -610,7 +615,7 @@ async function filterSearchResults(searchResults, searchEngine, storage, reorder
// Handle source -> destination filtering
let matchingSource = await commonFunctionFindMatchingSite(searchResultLink, crossLanguageSetting);
if (matchingSource) {
countFiltered = await _filterSearchResult(matchingSource, searchResult, searchEngine, countFiltered, storage, reorderedHrefs);
countFiltered = await filterSearchResult(matchingSource, searchResult, searchEngine, countFiltered, storage, reorderedHrefs);
}
}
} catch (e) {
@ -619,23 +624,24 @@ async function filterSearchResults(searchResults, searchEngine, storage, reorder
};
// Add location observer to check for additional mutations
addDOMChangeObserver(main);
addDOMChangeObserver(startFiltering, searchEngine, storage);
// If any results were filtered, update search filter count
if (countFiltered > 0) {
chrome.storage.sync.set({ 'countSearchFilters': (storage.countSearchFilters ?? 0) + countFiltered });
extensionAPI.storage.sync.set({ 'countSearchFilters': (storage.countSearchFilters ?? 0) + countFiltered });
}
}
function main(mutations = null, observer = null) {
function startFiltering(searchEngine, storage, mutations = null, observer = null) {
if (observer) {
observer.disconnect();
}
chrome.runtime.sendMessage({action: 'getStorage'}).then((storage) => {
// Check if extension is on:
if ((storage.power ?? 'on') === 'on') {
// Determine which search engine we're on
if (currentURL.hostname.includes('www.google.')) {
// Check if extension is on:
if ((storage.power ?? 'on') === 'on') {
// Determine which search engine we're on
switch (searchEngine) {
case 'google':
// Function to filter search results in Google
function filterGoogle(reorderedHrefs) {
let searchResults = document.querySelectorAll(`
@ -658,7 +664,8 @@ function main(mutations = null, observer = null) {
// Filtering happens after re-ordering, so that we can filter anything that matches what we re-ordered
filterGoogle(r);
});
} else if (currentURL.hostname.includes('duckduckgo.com') && (currentURL.search.includes('q=') || currentURL.pathname.includes('html'))) {
break;
case 'duckduckgo':
// Function to filter search results in DuckDuckGo
function filterDuckDuckGo() {
let searchResults = document.querySelectorAll('h2>a[href*=".fandom.com"], h2>a[href*=".wiki.fextralife.com"], h2>a[href*=".neoseeker.com/wiki/"]');
@ -666,7 +673,8 @@ function main(mutations = null, observer = null) {
}
filterDuckDuckGo();
} else if (currentURL.hostname.endsWith('.bing.com')) {
break;
case 'bing':
// Function to filter search results in Bing
function filterBing() {
let searchResultsEncoded = document.querySelectorAll('li.b_algo h2 a, li.b_algo .b_algoheader a');
@ -694,7 +702,8 @@ function main(mutations = null, observer = null) {
}
filterBing();
} else if (currentURL.hostname.includes('search.brave.com')) {
break;
case 'brave':
// Function to filter search results in Brave
function filterBrave() {
let searchResults = Array.from(document.querySelectorAll('div.snippet[data-type="web"] a')).filter(el =>
@ -705,7 +714,8 @@ function main(mutations = null, observer = null) {
}
filterBrave();
} else if (currentURL.hostname.includes('ecosia.org')) {
break;
case 'ecosia':
// Function to filter search results in Ecosia
function filterEcosia() {
let searchResults = Array.from(document.querySelectorAll('section.mainline .result__title a.result__link')).filter(el =>
@ -716,7 +726,8 @@ function main(mutations = null, observer = null) {
}
filterEcosia();
} else if (currentURL.hostname.includes('qwant.com')) {
break;
case 'qwant':
// Function to filter search results in Qwant
function filterQwant() {
let searchResults = Array.from(document.querySelectorAll('a[data-testid=serTitle]')).filter(el => el.href.includes('fandom.com') || el.href.includes('fextralife.com'));
@ -724,7 +735,8 @@ function main(mutations = null, observer = null) {
}
filterQwant();
} else if (currentURL.hostname.includes('startpage.com')) {
break;
case 'startpage':
// Function to filter search results in Startpage
function filterStartpage() {
let searchResults = Array.from(document.querySelectorAll('a.result-link')).filter(el =>
@ -735,10 +747,11 @@ function main(mutations = null, observer = null) {
}
filterStartpage();
} else if (currentURL.hostname.includes('yandex.') || currentURL.hostname.includes('ya.ru')) {
break;
case 'yandex':
// Function to filter search results in Yandex
function filterYandex() {
let searchResults = Array.from(document.querySelectorAll('.serp-item a.link, .serp-item a.Link, .MMOrganicSnippet a, .viewer-snippet a')).filter(el =>
let searchResults = Array.from(document.querySelectorAll('li[data-cid] a.link, li[data-cid] a.Link, .serp-item a.link, .serp-item a.Link, .MMOrganicSnippet a, .viewer-snippet a')).filter(el =>
el.href?.includes('.fandom.com') ||
el.href?.includes('.wiki.fextralife.com') ||
el.href?.includes('.neoseeker.com/wiki/'));
@ -746,7 +759,8 @@ function main(mutations = null, observer = null) {
}
filterYandex();
} else if (currentURL.hostname.includes('yahoo.com')) {
break;
case 'yahoo':
// Function to filter search results in Yahoo
function filterYahoo() {
let searchResultsEncoded = document.querySelectorAll('#web > ol > li a:not(.thmb), #main-algo section.algo a:not(.thmb)');
@ -777,7 +791,8 @@ function main(mutations = null, observer = null) {
}
filterYahoo();
} else if (currentURL.hostname.includes('kagi.com')) {
break;
case 'kagi':
// Function to filter search results in Kagi
function filterKagi() {
let searchResults = Array.from(document.querySelectorAll('h3>a, a.__sri-url')).filter(el =>
@ -788,39 +803,73 @@ function main(mutations = null, observer = null) {
}
filterKagi();
} else if (storage.customSearchEngines) {
function filterSearXNG() {
let searchResults = Array.from(document.querySelectorAll('h3>a')).filter(el =>
el.href?.includes('.fandom.com') ||
el.href?.includes('.wiki.fextralife.com') ||
el.href?.includes('.neoseeker.com/wiki/'));
filterSearchResults(searchResults, 'searxng', storage);
}
break;
default:
if (storage.customSearchEngines) {
function filterSearXNG() {
let searchResults = Array.from(document.querySelectorAll('h3>a')).filter(el =>
el.href?.includes('.fandom.com') ||
el.href?.includes('.wiki.fextralife.com') ||
el.href?.includes('.neoseeker.com/wiki/'));
filterSearchResults(searchResults, 'searxng', storage);
}
function filterWhoogle() {
let searchResults = Array.from(document.querySelectorAll('div>a')).filter(el =>
el.href?.includes('.fandom.com') ||
el.href?.includes('.wiki.fextralife.com') ||
el.href?.includes('.neoseeker.com/wiki/'));
filterSearchResults(searchResults, 'whoogle', storage);
}
function filterWhoogle() {
let searchResults = Array.from(document.querySelectorAll('div>a')).filter(el =>
el.href?.includes('.fandom.com') ||
el.href?.includes('.wiki.fextralife.com') ||
el.href?.includes('.neoseeker.com/wiki/'));
filterSearchResults(searchResults, 'whoogle', storage);
}
function filter(searchEngine) {
if (searchEngine === 'searxng') {
filterSearXNG();
} else if (searchEngine === 'whoogle') {
filterWhoogle();
function filter(searchEngine) {
if (searchEngine === 'searxng') {
filterSearXNG();
} else if (searchEngine === 'whoogle') {
filterWhoogle();
}
}
let customSearchEngines = storage.customSearchEngines;
if (customSearchEngines[currentURL.hostname]) {
let customSearchEnginePreset = customSearchEngines[currentURL.hostname];
filter(customSearchEnginePreset);
}
}
}
}
}
let customSearchEngines = storage.customSearchEngines;
if (customSearchEngines[currentURL.hostname]) {
let customSearchEnginePreset = customSearchEngines[currentURL.hostname];
filter(customSearchEnginePreset);
}
}
// Check if user has enabled filtering for the current search engine
// If so, call startFiltering function to start filtering process
function checkIfEnabled(searchEngine) {
extensionAPI.runtime.sendMessage({action: 'getStorage'}, (storage) => {
searchEngineToggles = storage.searchEngineToggles || {};
if (searchEngineToggles[searchEngine] === 'on' || !searchEngineToggles.hasOwnProperty(searchEngine)) {
startFiltering(searchEngine, storage);
}
});
}
main();
// Figure out which search engine we're on
if (currentURL.hostname.includes('www.google.')) {
checkIfEnabled('google');
} else if (currentURL.hostname.includes('duckduckgo.com') && (currentURL.search.includes('q=') || currentURL.pathname.includes('html'))) {
checkIfEnabled('duckduckgo');
} else if (currentURL.hostname.endsWith('.bing.com')) {
checkIfEnabled('bing');
} else if (currentURL.hostname.includes('search.brave.com')) {
checkIfEnabled('brave');
} else if (currentURL.hostname.includes('ecosia.org')) {
checkIfEnabled('ecosia');
} else if (currentURL.hostname.includes('qwant.com')) {
checkIfEnabled('qwant');
} else if (currentURL.hostname.includes('startpage.com')) {
checkIfEnabled('startpage');
} else if (currentURL.hostname.includes('yandex.') || currentURL.hostname.includes('ya.ru')) {
checkIfEnabled('yandex');
} else if (currentURL.hostname.includes('yahoo.com')) {
checkIfEnabled('yahoo');
} else if (currentURL.hostname.includes('kagi.com')) {
checkIfEnabled('kagi');
}