[tbb-commits] [Git][tpo/applications/tor-browser][tor-browser-115.9.0esr-13.5-1] 3 commits: fixup! Bug 40925: Implemented the Security Level component

richard (@richard) git at gitlab.torproject.org
Mon Mar 25 22:08:47 UTC 2024



richard pushed to branch tor-browser-115.9.0esr-13.5-1 at The Tor Project / Applications / Tor Browser


Commits:
74db46f9 by Henry Wilkes at 2024-03-25T21:54:25+00:00
fixup! Bug 40925: Implemented the Security Level component

Bug 42214: Migrate security level strings to Fluent.

- - - - -
142836ed by Henry Wilkes at 2024-03-25T21:54:25+00:00
fixup! Base Browser strings

Bug 42214: Migrate security level strings to Fluent.

Also change some strings to be sentence case in English.

- - - - -
4338bda1 by Henry Wilkes at 2024-03-25T21:54:25+00:00
fixup! Tor Browser localization migration scripts.

Bug 42214: Migrate security level strings to Fluent.

- - - - -


7 changed files:

- browser/components/preferences/preferences.xhtml
- browser/components/securitylevel/content/securityLevel.js
- browser/components/securitylevel/content/securityLevelPanel.inc.xhtml
- browser/components/securitylevel/content/securityLevelPreferences.inc.xhtml
- browser/locales/en-US/browser/base-browser.ftl
- browser/locales/jar.mn
- + tools/torbrowser/l10n/migrations/bug-42214-security-level.py


Changes:

=====================================
browser/components/preferences/preferences.xhtml
=====================================
@@ -60,6 +60,7 @@
   <link rel="localization" href="security/certificates/certManager.ftl"/>
   <link rel="localization" href="security/certificates/deviceManager.ftl"/>
   <link rel="localization" href="toolkit/updates/history.ftl"/>
+  <link rel="localization" href="browser/base-browser.ftl"/>
   <link rel="localization" href="browser/tor-browser.ftl"/>
 
   <link rel="shortcut icon" href="chrome://global/skin/icons/settings.svg"/>


=====================================
browser/components/securitylevel/content/securityLevel.js
=====================================
@@ -8,65 +8,6 @@ ChromeUtils.defineModuleGetter(
   "resource://gre/modules/SecurityLevel.jsm"
 );
 
