tbb-commits
Threads by month
- ----- 2026 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
November 2026
- 1 participants
- 6 discussions
[Git][tpo/applications/tor-browser][tor-browser-155.0a1-17.0-1] 2 commits: BB 41108: Remove privileged macOS installation
by Pier Angelo Vendrame (@pierov) 04 Nov '26
by Pier Angelo Vendrame (@pierov) 04 Nov '26
04 Nov '26
Pier Angelo Vendrame pushed to branch tor-browser-155.0a1-17.0-1 at The Tor Project / Applications / Tor Browser
Commits:
d646ae03 by Pier Angelo Vendrame at 2026-11-04T21:59:23+01:00
BB 41108: Remove privileged macOS installation
- - - - -
8518d56b by Pier Angelo Vendrame at 2026-11-04T21:59:23+01:00
fixup! Base Browser's .mozconfigs.
BB 45240: Fix updater-related build errors on macOS.
Introduce CONFIG["BASE_BROWSER"].
- - - - -
4 changed files:
- browser/app/moz.build
- moz.configure
- toolkit/moz.build
- toolkit/xre/MacRunFromDmgUtils.mm
Changes:
=====================================
browser/app/moz.build
=====================================
@@ -80,6 +80,12 @@ if CONFIG["MOZ_WIDGET_TOOLKIT"] == "cocoa":
f"!/{FINAL_TARGET}/org.mozilla.updater",
"Library/LaunchServices/org.mozilla.updater",
))
+ moves = [("ChannelPrefs.framework", "Frameworks/ChannelPrefs.framework")]
+ if not CONFIG["BASE_BROWSER"]:
+ moves.append((
+ "org.mozilla.dmgInstallHelper",
+ "Library/LaunchServices/org.mozilla.dmgInstallHelper",
+ ))
MacOSBundle(
f"!/dist/{CONFIG['MOZ_MACBUNDLE_NAME']}",
skeleton="macbuild/Contents",
@@ -93,13 +99,7 @@ if CONFIG["MOZ_WIDGET_TOOLKIT"] == "cocoa":
(f"!/{FINAL_TARGET}/{CONFIG['MOZ_APP_NAME']}", CONFIG["MOZ_APP_NAME"])
],
extra_files=extra_files,
- moves=[
- ("ChannelPrefs.framework", "Frameworks/ChannelPrefs.framework"),
- (
- "org.mozilla.dmgInstallHelper",
- "Library/LaunchServices/org.mozilla.dmgInstallHelper",
- ),
- ],
+ moves=moves,
pkginfo="APPLTORB",
)
=====================================
moz.configure
=====================================
@@ -1035,6 +1035,9 @@ def base_browser_version_quoted(value):
return f'"{value[0]}"'
+set_config(
+ "BASE_BROWSER", depends(base_browser_version)(lambda v: True if v else False)
+)
set_define("BASE_BROWSER_VERSION", base_browser_version)
set_define("BASE_BROWSER_VERSION_QUOTED", base_browser_version_quoted)
=====================================
toolkit/moz.build
=====================================
@@ -63,11 +63,12 @@ if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk":
]
elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "cocoa":
DIRS += [
- "mozapps/dmgInstallHelper",
"mozapps/macos-frameworks",
"system/commonproxy",
"system/osxproxy",
]
+ if not CONFIG["BASE_BROWSER"]:
+ DIRS += ["mozapps/dmgInstallHelper"]
elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "windows":
DIRS += [
"system/commonproxy",
=====================================
toolkit/xre/MacRunFromDmgUtils.mm
=====================================
@@ -279,6 +279,7 @@ static void ShowInstallFailedDialog() {
NS_OBJC_END_TRY_IGNORE_BLOCK;
}
+#ifndef BASE_BROWSER_VERSION
// Install the DMGInstallHelper as an elevated helper and use it to install
bool LaunchElevatedDmgInstall(NSString* aBundlePath, NSString* aDestPath) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
@@ -355,6 +356,7 @@ bool LaunchElevatedDmgInstall(NSString* aBundlePath, NSString* aDestPath) {
NS_OBJC_END_TRY_BLOCK_RETURN(false);
}
+#endif
// Note: both arguments are expected to contain the app name (to end with
// '.app').
@@ -381,6 +383,7 @@ static bool InstallFromPath(NSString* aBundlePath, NSString* aDestPath) {
os_log_info(runFromDMGLogger, "Unelevated installation: %s",
installSuccessful ? "success" : "failed");
+#ifndef BASE_BROWSER_VERSION
// The installation may have been unsuccessful if the user did not have the
// rights to write to the Applications directory. Check for this situation and
// launch an elevated helper application.
@@ -396,6 +399,7 @@ static bool InstallFromPath(NSString* aBundlePath, NSString* aDestPath) {
return false;
}
}
+#endif
if (!installSuccessful) {
os_log_error(runFromDMGLogger, "Unknown install failure.");
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/90e50e…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/90e50e…
You're receiving this email because of your account on gitlab.torproject.org. Manage all notifications: https://gitlab.torproject.org/-/profile/notifications | Help: https://gitlab.torproject.org/help
1
0
[Git][tpo/applications/tor-browser][tor-browser-153.6.0esr-16.0-1] 4 commits: fixup! Tor Browser localization migration scripts.
by henry (@henry) 04 Nov '26
by henry (@henry) 04 Nov '26
04 Nov '26
henry pushed to branch tor-browser-153.6.0esr-16.0-1 at The Tor Project / Applications / Tor Browser
Commits:
0d103a1e by Henry Wilkes at 2026-11-03T15:03:48+00:00
fixup! Tor Browser localization migration scripts.
TB 45433: Change the script to be more versatile for test runs.
Instead of passing in a python module name for the recipe, you now pass
in the file path to the recipe script.
You can now change the reference directory with the
--reference-directory argument, which is useful for testing scripts
before the changes have reached the translation repository.
- - - - -
7e33b574 by Henry Wilkes at 2026-11-04T14:51:14+00:00
fixup! Tor Browser localization migration scripts.
TB 45433: Refactor the WeblateMetadata class.
We are stricter about checking the return types from the weblate API,
and making sure it doesn't make requests to unexpected URLs.
We also limit the components to the browser components, and we slightly
alter the `is_translated` public method.
- - - - -
90fb8c89 by Henry Wilkes at 2026-11-04T14:51:16+00:00
fixup! Tor Browser localization migration scripts.
TB 45433: Add type hints to the script.
- - - - -
fdcaef33 by Henry Wilkes at 2026-11-04T14:51:17+00:00
fixup! Tor Browser localization migration scripts.
TB 45433: Update the migrate.py documentation.
- - - - -
1 changed file:
- tools/torbrowser/l10n/migrate.py
Changes:
=====================================
tools/torbrowser/l10n/migrate.py
=====================================
@@ -1,58 +1,252 @@
"""
-Migration script for running migration recipes.
+Migration script for running Tor Browser migration recipes.
-Requires the mozilla fluent.migrate package (available with pip).
+Based on the Firefox migration script, adapted for Tor Browser. See
+https://firefox-source-docs.mozilla.org/l10n/migrations/ for more context and
+information on how to write the migration recipes.
-NOTE: This will likely send queries to the weblate API as part of the run.
-Weblate may have a query limit of 100 requests per day for unauthorised users.
+## Concepts
+
++ String. Here, when we say "string", it refers to a piece of text that can be
+ translated. In practice, you can think of it as a being defined by a triple:
+ a file path relative to a locale's directory, an ID, and some content. For
+ example `("./tor-browser.ftl", "my-id", "my-id =\\n .label=Content")`.
+ When a string is translated the file path and ID stay the same, whilst the
+ translatable part of the content can vary.
++ Reference files. These are the en-US source Fluent files that contain the
+ *manual* string changes made by a developer. For most migrations, there is
+ only one reference file.
++ Migration recipe. A collection of instructions that take some string inputs
+ and transforms them into new strings. These are meant to mirror the manual
+ changes that were made in the reference files, in a way that can be applied
+ to any locale.
++ Translation repository. This refers to a local copy of the `translation`
+ repository (https://gitlab.torproject.org/tpo/translation) This repository
+ contains a different branch for different collections of strings. For
+ Tor Browser we usually use `tor-browser`, `base-browser` and
+ `fenix-torbrowserstringsxml`. Each branch will contain an `en-US` directory,
+ which contains the "source" files for translators to translate. These source
+ files are taken from the `tor-browser` repository. The branches also contain
+ a directory for each locale that is to be translated, in a file structure that
+ reflects the source `en-US` directory. This is where the migration script will
+ write changes to the translated files.
+
+
+## Usage
+
+You will likely want to run this with `./mach python`, so that it uses the
+`fluent.migrate` and `fluent.syntax` packages provided with the `tor-browser`
+repository.
+
+For example, you might run this as
-Based on the firefox migration script, adapted for tor browser. See
-https://firefox-source-docs.mozilla.org/l10n/migrations/ for more context and
-information on how to write the migration recipes.
+```
+ ./mach python migrate.py --translation-git /home/user/translation --locales 'es-ES sr' ./migrations/bug-xxxx-my-migration-recipe.py
+```
+
+Here `/home/user/translation` is a local translation repository with one of its
+branches checked out (see below). This will run the migration recipe given in
+`./migrations/bug-xxxx-my-migration-recipe.py` for the `es-ES` and `sr`
+sub-directories within the `translation/` directory.
+
+### Changing the reference location
+
+You can optionally run the script with `--reference_directory` to read the
+reference en-US files from somewhere other than the `translation` directory.
+This can be useful when your manual changes have yet to reach the translation
+repository, so you want to point the script to read the reference from the
+`tor-browser` working directory instead. E.g.
+
+```
+ --reference-directory /home/user/tor-browser/toolkit/locales/en-US/toolkit/global/
+```
+
+
+## Recipes
+
+Migration recipes are meant to mirror some manual change that was made to the
+en-US source strings, in a way that can be reproduced in another locale.
+### Example 1
-Usage with an example:
+For this example, a developer wants to remove the string content from
+`old-strings.properties`:
-We have some en-US file "updated.ftl" in the tor-browser repository that we have
-added new strings to. Some of these strings are copies or concatenations of some
-already existing strings in a `.dtd`, `.properties` or `.ftl` file (including
-strings within "updated.ftl").
+```
+my.old.string=Some string content
+my.old.title=This is the tooltip
+```
+
+And add them to `tor-browser.ftl` instead, as:
-So we also write a migration recipe in
-`./l10n_migrations/bug-xxxx-my-migration-recipe.py`
-which includes a `migrate(ctx)` method. This method takes the old strings and
-create new Messages or Terms for "updated.ftl" using `ctx.add_transforms`. These
-should match what was already done manually in "updated.ftl".
+```
+my-new-string = Some string content
+ .title = This is the tooltip
+```
+
+For the en-US source strings, the developer simply deletes the two lines in the
+`old-strings.properties` file (or the whole file, if these are the last two).
+And they manually write in the content of `my-new-string` to `tor-browser.ftl`.
+These manual changes will then eventually reach the `translation` repository to
+be translated.
+
+But to save translators making the same manual changes, or re-translating, the
+developer can write a migration recipe that mirror's their manual changes. In
+this case, this migration recipe would contain:
+
+```
+ctx.add_transforms(
+ "tor-browser.ftl", # The path to write to.
+ "tor-browser.ftl", # The path to the reference file.
+ transforms_from(
+ \"\"\"
+my-new-string = { COPY(path, "my.old.string") }
+ .title = { COPY(path, "my.old.title") }
+\"\"\",
+ path="old-strings.properties", # The path to read from.
+ ),
+)
+```
+
+Note, the first argument of `add_transforms` is the target path, which is
+`tor-browser.ftl` in this case. This means that the migration script will try to
+write the resulting `my-new-string` to the locale's `./tor-browser.ftl` file.
+For example, to `translation/es-ES/tor-browser.ftl`.
+
+The second argument refers to the *reference* path. In almost all cases the
+reference file will have the same name and path as the target path, but it has a
+different role. Here the path is relative to the reference directory, which
+contains the en-US source files. In this case, by default this means that
+`translation/en-US/tor-browser.ftl` will act as the reference, but the exact
+path could be changed with the `--reference-directory` argument. The existing
+`my-new-string` will be read from this file to confirm that the migration
+recipe produces the correct result.
+
+The file `old-strings.properties` is used as an input. This means that the
+existing strings in the locale's `old-strings.properties` file will be read to
+construct the new string `my-new-string`. For example, it will be read from
+`translation/es-ES/old-strings.properties`.
+
+The `COPY` acts like a Fluent function, which asks the transformation to copy
+the content from the translated string directly.
+
+### Example 2
+
+For this example, a developer wants to swap a string in `tor-browser.ftl` from:
+
+```
+my-old-string2 = Some string content
+ .title = This is the tooltip
+```
+
+to
+
+```
+my-new-string2 =
+ .label = Some string content
+ .title = This is the tooltip
+```
-Then we copy the en-US file to our local translation repository, say at
-`/home/user/translation/en-US/updated.ftl`. The en-US file is needed as a
-reference during migration to know where in the new file the new Messages or
-Terms should be placed. Moreover, the migration can be verified against the
-en-US file to ensure it is working as intended.
+The developer removes `my-old-string2` from the file and adds `my-new-string2`
+instead. This manual change will then eventually reach the `translation`
+repository for `my-new-string2` to be translated.
-Then we run the migration for individual locales:
+The developer also writes a migration recipe to mirror this change:
```
- python migrate_l10n.py --translation-git /home/user/translation --locales 'es-ES sr' l10n_migrations.bug-xxxx-my-migration-recipe
+ctx.add_transforms(
+ "tor-browser.ftl",
+ "tor-browser.ftl",
+ transforms_from(
+ \"\"\"
+my-new-string2 =
+ .label = { COPY_PATTERN(path, "my-old-string2") }
+ .title = { COPY_PATTERN(path, "my-old-string2.title") }
+\"\"\",
+ path="tor-browser.ftl",
+ ),
+)
```
-This will first run a mock migration using the en-US localization files. This is
-to help ensure that the migration will work as intended. I.e. if we ran the
-migration recipe for en-US, using it as both the source of old strings and as a
-reference, then each transformation using these old strings should produce a
-Message or Term that is identical to the one in the reference file.
+Note that in this case the locale's `tor-browser.ftl` file is being used as both
+the input and the output.
+
+Note that for a Fluent-to-Fluent migration we use `COPY_PATTERN` rather than
+`COPY`. The second argument provides an ID that either point's to the
+Fluent Messages' value (roughly, the text content) by giving the Message's ID,
+or one of its attributes by adding a corresponding suffix to the ID.
+
+### Other examples
+
+Migration recipes can support a lot more, including more advanced
+transformations like removing or replacing HTML tags from content. There are
+some existing recipes in the `./migrations` directory that can be used as a
+reference.
+
+
+## translation directory
+
+In most cases, you will just need to check out a `translation` branch that
+contains the translated strings used by the migration recipe, as well as the
+Fluent file that will be written to. Usually, this will be a branch based on
+the origin/upstream `tor-browser` or `base-browser` branches.
+
+However, if the migration recipe requires source files that are in a different
+branch to the Fluent file that is being written to, then you will need to
+manually copy those files into the working directory before running the script.
+
+
+## Script procedure
-Then this will run `migrate(ctx)` for the es-ES and sr locales. Some of the
-transformations will not be completed for a locale if that locale does not
-contain a translated version of the old strings the transformation requires
-(because there is no string to copy).
+### Test en-US migration
-If one of the old strings is from a `.dtd` or `.properties` file, this will
-check whether they are marked as translated on weblate using its API. This
-prevents copying "placeholder" en-US values into the locale's fluent files.
+The script will first run a test migration using the en-US strings. It will run
+the migration using the files from `translation/en-US/` as the input. In the
+previous example 1, this will read `my.old.string` and `my.old.title` from
+`translation/en-US/old-strings.properties`. And in example 2, this will read
+`my-old-string2` from `translation/en-US/tor-browser.ftl`.
-Any warnings or errors will be logged to stderr in the console.
+If any of the input strings are missing, this indicates that there is likely a
+mistake in the recipe or the translation directory and the script will be
+aborted without running the migration for the other locales.
+
+Otherwise, it then compares the result of this migration with the strings found
+in the reference files. In the previous example 1, this will read the entry for
+`my-new-string` from `<reference-dir>/tor-browser.ftl`, where `<reference-dir>`
+is `translation/en-US/` unless `--reference-directory` is given to use a
+different directory. If the reference entry for `my-new-string` differs from the
+entry that the recipe automatically produced, then this indicates that there is
+a mistake in the recipe and the script will be aborted.
+
+### Locale migrations
+
+If the test migration passed, then the recipe will be re-run for each of the
+specified locales. If the locale is missing some strings or files that a single
+transformation requires, then that transformation will be skipped and the
+corresponding entry won't be written to the Fluent file. Otherwise the new
+entries will be appended to the existing Fluent files.
+
+#### Non-Fluent strings and Weblate queries
+
+Some non-Fluent formats, like DTD and properties, will fill untranslated strings
+with the source en-US content. And we don't want these untranslated strings to
+be used for migrations. There is no metadata within the files to determine this,
+and simply being the same as the en-US string is not a reliable indicator.
+
+So for these strings the script will additionally make a remote query to the
+Weblate API to fetch the metadata that indicates whether the string is
+considered translated or not. If a transformation requires a string that is
+marked as untranslated, it will be skipped.
+
+NOTE: The Weblate metadata is not always reliable, so you should still manually
+review the changes.
+
+NOTE: When testing before, the Weblate API was limited to 100 requests per day
+per IP address for unauthorised users. If this becomes an issue you may want to
+run the migrations in limited batches of locales with new IP addresses. Or, you
+can create a Weblate account and change this script to pass an authorisation
+token with the request.
"""
import argparse
@@ -63,142 +257,299 @@ import logging
import os
import sys
import urllib.request
+from collections.abc import Iterator
+from typing import Any, NamedTuple, Protocol, cast
from fluent.migrate.context import MigrationContext
from fluent.migrate.errors import EmptyLocalizationError, UnreadableReferenceError
from fluent.syntax import ast, parse, serialize
-def in_red(string):
+def in_red(string: str) -> str:
"""
Wrap a string so that it is shown as red in the console.
+ :param string: The string to wrap.
+ :returns: The wrapped string.
"""
return f"\x1b[1;91m{string}\x1b[0m"
+def assert_keys(
+ check_dict: dict[Any, Any], expected_keys: tuple[str, ...], url: str
+) -> None:
+ """
+ Verify that the dictionary contains *at least* the expected keys,
+ otherwise this throws.
+ :param check_dict: The dictionary to check.
+ :param url: The url where the dictionary was fetched from.
+ """
+ for key in expected_keys:
+ if key not in check_dict:
+ raise ValueError(f"Missing '{key}' in response for {url}")
+
+
+class WeblateUnit:
+ """
+ Represents a Weblate "unit": roughly corresponds to a translated string.
+
+ See https://docs.weblate.org/en/latest/api.html#units.
+ """
+
+ def __init__(self, data: dict[Any, Any], url: str) -> None:
+ """
+ :param data: The Weblate data response.
+ :param url: The URL that the data came from.
+ """
+ assert_keys(data, ("context", "translated"), url)
+ string_id = data["context"]
+ translated = data["translated"]
+ if not isinstance(string_id, str):
+ raise ValueError(f"Unexpected 'context' type in response for {url}")
+ if not isinstance(translated, bool):
+ raise ValueError(f"Unexpected 'translated' type in response for {url}")
+
+ self.string_id = string_id
+ self.translated = translated
+
+
+class WeblateTranslation:
+ """
+ Represents a Weblate "translation": roughly corresponds to the translation
+ of a file for a given locale/language.
+
+ See https://docs.weblate.org/en/latest/api.html#translations.
+ """
+
+ def __init__(self, data: dict[Any, Any], url: str) -> None:
+ """
+ :param data: The Weblate data response.
+ :param url: The URL that the data came from.
+ """
+ assert_keys(data, ("filename", "units_list_url"), url)
+ locale_path = data["filename"]
+ units_url = data["units_list_url"]
+ if not isinstance(locale_path, str):
+ raise ValueError(f"Unexpected 'filename' type in response for {url}")
+ if not isinstance(units_url, str):
+ raise ValueError(f"Unexpected 'units_list_url' type in response for {url}")
+
+ self.locale_path = locale_path
+ self.units_url = units_url
+ # The units, indexed by their string ID. Lazy-loaded and `None` whilst
+ # unfilled.
+ self.units: None | dict[str, WeblateUnit] = None
+
+
+class WeblateComponent:
+ """
+ Represents a Weblate "component": roughly corresponds to a source (en-US)
+ file that can be translated.
+
+ See https://docs.weblate.org/en/latest/api.html#components.
+ And https://docs.weblate.org/en/latest/user/basic.html.
+ """
+
+ def __init__(self, data: dict[Any, Any], url: str) -> None:
+ """
+ :param data: The Weblate data response.
+ :param url: The URL that the data came from.
+ """
+ assert_keys(data, ("template", "translations_url", "branch"), url)
+ template_path = data["template"]
+ translations_url = data["translations_url"]
+ branch = data["branch"]
+ if not isinstance(template_path, str):
+ raise ValueError(f"Unexpected 'template' type in response for {url}")
+ if not isinstance(translations_url, str):
+ raise ValueError(
+ f"Unexpected 'translations_url' type in response for {url}"
+ )
+ if not isinstance(branch, str):
+ raise ValueError(f"Unexpected 'branch' type in response for {url}")
+
+ self.branch = branch
+ # The path to the source (en-US) file.
+ self.template_path = template_path
+ # The URL to fetch the component's translations from.
+ self.translations_url = translations_url
+ # The translations data, indexed by the locale file paths. Lazy-loaded
+ # and `None` whilst unfilled.
+ self.translations: None | dict[str, WeblateTranslation] = None
+
+
class WeblateMetadata:
"""
- Manages and fetches string metadata from weblate.
+ Manages and fetches string metadata from Weblate.
"""
- def __init__(self):
+ # The translation branches that we expect to be used for Weblate.
+ _BROWSER_BRANCHES = ["tor-browser", "base-browser", "fenix-torbrowserstringsxml"]
+ _WEBLATE_API_URL = "https://hosted.weblate.org/api/"
+ _WEBLATE_API_TOR_COMPONENTS_URL = _WEBLATE_API_URL + "projects/tor/components/"
+
+ def __init__(self) -> None:
+ """
+ Create a new instance for fetching Weblate metadata.
+ """
self.logger = logging.getLogger("weblate-metadata")
self.logger.setLevel(logging.INFO)
- # The _components property will be lazy-loaded with weblate data.
- #
- # On weblate, for monolingual formats, the component will have a
- # "template" file, which matches the en-US file path in the
- # "translation" git repo. So we can find a component through a matching
- # template.
- #
- # Each translation in that component will have a "filename" that will
- # match the locale's file path in the "translation" git repo. So we can
- # find a translation through a matching filename.
- #
- # Each translation can be queried for its units, including metadata.
- # Each unit's "context" will match the string's id in the corresponding
- # file.
- #
- # Expect the final structure to be:
- # {
- # template: {
- # "translations-url": str, # Used for API translations query.
- # "translations": {
- # filename: {
- # "units-url": str, # Used for API units query.
- # "units": {
- # context: {
- # "translated": bool,
- # },
- # },
- # },
- # },
- # },
- # }
- self._components = None
-
- def _get_weblate_response(self, url):
+ # The _components property will be lazy-loaded with Weblate data.
+ self._components: dict[str, WeblateComponent] | None = None
+
+ def _get_weblate_response(self, url: str) -> Any:
+ """
+ Make a single query to Weblate.
+ :param url: The URL to fetch.
+ :returns: The JSON response.
+ """
+ if not url.startswith(self._WEBLATE_API_URL):
+ raise ValueError(f"Unexpected URL request: {url}")
+
weblate_request = urllib.request.Request(
url,
# NOTE: can set the request header:
# "Authorization": "Token WEBLATE_TOKEN"
- # to get around rate-limiting
+ # to get around rate-limiting.
+ # NOTE: We empty the User-Agent to override the default
+ # value of "Python-urllib/{major}.{minor}".
headers={"User-Agent": ""},
)
- with urllib.request.urlopen(weblate_request, timeout=20) as response:
+ with urllib.request.urlopen(weblate_request) as response:
return json.load(response)
- def _get_from_weblate(self, url):
- ret = []
+ def _get_from_weblate(self, url: str) -> list[dict[Any, Any]]:
+ """
+ Fetch a list of results from Weblate.
+ :param url: The initial URL to fetch a response from.
+ :returns: The returned list of results.
+ """
+ ret: list[dict[Any, Any]] = []
while url:
response = self._get_weblate_response(url)
+ if not isinstance(response, dict):
+ raise ValueError(f"Unexpected response type for {url}")
+ assert_keys(response, ("results", "next"), url)
+
+ res_val = response["results"]
+ if not isinstance(res_val, list):
+ raise ValueError(f"Unexpected 'results' type for {url}")
+ for res_item in res_val:
+ if not isinstance(res_item, dict):
+ raise ValueError(f"Unexpected 'results' item type for {url}")
+ ret.append(res_item)
+
# Continue to fetch the next page, if it is present.
- # Expect the "next" url to be empty
+ # Expect the "next" url to be null
# or the same url with "?page=2", etc.
- url = response["next"]
- ret.extend(response["results"])
+ next_val = response["next"]
+ if next_val is not None and not isinstance(next_val, str):
+ raise ValueError(f"Unexpected 'next' type in response for {url}")
+ url = "" if next_val is None else next_val
return ret
- def _get_components(self):
+ def _get_components(self) -> dict[str, WeblateComponent]:
+ """
+ Get all the Tor Browser Weblate components.
+
+ We identify each Weblate component by its template path: the en-US
+ file path in the translation repository.
+
+ NOTE: We assume that the template path uniquely identifies the
+ component, even though this is not guaranteed in general by Weblate.
+
+ :returns: A dictionary of components, indexed by their en-US template
+ path.
+ """
+ url = self._WEBLATE_API_TOR_COMPONENTS_URL
if self._components is None:
self._components = {
- comp["template"]: {
- "translations": None,
- "translations-url": comp["translations_url"],
- }
- for comp in self._get_from_weblate(
- "https://hosted.weblate.org/api/projects/tor/components/"
+ comp.template_path: comp
+ for comp in (
+ WeblateComponent(data, url) for data in self._get_from_weblate(url)
)
- if comp["template"]
+ if comp.template_path and comp.branch in self._BROWSER_BRANCHES
}
return self._components
- def _get_translations(self, template):
- component = self._get_components().get(template, None)
+ def _get_translations(
+ self, template_path: str
+ ) -> dict[str, WeblateTranslation] | None:
+ """
+ Get the Weblate translations for a given Weblate component.
+
+ We identify each translation by its file path: the locale-specific path
+ that the translated file is written to.
+
+ :param template_path: The component's en-US template path.
+ :returns: A dictionary of translations, indexed by their locale file
+ paths. Or `None` if no components were found.
+ """
+ component = self._get_components().get(template_path, None)
if not component:
- self.logger.warning(f"No component in weblate for {template}.")
+ self.logger.warning(f"No component in Weblate for {template_path}.")
return None
- if component["translations"] is None:
- component["translations"] = {
- trans["filename"]: {
- "units": None,
- "units-url": trans["units_list_url"],
- }
- for trans in self._get_from_weblate(component["translations-url"])
+ if component.translations is None:
+ url = component.translations_url
+ component.translations = {
+ trans.locale_path: trans
+ for trans in (
+ WeblateTranslation(data, url)
+ for data in self._get_from_weblate(url)
+ )
}
- return component["translations"]
+ return component.translations
+
+ def _get_units(
+ self, template_path: str, locale_path: str
+ ) -> dict[str, WeblateUnit] | None:
+ """
+ Get the Weblate units for a given Weblate translation.
+
+ We identify each unit by its string ID.
- def _get_units(self, template, file):
- translation_dict = self._get_translations(template)
+ :param template_path: The containing component's en-US template path.
+ :param locale_path: The translation's locale file path.
+ :returns: A dictionary of units, indexed by their string ID. Or `None`
+ if no translations could be found.
+ """
+ translation_dict = self._get_translations(template_path)
if translation_dict is None:
return None
- translation = translation_dict.get(file, None)
+ translation = translation_dict.get(locale_path, None)
if translation is None:
- self.logger.warning(f"No translation in weblate for {file}.")
+ self.logger.warning(f"No translation in Weblate for {locale_path}.")
return None
- if translation["units"] is None:
- translation["units"] = {
- unit["context"]: {
- "translated": unit["translated"],
- }
- for unit in self._get_from_weblate(translation["units-url"])
+ if translation.units is None:
+ url = translation.units_url
+ translation.units = {
+ unit.string_id: unit
+ for unit in (
+ WeblateUnit(data, url) for data in self._get_from_weblate(url)
+ )
}
- return translation["units"]
+ return translation.units
- def is_translated(self, template_path, locale_path, string_id):
+ def is_translated(self, file_path: str, locale: str, string_id: str) -> bool:
"""
- Whether the given string is marked as translated on weblate.
+ Test whether the given string is marked as translated on Weblate.
+
+ :param file_path: The file to check the translation of, relative to the
+ locale's directory.
+ :param locale: The locale to check for.
+ :param string_id: The ID of the string to check.
"""
+ template_path = os.path.join("en-US", file_path)
+ locale_path = os.path.join(locale, file_path)
unit_dict = self._get_units(template_path, locale_path)
if unit_dict is None:
return False
unit = unit_dict.get(string_id, None)
if unit is None:
- self.logger.warning(f"No unit in weblate for {locale_path}:{string_id}.")
+ self.logger.warning(f"No unit in Weblate for {locale_path}:{string_id}.")
return False
- return unit["translated"]
+ return unit.translated
class TorBrowserMigrationContext(MigrationContext):
@@ -206,12 +557,18 @@ class TorBrowserMigrationContext(MigrationContext):
Extension which adds some extra methods to use for tor-browser.
"""
- def __init__(self, locale, reference_dir, localization_dir):
+ def __init__(self, locale: str, reference_dir: str, localization_dir: str) -> None:
super().__init__(locale, reference_dir, localization_dir)
- def _fluent_keys(self, resource):
+ def _fluent_keys(self, resource: ast.Resource) -> Iterator[str]:
+ """
+ Generate all the keys within a Fluent resource, where a key is an
+ identifier for a Term, a Message, a Term attribute, or a Message
+ attribute.
+ :yield: The Fluent keys.
+ """
# ast.Resource, want to extract all Message and Term identifiers, as
- # well as their
+ # well as their attributes.
for entry in resource.body:
if not isinstance(entry, (ast.Term, ast.Message)):
continue
@@ -223,12 +580,13 @@ class TorBrowserMigrationContext(MigrationContext):
for attr in entry.attributes:
yield f"{key}.{attr.id.name}"
- def tb_get_available_strings(self):
+ def tb_get_available_strings(self) -> set[tuple[str, str]]:
"""
- Return all the (path, string_id) pairs for all loaded localization
+ Get all the (path, string_id) pairs for all loaded localization
resources.
+ :returns: The string pairs.
"""
- all_strings = set()
+ all_strings: set[tuple[str, str]] = set()
# ctx.localization_resources is a dict containing all the loaded
# localization_resources that have been added during add_transforms.
# { localization_path: resource }
@@ -237,14 +595,13 @@ class TorBrowserMigrationContext(MigrationContext):
all_strings.update((path, key) for key in self._fluent_keys(resource))
else:
# dictionary of { identifies: value } in legacy resource.
- # For tor-browser,
- # Only include references that differ from the en-US strings.
all_strings.update((path, key) for key in resource.keys())
return all_strings
- def tb_get_missing_resources(self):
+ def tb_get_missing_resources(self) -> set[str]:
"""
- Return the missing localization resources.
+ Get the missing localization resources.
+ :returns: The set of resource paths.
"""
return set(
path
@@ -253,25 +610,51 @@ class TorBrowserMigrationContext(MigrationContext):
if path not in self.localization_resources
)
- def tb_get_transform(self, target_path, transform_id):
+ def tb_get_transform(
+ self, target_path: str, transform_id: str
+ ) -> ast.Message | ast.Term | None:
"""
- Find the transformation node with the given id for the given path.
+ Find a transformation node.
+ :param target_path: The target path of the transformation.
+ :param transform_id: The ID of the transformation, AKA the string ID.
+ :returns: The matching transformation node, or `None` if there is no
+ match.
"""
for node in self.transforms[target_path]:
if node.id.name == transform_id:
return node
return None
- def tb_get_reference_entry(self, target_path, entry_id):
+ def tb_get_reference_entry(
+ self, target_path: str, transform_id: str
+ ) -> ast.Message | ast.Term | None:
"""
- Find the reference node that would be used for the given id and path.
+ Find a reference Message or Term for a given transformation.
+ :param target_path: The target path of the transformation.
+ :param transform_id: The ID of the transformation, AKA the string ID.
+ :returns: The matching reference entry for the transformation, or `None`
+ if there is no match.
"""
for entry in self.reference_resources[target_path].body:
- if isinstance(entry, (ast.Term, ast.Message)) and entry.id.name == entry_id:
+ if (
+ isinstance(entry, (ast.Term, ast.Message))
+ and entry.id.name == transform_id
+ ):
return entry.clone()
return None
+class RecipeModule(Protocol):
+ def migrate(self, context: MigrationContext) -> None: ...
+
+
+class FluentSyntaxError(NamedTuple):
+ path: str
+ message: str
+ line: int
+ sample: str
+
+
class TorBrowserMigrator:
"""
Performs a tor-browser migration.
@@ -279,26 +662,38 @@ class TorBrowserMigrator:
def __init__(
self,
- en_US_dir,
- locale_dirs,
- migrate_module,
- weblate_metadata,
- ):
+ en_US_ref_dir: str,
+ en_US_target_dir: str,
+ locale_dirs: dict[str, str],
+ recipe_module: RecipeModule,
+ weblate_metadata: WeblateMetadata,
+ ) -> None:
+ """
+ :param en_US_ref_dir: The path to the en-US directory where reference
+ Fluent entries for the recipe can be found.
+ :param en_US_target_dir: The path to the en-US directory where existing
+ strings used by the recipe can be found.
+ :param locale_dirs: The collection of locales to run the migrations for.
+ :param recipe_module: The python module that contains the recipe
+ instructions.
+ :param weblate_metadata: The object to fetch Weblate metadata from.
+ """
self.logger = logging.getLogger("tor-browser-migrator")
self.logger.setLevel(logging.INFO)
- self.en_US_dir = en_US_dir
+ self.en_US_ref_dir = en_US_ref_dir
+ self.en_US_target_dir = en_US_target_dir
self.locale_dirs = locale_dirs
- self.migrate_module = migrate_module
+ self.recipe_module = recipe_module
self.weblate_metadata = weblate_metadata
- def run(self):
+ def run(self) -> None:
"""
Run the migration.
"""
if not self._check_en_US_resources():
sys.exit(1)
- fluent_errors = []
+ fluent_errors: list[FluentSyntaxError] = []
for locale, locale_dir in self.locale_dirs.items():
if locale == "en-US":
print("", file=sys.stderr)
@@ -316,12 +711,18 @@ class TorBrowserMigrator:
"Migration does not need to be run again, but the following "
"syntax errors should be fixed manually.\n"
+ "\n".join(
- f"{in_red(full_path)}: line {line}: {message}: [[{sample}]]"
- for full_path, message, line, sample in fluent_errors
+ f"{in_red(err.path)}: line {err.line}: {err.message}: [[{err.sample}]]"
+ for err in fluent_errors
)
)
- def _run_locale(self, locale, locale_dir):
+ def _run_locale(self, locale: str, locale_dir: str) -> list[FluentSyntaxError]:
+ """
+ Run a migration for a given locale.
+ :param locale: The name of the locale.
+ :param locale_dir: The path to the locale's directory.
+ :returns: A list of Fluent errors in the written files.
+ """
print("\n\n", file=sys.stderr)
self.logger.info(f"Migrating '{in_red(locale)}' locale\n")
@@ -358,7 +759,7 @@ class TorBrowserMigrator:
available_strings = ctx.tb_get_available_strings()
wrote_file = False
- errors = []
+ errors: list[FluentSyntaxError] = []
for target_path, reference in ctx.reference_resources.items():
translated_ids = [
@@ -422,13 +823,13 @@ class TorBrowserMigrator:
break
# Strings in legacy formats might have an entry in the file
# that is just a copy of the en-US strings.
- # For these we want to check the weblate metadata to ensure
+ # For these we want to check the Weblate metadata to ensure
# it is a translated string.
if not path.endswith(
".ftl"
) and not self.weblate_metadata.is_translated(
- os.path.join("en-US", path),
- os.path.join(locale, path),
+ path,
+ locale,
string_id,
):
can_transform = False
@@ -436,7 +837,7 @@ class TorBrowserMigrator:
f"Skipping transform {target_path}:{transform_id} "
f"for '{locale}' locale because the string "
f"{path}:{string_id} has not been translated on "
- "weblate."
+ "Weblate."
)
break
if not can_transform:
@@ -463,7 +864,9 @@ class TorBrowserMigrator:
wrote_file = True
# Collect any fluent parsing errors from the newly written file.
errors.extend(
- (full_path, message, line, sample)
+ FluentSyntaxError(
+ path=full_path, message=message, line=line, sample=sample
+ )
for message, line, sample in self._fluent_errors(full_content)
)
@@ -471,27 +874,42 @@ class TorBrowserMigrator:
self.logger.info(f"No files written for '{locale}' locale.")
return errors
- def _fluent_errors(self, fluent):
+ def _fluent_errors(self, fluent_content: str) -> Iterator[tuple[str, int, str]]:
"""
- Verify that the given fluent string can be parsed correctly.
+ Parse the given content as a Fluent file and generate all the syntax
+ errors.
+ :param fluent_content: The file content to parse.
+ :yield: Each encountered Fluent syntax error as a triple of the message,
+ the line number, and a sample.
"""
- resource = parse(fluent)
+ resource = parse(fluent_content)
for entry in resource.body:
if not isinstance(entry, ast.Junk):
continue
for annotation in entry.annotations:
- line = fluent[0 : annotation.span.start].count("\n") + 1
- sample_start = max(annotation.span.start - 15, 0)
- sample = "…" + fluent[sample_start : sample_start + 30] + "…"
- yield annotation.message, line, sample
-
- def _get_migration_context(self, locale, locale_dir):
- prev_missing_resources = set()
+ start = 0
+ if annotation.span:
+ start = annotation.span.start
+ line = fluent_content[0:start].count("\n") + 1
+ sample_start = max(start - 15, 0)
+ sample = "…" + fluent_content[sample_start : sample_start + 30] + "…"
+ yield annotation.message or "", line, sample
+
+ def _get_migration_context(
+ self, locale: str, locale_dir: str
+ ) -> TorBrowserMigrationContext:
+ """
+ Create a new migration context.
+ :param locale: The name of the locale.
+ :param locale_dir: The directory path for the locale.
+ :returns: The new context.
+ """
+ prev_missing_resources: set[str] = set()
while True:
- ctx = TorBrowserMigrationContext(locale, self.en_US_dir, locale_dir)
+ ctx = TorBrowserMigrationContext(locale, self.en_US_ref_dir, locale_dir)
try:
- self.migrate_module.migrate(ctx)
+ self.recipe_module.migrate(ctx)
except EmptyLocalizationError:
# This case will be handled by missing_resources below.
# NOTE: At the time of writing, add_transforms only throws if
@@ -543,20 +961,28 @@ class TorBrowserMigrator:
# before localization_resources was fully populated.
prev_missing_resources = missing_resources
- def _remove_if_empty(self, path):
+ def _remove_if_empty(self, path: str) -> None:
+ """
+ Remove a file if it is empty.
+ :param path: The path to remove.
+ """
if os.stat(path).st_size:
self.logger.warning(f"{path} is no longer empty. Not deleting.")
return
os.remove(path)
- def _check_en_US_resources(self):
- # We pass in the en-US directory as the localization directory, as well
- # as the reference directory.
- ctx = TorBrowserMigrationContext("en-US", self.en_US_dir, self.en_US_dir)
+ def _check_en_US_resources(self) -> bool:
+ """
+ Verify that the migration recipe works as expected using en-US strings.
+ :returns: Whether the recipe worked as expected.
+ """
+ ctx = TorBrowserMigrationContext(
+ "en-US", self.en_US_ref_dir, self.en_US_target_dir
+ )
have_error = False
try:
- self.migrate_module.migrate(ctx)
+ self.recipe_module.migrate(ctx)
except EmptyLocalizationError:
# Handle with localization_resources check.
# NOTE: This throwing may have prevented further add_transforms from
@@ -566,7 +992,9 @@ class TorBrowserMigrator:
have_error = True
except UnreadableReferenceError:
# Reference filename is printed before this.
- self.logger.error("Missing an en-US reference file.")
+ self.logger.error(
+ "Missing an en-US reference file. Is --reference-directory correct?"
+ )
return False
# Check each transform would create the same entry in the target as the
@@ -602,7 +1030,8 @@ class TorBrowserMigrator:
reference_entry = ctx.tb_get_reference_entry(target_path, transform_id)
if reference_entry is None:
self.logger.error(
- f"Missing en-US reference entry for transform {transform_name}"
+ f"Missing en-US reference entry for transform {transform_name}. "
+ "Is --reference-directory correct?"
)
have_error = True
continue
@@ -625,9 +1054,50 @@ class TorBrowserMigrator:
return not have_error
+def main(recipe_path: str, translation_dir: str, locales: str, ref_dir: str) -> None:
+ """
+ The main method.
+ :param recipe_path: The path to the recipe script.
+ :param translation_dir: The path to the translation repository directory.
+ :param locales: The locales to run the recipe for, separated by spaces.
+ :param ref_dir: The path to the reference directory.
+ """
+ if not os.path.isfile(recipe_path):
+ print(f"{in_red(recipe_path)} is not a file.", file=sys.stderr)
+ sys.exit(1)
+
+ recipe_module_spec = importlib.util.spec_from_file_location("_recipe", recipe_path)
+ recipe_module = cast(
+ RecipeModule, importlib.util.module_from_spec(recipe_module_spec)
+ )
+ recipe_module_spec.loader.exec_module(recipe_module)
+
+ def check_dir(path: str) -> str:
+ if not os.path.isdir(path):
+ print(f"{in_red(path)} is not a directory.", file=sys.stderr)
+ sys.exit(1)
+ return path
+
+ translation_dir = check_dir(translation_dir)
+ en_US_target_dir = check_dir(os.path.join(translation_dir, "en-US"))
+ en_US_ref_dir = en_US_target_dir if ref_dir is None else check_dir(ref_dir)
+
+ TorBrowserMigrator(
+ en_US_ref_dir,
+ en_US_target_dir,
+ {
+ locale: check_dir(os.path.join(translation_dir, locale))
+ for locale in (l.strip() for l in locales.split(" "))
+ if locale
+ },
+ recipe_module,
+ WeblateMetadata(),
+ ).run()
+
+
parser = argparse.ArgumentParser(
description="Run a tor-browser localization migration. "
- "See documentation within migrate_l10n.py."
+ "See documentation within migrate.py."
)
parser.add_argument(
"--translation-git",
@@ -638,35 +1108,30 @@ parser.add_argument(
parser.add_argument(
"--locales",
required=True,
- metavar="<locale1> <locale2> ...",
- help="Set of locales to restrict the migration to, separated by space.",
+ metavar="'<locale1> <locale2> ...'",
+ help="Set of locales to run the migration for, separated by space.",
)
parser.add_argument(
- "migration",
- help="Migration to run, given as a python module. "
- 'E.g. "l10n_migrations.my-migration-script".',
+ "--reference-directory",
+ metavar="<dir>",
+ help="Location of the en-US directory that contains the reference changes "
+ "that the recipe corresponds to. E.g. if the recipe constructs the string "
+ "`my-new-string` in `./tor-browser.ftl`, it should point to a directory "
+ "that contains the en-US `tor-browser.ftl` with `my-new-string` already "
+ "within it. Defaults to the `en-US/` sub-directory within the "
+ "translation-git directory.",
+)
+parser.add_argument(
+ "recipe",
+ help="The path to the migration recipe to run.",
)
parsed_args = parser.parse_args()
-
-def check_dir(path):
- if not os.path.isdir(path):
- print(f"{in_red(path)} is not a directory.", file=sys.stderr)
- sys.exit(1)
- return path
-
-
-translation_dir = check_dir(os.path.abspath(parsed_args.translation_git))
-
-TorBrowserMigrator(
- check_dir(os.path.join(translation_dir, "en-US")),
- {
- locale: check_dir(os.path.join(translation_dir, locale))
- for locale in (l.strip() for l in parsed_args.locales.split(" "))
- if locale
- },
- importlib.import_module(parsed_args.migration),
- WeblateMetadata(),
-).run()
+main(
+ parsed_args.recipe,
+ parsed_args.translation_git,
+ parsed_args.locales,
+ parsed_args.reference_directory,
+)
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/1f8c6d…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/1f8c6d…
You're receiving this email because of your account on gitlab.torproject.org. Manage all notifications: https://gitlab.torproject.org/-/profile/notifications | Help: https://gitlab.torproject.org/help
1
0
[Git][tpo/applications/tor-browser][tor-browser-155.0a1-17.0-1] 32 commits: fixup! TB 44806: Implement the tor integration in Rust.
by Pier Angelo Vendrame (@pierov) 04 Nov '26
by Pier Angelo Vendrame (@pierov) 04 Nov '26
04 Nov '26
Pier Angelo Vendrame pushed to branch tor-browser-155.0a1-17.0-1 at The Tor Project / Applications / Tor Browser
Commits:
7b5a2f23 by Elena at 2026-10-29T12:24:46+01:00
fixup! TB 44806: Implement the tor integration in Rust.
TB 44930: Implement the commands on the Rust control port
Implemented string unescape.
- - - - -
934763cc by Elena at 2026-10-29T12:24:46+01:00
fixup! TB 44806: Implement the tor integration in Rust.
TB 44930: Implement the commands on the Rust control port
Implemented the string escaping.
- - - - -
cada30ea by Beatriz Rizental at 2026-10-29T12:24:47+01:00
fixup! TB 40562: Added Tor Browser preferences to 000-tor-browser.js
Bug 44155: Set local network access prefs to block it all.
This is defense-in-depth, since other mechanisms already block it.
- - - - -
bdf10fa2 by Beatriz Rizental at 2026-10-29T12:24:47+01:00
fixup! [android] Disable features and functionality
Bug 44155: Hide local network access toggles from settings.
These toggles are no-op already, since local network access is always
disabled throuh other mechanisms.
- - - - -
1ff06067 by hackademix at 2026-10-29T12:24:47+01:00
fixup! TB 27476: Implement about:torconnect captive portal within Tor Browser
TB 45264: Use parent process for TorConnect redirections
- - - - -
6ba967f6 by Beatriz Rizental at 2026-10-29T12:24:48+01:00
fixup! TB 44806: Implement the tor integration in Rust.
TB 44930: Implement the commands on the Rust control port
Implement more tests.
- - - - -
2be540e0 by clairehurst at 2026-10-29T12:24:48+01:00
fixup! [android] Implement Android-native Connection Assist UI
Bug 45172: Move away from openToBrowserAndLoad()
- - - - -
f1a07514 by clairehurst at 2026-10-29T12:24:48+01:00
fixup! [android] Modify UI/UX
Bug 45172: Move away from openToBrowserAndLoad()
- - - - -
67576928 by Beatriz Rizental at 2026-10-29T12:24:48+01:00
fixup! BB 45171: Disable split view.
Bug 44431: Disable about:opentabs
- - - - -
e5807d23 by clairehurst at 2026-10-29T12:24:49+01:00
TB 45269 [android]: Completely disable search suggestion feature
- - - - -
76ab21ba by clairehurst at 2026-10-29T12:24:49+01:00
fixup! TB 44653 [android]: Disable 'Allow search suggestions in private sessions' prompt presented in RR 148 android
TB 45269 [android]: Completely disable search suggestion feature.
Note to rebaser: After squashing this commit into "TB 44653 [android]: Disable 'Allow search suggestions in private sessions' prompt presented in RR 148 android", I think that it would make sense to then squash that commit into TB 45269 [android]: Completely disable search suggestion feature
- - - - -
0a797fce by Beatriz Rizental at 2026-10-29T12:24:49+01:00
fixup! [android] Modify UI/UX
Bug 44695: Drop unnecessary Android test patch
- - - - -
44cb3522 by Henry Wilkes at 2026-10-29T12:24:50+01:00
fixup! TB 40562: Added Tor Browser preferences to 000-tor-browser.js
TB 45262: Hide the reset PBM button.
- - - - -
79622727 by Henry Wilkes at 2026-10-29T12:24:50+01:00
fixup! TB 41736: Customize toolbar for tor-browser.
TB 45262: Hide the reset PBM button.
- - - - -
50527013 by Henry Wilkes at 2026-10-29T12:24:50+01:00
TB 45218: YEC 2026 assets.
- - - - -
60bc6e90 by Pier Angelo Vendrame at 2026-10-29T12:24:51+01:00
fixup! Firefox preference overrides.
BB 45278: Disable WebXR as a defense-in-depth.
- - - - -
5698ad6f by Henry Wilkes at 2026-10-29T12:24:51+01:00
fixup! TB 2176: Rebrand Firefox to TorBrowser
TB 45277: Swap firefox icon for tor browser icon in settings.
- - - - -
d6a4ae2e by Beatriz Rizental at 2026-10-29T12:24:51+01:00
fixup! Firefox preference overrides.
Bug 45133: Disable browser.toolbars.share-button.enabled
- - - - -
e558d8fc by Pier Angelo Vendrame at 2026-10-29T12:24:52+01:00
fixup! TB 40562: Added Tor Browser preferences to 000-tor-browser.js
TB 45275: Drop some clearOnShutdown preferences.
They were in the Android-specific profile file, but they do not do
anything on Android.
- - - - -
d72a3a21 by clairehurst at 2026-10-29T12:24:52+01:00
fixup! [android] Disable features and functionality
TB 44548: Remove "Passwords" UI from Android
- - - - -
6bba5472 by clairehurst at 2026-10-29T12:24:52+01:00
fixup! [android] Disable features and functionality
TB 45250: Remove "Privacy report" in tabs settings in Android
- - - - -
27738db1 by clairehurst at 2026-10-29T12:24:53+01:00
fixup! [android] Disable features and functionality
TB 45225: Remove "Share" and "Translate" options from "Settings" -> "Customize" -> "Toolbar shortcut"
- - - - -
479ca0f8 by Beatriz Rizental at 2026-10-29T12:24:53+01:00
fixup! TB 40562: Added Tor Browser preferences to 000-tor-browser.js
Bug 45237: Disable multiple profiles feature
- - - - -
d7806ca4 by Elena at 2026-10-29T12:24:53+01:00
fixup! TB 44806: Implement the tor integration in Rust.
TB 44930: Implement the commands on the Rust control port
Created TorController
- - - - -
bf79688d by Elena at 2026-10-29T12:24:54+01:00
fixup! TB 44806: Implement the tor integration in Rust.
TB 44930: Implement the commands on the Rust control port
Implemented the authenticate method.
- - - - -
78188881 by Elena at 2026-10-29T12:24:54+01:00
fixup! TB 44806: Implement the tor integration in Rust.
TB 44930: Implement the commands on the Rust control port
Implemented a few simple commands.
- - - - -
ab3b1eef by Dan Ballard at 2026-10-29T12:24:54+01:00
fixup! [android] Disable features and functionality
TB 45251: Disable and Remove remote improvements UI
- - - - -
2067b3ab by Beatriz Rizental at 2026-10-29T12:24:54+01:00
TB 45621: Implement linter for Tor Browser-specific checks
- - - - -
3cd14c89 by Gela at 2026-11-02T18:14:12+01:00
Bug 2053320 - Part 1: Don't tie Nimbus tooling to `HomeActivity` UI a=RyanVM
Original Revision: https://phabricator.services.mozilla.com/D319628
Differential Revision: https://phabricator.services.mozilla.com/D320784
- - - - -
9177d2a4 by Beatriz Rizental at 2026-11-02T18:14:48+01:00
fixup! [android] Disable features and functionality
Bug 45621: Prevent other apps from opening Tor Browser
- - - - -
11310765 by Pier Angelo Vendrame at 2026-11-02T18:14:51+01:00
fixup! Firefox preference overrides.
BB 45133: Add a missing semicolon.
- - - - -
90e50e2b by clairehurst at 2026-11-02T18:14:51+01:00
fixup! [android] Disable features and functionality
TB 45252: Remove the change wallpaper menu item
155.0a1 rebase note: this was replaced upstream with a button to
customize the homepage.
I replaced that one instead.
- - - - -
70 changed files:
- Cargo.lock
- browser/app/profile/000-tor-browser.js
- browser/app/profile/001-base-profile.js
- browser/components/about/AboutRedirector.cpp
- browser/components/about/components.conf
- browser/components/abouttor/content/aboutTor.html
- browser/components/customizableui/CustomizableUI.sys.mjs
- browser/components/torconnect/TorConnectChild.sys.mjs
- browser/components/torconnect/TorConnectParent.sys.mjs
- browser/themes/shared/jar.inc.mn
- + browser/themes/shared/sidebar/tor-browser.svg
- mobile/android/app/000-tor-browser-android.js
- mobile/android/fenix/app/src/main/AndroidManifest.xml
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/addons/AddonDetailsFragment.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/addons/AddonPermissionsDetailsFragment.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/addons/Extensions.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/addons/InstalledAddonDetailsFragment.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/MenuDialogFragment.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/compose/MainMenu.kt
- + mobile/android/fenix/app/src/main/java/org/mozilla/fenix/experiments/QANimbusToolingReceiver.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/HttpsOnlyFragment.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/TabsSettingsFragment.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/ToolbarShortcut.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/about/AboutFragment.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/search/SaveSearchEngineFragment.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/search/SearchEngineFragment.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsDetailsExceptionsFragment.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/SiteSettingsFragment.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt
- mobile/android/fenix/app/src/main/res/xml/preferences.xml
- mobile/android/fenix/app/src/main/res/xml/remote_improvements_preferences.xml
- mobile/android/fenix/app/src/main/res/xml/save_logins_preferences.xml
- mobile/android/fenix/app/src/main/res/xml/search_settings_preferences.xml
- mobile/android/fenix/app/src/main/res/xml/tabs_preferences.xml
- mobile/android/fenix/app/src/nightly/AndroidManifest.xml
- + mobile/android/fenix/app/src/test/java/org/mozilla/fenix/experiments/QANimbusToolingReceiverTest.kt
- mobile/android/fenix/app/src/test/java/org/mozilla/fenix/settings/SupportUtilsTest.kt
- toolkit/components/tor-integration/tor_provider/Cargo.toml
- toolkit/components/tor-integration/tor_provider/src/ctor/control_port/control_port.rs
- toolkit/components/tor-integration/tor_provider/src/ctor/control_port/mod.rs
- + toolkit/components/tor-integration/tor_provider/src/ctor/controller/commands/authenticate.rs
- + toolkit/components/tor-integration/tor_provider/src/ctor/controller/commands/command.rs
- + toolkit/components/tor-integration/tor_provider/src/ctor/controller/commands/mod.rs
- + toolkit/components/tor-integration/tor_provider/src/ctor/controller/commands/reset_conf.rs
- + toolkit/components/tor-integration/tor_provider/src/ctor/controller/commands/save_conf.rs
- + toolkit/components/tor-integration/tor_provider/src/ctor/controller/commands/set_events.rs
- + toolkit/components/tor-integration/tor_provider/src/ctor/controller/commands/signal.rs
- + toolkit/components/tor-integration/tor_provider/src/ctor/controller/commands/take_ownership.rs
- + toolkit/components/tor-integration/tor_provider/src/ctor/controller/controller.rs
- + toolkit/components/tor-integration/tor_provider/src/ctor/controller/error.rs
- + toolkit/components/tor-integration/tor_provider/src/ctor/controller/mod.rs
- + toolkit/components/tor-integration/tor_provider/src/ctor/controller/parsers/ack.rs
- + toolkit/components/tor-integration/tor_provider/src/ctor/controller/parsers/escape.rs
- + toolkit/components/tor-integration/tor_provider/src/ctor/controller/parsers/mod.rs
- + toolkit/components/tor-integration/tor_provider/src/ctor/controller/parsers/tests.rs
- + toolkit/components/tor-integration/tor_provider/src/ctor/controller/parsers/unescape.rs
- toolkit/components/tor-integration/tor_provider/src/ctor/mod.rs
- toolkit/components/tor-integration/tor_provider/src/ctor/reply_parser/line.rs
- toolkit/components/tor-integration/tor_service/src/control_port.rs
- toolkit/locales/en-US/toolkit/global/tor-browser.ftl
- + tools/lint/test/files/tor-browser-checks/bad/AndroidManifest.xml
- + tools/lint/test/files/tor-browser-checks/good/AndroidManifest.xml
- tools/lint/test/python.toml
- + tools/lint/test/test_tor_browser_checks.py
- + tools/lint/tor-browser-checks.yml
- + tools/lint/tor-browser-checks/__init__.py
The diff was not included because it is too large.
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/6d27f4…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/6d27f4…
You're receiving this email because of your account on gitlab.torproject.org. Manage all notifications: https://gitlab.torproject.org/-/profile/notifications | Help: https://gitlab.torproject.org/help
1
0
[Git][tpo/applications/torbrowser-launcher][main] 4 commits: feat: Add aarch64 support
by asciiwolf (@asciiwolf) 04 Nov '26
by asciiwolf (@asciiwolf) 04 Nov '26
04 Nov '26
asciiwolf pushed to branch main at The Tor Project / Applications / torbrowser-launcher
Commits:
62732628 by Ferenc Géczi at 2026-05-30T00:00:00+00:00
feat: Add aarch64 support
Signed-off-by: Ferenc Géczi <ferenc.gm(a)gmail.com>
- - - - -
ada48643 by Ferenc Géczi at 2026-11-03T00:00:00+00:00
fix: Drop unsupported i686 branch
Signed-off-by: Ferenc Géczi <ferenc.gm(a)gmail.com>
- - - - -
944343e5 by Ferenc Géczi at 2026-11-03T00:00:00+00:00
fix: Raise unknown architecture exception
Signed-off-by: Ferenc Géczi <ferenc.gm(a)gmail.com>
- - - - -
6b98556b by asciiwolf at 2026-11-04T00:12:19+00:00
Merge branch 'aarch64' into 'main'
feat: Add aarch64 support
See merge request tpo/applications/torbrowser-launcher!48
- - - - -
1 changed file:
- torbrowser_launcher/common.py
Changes:
=====================================
torbrowser_launcher/common.py
=====================================
@@ -47,7 +47,7 @@ class Common(object):
self.tbl_version = tbl_version
# initialize the app
- self.architecture = "x86_64" if "64" in platform.architecture()[0] else "i686"
+ self.architecture = platform.machine()
self.default_mirror = "https://dist.torproject.org/"
self.build_paths()
self.torbrowser12_rename_old_tbb()
@@ -96,8 +96,10 @@ class Common(object):
# tarball filename
if self.architecture == "x86_64":
arch = "linux-x86_64"
+ elif self.architecture == "aarch64":
+ arch = "linux-aarch64"
else:
- arch = "linux-i686"
+ raise ValueError("Unsupported architecture!", self.architecture)
tarball_filename = "tor-browser-" + arch + "-" + tbb_version + ".tar.xz"
View it on GitLab: https://gitlab.torproject.org/tpo/applications/torbrowser-launcher/-/compar…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/torbrowser-launcher/-/compar…
You're receiving this email because of your account on gitlab.torproject.org. Manage all notifications: https://gitlab.torproject.org/-/profile/notifications | Help: https://gitlab.torproject.org/help
1
0
[Git][tpo/applications/tor-browser-build][main] 2 commits: Bug 41908: Prepare Tor VPN 1.10.0Beta
by boklm (@boklm) 03 Nov '26
by boklm (@boklm) 03 Nov '26
03 Nov '26
boklm pushed to branch main at The Tor Project / Applications / tor-browser-build
Commits:
03863d93 by Nicolas Vigier at 2026-11-03T17:23:32+01:00
Bug 41908: Prepare Tor VPN 1.10.0Beta
- - - - -
7775a34e by Nicolas Vigier at 2026-11-03T17:45:42+01:00
Bug 41909: Update tools/signing/download-torvpn-release.torvpn for new arch names
- - - - -
2 changed files:
- rbm.conf
- tools/signing/download-torvpn-release.torvpn
Changes:
=====================================
rbm.conf
=====================================
@@ -341,9 +341,9 @@ targets:
torvpn:
var:
tor-vpn: 1
- torbrowser_version: '1.9.1Beta'
+ torbrowser_version: '1.10.0Beta'
torbrowser_build: 'build1'
- browser_release_date: '2026/08/31 07:30:00'
+ browser_release_date: '2026/11/03 07:30:00'
project-name: tor-vpn
projectname: torvpn
Project_Name: 'Tor VPN'
=====================================
tools/signing/download-torvpn-release.torvpn
=====================================
@@ -24,13 +24,13 @@ test $# -ne 1 && \
tmpdir=$(mktemp -p "$script_dir/../../tmp" -d)
trap "rm -Rf $tmpdir" EXIT
cd $tmpdir
-for arch in arm64v8a armeabiv7a universal x86_64
+for arch in arm64-v8a armeabi-v7a universal x86_64
do
case "$arch" in
- arm64v8a)
+ arm64-v8a)
dest_arch=aarch64
;;
- armeabiv7a)
+ armeabi-v7a)
dest_arch=armv7
;;
universal)
@@ -45,8 +45,8 @@ do
mv "$dl_filename" "tor-vpn-qa-unsigned-android-${dest_arch}-${tbb_version}.apk"
done
-wget -O app-universal-release.aab "$base_url/app-universal-release.aab"
-mv app-universal-release.aab "tor-vpn-${tbb_version}.aab"
+wget -O app-release.aab "$base_url/app-release.aab"
+mv app-release.aab "tor-vpn-${tbb_version}.aab"
sha256sum $(ls -1 *.apk *.aab | sort) > sha256sums-unsigned-build.txt
cat sha256sums-unsigned-build.txt
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/compare/…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/compare/…
You're receiving this email because of your account on gitlab.torproject.org. Manage all notifications: https://gitlab.torproject.org/-/profile/notifications | Help: https://gitlab.torproject.org/help
1
0
[Git][tpo/applications/tor-browser][tor-browser-155.0a1-17.0-1] 59 commits: fixup! BB 44711: Hide unwanted setting controls in Base Browser.
by Pier Angelo Vendrame (@pierov) 02 Nov '26
by Pier Angelo Vendrame (@pierov) 02 Nov '26
02 Nov '26
Pier Angelo Vendrame pushed to branch tor-browser-155.0a1-17.0-1 at The Tor Project / Applications / Tor Browser
Commits:
31b1b73b by Henry Wilkes at 2026-10-29T10:58:13+01:00
fixup! BB 44711: Hide unwanted setting controls in Base Browser.
BB 44831: Hide the search suggestions private browsing banner.
- - - - -
97c30067 by clairehurst at 2026-10-29T10:58:14+01:00
fixup! [android] Rename as Tor Browser
TB 45170: Tab Switcher shows Firefox's private browsing mask badge on tab switcher icon
- - - - -
ff3c28cb by clairehurst at 2026-10-29T10:58:14+01:00
fixup! TB 34378: [android] Port external helper app prompting
TB 45049, 41758, 45127: Only open pdf intents from within the app
# Conflicts:
# mobile/android/android-components/components/support/utils/src/main/java/mozilla/components/support/utils/DefaultDownloadFileUtils.kt
- - - - -
7015f61b by clairehurst at 2026-10-29T10:58:36+01:00
fixup! TB 40041: [android] Implement Tor Network Settings
Bug 44881: Remove link sharing pref on android
- - - - -
76cd0fa0 by clairehurst at 2026-10-29T10:58:36+01:00
fixup! [android] Disable features and functionality
Bug 44881: Remove link sharing pref on android
- - - - -
02843c78 by Pier Angelo Vendrame at 2026-10-29T10:58:36+01:00
Bug 2059465 - Disable screen orientation locking on Windows with RFP on. r=timhuang
Differential Revision: https://phabricator.services.mozilla.com/D315311
- - - - -
e99700f7 by Henry Wilkes at 2026-10-29T10:58:37+01:00
fixup! TB 41600: Add a tor circuit display panel.
TB 45194: Match the circuit display button height with its neighbours.
- - - - -
7878c0a7 by Henry Wilkes at 2026-10-29T10:58:37+01:00
fixup! TB 31286: Implementation of bridge, proxy, and firewall settings in about:preferences#connection
TB 45194: Hard code the "your bridges" background colour.
- - - - -
7a8fa140 by Henry Wilkes at 2026-10-29T10:58:37+01:00
fixup! TB 2176: Rebrand Firefox to TorBrowser
TB 44998: Tidy up branding assets.
+ We drop the assets that we expect to be unused.
+ We update `about-logo.png` and `about-logo(a)2x.png` based on
`about-logo.svg` using `rsvg-convert`.
+ We drop our override of the about dialog logo.
+ We add `about-logo-small.svg`, which is a copy of `about-logo.svg`
excluding the "alpha" and "moon" bitmaps. And we use this in place of
`about-logo.png` in `about:preferences`, `about:addons`, and other
consumers of `moz-page-nav`.
- - - - -
82d405cc by Henry Wilkes at 2026-10-29T10:58:38+01:00
BB 45211: Settings UI for protections from third party applications.
- - - - -
a5e86967 by Henry Wilkes at 2026-10-29T10:58:38+01:00
fixup! Base Browser strings
BB 45211: Add strings for protections from third party applications.
- - - - -
2cc22ea2 by Henry Wilkes at 2026-10-29T10:58:38+01:00
TB 45211: Add extra Tor Browser UI for protections from third-party applications.
- - - - -
ebf9b606 by Henry Wilkes at 2026-10-29T10:58:39+01:00
fixup! Tor Browser strings
TB 45211: Add tails recommendation.
- - - - -
012ae8f0 by Pier Angelo Vendrame at 2026-10-29T10:58:39+01:00
dropme! TB 42583: Modify moz-support-link for Tor Browser.
Revert "TB 42583: Modify moz-support-link for Tor Browser."
This reverts commit 6e6a1e36701f649435a84b3911b72a8b5f44f381.
- - - - -
b1a5cf1d by Pier Angelo Vendrame at 2026-10-29T10:58:39+01:00
fixup! BB 42583: Modify moz-support-link for Base Browser.
MB 566: Fix manual links.
- - - - -
55b3e44e by Henry Wilkes at 2026-10-29T10:58:39+01:00
dropme! TB 42583: Modify moz-support-link for Tor Browser.
Restore 6e6a1e36701f649435a84b3911b72a8b5f44f381.
- - - - -
50145dfa by Henry Wilkes at 2026-10-29T10:58:40+01:00
fixup! BB 43902: Modify the new sidebar for Base Browser.
BB 45169: Allow the history item in the sidebar, but hide it by default.
- - - - -
b2d13bf0 by Pier Angelo Vendrame at 2026-10-29T10:58:40+01:00
fixup! TB 27476: Implement about:torconnect captive portal within Tor Browser
TB 45220: Fix about:torconnect not opening when always-on PBM is disabled.
- - - - -
6b7565e6 by Henry Wilkes at 2026-10-29T10:58:40+01:00
fixup! BB 44711: Hide unwanted setting controls in Base Browser.
BB 45209: Replace "Account and sync" with "Profiles".
- - - - -
dd712e8f by Henry Wilkes at 2026-10-29T10:58:41+01:00
fixup! Base Browser strings
BB 45209: Replace "Account and sync" with "Profiles".
- - - - -
772a47a6 by Henry Wilkes at 2026-10-29T10:58:41+01:00
fixup! Firefox preference overrides.
BB 45214: Disable megalist (contextual password manager).
- - - - -
f00edd74 by clairehurst at 2026-10-29T10:58:41+01:00
fixup! [android] Disable features and functionality
- - - - -
97562860 by Beatriz Rizental at 2026-10-29T10:58:41+01:00
fixup! BB 42728: Modify ./mach lint to skip unused linters
Bug 45224: Enable Rust linters
- - - - -
500a325a by Elena at 2026-10-29T10:59:42+01:00
fixup! TB 44806: Implement the tor integration in Rust.
TB 44930: Implement the commands on the Rust control port
Rename ITor... interfaces to torITor...
The prefix is basically a namespace, and really few interfaces do not
have one, so add that prefix also to our interfaces.
- - - - -
e23b1211 by Elena at 2026-10-29T10:59:43+01:00
fixup! TB 44806: Implement the tor integration in Rust.
TB 44930: Implement the commands on the Rust control port
Make it possible to remove the async event handler.
That will help when cleaning stuff up, to make sure not to keep any
circular reference around.
- - - - -
2c60d1f4 by Elena at 2026-10-29T10:59:43+01:00
fixup! TB 44806: Implement the tor integration in Rust.
TB 44930: Implement the commands on the Rust control port
Stop exposing ReplyFactory to the crate.
That should remain an internal type.
Instead, we can expose a "make_reply" test utility, to create one reply
at once. That will be enough.
- - - - -
a56aeeee by Elena at 2026-10-29T10:59:43+01:00
fixup! TB 44806: Implement the tor integration in Rust.
TB 44930: Implement the commands on the Rust control port
Do not add missing CRLF at the control port.
We will be building commands, no need to really include the logic to
add missing CRLF. Instead, catch malformed commands during development.
- - - - -
c19f14e4 by Elena at 2026-10-29T10:59:43+01:00
fixup! TB 44806: Implement the tor integration in Rust.
TB 44930: Implement the commands on the Rust control port
Reorder some methods.
- - - - -
72b51bb6 by Elena at 2026-10-29T10:59:44+01:00
fixup! TB 44806: Implement the tor integration in Rust.
TB 44930: Implement the commands on the Rust control port
Remove ambiguity on the connection closed error.
- - - - -
592afd63 by Henry Wilkes at 2026-10-29T10:59:44+01:00
fixup! TB 31286: Implementation of bridge, proxy, and firewall settings in about:preferences#connection
TB 45226: Make a stylelint exception for "Your bridges".
- - - - -
2b4bb492 by Elena at 2026-10-29T10:59:44+01:00
fixup! TB 44806: Implement the tor integration in Rust.
TB 44930: Implement the commands on the Rust control port
Add a way to add a handler for when connections are closed.
- - - - -
7936ea13 by Dan Ballard at 2026-10-29T10:59:45+01:00
fixup! [android] Disable features and functionality
TB44921: Disable google lens feature
- - - - -
40c61e8b by Dan Ballard at 2026-10-29T10:59:45+01:00
fixup! TB 40002: [android] Ensure system download manager is not used
TB 44054: Remove "open" button from download snackbar; second line defense for shouldShowAppDownloaderDialog
- - - - -
a0716349 by Dan Ballard at 2026-10-29T10:59:45+01:00
fixup! TB 34378: [android] Port external helper app prompting
TB 45221: Remove 'Manage Downloads with another app' pref from download settings
- - - - -
a36b9ed1 by Pier Angelo Vendrame at 2026-10-29T10:59:45+01:00
fixup! Firefox preference overrides.
BB 44511&45228: Review some urlbar prefs.
- - - - -
6ad02afa by Henry Wilkes at 2026-10-29T10:59:59+01:00
fixup! BB 40925: Implemented the Security Level component
BB 45201: Move security level settings to the settings config.
- - - - -
8eb132dd by Henry Wilkes at 2026-10-29T11:00:00+01:00
fixup! Base Browser strings
BB 45201: Update security level setting strings.
- - - - -
0e1a79df by Henry Wilkes at 2026-10-29T11:00:00+01:00
BB 45201: Customize moz- input widgets for Base Browser.
- - - - -
934b50cd by Henry Wilkes at 2026-10-29T11:00:00+01:00
fixup! BB 31575: Disable Firefox Home (Activity Stream)
BB 44830: Drop the "home" setting group.
- - - - -
8136e0ae by Henry Wilkes at 2026-10-29T11:08:18+01:00
fixup! TB 7494: Create local home page for TBB.
TB 44830: Replace Firefox Home with Tor Browser Home.
- - - - -
b9be099f by Henry Wilkes at 2026-10-29T11:08:18+01:00
fixup! BB 41369: Improve Firefox language settings for multi-lingual packages
BB 45195: Change the subcategory for the language notification.
- - - - -
a2a6a595 by Henry Wilkes at 2026-10-29T11:08:18+01:00
fixup! BB 41454: Move focus after calling openPreferences for a sub-category.
BB 43640: Modify the focus handling to work with the new settings
redesign.
- - - - -
37b75b16 by Henry Wilkes at 2026-10-29T11:08:18+01:00
fixup! TB 31286: Implementation of bridge, proxy, and firewall settings in about:preferences#connection
TB 45195: Add the "viewlogs" subcategory.
- - - - -
e636b911 by Henry Wilkes at 2026-10-29T11:08:19+01:00
fixup! Firefox preference overrides.
BB 45208: Enable the settings redesign.
- - - - -
a70ce43a by Pier Angelo Vendrame at 2026-10-29T11:08:19+01:00
Bug 2063031 - Spoof video PiP size under RFP. r=media-playback-reviewers,kpatenio,alwu,tjr
Differential Revision: https://phabricator.services.mozilla.com/D318184
- - - - -
eb1c014b by Pier Angelo Vendrame at 2026-10-29T11:08:19+01:00
Bug 2059471: Do not spoof screen orientation when it is locked. r=tjr
Differential Revision: https://phabricator.services.mozilla.com/D315317
- - - - -
835719dc by Beatriz Rizental at 2026-10-29T11:10:13+01:00
fixup! TB 34403: [android] Disable Normal mode by default.
Bug 44210: Drop disableNormalModeByDefault setting. This setting is not
useful, because it (1) is not changeable by the user and (2) it just adds
complexity to the original patch to disable normal mode.
- - - - -
bff43334 by Beatriz Rizental at 2026-10-29T11:10:14+01:00
fixup! TB 34403: [android] Disable Normal mode by default.
Bug 44210: [EXTRA] Drop test changes from original patch. These test
changes justse rebase conflicts. We are not running these tests yet.
Let's drop it for now and deal with it when we decide to run the tests
-- if we do.
- - - - -
e7cc51b6 by Pier Angelo Vendrame at 2026-10-29T11:10:15+01:00
fixup! Firefox preference overrides.
BB 45243: Disable taskbar tabs.
- - - - -
82c67cde by Henry Wilkes at 2026-10-29T11:11:13+01:00
fixup! TB 27476: Implement about:torconnect captive portal within Tor Browser
TB 45236: Make the breadcrumbs focusable and activatable with a
keyboard.
We also update the breadcrumb states to be more consistent between
stages, and we no longer disable prior breadcrumbs during a bootstrap
since it is safe for the user to switch back to a prior stage.
- - - - -
01eea3bb by Henry Wilkes at 2026-10-29T11:11:13+01:00
fixup! TB 27476: Implement about:torconnect captive portal within Tor Browser
TB 45236: Have the "configure connection" link point to
about:preferences to give users a hint of where they are going.
- - - - -
8de72a00 by Henry Wilkes at 2026-10-29T11:11:14+01:00
fixup! TB 27476: Implement about:torconnect captive portal within Tor Browser
TB 45236: Drop the wrapping <form> element.
Also fix the `for` attribute to point to the `<select>` element.
- - - - -
4f5894e2 by Henry Wilkes at 2026-10-29T11:11:14+01:00
fixup! TB 27476: Implement about:torconnect captive portal within Tor Browser
TB 45236: Expose the progress bar to accessibility tools.
- - - - -
cd12a9d4 by Henry Wilkes at 2026-10-29T11:11:14+01:00
fixup! TB 40597: Implement TorSettings module
TB 45236: Return early when Moat returns no bridges.
- - - - -
d4fd69ba by Henry Wilkes at 2026-10-29T11:11:15+01:00
fixup! TB 40597: Implement TorSettings module
TB 45236: Add an option to simulate progress in simulated bootstraps.
This is useful for debugging the about:torconnect page.
We also lazy-load the `setTimeout` and related methods since these are
only used for simulated scenarios.
- - - - -
6e0f6a23 by Pier Angelo Vendrame at 2026-10-29T11:11:15+01:00
fixup! TB 44806: Implement the tor integration in Rust.
No bug: fix the onClosed call.
- - - - -
f91ab1cb by Beatriz Rizental at 2026-10-29T11:11:15+01:00
fixup! [android] Disable features and functionality
Bug 45145: Disable app links feature
This feature starts an observer to watch for potential redirects
to other apps. This commit prevents that observer from ever starting.
- - - - -
5e02b9d4 by Beatriz Rizental at 2026-10-29T11:11:15+01:00
fixup! [android] Disable features and functionality
Bug 45145: Prevent other apps from opening Tor Browser
- - - - -
6d27f4da by Sylvestre Ledru at 2026-10-29T12:24:19+01:00
Bug 2075120 - Bump rumdl to 0.1.96 since 0.1.91 is no longer on PyPI r=dao
rumdl 0.1.91 was removed from PyPI upstream, so the lint and python-test
virtualenvs can no longer be created. 0.1.96 is the nearest published
release and reports no new errors in-tree.
Differential Revision: https://phabricator.services.mozilla.com/D328750
- - - - -
112 changed files:
- browser/app/profile/001-base-profile.js
- browser/base/content/browser-init.js
- browser/base/content/languageNotification.js
- + browser/branding/tb-alpha/content/about-logo-small.svg
- browser/branding/tb-alpha/content/about-logo.png
- browser/branding/tb-alpha/content/about-logo(a)2x.png
- − browser/branding/tb-alpha/content/about.png
- browser/branding/tb-alpha/content/aboutDialog.css
- − browser/branding/tb-alpha/content/firefox-wordmark.svg
- browser/branding/tb-alpha/content/jar.mn
- + browser/branding/tb-nightly/content/about-logo-small.svg
- browser/branding/tb-nightly/content/about-logo.png
- browser/branding/tb-nightly/content/about-logo(a)2x.png
- − browser/branding/tb-nightly/content/about.png
- browser/branding/tb-nightly/content/aboutDialog.css
- − browser/branding/tb-nightly/content/firefox-wordmark.svg
- browser/branding/tb-nightly/content/jar.mn
- + browser/branding/tb-release/content/about-logo-small.svg
- browser/branding/tb-release/content/about-logo.png
- browser/branding/tb-release/content/about-logo(a)2x.png
- − browser/branding/tb-release/content/about.png
- browser/branding/tb-release/content/aboutDialog.css
- − browser/branding/tb-release/content/firefox-wordmark.svg
- browser/branding/tb-release/content/jar.mn
- browser/components/preferences/config/account-sync.mjs
- browser/components/preferences/config/languages.mjs
- browser/components/preferences/config/privacy.mjs
- + browser/components/preferences/config/protections-from-apps.mjs
- browser/components/preferences/config/search.mjs
- browser/components/preferences/findInPage.js
- browser/components/preferences/jar.mn
- browser/components/preferences/main.inc.xhtml
- browser/components/preferences/preferences.js
- browser/components/preferences/preferences.xhtml
- browser/components/preferences/privacy.inc.xhtml
- browser/components/preferences/privacy.js
- − browser/components/securitylevel/SecurityLevelUIUtils.sys.mjs
- + browser/components/securitylevel/config/security-level.mjs
- browser/components/securitylevel/content/securityLevel.js
- + browser/components/securitylevel/content/securityLevelDialog.css
- browser/components/securitylevel/content/securityLevelDialog.js
- browser/components/securitylevel/content/securityLevelDialog.xhtml
- − browser/components/securitylevel/content/securityLevelPreferences.css
- − browser/components/securitylevel/content/securityLevelPreferences.inc.xhtml
- browser/components/securitylevel/jar.mn
- browser/components/securitylevel/moz.build
- + browser/components/securitylevel/widgets/security-level-description.css
- + browser/components/securitylevel/widgets/security-level-description.mjs
- + browser/components/securitylevel/widgets/security-level-display.css
- + browser/components/securitylevel/widgets/security-level-display.mjs
- browser/components/sidebar/SidebarManager.sys.mjs
- browser/components/sidebar/browser-sidebar.js
- browser/components/torconnect/content/aboutTorConnect.css
- browser/components/torconnect/content/aboutTorConnect.html
- browser/components/torconnect/content/aboutTorConnect.js
- browser/components/torpreferences/config/connection.mjs
- browser/components/torpreferences/content/torPreferences.css
- browser/extensions/newtab/lib/AboutPreferences.sys.mjs
- browser/themes/shared/identity-block/identity-block.css
- dom/base/ScreenOrientation.cpp
- dom/media/PictureInPictureWindow.cpp
- dom/media/PictureInPictureWindow.h
- dom/media/mediaelement/HTMLVideoElement.cpp
- dom/media/mediaelement/HTMLVideoElement.h
- mobile/android/android-components/components/feature/downloads/src/main/java/mozilla/components/feature/downloads/DownloadsFeature.kt
- mobile/android/android-components/components/support/utils/src/main/java/mozilla/components/support/utils/DefaultDownloadFileUtils.kt
- mobile/android/android-components/components/ui/tabcounter/src/main/java/mozilla/components/ui/tabcounter/TabCounter.kt
- mobile/android/fenix/app/nimbus.fml.yaml
- mobile/android/fenix/app/src/main/AndroidManifest.xml
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/addons/AddonPopupBaseFragment.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/bookmarks/BookmarksScreen.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/browsingmode/BrowsingModeManager.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/search/ApplicationSearchMiddleware.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/HttpsOnlyFragment.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/TabsSettingsFragment.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/search/RadioSearchEngineListPreference.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/search/SearchEngineFragment.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/snackbar/SnackbarBinding.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt
- mobile/android/fenix/app/src/main/res/layout/preference_search_engine_chooser.xml
- mobile/android/fenix/app/src/main/res/values/preference_keys.xml
- mobile/android/fenix/app/src/main/res/xml/default_search_engine_preferences.xml
- mobile/android/fenix/app/src/main/res/xml/downloads_settings_preferences.xml
- mobile/android/fenix/app/src/main/res/xml/preferences.xml
- mobile/android/fenix/app/src/test/java/org/mozilla/fenix/utils/SettingsTest.kt
- python/mozlint/mozlint/cli.py
- python/sites/lint.txt
- python/sites/python-test.txt
- toolkit/components/pictureinpicture/tests/browser.toml
- + toolkit/components/pictureinpicture/tests/browser_resistFingerprinting.js
- toolkit/components/tor-integration/TorService.h
- toolkit/components/tor-integration/components.conf
- toolkit/components/tor-integration/moz.build
- toolkit/components/tor-integration/test/xpcshell/head.js
- toolkit/components/tor-integration/test/xpcshell/test_control_port.js
- toolkit/components/tor-integration/ITorService.idl → toolkit/components/tor-integration/torITorService.idl
- toolkit/components/tor-integration/tor_provider/src/ctor/control_port/control_port.rs
- toolkit/components/tor-integration/tor_provider/src/ctor/control_port/error.rs
- toolkit/components/tor-integration/tor_provider/src/ctor/reply_parser/dispatcher.rs
- toolkit/components/tor-integration/tor_provider/src/ctor/reply_parser/mod.rs
- toolkit/components/tor-integration/tor_provider/src/ctor/reply_parser/test_utils.rs
- toolkit/components/tor-integration/tor_service/src/control_port.rs
- toolkit/components/tor-integration/tor_service/src/service.rs
- toolkit/components/tor-launcher/TorControlPort.sys.mjs
- toolkit/content/widgets/lit-utils.mjs
- toolkit/content/widgets/moz-page-nav/moz-page-nav.css
- toolkit/locales/en-US/toolkit/global/base-browser.ftl
- toolkit/locales/en-US/toolkit/global/tor-browser.ftl
- toolkit/modules/TorConnect.sys.mjs
- tools/lint/eslint/eslint-plugin-mozilla/lib/services.json
The diff was not included because it is too large.
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/999922…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/999922…
You're receiving this email because of your account on gitlab.torproject.org. Manage all notifications: https://gitlab.torproject.org/-/profile/notifications | Help: https://gitlab.torproject.org/help
1
0