Bug 1368667 - Move Section Specific code to their own objects r=chutten
authorflyingrub <flyinggrub@gmail.com>
Wed, 31 May 2017 14:38:11 +0200
changeset 410185 dfd1b819e2040673e47352cfa6aa58d7b36242b9
parent 410184 0eef7d224f45f05f4843730c9ec055d2378f77ba
child 410186 d91ee7347dce732a5ac39f488536c5d43ef92c37
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerschutten
bugs1368667
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1368667 - Move Section Specific code to their own objects r=chutten Most of the sections were already in their own object. This fixes the one that are not. MozReview-Commit-ID: 92lAtwYwbDl
toolkit/content/aboutTelemetry.js
--- a/toolkit/content/aboutTelemetry.js
+++ b/toolkit/content/aboutTelemetry.js
@@ -1506,23 +1506,29 @@ var KeyValueTable = {
       let valueField = document.createElement("td");
       valueField.appendChild(document.createTextNode(value + "\n"));
       newRow.appendChild(valueField);
     }
   }
 };
 
 var GenericTable = {
+
+  defaultHeadings: [
+    bundle.GetStringFromName("keysHeader"),
+    bundle.GetStringFromName("valuesHeader")
+  ],
+
   /**
    * Returns a n-column table.
    * @param rows An array of arrays, each containing data to render
    *             for one row.
    * @param headings The column header strings.
    */
-  render(rows, headings) {
+  render(rows, headings = this.defaultHeadings) {
     let table = document.createElement("table");
     this.renderHeader(table, headings);
     this.renderBody(table, rows);
     return table;
   },
 
   /**
    * Create the table header.
@@ -1568,17 +1574,17 @@ var GenericTable = {
 
       for (let i = 0; i < row.length; ++i) {
         let suffix = (i == (row.length - 1)) ? "\n" : "\t";
         let field = document.createElement("td");
         field.appendChild(document.createTextNode(row[i] + suffix));
         newRow.appendChild(field);
       }
     }
-  }
+  },
 };
 
 var KeyedHistogram = {
   render(parent, id, keyedHistogram) {
     let outerDiv = document.createElement("div");
     outerDiv.className = "keyed-histogram";
     outerDiv.id = id;
 
@@ -1618,17 +1624,17 @@ var AddonDetails = {
       let providerSection = document.createElement("h2");
       let titleText = bundle.formatStringFromName("addonProvider", [provider], 1);
       providerSection.appendChild(document.createTextNode(titleText));
       addonSection.appendChild(providerSection);
       addonSection.appendChild(
         KeyValueTable.render(addonDetails[provider],
                              this.tableIDTitle, this.tableDetailsTitle));
     }
-  }
+  },
 };
 
 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) {
@@ -1650,17 +1656,17 @@ var Scalars = {
     if (!hasData) {
       return;
     }
 
     const headingName = bundle.GetStringFromName("namesHeader");
     const headingValue = bundle.GetStringFromName("valuesHeader");
     const table = KeyValueTable.render(scalars, headingName, headingValue);
     scalarsSection.appendChild(table);
-  }
+  },
 };
 
 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) {
@@ -1689,17 +1695,17 @@ var KeyedScalars = {
       // Add the name of the scalar.
       let scalarNameSection = document.createElement("h2");
       scalarNameSection.appendChild(document.createTextNode(scalar));
       scalarsSection.appendChild(scalarNameSection);
       // Populate the section with the key-value pairs from the scalar.
       const table = KeyValueTable.render(keyedScalars[scalar], headingName, headingValue);
       scalarsSection.appendChild(table);
     }
-  }
+  },
 };
 
 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) {
@@ -1732,17 +1738,17 @@ var Events = {
       "methodHeader",
       "objectHeader",
       "valuesHeader",
       "extraHeader",
     ].map(h => bundle.GetStringFromName(h));
 
     const table = GenericTable.render(events, headings);
     eventsSection.appendChild(table);
-  }
+  },
 };
 
 /**
  * Helper function for showing either the toggle element or "No data collected" message for a section
  *
  * @param aSectionID ID of the section element that needs to be changed
  * @param aHasData true (default) indicates that toggle should be displayed
  */
@@ -1912,62 +1918,186 @@ var LateWritesSingleton = {
     if (!lateWrites) {
       return;
     }
 
     let stacks = lateWrites.stacks;
     let memoryMap = lateWrites.memoryMap;
     StackRenderer.renderStacks("late-writes", stacks, memoryMap,
                                LateWritesSingleton.renderHeader);
-  }
+  },
 };
 
