Bug 1437446 : Make probe process choice more visible in about:telemetry, r?chutten draft
authorakriti <akriti.v10@gmail.com>
Sat, 09 Jun 2018 17:12:42 +0530
changeset 806351 fe579c3d3004337c9f6c1c70867d0d4b982590d8
parent 782064 ceac91dc08bef5d099c10dda632fc3651b23c897
push id112874
push userbmo:akriti.v10@gmail.com
push dateSat, 09 Jun 2018 11:44:55 +0000
reviewerschutten
bugs1437446
milestone61.0a1
Bug 1437446 : Make probe process choice more visible in about:telemetry, r?chutten MozReview-Commit-ID: 9neQf2PaEI5
toolkit/content/aboutTelemetry.js
--- a/toolkit/content/aboutTelemetry.js
+++ b/toolkit/content/aboutTelemetry.js
@@ -41,16 +41,19 @@ const isWindows = (Services.appinfo.OS =
 const EOL = isWindows ? "\r\n" : "\n";
 
 // This is the ping object currently displayed in the page.
 var gPingData = null;
 
 // Cached value of document's RTL mode
 var documentRTLMode = "";
 
+// Data Collection Processes
+var gOptions = ["parent", "content", "extension", "dynamic", "gpu"];
+
 /**
  * Helper function for determining whether the document direction is RTL.
  * Caches result of check on first invocation.
  */
 function isRTL() {
   if (!documentRTLMode)
     documentRTLMode = window.getComputedStyle(document.body).direction;
   return (documentRTLMode == "rtl");
@@ -1700,35 +1703,58 @@ var AddonDetails = {
 };
 
 var Scalars = {
   /**
    * Render the scalar data - if present - from the payload in a simple key-value table.
    * @param aPayload A payload object to render the data from.
    */
   render(aPayload) {
+    this.scalarSelect("parent", aPayload);
+    this.checkProcessData("scalars-section", aPayload);
+  },
+
+  checkProcessData(aId, aPayload) {
+    let prOptions = [];
+    var i = 0;
+    for (let f of gOptions) {
+      if (f === "parent" && aPayload.scalars) {
+         prOptions[i] = f;
+         i = i + 1;
+      } else if ("processes" in aPayload && f in aPayload.processes &&
+               "scalars" in aPayload.processes[f]) {
+           let scalars = aPayload.processes[f].scalars;
+           if (Object.keys(scalars).length > 0 && scalars) {
+              prOptions[i] = f;
+              i = i + 1;
+           }
+        }
+   }
+
+   addSubSection(aId, aPayload, prOptions, Scalars.scalarSelect);
+
+  },
+
+  scalarSelect(aProcess, aPayload) {
     let scalarsSection = document.getElementById("scalars");
     removeAllChildNodes(scalarsSection);
 
-    let processesSelect = document.getElementById("processes");
-    let selectedProcess = processesSelect.selectedOptions.item(0).getAttribute("value");
-
     if (!aPayload.processes ||
-        !selectedProcess ||
-        !(selectedProcess in aPayload.processes)) {
+        !aProcess ||
+        !(aProcess in aPayload.processes)) {
       return;
     }
 
-    let scalars = aPayload.processes[selectedProcess].scalars || {};
-    let hasData = Array.from(processesSelect.options).some((option) => {
-      let value = option.getAttribute("value");
+    let scalars = aPayload.processes[aProcess].scalars || {};
+    let hasData = gOptions.some((option) => {
+      let value = aProcess;
       let sclrs = aPayload.processes[value].scalars;
       return sclrs && Object.keys(sclrs).length > 0;
     });
-    setHasData("scalars-section", hasData);
+    hasSubsectionData("scalars-section", hasData);
     if (Object.keys(scalars).length > 0) {
       const headings = [
         "namesHeader",
         "valuesHeader",
       ].map(h => bundle.GetStringFromName(h));
       const table = GenericTable.render(explodeObject(scalars), headings);
       scalarsSection.appendChild(table);
     }
@@ -1736,35 +1762,58 @@ var Scalars = {
 };
 
 var KeyedScalars = {
   /**
    * Render the keyed scalar data - if present - from the payload in a simple key-value table.
    * @param aPayload A payload object to render the data from.
    */
   render(aPayload) {
+    this.keyedScalarSelect("parent", aPayload);
+    this.checkProcessData("keyed-scalars-section", aPayload);
+  },
+
+  checkProcessData(aId, aPayload) {
+    let prOptions = [];
+    var i = 0;
+    for (let f of gOptions) {
+      if (f === "parent" && aPayload.keyedScalars) {
+         prOptions[i] = f;
+         i = i + 1;
+      } else if ("processes" in aPayload && f in aPayload.processes &&
+               "keyedScalars" in aPayload.processes[f]) {
+           let keyedScalars = aPayload.processes[f].keyedScalars;
+           if (Object.keys(keyedScalars).length > 0 && keyedScalars) {
+              prOptions[i] = f;
+              i = i + 1;
+           }
+        }
+   }
+
+   addSubSection(aId, aPayload, prOptions, KeyedScalars.keyedScalarSelect);
+
+  },
+
+  keyedScalarSelect(aProcess, aPayload) {
     let scalarsSection = document.getElementById("keyed-scalars");
     removeAllChildNodes(scalarsSection);
 
-    let processesSelect = document.getElementById("processes");
-    let selectedProcess = processesSelect.selectedOptions.item(0).getAttribute("value");
-
     if (!aPayload.processes ||
-        !selectedProcess ||
-        !(selectedProcess in aPayload.processes)) {
+        !aProcess ||
+        !(aProcess in aPayload.processes)) {
       return;
     }
 
-    let keyedScalars = aPayload.processes[selectedProcess].keyedScalars || {};
-    let hasData = Array.from(processesSelect.options).some((option) => {
-      let value = option.getAttribute("value");
+    let keyedScalars = aPayload.processes[aProcess].keyedScalars || {};
+    let hasData = gOptions.some((option) => {
+      let value = aProcess;
       let keyedS = aPayload.processes[value].keyedScalars;
       return keyedS && Object.keys(keyedS).length > 0;
     });
-    setHasData("keyed-scalars-section", hasData);
+    hasSubsectionData("keyed-scalars-section", hasData);
     if (!Object.keys(keyedScalars).length > 0) {
       return;
     }
 
     const headings = [
       "namesHeader",
       "valuesHeader",
     ].map(h => bundle.GetStringFromName(h));
@@ -1786,35 +1835,59 @@ var KeyedScalars = {
 };
 
 var Events = {
   /**
    * Render the event data - if present - from the payload in a simple table.
    * @param aPayload A payload object to render the data from.
    */
   render(aPayload) {
+    this.eventsSelect("parent", aPayload);
+    this.checkProcessData("events-section", aPayload);
+  },
+
+  checkProcessData(aId, aPayload) {
+    let prOptions = [];
+    var i = 0;
+    for (let f of gOptions) {
+      if (f === "parent" && aPayload.events) {
+         prOptions[i] = f;
+         i = i + 1;
+      } else if ("processes" in aPayload && f in aPayload.processes &&
+               "events" in aPayload.processes[f]) {
+           let events = aPayload.processes[f].events;
+           if (Object.keys(events).length > 0 && events) {
+              prOptions[i] = f;
+              i = i + 1;
+           }
+        }
+   }
+
+   addSubSection(aId, aPayload, prOptions, Events.eventsSelect);
+
+  },
+
+   
+  eventsSelect(aProcess, aPayload) {
     let eventsSection = document.getElementById("events");
     removeAllChildNodes(eventsSection);
 
-    let processesSelect = document.getElementById("processes");
-    let selectedProcess = processesSelect.selectedOptions.item(0).getAttribute("value");
-
     if (!aPayload.processes ||
-        !selectedProcess ||
-        !(selectedProcess in aPayload.processes)) {
+        !aProcess ||
+        !(aProcess in aPayload.processes)) {
       return;
     }
 
-    let events = aPayload.processes[selectedProcess].events || {};
-    let hasData = Array.from(processesSelect.options).some((option) => {
-      let value = option.getAttribute("value");
+    let events = aPayload.processes[aProcess].events || {};
+    let hasData = gOptions.some((option) => {
+      let value = aProcess;
       let evts = aPayload.processes[value].events;
       return evts && Object.keys(evts).length > 0;
     });
-    setHasData("events-section", hasData);
+    hasSubsectionData("events-section", hasData);
     if (Object.keys(events).length > 0) {
       const headings = [
         "timestampHeader",
         "categoryHeader",
         "methodHeader",
         "objectHeader",
         "valuesHeader",
         "extraHeader",
@@ -1836,16 +1909,21 @@ function setHasData(aSectionID, aHasData
   let sectionElement = document.getElementById(aSectionID);
   sectionElement.classList[aHasData ? "add" : "remove"]("has-data");
 
   // Display or Hide the section in the sidebar
   let sectionCategory = document.querySelector(".category[value=" + aSectionID + "]");
   sectionCategory.classList[aHasData ? "add" : "remove"]("has-data");
 }
 
+function hasSubsectionData(aSectionID, aHasData) {
+  let sectionElement = document.getElementById(aSectionID);
+  sectionElement.classList[aHasData ? "add" : "remove"]("has-data");
+}
+
 /**
  * Sets the text of the page header based on a config pref + bundle strings
  */
 function setupPageHeader() {
   let serverOwner = Preferences.get(PREF_TELEMETRY_SERVER_OWNER, "Mozilla");
   let brandName = brandBundle.GetStringFromName("brandFullName");
   let subtitleText = bundle.formatStringFromName(
     "pageSubtitle", [serverOwner, brandName], 2);
@@ -1859,28 +1937,16 @@ function setupPageHeader() {
     "https://telemetry.mozilla.org/",
   ];
   let htmlLink = document.querySelectorAll("#home-section > ul > li > a");
   htmlLink.forEach((a, index) => {
     a.href = links[index];
   });
 }
 
-function displayProcessesSelector(selectedSection) {
-  let whitelist = [
-    "scalars-section",
-    "keyed-scalars-section",
-    "histograms-section",
-    "keyed-histograms-section",
-    "events-section"
-  ];
-  let processes = document.getElementById("processes");
-  processes.hidden = !whitelist.includes(selectedSection);
-}
-
 function refreshSearch() {
   removeSearchSectionTitles();
   let selectedSection = document.querySelector(".category.selected").getAttribute("value");
   let search = document.getElementById("search");
   if (!Search.blacklist.includes(selectedSection)) {
     Search.search(search.value);
   }
 }
@@ -1989,21 +2055,56 @@ function show(selected) {
   selected.classList.add("selected");
 
   document.querySelectorAll("section").forEach((section) => {
     section.classList.remove("active");
   });
   selected_section.classList.add("active");
 
   adjustHeaderState();
-  displayProcessesSelector(selectedValue);
   adjustSearchState();
   changeUrlPath(selectedValue);
 }
 
+/**
+ * This function only highlights the selected sub-section by attaching the "selected" class
+ */
+function showSection(aSectionId) {
+  if (!aSectionId) {
+    return;
+  }
+  let current_selection = document.querySelector(".category-subsection.selected");
+  if (current_selection) {
+    current_selection.classList.remove("selected");
+  }
+
+  document.getElementById(aSectionId).classList.add("selected");
+}
+
+/**
+ * Adds sub-sections
+ */
+function addSubSection(aId, aPayload, aProcessList, aCallFunc) {
+  let category = document.querySelector("#categories > [value=" + aId + "]");
+  category.classList.add("has-subsection");
+  for (let f of aProcessList) {
+    let subCategory = document.createElement("div");
+    subCategory.classList.add("category-subsection");
+    subCategory.setAttribute("value", aId + "-" + f);
+    subCategory.setAttribute("id", aId + "-" + f);
+    subCategory.addEventListener("click", () => {
+      let sectionId = aId + "-" + f;
+      showSection(sectionId);
+      aCallFunc(f, aPayload);
+    });
+   subCategory.appendChild(document.createTextNode(f));
+   category.appendChild(subCategory);
+  }
+}
+
 function showSubSection(selected) {
   if (!selected) {
     return;
   }
   let current_selection = document.querySelector(".category-subsection.selected");
   if (current_selection)
     current_selection.classList.remove("selected");
   selected.classList.add("selected");
@@ -2194,74 +2295,121 @@ var LateWritesSingleton = {
     let memoryMap = lateWrites.memoryMap;
     StackRenderer.renderStacks("late-writes", stacks, memoryMap,
                                LateWritesSingleton.renderHeader);
   },
 };
 
 var HistogramSection = {
   render(aPayload) {
+    this.histogramSelect("parent", aPayload);
+    this.checkProcessData("histograms-section", aPayload);
+  },
+
+  checkProcessData(aId, aPayload) {
+    let prOptions = [];
+    var i = 0;
+    for (let f of gOptions) {
+      if (f === "parent" && aPayload.histograms) {
+         prOptions[i] = f;
+         i = i + 1;
+      } else if ("processes" in aPayload && f in aPayload.processes &&
+               "histograms" in aPayload.processes[f]) {
+           let histograms = aPayload.processes[f].histograms;
+           if (Object.keys(histograms).length > 0 && histograms) {
+              prOptions[i] = f;
+              i = i + 1;
+           }
+        }
+   }
+
+   addSubSection(aId, aPayload, prOptions, HistogramSection.histogramSelect);
+
+  },
+
+  histogramSelect(aProcess, aPayload) {
     let hgramDiv = document.getElementById("histograms");
     removeAllChildNodes(hgramDiv);
 
     let histograms = {};
-    let hgramsSelect = document.getElementById("processes");
-    let hgramsOption = hgramsSelect.selectedOptions.item(0);
-    let hgramsProcess = hgramsOption.getAttribute("value");
-
-    if (hgramsProcess === "parent") {
+    
+    if (aProcess === "parent") {
       histograms = aPayload.histograms;
-    } else if ("processes" in aPayload && hgramsProcess in aPayload.processes &&
-               "histograms" in aPayload.processes[hgramsProcess]) {
-      histograms = aPayload.processes[hgramsProcess].histograms;
+    } else if ("processes" in aPayload && aProcess in aPayload.processes &&
+               "histograms" in aPayload.processes[aProcess]) {
+      histograms = aPayload.processes[aProcess].histograms;
     }
 
-    let hasData = Array.from(hgramsSelect.options).some((option) => {
-      let value = option.getAttribute("value");
+    let hasData = gOptions.some((option) => {
+      let value = aProcess;
       if (value == "parent") {
         return Object.keys(aPayload.histograms).length > 0;
       }
       let histos = aPayload.processes[value].histograms;
       return histos && Object.keys(histos).length > 0;
     });
-    setHasData("histograms-section", hasData);
+    hasSubsectionData("histograms-section", hasData);
 
     if (Object.keys(histograms).length > 0) {
       for (let [name, hgram] of Object.entries(histograms)) {
         Histogram.render(hgramDiv, name, hgram, {unpacked: true});
       }
     }
   },
 };
 
 var KeyedHistogramSection = {
   render(aPayload) {
+    this.keyedHistogramSelect("parent", aPayload);
+    this.checkProcessData("keyed-histograms-section", aPayload);
+  },
+
+  checkProcessData(aId, aPayload) {
+    let prOptions = [];
+    var i = 0;
+    for (let f of gOptions) {
+      if (f === "parent" && aPayload.keyedHistograms) {
+         prOptions[i] = f;
+         i = i + 1;
+      } else if ("processes" in aPayload && f in aPayload.processes &&
+               "keyedHistograms" in aPayload.processes[f]) {
+           let keyedHistograms = aPayload.processes[f].keyedHistograms;
+           if (Object.keys(keyedHistograms).length > 0 && keyedHistograms) {
+              prOptions[i] = f;
+              i = i + 1;
+           }
+        }
+   }
+
+   addSubSection(aId, aPayload, prOptions, KeyedHistogramSection.keyedHistogramSelect);
+
+  },
+
+  keyedHistogramSelect(aProcess, aPayload) {
     let keyedDiv = document.getElementById("keyed-histograms");
     removeAllChildNodes(keyedDiv);
 
     let keyedHistograms = {};
-    let keyedHgramsSelect = document.getElementById("processes");
-    let keyedHgramsOption = keyedHgramsSelect.selectedOptions.item(0);
-    let keyedHgramsProcess = keyedHgramsOption.getAttribute("value");
-    if (keyedHgramsProcess === "parent") {
+    
+    if (aProcess === "parent") {
       keyedHistograms = aPayload.keyedHistograms;
-    } else if ("processes" in aPayload && keyedHgramsProcess in aPayload.processes &&
-               "keyedHistograms" in aPayload.processes[keyedHgramsProcess]) {
-      keyedHistograms = aPayload.processes[keyedHgramsProcess].keyedHistograms;
+    } else if ("processes" in aPayload && aProcess in aPayload.processes &&
+               "keyedHistograms" in aPayload.processes[aProcess]) {
+      keyedHistograms = aPayload.processes[aProcess].keyedHistograms;
     }
 
-    let hasData = Array.from(keyedHgramsSelect.options).some((option) => {
-      let value = option.getAttribute("value");
+    let hasData = gOptions.some((option) => {
+      let value = aProcess;
       if (value == "parent") {
         return Object.keys(aPayload.keyedHistograms).length > 0;
       }
-      let keyedHistos = aPayload.processes[value].keyedHistograms;
-      return keyedHistos && Object.keys(keyedHistos).length > 0;
+      let histos = aPayload.processes[value].keyedHistograms;
+      return histos && Object.keys(histos).length > 0;
     });
-    setHasData("keyed-histograms-section", hasData);
+    hasSubsectionData("keyed-histograms-section", hasData);
     if (Object.keys(keyedHistograms).length > 0) {
       for (let [id, keyed] of Object.entries(keyedHistograms)) {
         if (Object.keys(keyed).length > 0) {
           KeyedHistogram.render(keyedDiv, id, keyed, {unpacked: true});
         }
       }
     }
   },