Commits:
-
fd210716
by Pier Angelo Vendrame at 2025-09-08T11:52:36+02:00
fixup! MB 213: Customize the search engines list
BB 43525: Skip Remote Settings for search engine customization.
Drop some changes that we are not going to keep with the shared
approach.
-
0c345e48
by Pier Angelo Vendrame at 2025-09-08T11:53:16+02:00
dropme! MB 213: Customize the search engines list
BB 43525: Skip Remote Settings for search engine customization.
Prepare the tree for the new approach.
-
e95419fa
by Pier Angelo Vendrame at 2025-09-08T11:53:17+02:00
BB 43525: Skip Remote Settings for search engine customization.
Also, add some bundled search engines.
-
b80c84c1
by Pier Angelo Vendrame at 2025-09-08T11:53:17+02:00
amend! MB 213: Customize the search engines list
MB 213: Customize the search engines list.
6 changed files:
Changes:
toolkit/components/search/AppProvidedSearchEngine.sys.mjs
| ... |
... |
@@ -116,7 +116,14 @@ class IconHandler { |
|
116
|
116
|
await this.#buildIconMap();
|
|
117
|
117
|
}
|
|
118
|
118
|
|
|
119
|
|
- return this.#iconMap.get(engineIdentifier);
|
|
|
119
|
+ if (AppConstants.BASE_BROWSER_VERSION) {
|
|
|
120
|
+ return this.#iconMap.get(engineIdentifier);
|
|
|
121
|
+ }
|
|
|
122
|
+
|
|
|
123
|
+ let iconList = this.#iconMap.get(this.getKey(engineIdentifier)) || [];
|
|
|
124
|
+ return iconList.filter(r =>
|
|
|
125
|
+ this.#identifierMatches(engineIdentifier, r.engineIdentifiers)
|
|
|
126
|
+ );
|
|
120
|
127
|
}
|
|
121
|
128
|
|
|
122
|
129
|
/**
|
| ... |
... |
@@ -218,7 +225,7 @@ class IconHandler { |
|
218
|
225
|
Object.entries(
|
|
219
|
226
|
await (
|
|
220
|
227
|
await fetch(
|
|
221
|
|
- "chrome://global/content/search/mullvadBrowserSearchEngineIcons.json"
|
|
|
228
|
+ "chrome://global/content/search/base-browser-search-engine-icons.json"
|
|
222
|
229
|
)
|
|
223
|
230
|
).json()
|
|
224
|
231
|
)
|
toolkit/components/search/SearchEngineSelector.sys.mjs
| ... |
... |
@@ -2,6 +2,8 @@ |
|
2
|
2
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
3
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
4
|
4
|
|
|
|
5
|
+import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs";
|
|
|
6
|
+
|
|
5
|
7
|
/**
|
|
6
|
8
|
* @typedef {import("../uniffi-bindgen-gecko-js/components/generated/RustSearch.sys.mjs").SearchEngineSelector} RustSearchEngineSelector
|
|
7
|
9
|
* We use "Rust" above to avoid conflict with the class name for the _javascript_ wrapper.
|
| ... |
... |
@@ -92,30 +94,15 @@ export class SearchEngineSelector { |
|
92
|
94
|
return this._getConfigurationPromise;
|
|
93
|
95
|
}
|
|
94
|
96
|
|
|
95
|
|
- this._getConfigurationPromise = Promise.all([
|
|
96
|
|
- this._getConfiguration(),
|
|
97
|
|
- this._getConfigurationOverrides(),
|
|
98
|
|
- ]);
|
|
99
|
|
- let remoteSettingsData = await this._getConfigurationPromise;
|
|
100
|
|
- this._configuration = remoteSettingsData[0];
|
|
101
|
|
- this._configurationOverrides = remoteSettingsData[1];
|
|
102
|
|
- delete this._getConfigurationPromise;
|
|
103
|
|
-
|
|
104
|
|
- if (!this._configuration?.length) {
|
|
105
|
|
- throw Components.Exception(
|
|
106
|
|
- "Failed to get engine data from Remote Settings",
|
|
107
|
|
- Cr.NS_ERROR_UNEXPECTED
|
|
108
|
|
- );
|
|
109
|
|
- }
|
|
110
|
|
-
|
|
111
|
|
- if (!this._listenerAdded) {
|
|
112
|
|
- this._remoteConfig.on("sync", this._onConfigurationUpdated);
|
|
113
|
|
- this._remoteConfigOverrides.on(
|
|
114
|
|
- "sync",
|
|
115
|
|
- this._onConfigurationOverridesUpdated
|
|
116
|
|
- );
|
|
117
|
|
- this._listenerAdded = true;
|
|
118
|
|
- }
|
|
|
97
|
+ let { promise, resolve } = Promise.withResolvers();
|
|
|
98
|
+ this._getConfigurationPromise = promise;
|
|
|
99
|
+ this._configuration = await (
|
|
|
100
|
+ await fetch(
|
|
|
101
|
+ "chrome://global/content/search/base-browser-search-engines.json"
|
|
|
102
|
+ )
|
|
|
103
|
+ ).json();
|
|
|
104
|
+ this._configurationOverrides = [];
|
|
|
105
|
+ resolve(this._configuration);
|
|
119
|
106
|
|
|
120
|
107
|
if (lazy.SearchUtils.rustSelectorFeatureGate) {
|
|
121
|
108
|
this.#selector.setSearchConfig(
|
| ... |
... |
@@ -242,6 +229,12 @@ export class SearchEngineSelector { |
|
242
|
229
|
* The new configuration object
|
|
243
|
230
|
*/
|
|
244
|
231
|
_onConfigurationUpdated({ data: { current } }) {
|
|
|
232
|
+ // tor-browser#43525: Even though RemoteSettings are a no-op for us, we do
|
|
|
233
|
+ // not want them to interfere in any way.
|
|
|
234
|
+ if (AppConstants.BASE_BROWSER_VERSION) {
|
|
|
235
|
+ return;
|
|
|
236
|
+ }
|
|
|
237
|
+
|
|
245
|
238
|
this._configuration = current;
|
|
246
|
239
|
|
|
247
|
240
|
if (lazy.SearchUtils.rustSelectorFeatureGate) {
|
| ... |
... |
@@ -268,6 +261,12 @@ export class SearchEngineSelector { |
|
268
|
261
|
* The new configuration object
|
|
269
|
262
|
*/
|
|
270
|
263
|
_onConfigurationOverridesUpdated({ data: { current } }) {
|
|
|
264
|
+ // tor-browser#43525: Even though RemoteSettings are a no-op for us, we do
|
|
|
265
|
+ // not want them to interfere in any way.
|
|
|
266
|
+ if (AppConstants.BASE_BROWSER_VERSION) {
|
|
|
267
|
+ return;
|
|
|
268
|
+ }
|
|
|
269
|
+
|
|
271
|
270
|
this._configurationOverrides = current;
|
|
272
|
271
|
|
|
273
|
272
|
if (lazy.SearchUtils.rustSelectorFeatureGate) {
|
toolkit/components/search/SearchService.sys.mjs
| ... |
... |
@@ -25,7 +25,6 @@ ChromeUtils.defineESModuleGetters(lazy, { |
|
25
|
25
|
Region: "resource://gre/modules/Region.sys.mjs",
|
|
26
|
26
|
RemoteSettings: "resource://services-settings/remote-settings.sys.mjs",
|
|
27
|
27
|
SearchEngine: "moz-src:///toolkit/components/search/SearchEngine.sys.mjs",
|
|
28
|
|
- // eslint-disable-next-line mozilla/valid-lazy
|
|
29
|
28
|
SearchEngineSelector:
|
|
30
|
29
|
"moz-src:///toolkit/components/search/SearchEngineSelector.sys.mjs",
|
|
31
|
30
|
SearchSettings: "moz-src:///toolkit/components/search/SearchSettings.sys.mjs",
|
| ... |
... |
@@ -579,7 +578,11 @@ export class SearchService { |
|
579
|
578
|
|
|
580
|
579
|
// Test-only function to reset just the engine selector so that it can
|
|
581
|
580
|
// load a different configuration.
|
|
582
|
|
- resetEngineSelector() {}
|
|
|
581
|
+ resetEngineSelector() {
|
|
|
582
|
+ this.#engineSelector = new lazy.SearchEngineSelector(
|
|
|
583
|
+ this.#handleConfigurationUpdated.bind(this)
|
|
|
584
|
+ );
|
|
|
585
|
+ }
|
|
583
|
586
|
|
|
584
|
587
|
resetToAppDefaultEngine() {
|
|
585
|
588
|
let appDefaultEngine = this.appDefaultEngine;
|
| ... |
... |
@@ -1420,6 +1423,10 @@ export class SearchService { |
|
1420
|
1423
|
// We need to catch the region being updated during initialization so we
|
|
1421
|
1424
|
// start listening straight away.
|
|
1422
|
1425
|
Services.obs.addObserver(this, lazy.Region.REGION_TOPIC);
|
|
|
1426
|
+
|
|
|
1427
|
+ this.#engineSelector = new lazy.SearchEngineSelector(
|
|
|
1428
|
+ this.#handleConfigurationUpdated.bind(this)
|
|
|
1429
|
+ );
|
|
1423
|
1430
|
}
|
|
1424
|
1431
|
|
|
1425
|
1432
|
/**
|
| ... |
... |
@@ -1652,7 +1659,6 @@ export class SearchService { |
|
1652
|
1659
|
* Handles the search configuration being - adds a wait on the user
|
|
1653
|
1660
|
* being idle, before the search engine update gets handled.
|
|
1654
|
1661
|
*/
|
|
1655
|
|
- // eslint-disable-next-line no-unused-private-class-members
|
|
1656
|
1662
|
#handleConfigurationUpdated() {
|
|
1657
|
1663
|
if (this.#queuedIdle) {
|
|
1658
|
1664
|
return;
|
| ... |
... |
@@ -2622,12 +2628,21 @@ export class SearchService { |
|
2622
|
2628
|
// This is prefixed with _ rather than # because it is
|
|
2623
|
2629
|
// called in test_remove_engine_notification_box.js
|
|
2624
|
2630
|
async _fetchEngineSelectorEngines() {
|
|
2625
|
|
- const engines = await (
|
|
2626
|
|
- await fetch(
|
|
2627
|
|
- "chrome://global/content/search/mullvadBrowserSearchEngines.json"
|
|
2628
|
|
- )
|
|
2629
|
|
- ).json();
|
|
2630
|
|
- return { engines, privateDefault: undefined };
|
|
|
2631
|
+ let searchEngineSelectorProperties = {
|
|
|
2632
|
+ locale: Services.locale.appLocaleAsBCP47,
|
|
|
2633
|
+ region: lazy.Region.home || "unknown",
|
|
|
2634
|
+ channel: lazy.SearchUtils.MODIFIED_APP_CHANNEL,
|
|
|
2635
|
+ experiment: this._experimentPrefValue,
|
|
|
2636
|
+ distroID: lazy.SearchUtils.distroID ?? "",
|
|
|
2637
|
+ };
|
|
|
2638
|
+
|
|
|
2639
|
+ for (let [key, value] of Object.entries(searchEngineSelectorProperties)) {
|
|
|
2640
|
+ this._settings.setMetaDataAttribute(key, value);
|
|
|
2641
|
+ }
|
|
|
2642
|
+
|
|
|
2643
|
+ return this.#engineSelector.fetchEngineConfiguration(
|
|
|
2644
|
+ searchEngineSelectorProperties
|
|
|
2645
|
+ );
|
|
2631
|
2646
|
}
|
|
2632
|
2647
|
|
|
2633
|
2648
|
#setDefaultFromSelector(refinedConfig) {
|
toolkit/components/search/content/mullvadBrowserSearchEngineIcons.json
→
toolkit/components/search/content/base-browser-search-engine-icons.json
|
1
|
1
|
{
|
|
2
|
2
|
"ddg": [
|
|
3
|
|
- { "url": "chrome://global/content/search/duckduckgo.ico", "iconSize": 32 }
|
|
|
3
|
+ { "url": "chrome://global/content/search/duckduckgo.ico", "imageSize": 32 }
|
|
4
|
4
|
],
|
|
5
|
5
|
"ddg-html": [
|
|
6
|
|
- { "url": "chrome://global/content/search/duckduckgo.ico", "iconSize": 32 }
|
|
|
6
|
+ { "url": "chrome://global/content/search/duckduckgo.ico", "imageSize": 32 }
|
|
7
|
7
|
],
|
|
8
|
8
|
"mullvad-leta": [
|
|
9
|
|
- { "url": "chrome://global/content/search/mullvad-leta.svg", "iconSize": 16 }
|
|
|
9
|
+ {
|
|
|
10
|
+ "url": "chrome://global/content/search/mullvad-leta.svg",
|
|
|
11
|
+ "imageSize": 16
|
|
|
12
|
+ }
|
|
10
|
13
|
],
|
|
11
|
14
|
"mojeek": [
|
|
12
|
|
- { "url": "chrome://global/content/search/mojeek.ico", "iconSize": 32 }
|
|
|
15
|
+ { "url": "chrome://global/content/search/mojeek.ico", "imageSize": 32 }
|
|
13
|
16
|
],
|
|
14
|
17
|
"brave": [
|
|
15
|
|
- { "url": "chrome://global/content/search/brave.svg", "iconSize": 16 }
|
|
|
18
|
+ { "url": "chrome://global/content/search/brave.svg", "imageSize": 16 }
|
|
16
|
19
|
],
|
|
17
|
20
|
"startpage": [
|
|
18
|
21
|
{
|
|
19
|
22
|
"url": "chrome://global/content/search/startpage-16.png",
|
|
20
|
|
- "iconSize": 16
|
|
|
23
|
+ "imageSize": 16
|
|
21
|
24
|
},
|
|
22
|
|
- { "url": "chrome://global/content/search/startpage-32.png", "iconSize": 32 }
|
|
|
25
|
+ {
|
|
|
26
|
+ "url": "chrome://global/content/search/startpage-32.png",
|
|
|
27
|
+ "imageSize": 32
|
|
|
28
|
+ }
|
|
23
|
29
|
],
|
|
24
|
30
|
"metager": [
|
|
25
|
|
- { "url": "chrome://global/content/search/metager.ico", "iconSize": 196 }
|
|
|
31
|
+ { "url": "chrome://global/content/search/metager.ico", "imageSize": 196 }
|
|
26
|
32
|
]
|
|
27
|
33
|
} |
toolkit/components/search/content/base-browser-search-engines.json
|
|
1
|
+[
|
|
|
2
|
+ {
|
|
|
3
|
+ "base": {
|
|
|
4
|
+ "aliases": ["mullvad-leta", "leta", "mullvad", "ml"],
|
|
|
5
|
+ "classification": "general",
|
|
|
6
|
+ "name": "Mullvad Leta",
|
|
|
7
|
+ "urls": {
|
|
|
8
|
+ "search": {
|
|
|
9
|
+ "base": "https://leta.mullvad.net/",
|
|
|
10
|
+ "params": [],
|
|
|
11
|
+ "searchTermParamName": "q"
|
|
|
12
|
+ }
|
|
|
13
|
+ }
|
|
|
14
|
+ },
|
|
|
15
|
+ "id": "ee88d691-6d7a-4adb-9fec-5a205565505a",
|
|
|
16
|
+ "identifier": "mullvad-leta",
|
|
|
17
|
+ "recordType": "engine",
|
|
|
18
|
+ "variants": [{ "environment": { "allRegionsAndLocales": true } }]
|
|
|
19
|
+ },
|
|
|
20
|
+ {
|
|
|
21
|
+ "base": {
|
|
|
22
|
+ "aliases": ["duckduckgo", "ddg"],
|
|
|
23
|
+ "classification": "general",
|
|
|
24
|
+ "name": "DuckDuckGo",
|
|
|
25
|
+ "urls": {
|
|
|
26
|
+ "search": {
|
|
|
27
|
+ "base": "https://duckduckgo.com/",
|
|
|
28
|
+ "params": [],
|
|
|
29
|
+ "searchTermParamName": "q"
|
|
|
30
|
+ }
|
|
|
31
|
+ }
|
|
|
32
|
+ },
|
|
|
33
|
+ "id": "04e99a38-13ee-47d8-8aa4-64482b3dea99",
|
|
|
34
|
+ "identifier": "ddg",
|
|
|
35
|
+ "recordType": "engine",
|
|
|
36
|
+ "variants": [{ "environment": { "allRegionsAndLocales": true } }]
|
|
|
37
|
+ },
|
|
|
38
|
+ {
|
|
|
39
|
+ "base": {
|
|
|
40
|
+ "aliases": ["ddg-html", "duckduckgohtml", "ddgh"],
|
|
|
41
|
+ "classification": "general",
|
|
|
42
|
+ "name": "DuckDuckGo (HTML)",
|
|
|
43
|
+ "urls": {
|
|
|
44
|
+ "search": {
|
|
|
45
|
+ "base": "https://html.duckduckgo.com/html/",
|
|
|
46
|
+ "params": [],
|
|
|
47
|
+ "searchTermParamName": "q"
|
|
|
48
|
+ }
|
|
|
49
|
+ }
|
|
|
50
|
+ },
|
|
|
51
|
+ "id": "98d8c84b-7455-431d-98b9-890e7bcc0041",
|
|
|
52
|
+ "identifier": "ddg-html",
|
|
|
53
|
+ "recordType": "engine",
|
|
|
54
|
+ "variants": [{ "environment": { "allRegionsAndLocales": true } }]
|
|
|
55
|
+ },
|
|
|
56
|
+ {
|
|
|
57
|
+ "base": {
|
|
|
58
|
+ "aliases": ["mojeek", "mj"],
|
|
|
59
|
+ "classification": "general",
|
|
|
60
|
+ "name": "Mojeek",
|
|
|
61
|
+ "urls": {
|
|
|
62
|
+ "search": {
|
|
|
63
|
+ "base": "https://www.mojeek.com/search",
|
|
|
64
|
+ "params": [],
|
|
|
65
|
+ "searchTermParamName": "q"
|
|
|
66
|
+ }
|
|
|
67
|
+ }
|
|
|
68
|
+ },
|
|
|
69
|
+ "id": "10df12ac-2b39-4aa9-8845-d5b35d5bb70c",
|
|
|
70
|
+ "identifier": "mojeek",
|
|
|
71
|
+ "recordType": "engine",
|
|
|
72
|
+ "variants": [{ "environment": { "allRegionsAndLocales": true } }]
|
|
|
73
|
+ },
|
|
|
74
|
+ {
|
|
|
75
|
+ "base": {
|
|
|
76
|
+ "aliases": ["brave", "bv"],
|
|
|
77
|
+ "classification": "general",
|
|
|
78
|
+ "name": "Brave Search",
|
|
|
79
|
+ "urls": {
|
|
|
80
|
+ "search": {
|
|
|
81
|
+ "base": "https://search.brave.com/search",
|
|
|
82
|
+ "params": [],
|
|
|
83
|
+ "searchTermParamName": "q"
|
|
|
84
|
+ }
|
|
|
85
|
+ }
|
|
|
86
|
+ },
|
|
|
87
|
+ "id": "f479314b-030b-49a8-a2fe-7e1c5d1d9071",
|
|
|
88
|
+ "identifier": "brave",
|
|
|
89
|
+ "recordType": "engine",
|
|
|
90
|
+ "variants": [{ "environment": { "allRegionsAndLocales": true } }]
|
|
|
91
|
+ },
|
|
|
92
|
+ {
|
|
|
93
|
+ "base": {
|
|
|
94
|
+ "aliases": ["startpage", "sp"],
|
|
|
95
|
+ "classification": "general",
|
|
|
96
|
+ "name": "Startpage",
|
|
|
97
|
+ "urls": {
|
|
|
98
|
+ "search": {
|
|
|
99
|
+ "base": "https://www.startpage.com/sp/search",
|
|
|
100
|
+ "params": [],
|
|
|
101
|
+ "searchTermParamName": "q"
|
|
|
102
|
+ }
|
|
|
103
|
+ }
|
|
|
104
|
+ },
|
|
|
105
|
+ "id": "927bbd9f-b2f3-48b4-8974-1c1148028f4d",
|
|
|
106
|
+ "identifier": "startpage",
|
|
|
107
|
+ "recordType": "engine",
|
|
|
108
|
+ "variants": [{ "environment": { "allRegionsAndLocales": true } }]
|
|
|
109
|
+ },
|
|
|
110
|
+ {
|
|
|
111
|
+ "base": {
|
|
|
112
|
+ "aliases": ["metager", "mg"],
|
|
|
113
|
+ "classification": "general",
|
|
|
114
|
+ "name": "MetaGer",
|
|
|
115
|
+ "urls": {
|
|
|
116
|
+ "search": {
|
|
|
117
|
+ "base": "https://metager.org/meta/meta.ger3",
|
|
|
118
|
+ "params": [],
|
|
|
119
|
+ "searchTermParamName": "eingabe"
|
|
|
120
|
+ }
|
|
|
121
|
+ }
|
|
|
122
|
+ },
|
|
|
123
|
+ "id": "a9d07d93-469c-4bf4-8dd1-fa137f1cc85f",
|
|
|
124
|
+ "identifier": "metager",
|
|
|
125
|
+ "recordType": "engine",
|
|
|
126
|
+ "variants": [{ "environment": { "allRegionsAndLocales": true } }]
|
|
|
127
|
+ },
|
|
|
128
|
+ {
|
|
|
129
|
+ "recordType": "defaultEngines",
|
|
|
130
|
+ "globalDefault": "mullvad-leta",
|
|
|
131
|
+ "globalDefaultPrivate": "mullvad-leta"
|
|
|
132
|
+ }
|
|
|
133
|
+] |
toolkit/components/search/content/mullvadBrowserSearchEngines.json
deleted
|
1
|
|
-[
|
|
2
|
|
- {
|
|
3
|
|
- "aliases": ["mullvad-leta", "leta", "mullvad", "ml"],
|
|
4
|
|
- "name": "Mullvad Leta",
|
|
5
|
|
- "urls": {
|
|
6
|
|
- "search": {
|
|
7
|
|
- "base": "https://leta.mullvad.net/",
|
|
8
|
|
- "params": [],
|
|
9
|
|
- "searchTermParamName": "q"
|
|
10
|
|
- }
|
|
11
|
|
- },
|
|
12
|
|
- "id": "ee88d691-6d7a-4adb-9fec-5a205565505a",
|
|
13
|
|
- "identifier": "mullvad-leta",
|
|
14
|
|
- "recordType": "engine",
|
|
15
|
|
- "orderHint": 100,
|
|
16
|
|
- "variants": []
|
|
17
|
|
- },
|
|
18
|
|
- {
|
|
19
|
|
- "aliases": ["duckduckgo", "ddg"],
|
|
20
|
|
- "name": "DuckDuckGo",
|
|
21
|
|
- "urls": {
|
|
22
|
|
- "search": {
|
|
23
|
|
- "base": "https://duckduckgo.com/",
|
|
24
|
|
- "params": [],
|
|
25
|
|
- "searchTermParamName": "q"
|
|
26
|
|
- }
|
|
27
|
|
- },
|
|
28
|
|
- "id": "04e99a38-13ee-47d8-8aa4-64482b3dea99",
|
|
29
|
|
- "identifier": "ddg",
|
|
30
|
|
- "recordType": "engine",
|
|
31
|
|
- "orderHint": 90,
|
|
32
|
|
- "variants": []
|
|
33
|
|
- },
|
|
34
|
|
- {
|
|
35
|
|
- "aliases": ["ddg-html", "duckduckgohtml", "ddgh"],
|
|
36
|
|
- "name": "DuckDuckGo (HTML)",
|
|
37
|
|
- "urls": {
|
|
38
|
|
- "search": {
|
|
39
|
|
- "base": "https://html.duckduckgo.com/html/",
|
|
40
|
|
- "params": [],
|
|
41
|
|
- "searchTermParamName": "q"
|
|
42
|
|
- }
|
|
43
|
|
- },
|
|
44
|
|
- "id": "98d8c84b-7455-431d-98b9-890e7bcc0041",
|
|
45
|
|
- "identifier": "ddg-html",
|
|
46
|
|
- "recordType": "engine",
|
|
47
|
|
- "orderHint": 80,
|
|
48
|
|
- "variants": []
|
|
49
|
|
- },
|
|
50
|
|
- {
|
|
51
|
|
- "aliases": ["mojeek", "mj"],
|
|
52
|
|
- "name": "Mojeek",
|
|
53
|
|
- "urls": {
|
|
54
|
|
- "search": {
|
|
55
|
|
- "base": "https://www.mojeek.com/search",
|
|
56
|
|
- "params": [],
|
|
57
|
|
- "searchTermParamName": "q"
|
|
58
|
|
- }
|
|
59
|
|
- },
|
|
60
|
|
- "id": "10df12ac-2b39-4aa9-8845-d5b35d5bb70c",
|
|
61
|
|
- "identifier": "mojeek",
|
|
62
|
|
- "recordType": "engine",
|
|
63
|
|
- "orderHint": 70,
|
|
64
|
|
- "variants": []
|
|
65
|
|
- },
|
|
66
|
|
- {
|
|
67
|
|
- "aliases": ["brave", "bv"],
|
|
68
|
|
- "name": "Brave Search",
|
|
69
|
|
- "urls": {
|
|
70
|
|
- "search": {
|
|
71
|
|
- "base": "https://search.brave.com/search",
|
|
72
|
|
- "params": [],
|
|
73
|
|
- "searchTermParamName": "q"
|
|
74
|
|
- }
|
|
75
|
|
- },
|
|
76
|
|
- "id": "f479314b-030b-49a8-a2fe-7e1c5d1d9071",
|
|
77
|
|
- "identifier": "brave",
|
|
78
|
|
- "recordType": "engine",
|
|
79
|
|
- "orderHint": 60,
|
|
80
|
|
- "variants": []
|
|
81
|
|
- },
|
|
82
|
|
- {
|
|
83
|
|
- "aliases": ["startpage", "sp"],
|
|
84
|
|
- "name": "Startpage",
|
|
85
|
|
- "urls": {
|
|
86
|
|
- "search": {
|
|
87
|
|
- "base": "https://www.startpage.com/sp/search",
|
|
88
|
|
- "params": [],
|
|
89
|
|
- "searchTermParamName": "q"
|
|
90
|
|
- }
|
|
91
|
|
- },
|
|
92
|
|
- "id": "049f86fd-28fe-4389-910f-aac28f07d745",
|
|
93
|
|
- "identifier": "startpage",
|
|
94
|
|
- "recordType": "engine",
|
|
95
|
|
- "orderHint": 50,
|
|
96
|
|
- "variants": []
|
|
97
|
|
- },
|
|
98
|
|
- {
|
|
99
|
|
- "aliases": ["metager", "mg"],
|
|
100
|
|
- "name": "MetaGer",
|
|
101
|
|
- "urls": {
|
|
102
|
|
- "search": {
|
|
103
|
|
- "base": "https://metager.org/meta/meta.ger3",
|
|
104
|
|
- "params": [],
|
|
105
|
|
- "searchTermParamName": "eingabe"
|
|
106
|
|
- }
|
|
107
|
|
- },
|
|
108
|
|
- "id": "a9d07d93-469c-4bf4-8dd1-fa137f1cc85f",
|
|
109
|
|
- "identifier": "metager",
|
|
110
|
|
- "recordType": "engine",
|
|
111
|
|
- "orderHint": 40,
|
|
112
|
|
- "variants": []
|
|
113
|
|
- }
|
|
114
|
|
-] |
|