-/**
- * Helper function for sorting the startup milestones in the Simple Measurements
- * section into temporal order.
- *
- * @param aSimpleMeasurements Telemetry ping's "Simple Measurements" data
- * @return Sorted measurements
- */
-function sortStartupMilestones(aSimpleMeasurements) {
-  const telemetryTimestamps = TelemetryTimestamps.get();
-  let startupEvents = Services.startup.getStartupInfo();
-  delete startupEvents["process"];
+var HistogramSection = {
+  render(aPayload) {
+    let hgramDiv = document.getElementById("histograms");
+    removeAllChildNodes(hgramDiv);
+
+    let histograms = aPayload.histograms;
+
+    let hgramsSelect = document.getElementById("histograms-processes");
+    let hgramsOption = hgramsSelect.selectedOptions.item(0);
+    let hgramsProcess = hgramsOption.getAttribute("value");
+    // "parent" histograms/keyedHistograms aren't under "parent". Fix that up.
+    if (hgramsProcess === "parent") {
+      hgramsProcess = "";
+    }
+    if (hgramsProcess &&
+        "processes" in aPayload &&
+        hgramsProcess in aPayload.processes) {
+      histograms = aPayload.processes[hgramsProcess].histograms;
+    }
+
+    let hasData = Object.keys(histograms).length > 0;
+    setHasData("histograms-section", hasData || hgramsSelect.options.length);
+
+    if (hasData) {
+      for (let [name, hgram] of Object.entries(histograms)) {
+        Histogram.render(hgramDiv, name, hgram, {unpacked: true});
+      }
+
+      let filterBox = document.getElementById("histograms-filter");
+      filterBox.addEventListener("input", Histogram.histogramFilterChanged);
+      if (filterBox.value.trim() != "") { // on load, no need to filter if empty
+        Histogram.filterHistograms(hgramDiv, filterBox.value);
+      }
+
+      setHasData("histograms-section", true);
+    }
+  },
+}
 
-  function keyIsMilestone(k) {
-    return (k in startupEvents) || (k in telemetryTimestamps);
-  }
+var KeyedHistogramSection = {
+  render(aPayload) {
+    let keyedDiv = document.getElementById("keyed-histograms");
+    removeAllChildNodes(keyedDiv);
+
+    let keyedHistograms = aPayload.keyedHistograms;
 
-  let sortedKeys = Object.keys(aSimpleMeasurements);
+    let keyedHgramsSelect = document.getElementById("keyed-histograms-processes");
+    let keyedHgramsOption = keyedHgramsSelect.selectedOptions.item(0);
+    let keyedHgramsProcess = keyedHgramsOption.getAttribute("value");
+    // "parent" histograms/keyedHistograms aren't under "parent". Fix that up.
+    if (keyedHgramsProcess === "parent") {
+      keyedHgramsProcess = "";
+    }
+    if (keyedHgramsProcess &&
+        "processes" in aPayload &&
+        keyedHgramsProcess in aPayload.processes) {
+      keyedHistograms = aPayload.processes[keyedHgramsProcess].keyedHistograms;
+    }
+
+    setHasData("keyed-histograms-section", keyedHgramsSelect.options.length);
+    if (keyedHistograms) {
+      let hasData = false;
+      for (let [id, keyed] of Object.entries(keyedHistograms)) {
+        if (Object.keys(keyed).length > 0) {
+          hasData = true;
+          KeyedHistogram.render(keyedDiv, id, keyed, {unpacked: true});
+        }
+      }
+      setHasData("keyed-histograms-section", hasData || keyedHgramsSelect.options.length);
+    }
+  },
+}
+
+var AddonHistogramSection = {
+  render(aPayload) {
+    let addonDiv = document.getElementById("addon-histograms");
+    removeAllChildNodes(addonDiv);
 
-  // Sort the measurements, with startup milestones at the front + ordered by time
-  sortedKeys.sort(function keyCompare(keyA, keyB) {
-    let isKeyAMilestone = keyIsMilestone(keyA);
-    let isKeyBMilestone = keyIsMilestone(keyB);
+    let addonHistogramsRendered = false;
+    let addonData = aPayload.addonHistograms;
+    if (addonData) {
+      for (let [addon, histograms] of Object.entries(addonData)) {
+        for (let [name, hgram] of Object.entries(histograms)) {
+          addonHistogramsRendered = true;
+          Histogram.render(addonDiv, addon + ": " + name, hgram, {unpacked: true});
+        }
+      }
+    }
+
+    setHasData("addon-histograms-section", addonHistogramsRendered);
+  },
+}
+
+var SessionInformation = {
+  render(aPayload) {
+    let infoSection = document.getElementById("session-info");
+    removeAllChildNodes(infoSection);
+
+    let hasData = Object.keys(aPayload.info).length > 0;
+    setHasData("session-info-section", hasData);
+
+    if (hasData) {
+      const table = GenericTable.render(explodeObject(aPayload.info));
+      infoSection.appendChild(table);
+    }
+  },
+}
+
+var SimpleMeasurements = {
+  render(aPayload) {
+    let simpleSection = document.getElementById("simple-measurements");
+    removeAllChildNodes(simpleSection);
+
+    let simpleMeasurements = this.sortStartupMilestones(aPayload.simpleMeasurements);
+    let hasData = Object.keys(simpleMeasurements).length > 0;
+    setHasData("simple-measurements-section", hasData);
+
+    if (hasData) {
+      const table = GenericTable.render(explodeObject(simpleMeasurements));
+      simpleSection.appendChild(table);
+    }
+  },
 
-    // First order by startup vs non-startup measurement
-    if (isKeyAMilestone && !isKeyBMilestone)
-      return -1;
-    if (!isKeyAMilestone && isKeyBMilestone)
-      return 1;
-    // Don't change order of non-startup measurements
-    if (!isKeyAMilestone && !isKeyBMilestone)
-      return 0;
+  /**
+   * Helper function for sorting the startup milestones in the Simple Measurements
+   * section into temporal order.
+   *
+   * @param aSimpleMeasurements Telemetry ping's "Simple Measurements" data
+   * @return Sorted measurements
+   */
+  sortStartupMilestones(aSimpleMeasurements) {
+    const telemetryTimestamps = TelemetryTimestamps.get();
+    let startupEvents = Services.startup.getStartupInfo();
+    delete startupEvents["process"];
+
+    function keyIsMilestone(k) {
+      return (k in startupEvents) || (k in telemetryTimestamps);
+    }
+
+    let sortedKeys = Object.keys(aSimpleMeasurements);
 
-    // If both keys are startup measurements, order them by value
-    return aSimpleMeasurements[keyA] - aSimpleMeasurements[keyB];
-  });
+    // Sort the measurements, with startup milestones at the front + ordered by time
+    sortedKeys.sort(function keyCompare(keyA, keyB) {
+      let isKeyAMilestone = keyIsMilestone(keyA);
+      let isKeyBMilestone = keyIsMilestone(keyB);
 
-  // Insert measurements into a result object in sort-order
-  let result = {};
-  for (let key of sortedKeys) {
-    result[key] = aSimpleMeasurements[key];
-  }
+      // First order by startup vs non-startup measurement
+      if (isKeyAMilestone && !isKeyBMilestone)
+        return -1;
+      if (!isKeyAMilestone && isKeyBMilestone)
+        return 1;
+      // Don't change order of non-startup measurements
+      if (!isKeyAMilestone && !isKeyBMilestone)
+        return 0;
 
-  return result;
+      // If both keys are startup measurements, order them by value
+      return aSimpleMeasurements[keyA] - aSimpleMeasurements[keyB];
+    });
+
+    // Insert measurements into a result object in sort-order
+    let result = {};
+    for (let key of sortedKeys) {
+      result[key] = aSimpleMeasurements[key];
+    }
+
+    return result;
+  },
 }
 
 function renderProcessList(ping, selectEl) {
   removeAllChildNodes(selectEl);
   let option = document.createElement("option");
   option.appendChild(document.createTextNode("parent"));
   option.setAttribute("value", "parent");
   option.selected = true;
@@ -2059,20 +2189,16 @@ function displayPingData(ping, updatePay
   try {
     displayRichPingData(ping, updatePayloadList);
   } catch (err) {
     PingPicker._showRawPingData();
   }
 }
 
 function displayRichPingData(ping, updatePayloadList) {
-  // Update the structured data rendering.
-  const keysHeader = bundle.GetStringFromName("keysHeader");
-  const valuesHeader = bundle.GetStringFromName("valuesHeader");
-
   // Update the payload list and process lists
   if (updatePayloadList) {
     renderPayloadList(ping);
     renderProcessList(ping, document.getElementById("scalars-processes"));
     renderProcessList(ping, document.getElementById("keyed-scalars-processes"));
     renderProcessList(ping, document.getElementById("histograms-processes"));
     renderProcessList(ping, document.getElementById("keyed-histograms-processes"));
     renderProcessList(ping, document.getElementById("events-processes"));
@@ -2118,125 +2244,33 @@ function displayRichPingData(ping, updat
 
   // Show thread hang stats
   ThreadHangStats.render(payload);
 
   // Show captured stacks.
   CapturedStacks.render(payload);
 
   // Show simple measurements
-  let simpleMeasurements = sortStartupMilestones(payload.simpleMeasurements);
-  let hasData = Object.keys(simpleMeasurements).length > 0;
-  setHasData("simple-measurements-section", hasData);
-  let simpleSection = document.getElementById("simple-measurements");
-  removeAllChildNodes(simpleSection);
-
-  if (hasData) {
-    simpleSection.appendChild(KeyValueTable.render(simpleMeasurements,
-                                                   keysHeader, valuesHeader));
-  }
+  SimpleMeasurements.render(payload);
 
   LateWritesSingleton.renderLateWrites(payload.lateWrites);
 
   // Show basic session info gathered
-  hasData = Object.keys(ping.payload.info).length > 0;
-  setHasData("session-info-section", hasData);
-  let infoSection = document.getElementById("session-info");
-  removeAllChildNodes(infoSection);
-
-  if (hasData) {
-    infoSection.appendChild(KeyValueTable.render(ping.payload.info,
-                                                 keysHeader, valuesHeader));
-  }
+  SessionInformation.render(payload);
 
   // Show scalar data.
   Scalars.render(payload);
   KeyedScalars.render(payload);
 
   // Show histogram data
-  let hgramDiv = document.getElementById("histograms");
-  removeAllChildNodes(hgramDiv);
-
-  let histograms = payload.histograms;
-
-  let hgramsSelect = document.getElementById("histograms-processes");
-  let hgramsOption = hgramsSelect.selectedOptions.item(0);
-  let hgramsProcess = hgramsOption.getAttribute("value");
-  // "parent" histograms/keyedHistograms aren't under "parent". Fix that up.
-  if (hgramsProcess === "parent") {
-    hgramsProcess = "";
-  }
-  if (hgramsProcess &&
-      "processes" in ping.payload &&
-      hgramsProcess in ping.payload.processes) {
-    histograms = ping.payload.processes[hgramsProcess].histograms;
-  }
-
-  hasData = Object.keys(histograms).length > 0;
-  setHasData("histograms-section", hasData || hgramsSelect.options.length);
-
-  if (hasData) {
-    for (let [name, hgram] of Object.entries(histograms)) {
-      Histogram.render(hgramDiv, name, hgram, {unpacked: true});
-    }
-
-    let filterBox = document.getElementById("histograms-filter");
-    filterBox.addEventListener("input", Histogram.histogramFilterChanged);
-    if (filterBox.value.trim() != "") { // on load, no need to filter if empty
-      Histogram.filterHistograms(hgramDiv, filterBox.value);
-    }
-
-    setHasData("histograms-section", true);
-  }
+  HistogramSection.render(payload);
 
   // Show keyed histogram data
-  let keyedDiv = document.getElementById("keyed-histograms");
-  removeAllChildNodes(keyedDiv);
-
-  let keyedHistograms = payload.keyedHistograms;
-
-  let keyedHgramsSelect = document.getElementById("keyed-histograms-processes");
-  let keyedHgramsOption = keyedHgramsSelect.selectedOptions.item(0);
-  let keyedHgramsProcess = keyedHgramsOption.getAttribute("value");
-  // "parent" histograms/keyedHistograms aren't under "parent". Fix that up.
-  if (keyedHgramsProcess === "parent") {
-    keyedHgramsProcess = "";
-  }
-  if (keyedHgramsProcess &&
-      "processes" in ping.payload &&
-      keyedHgramsProcess in ping.payload.processes) {
-    keyedHistograms = ping.payload.processes[keyedHgramsProcess].keyedHistograms;
-  }
-
-  setHasData("keyed-histograms-section", keyedHgramsSelect.options.length);
-  if (keyedHistograms) {
-    let hasData = false;
-    for (let [id, keyed] of Object.entries(keyedHistograms)) {
-      if (Object.keys(keyed).length > 0) {
-        hasData = true;
-        KeyedHistogram.render(keyedDiv, id, keyed, {unpacked: true});
-      }
-    }
-    setHasData("keyed-histograms-section", hasData || keyedHgramsSelect.options.length);
-  }
+  KeyedHistogramSection.render(payload);
 
   // Show event data.
   Events.render(payload);
 
   // Show addon histogram data
-  let addonDiv = document.getElementById("addon-histograms");
-  removeAllChildNodes(addonDiv);
-
-  let addonHistogramsRendered = false;
-  let addonData = payload.addonHistograms;
-  if (addonData) {
-    for (let [addon, histograms] of Object.entries(addonData)) {
-      for (let [name, hgram] of Object.entries(histograms)) {
-        addonHistogramsRendered = true;
-        Histogram.render(addonDiv, addon + ": " + name, hgram, {unpacked: true});
-      }
-    }
-  }
-
-  setHasData("addon-histograms-section", addonHistogramsRendered);
+  AddonHistogramSection.render(payload);
 }
 
 window.addEventListener("load", onLoad);