Pier Angelo Vendrame pushed to branch tor-browser-145.0a1-16.0-1 at The Tor Project / Applications / Tor Browser
Commits:
-
57842b65
by Henry Wilkes at 2025-11-20T17:47:36+01:00
-
7fe873d8
by Pier Angelo Vendrame at 2025-11-20T17:47:37+01:00
-
5079b9ac
by Pier Angelo Vendrame at 2025-11-20T17:47:38+01:00
-
f940028c
by Pier Angelo Vendrame at 2025-11-20T17:47:38+01:00
-
81b52668
by Beatriz Rizental at 2025-11-20T17:47:39+01:00
-
851147b1
by clairehurst at 2025-11-20T17:47:40+01:00
10 changed files:
- browser/components/abouttor/AboutTorChild.sys.mjs
- browser/components/abouttor/AboutTorParent.sys.mjs
- browser/components/abouttor/content/aboutTor.js
- browser/components/tabbrowser/NewTabPagePreloading.sys.mjs
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/DefaultToolbarMenu.kt
- testing/testsuite-targets.mk
- toolkit/components/search/content/base-browser-search-engine-icons.json
- toolkit/components/search/content/base-browser-search-engines.json
- toolkit/components/search/tests/xpcshell/test_base_browser.js
- toolkit/mozapps/update/updater/updater.cpp
Changes:
| ... | ... | @@ -6,11 +6,9 @@ export class AboutTorChild extends JSWindowActorChild { |
| 6 | 6 | switch (event.type) {
|
| 7 | 7 | case "DOMContentLoaded":
|
| 8 | 8 | this.sendQuery("AboutTor:GetInitialData").then(data => {
|
| 9 | - const initialDataEvent = new this.contentWindow.CustomEvent(
|
|
| 10 | - "InitialData",
|
|
| 11 | - { detail: Cu.cloneInto(data, this.contentWindow) }
|
|
| 12 | - );
|
|
| 13 | - this.contentWindow.dispatchEvent(initialDataEvent);
|
|
| 9 | + if (data) {
|
|
| 10 | + this.#dispatchInitialData(data);
|
|
| 11 | + }
|
|
| 14 | 12 | });
|
| 15 | 13 | break;
|
| 16 | 14 | case "SubmitSearchOnionize":
|
| ... | ... | @@ -36,6 +34,9 @@ export class AboutTorChild extends JSWindowActorChild { |
| 36 | 34 | |
| 37 | 35 | receiveMessage(message) {
|
| 38 | 36 | switch (message.name) {
|
| 37 | + case "AboutTor:DelayedInitialData":
|
|
| 38 | + this.#dispatchInitialData(message.data);
|
|
| 39 | + break;
|
|
| 39 | 40 | case "AboutTor:DismissYEC": {
|
| 40 | 41 | this.contentWindow.dispatchEvent(
|
| 41 | 42 | new this.contentWindow.CustomEvent("DismissYEC")
|
| ... | ... | @@ -45,4 +46,16 @@ export class AboutTorChild extends JSWindowActorChild { |
| 45 | 46 | }
|
| 46 | 47 | return undefined;
|
| 47 | 48 | }
|
| 49 | + |
|
| 50 | + /**
|
|
| 51 | + * Send the initial data to the page.
|
|
| 52 | + *
|
|
| 53 | + * @param {object} data - The data to send.
|
|
| 54 | + */
|
|
| 55 | + #dispatchInitialData(data) {
|
|
| 56 | + const initialDataEvent = new this.contentWindow.CustomEvent("InitialData", {
|
|
| 57 | + detail: Cu.cloneInto(data, this.contentWindow),
|
|
| 58 | + });
|
|
| 59 | + this.contentWindow.dispatchEvent(initialDataEvent);
|
|
| 60 | + }
|
|
| 48 | 61 | } |
| ... | ... | @@ -8,6 +8,8 @@ ChromeUtils.defineESModuleGetters(lazy, { |
| 8 | 8 | });
|
| 9 | 9 | |
| 10 | 10 | const initializedActors = new Set();
|
| 11 | +const onionizePref = "torbrowser.homepage.search.onionize";
|
|
| 12 | +const surveyDismissVersionPref = "torbrowser.homepage.survey.dismiss_version";
|
|
| 11 | 13 | |
| 12 | 14 | /**
|
| 13 | 15 | * Actor parent class for the about:tor page.
|
| ... | ... | @@ -21,35 +23,76 @@ export class AboutTorParent extends JSWindowActorParent { |
| 21 | 23 | */
|
| 22 | 24 | static #dismissYEC = false;
|
| 23 | 25 | |
| 26 | + /**
|
|
| 27 | + * Whether this instance has a preloaded browser.
|
|
| 28 | + *
|
|
| 29 | + * @type {boolean}
|
|
| 30 | + */
|
|
| 31 | + #preloaded = false;
|
|
| 32 | + |
|
| 33 | + /**
|
|
| 34 | + * Method to be called when the browser corresponding to this actor has its
|
|
| 35 | + * preloadedState attribute removed.
|
|
| 36 | + */
|
|
| 37 | + preloadedRemoved() {
|
|
| 38 | + if (!this.#preloaded) {
|
|
| 39 | + return;
|
|
| 40 | + }
|
|
| 41 | + this.#preloaded = false;
|
|
| 42 | + // Send in the initial data now that the page is actually going to be
|
|
| 43 | + // visible.
|
|
| 44 | + this.sendAsyncMessage(
|
|
| 45 | + "AboutTor:DelayedInitialData",
|
|
| 46 | + this.#getInitialData()
|
|
| 47 | + );
|
|
| 48 | + }
|
|
| 49 | + |
|
| 50 | + /**
|
|
| 51 | + * Get the initial data for the page when it is about to be shown.
|
|
| 52 | + *
|
|
| 53 | + * @returns {object} - The initial data.
|
|
| 54 | + */
|
|
| 55 | + #getInitialData() {
|
|
| 56 | + let appLocale = Services.locale.appLocaleAsBCP47;
|
|
| 57 | + if (appLocale === "ja-JP-macos") {
|
|
| 58 | + appLocale = "ja";
|
|
| 59 | + }
|
|
| 60 | + |
|
| 61 | + return {
|
|
| 62 | + torConnectEnabled: lazy.TorConnect.enabled,
|
|
| 63 | + messageData: lazy.AboutTorMessage.getNext(),
|
|
| 64 | + isStable: AppConstants.MOZ_UPDATE_CHANNEL === "release",
|
|
| 65 | + searchOnionize: Services.prefs.getBoolPref(onionizePref, false),
|
|
| 66 | + surveyDismissVersion: Services.prefs.getIntPref(
|
|
| 67 | + surveyDismissVersionPref,
|
|
| 68 | + 0
|
|
| 69 | + ),
|
|
| 70 | + appLocale,
|
|
| 71 | + dismissYEC: AboutTorParent.#dismissYEC,
|
|
| 72 | + };
|
|
| 73 | + }
|
|
| 74 | + |
|
| 24 | 75 | didDestroy() {
|
| 25 | 76 | initializedActors.delete(this);
|
| 26 | 77 | }
|
| 27 | 78 | |
| 28 | 79 | receiveMessage(message) {
|
| 29 | - const onionizePref = "torbrowser.homepage.search.onionize";
|
|
| 30 | - const surveyDismissVersionPref =
|
|
| 31 | - "torbrowser.homepage.survey.dismiss_version";
|
|
| 32 | 80 | switch (message.name) {
|
| 33 | 81 | case "AboutTor:GetInitialData": {
|
| 34 | 82 | // Track this actor to send future updates.
|
| 35 | 83 | initializedActors.add(this);
|
| 36 | 84 | |
| 37 | - let appLocale = Services.locale.appLocaleAsBCP47;
|
|
| 38 | - if (appLocale === "ja-JP-macos") {
|
|
| 39 | - appLocale = "ja";
|
|
| 85 | + const browser = this.browsingContext.top.embedderElement;
|
|
| 86 | + if (browser?.getAttribute("preloadedState") === "preloaded") {
|
|
| 87 | + // Wait until the page is actually about to be shown before sending
|
|
| 88 | + // the initial data.
|
|
| 89 | + // Otherwise the preloaded page might receive data that has expired by
|
|
| 90 | + // the time the page is shown. And it will iterate
|
|
| 91 | + // AboutTorMessage.getNext too early. See tor-browser#44314.
|
|
| 92 | + this.#preloaded = true;
|
|
| 93 | + return Promise.resolve(null);
|
|
| 40 | 94 | }
|
| 41 | - return Promise.resolve({
|
|
| 42 | - torConnectEnabled: lazy.TorConnect.enabled,
|
|
| 43 | - messageData: lazy.AboutTorMessage.getNext(),
|
|
| 44 | - isStable: AppConstants.MOZ_UPDATE_CHANNEL === "release",
|
|
| 45 | - searchOnionize: Services.prefs.getBoolPref(onionizePref, false),
|
|
| 46 | - surveyDismissVersion: Services.prefs.getIntPref(
|
|
| 47 | - surveyDismissVersionPref,
|
|
| 48 | - 0
|
|
| 49 | - ),
|
|
| 50 | - appLocale,
|
|
| 51 | - dismissYEC: AboutTorParent.#dismissYEC,
|
|
| 52 | - });
|
|
| 95 | + return Promise.resolve(this.#getInitialData());
|
|
| 53 | 96 | }
|
| 54 | 97 | case "AboutTor:SetSearchOnionize":
|
| 55 | 98 | Services.prefs.setBoolPref(onionizePref, message.data);
|
| ... | ... | @@ -562,11 +562,35 @@ const YecArea = { |
| 562 | 562 | },
|
| 563 | 563 | };
|
| 564 | 564 | |
| 565 | +let gInitialData = false;
|
|
| 566 | +let gLoaded = false;
|
|
| 567 | + |
|
| 568 | +function maybeComplete() {
|
|
| 569 | + if (!gInitialData || !gLoaded) {
|
|
| 570 | + return;
|
|
| 571 | + }
|
|
| 572 | + // Wait to show the content when the l10n population has completed.
|
|
| 573 | + if (document.hasPendingL10nMutations) {
|
|
| 574 | + window.addEventListener(
|
|
| 575 | + "L10nMutationsFinished",
|
|
| 576 | + () => {
|
|
| 577 | + document.body.classList.add("initialized");
|
|
| 578 | + },
|
|
| 579 | + { once: true }
|
|
| 580 | + );
|
|
| 581 | + } else {
|
|
| 582 | + document.body.classList.add("initialized");
|
|
| 583 | + }
|
|
| 584 | +}
|
|
| 585 | + |
|
| 565 | 586 | window.addEventListener("DOMContentLoaded", () => {
|
| 566 | 587 | SearchWidget.init();
|
| 567 | 588 | MessageArea.init();
|
| 568 | 589 | SurveyArea.init();
|
| 569 | 590 | YecArea.init();
|
| 591 | + |
|
| 592 | + gLoaded = true;
|
|
| 593 | + maybeComplete();
|
|
| 570 | 594 | });
|
| 571 | 595 | |
| 572 | 596 | window.addEventListener("InitialData", event => {
|
| ... | ... | @@ -584,18 +608,8 @@ window.addEventListener("InitialData", event => { |
| 584 | 608 | SurveyArea.potentiallyShow(surveyDismissVersion, isStable, appLocale);
|
| 585 | 609 | YecArea.potentiallyShow(dismissYEC, isStable, appLocale);
|
| 586 | 610 | |
| 587 | - // Wait to show the content when the l10n population has completed.
|
|
| 588 | - if (document.hasPendingL10nMutations) {
|
|
| 589 | - window.addEventListener(
|
|
| 590 | - "L10nMutationsFinished",
|
|
| 591 | - () => {
|
|
| 592 | - document.body.classList.add("initialized");
|
|
| 593 | - },
|
|
| 594 | - { once: true }
|
|
| 595 | - );
|
|
| 596 | - } else {
|
|
| 597 | - document.body.classList.add("initialized");
|
|
| 598 | - }
|
|
| 611 | + gInitialData = true;
|
|
| 612 | + maybeComplete();
|
|
| 599 | 613 | });
|
| 600 | 614 | |
| 601 | 615 | window.addEventListener("DismissYEC", () => {
|
| ... | ... | @@ -178,6 +178,24 @@ export let NewTabPagePreloading = { |
| 178 | 178 | this.browserCounts[countKey]--;
|
| 179 | 179 | browser.removeAttribute("preloadedState");
|
| 180 | 180 | browser.setAttribute("autocompletepopup", "PopupAutoComplete");
|
| 181 | + // Let a preloaded about:tor page know that it is no longer preloaded
|
|
| 182 | + // (about to be shown). See tor-browser#44314.
|
|
| 183 | + // NOTE: We call the AboutTorParent instance directly because it is not
|
|
| 184 | + // reliable for the AboutTorParent to wait for the "preloadedState"
|
|
| 185 | + // attribute to change via a MutationObserver on the browsingContext's
|
|
| 186 | + // browser element because the AboutTorParent's browsingContext's browser
|
|
| 187 | + // element may be swapped out. E.g. see the "SwapDocShells" event.
|
|
| 188 | + // NOTE: We assume that this is the only place that removes the
|
|
| 189 | + // "preloadedState" attribute.
|
|
| 190 | + // NOTE: Alternatively, we could have the AboutTorParent wait for
|
|
| 191 | + // MozAfterPaint, but this would be slightly delayed.
|
|
| 192 | + try {
|
|
| 193 | + browser.browsingContext?.currentWindowGlobal
|
|
| 194 | + ?.getActor("AboutTor")
|
|
| 195 | + .preloadedRemoved();
|
|
| 196 | + } catch {
|
|
| 197 | + // Not an about:tor page with an AboutTorParent instance.
|
|
| 198 | + }
|
|
| 181 | 199 | }
|
| 182 | 200 | |
| 183 | 201 | return browser;
|
| ... | ... | @@ -203,11 +203,9 @@ open class DefaultToolbarMenu( |
| 203 | 203 | */
|
| 204 | 204 | @VisibleForTesting(otherwise = PRIVATE)
|
| 205 | 205 | fun shouldShowTranslations(): Boolean {
|
| 206 | - val isEngineSupported = store.state.translationEngine.isEngineSupported
|
|
| 207 | - return selectedSession?.let {
|
|
| 208 | - isEngineSupported == true &&
|
|
| 209 | - FxNimbus.features.translations.value().mainFlowBrowserMenuEnabled
|
|
| 210 | - } ?: false
|
|
| 206 | + // We need this because in FxNimbus.kt, mainFlowToolbarEnabled defaults to true
|
|
| 207 | + // ```mainFlowToolbarEnabled: Boolean = true```
|
|
| 208 | + return false // bug_44304 Hide broken translat page action.
|
|
| 211 | 209 | }
|
| 212 | 210 | |
| 213 | 211 | /**
|
| ... | ... | @@ -151,7 +151,7 @@ download-wpt-manifest: |
| 151 | 151 | $(call py_action,download_wpt_manifest)
|
| 152 | 152 | |
| 153 | 153 | define package_archive
|
| 154 | -package-tests-$(1): stage-all package-tests-prepare-dest download-wpt-manifest
|
|
| 154 | +package-tests-$(1): stage-all package-tests-prepare-dest
|
|
| 155 | 155 | $$(call py_action,test_archive, \
|
| 156 | 156 | $(1) \
|
| 157 | 157 | '$$(abspath $$(test_archive_dir))/$$(PKG_BASENAME).$(1).tests.$(2)')
|
| ... | ... | @@ -2,6 +2,9 @@ |
| 2 | 2 | "ddg": [
|
| 3 | 3 | { "url": "chrome://global/content/search/duckduckgo.ico", "imageSize": 32 }
|
| 4 | 4 | ],
|
| 5 | + "ddg-noai": [
|
|
| 6 | + { "url": "chrome://global/content/search/duckduckgo.ico", "imageSize": 32 }
|
|
| 7 | + ],
|
|
| 5 | 8 | "ddg-onion": [
|
| 6 | 9 | { "url": "chrome://global/content/search/duckduckgo.ico", "imageSize": 32 }
|
| 7 | 10 | ],
|
| ... | ... | @@ -17,6 +17,24 @@ |
| 17 | 17 | "recordType": "engine",
|
| 18 | 18 | "variants": [{ "environment": { "allRegionsAndLocales": true } }]
|
| 19 | 19 | },
|
| 20 | + {
|
|
| 21 | + "base": {
|
|
| 22 | + "aliases": ["ddgnoai"],
|
|
| 23 | + "classification": "general",
|
|
| 24 | + "name": "DuckDuckGo (no AI)",
|
|
| 25 | + "urls": {
|
|
| 26 | + "search": {
|
|
| 27 | + "base": "https://noai.duckduckgo.com/",
|
|
| 28 | + "params": [],
|
|
| 29 | + "searchTermParamName": "q"
|
|
| 30 | + }
|
|
| 31 | + }
|
|
| 32 | + },
|
|
| 33 | + "id": "91687f02-56dd-4fef-ba26-bf139dff3166",
|
|
| 34 | + "identifier": "ddg-noai",
|
|
| 35 | + "recordType": "engine",
|
|
| 36 | + "variants": [{ "environment": { "allRegionsAndLocales": true } }]
|
|
| 37 | + },
|
|
| 20 | 38 | {
|
| 21 | 39 | "base": {
|
| 22 | 40 | "aliases": ["ddgonion"],
|
| ... | ... | @@ -93,5 +111,21 @@ |
| 93 | 111 | "recordType": "defaultEngines",
|
| 94 | 112 | "globalDefault": "ddg",
|
| 95 | 113 | "globalDefaultPrivate": "ddg"
|
| 114 | + },
|
|
| 115 | + {
|
|
| 116 | + "recordType": "engineOrders",
|
|
| 117 | + "orders": [
|
|
| 118 | + {
|
|
| 119 | + "environment": { "allRegionsAndLocales": true },
|
|
| 120 | + "order": [
|
|
| 121 | + "ddg",
|
|
| 122 | + "ddg-noai",
|
|
| 123 | + "ddg-onion",
|
|
| 124 | + "startpage",
|
|
| 125 | + "startpage-onion",
|
|
| 126 | + "wikipedia"
|
|
| 127 | + ]
|
|
| 128 | + }
|
|
| 129 | + ]
|
|
| 96 | 130 | }
|
| 97 | 131 | ] |
| ... | ... | @@ -4,12 +4,15 @@ |
| 4 | 4 | /**
|
| 5 | 5 | * This tests the SearchService to check our override of the remote settings is
|
| 6 | 6 | * working as expected.
|
| 7 | + *
|
|
| 8 | + * When adding new engines, it should be enough to change expectedURLs below.
|
|
| 7 | 9 | */
|
| 8 | 10 | |
| 9 | 11 | "use strict";
|
| 10 | 12 | |
| 11 | 13 | const expectedURLs = {
|
| 12 | 14 | ddg: "https://duckduckgo.com/?q=test",
|
| 15 | + "ddg-noai": "https://noai.duckduckgo.com/?q=test",
|
|
| 13 | 16 | "ddg-onion":
|
| 14 | 17 | "https://duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion/?q=test",
|
| 15 | 18 | startpage: "https://www.startpage.com/sp/search?q=test",
|
| ... | ... | @@ -50,3 +53,11 @@ add_task(function test_checkSearchURLs() { |
| 50 | 53 | Assert.equal(foundUrl, url, `The URL of ${engine.name} is not altered.`);
|
| 51 | 54 | }
|
| 52 | 55 | });
|
| 56 | + |
|
| 57 | +add_task(async function test_iconsDoesNotFail() {
|
|
| 58 | + for (const id of Object.keys(expectedURLs)) {
|
|
| 59 | + const engine = Services.search.getEngineById(id);
|
|
| 60 | + // No need to assert anything, as in case of error this method should throw.
|
|
| 61 | + await engine.getIconURL();
|
|
| 62 | + }
|
|
| 63 | +}); |
| ... | ... | @@ -3474,6 +3474,10 @@ int NS_main(int argc, NS_tchar** argv) { |
| 3474 | 3474 | putenv(const_cast<char*>("MOZ_USING_SERVICE="));
|
| 3475 | 3475 | #endif
|
| 3476 | 3476 | |
| 3477 | +#if defined(XP_UNIX) && !defined(XP_MACOSX)
|
|
| 3478 | + unsetenv("FONTCONFIG_PATH");
|
|
| 3479 | +#endif
|
|
| 3480 | + |
|
| 3477 | 3481 | if (argc == 2 && NS_tstrcmp(argv[1], NS_T("--channels-allowed")) == 0) {
|
| 3478 | 3482 | #ifdef MOZ_VERIFY_MAR_SIGNATURE
|
| 3479 | 3483 | int rv = PopulategMARStrings();
|