Bug 1370513 - Add an explanation text on about:telemetry homepage r?chutten draft
authorflyingrub <flyinggrub@gmail.com>
Mon, 12 Jun 2017 18:52:17 +0200
changeset 599051 6789f6766955498fe6ceb0fbf439c21f1220732b
parent 599050 160b9343ae5a3d951e7be39b193072cef537281d
child 599052 6f957069278aaf506f98f3862a155b7d0ee01776
child 599745 18514f82886be5ff8347145a14217dbf91d486ee
child 599762 6fb8a6ee6a6d4eef3c8590562b84e338499ac74a
push id65412
push userbmo:flyinggrub@gmail.com
push dateThu, 22 Jun 2017 16:37:42 +0000
reviewerschutten
bugs1370513
milestone56.0a1
Bug 1370513 - Add an explanation text on about:telemetry homepage r?chutten MozReview-Commit-ID: Bu0durfGC5R
toolkit/content/aboutTelemetry.css
toolkit/content/aboutTelemetry.js
toolkit/content/aboutTelemetry.xhtml
toolkit/locales/en-US/chrome/global/aboutTelemetry.dtd
toolkit/locales/en-US/chrome/global/aboutTelemetry.properties
--- a/toolkit/content/aboutTelemetry.css
+++ b/toolkit/content/aboutTelemetry.css
@@ -12,25 +12,27 @@ body {
   display: flex;
   align-items: stretch;
   height: 100%;
 }
 
 #categories {
   padding-top: 0px;
   min-width: 300px;
+  overflow-y: auto;
 }
 
 #category-raw {
   border-top: 1px solid var(--in-content-header-border-color);
   box-sizing: border-box;
-  position: fixed;
+  background-color: inherit;
+  min-width: inherit;
+  position: absolute;
   bottom: 0;
   left: 0;
-  min-width: inherit;
 }
 
 .heading {
   padding-inline-start: 21px;
   padding-inline-end: 21px;
   color: var(--in-content-category-text);
 }
 
@@ -45,40 +47,51 @@ body {
 }
 
 .category-name {
   pointer-events: none;
 }
 
 .main-content {
   width: 100%;
+  font-size: 18px;
+  line-height:1.6;
 }
 
 #page-description {
   border: 1px solid threedshadow;
   margin: 0px;
   padding: 10px;
+  line-height: 1.2;
 }
 
 #settings {
   border: 1px solid lightgrey;
   padding: 5px;
 }
 
-.description-enabled,
-.description-disabled {
-  margin: 0px;
+.change-data-choices-link {
+  border-bottom-width: 2px;
+  border-bottom-style: solid;
+}
+
+.change-data-choices-link:hover {
+  text-decoration: none;
 }
 
-.description-enabled > span {
-  color: green;
+#ping-explanation > span {
+  cursor: pointer;
+  border-bottom-width: 2px;
+  border-bottom-style: solid;
 }
 
-.description-disabled > span {
-  color: red;
+#ping-explanation > span:hover {
+  color: var(--in-content-page-color);
+  border-bottom-width: 2px;
+  border-bottom-style: solid;
 }
 
 #ping-picker {
   margin-top: 10px;
   border: 1px solid lightgrey;
   padding: 5px;
 }
 
