[tbb-commits] [Git][tpo/applications/tor-browser][tor-browser-102.12.0esr-12.5-1] 2 commits: fixup! Bug 31286: Implementation of bridge, proxy, and firewall settings in...

Pier Angelo Vendrame (@pierov) git at gitlab.torproject.org
Wed Jun 7 14:16:15 UTC 2023



Pier Angelo Vendrame pushed to branch tor-browser-102.12.0esr-12.5-1 at The Tor Project / Applications / Tor Browser


Commits:
db0a953f by Henry Wilkes at 2023-06-07T14:09:59+01:00
fixup! Bug 31286: Implementation of bridge, proxy, and firewall settings in about:preferences#connection

Bug 41734 - Add a connected label to the built-in bridge dialog.

- - - - -
e86c7eaf by Henry Wilkes at 2023-06-07T14:09:59+01:00
fixup! Add TorStrings module for localization

Bug 41734 - Add a connected label to the built-in bridge dialog.

- - - - -


7 changed files:

- browser/components/torpreferences/content/builtinBridgeDialog.jsm
- browser/components/torpreferences/content/builtinBridgeDialog.xhtml
- browser/components/torpreferences/content/connectionPane.js
- browser/components/torpreferences/content/connectionPane.xhtml
- browser/components/torpreferences/content/torPreferences.css
- browser/modules/TorStrings.jsm
- toolkit/torbutton/chrome/locale/en-US/settings.properties


Changes:

