[tor-commits] [tor-browser/tor-browser-60.6.1esr-8.5-1] Bug 29768: Introduce new features to users

gk at torproject.org gk at torproject.org
Thu Apr 4 14:06:26 UTC 2019


commit e4a163b58530f37b7f292fe49ad7b882b2f046d0
Author: Kathy Brade <brade at pearlcrescent.com>
Date:   Wed Apr 3 16:14:46 2019 -0400

    Bug 29768: Introduce new features to users
    
    Add an "update" tour for the Tor Browser 8.5 release that contains two
    panels: Toolbar and Security (with appropriate description text and
    images).
    
    Display an attention-grabbing dot on the onboarding text bubble when
    the update tour is active. The animation lasts for 14 seconds.
---
 browser/app/profile/000-tor-browser.js             |   3 +-
 browser/extensions/onboarding/bootstrap.js         |   2 +
 .../content/img/figure_tor-security-level.png      | Bin 0 -> 12185 bytes
 .../content/img/figure_tor-toolbar-layout.png      | Bin 0 -> 5837 bytes
 .../extensions/onboarding/content/onboarding.css   |  54 +++++++++++++--
 .../extensions/onboarding/content/onboarding.js    |  75 ++++++++++++++++++++-
 6 files changed, 128 insertions(+), 6 deletions(-)

diff --git a/browser/app/profile/000-tor-browser.js b/browser/app/profile/000-tor-browser.js
index cca469725d28..c810c18a84a1 100644
--- a/browser/app/profile/000-tor-browser.js
+++ b/browser/app/profile/000-tor-browser.js
@@ -327,8 +327,9 @@ pref("browser.download.panel.shown", true);
 pref("dom.securecontext.whitelist_onions", true);
 
 // Onboarding.
+pref("browser.onboarding.tourset-version", 3);
 pref("browser.onboarding.newtour", "welcome,privacy,tor-network,circuit-display,security,expect-differences,onion-services");
-pref("browser.onboarding.updatetour", "welcome,privacy,tor-network,circuit-display,security,expect-differences,onion-services");
+pref("browser.onboarding.updatetour", "toolbar-update-8.5,security-update-8.5");
 pref("browser.onboarding.skip-tour-button.hide", true);
 
 // prefs to disable jump-list entries in the taskbar on Windows (see bug #12885)
diff --git a/browser/extensions/onboarding/bootstrap.js b/browser/extensions/onboarding/bootstrap.js
index a90bef0faaa2..6eec2122ce2a 100644
--- a/browser/extensions/onboarding/bootstrap.js
+++ b/browser/extensions/onboarding/bootstrap.js
@@ -38,6 +38,8 @@ const PREF_WHITELIST = [
   "onboarding-tour-tor-security",
   "onboarding-tour-tor-expect-differences",
   "onboarding-tour-tor-onion-services",
+  "onboarding-tour-tor-toolbar-update-8-5",
+  "onboarding-tour-tor-security-update-8-5",
 #if 0
 // Firefox tours. To reduce conflicts when rebasing against newer Firefox
 // code, we use the preprocessor to omit this code block.
diff --git a/browser/extensions/onboarding/content/img/figure_tor-security-level.png b/browser/extensions/onboarding/content/img/figure_tor-security-level.png
new file mode 100644
index 000000000000..5c7b8c5635fe
Binary files /dev/null and b/browser/extensions/onboarding/content/img/figure_tor-security-level.png differ
diff --git a/browser/extensions/onboarding/content/img/figure_tor-toolbar-layout.png b/browser/extensions/onboarding/content/img/figure_tor-toolbar-layout.png
new file mode 100644
index 000000000000..0a8161087827
Binary files /dev/null and b/browser/extensions/onboarding/content/img/figure_tor-toolbar-layout.png differ
diff --git a/browser/extensions/onboarding/content/onboarding.css b/browser/extensions/onboarding/content/onboarding.css
index e70cf3fa671a..4804c4fbadc6 100644
--- a/browser/extensions/onboarding/content/onboarding.css
+++ b/browser/extensions/onboarding/content/onboarding.css
@@ -23,11 +23,44 @@
   display: block;
 }
 
-#onboarding-overlay-button {
-  padding: 10px 0 0 0;
+#onboarding-overlay-button-container {
+  padding: 16px 0 0 0;
   position: fixed;