--- a/toolkit/content/aboutTelemetry.js
+++ b/toolkit/content/aboutTelemetry.js
@@ -201,25 +201,21 @@ function shortTimeString(date) {
 }
 
 var Settings = {
   SETTINGS: [
     // data upload
     {
       pref: PREF_FHR_UPLOAD_ENABLED,
       defaultPrefValue: false,
-      descriptionEnabledId: "description-upload-enabled",
-      descriptionDisabledId: "description-upload-disabled",
     },
     // extended "Telemetry" recording
     {
       pref: PREF_TELEMETRY_ENABLED,
       defaultPrefValue: false,
-      descriptionEnabledId: "description-extended-recording-enabled",
-      descriptionDisabledId: "description-extended-recording-disabled",
     },
   ],
 
   attachObservers() {
     for (let s of this.SETTINGS) {
       let setting = s;
       Preferences.observe(setting.pref, this.render, this);
     }
@@ -243,33 +239,39 @@ var Settings = {
   },
 
   detachObservers() {
     for (let setting of this.SETTINGS) {
       Preferences.ignore(setting.pref, this.render, this);
     }
   },
 
+  getStatusStringForSetting(setting) {
+    let enabled = Preferences.get(setting.pref, setting.defaultPrefValue);
+    let status = bundle.GetStringFromName(enabled ? "enabled" : "disabled");
+    return status;
+  },
+
   /**
    * Updates the button & text at the top of the page to reflect Telemetry state.
    */
   render() {
-    for (let setting of this.SETTINGS) {
-      let enabledElement = document.getElementById(setting.descriptionEnabledId);
-      let disabledElement = document.getElementById(setting.descriptionDisabledId);
+    let homeExplanation = document.getElementById("home-explanation");
+    let fhrEnabled = this.getStatusStringForSetting(this.SETTINGS[0]);
+    let extendedEnabled = this.getStatusStringForSetting(this.SETTINGS[1]);
+    let parameters = [fhrEnabled, extendedEnabled].map(this.convertStringToLink);
 
-      if (Preferences.get(setting.pref, setting.defaultPrefValue)) {
-        enabledElement.hidden = false;
-        disabledElement.hidden = true;
-      } else {
-        enabledElement.hidden = true;
-        disabledElement.hidden = false;
-      }
-    }
-  }
+    let explanation = bundle.formatStringFromName("homeExplanation", parameters, 2);
+    homeExplanation.innerHTML = explanation;
+    this.attachObservers()
+  },
+
+  convertStringToLink(string) {
+    return "<a href=\"\" class=\"change-data-choices-link\">" + string + "</a>";
+  },
 };
 
 var PingPicker = {
   viewCurrentPingData: null,
   _archivedPings: null,
 
   attachObservers() {
     let elements = document.getElementsByName("choose-ping-source");
@@ -315,16 +317,27 @@ var PingPicker = {
   onPingSourceChanged() {
     this.update();
   },
 
   onPingDisplayChanged() {
     this.update();
   },
 
+  render() {
+    let pings = bundle.GetStringFromName("pings");
+    let pingLink = "<a href=\"http://gecko.readthedocs.io/en/latest/toolkit/components/telemetry/telemetry/concepts/pings.html\">&quot;" + pings + "&quot;</a>";
+    let pingName = "<span class=\"change-ping\">" + this._getSelectedPingName() + "</span>";
+
+    let explanation = bundle.formatStringFromName("pingExplanation", [pingLink, pingName], 2);
+    let pingExplanation = document.getElementById("ping-explanation");
+    pingExplanation.innerHTML = explanation;
+    this.attachObservers();
+  },
+
   async update() {
     let viewCurrent = document.getElementById("ping-source-current").checked;
     let currentChanged = viewCurrent !== this.viewCurrentPingData;
     this.viewCurrentPingData = viewCurrent;
 
     // If we have no archived pings, disable the ping archive selection.
     // This can happen on new profiles or if the ping archive is disabled.
     let archivedPingList = await TelemetryArchive.promiseArchivedPingList();
@@ -337,16 +350,17 @@ var PingPicker = {
         document.getElementById("archived-ping-picker").hidden = true;
         this._updateCurrentPingData();
       } else {
         document.getElementById("current-ping-picker").hidden = true;
         await this._updateArchivedPingList(archivedPingList);
         document.getElementById("archived-ping-picker").hidden = false;
       }
     }
+    this.render();
   },
 
   _updateCurrentPingData() {
     const subsession = document.getElementById("show-subsession-data").checked;
     const ping = TelemetryController.getCurrentPingData(subsession);
     if (!ping) {
       return;
     }
@@ -440,16 +454,24 @@ var PingPicker = {
       option.setAttribute("value", p.id);
       if (id && p.id == id) {
         option.selected = true;
       }
       pingSelector.appendChild(option);
     }
   },
 
+  _getSelectedPingName() {
+    if (this.viewCurrentPingData) return "current";
+
+    let pingSelector = document.getElementById("choose-ping-id");
+    let selected = pingSelector.selectedOptions.item(0);
+    return selected.textContent;
+  },
+
   _getSelectedPingId() {
     let pingSelector = document.getElementById("choose-ping-id");
     let selected = pingSelector.selectedOptions.item(0);
     return selected.getAttribute("value");
   },
 
   _movePingIndex(offset) {
     const id = this._getSelectedPingId();
@@ -510,17 +532,17 @@ var EnvironmentData = {
     setHasData("environment-data-section", hasData);
     if (!hasData) {
       return;
     }
 
     let ignore = ["addons"];
     let env = filterObject(ping.environment, ignore);
     let sections = sectionalizeObject(env);
-    GenericSubsection.render(sections, dataDiv);
+    GenericSubsection.render(sections, dataDiv, "environment-data-section");
 
     // We use specialized rendering here to make the addon and plugin listings
     // more readable.
     this.createAddonSection(dataDiv, ping);
   },
 
   renderPersona(addonObj, addonSection, sectionTitle) {
     let table = document.createElement("table");
@@ -599,17 +621,17 @@ var EnvironmentData = {
     this.renderAddonsObject(addons.activeAddons, addonSection, "activeAddons");
     this.renderActivePlugins(addons.activePlugins, addonSection, "activePlugins");
     this.renderKeyValueObject(addons.theme, addonSection, "theme");
     this.renderKeyValueObject(addons.activeExperiment, addonSection, "activeExperiment");
     this.renderAddonsObject(addons.activeGMPlugins, addonSection, "activeGMPlugins");
     this.renderPersona(addons, addonSection, "persona");
 
     let hasAddonData = Object.keys(ping.environment.addons).length > 0;
-    let s = GenericSubsection.renderSubsectionHeader("addons", hasAddonData);
+    let s = GenericSubsection.renderSubsectionHeader("addons", hasAddonData, "environment-data-section");
     s.appendChild(addonSection);
     dataDiv.appendChild(s);
   },
 
   appendRow(table, id, value) {
     let row = document.createElement("tr");
     this.appendColumn(row, "td", id);
     this.appendColumn(row, "td", value);
@@ -1354,56 +1376,40 @@ function RenderObject(aObject) {
   for (let i = 1; i < keys.length; i++) {
     output += ", \"" + keys[i] + "\":\u00A0" + JSON.stringify(aObject[keys[i]]);
   }
   return output + "}";
 }
 
 var GenericSubsection = {
 
-  render(data, dataDiv) {
+  addSubSectionToSidebar(id, title) {
+    let category = document.querySelector("#categories > [value=" + id + "]");
+    let subCategory = document.createElement("div");
+    subCategory.setAttribute("class", "subsection");
+    subCategory.appendChild(document.createTextNode(title))
+    category.appendChild(subCategory);
+  },
+
+  render(data, dataDiv, sectionID) {
     for (let [title, sectionData] of data) {
       let hasData = sectionData.size > 0;
-      let s = this.renderSubsectionHeader(title, hasData);
+      let s = this.renderSubsectionHeader(title, hasData, sectionID);
       s.appendChild(this.renderSubsectionData(sectionData));
       dataDiv.appendChild(s);
     }
   },
 
-  renderSubsectionHeader(title, hasData) {
+  renderSubsectionHeader(title, hasData, sectionID) {
+    this.addSubSectionToSidebar(sectionID, title);
     let section = document.createElement("section");
     section.classList.add("data-subsection");
     if (hasData) {
       section.classList.add("has-subdata");
     }
-
-    // Create section heading
-    let sectionName = document.createElement("h2");
-    sectionName.setAttribute("class", "section-name");
-    sectionName.appendChild(document.createTextNode(title));
-    sectionName.addEventListener("click", toggleSection);
-
-    // Create caption for toggling the subsection visibility.
-    let toggleCaption = document.createElement("span");
-    toggleCaption.setAttribute("class", "toggle-caption");
-    let toggleText = bundle.GetStringFromName("environmentDataSubsectionToggle");
-    toggleCaption.appendChild(document.createTextNode(" " + toggleText));
-    toggleCaption.addEventListener("click", toggleSection);
-
-    // Create caption for empty subsections.
-    let emptyCaption = document.createElement("span");
-    emptyCaption.setAttribute("class", "empty-caption");
-    let emptyText = bundle.GetStringFromName("environmentDataSubsectionEmpty");
-    emptyCaption.appendChild(document.createTextNode(" " + emptyText));
-
-    // Append elements
-    section.appendChild(sectionName);
-    section.appendChild(toggleCaption);
-    section.appendChild(emptyCaption);
-
     return section;
   },
 
   renderSubsectionData(data) {
     // Create data container
     let dataDiv = document.createElement("div");
     dataDiv.setAttribute("class", "subsection-data subdata");
     // Instanciate the data
--- a/toolkit/content/aboutTelemetry.xhtml
+++ b/toolkit/content/aboutTelemetry.xhtml
@@ -94,37 +94,18 @@
       <div class="header">
           <div id="sectionTitle" class="header-name">
               &aboutTelemetry.pageTitle;
           </div>
       </div>
       <div id="home" class="tab active">
 
         <h3 id="page-subtitle"></h3>
-
-        <table id="settings">
-          <tr>
-            <td>
-              <p id="description-upload-enabled" class="description-enabled">&aboutTelemetry.uploadEnabled;</p>
-              <p id="description-upload-disabled" class="description-disabled">&aboutTelemetry.uploadDisabled;</p>
-            </td>
-            <td>
-              <a href="" class="change-data-choices-link">&aboutTelemetry.changeDataChoices;</a>
-            </td>
-          </tr>
-          <tr>
-            <td>
-              <p id="description-extended-recording-enabled" class="description-enabled">&aboutTelemetry.extendedRecordingEnabled;</p>
-              <p id="description-extended-recording-disabled" class="description-disabled">&aboutTelemetry.extendedRecordingDisabled;</p>
-            </td>
-            <td>
-              <a href="" class="change-data-choices-link">&aboutTelemetry.changeDataChoices;</a>
-            </td>
-          </tr>
-        </table>
+        <p id="home-explanation"></p>
+        <p id="ping-explanation"></p>
 
         <div id="ping-picker">
           <div id="ping-source-picker">
             &aboutTelemetry.pingDataSource;<br/>
             <input type="radio" id="ping-source-current" name="choose-ping-source" value="current" checked="checked" />
             &aboutTelemetry.showCurrentPingData;<br />
             <input type="radio" id="ping-source-archive" name="choose-ping-source" value="archive" />
             &aboutTelemetry.showArchivedPingData;<br />
--- a/toolkit/locales/en-US/chrome/global/aboutTelemetry.dtd
+++ b/toolkit/locales/en-US/chrome/global/aboutTelemetry.dtd
@@ -3,32 +3,16 @@
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
 <!ENTITY aboutTelemetry.pageTitle "Telemetry Data">
 
 <!ENTITY aboutTelemetry.changeDataChoices "
   Change
 ">
 
-<!ENTITY aboutTelemetry.uploadEnabled "
-  FHR data upload is <span>enabled</span>.
-">
-
-<!ENTITY aboutTelemetry.uploadDisabled "
-  FHR data upload is <span>disabled</span>.
-">
-
-<!ENTITY aboutTelemetry.extendedRecordingEnabled "
-  Extended Telemetry recording is <span>enabled</span>.
-">
-
-<!ENTITY aboutTelemetry.extendedRecordingDisabled "
-  Extended Telemetry recording is <span>disabled</span>.
-">
-
 <!ENTITY aboutTelemetry.pingDataSource "
 Ping data source:
 ">
 
 <!ENTITY aboutTelemetry.showCurrentPingData "
 Current ping data
 ">
 
--- a/toolkit/locales/en-US/chrome/global/aboutTelemetry.properties
+++ b/toolkit/locales/en-US/chrome/global/aboutTelemetry.properties
@@ -2,16 +2,32 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 # Note to translators:
 # - %1$S will be replaced by brandFullName
 # - %2$S will be replaced with the value of the toolkit.telemetry.server_owner preference
 pageSubtitle = This page shows the information about performance, hardware, usage and customizations collected by Telemetry. This information is submitted to %1$S to help improve %2$S.
 
+# Note to translators:
+# - %1$S will be replaced by either enabled or disabled
+# - %2$S will be replaced by either enabled or disabled
+homeExplanation = Telemetry is %1$S and extended telemetry is %2$S.
+
+# Note to translators:
+# - %1$S will be replaced by a link with "pings" as text
+# - %2$S will be replaced by the ping name
+pingExplanation = Each piece of information is sent bundled into %1$S. You are looking at the %2$S ping.
+
+pings = pings
+
+enabled = enabled
+
+disabled = disabled
+
 generalDataTitle = General Data
 
 environmentDataSubsectionToggle = Click to toggle section
 
 environmentDataSubsectionEmpty = (No data collected)
 
 telemetryLogTitle = Telemetry Log