Loading toolkit/components/search/ConfigSearchEngine.sys.mjs +16 −38 Original line number Diff line number Diff line Loading @@ -112,6 +112,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 @@ -128,29 +132,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 @@ -234,27 +216,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 +22 −49 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 @@ -91,42 +92,19 @@ export class SearchEngineSelector { return this.#getConfigurationPromise; } this.#getConfigurationPromise = Promise.all([ this.#getConfiguration(), this.#getConfigurationOverrides(), ]); let remoteSettingsData = await this.#getConfigurationPromise; this.#configuration = remoteSettingsData[0]; this.#getConfigurationPromise = null; if (!this.#configuration?.length) { 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) { this.#remoteConfig.on("sync", this.#boundOnConfigurationUpdated); this.#remoteConfigOverrides.on( "sync", this.#boundOnConfigurationOverridesUpdated ); /** * Records whether the listeners have been added or not. */ this.#listenerAdded = true; } let { promise, resolve } = Promise.withResolvers(); this.#getConfigurationPromise = promise; this.#configuration = await ( await fetch( "chrome://global/content/search/base-browser-search-engines.json" ) ).json(); resolve(this.#configuration); this.#selector.setSearchConfig( JSON.stringify({ data: this.#configuration }) ); this.#selector.setConfigOverrides( JSON.stringify({ data: remoteSettingsData[1] }) ); this.#selector.setConfigOverrides(JSON.stringify({ data: [] })); return this.#configuration; } Loading Loading @@ -369,6 +347,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 @@ -396,6 +380,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 @@ -404,23 +394,6 @@ export class SearchEngineSelector { } } /** * Obtains the configuration overrides from remote settings. * * @returns {Promise<object[]>} * An array of objects in the database, or an empty array if none * could be obtained. */ async #getConfigurationOverrides() { let result = []; try { result = await this.#remoteConfigOverrides.get(); } catch (ex) { // This data is remote only, so we just return an empty array if it fails. } return result; } /** * @type {InstanceType<typeof lazy.SearchEngineSelector>?} */ Loading toolkit/components/search/content/base-browser-search-engine-icons.json 0 → 100644 +15 −0 Original line number Diff line number Diff line { "ddg": [ { "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 +43 −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": ["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" } ] 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 @@ -112,6 +112,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 @@ -128,29 +132,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 @@ -234,27 +216,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 +22 −49 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 @@ -91,42 +92,19 @@ export class SearchEngineSelector { return this.#getConfigurationPromise; } this.#getConfigurationPromise = Promise.all([ this.#getConfiguration(), this.#getConfigurationOverrides(), ]); let remoteSettingsData = await this.#getConfigurationPromise; this.#configuration = remoteSettingsData[0]; this.#getConfigurationPromise = null; if (!this.#configuration?.length) { 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) { this.#remoteConfig.on("sync", this.#boundOnConfigurationUpdated); this.#remoteConfigOverrides.on( "sync", this.#boundOnConfigurationOverridesUpdated ); /** * Records whether the listeners have been added or not. */ this.#listenerAdded = true; } let { promise, resolve } = Promise.withResolvers(); this.#getConfigurationPromise = promise; this.#configuration = await ( await fetch( "chrome://global/content/search/base-browser-search-engines.json" ) ).json(); resolve(this.#configuration); this.#selector.setSearchConfig( JSON.stringify({ data: this.#configuration }) ); this.#selector.setConfigOverrides( JSON.stringify({ data: remoteSettingsData[1] }) ); this.#selector.setConfigOverrides(JSON.stringify({ data: [] })); return this.#configuration; } Loading Loading @@ -369,6 +347,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 @@ -396,6 +380,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 @@ -404,23 +394,6 @@ export class SearchEngineSelector { } } /** * Obtains the configuration overrides from remote settings. * * @returns {Promise<object[]>} * An array of objects in the database, or an empty array if none * could be obtained. */ async #getConfigurationOverrides() { let result = []; try { result = await this.#remoteConfigOverrides.get(); } catch (ex) { // This data is remote only, so we just return an empty array if it fails. } return result; } /** * @type {InstanceType<typeof lazy.SearchEngineSelector>?} */ Loading
toolkit/components/search/content/base-browser-search-engine-icons.json 0 → 100644 +15 −0 Original line number Diff line number Diff line { "ddg": [ { "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 +43 −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": ["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" } ]