-  cursor: pointer;
   top: 4px;
+}
+
+/*
+ * Define an animated attention-grabbing dot which is shown on the
+ * speech bubble when we are displaying the "updated" tour.
+*/
+#onboarding-overlay-button-container.onboarding-overlay-attention-dot::after {
+  display: inline-block;
+  position: relative;
+  content: " ";
+  width: 20px;
+  height: 20px;
+  top: -8px;
+  offset-inline-start: -16px;
+  background-color: #00E2B1;
+  border-radius: 50%;
+  animation: pulsate 2.0s ease-out;
+  animation-iteration-count: 7;
+}
+
+ at keyframes pulsate {
+  0% {
+    opacity: 1.0;
+  }
+  50% {
+    opacity: 0.5;
+  }
+  100% {
+    opacity: 1.0;
+  }
+}
+
+#onboarding-overlay-button {
+  cursor: pointer;
   offset-inline-start: 12px;
   border: none;
   /* Set to none so no grey contrast background in the high-contrast mode */
@@ -78,7 +111,7 @@
   font-weight: 400;
   content: attr(aria-label);
   border: 1px solid transparent;
-  border-radius: 58px;
+  border-radius: 12px;
   padding: 10px 16px;
   width: auto;
   height: auto;
@@ -308,6 +341,19 @@
   grid-template-columns: [tour-page-start] 368px [tour-content-start] 1fr [tour-page-end];
 }
 