-XPCOMUtils.defineLazyGetter(this, "SecurityLevelStrings", () => {
-  let strings = {
-    // Generic terms
-    security_level: "Security Level",
-    security_level_standard: "Standard",
-    security_level_safer: "Safer",
-    security_level_safest: "Safest",
-    security_level_tooltip_standard: "Security Level: Standard",
-    security_level_tooltip_safer: "Security Level: Safer",
-    security_level_tooltip_safest: "Security Level: Safest",
-    // Shown only for custom level
-    security_level_custom: "Custom",
-    security_level_restore: "Restore Defaults",
-    security_level_learn_more: "Learn more",
-    // Panel
-    security_level_open_settings: "Settings…",
-    security_level_standard_summary:
-      "All browser and website features are enabled.",
-    security_level_safer_summary:
-      "Disables website features that are often dangerous, causing some sites to lose functionality.",
-    security_level_safest_summary:
-      "Only allows website features required for static sites and basic services. These changes affect images, media, and scripts.",
-    security_level_custom_heading: "Custom security level configured",
-    security_level_custom_summary:
-      "Your custom browser preferences have resulted in unusual security settings. For security and privacy reasons, we recommend you choose one of the default security levels.",
-    // Security level section in about:preferences#privacy
-    security_level_overview:
-      "Disable certain web features that can be used to attack your security and anonymity.",
-    security_level_list_safer: "At the safer setting:",
-    security_level_list_safest: "At the safest setting:",
-    // Strings for descriptions
-    security_level_js_https_only: "JavaScript is disabled on non-HTTPS sites.",
-    security_level_js_disabled:
-      "JavaScript is disabled by default on all sites.",
-    security_level_limit_typography:
-      "Some fonts and math symbols are disabled.",
-    security_level_limit_typography_svg:
-      "Some fonts, icons, math symbols, and images are disabled.",
-    security_level_limit_media:
-      "Audio and video (HTML5 media), and WebGL are click-to-play.",
-  };
-  let bundle = null;
-  try {
-    bundle = Services.strings.createBundle(
-      "chrome://browser/locale/securityLevel.properties"
-    );
-  } catch (e) {
-    console.warn("Could not load the Security Level strings");
-  }
-  if (bundle) {
-    for (const key of Object.keys(strings)) {
-      try {
-        strings[key] = bundle.GetStringFromName(key);
-      } catch (e) {}
-    }
-  }
-  return strings;
-});
-
 /*
   Security Level Button Code
 
@@ -100,12 +41,30 @@ var SecurityLevelButton = {
     if (!level) {
       return;
     }
-    const customStr = SecurityLevelPrefs.securityCustom ? "_custom" : "";
-    this._button.setAttribute("level", `${level}${customStr}`);
-    this._button.setAttribute(
-      "tooltiptext",
-      SecurityLevelStrings[`security_level_tooltip_${level}`]
-    );
+    const custom = SecurityLevelPrefs.securityCustom;
+    this._button.setAttribute("level", custom ? `${level}_custom` : level);
+
+    let l10nIdLevel;
+    switch (level) {
+      case "standard":
+        l10nIdLevel = "security-level-toolbar-button-standard";
+        break;
+      case "safer":
+        l10nIdLevel = "security-level-toolbar-button-safer";
+        break;
+      case "safest":
+        l10nIdLevel = "security-level-toolbar-button-safest";
+        break;
+      default:
+        throw Error(`Unhandled level: ${level}`);
+    }
+    if (custom) {
+      // Don't distinguish between the different levels when in the custom
+      // state. We just want to emphasise that it is custom rather than any
+      // specific level.
+      l10nIdLevel = "security-level-toolbar-button-custom";
+    }
+    document.l10n.setAttributes(this._button, l10nIdLevel);
   },
 
   /**
@@ -159,7 +118,6 @@ var SecurityLevelButton = {
       window.gNavToolbox.palette.querySelector("#security-level-button");
     // Set a label to be be used as the accessible name, and to be shown in the
     // overflow menu and during customization.
-    this._button.setAttribute("label", SecurityLevelStrings.security_level);
     this._button.addEventListener("command", () => this.openPopup());
     // set the initial class based off of the current pref
     this._configUIFromPrefs();
@@ -213,21 +171,12 @@ var SecurityLevelPanel = {
       settingsButton: document.getElementById("securityLevel-settings"),
     };
 
-    document.getElementById("securityLevel-header").textContent =
-      SecurityLevelStrings.security_level;
-    this._elements.customName.textContent =
-      SecurityLevelStrings.security_level_custom;
     const learnMoreEl = document.getElementById("securityLevel-learnMore");
-    learnMoreEl.textContent = SecurityLevelStrings.security_level_learn_more;
     learnMoreEl.addEventListener("click", event => {
       window.openTrustedLinkIn(learnMoreEl.href, "tab");
       this.hide();
       event.preventDefault();
     });
-    this._elements.restoreDefaultsButton.textContent =
-      SecurityLevelStrings.security_level_restore;
-    this._elements.settingsButton.textContent =
-      SecurityLevelStrings.security_level_open_settings;
 
     this._elements.restoreDefaultsButton.addEventListener("command", () => {
       this.restoreDefaults();
@@ -268,11 +217,30 @@ var SecurityLevelPanel = {
 
     // Descriptions change based on security level
     this._elements.background.setAttribute("level", level);
-    this._elements.levelName.textContent =
-      SecurityLevelStrings[`security_level_${level}`];
-    this._elements.summary.textContent = custom
-      ? SecurityLevelStrings.security_level_custom_summary
-      : SecurityLevelStrings[`security_level_${level}_summary`];
+    let l10nIdLevel;
+    let l10nIdSummary;
+    switch (level) {
+      case "standard":
+        l10nIdLevel = "security-level-panel-level-standard";
+        l10nIdSummary = "security-level-summary-standard";
+        break;
+      case "safer":
+        l10nIdLevel = "security-level-panel-level-safer";
+        l10nIdSummary = "security-level-summary-safer";
+        break;
+      case "safest":
+        l10nIdLevel = "security-level-panel-level-safest";
+        l10nIdSummary = "security-level-summary-safest";
+        break;
+      default:
+        throw Error(`Unhandled level: ${level}`);
+    }
+    if (custom) {
+      l10nIdSummary = "security-level-summary-custom";
+    }
+
+    document.l10n.setAttributes(this._elements.levelName, l10nIdLevel);
+    document.l10n.setAttributes(this._elements.summary, l10nIdSummary);
   },
 
   /**
@@ -358,25 +326,13 @@ var SecurityLevelPreferences = {
     this._customNotification = document.getElementById(
       "securityLevel-customNotification"
     );
-    this._radiogroup = document.getElementById("securityLevel-radiogroup");
-
-    document.querySelector("#securityLevel-groupbox h2").textContent =
-      SecurityLevelStrings.security_level;
-    document.getElementById("securityLevel-overview").textContent =
-      SecurityLevelStrings.security_level_overview;
     document
-      .getElementById("securityLevel-learnMore")
-      .setAttribute("value", SecurityLevelStrings.security_level_learn_more);
-
-    document.getElementById("securityLevel-customHeading").textContent =
-      SecurityLevelStrings.security_level_custom_heading;
-    document.getElementById("securityLevel-customDescription").textContent =
-      SecurityLevelStrings.security_level_custom_summary;
-    const restoreDefaultsButton = document.getElementById(
-      "securityLevel-restoreDefaults"
-    );
-    restoreDefaultsButton.textContent =
-      SecurityLevelStrings.security_level_restore;
+      .getElementById("securityLevel-restoreDefaults")
+      .addEventListener("command", () => {
+        SecurityLevelPrefs.securityCustom = false;
+      });
+
+    this._radiogroup = document.getElementById("securityLevel-radiogroup");
 
     this._radioOptions = Array.from(
       this._radiogroup.querySelectorAll(".securityLevel-radio-option"),
@@ -384,46 +340,7 @@ var SecurityLevelPreferences = {
         return { container, radio: container.querySelector("radio") };
       }
     );
-    const descListItemsMap = {
-      safer: [
-        SecurityLevelStrings.security_level_js_https_only,
-        SecurityLevelStrings.security_level_limit_typography,
-        SecurityLevelStrings.security_level_limit_media,
-      ],
-      safest: [
-        SecurityLevelStrings.security_level_js_disabled,
-        SecurityLevelStrings.security_level_limit_typography_svg,
-        SecurityLevelStrings.security_level_limit_media,
-      ],
-    };
-    for (const { container, radio } of this._radioOptions) {
-      const level = radio.value;
-      radio.setAttribute(
-        "label",
-        SecurityLevelStrings[`security_level_${level}`]
-      );
-      container.querySelector(".summary").textContent =
-        SecurityLevelStrings[`security_level_${level}_summary`];
-      const descListItems = descListItemsMap[level];
-      if (!descListItems) {
-        continue;
-      }
-      const descrList = container.querySelector(
-        ".securityLevel-descriptionList"
-      );
-      // TODO: Add the elements in securityLevelPreferences.inc.xhtml again
-      // when we switch to Fluent
-      for (const text of descListItems) {
-        let elem = document.createXULElement("description");
-        elem.textContent = text;
-        elem.className = "indent";
-        descrList.append(elem);
-      }
-    }
 
-    restoreDefaultsButton.addEventListener("command", () => {
-      SecurityLevelPrefs.securityCustom = false;
-    });
     this._radiogroup.addEventListener("select", () => {
       SecurityLevelPrefs.securityLevel = this._radiogroup.value;
     });


=====================================
browser/components/securitylevel/content/securityLevelPanel.inc.xhtml
=====================================
@@ -7,20 +7,35 @@
        level="top"
        class="cui-widget-panel panel-no-padding">
   <box class="panel-header">
-    <html:h1 id="securityLevel-header"></html:h1>
+    <html:h1
+      id="securityLevel-header"
+      data-l10n-id="security-level-panel-heading"
+    ></html:h1>
   </box>
   <toolbarseparator id="securityLevel-separator"></toolbarseparator>
   <vbox id="securityLevel-background" class="panel-subview-body">
     <html:p id="securityLevel-subheading">
       <html:span id="securityLevel-level"></html:span>
-      <html:span id="securityLevel-custom"></html:span>
+      <html:span
+        id="securityLevel-custom"
+        data-l10n-id="security-level-panel-custom-badge"
+      ></html:span>
     </html:p>
     <html:p id="securityLevel-summary"></html:p>
-    <html:a id="securityLevel-learnMore" href="about:manual#security-settings">
-    </html:a>
+    <html:a
+      id="securityLevel-learnMore"
+      data-l10n-id="security-level-panel-learn-more-link"
+      href="about:manual#security-settings"
+    ></html:a>
   </vbox>
   <hbox class="panel-footer">
-    <button id="securityLevel-settings"/>
-    <button id="securityLevel-restoreDefaults"/>
+    <button
+      id="securityLevel-settings"
+      data-l10n-id="security-level-panel-open-settings-button"
+    />
+    <button
+      id="securityLevel-restoreDefaults"
+      data-l10n-id="security-level-restore-defaults-button"
+    />
   </hbox>
 </panel>


=====================================
browser/components/securitylevel/content/securityLevelPreferences.inc.xhtml
=====================================
@@ -2,37 +2,64 @@
           data-category="panePrivacy"
           data-subcategory="securitylevel"
           hidden="true">
-  <label><html:h2></html:h2></label>
+  <label>
+    <html:h2 data-l10n-id="security-level-preferences-heading"></html:h2>
+  </label>
   <vbox flex="1">
     <description flex="1">
-      <html:span id="securityLevel-overview" class="tail-with-learn-more">
-      </html:span>
-      <label id="securityLevel-learnMore"
-             class="learnMore text-link"
-             is="text-link"
-             href="about:manual#security-settings"
-             useoriginprincipal="true"/>
+      <html:span
+        id="securityLevel-overview"
+        class="tail-with-learn-more"
+        data-l10n-id="security-level-preferences-overview"
+      ></html:span>
+      <label
+        id="securityLevel-learnMore"
+        class="learnMore text-link"
+        is="text-link"
+        data-l10n-id="security-level-preferences-learn-more-link"
+        href="about:manual#security-settings"
+        useoriginprincipal="true"
+      />
     </description>
-    <hbox id="securityLevel-customNotification"
-          class="info-box-container"
-          flex="1">
+    <hbox
+      id="securityLevel-customNotification"
+      class="info-box-container"
+      flex="1"
+    >
       <hbox class="info-icon-container">
         <image class="info-icon securityLevel-custom-warning-icon"/>
       </hbox>
       <vbox flex="1">
-        <label id="securityLevel-customHeading"/>
-        <description id="securityLevel-customDescription" flex="1"/>
+        <label
+          id="securityLevel-customHeading"
+          data-l10n-id="security-level-preferences-custom-heading"
+        />
+        <description
+          id="securityLevel-customDescription"
+          data-l10n-id="security-level-summary-custom"
+          flex="1"
+        />
       </vbox>
       <hbox align="center">
-        <button id="securityLevel-restoreDefaults"/>
+        <button
+          id="securityLevel-restoreDefaults"
+          data-l10n-id="security-level-restore-defaults-button"
+        />
       </hbox>
     </hbox>
     <radiogroup id="securityLevel-radiogroup">
       <vbox class="securityLevel-radio-option">
-        <radio value="standard"
-               aria-describedby="securityLevelSummary-standard"/>
+        <radio
+          value="standard"
+          data-l10n-id="security-level-preferences-level-standard"
+          aria-describedby="securityLevelSummary-standard"
+        />
         <vbox id="securityLevelSummary-standard">
-          <description class="summary indent" flex="1"/>
+          <description
+            class="summary indent"
+            flex="1"
+            data-l10n-id="security-level-summary-standard"
+          />
         </vbox>
       </vbox>
       <vbox class="securityLevel-radio-option">
@@ -41,19 +68,59 @@
           - securityLevel-descriptionList is shown or hidden, its text content
           - is included or excluded from the accessible description,
           - respectively. -->
-        <radio value="safer"
-               aria-describedby="securityLevelSummary-safer"/>
+        <radio
+          value="safer"
+          data-l10n-id="security-level-preferences-level-safer"
+          aria-describedby="securityLevelSummary-safer"
+        />
         <vbox id="securityLevelSummary-safer">
-          <description class="summary indent" flex="1"/>
-          <vbox class="securityLevel-descriptionList indent"/>
+          <description
+            class="summary indent"
+            flex="1"
+            data-l10n-id="security-level-summary-safer"
+          />
+          <vbox class="securityLevel-descriptionList indent">
+            <description
+              class="indent"
+              data-l10n-id="security-level-preferences-bullet-https-only-javascript"
+            />
+            <description
+              class="indent"
+              data-l10n-id="security-level-preferences-bullet-limit-font-and-symbols"
+            />
+            <description
+              class="indent"
+              data-l10n-id="security-level-preferences-bullet-limit-media"
+            />
+          </vbox>
         </vbox>
       </vbox>
       <vbox class="securityLevel-radio-option">
-        <radio value="safest"
-               aria-describedby="securityLevelSummary-safest"/>
+        <radio
+          value="safest"
+          data-l10n-id="security-level-preferences-level-safest"
+          aria-describedby="securityLevelSummary-safest"
+        />
         <vbox id="securityLevelSummary-safest">
-          <description class="summary indent" flex="1"/>
-          <vbox class="securityLevel-descriptionList indent"/>
+          <description
+            class="summary indent"
+            flex="1"
+            data-l10n-id="security-level-summary-safest"
+          />
+          <vbox class="securityLevel-descriptionList indent">
+            <description
+              class="indent"
+              data-l10n-id="security-level-preferences-bullet-disabled-javascript"
+            />
+            <description
+              class="indent"
+              data-l10n-id="security-level-preferences-bullet-limit-font-and-symbols-and-images"
+            />
+            <description
+              class="indent"
+              data-l10n-id="security-level-preferences-bullet-limit-media"
+            />
+          </vbox>
         </vbox>
       </vbox>
     </radiogroup>


=====================================
browser/locales/en-US/browser/base-browser.ftl
=====================================
@@ -70,6 +70,7 @@ new-identity-dialog-confirm =
 new-identity-blocked-home-notification = { -brand-short-name } blocked your homepage ({ $url }) from loading because it might recognize your previous session.
 # Button to continue loading the home page, despite the warning message.
 new-identity-blocked-home-ignore-button = Load it anyway
+
 ## Preferences - Letterboxing.
 
 # The word "Letterboxing" is the proper noun for the Tor Browser feature, and is therefore capitalised.
@@ -94,3 +95,74 @@ letterboxing-disabled-description = Letterboxing is currently disabled.
 # "Letterboxing" should be treated as a feature/product name, and likely not changed in other languages.
 letterboxing-enable-button =
     .label = Enable Letterboxing
+
+## Security level toolbar button.
+## Uses sentence case in English (US).
+## ".label" is the accessible name, and shown in the overflow menu and when customizing the toolbar.
+
+security-level-toolbar-button-standard =
+    .label = Security level
+    .tooltiptext = Security level: Standard
+security-level-toolbar-button-safer =
+    .label = Security level
+    .tooltiptext = Security level: Safer
+security-level-toolbar-button-safest =
+    .label = Security level
+    .tooltiptext = Security level: Safest
+# Used when the user is in some custom configuration that does not match a security level.
+security-level-toolbar-button-custom =
+    .label = Security level
+    .tooltiptext = Security level: Custom
+
+## Security level popup panel.
+
+# Uses sentence case in English (US).
+security-level-panel-heading = Security level
+
+security-level-panel-level-standard = Standard
+security-level-panel-level-safer = Safer
+security-level-panel-level-safest = Safest
+security-level-panel-learn-more-link = Learn more
+# Button to open security level settings.
+security-level-panel-open-settings-button = Settings…
+
+## Security level settings.
+
+security-level-preferences-heading = Security Level
+security-level-preferences-overview = Disable certain web features that can be used to attack your security and anonymity.
+security-level-preferences-learn-more-link = Learn more
+security-level-preferences-level-standard =
+    .label = Standard
+security-level-preferences-level-safer =
+    .label = Safer
+security-level-preferences-level-safest =
+    .label = Safest
+
+## Security level summaries shown in security panel and settings.
+
+security-level-summary-standard = All browser and website features are enabled.
+security-level-summary-safer = Disables website features that are often dangerous, causing some sites to lose functionality.
+security-level-summary-safest = Only allows website features required for static sites and basic services. These changes affect images, media, and scripts.
+
+## Security level feature bullet points.
+## Shown in the settings under the security level when it is selected.
+
+security-level-preferences-bullet-https-only-javascript = JavaScript is disabled on non-HTTPS sites.
+security-level-preferences-bullet-limit-font-and-symbols = Some fonts and math symbols are disabled.
+security-level-preferences-bullet-limit-media = Audio and video (HTML5 media), and WebGL are click-to-play.
+security-level-preferences-bullet-disabled-javascript = JavaScript is disabled by default on all sites.
+security-level-preferences-bullet-limit-font-and-symbols-and-images = Some fonts, icons, math symbols, and images are disabled.
+
+## Custom security level.
+## Some custom preferences configuration has placed the user outside one of the standard three levels.
+
+# Shown in the security level panel as an orange badge next to the expected level.
+security-level-panel-custom-badge = Custom
+# Shown in the security level settings in a warning box.
+security-level-preferences-custom-heading = Custom security level configured
+# Description of custom state and recommended action.
+# Shown in the security level panel and settings.
+security-level-summary-custom = Your custom browser preferences have resulted in unusual security settings. For security and privacy reasons, we recommend you choose one of the default security levels.
+# Button to undo custom changes to the security level and place the user in one of the standard security levels.
+# Shown in the security level panel and settings.
+security-level-restore-defaults-button = Restore defaults


=====================================
browser/locales/jar.mn
=====================================
@@ -33,6 +33,5 @@
     locale/browser/safebrowsing/safebrowsing.properties   (%chrome/browser/safebrowsing/safebrowsing.properties)
     locale/browser/feeds/subscribe.properties       (%chrome/browser/feeds/subscribe.properties)
     locale/browser/syncSetup.properties         (%chrome/browser/syncSetup.properties)
-    locale/browser/securityLevel.properties        (%chrome/browser/securityLevel.properties)
     locale/browser/cryptoSafetyPrompt.properties    (%chrome/browser/cryptoSafetyPrompt.properties)
 % locale browser-region @AB_CD@ %locale/browser-region/


=====================================
tools/torbrowser/l10n/migrations/bug-42214-security-level.py
=====================================
@@ -0,0 +1,43 @@
+from fluent.migrate.helpers import transforms_from
+
+
+def migrate(ctx):
+    ctx.add_transforms(
+        "base-browser.ftl",
+        "base-browser.ftl",
+        transforms_from(
+            """
+security-level-panel-level-standard = { COPY(path, "security_level_standard") }
+security-level-panel-level-safer = { COPY(path, "security_level_safer") }
+security-level-panel-level-safest = { COPY(path, "security_level_safest") }
+security-level-panel-learn-more-link = { COPY(path, "security_level_learn_more") }
+security-level-panel-open-settings-button = { COPY(path, "security_level_open_settings") }
+
+security-level-preferences-heading = { COPY(path, "security_level") }
+security-level-preferences-overview = { COPY(path, "security_level_overview") }
+security-level-preferences-learn-more-link = { COPY(path, "security_level_learn_more") }
+security-level-preferences-level-standard =
+    .label = { COPY(path, "security_level_standard") }
+security-level-preferences-level-safer =
+    .label = { COPY(path, "security_level_safer") }
+security-level-preferences-level-safest =
+    .label = { COPY(path, "security_level_safest") }
+
+security-level-summary-standard = { COPY(path, "security_level_standard_summary") }
+security-level-summary-safer = { COPY(path, "security_level_safer_summary") }
+security-level-summary-safest = { COPY(path, "security_level_safest_summary") }
+
+
+security-level-preferences-bullet-https-only-javascript = { COPY(path, "security_level_js_https_only") }
+security-level-preferences-bullet-limit-font-and-symbols = { COPY(path, "security_level_limit_typography") }
+security-level-preferences-bullet-limit-media = { COPY(path, "security_level_limit_media") }
+security-level-preferences-bullet-disabled-javascript = { COPY(path, "security_level_js_disabled") }
+security-level-preferences-bullet-limit-font-and-symbols-and-images = { COPY(path, "security_level_limit_typography_svg") }
+
+security-level-panel-custom-badge = { COPY(path, "security_level_custom") }
+security-level-preferences-custom-heading = { COPY(path, "security_level_custom_heading") }
+security-level-summary-custom = { COPY(path, "security_level_custom_summary") }
+""",
+            path="securityLevel.properties",
+        ),
+    )



View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/966b7f3067cc7b71b56178af98f848451f9a7955...4338bda18aff6d40d6b2eb59cb43d2c3cf2cd4c0

-- 
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/966b7f3067cc7b71b56178af98f848451f9a7955...4338bda18aff6d40d6b2eb59cb43d2c3cf2cd4c0
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/20240325/b2184d81/attachment-0001.htm>


More information about the tbb-commits mailing list