Loading toolkit/components/search/ConfigSearchEngine.sys.mjs +16 −38 Original line number Diff line number Diff line Loading @@ -113,6 +113,10 @@ class IconHandler { await this.#buildIconMap(); } if (AppConstants.BASE_BROWSER_VERSION) { return this.#iconMap.get(engineIdentifier); } let iconList = this.#iconMap.get(this.getKey(engineIdentifier)) || []; return iconList.filter(r => this.#identifierMatches(engineIdentifier, r.engineIdentifiers) Loading @@ -129,29 +133,7 @@ class IconHandler { * source object or null of there is no icon with the supplied width. */ async createIconURL(iconRecord) { let iconData; try { iconData = await this.#iconCollection.attachments.get(iconRecord); } catch (ex) { console.error(ex); } if (!iconData) { console.warn("Unable to find the attachment for", iconRecord.id); // Queue an update in case we haven't downloaded it yet. this.#pendingUpdatesMap.set(iconRecord.id, iconRecord); this.#maybeQueueIdle(); return null; } if (iconData.record.last_modified != iconRecord.last_modified) { // The icon we have stored is out of date, queue an update so that we'll // download the new icon. this.#pendingUpdatesMap.set(iconRecord.id, iconRecord); this.#maybeQueueIdle(); } return URL.createObjectURL( new Blob([iconData.buffer], { type: iconRecord.attachment.mimetype }) ); return iconRecord.url; } QueryInterface = ChromeUtils.generateQI(["nsIObserver"]); Loading Loading @@ -235,27 +217,23 @@ class IconHandler { * Obtains the icon list from the remote settings collection. */ async #buildIconMap() { let iconList = []; try { iconList = await this.#iconCollection.get(); this.#iconMap = new Map( Object.entries( await ( await fetch( "chrome://global/content/search/base-browser-search-engine-icons.json" ) ).json() ) ); } catch (ex) { console.error(ex); this.#iconMap = null; } if (!iconList.length) { if (!this.#iconMap) { console.error("Failed to obtain search engine icon list records"); } this.#iconMap = new Map(); for (let record of iconList) { let keys = new Set(record.engineIdentifiers.map(this.getKey)); for (let key of keys) { if (this.#iconMap.has(key)) { this.#iconMap.get(key).push(record); } else { this.#iconMap.set(key, [record]); } } } } /** Loading toolkit/components/search/SearchEngineSelector.sys.mjs +34 −3 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ * } from "../uniffi-bindgen-gecko-js/components/generated/RustSearch.sys.mjs"; */ import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs"; import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs"; const lazy = XPCOMUtils.declareLazy({ Loading Loading @@ -97,16 +98,21 @@ export class SearchEngineSelector { ]); let remoteSettingsData = await this.#getConfigurationPromise; this.#configuration = remoteSettingsData[0]; this.#getConfigurationPromise = null; // For Base Browser, we don't expect the configuration to ever change in a // session, so we keep the #getConfigurationPromise as-is for later calls. if (!this.#configuration?.length) { throw new Error("Failed to get engine data from Remote Settings"); throw Components.Exception( "Failed to get engine data from Remote Settings", Cr.NS_ERROR_UNEXPECTED ); } /** * Records whether the listeners have been added or not. */ if (!this.#listenerAdded) { // For Base Browser, we don't use remoteConfig. tor-browser#43525. if (!AppConstants.BASE_BROWSER_VERSION && !this.#listenerAdded) { this.#remoteConfig.on("sync", this.#boundOnConfigurationUpdated); this.#remoteConfigOverrides.on( "sync", Loading Loading @@ -328,6 +334,15 @@ export class SearchEngineSelector { * could be obtained. */ async #getConfiguration(firstTime = true) { if (AppConstants.BASE_BROWSER_VERSION) { // For Base Browser, load the config from a local file, rather than // #remoteConfig. tor-browser#43525. return ( await fetch( "chrome://global/content/search/base-browser-search-engines.json" ) ).json(); } let result = []; let failed = false; try { Loading Loading @@ -366,6 +381,12 @@ export class SearchEngineSelector { * The new configuration object */ _onConfigurationUpdated({ data: { current } }) { // tor-browser#43525: Even though RemoteSettings are a no-op for us, we do // not want them to interfere in any way. if (AppConstants.BASE_BROWSER_VERSION) { return; } this.#configuration = current; this.#selector.setSearchConfig( Loading Loading @@ -393,6 +414,12 @@ export class SearchEngineSelector { * The new configuration object */ _onConfigurationOverridesUpdated({ data: { current } }) { // tor-browser#43525: Even though RemoteSettings are a no-op for us, we do // not want them to interfere in any way. if (AppConstants.BASE_BROWSER_VERSION) { return; } this.#selector.setConfigOverrides(JSON.stringify({ data: current })); lazy.logConsole.debug("Search configuration overrides updated remotely"); Loading @@ -409,6 +436,10 @@ export class SearchEngineSelector { * could be obtained. */ async #getConfigurationOverrides() { if (AppConstants.BASE_BROWSER_VERSION) { // For Base Browser, we don't want overrides. tor-browser#43525. return []; } let result = []; try { result = await this.#remoteConfigOverrides.get(); Loading toolkit/components/search/content/base-browser-search-engine-icons.json 0 → 100644 +18 −0 Original line number Diff line number Diff line { "ddg": [ { "url": "chrome://global/content/search/duckduckgo.ico", "imageSize": 32 } ], "ddg-noai": [ { "url": "chrome://global/content/search/duckduckgo.ico", "imageSize": 32 } ], "startpage": [ { "url": "chrome://global/content/search/startpage-16.png", "imageSize": 16 }, { "url": "chrome://global/content/search/startpage-32.png", "imageSize": 32 } ] } toolkit/components/search/content/base-browser-search-engines.json 0 → 100644 +70 −0 Original line number Diff line number Diff line [ { "base": { "aliases": ["duckduckgo", "ddg"], "classification": "general", "name": "DuckDuckGo", "urls": { "search": { "base": "https://duckduckgo.com/", "params": [], "searchTermParamName": "q" } } }, "id": "04e99a38-13ee-47d8-8aa4-64482b3dea99", "identifier": "ddg", "recordType": "engine", "variants": [{ "environment": { "allRegionsAndLocales": true } }] }, { "base": { "aliases": ["ddgnoai"], "classification": "general", "name": "DuckDuckGo (no AI)", "urls": { "search": { "base": "https://noai.duckduckgo.com/", "params": [], "searchTermParamName": "q" } } }, "id": "91687f02-56dd-4fef-ba26-bf139dff3166", "identifier": "ddg-noai", "recordType": "engine", "variants": [{ "environment": { "allRegionsAndLocales": true } }] }, { "base": { "aliases": ["startpage", "sp"], "classification": "general", "name": "Startpage", "urls": { "search": { "base": "https://www.startpage.com/sp/search", "params": [], "searchTermParamName": "q" } } }, "id": "927bbd9f-b2f3-48b4-8974-1c1148028f4d", "identifier": "startpage", "recordType": "engine", "variants": [{ "environment": { "allRegionsAndLocales": true } }] }, { "recordType": "defaultEngines", "globalDefault": "ddg", "globalDefaultPrivate": "ddg" }, { "recordType": "engineOrders", "orders": [ { "environment": { "allRegionsAndLocales": true }, "order": ["ddg", "ddg-noai", "startpage"] } ] } ] toolkit/components/search/content/duckduckgo.ico 0 → 100644 +2.73 KiB Loading image diff... Loading
toolkit/components/search/ConfigSearchEngine.sys.mjs +16 −38 Original line number Diff line number Diff line Loading @@ -113,6 +113,10 @@ class IconHandler { await this.#buildIconMap(); } if (AppConstants.BASE_BROWSER_VERSION) { return this.#iconMap.get(engineIdentifier); } let iconList = this.#iconMap.get(this.getKey(engineIdentifier)) || []; return iconList.filter(r => this.#identifierMatches(engineIdentifier, r.engineIdentifiers) Loading @@ -129,29 +133,7 @@ class IconHandler { * source object or null of there is no icon with the supplied width. */ async createIconURL(iconRecord) { let iconData; try { iconData = await this.#iconCollection.attachments.get(iconRecord); } catch (ex) { console.error(ex); } if (!iconData) { console.warn("Unable to find the attachment for", iconRecord.id); // Queue an update in case we haven't downloaded it yet. this.#pendingUpdatesMap.set(iconRecord.id, iconRecord); this.#maybeQueueIdle(); return null; } if (iconData.record.last_modified != iconRecord.last_modified) { // The icon we have stored is out of date, queue an update so that we'll // download the new icon. this.#pendingUpdatesMap.set(iconRecord.id, iconRecord); this.#maybeQueueIdle(); } return URL.createObjectURL( new Blob([iconData.buffer], { type: iconRecord.attachment.mimetype }) ); return iconRecord.url; } QueryInterface = ChromeUtils.generateQI(["nsIObserver"]); Loading Loading @@ -235,27 +217,23 @@ class IconHandler { * Obtains the icon list from the remote settings collection. */ async #buildIconMap() { let iconList = []; try { iconList = await this.#iconCollection.get(); this.#iconMap = new Map( Object.entries( await ( await fetch( "chrome://global/content/search/base-browser-search-engine-icons.json" ) ).json() ) ); } catch (ex) { console.error(ex); this.#iconMap = null; } if (!iconList.length) { if (!this.#iconMap) { console.error("Failed to obtain search engine icon list records"); } this.#iconMap = new Map(); for (let record of iconList) { let keys = new Set(record.engineIdentifiers.map(this.getKey)); for (let key of keys) { if (this.#iconMap.has(key)) { this.#iconMap.get(key).push(record); } else { this.#iconMap.set(key, [record]); } } } } /** Loading
toolkit/components/search/SearchEngineSelector.sys.mjs +34 −3 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ * } from "../uniffi-bindgen-gecko-js/components/generated/RustSearch.sys.mjs"; */ import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs"; import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs"; const lazy = XPCOMUtils.declareLazy({ Loading Loading @@ -97,16 +98,21 @@ export class SearchEngineSelector { ]); let remoteSettingsData = await this.#getConfigurationPromise; this.#configuration = remoteSettingsData[0]; this.#getConfigurationPromise = null; // For Base Browser, we don't expect the configuration to ever change in a // session, so we keep the #getConfigurationPromise as-is for later calls. if (!this.#configuration?.length) { throw new Error("Failed to get engine data from Remote Settings"); throw Components.Exception( "Failed to get engine data from Remote Settings", Cr.NS_ERROR_UNEXPECTED ); } /** * Records whether the listeners have been added or not. */ if (!this.#listenerAdded) { // For Base Browser, we don't use remoteConfig. tor-browser#43525. if (!AppConstants.BASE_BROWSER_VERSION && !this.#listenerAdded) { this.#remoteConfig.on("sync", this.#boundOnConfigurationUpdated); this.#remoteConfigOverrides.on( "sync", Loading Loading @@ -328,6 +334,15 @@ export class SearchEngineSelector { * could be obtained. */ async #getConfiguration(firstTime = true) { if (AppConstants.BASE_BROWSER_VERSION) { // For Base Browser, load the config from a local file, rather than // #remoteConfig. tor-browser#43525. return ( await fetch( "chrome://global/content/search/base-browser-search-engines.json" ) ).json(); } let result = []; let failed = false; try { Loading Loading @@ -366,6 +381,12 @@ export class SearchEngineSelector { * The new configuration object */ _onConfigurationUpdated({ data: { current } }) { // tor-browser#43525: Even though RemoteSettings are a no-op for us, we do // not want them to interfere in any way. if (AppConstants.BASE_BROWSER_VERSION) { return; } this.#configuration = current; this.#selector.setSearchConfig( Loading Loading @@ -393,6 +414,12 @@ export class SearchEngineSelector { * The new configuration object */ _onConfigurationOverridesUpdated({ data: { current } }) { // tor-browser#43525: Even though RemoteSettings are a no-op for us, we do // not want them to interfere in any way. if (AppConstants.BASE_BROWSER_VERSION) { return; } this.#selector.setConfigOverrides(JSON.stringify({ data: current })); lazy.logConsole.debug("Search configuration overrides updated remotely"); Loading @@ -409,6 +436,10 @@ export class SearchEngineSelector { * could be obtained. */ async #getConfigurationOverrides() { if (AppConstants.BASE_BROWSER_VERSION) { // For Base Browser, we don't want overrides. tor-browser#43525. return []; } let result = []; try { result = await this.#remoteConfigOverrides.get(); Loading
toolkit/components/search/content/base-browser-search-engine-icons.json 0 → 100644 +18 −0 Original line number Diff line number Diff line { "ddg": [ { "url": "chrome://global/content/search/duckduckgo.ico", "imageSize": 32 } ], "ddg-noai": [ { "url": "chrome://global/content/search/duckduckgo.ico", "imageSize": 32 } ], "startpage": [ { "url": "chrome://global/content/search/startpage-16.png", "imageSize": 16 }, { "url": "chrome://global/content/search/startpage-32.png", "imageSize": 32 } ] }
toolkit/components/search/content/base-browser-search-engines.json 0 → 100644 +70 −0 Original line number Diff line number Diff line [ { "base": { "aliases": ["duckduckgo", "ddg"], "classification": "general", "name": "DuckDuckGo", "urls": { "search": { "base": "https://duckduckgo.com/", "params": [], "searchTermParamName": "q" } } }, "id": "04e99a38-13ee-47d8-8aa4-64482b3dea99", "identifier": "ddg", "recordType": "engine", "variants": [{ "environment": { "allRegionsAndLocales": true } }] }, { "base": { "aliases": ["ddgnoai"], "classification": "general", "name": "DuckDuckGo (no AI)", "urls": { "search": { "base": "https://noai.duckduckgo.com/", "params": [], "searchTermParamName": "q" } } }, "id": "91687f02-56dd-4fef-ba26-bf139dff3166", "identifier": "ddg-noai", "recordType": "engine", "variants": [{ "environment": { "allRegionsAndLocales": true } }] }, { "base": { "aliases": ["startpage", "sp"], "classification": "general", "name": "Startpage", "urls": { "search": { "base": "https://www.startpage.com/sp/search", "params": [], "searchTermParamName": "q" } } }, "id": "927bbd9f-b2f3-48b4-8974-1c1148028f4d", "identifier": "startpage", "recordType": "engine", "variants": [{ "environment": { "allRegionsAndLocales": true } }] }, { "recordType": "defaultEngines", "globalDefault": "ddg", "globalDefaultPrivate": "ddg" }, { "recordType": "engineOrders", "orders": [ { "environment": { "allRegionsAndLocales": true }, "order": ["ddg", "ddg-noai", "startpage"] } ] } ]