[tor-commits] [tor-browser] 17/33: fixup! squash! Bug 27476: Implement about:torconnect captive portal within Tor Browser

gitolite role git at cupani.torproject.org
Tue May 3 22:40:25 UTC 2022


This is an automated email from the git hooks/post-receive script.

richard pushed a commit to branch tor-browser-91.9.0esr-11.5-1
in repository tor-browser.

commit 251c38c5c362aaf7d2bd55ea5ab515dca9d9fcd4
Author: Pier Angelo Vendrame <pierov at torproject.org>
AuthorDate: Wed Apr 13 09:05:37 2022 +0200

    fixup! squash! Bug 27476: Implement about:torconnect captive portal within Tor Browser
    
    Reworked the about:torconnect page to have its own state machine, that
    is slightly different from the TorConnect's one.
    
    Also includes:
    Bug 40889: applied visual tweaks to breadcrumb styling
    Bug 40892: hghlighted the UI elements in error red instead of the
    breadcrumb
---
 browser/components/torconnect/TorConnectParent.jsm |  13 -
 .../torconnect/content/aboutTorConnect.css         |  79 ++--
 .../torconnect/content/aboutTorConnect.js          | 479 +++++++++++----------
 .../torconnect/content/aboutTorConnect.xhtml       |  15 +-
 browser/components/torconnect/content/globe.svg    |   4 -
 browser/components/torconnect/jar.mn               |   1 -
 6 files changed, 302 insertions(+), 289 deletions(-)

diff --git a/browser/components/torconnect/TorConnectParent.jsm b/browser/components/torconnect/TorConnectParent.jsm
index f39b31a974a95..528f48392880b 100644
--- a/browser/components/torconnect/TorConnectParent.jsm
+++ b/browser/components/torconnect/TorConnectParent.jsm
@@ -9,7 +9,6 @@ const {
   TorConnect,
   TorConnectTopics,
   TorConnectState,
-  TorCensorshipLevel,
 } = ChromeUtils.import("resource:///modules/TorConnect.jsm");
 const { TorSettings, TorSettingsTopics, TorSettingsData } = ChromeUtils.import(
   "resource:///modules/TorSettings.jsm"
@@ -33,11 +32,9 @@ class TorConnectParent extends JSWindowActorParent {
       ErrorDetails: TorConnect.errorDetails,
       BootstrapProgress: TorConnect.bootstrapProgress,
       BootstrapStatus: TorConnect.bootstrapStatus,
-      DetectedCensorshipLevel: TorConnect.detectedCensorshipLevel,
       InternetStatus: TorConnect.internetStatus,
       ShowViewLog: TorConnect.logHasWarningOrError,
       QuickStartEnabled: TorSettings.quickstart.enabled,
-      CountryCodes: TorConnect.countryCodes,
     };
 
     // JSWindowActiveParent derived objects cannot observe directly, so create a member
@@ -78,16 +75,7 @@ class TorConnectParent extends JSWindowActorParent {
           case TorConnectTopics.BootstrapError: {
             self.state.ErrorMessage = obj.message;
             self.state.ErrorDetails = obj.details;
-            self.state.DetectedCensorshipLevel = obj.censorshipLevel;
             self.state.InternetStatus = TorConnect.internetStatus;
-
-            // With severe censorshp, we offer user list of countries to try
-            if (
-              self.state.DetectedCensorshipLevel == TorCensorshipLevel.Severe
-            ) {
-              self.state.CountryCodes = TorConnect.countryCodes;
-            }
-
             self.state.ShowViewLog = true;
             break;
           }
@@ -171,7 +159,6 @@ class TorConnectParent extends JSWindowActorParent {
         return {
           TorStrings,
           TorConnectState,
-          TorCensorshipLevel,
           InternetStatus,
           Direction: Services.locale.isAppLocaleRTL ? "rtl" : "ltr",
           State: this.state,
diff --git a/browser/components/torconnect/content/aboutTorConnect.css b/browser/components/torconnect/content/aboutTorConnect.css
index 926ff4927505a..7f7d75010e82e 100644
--- a/browser/components/torconnect/content/aboutTorConnect.css
+++ b/browser/components/torconnect/content/aboutTorConnect.css
@@ -10,22 +10,9 @@
   --onion-radius: 75px;
 }
 
-/* override firefox's default blue focus coloring */
-:focus {
-  outline:  none!important;
-  box-shadow: 0 0 0 3px var(--purple-30) !important;
-  border:  1px var(--purple-80) solid !important;
-}
-
- at media (prefers-color-scheme: dark)
-{
-  :focus {
-    box-shadow: 0 0 0 3px var(--purple-50)!important;
-  }
-}
-
 #breadcrumbs {
   display: flex;
+  align-items: center;
   margin: 0 0 24px 0;
   color: var(--grey-40);
 }
@@ -38,15 +25,24 @@
   display: flex;
   margin: 0;
   margin-inline-start: 20px;
+  padding: 8px;
 }
 
 .breadcrumb-item {
+  align-items: center;
   cursor: pointer;
   color: var(--in-content-text-color);
+  border-radius: 4px;
 }
 
 .breadcrumb-item:hover {
+  color: var(--in-content-accent-color);
+  background-color: var(--grey-20);
+}
+
+.breadcrumb-item:active {
   color: var(--in-content-accent-color-active);
+  background-color: var(--grey-30);
 }
 
 .breadcrumb-separator {
@@ -60,24 +56,26 @@
 
 .breadcrumb-icon {
   display: inline list-item;
+  height: 16px;
   list-style-position: inside;
   fill: currentColor;
   -moz-context-properties: fill;
 }
 
-.breadcrumb-label {
-  margin-top: -1px;
-}
-
 .breadcrumb-item.active {
-  color: var(--in-content-accent-color-active);
+  color: var(--in-content-accent-color);
 }
 
-.breadcrumb-item.disabled, .breadcrumb-item.disabled:hover {
-  color: var(--green-90-a40);
+.breadcrumb-item.disabled, .breadcrumb-item.disabled:hover, .breadcrumb-item.disabled:active {
+  color: var(--in-content-text-color);
+  opacity: 0.4;
   cursor: default;
 }
 
+.breadcrumb-item.disabled:hover, .breadcrumb-item.disabled:active {
+  background-color: var(--grey-20);
+}
+
 .breadcrumb-item.error {
   color: var(--in-content-danger-button-background);
 }
@@ -94,8 +92,12 @@
   display: none;
 }
 
-#connection-assist {
-  margin-left: 0;
+#connect-to-tor {
+  margin-inline-start: 0;
+}
+
+#connect-to-tor-icon {
+  list-style-image: url("chrome://browser/content/torconnect/onion.svg");
 }
 
 #connection-assist-icon {
