morgan pushed to branch tor-browser-153.0esr-16.0-1 at The Tor Project / Applications / Tor Browser
Commits:
-
4983f698
by Henry Wilkes at 2026-08-06T15:48:25+00:00
-
b825b06d
by Henry Wilkes at 2026-08-06T15:48:25+00:00
-
09269559
by Henry Wilkes at 2026-08-06T15:48:25+00:00
6 changed files:
- browser/components/preferences/preferences.xhtml
- browser/components/torpreferences/config/connection.mjs
- browser/components/torpreferences/jar.mn
- + browser/components/torpreferences/widgets/tor-connection-assist-banner.mjs
- toolkit/locales/en-US/toolkit/global/tor-browser.ftl
- toolkit/modules/TorConnect.sys.mjs
Changes:
| ... | ... | @@ -109,6 +109,7 @@ |
| 109 | 109 | <script type="module" src="chrome://browser/content/preferences/widgets/update-state.mjs"></script>
|
| 110 | 110 | <script type="module" src="chrome://browser/content/ipprotection/bandwidth-usage.mjs"></script>
|
| 111 | 111 | <script type="module" src="chrome://browser/content/torpreferences/widgets/tor-bridges-display.mjs"></script>
|
| 112 | + <script type="module" src="chrome://browser/content/torpreferences/widgets/tor-connection-assist-banner.mjs"></script>
|
|
| 112 | 113 | <script type="module" src="chrome://browser/content/torpreferences/widgets/tor-connection-status.mjs"></script>
|
| 113 | 114 | <script src="chrome://browser/content/torpreferences/bridgemoji/BridgeEmoji.js"/>
|
| 114 | 115 | </head>
|
| ... | ... | @@ -4,6 +4,8 @@ import { Preferences } from "chrome://global/content/preferences/Preferences.mjs |
| 4 | 4 | const lazy = {};
|
| 5 | 5 | ChromeUtils.defineESModuleGetters(lazy, {
|
| 6 | 6 | InternetStatus: "moz-src:///toolkit/modules/TorConnect.sys.mjs",
|
| 7 | + moveFocusToBridgeHeading:
|
|
| 8 | + "chrome://browser/content/torpreferences/config/helpers.mjs",
|
|
| 7 | 9 | openBridgeDialog:
|
| 8 | 10 | "chrome://browser/content/torpreferences/config/helpers.mjs",
|
| 9 | 11 | openUserProvideBridgeDialog:
|
| ... | ... | @@ -68,6 +70,18 @@ SettingGroupManager.registerGroups({ |
| 68 | 70 | headingLevel: 2,
|
| 69 | 71 | controlAttrs: { "focusable-heading": true },
|
| 70 | 72 | items: [
|
| 73 | + {
|
|
| 74 | + id: "connectionAssistBanner",
|
|
| 75 | + // NOTE: Instead of using a custom widget for this one banner, we could
|
|
| 76 | + // use moz-message-bar and populate it's children. However, we want to
|
|
| 77 | + // intercept the "click" event for the "Connection Assist" link within
|
|
| 78 | + // the banner text. As of ESR 153, onUserClick would not allow us to
|
|
| 79 | + // intercept the event because the `<a>` would need to be wrapped in a
|
|
| 80 | + // `<setting-control>`. But Fluent would not allow wrapping the
|
|
| 81 | + // `<setting-control>` element as part of a wider string (unlike
|
|
| 82 | + // `<a data-l10n-name="link">`, which is allowed). tor-browser#43939.
|
|
| 83 | + control: "tor-connection-assist-banner",
|
|
| 84 | + },
|
|
| 71 | 85 | {
|
| 72 | 86 | id: "bridgesEnabled",
|
| 73 | 87 | l10nId: "tor-bridges-use-bridges",
|
| ... | ... | @@ -253,6 +267,27 @@ Preferences.addSetting({ |
| 253 | 267 | },
|
| 254 | 268 | });
|
| 255 | 269 | |
| 270 | +Preferences.addSetting({
|
|
| 271 | + id: "connectionAssistBanner",
|
|
| 272 | + deps: ["torStatus"],
|
|
| 273 | + _wasVisible: false,
|
|
| 274 | + visible({ torStatus }) {
|
|
| 275 | + const visible = torStatus.value === "potentially-blocked";
|
|
| 276 | + if (
|
|
| 277 | + !visible &&
|
|
| 278 | + this._wasVisible &&
|
|
| 279 | + document
|
|
| 280 | + .getElementById("connectionAssistBanner")
|
|
| 281 | + ?.contains(document.activeElement)
|
|
| 282 | + ) {
|
|
| 283 | + // About to loose focus, move focus to the bridge heading.
|
|
| 284 | + lazy.moveFocusToBridgeHeading(window, true);
|
|
| 285 | + }
|
|
| 286 | + this._wasVisible = visible;
|
|
| 287 | + return visible;
|
|
| 288 | + },
|
|
| 289 | +});
|
|
| 290 | + |
|
| 256 | 291 | Preferences.addSetting({
|
| 257 | 292 | id: "torSettingsReady",
|
| 258 | 293 | _ready: false,
|
| ... | ... | @@ -27,6 +27,7 @@ browser.jar: |
| 27 | 27 | content/browser/torpreferences/config/connection.mjs (config/connection.mjs)
|
| 28 | 28 | content/browser/torpreferences/config/helpers.mjs (config/helpers.mjs)
|
| 29 | 29 | content/browser/torpreferences/widgets/tor-bridges-display.mjs (widgets/tor-bridges-display.mjs)
|
| 30 | + content/browser/torpreferences/widgets/tor-connection-assist-banner.mjs (widgets/tor-connection-assist-banner.mjs)
|
|
| 30 | 31 | content/browser/torpreferences/widgets/tor-connection-status.mjs (widgets/tor-connection-status.mjs)
|
| 31 | 32 | content/browser/torpreferences/widgets/tor-connection-status.css (widgets/tor-connection-status.css)
|
| 32 | 33 | content/browser/torpreferences/connectionPane.js (content/connectionPane.js)
|
| 1 | +import { MozLitElement } from "chrome://global/content/lit-utils.mjs";
|
|
| 2 | +import { html } from "chrome://global/content/vendor/lit.all.mjs";
|
|
| 3 | + |
|
| 4 | +const lazy = {};
|
|
| 5 | +ChromeUtils.defineESModuleGetters(lazy, {
|
|
| 6 | + TorConnect: "moz-src:///toolkit/modules/TorConnect.sys.mjs",
|
|
| 7 | + TorConnectParent:
|
|
| 8 | + "moz-src:///browser/components/torconnect/TorConnectParent.sys.mjs",
|
|
| 9 | +});
|
|
| 10 | + |
|
| 11 | +const TOR_CONNECT_HREF = "about:torconnect";
|
|
| 12 | + |
|
| 13 | +/**
|
|
| 14 | + * Widget for displaying a Connection Assist banner.
|
|
| 15 | + *
|
|
| 16 | + * @tagname tor-connection-status
|
|
| 17 | + */
|
|
| 18 | +class TorConnectionAssistBanner extends MozLitElement {
|
|
| 19 | + render() {
|
|
| 20 | + return html`
|
|
| 21 | + <moz-message-bar
|
|
| 22 | + role="complementary"
|
|
| 23 | + type="warning"
|
|
| 24 | + @click=${this.#handleClick}
|
|
| 25 | + >
|
|
| 26 | + <span
|
|
| 27 | + slot="message"
|
|
| 28 | + data-l10n-id="tor-bridges-connection-assist-message"
|
|
| 29 | + >
|
|
| 30 | + <a
|
|
| 31 | + id="link"
|
|
| 32 | + data-l10n-name="link"
|
|
| 33 | + href=${TOR_CONNECT_HREF}
|
|
| 34 | + target="_blank"
|
|
| 35 | + ></a>
|
|
| 36 | + </span>
|
|
| 37 | + </moz-message-bar>
|
|
| 38 | + `;
|
|
| 39 | + }
|
|
| 40 | + |
|
| 41 | + #handleClick(event) {
|
|
| 42 | + if (!this.shadowRoot.getElementById("link")?.contains(event.target)) {
|
|
| 43 | + return;
|
|
| 44 | + }
|
|
| 45 | + event.preventDefault();
|
|
| 46 | + if (!lazy.TorConnect.inConnectionAssistStage) {
|
|
| 47 | + // Switch to the "ChooseRegion" stage to reflect "Connection Assist".
|
|
| 48 | + lazy.TorConnect.chooseRegion();
|
|
| 49 | + }
|
|
| 50 | + lazy.TorConnectParent.open();
|
|
| 51 | + }
|
|
| 52 | +}
|
|
| 53 | +customElements.define(
|
|
| 54 | + "tor-connection-assist-banner",
|
|
| 55 | + TorConnectionAssistBanner
|
|
| 56 | +); |
| ... | ... | @@ -156,6 +156,11 @@ tor-bridges-group = |
| 156 | 156 | .label = Bridges
|
| 157 | 157 | .description = Bridges help you securely access the Tor network in places where Tor is blocked. Depending on where you are, one bridge may work better than another.
|
| 158 | 158 | |
| 159 | +# "{ -brand-product-name }" will be replaced with the localized name of the browser, e.g. "Tor Browser".
|
|
| 160 | +# "Connection Assist" is the name of a Tor Browser feature, and is therefore capitalised in English. For translations, it should similarly be treated as a feature/product name. It should also be wrapped by the tags '<a data-l10n-name="link">' and '</a>'.
|
|
| 161 | +tor-bridges-connection-assist-message = { -brand-short-name } could not connect to the Tor network. You may want to change your bridge settings below, or use <a data-l10n-name="link">Connection Assist</a> to find bridges for you.
|
|
| 162 | + |
|
| 163 | + |
|
| 159 | 164 | # Toggle button for enabling and disabling the use of bridges.
|
| 160 | 165 | tor-bridges-use-bridges =
|
| 161 | 166 | .label = Use bridges
|
| ... | ... | @@ -305,6 +305,8 @@ class BootstrapAttempt { |
| 305 | 305 | |
| 306 | 306 | /**
|
| 307 | 307 | * Each instance can be used to attempt one auto-bootstrapping sequence.
|
| 308 | + *
|
|
| 309 | + * AKA Connection Assist bootstrap.
|
|
| 308 | 310 | */
|
| 309 | 311 | class AutoBootstrapAttempt {
|
| 310 | 312 | /**
|
| ... | ... | @@ -811,6 +813,12 @@ export const TorConnect = { |
| 811 | 813 | */
|
| 812 | 814 | _bootstrapAttempt: null,
|
| 813 | 815 | |
| 816 | + /**
|
|
| 817 | + * Whether the current or last bootstrap attempt was a "normal" bootstrap (not
|
|
| 818 | + * Connection Assist).
|
|
| 819 | + */
|
|
| 820 | + _wasNormalBootstrap: false,
|
|
| 821 | + |
|
| 814 | 822 | /**
|
| 815 | 823 | * The bootstrap error that was last generated.
|
| 816 | 824 | *
|
| ... | ... | @@ -1048,7 +1056,7 @@ export const TorConnect = { |
| 1048 | 1056 | // No change.
|
| 1049 | 1057 | return;
|
| 1050 | 1058 | }
|
| 1051 | - if (this._stageName === "Bootstrapping") {
|
|
| 1059 | + if (this._stageName === TorConnectStage.Bootstrapping) {
|
|
| 1052 | 1060 | this._bootstrappingStatus.hasWarning = true;
|
| 1053 | 1061 | this._notifyBootstrapProgress();
|
| 1054 | 1062 | }
|
| ... | ... | @@ -1197,6 +1205,19 @@ export const TorConnect = { |
| 1197 | 1205 | );
|
| 1198 | 1206 | },
|
| 1199 | 1207 | |
| 1208 | + /**
|
|
| 1209 | + * Whether we are in a stage that is considered part of "Connection Assist".
|
|
| 1210 | + *
|
|
| 1211 | + * @type {boolean}
|
|
| 1212 | + */
|
|
| 1213 | + get inConnectionAssistStage() {
|
|
| 1214 | + return (
|
|
| 1215 | + this.canBeginAutoBootstrap ||
|
|
| 1216 | + (this._stageName === TorConnectStage.Bootstrapping &&
|
|
| 1217 | + !this._wasNormalBootstrap)
|
|
| 1218 | + );
|
|
| 1219 | + },
|
|
| 1220 | + |
|
| 1200 | 1221 | /**
|
| 1201 | 1222 | * Get a map of all region codes and their localized names.
|
| 1202 | 1223 | *
|
| ... | ... | @@ -1377,9 +1398,10 @@ export const TorConnect = { |
| 1377 | 1398 | |
| 1378 | 1399 | const beginStage = this._stageName;
|
| 1379 | 1400 | const bootstrapOptions = { regionCode };
|
| 1380 | - const bootstrapAttempt = regionCode
|
|
| 1381 | - ? new AutoBootstrapAttempt()
|
|
| 1382 | - : new BootstrapAttempt();
|
|
| 1401 | + const normalBootstrap = !regionCode;
|
|
| 1402 | + const bootstrapAttempt = normalBootstrap
|
|
| 1403 | + ? new BootstrapAttempt()
|
|
| 1404 | + : new AutoBootstrapAttempt();
|
|
| 1383 | 1405 | |
| 1384 | 1406 | this._addSimulateOptions(bootstrapOptions, regionCode);
|
| 1385 | 1407 | |
| ... | ... | @@ -1398,6 +1420,7 @@ export const TorConnect = { |
| 1398 | 1420 | this._requestedStage = null;
|
| 1399 | 1421 | this._bootstrapTrigger = beginStage;
|
| 1400 | 1422 | this._isQuickstart = isQuickstart;
|
| 1423 | + this._wasNormalBootstrap = normalBootstrap;
|
|
| 1401 | 1424 | this._setStage(TorConnectStage.Bootstrapping);
|
| 1402 | 1425 | this._bootstrapAttempt = bootstrapAttempt;
|
| 1403 | 1426 |