Fixes for search engine result reordering

Fixed bug where search engine result re-ordering was not taking into account whether a user has disabled search engine filtering for a particular wiki. Also, search engine result re-ordering can now detect and compare main pages (for the purpose of hiding duplicate results from non-indie wikis).
pull/958/head
Kevin Payravi 2024-11-17 02:41:59 -05:00
parent 449682d93f
commit 2fbf9a33dc
1 changed files with 117 additions and 96 deletions

View File

@ -137,64 +137,64 @@ function replaceSearchResult(searchResultContainer, wikiInfo, link) {
*/
function mountToTopOfSearchResults(element) {
switch (searchEngine) {
case 'google':
if (document.querySelector('#search')) {
document.querySelector('#search')?.prepend(element);
} else if (document.querySelector('#topstuff')) {
document.querySelector('#topstuff')?.prepend(element);
} else if (document.querySelector('#main')) {
document.querySelector('#main > div:nth-of-type(2)')?.insertAdjacentElement('beforebegin', element);
}
break;
case 'bing':
case 'google':
if (document.querySelector('#search')) {
document.querySelector('#search')?.prepend(element);
} else if (document.querySelector('#topstuff')) {
document.querySelector('#topstuff')?.prepend(element);
} else if (document.querySelector('#main')) {
document.querySelector('#main > div:nth-of-type(2)')?.insertAdjacentElement('beforebegin', element);
}
break;
case 'bing':
var li = document.createElement('li');
li.appendChild(element);
document.querySelector('#b_results')?.prepend(li);
break;
case 'duckduckgo':
if (document.getElementById('web_content_wrapper')) {
var li = document.createElement('li');
li.appendChild(element);
document.querySelector('#b_results')?.prepend(li);
break;
case 'duckduckgo':
if (document.getElementById('web_content_wrapper')) {
var li = document.createElement('li');
li.appendChild(element);
document.querySelector('#web_content_wrapper ol')?.prepend(li);
} else {
document.getElementById('links')?.prepend(element);
}
break;
case 'brave':
document.getElementById('results')?.prepend(element);
break;
case 'ecosia':
document.querySelector('section.mainline')?.prepend(element);
break;
case 'qwant':
document.querySelector('div[data-testid=sectionWeb]')?.prepend(element);
break;
case 'startpage':
document.querySelector('#main')?.prepend(element);
break;
case 'yandex':
var searchResultsContainer = document.querySelector('#search-result') || document.querySelector('.main__content .content');
searchResultsContainer?.prepend(element);
break;
case 'yahoo':
if (document.querySelector('#web > ol')) {
var li = document.createElement('li');
li.appendChild(element);
document.querySelector('#web > ol')?.prepend(li);
} else {
document.querySelector('#main-algo')?.prepend(element);
}
break;
case 'kagi':
document.querySelector('#main')?.prepend(element);
break;
case 'searxng':
document.querySelector('#results')?.prepend(element);
break;
case 'whoogle':
document.querySelector('#main')?.prepend(element);
break;
default:
document.querySelector('#web_content_wrapper ol')?.prepend(li);
} else {
document.getElementById('links')?.prepend(element);
}
break;
case 'brave':
document.getElementById('results')?.prepend(element);
break;
case 'ecosia':
document.querySelector('section.mainline')?.prepend(element);
break;
case 'qwant':
document.querySelector('div[data-testid=sectionWeb]')?.prepend(element);
break;
case 'startpage':
document.querySelector('#main')?.prepend(element);
break;
case 'yandex':
var searchResultsContainer = document.querySelector('#search-result') || document.querySelector('.main__content .content');
searchResultsContainer?.prepend(element);
break;
case 'yahoo':
if (document.querySelector('#web > ol')) {
var li = document.createElement('li');
li.appendChild(element);
document.querySelector('#web > ol')?.prepend(li);
} else {
document.querySelector('#main-algo')?.prepend(element);
}
break;
case 'kagi':
document.querySelector('#main')?.prepend(element);
break;
case 'searxng':
document.querySelector('#results')?.prepend(element);
break;
case 'whoogle':
document.querySelector('#main')?.prepend(element);
break;
default:
}
// Return whether element was successfully mounted
@ -385,45 +385,60 @@ function getResultContainer(searchEngine, searchResult) {
}
/**
* @param {SiteData} wikiInfo
* @param {HTMLAnchorElement} anchorElement
* Given a wiki ID, returns the corresponding search filter setting
* @param {string} wikiId
*/
function filterSearchResult(wikiInfo, anchorElement) {
// Get user's settings for the wiki
let id = wikiInfo.id;
function getSearchFilterSetting(wikiId) {
let searchFilterSetting = 'replace';
let reorderResults = storage.reorderResults ?? 'on';
let searchEngineSettings = storage.searchEngineSettings ?? {};
if (searchEngineSettings[id]) {
searchFilterSetting = searchEngineSettings[id];
if (searchEngineSettings[wikiId]) {
searchFilterSetting = searchEngineSettings[wikiId];
} else if (storage.defaultSearchAction) {
searchFilterSetting = storage.defaultSearchAction;
}
return searchFilterSetting;
}
/**
* @param {SiteData} wikiInfo
* @param {HTMLAnchorElement} anchorElement
*/
function filterSearchResult(wikiInfo, anchorElement) {
let countFiltered = 0;
// Get the containing element for the search result
let searchResultContainer = getResultContainer(searchEngine, anchorElement);
if (searchResultContainer) {
// If this page from Fandom is the same as a re-ordered page, filter it out
let searchResultLink = anchorElement.getAttribute('data-iwb-href') || anchorElement.href;
let originArticle = commonFunctionGetOriginArticle(searchResultLink, wikiInfo);
let destinationArticle = commonFunctionGetDestinationArticle(wikiInfo, originArticle);
if (getSearchFilterSetting(wikiInfo.id) !== 'disabled') {
// Get user's reorder settings
let reorderResults = storage.reorderResults ?? 'on';
if (reorderResults === 'on' && processedCache.find(({ url }) => url.match(
// Match for destination URL with content path and article name
new RegExp(
`http(s)?://${wikiInfo.destination_base_url}${wikiInfo.destination_content_path}${decodeURI(destinationArticle)}$`
)
))) {
countFiltered += hideSearchResults(searchResultContainer, wikiInfo, 'off');
console.debug(`Indie Wiki Buddy has hidden a result matching ${searchResultLink} because we re-ordered an indie wiki result with a matching article`);
} else if (searchFilterSetting !== 'disabled') {
if (searchFilterSetting === 'hide') {
// Else, if the user has the preference set to hide search results, hide it indiscriminately
countFiltered += hideSearchResults(searchResultContainer, wikiInfo, storage['hiddenResultsBanner']);
// Get the containing element for the search result
let searchResultContainer = getResultContainer(searchEngine, anchorElement);
if (searchResultContainer) {
// If this page from the non-indie wiki is the same as a re-ordered page, filter it out
let searchResultLink = anchorElement.getAttribute('data-iwb-href') || anchorElement.href;
let originArticle = commonFunctionGetOriginArticle(searchResultLink, wikiInfo);
let destinationArticle = commonFunctionGetDestinationArticle(wikiInfo, originArticle);
if (reorderResults === 'on' && ((processedCache.find(({ url }) => url.match(
// Match for destination URL with content path and article name
new RegExp(
`http(s)?://${wikiInfo.destination_base_url}${wikiInfo.destination_content_path}${decodeURI(destinationArticle)}$`
)
))) || ((originArticle === wikiInfo.origin_main_page) && processedCache.find(({ url }) => url.match(
// Match for destination URL by main page, when applicable
new RegExp(
`http(s)?://${wikiInfo.destination_base_url}${wikiInfo.destination_content_path}${decodeURI(wikiInfo.destination_main_page)}$`
)
))))) {
countFiltered += hideSearchResults(searchResultContainer, wikiInfo, 'off');
console.debug(`Indie Wiki Buddy has hidden a result matching ${searchResultLink} because we re-ordered an indie wiki result with a matching article`);
} else {
countFiltered += replaceSearchResult(searchResultContainer, wikiInfo, searchResultLink);
if (getSearchFilterSetting(wikiInfo.id) === 'hide') {
// Else, if the user has the preference set to hide search results, hide it indiscriminately
countFiltered += hideSearchResults(searchResultContainer, wikiInfo, storage['hiddenResultsBanner']);
} else {
countFiltered += replaceSearchResult(searchResultContainer, wikiInfo, searchResultLink);
}
}
}
}
@ -498,9 +513,11 @@ async function filterSearchResults(searchResults) {
// Handle source -> destination filtering, i.e. non-indie/commercial wikis
let matchingNonIndieWiki = await commonFunctionFindMatchingSite(searchResultLink, crossLanguageSetting);
if (matchingNonIndieWiki) {
console.debug('Indie Wiki Buddy: Filtering search result:', searchResultLink);
// Site found in db, process search result
console.debug('Indie Wiki Buddy: Filtering search result:', searchResultLink);
countFiltered += filterSearchResult(matchingNonIndieWiki, searchResult);
processedCache.push({
url: searchResultLink,
isNonIndie: true,
@ -521,18 +538,22 @@ async function filterSearchResults(searchResults) {
anchor: searchResult,
};
if ((storage.reorderResults ?? 'on') == 'on' && processedCache.at(-1)?.isNonIndie) {
console.debug('Indie Wiki Buddy: Reordering search result:', searchResultLink);
if (getSearchFilterSetting(matchingIndieWiki.id) !== 'disabled') {
if ((storage.reorderResults ?? 'on') == 'on' && processedCache.at(-1)?.isNonIndie) {
console.debug('Indie Wiki Buddy: Reordering search result:', searchResultLink);
const index = processedCache.findIndex(({ isNonIndie }) => isNonIndie);
// push cacheInfo right before the first non-indie wiki
processedCache.splice(index, 0, cacheInfo);
// swap the elements upwards until the indie wiki is above the non-indie wiki
for (let i = processedCache.length - 1; i > index; i--) {
const prev = processedCache[i];
swapDOMElements(prev.container, searchResultContainer);
// try re-filtering the element that was swapped
countFiltered += filterSearchResult(prev.siteData, prev.anchor);
const index = processedCache.findIndex(({ isNonIndie }) => isNonIndie);
// push cacheInfo right before the first non-indie wiki
processedCache.splice(index, 0, cacheInfo);
// swap the elements upwards until the indie wiki is above the non-indie wiki
for (let i = processedCache.length - 1; i > index; i--) {
const prev = processedCache[i];
swapDOMElements(prev.container, searchResultContainer);
// try re-filtering the element that was swapped
countFiltered += filterSearchResult(prev.siteData, prev.anchor);
}
} else {
processedCache.push(cacheInfo);
}
} else {
processedCache.push(cacheInfo);