@@ -114,29 +116,24 @@
   list-style-image: url("chrome://browser/content/torconnect/bridge.svg");
 }
 
-button.primary {
-  background-color: var(--purple-60)!important;
-  color: white!important;
-  fill: white!important;
-}
-
-button.primary:hover {
-  background-color: var(--purple-70)!important;
-  color: white!important;
-  fill: white!important;
-}
-
-button.primary:active {
-  background-color: var(--purple-80)!important;
-  color: white!important;
-  fill: white!important;
+button {
+  --in-content-primary-button-background: var(--purple-60);
+  --in-content-primary-button-background-hover: var(--purple-70);
+  --in-content-primary-button-background-active: var(--purple-80);
+  --in-content-focus-outline-color: var(--purple-60);
+  --in-content-primary-button-text-color: white;
+  fill: white;
 }
 
-div#locationDropdownLabel {
+#locationDropdownLabel {
   margin-block: auto;
   margin-inline: 4px;
 }
 
+#locationDropdownLabel.error {
+  color: var(--in-content-danger-button-background)
+}
+
 /* this follows similar css in error-pages.css for buttons */
 @media only screen and (min-width: 480px) {
   form#locationDropdown {
@@ -277,7 +274,7 @@ body {
   fill: var(--onion-color);
 }
 
-.title.error {
+.title.assit {
   background-image: url("chrome://browser/content/torconnect/connection-failure.svg");
 }
 
diff --git a/browser/components/torconnect/content/aboutTorConnect.js b/browser/components/torconnect/content/aboutTorConnect.js
index 30dfbd978315f..e525949c40d88 100644
--- a/browser/components/torconnect/content/aboutTorConnect.js
+++ b/browser/components/torconnect/content/aboutTorConnect.js
@@ -5,7 +5,6 @@
 // populated in AboutTorConnect.init()
 let TorStrings = {};
 let TorConnectState = {};
-let TorCensorshipLevel = {};
 let InternetStatus = {};
 
 const BreadcrumbStatus = Object.freeze({
@@ -29,15 +28,15 @@ class AboutTorConnect {
     },
     breadcrumbs: {
       container: "#breadcrumbs",
+      connectToTor: {
+        link: "#connect-to-tor",
+        label: "#connect-to-tor .breadcrumb-label",
+      },
       connectionAssist: {
+        separator: "#connection-assist-separator",
         link: "#connection-assist",
         label: "#connection-assist .breadcrumb-label",
       },
-      locationSettings: {
-        separator: "#location-settings-separator",
-        link: "#location-settings",
-        label: "#location-settings .breadcrumb-label",
-      },
       tryBridge: {
         separator: "#try-bridge-separator",
         link: "#try-bridge",
@@ -59,10 +58,9 @@ class AboutTorConnect {
       cancel: "button#cancelButton",
       connect: "button#connectButton",
       tryBridge: "button#tryBridgeButton",
-      locationDropdownLabel: "div#locationDropdownLabel",
+      locationDropdownLabel: "#locationDropdownLabel",
       locationDropdown: "form#locationDropdown",
       locationDropdownSelect: "form#locationDropdown select",
-      tryAgain: "button#tryAgainButton",
     },
   });
 
@@ -79,21 +77,21 @@ class AboutTorConnect {
     breadcrumbContainer: document.querySelector(
       this.selectors.breadcrumbs.container
     ),
+    connectToTorLink: document.querySelector(
+      this.selectors.breadcrumbs.connectToTor.link
+    ),
+    connectToTorLabel: document.querySelector(
+      this.selectors.breadcrumbs.connectToTor.label
+    ),
+    connectionAssistSeparator: document.querySelector(
+      this.selectors.breadcrumbs.connectionAssist.separator
+    ),
     connectionAssistLink: document.querySelector(
       this.selectors.breadcrumbs.connectionAssist.link
     ),
     connectionAssistLabel: document.querySelector(
       this.selectors.breadcrumbs.connectionAssist.label
     ),
-    locationSettingsSeparator: document.querySelector(
-      this.selectors.breadcrumbs.locationSettings.separator
-    ),
-    locationSettingsLink: document.querySelector(
-      this.selectors.breadcrumbs.locationSettings.link
-    ),
-    locationSettingsLabel: document.querySelector(
-      this.selectors.breadcrumbs.locationSettings.label
-    ),
     tryBridgeSeparator: document.querySelector(
       this.selectors.breadcrumbs.tryBridge.separator
     ),
@@ -116,7 +114,6 @@ class AboutTorConnect {
     configureButton: document.querySelector(this.selectors.buttons.configure),
     cancelButton: document.querySelector(this.selectors.buttons.cancel),
     connectButton: document.querySelector(this.selectors.buttons.connect),
-    tryBridgeButton: document.querySelector(this.selectors.buttons.tryBridge),
     locationDropdownLabel: document.querySelector(
       this.selectors.buttons.locationDropdownLabel
     ),
@@ -126,13 +123,21 @@ class AboutTorConnect {
     locationDropdownSelect: document.querySelector(
       this.selectors.buttons.locationDropdownSelect
     ),
-    tryAgainButton: document.querySelector(this.selectors.buttons.tryAgain),
+    tryBridgeButton: document.querySelector(this.selectors.buttons.tryBridge),
   });
 
   // a redirect url can be passed as a query parameter for the page to
   // forward us to once bootstrap completes (otherwise the window will just close)
   redirect = null;
 
+  showNext = state => {};
+
+  allowAutomaticLocation = true;
+
+  bootstrappingTitle = "";
+  bootstrappingDescription = "";
+  bootstrappingBreadcrumb = -1;
+
   locations = {};
 
   beginBootstrap() {
@@ -147,6 +152,9 @@ class AboutTorConnect {
     this.hide(this.elements.tryBridgeButton);
     this.show(this.elements.cancelButton);
     this.elements.cancelButton.focus();
+    if (countryCode === "automatic") {
+      countryCode = "";
+    }
     RPMSendAsyncMessage("torconnect:begin-autobootstrap", countryCode);
   }
 
@@ -159,11 +167,7 @@ class AboutTorConnect {
   */
 
   show(element, primary) {
-    if (primary) {
-      element.classList.add("primary");
-    } else {
-      element.classList.remove("primary");
-    }
+    element.classList.toggle("primary", primary !== undefined && primary);
     element.removeAttribute("hidden");
   }
 
@@ -176,10 +180,9 @@ class AboutTorConnect {
     this.hide(this.elements.configureButton);
     this.hide(this.elements.cancelButton);
     this.hide(this.elements.connectButton);
-    this.hide(this.elements.tryBridgeButton);
     this.hide(this.elements.locationDropdownLabel);
     this.hide(this.elements.locationDropdown);
-    this.hide(this.elements.tryAgainButton);
+    this.hide(this.elements.tryBridgeButton);
   }
 
   populateLocations() {
@@ -205,14 +208,14 @@ class AboutTorConnect {
     );
   }
 
-  populateSpecialLocations(specialLocations) {
-    this.removeSpecialLocations();
-    if (!specialLocations || !specialLocations.length) {
+  populateFrequentLocations(locations) {
+    this.removeFrequentLocations();
+    if (!locations || !locations.length) {
       return;
     }
 
     const locationNodes = [];
-    for (const code of specialLocations) {
+    for (const code of locations) {
       const option = document.createElement("option");
       option.value = code;
       option.className = "frequent-location";
@@ -230,21 +233,24 @@ class AboutTorConnect {
       left.textContent.localeCompare(right.textContent)
     );
 
-    const specialGroup = document.createElement("optgroup");
-    specialGroup.setAttribute("label", TorStrings.torConnect.frequentLocations);
-    specialGroup.className = "frequent-location";
+    const frequentGroup = document.createElement("optgroup");
+    frequentGroup.setAttribute(
+      "label",
+      TorStrings.torConnect.frequentLocations
+    );
+    frequentGroup.className = "frequent-location";
     const locationGroup = document.createElement("optgroup");
     locationGroup.setAttribute("label", TorStrings.torConnect.otherLocations);
     locationGroup.className = "frequent-location";
-    // options[0] is "Select Country or Region"
+    // options[0] is either "Select Country or Region" or "Automatic"
     this.elements.locationDropdownSelect.options[0].after(
-      specialGroup,
+      frequentGroup,
       ...locationNodes,
       locationGroup
     );
   }
 
-  removeSpecialLocations() {
+  removeFrequentLocations() {
     const select = this.elements.locationDropdownSelect;
     for (const option of select.querySelectorAll(".frequent-location")) {
       option.remove();
@@ -257,20 +263,15 @@ class AboutTorConnect {
       selectedIndex
     ];
     if (!selectedOption.value) {
-      this.elements.tryAgainButton.setAttribute("disabled", "disabled");
+      this.elements.tryBridgeButton.setAttribute("disabled", "disabled");
     } else {
-      this.elements.tryAgainButton.removeAttribute("disabled");
+      this.elements.tryBridgeButton.removeAttribute("disabled");
     }
   }
 
   setTitle(title, className) {
     this.elements.titleText.textContent = title;
-    if (className !== "error") {
-      this.elements.title.classList.remove("error");
-    }
-    if (className !== "location") {
-      this.elements.title.classList.remove("location");
-    }
+    this.elements.title.className = "title";
     if (className) {
       this.elements.title.classList.add(className);
     }
@@ -292,14 +293,14 @@ class AboutTorConnect {
     }
   }
 
-  setBreadcrumbsStatus(connectionAssist, locationSettings, tryBridge) {
+  setBreadcrumbsStatus(connectToTor, connectionAssist, tryBridge) {
     this.elements.breadcrumbContainer.classList.remove("hidden");
     const elems = [
-      [this.elements.connectionAssistLink, connectionAssist, null],
+      [this.elements.connectToTorLink, connectToTor, null],
       [
-        this.elements.locationSettingsLink,
-        locationSettings,
-        this.elements.locationSettingsSeparator,
+        this.elements.connectionAssistLink,
+        connectionAssist,
+        this.elements.connectionAssistSeparator,
       ],
       [
         this.elements.tryBridgeLink,
@@ -336,118 +337,29 @@ class AboutTorConnect {
   /* Per-state updates */
 
   update_Initial(state) {
-    const hasError = false;
-    const showProgressbar = false;
-
-    this.setTitle(TorStrings.torConnect.torConnect, hasError ? "error" : "");
-    this.setProgress(
-      TorStrings.settings.torPreferencesDescription,
-      showProgressbar
-    );
-    this.hide(this.elements.quickstartContainer);
-    this.hide(this.elements.viewLogContainer);
-    this.hideButtons();
+    this.showConnectToTor(state, false);
   }
 
   update_Configuring(state) {
-    const hasError = state.ErrorMessage != null;
-    const showProgressbar = false;
-
     this.hide(this.elements.quickstartContainer);
     this.hide(this.elements.viewLogContainer);
     this.hideButtons();
 
-    if (hasError) {
-      if (state.InternetStatus === InternetStatus.Offline) {
-        this.showOffline(state.ErrorMessage);
-        return;
-      }
-      switch (state.DetectedCensorshipLevel) {
-        case TorCensorshipLevel.None:
-          // we shouldn't be able to get here
-          break;
-        case TorCensorshipLevel.Moderate:
-          // bootstrap failed once, offer auto bootstrap
-          this.showConnectionAssistant(state.ErrorDetails);
-          if (state.StateChanged) {
-            this.elements.tryBridgeButton.focus();
-          }
-          break;
-        case TorCensorshipLevel.Severe:
-          // autobootstrap failed, verify correct location
-          this.showLocationSettings(state.CountryCodes, state.ErrorMessage);
-          if (state.StateChanged) {
-            this.elements.tryAgainButton.focus();
-          }
-          break;
-        case TorCensorshipLevel.Extreme:
-          // finally offer to restart tor-browser or go to configure options
-          this.showFinalError(state);
-          break;
-      }
+    if (state.ErrorMessage === null) {
+      this.showConnectToTor(state, false);
+    } else if (state.InternetStatus === InternetStatus.Offline) {
+      this.showOffline(state.ErrorMessage);
     } else {
-      this.setTitle(TorStrings.torConnect.torConnect, "");
-      this.setLongText(TorStrings.settings.torPreferencesDescription);
-      this.setProgress("", showProgressbar);
-      this.show(this.elements.quickstartContainer);
-      this.show(this.elements.configureButton);
-      this.show(this.elements.connectButton, true);
-      this.elements.connectButton.textContent =
-        TorStrings.torConnect.torConnectButton;
-      if (state.StateChanged) {
-        this.elements.connectButton.focus();
-      }
+      this.showNext(state);
     }
   }
 
   update_AutoBootstrapping(state) {
-    const showProgressbar = true;
-
-    if (state.DetectedCensorshipLevel >= TorCensorshipLevel.Severe) {
-      this.setTitle(TorStrings.torConnect.tryingBridgeAgain, "");
-    } else {
-      this.setTitle(TorStrings.torConnect.tryingBridge, "");
-    }
-    this.showConfigureConnectionLink(TorStrings.torConnect.assistDescription);
-    this.setProgress(
-      state.BootstrapStatus,
-      showProgressbar,
-      state.BootstrapProgress
-    );
-    this.setBreadcrumbsStatus(
-      BreadcrumbStatus.Disabled,
-      BreadcrumbStatus.Disabled,
-      BreadcrumbStatus.Active
-    );
-    if (state.ShowViewLog) {
-      this.show(this.elements.viewLogContainer);
-    } else {
-      this.hide(this.elements.viewLogContainer);
-    }
-    this.hideButtons();
-    this.show(this.elements.cancelButton, true);
-    if (state.StateChanged) {
-      this.elements.cancelButton.focus();
-    }
+    this.showBootstrapping(state);
   }
 
   update_Bootstrapping(state) {
-    const showProgressbar = true;
-
-    this.setTitle(TorStrings.torConnect.torConnecting, "");
-    this.setLongText(TorStrings.settings.torPreferencesDescription);
-    this.setProgress("", showProgressbar, state.BootstrapProgress);
-    this.hideBreadcrumbs();
-    if (state.ShowViewLog) {
-      this.show(this.elements.viewLogContainer);
-    } else {
-      this.hide(this.elements.viewLogContainer);
-    }
-    this.hideButtons();
-    this.show(this.elements.cancelButton, true);
-    if (state.StateChanged) {
-      this.elements.cancelButton.focus();
-    }
+    this.showBootstrapping(state);
   }
 
   update_Error(state) {
@@ -479,6 +391,63 @@ class AboutTorConnect {
     // it isn't in use (eg using tor-launcher or system tor)
   }
 
+  showConnectToTor(state, tryAgain) {
+    this.setTitle(TorStrings.torConnect.torConnect, "");
+    this.setLongText(TorStrings.settings.torPreferencesDescription);
+    this.setProgress("", false);
+    this.hideButtons();
+    this.show(this.elements.quickstartContainer);
+    this.show(this.elements.configureButton);
+    this.show(this.elements.connectButton, true);
+    if (state?.StateChanged) {
+      this.elements.connectButton.focus();
+    }
+    if (tryAgain) {
+      this.setBreadcrumbsStatus(
+        BreadcrumbStatus.Active,
+        BreadcrumbStatus.Default,
+        BreadcrumbStatus.Disabled
+      );
+      this.elements.connectButton.textContent = TorStrings.torConnect.tryAgain;
+    }
+    this.bootstrappingDescription =
+      TorStrings.settings.torPreferencesDescription;
+    this.showNext = fromState => {
+      this.showConnectionAssistant(fromState.ErrorDetails);
+      if (fromState.StateChanged) {
+        this.elements.tryBridgeButton.focus();
+      }
+    };
+  }
+
+  showBootstrapping(state) {
+    const showProgressbar = true;
+    this.setTitle(this.bootstrappingTitle, "");
+    this.showConfigureConnectionLink(this.bootstrappingDescription);
+    this.setProgress("", showProgressbar, state.BootstrapProgress);
+    if (this.bootstrappingBreadcrumb < 0) {
+      this.hideBreadcrumbs();
+    } else {
+      const breadcrumbs = [
+        BreadcrumbStatus.Disabled,
+        BreadcrumbStatus.Disabled,
+        BreadcrumbStatus.Disabled,
+      ];
+      breadcrumbs[this.bootstrappingBreadcrumb] = BreadcrumbStatus.Active;
+      this.setBreadcrumbsStatus(...breadcrumbs);
+    }
+    if (state.ShowViewLog) {
+      this.show(this.elements.viewLogContainer);
+    } else {
+      this.hide(this.elements.viewLogContainer);
+    }
+    this.hideButtons();
+    this.show(this.elements.cancelButton, true);
+    if (state.StateChanged) {
+      this.elements.cancelButton.focus();
+    }
+  }
+
   showOffline(error) {
     this.setTitle(TorStrings.torConnect.noInternet, "error");
     this.setLongText("Some long text from 🍩️");
@@ -494,24 +463,89 @@ class AboutTorConnect {
     this.elements.connectButton.textContent = TorStrings.torConnect.tryAgain;
   }
 
-  showConnectionAssistant(error) {
-    const hasError = !!error;
-    this.setTitle(
-      TorStrings.torConnect.couldNotConnect,
-      hasError ? "error" : ""
-    );
+  showConnectionAssistant(errorMessage) {
+    this.setTitle(TorStrings.torConnect.couldNotConnect, "assit");
     this.showConfigureConnectionLink(TorStrings.torConnect.assistDescription);
-    this.setProgress(error, false);
+    this.setProgress(errorMessage, false);
     this.setBreadcrumbsStatus(
+      BreadcrumbStatus.Default,
       BreadcrumbStatus.Active,
+      BreadcrumbStatus.Disabled
+    );
+    this.showLocationForm(false, TorStrings.torConnect.tryBridge);
+    this.bootstrappingBreadcrumb = 2;
+    this.bootstrappingTitle = TorStrings.torConnect.tryingBridge;
+    this.bootstrappingDescription = TorStrings.torConnect.assistDescription;
+    this.showNext = state => {
+      if (this.getLocation() === "automatic") {
+        this.showCannotLocate(state.ErrorMessage);
+      } else {
+        this.showLocationConfirmation(state.ErrorMessage);
+      }
+      if (state.StateChanged) {
+        this.elements.tryBridgeButton.focus();
+      }
+    };
+  }
+
+  showCannotLocate(errorMessage) {
+    this.allowAutomaticLocation = false;
+    this.setTitle(TorStrings.torConnect.errorLocation, "location");
+    this.showConfigureConnectionLink(
+      TorStrings.torConnect.errorLocationDescription
+    );
+    this.setProgress(errorMessage, false);
+    this.setBreadcrumbsStatus(
       BreadcrumbStatus.Default,
+      BreadcrumbStatus.Active,
       BreadcrumbStatus.Disabled
     );
+    this.showLocationForm(true, TorStrings.torConnect.tryBridge);
+    this.bootstrappingBreadcrumb = 2;
+    this.bootstrappingTitle = TorStrings.torConnect.tryingBridgeAgain;
+    this.bootstrappingDescription =
+      TorStrings.torConnect.errorLocationDescription;
+    this.showNext = state => {
+      this.showFinalError(state);
+    };
+  }
+
+  showLocationConfirmation(errorMessage) {
+    this.setTitle(TorStrings.torConnect.isLocationCorrect, "location");
+    this.showConfigureConnectionLink(
+      TorStrings.torConnect.isLocationCorrectDescription
+    );
+    this.setProgress(errorMessage, false);
+    this.setBreadcrumbsStatus(
+      BreadcrumbStatus.Default,
+      BreadcrumbStatus.Default,
+      BreadcrumbStatus.Active
+    );
+    this.showLocationForm(true, TorStrings.torConnect.tryAgain);
+    this.bootstrappingBreadcrumb = 2;
+    this.bootstrappingTitle = TorStrings.torConnect.tryingBridgeAgain;
+    this.bootstrappingDescription =
+      TorStrings.torConnect.isLocationCorrectDescription;
+    this.showNext = state => {
+      this.showFinalError(state);
+    };
+  }
+
+  showFinalError(state) {
+    this.setTitle(TorStrings.torConnect.finalError, "error");
+    this.setLongText(TorStrings.torConnect.finalErrorDescription);
+    this.setProgress(state ? state.ErrorDetails : "", false);
+    this.setBreadcrumbsStatus(
+      BreadcrumbStatus.Default,
+      BreadcrumbStatus.Default,
+      BreadcrumbStatus.Active
+    );
     this.hideButtons();
-    this.show(this.elements.configureButton);
-    this.show(this.elements.connectButton);
-    this.elements.connectButton.textContent = TorStrings.torConnect.tryAgain;
-    this.show(this.elements.tryBridgeButton, true);
+    this.show(this.elements.restartButton);
+    this.show(this.elements.configureButton, true);
+    this.showNext = fromState => {
+      this.showFinalError(fromState);
+    };
   }
 
   showConfigureConnectionLink(text) {
@@ -523,76 +557,77 @@ class AboutTorConnect {
       e.preventDefault();
       RPMSendAsyncMessage("torconnect:open-tor-preferences");
     });
-    this.setLongText(pieces[0], link, pieces[1]);
-  }
-
-  showLocationSettings(locations, error) {
-    const hasError = !!error;
-    if (hasError) {
-      this.setTitle(TorStrings.torConnect.errorLocation, "location");
-      this.setLongText(TorStrings.torConnect.errorLocationDescription);
-      this.setBreadcrumbsStatus(
-        BreadcrumbStatus.Disabled,
-        BreadcrumbStatus.Error,
-        BreadcrumbStatus.Disabled
-      );
-      this.elements.tryAgainButton.textContent = TorStrings.torConnect.tryAgain;
+    if (pieces.length > 1) {
+      const first = pieces.shift();
+      this.setLongText(first, link, ...pieces);
     } else {
-      this.setTitle(TorStrings.torConnect.addLocation, "location");
-      this.showConfigureConnectionLink(
-        TorStrings.torConnect.addLocationDescription
-      );
-      this.setBreadcrumbsStatus(
-        BreadcrumbStatus.Default,
-        BreadcrumbStatus.Active,
-        BreadcrumbStatus.Disabled
-      );
-      this.elements.tryAgainButton.textContent =
-        TorStrings.torConnect.tryBridge;
+      this.setLongText(text);
     }
-    this.setProgress(error, false);
+  }
+
+  showLocationForm(isError, buttonLabel) {
     this.hideButtons();
-    if (!locations || !locations.length) {
-      RPMSendQuery("torconnect:get-country-codes").then(codes => {
-        if (codes && codes.length) {
-          this.populateSpecialLocations(codes);
-        }
-      });
+    RPMSendQuery("torconnect:get-country-codes").then(codes => {
+      if (codes && codes.length) {
+        this.populateFrequentLocations(codes);
+      }
+    });
+    let firstOpt = this.elements.locationDropdownSelect.options[0];
+    if (this.allowAutomaticLocation) {
+      firstOpt.value = "automatic";
+      firstOpt.textContent = TorStrings.torConnect.automatic;
     } else {
-      this.populateSpecialLocations(locations);
+      firstOpt.value = "";
+      firstOpt.textContent = TorStrings.torConnect.selectCountryRegion;
     }
     this.validateLocation();
     this.show(this.elements.locationDropdownLabel);
     this.show(this.elements.locationDropdown);
-    this.show(this.elements.tryAgainButton, true);
+    this.elements.locationDropdownLabel.classList.toggle("error", isError);
+    this.show(this.elements.tryBridgeButton, true);
+    this.elements.tryBridgeButton.classList.toggle("danger-button", isError);
+    if (buttonLabel !== undefined) {
+      this.elements.tryBridgeButton.textContent = buttonLabel;
+    }
   }
 
-  showFinalError(state) {
-    this.setTitle(TorStrings.torConnect.finalError, "error");
-    this.setLongText(TorStrings.torConnect.finalErrorDescription);
-    this.setProgress(state ? state.ErrorDetails : "", false);
-    this.hideButtons();
-    this.show(this.elements.restartButton);
-    this.show(this.elements.configureButton, true);
+  getLocation() {
+    const selectedIndex = this.elements.locationDropdownSelect.selectedIndex;
+    return this.elements.locationDropdownSelect.options[selectedIndex].value;
   }
 
   initElements(direction) {
     document.documentElement.setAttribute("dir", direction);
 
+    this.bootstrappingTitle = TorStrings.torConnect.torConnecting;
+
+    this.elements.connectToTorLink.addEventListener("click", event => {
+      if (
+        this.elements.connectToTorLink.classList.contains(
+          BreadcrumbStatus.Active
+        )
+      ) {
+        return;
+      }
+      this.showConnectToTor(null, true);
+    });
+    this.elements.connectToTorLabel.textContent =
+      TorStrings.torConnect.torConnect;
     this.elements.connectionAssistLink.addEventListener("click", event => {
-      if (!this.elements.connectionAssistLink.classList.contains("disabled")) {
-        this.showConnectionAssistant();
+      if (
+        this.elements.connectionAssistLink.classList.contains(
+          BreadcrumbStatus.Active
+        ) ||
+        this.elements.connectionAssistLink.classList.contains(
+          BreadcrumbStatus.Disabled
+        )
+      ) {
+        return;
       }
+      this.showConnectionAssistant();
     });
     this.elements.connectionAssistLabel.textContent =
       TorStrings.torConnect.breadcrumbAssist;
-    this.elements.locationSettingsLink.addEventListener("click", event => {
-      if (!this.elements.connectionAssistLink.classList.contains("disabled")) {
-        this.showLocationSettings();
-      }
-    });
-    this.elements.locationSettingsLabel.textContent =
-      TorStrings.torConnect.breadcrumbLocation;
     this.elements.tryBridgeLabel.textContent =
       TorStrings.torConnect.breadcrumbTryBridge;
 
@@ -629,6 +664,13 @@ class AboutTorConnect {
     this.elements.connectButton.textContent =
       TorStrings.torConnect.torConnectButton;
     this.elements.connectButton.addEventListener("click", () => {
+      if (
+        this.elements.connectButton.textContent ===
+        TorStrings.torConnect.tryAgain
+      ) {
+        this.bootstrappingBreadcrumb = 0;
+        this.bootstrappingTitle = TorStrings.torConnect.tryingAgain;
+      }
       this.beginBootstrap();
     });
 
@@ -637,23 +679,17 @@ class AboutTorConnect {
       this.validateLocation();
     });
 
-    this.elements.tryBridgeButton.textContent = TorStrings.torConnect.tryBridge;
-    this.elements.tryBridgeButton.addEventListener("click", () => {
-      this.beginAutoBootstrap();
-    });
-
     this.elements.locationDropdownLabel.textContent =
       TorStrings.torConnect.yourLocation;
 
-    this.elements.tryAgainButton.textContent = TorStrings.torConnect.tryAgain;
-    this.elements.tryAgainButton.setAttribute("disabled", "disabled");
-    this.elements.tryAgainButton.addEventListener("click", () => {
-      let selectedIndex = this.elements.locationDropdownSelect.selectedIndex;
-      let selectedOption = this.elements.locationDropdownSelect.options[
-        selectedIndex
-      ];
-
-      this.beginAutoBootstrap(selectedOption.value);
+    this.elements.tryBridgeButton.textContent = TorStrings.torConnect.tryBridge;
+    this.elements.tryBridgeButton.addEventListener("click", () => {
+      const value = this.getLocation();
+      if (value === "automatic") {
+        this.beginAutoBootstrap();
+      } else {
+        this.beginAutoBootstrap(value);
+      }
     });
   }
 
@@ -692,7 +728,6 @@ class AboutTorConnect {
     // various constants
     TorStrings = Object.freeze(args.TorStrings);
     TorConnectState = Object.freeze(args.TorConnectState);
-    TorCensorshipLevel = Object.freeze(args.TorCensorshipLevel);
     InternetStatus = Object.freeze(args.InternetStatus);
     this.locations = args.CountryNames;
 
diff --git a/browser/components/torconnect/content/aboutTorConnect.xhtml b/browser/components/torconnect/content/aboutTorConnect.xhtml
index 4bb5b31949a67..674029fdeda34 100644
--- a/browser/components/torconnect/content/aboutTorConnect.xhtml
+++ b/browser/components/torconnect/content/aboutTorConnect.xhtml
@@ -10,13 +10,13 @@
     <div id="progressBackground"></div>
     <div id="connectPageContainer" class="container">
       <div id="breadcrumbs" class="hidden">
-        <span id="connection-assist" class="breadcrumb-item">
-          <span id="connection-assist-icon" class="breadcrumb-icon" />
+        <span id="connect-to-tor" class="breadcrumb-item">
+          <span id="connect-to-tor-icon" class="breadcrumb-icon" />
           <span class="breadcrumb-label"/>
         </span>
-        <span id="location-settings-separator" class="breadcrumb-separator breadcrumb-icon" />
-        <span id="location-settings" class="breadcrumb-item">
-          <span id="location-settings-icon" class="breadcrumb-icon" />
+        <span id="connection-assist-separator" class="breadcrumb-separator breadcrumb-icon" />
+        <span id="connection-assist" class="breadcrumb-item">
+          <span id="connection-assist-icon" class="breadcrumb-icon" />
           <span class="breadcrumb-label"/>
         </span>
         <span id="try-bridge-separator" class="breadcrumb-separator breadcrumb-icon" />
@@ -50,13 +50,12 @@
           <button id="configureButton" hidden="true"></button>
           <button id="cancelButton" hidden="true"></button>
           <button id="connectButton" class="primary" hidden="true"></button>
-          <button id="tryBridgeButton" class="primary" hidden="true"></button>
-          <div id="locationDropdownLabel"/>
+          <label id="locationDropdownLabel" for="countries"/>
           <form id="locationDropdown" hidden="true">
             <select id="countries">
             </select>
           </form>
-          <button id="tryAgainButton" class="primary" hidden="true"></button>
+          <button id="tryBridgeButton" class="primary" hidden="true"></button>
         </div>
       </div>
     </div>
diff --git a/browser/components/torconnect/content/globe.svg b/browser/components/torconnect/content/globe.svg
deleted file mode 100644
index f4d1f19b43ce8..0000000000000
--- a/browser/components/torconnect/content/globe.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
-    <path d="M8 0.5C6.01088 0.5 4.10322 1.29018 2.6967 2.6967C1.29018 4.10322 0.5 6.01088 0.5 8C0.5 9.98912 1.29018 11.8968 2.6967 13.3033C4.10322 14.7098 6.01088 15.5 8 15.5C9.98912 15.5 11.8968 14.7098 13.3033 13.3033C14.7098 11.8968 15.5 9.98912 15.5 8C15.5 6.01088 14.7098 4.10322 13.3033 2.6967C11.8968 1.29018 9.98912 0.5 8 0.5ZM10.447 2.25C11.4738 2.69088 12.3637 3.39877 13.0242 4.30006C13.6848 5.20135 14.0918 6.26313 14.203 7.375H11.974C11.8509 5.51288 11.1778 3.72922 10.04 2.25H10 [...]
-</svg>
diff --git a/browser/components/torconnect/jar.mn b/browser/components/torconnect/jar.mn
index 8ca0b0651523e..043bd1435cda5 100644
--- a/browser/components/torconnect/jar.mn
+++ b/browser/components/torconnect/jar.mn
@@ -5,7 +5,6 @@ browser.jar:
     content/browser/torconnect/aboutTorConnect.js                  (content/aboutTorConnect.js)
     content/browser/torconnect/arrow-right.svg                     (content/arrow-right.svg)
     content/browser/torconnect/bridge.svg                          (content/bridge.svg)
-    content/browser/torconnect/globe.svg                           (content/globe.svg)
     content/browser/torconnect/connection-failure.svg              (content/connection-failure.svg)
     content/browser/torconnect/connection-location.svg             (content/connection-location.svg)
     content/browser/torconnect/onion.svg                           (content/onion.svg)

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the tor-commits mailing list