=====================================
browser/components/torpreferences/content/builtinBridgeDialog.jsm
=====================================
@@ -17,82 +17,81 @@ const { TorConnect, TorConnectTopics } = ChromeUtils.import(
 );
 
 class BuiltinBridgeDialog {
+  /**
+   * Create a new instance.
+   *
+   * @param {Function} onSubmit - A callback for when the user accepts the
+   *   dialog selection.
+   */
   constructor(onSubmit) {
     this.onSubmit = onSubmit;
-    this._dialog = null;
     this._acceptButton = null;
   }
 
-  static get selectors() {
-    return {
-      description: "#torPreferences-builtinBridge-description",
-      radiogroup: "#torPreferences-builtinBridge-typeSelection",
-      obfsRadio: "#torPreferences-builtinBridges-radioObfs",
-      obfsDescr: "#torPreferences-builtinBridges-descrObfs",
-      snowflakeRadio: "#torPreferences-builtinBridges-radioSnowflake",
-      snowflakeDescr: "#torPreferences-builtinBridges-descrSnowflake",
-      meekAzureRadio: "#torPreferences-builtinBridges-radioMeekAzure",
-      meekAzureDescr: "#torPreferences-builtinBridges-descrMeekAzure",
-    };
-  }
-
-  _populateXUL(window, aDialog) {
-    const selectors = BuiltinBridgeDialog.selectors;
-
-    this._dialog = aDialog;
-    const dialogWin = this._dialog.parentElement;
+  _populateXUL(window, dialog) {
+    const dialogWin = dialog.parentElement;
     dialogWin.setAttribute("title", TorStrings.settings.builtinBridgeHeader);
 
-    this._dialog.querySelector(selectors.description).textContent =
-      TorStrings.settings.builtinBridgeDescription2;
+    dialog.querySelector(
+      "#torPreferences-builtinBridge-description"
+    ).textContent = TorStrings.settings.builtinBridgeDescription2;
 
-    this._acceptButton = this._dialog.getButton("accept");
+    this._acceptButton = dialog.getButton("accept");
     this.onTorStateChange();
 
-    let radioGroup = this._dialog.querySelector(selectors.radiogroup);
+    const radioGroup = dialog.querySelector(
+      "#torPreferences-builtinBridge-typeSelection"
+    );
 
-    let types = {
+    const typeStrings = {
       obfs4: {
-        elemRadio: this._dialog.querySelector(selectors.obfsRadio),
-        elemDescr: this._dialog.querySelector(selectors.obfsDescr),
         label: TorStrings.settings.builtinBridgeObfs4Title,
         descr: TorStrings.settings.builtinBridgeObfs4Description2,
       },
       snowflake: {
-        elemRadio: this._dialog.querySelector(selectors.snowflakeRadio),
-        elemDescr: this._dialog.querySelector(selectors.snowflakeDescr),
         label: TorStrings.settings.builtinBridgeSnowflake,
         descr: TorStrings.settings.builtinBridgeSnowflakeDescription2,
       },
       "meek-azure": {
-        elemRadio: this._dialog.querySelector(selectors.meekAzureRadio),
-        elemDescr: this._dialog.querySelector(selectors.meekAzureDescr),
         label: TorStrings.settings.builtinBridgeMeekAzure,
         descr: TorStrings.settings.builtinBridgeMeekAzureDescription2,
       },
     };
 
-    TorBuiltinBridgeTypes.forEach(type => {
-      types[type].elemRadio.setAttribute("label", types[type].label);
-      types[type].elemRadio.setAttribute("hidden", "false");
-      types[type].elemDescr.textContent = types[type].descr;
-      types[type].elemDescr.removeAttribute("hidden");
-    });
-
-    if (
+    const currentBuiltinType =
       TorSettings.bridges.enabled &&
       TorSettings.bridges.source == TorBridgeSource.BuiltIn
-    ) {
-      radioGroup.selectedItem =
-        types[TorSettings.bridges.builtin_type]?.elemRadio;
+        ? TorSettings.bridges.builtin_type
+        : null;
+    if (currentBuiltinType) {
+      radioGroup.value = currentBuiltinType;
     } else {
       radioGroup.selectedItem = null;
     }
 
-    this._dialog.addEventListener("dialogaccept", () => {
+    for (const optionEl of radioGroup.querySelectorAll(
+      ".builtin-bridges-option"
+    )) {
+      const radio = optionEl.querySelector("radio");
+      const type = radio.value;
+      optionEl.hidden = !TorBuiltinBridgeTypes.includes(type);
+      radio.label = typeStrings[type].label;
+      optionEl.querySelector(
+        ".builtin-bridges-option-description"
+      ).textContent = typeStrings[type].descr;
+      optionEl.querySelector(
+        ".torPreferences-current-bridge-label"
+      ).textContent = TorStrings.settings.currentBridge;
+      optionEl.classList.toggle(
+        "current-builtin-bridge-type",
+        type === currentBuiltinType
+      );
+    }
+
+    dialog.addEventListener("dialogaccept", () => {
       this.onSubmit(radioGroup.value, TorConnect.canBeginBootstrap);
     });
-    this._dialog.addEventListener("dialoghelp", e => {
+    dialog.addEventListener("dialoghelp", e => {
       window.top.openTrustedLinkIn(
         TorStrings.settings.learnMoreCircumventionURL,
         "tab"
@@ -100,8 +99,8 @@ class BuiltinBridgeDialog {
     });
 
     // Hack: see the CSS
-    this._dialog.style.minWidth = "0";
-    this._dialog.style.minHeight = "0";
+    dialog.style.minWidth = "0";
+    dialog.style.minHeight = "0";
 
     Services.obs.addObserver(this, TorConnectTopics.StateChange);
   }


=====================================
browser/components/torpreferences/content/builtinBridgeDialog.xhtml
=====================================
@@ -8,16 +8,57 @@
         xmlns:html="http://www.w3.org/1999/xhtml">
 <dialog id="torPreferences-builtinBridge-dialog"
         buttons="help,accept,cancel">
-  <description>
-    <html:div id="torPreferences-builtinBridge-description">​<br/>​</html:div>
+  <description id="torPreferences-builtinBridge-description">
   </description>
   <radiogroup id="torPreferences-builtinBridge-typeSelection">
-    <radio id="torPreferences-builtinBridges-radioObfs" value="obfs4" hidden="true"/>
-    <html:div id="torPreferences-builtinBridges-descrObfs" class="indent" hidden="true">​</html:div>
-    <radio id="torPreferences-builtinBridges-radioSnowflake" value="snowflake" hidden="true"/>
-    <html:div id="torPreferences-builtinBridges-descrSnowflake" class="indent" hidden="true">​</html:div>
-    <radio id="torPreferences-builtinBridges-radioMeekAzure" value="meek-azure" hidden="true"/>
-    <html:div id="torPreferences-builtinBridges-descrMeekAzure" class="indent" hidden="true">​</html:div>
+    <vbox class="builtin-bridges-option">
+      <hbox>
+        <!-- The radio option is described by both the "Current bridge" label
+          - and the full description. If the "Connected" label is hidden, then
+           - only the latter description should contribute. -->
+        <radio aria-describedby="obfs-bridges-current obfs-bridges-description"
+               value="obfs4"/>
+        <html:span class="torPreferences-current-bridge-badge">
+          <image class="torPreferences-current-bridge-icon"/>
+          <html:span id="obfs-bridges-current"
+                     class="torPreferences-current-bridge-label">
+          </html:span>
+        </html:span>
+      </hbox>
+      <html:div id="obfs-bridges-description"
+                class="indent builtin-bridges-option-description">
+      </html:div>
+    </vbox>
+    <vbox class="builtin-bridges-option">
+      <hbox>
+        <radio aria-describedby="snowflake-bridges-current snowflake-bridges-description"
+               value="snowflake"/>
+        <html:span class="torPreferences-current-bridge-badge">
+          <image class="torPreferences-current-bridge-icon"/>
+          <html:span id="snowflake-bridges-current"
+                     class="torPreferences-current-bridge-label">
+          </html:span>
+        </html:span>
+      </hbox>
+      <html:div id="snowflake-bridges-description"
+                class="indent builtin-bridges-option-description">
+      </html:div>
+    </vbox>
+    <vbox class="builtin-bridges-option">
+      <hbox>
+        <radio aria-describedby="meek-bridges-current meek-bridges-description"
+               value="meek-azure"/>
+        <html:span class="torPreferences-current-bridge-badge">
+          <image class="torPreferences-current-bridge-icon"/>
+          <html:span id="meek-bridges-current"
+                     class="torPreferences-current-bridge-label">
+          </html:span>
+        </html:span>
+      </hbox>
+      <html:div id="meek-bridges-description"
+                class="indent builtin-bridges-option-description">
+      </html:div>
+    </vbox>
   </radiogroup>
   <script type="application/javascript"><![CDATA[
     "use strict";


=====================================
browser/components/torpreferences/content/connectionPane.js
=====================================
@@ -124,7 +124,7 @@ const gConnectionPane = (function() {
       cardId: ".torPreferences-bridgeCard-id",
       cardHeadingManualLink: ".torPreferences-bridgeCard-manualLink",
       cardHeadingAddr: ".torPreferences-bridgeCard-headingAddr",
-      cardConnectedLabel: ".torPreferences-bridgeCard-connectedLabel",
+      cardConnectedLabel: ".torPreferences-current-bridge-label",
       cardOptions: ".torPreferences-bridgeCard-options",
       cardMenu: "#torPreferences-bridgeCard-menu",
       cardQrGrid: ".torPreferences-bridgeCard-grid",
@@ -168,7 +168,7 @@ const gConnectionPane = (function() {
 
     _controller: null,
 
-    _currentBridge: "",
+    _currentBridgeId: null,
 
     // populate xul with strings and cache the relevant elements
     _populateXUL() {
@@ -471,7 +471,7 @@ const gConnectionPane = (function() {
       }
       bridgeTemplate.querySelector(
         selectors.bridges.cardConnectedLabel
-      ).textContent = TorStrings.settings.statusTorConnected;
+      ).textContent = TorStrings.settings.connectedBridge;
       bridgeTemplate
         .querySelector(selectors.bridges.cardCopy)
         .setAttribute("label", TorStrings.settings.bridgeCopy);
@@ -607,7 +607,7 @@ const gConnectionPane = (function() {
             restoreTimeout = null;
           }, RESTORE_TIME);
         });
-        if (details && details.id === this._currentBridge) {
+        if (details?.id && details.id === this._currentBridgeId) {
           card.classList.add("currently-connected");
           bridgeCards.prepend(card);
         } else {
@@ -714,9 +714,9 @@ const gConnectionPane = (function() {
         // Add only the new strings that remained in the set
         for (const bridge of newStrings) {
           if (shownCards >= toShow) {
-            if (this._currentBridge === "") {
+            if (!this._currentBridgeId) {
               break;
-            } else if (!bridge.includes(this._currentBridge)) {
+            } else if (!bridge.includes(this._currentBridgeId)) {
               continue;
             }
           }
@@ -787,7 +787,7 @@ const gConnectionPane = (function() {
         )) {
           card.classList.remove("currently-connected");
         }
-        if (this._currentBridge === "") {
+        if (!this._currentBridgeId) {
           return;
         }
         // Make sure we have the connected bridge in the list
@@ -796,7 +796,7 @@ const gConnectionPane = (function() {
         // case also with built-in bridges!). E.g., one line for the IPv4
         // address and one for the IPv6 address, so use querySelectorAll
         const cards = bridgeCards.querySelectorAll(
-          `[data-bridge-id="${this._currentBridge}"]`
+          `[data-bridge-id="${this._currentBridgeId}"]`
         );
         for (const card of cards) {
           card.classList.add("currently-connected");
@@ -823,6 +823,12 @@ const gConnectionPane = (function() {
           // this circuit to check if the bridge can be used. We do this by
           // checking if the stream has SOCKS username, which actually contains
           // the destination of the stream.
+          // FIXME: We only know the currentBridge *after* a circuit event, but
+          // if the circuit event is sent *before* about:torpreferences is
+          // opened we will miss it. Therefore this approach only works if a
+          // circuit is created after opening about:torconnect. A dedicated
+          // backend outside of about:preferences would help, and could be
+          // shared with gTorCircuitPanel. See tor-browser#41700.
           this._controller.watchEvent(
             "STREAM",
             event =>
@@ -836,10 +842,22 @@ const gConnectionPane = (function() {
               }
               for (const status of circuitStatuses) {
                 if (status.id === event.CircuitID && status.circuit.length) {
-                  // The id in the circuit begins with a $ sign
-                  const bridgeId = status.circuit[0][0].substring(1);
-                  if (bridgeId !== this._currentBridge) {
-                    this._currentBridge = bridgeId;
+                  // The id in the circuit begins with a $ sign.
+                  const id = status.circuit[0][0].replace(/^\$/, "");
+                  if (id !== this._currentBridgeId) {
+                    const bridge = (
+                      await this._controller.getConf("bridge")
+                    )?.find(
+                      foundBridge =>
+                        foundBridge.ID?.toUpperCase() === id.toUpperCase()
+                    );
+                    if (!bridge) {
+                      // Either there is no bridge, or bridge with no
+                      // fingerprint.
+                      this._currentBridgeId = null;
+                    } else {
+                      this._currentBridgeId = id;
+                    }
                     this._updateConnectedBridges();
                   }
                   break;


=====================================
browser/components/torpreferences/content/connectionPane.xhtml
=====================================
@@ -109,9 +109,9 @@
       <label class="torPreferences-bridgeCard-manualLink learnMore text-link stop-click" is="text-link"/>
       <html:div class="torPreferences-bridgeCard-headingAddr"/>
       <html:div class="torPreferences-bridgeCard-buttons">
-        <html:span class="torPreferences-bridgeCard-connectedBadge">
-          <image class="torPreferences-bridgeCard-connectedIcon"/>
-          <html:span class="torPreferences-bridgeCard-connectedLabel"/>
+        <html:span class="torPreferences-current-bridge-badge">
+          <image class="torPreferences-current-bridge-icon"/>
+          <html:span class="torPreferences-current-bridge-label"></html:span>
         </html:span>
         <html:button class="torPreferences-bridgeCard-options stop-click"/>
       </html:div>


=====================================
browser/components/torpreferences/content/torPreferences.css
=====================================
@@ -298,28 +298,38 @@ html:dir(rtl) input[type="checkbox"].toggle-button::before {
   align-self: center;
 }
 
-.torPreferences-bridgeCard-connectedBadge {
+.torPreferences-current-bridge-badge {
+  /* Hidden by default, otherwise display is "flex". */
   display: none;
-  margin-inline-end: 12px;
-  color: var(--purple-60);
-}
-
- at media (prefers-color-scheme: dark) {
-  .torPreferences-bridgeCard-connectedBadge {
-    color: var(--purple-30);
-  }
+  align-items: center;
+  font-size: 0.85em;
 }
 
-.currently-connected .torPreferences-bridgeCard-connectedBadge {
+:is(
+  .builtin-bridges-option.current-builtin-bridge-type,
+  .torPreferences-bridgeCard.currently-connected
+) .torPreferences-current-bridge-badge {
   display: flex;
 }
 
-.torPreferences-bridgeCard-connectedIcon {
+.torPreferences-current-bridge-icon {
   margin-inline-start: 1px;
   margin-inline-end: 7px;
   list-style-image: url("chrome://browser/content/torpreferences/check.svg");
   -moz-context-properties: fill;
   fill: currentColor;
+  flex: 0 0 auto;
+}
+
+.torPreferences-bridgeCard .torPreferences-current-bridge-badge {
+  color: var(--purple-60);
+  margin-inline-end: 12px;
+}
+
+ at media (prefers-color-scheme: dark) {
+  .torPreferences-bridgeCard .torPreferences-current-bridge-badge {
+    color: var(--purple-30);
+  }
 }
 
 .torPreferences-bridgeCard-options {
@@ -564,6 +574,10 @@ dialog#torPreferences-requestBridge-dialog > hbox {
   font-weight: 700;
 }
 
+.builtin-bridges-option .torPreferences-current-bridge-badge {
+  color: var(--in-content-accent-color);
+}
+
 /* Request bridge dialog */
 /*
   This hbox is hidden by css here by default so that the


=====================================
browser/modules/TorStrings.jsm
=====================================
@@ -105,6 +105,8 @@ const Loader = {
       bridgeCurrentDescription:
         "You can keep one or more bridges saved, and Tor will choose which one to use when you connect. Tor will automatically switch to use another bridge when needed.",
       bridgeId: "%1$S bridge: %2$S",
+      currentBridge: "Current bridge",
+      connectedBridge: "Connected",
       remove: "Remove",
       bridgeDisableBuiltIn: "Disable built-in bridges",
       bridgeShare:


=====================================
toolkit/torbutton/chrome/locale/en-US/settings.properties
=====================================
@@ -39,6 +39,8 @@ settings.bridgeCurrentDescription=You can keep one or more bridges saved, and To
 
 # Translation note: %1$S = bridge type; %2$S = bridge emoji id
 settings.bridgeId=%1$S bridge: %2$S
+settings.connectedBridge=Connected
+settings.currentBridge=Current bridge
 settings.remove=Remove
 settings.bridgeDisableBuiltIn=Disable built-in bridges
 settings.bridgeShare=Share this bridge using the QR code or by copying its address:



View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/c2d6837d7f407570de73631b158f4a7c789099c7...e86c7eaf8a8a341d2fa564b906b32140c6a4174c

-- 
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/c2d6837d7f407570de73631b158f4a7c789099c7...e86c7eaf8a8a341d2fa564b906b32140c6a4174c
You're receiving this email because of your account on gitlab.torproject.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.torproject.org/pipermail/tbb-commits/attachments/20230607/12545b25/attachment-0001.htm>


More information about the tbb-commits mailing list