+.onboarding-tour-description-prefix {
+  display: inline-block;
+  margin-bottom: -8px; /* reduce vertical space below */
+  padding: 2px 10px;
+  vertical-align: center;
+  background-color: #F1F1F3;
+  border-radius: 4px;
+  min-height: 25px;
+  font-size: 10px;
+  font-weight: 600;
+  text-transform: uppercase;
+}
+
 .onboarding-tour-description {
   grid-row: tour-page-start / tour-page-end;
   grid-column: tour-page-start / tour-content-start;
diff --git a/browser/extensions/onboarding/content/onboarding.js b/browser/extensions/onboarding/content/onboarding.js
index ac5569d4b57b..acfcd93c5cef 100644
--- a/browser/extensions/onboarding/content/onboarding.js
+++ b/browser/extensions/onboarding/content/onboarding.js
@@ -51,6 +51,17 @@ function createOnboardingTourDescription(div, title, description) {
 }
 
 /**
+ * Helper function to insert a prefix above the tour description.
+ */
+function addOnboardingTourPrefix(section, l10nId) {
+  let doc = section.ownerDocument;
+  let div = doc.createElement("div");
+  div.className = "onboarding-tour-description-prefix";
+  div.setAttribute("data-l10n-id", l10nId);
+  section.insertBefore(div, section.firstChild); // Insert as first child.
+}
+
+/**
  * Helper function to create the tour content UI element.
  */
 function createOnboardingTourContent(div, imageSrc) {
@@ -108,6 +119,7 @@ function createOnboardingTourButton(div, buttonId, l10nId, buttonElementTagName
  **/
 // Tor Browser tours:
 var onboardingTourset = {
+  // Tour items for new users:
   "welcome": {
     id: "onboarding-tour-tor-welcome",
     tourNameId: TORBROWSER_WELCOME_TOUR_NAME_KEY,
@@ -228,6 +240,47 @@ var onboardingTourset = {
       return div;
     },
   },
+  // Tour items for users who have updated their Tor Browser:
+  "toolbar-update-8.5": {
+    id: "onboarding-tour-tor-toolbar-update-8-5",
+    tourNameId: "onboarding.tour-tor-toolbar",
+    instantComplete: true,
+    getPage(win) {
+      let div = win.document.createElement("div");
+
+      let desc = createOnboardingTourDescription(div,
+        "onboarding.tour-tor-toolbar-update-8.5.title", "onboarding.tour-tor-toolbar-update-8.5.description");
+      addOnboardingTourPrefix(desc, "onboarding.tour-tor-update.prefix-updated");
+
+      createOnboardingTourContent(div, "resource://onboarding/img/figure_tor-toolbar-layout.png");
+      createOnboardingTourButton(div,
+        "onboarding-tour-tor-toolbar-next-button", "onboarding.tour-tor-toolbar-update-8.5.next-button");
+
+      return div;
+    },
+  },
+  "security-update-8.5": {
+    id: "onboarding-tour-tor-security-update-8-5",
+    tourNameId: "onboarding.tour-tor-security",
+    getPage(win) {
+      let div = win.document.createElement("div");
+
+      let desc = createOnboardingTourDescription(div,
+        "onboarding.tour-tor-security-update-8.5.title", "onboarding.tour-tor-security-update-8.5.description");
+      addOnboardingTourPrefix(desc, "onboarding.tour-tor-update.prefix-new");
+
+      createOnboardingTourContent(div, "resource://onboarding/img/figure_tor-security-level.png");
+      let btnContainer = createOnboardingTourButton(div,
+        "onboarding-tour-tor-security-button", "onboarding.tour-tor-security-level.button");
+      btnContainer.className = "onboarding-tour-tor-action-button-container";
+      // It is confusing to use the two onion-services IDs below, but they
+      // provide the functionality and translated string ("Done") that we need.
+      createOnboardingTourButton(div,
+        "onboarding-tour-tor-onion-services-next-button", "onboarding.tour-tor-onion-services.next-button");
+
+      return div;
+    },
+  },
 };
 #if 0
 // Firefox tours. To reduce conflicts when rebasing against newer Firefox
@@ -669,6 +722,7 @@ class Onboarding {
     } else {
       this._overlayIcon.classList.remove("onboarding-speech-bubble");
     }
+    this.updateAttentionDot();
   }
 
   _initUI() {
@@ -683,7 +737,10 @@ class Onboarding {
     this._overlayIcon = this._renderOverlayButton();
     this._overlayIcon.addEventListener("click", this);
     this._overlayIcon.addEventListener("keypress", this);
-    body.insertBefore(this._overlayIcon, body.firstChild);
+    let buttonContainer = this._window.document.createElement("div");
+    buttonContainer.id = "onboarding-overlay-button-container";
+    buttonContainer.appendChild(this._overlayIcon);
+    body.insertBefore(buttonContainer, body.firstChild);
 
     this._overlay = this._renderOverlay();
     this._overlay.addEventListener("click", this);
@@ -917,6 +974,7 @@ class Onboarding {
       case "onboarding-tour-tor-security-next-button":
       case "onboarding-tour-tor-expect-differences-next-button":
       case "onboarding-tour-tor-onion-services-next-button":
+      case "onboarding-tour-tor-toolbar-next-button":
         this.gotoNextTourItem();
         handledTourActionClick = true;
         break;
@@ -1131,7 +1189,9 @@ class Onboarding {
     this._overlayIcon.dispatchEvent(new this._window.CustomEvent("Agent:Destroy"));
 
     this._clearPrefObserver();
+    let buttonContainer = this._overlayIcon.parentElement;
     this._overlayIcon.remove();
+    buttonContainer.remove();
     if (this._overlay) {
       // send overlay-session telemetry
       this.hideOverlay();
@@ -1155,9 +1215,21 @@ class Onboarding {
         this._overlayIcon.classList.add("onboarding-watermark");
         break;
     }
+    this.updateAttentionDot();
     return true;
   }
 
+  // Display an attention-grabbing dot on the speech bubble if the
+  // bubble is visible and we are showing the "update" tour.
+  updateAttentionDot() {
+    let buttonContainer = this._overlayIcon.parentElement;
+    if ((this._bubbleState === "bubble") && (this._tourType === "update")) {
+      buttonContainer.classList.add("onboarding-overlay-attention-dot");
+    } else {
+      buttonContainer.classList.remove("onboarding-overlay-attention-dot");
+    }
+  }
+
   showOverlay() {
     if (this._tourItems.length == 0) {
       // Lazy loading until first toggle.
@@ -1418,6 +1490,7 @@ class Onboarding {
     // After the notification mute on the 1st session,
     // we don't want to show the speech bubble by default
     this._overlayIcon.classList.remove("onboarding-speech-bubble");
+    this.updateAttentionDot();
 
     let queue = this._getNotificationQueue();
     let totalMaxTime = Services.prefs.getIntPref("browser.onboarding.notification.max-life-time-all-tours-ms");



More information about the tor-commits mailing list