From 8e073c45b6e09ef823a09519955133d400ce044b Mon Sep 17 00:00:00 2001 From: ManagarmrWhisperer Date: Thu, 7 Mar 2024 13:05:29 +0100 Subject: [PATCH 1/2] feat(bing): Bing search engine, using new architecture --- js/search/bing.js | 133 +++++++++++++++++++++++++++++++++++ manifests/chrome_dev.json | 14 +++- rollup-config-background.mjs | 1 + 3 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 js/search/bing.js diff --git a/js/search/bing.js b/js/search/bing.js new file mode 100644 index 0000000..bf2780f --- /dev/null +++ b/js/search/bing.js @@ -0,0 +1,133 @@ +'use strict'; + + +import { getWikis } from '../util.js'; +import { + GenericSearchModule, + prepareWikisInfo, + crawlUntilParentFound, + awaitElement, + RewriteUtil +} from './baseSearch.js'; +import { constructRedirectBadge, constructReplacementMarker } from './components.js'; + + +const wikis = prepareWikisInfo( getWikis( false, true ), { + titles: true, + selectors: true +} ); + + +class DdgSearchModule extends GenericSearchModule { + ENGINE_LAYOUT_SELECTOR = '#b_results'; + RESULT_CONTAINER_SELECTOR = 'li.b_algo, div.slide'; + ORDINARY_RESULT_CLASS_NAME = 'b_algo'; + URL_ELEMENT_SELECTOR = 'h2#b_topTitle'; + SPAN_TITLE_ELEMENT_SELECTOR = 'h2 > a'; + ANCHOR_ELEMENT_SELECTOR = 'div > cite'; + NETWORK_NAME_ELEMENT_SELECTOR = '.tptt'; + BLACKLIST = 'slide'; // TODO: This should be a list + /** + * @protected + * @return {string} + */ + getId() { + return 'ddg'; + } + + + /** + * Finds a general result container for a given element, if any. + * + * @protected + * @param {HTMLElement} element Element to find result container for. + * @return {HTMLElement?} + */ + resolveResultContainer( element ) { + return crawlUntilParentFound( element, this.RESULT_CONTAINER_SELECTOR ); + } + + /** + * @protected + * @param {SiteRecord} wikiInfo + * @param {HTMLElement} boundaryElement + * @return {HTMLElement?} + */ + + findNearestGgResult( wikiInfo, boundaryElement ) { + for ( const node of document.querySelectorAll( wikiInfo.search.goodSelector ) ) { + if ( this.isBlacklisted( node ) && ( node.compareDocumentPosition( boundaryElement ) & 0x02 ) ) { + return crawlUntilParentFound( node, this.RESULT_CONTAINER_SELECTOR ); + } + } + return null; + } + + /** + * @protected + * @param {SiteRecord} wikiInfo + * @param {HTMLElement} containerElement + * @param {HTMLElement} _foundLinkElement + */ + async hideResult( wikiInfo, containerElement, _foundLinkElement ) { + // This is just a placeholder, what if we had different elements? + if ( containerElement.classList.contains( this.ORDINARY_RESULT_CLASS_NAME ) ) { + + // Try to find the first wiki.gg result after this one + const ggResult = this.findNearestGgResult( wikiInfo, containerElement ); + + let replacement; + if ( ggResult ) { + replacement = ggResult; + } else { + replacement = constructReplacementMarker( wikiInfo ); + } + containerElement.textContent = ''; + containerElement.append( replacement ); + } else { + containerElement.style.display = 'none'; + } + + } + + + /** + * @protected + * @param {SiteRecord} wikiInfo + * @param {HTMLElement} containerElement + * @param {HTMLElement} _foundLinkElement + */ + async replaceResult( wikiInfo, containerElement, _foundLinkElement ) { + // Rewrite anchor href links + for ( const a of containerElement.getElementsByTagName( 'a' ) ) { + RewriteUtil.doLink( wikiInfo, a ); + } + + // Rewrite title and append a badge + // TODO: Maybe use All just incase that we get more elements + const titleSpan = containerElement.querySelector( this.SPAN_TITLE_ELEMENT_SELECTOR ); + if ( wikiInfo.search.titlePattern.test( titleSpan.textContent ) ) { + RewriteUtil.doH3( wikiInfo, titleSpan ); + } + + // Insert our badge + const badgeElement = constructRedirectBadge( { + allMoved: true, + theme: { + fontSize: '60%', + color: '#222' + } + } ); + titleSpan.appendChild( badgeElement ); + + // Rewrite URL breadcrumb + for ( const url of containerElement.querySelectorAll( this.ANCHOR_ELEMENT_SELECTOR ) ) { + RewriteUtil.doUrlSpan( wikiInfo, url ); + } + + // Rewrite network name + containerElement.querySelector( this.NETWORK_NAME_ELEMENT_SELECTOR ).textContent = 'wiki.gg'; + } +} + +DdgSearchModule.invoke( wikis ); diff --git a/manifests/chrome_dev.json b/manifests/chrome_dev.json index 7b54f26..e2e32ae 100644 --- a/manifests/chrome_dev.json +++ b/manifests/chrome_dev.json @@ -74,7 +74,18 @@ "built/fandom.js" ], "run_at": "document_end" + }, + { + "matches": [ + "https://www.bing.com/*" + ], + "js": [ + "built/bing.js" + ], + "run_at": "document_end" } + + ], "icons": { "128": "icons/128_dev.png" @@ -113,7 +124,8 @@ "https://www.google.nl/*", "https://www.google.pl/*", "https://www.google.pt/*", - "https://duckduckgo.com/*" + "https://duckduckgo.com/*", + "https://www.bing.com/*" ] } ], diff --git a/rollup-config-background.mjs b/rollup-config-background.mjs index 0cacfc7..7b296a1 100644 --- a/rollup-config-background.mjs +++ b/rollup-config-background.mjs @@ -6,6 +6,7 @@ const scripts = [ { script: 'popup' }, { script: 'search/google', output: 'google', isContentScript: true }, { script: 'search/ddg', output: 'ddg', isContentScript: true }, + { script: 'search/bing', output: 'bing', isContentScript: true }, { script: 'fandom', isContentScript: true }, ]; From 07bdb31193e30a796e44f1bedde26dacdc222247 Mon Sep 17 00:00:00 2001 From: ManagarmrWhisperer Date: Sat, 16 Mar 2024 23:44:51 +0100 Subject: [PATCH 2/2] feat(bing): added popup buttons, cleaned up code --- defaults.js | 4 ++++ js/popup/SearchFilterSettings.js | 5 +++++ js/search/bing.js | 6 +++--- manifests/chrome_dev.json | 3 ++- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/defaults.js b/defaults.js index e88e45f..df3cfed 100644 --- a/defaults.js +++ b/defaults.js @@ -43,7 +43,11 @@ export default function () { }, ddg: { mode: 'rewrite' + }, + bing: { + mode: 'rewrite' } + } }; } diff --git a/js/popup/SearchFilterSettings.js b/js/popup/SearchFilterSettings.js index 4b171be..032f575 100644 --- a/js/popup/SearchFilterSettings.js +++ b/js/popup/SearchFilterSettings.js @@ -25,6 +25,11 @@ export default class SearchFilterSettings { supportsFilter: true, supportsRewrite: true, }, + { + id: 'bing', + supportsFilter: true, + supportsRewrite: true, + } ]; diff --git a/js/search/bing.js b/js/search/bing.js index bf2780f..8f12628 100644 --- a/js/search/bing.js +++ b/js/search/bing.js @@ -32,7 +32,7 @@ class DdgSearchModule extends GenericSearchModule { * @return {string} */ getId() { - return 'ddg'; + return 'bing'; } @@ -56,8 +56,8 @@ class DdgSearchModule extends GenericSearchModule { findNearestGgResult( wikiInfo, boundaryElement ) { for ( const node of document.querySelectorAll( wikiInfo.search.goodSelector ) ) { - if ( this.isBlacklisted( node ) && ( node.compareDocumentPosition( boundaryElement ) & 0x02 ) ) { - return crawlUntilParentFound( node, this.RESULT_CONTAINER_SELECTOR ); + if ( node.compareDocumentPosition( boundaryElement ) & 0x02 ) { + return crawlUntilParentFound( node, this.ORDINARY_RESULT_CLASS_NAME ); } } return null; diff --git a/manifests/chrome_dev.json b/manifests/chrome_dev.json index e2e32ae..91f7682 100644 --- a/manifests/chrome_dev.json +++ b/manifests/chrome_dev.json @@ -125,7 +125,8 @@ "https://www.google.pl/*", "https://www.google.pt/*", "https://duckduckgo.com/*", - "https://www.bing.com/*" + "https://www.bing.com/*", + "https://www.startpage.com/*" ] } ],