Bug 1302663 - Part 4 - Add event rendering to about:telemetry. r=dexter
☠☠ backed out by 89d19198a0de ☠ ☠
authorGeorg Fritzsche <georg.fritzsche@googlemail.com>
Sun, 13 Nov 2016 01:52:29 +0700
changeset 349039 a4471f64e67a13257db4ebaa68b8de6595acff01
parent 349038 574bf5f49185f8fd4d89aa4daac3ea73677b78d2
child 349040 89d19198a0de6d839a1b2b390f9fc50dc9aa78ef
push id10298
push userraliiev@mozilla.com
push dateMon, 14 Nov 2016 12:33:03 +0000
treeherdermozilla-aurora@7e29173b1641 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdexter
bugs1302663
milestone52.0a1
Bug 1302663 - Part 4 - Add event rendering to about:telemetry. r=dexter
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.js
+++ b/toolkit/content/aboutTelemetry.js
@@ -1498,16 +1498,82 @@ var KeyValueTable = {
 
       let valueField = document.createElement("td");
       valueField.appendChild(document.createTextNode(value + "\n"));
       newRow.appendChild(valueField);
     }
   }
 };
 
+var GenericTable = {
+  /**
+   * 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: function(rows, headings) {
+    let table = document.createElement("table");
+    this.renderHeader(table, headings);
+    this.renderBody(table, rows);
+    return table;
+  },
+
+  /**
+   * Create the table header.
+   * Tabs & newlines added to cells to make it easier to copy-paste.
+   *
+   * @param table Table element
+   * @param headings Array of column header strings.
+   */
+  renderHeader: function(table, headings) {
+    let headerRow = document.createElement("tr");
+    table.appendChild(headerRow);
+
+    for (let i = 0; i < headings.length; ++i) {
+      let suffix = (i == (headings.length - 1)) ? "\n" : "\t";
+      let column = document.createElement("th");
+      column.appendChild(document.createTextNode(headings[i] + suffix));
+      headerRow.appendChild(column);
+    }
+  },
+
+  /**
+   * Create the table body
+   * Tabs & newlines added to cells to make it easier to copy-paste.
+   *
+   * @param table Table element
+   * @param rows An array of arrays, each containing data to render
+   *             for one row.
+   */
+  renderBody: function(table, rows) {
+    for (let row of rows) {
+      row = row.map(value => {
+        // use .valueOf() to unbox Number, String, etc. objects
+        if (value &&
+           (typeof value == "object") &&
+           (typeof value.valueOf() == "object")) {
+          return RenderObject(value);
+        }
+        return value;
+      });
+
+      let newRow = document.createElement("tr");
+      table.appendChild(newRow);
+
+      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: function(parent, id, keyedHistogram) {
     let outerDiv = document.createElement("div");
     outerDiv.className = "keyed-histogram";
     outerDiv.id = id;
 
     let divTitle = document.createElement("div");
     divTitle.className = "keyed-histogram-title";
@@ -1609,16 +1675,50 @@ var KeyedScalars = {
       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: function(aPayload) {
+    let eventsSection = document.getElementById("events");
+    removeAllChildNodes(eventsSection);
+
+    if (!aPayload.processes || !aPayload.processes.parent) {
+      return;
+    }
+
+    const events = aPayload.processes.parent.events;
+    const hasData = events && Object.keys(events).length > 0;
+    setHasData("events-section", hasData);
+    if (!hasData) {
+      return;
+    }
+
+    const headings = [
+      "timestampHeader",
+      "categoryHeader",
+      "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
  */
 function setHasData(aSectionID, aHasData) {
   let sectionElement = document.getElementById(aSectionID);
@@ -2046,16 +2146,19 @@ function displayPingData(ping, updatePay
       if (Object.keys(keyed).length > 0) {
         hasData = true;
         KeyedHistogram.render(keyedDiv, id, keyed, {unpacked: true});
       }
     }
     setHasData("keyed-histograms-section", hasData || keyedHgramsSelect.options.length);
   }
 
+  // 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)) {
--- a/toolkit/content/aboutTelemetry.xhtml
+++ b/toolkit/content/aboutTelemetry.xhtml
@@ -175,16 +175,25 @@
         <span class="empty-caption">&aboutTelemetry.emptySection;</span>
         <div class="processes-ui">
           <select id="keyed-histograms-processes" class="process-picker"></select>
         </div>
         <div id="keyed-histograms" class="data">
         </div>
       </section>
 
+      <section id="events-section" class="data-section">
+        <input type="checkbox" class="statebox"/>
+        <h1 class="section-name">&aboutTelemetry.eventsSection;</h1>
+        <span class="toggle-caption">&aboutTelemetry.toggle;</span>
+        <span class="empty-caption">&aboutTelemetry.emptySection;</span>
+        <div id="events" class="data">
+        </div>
+      </section>
+
       <section id="simple-measurements-section" class="data-section">
         <input type="checkbox" class="statebox"/>
         <h1 class="section-name">&aboutTelemetry.simpleMeasurementsSection;</h1>
         <span class="toggle-caption">&aboutTelemetry.toggle;</span>
         <span class="empty-caption">&aboutTelemetry.emptySection;</span>
         <div id="simple-measurements" class="data">
         </div>
       </section>
--- a/toolkit/locales/en-US/chrome/global/aboutTelemetry.dtd
+++ b/toolkit/locales/en-US/chrome/global/aboutTelemetry.dtd
@@ -111,16 +111,20 @@ Ping
 <!ENTITY aboutTelemetry.histogramsSection "
   Histograms
 ">
 
 <!ENTITY aboutTelemetry.keyedHistogramsSection "
   Keyed Histograms
 ">
 
+<!ENTITY aboutTelemetry.eventsSection "
+  Events
+">
+
 <!ENTITY aboutTelemetry.simpleMeasurementsSection "
   Simple Measurements
 ">
 
 <!ENTITY aboutTelemetry.addonDetailsSection "
   Add-on Details
 ">
 
--- a/toolkit/locales/en-US/chrome/global/aboutTelemetry.properties
+++ b/toolkit/locales/en-US/chrome/global/aboutTelemetry.properties
@@ -76,8 +76,18 @@ addonTableDetails = Details
 # - The %1$S will be replaced with the name of an Add-on Provider (e.g. "XPI", "Plugin")
 addonProvider = %1$S Provider
 
 parentPayload = Parent Payload
 
 # Note to translators:
 # - The %1$S will be replaced with the number of the child payload (e.g. "1", "2")
 childPayloadN = Child Payload %1$S
+
+timestampHeader = timestamp
+
+categoryHeader = category
+
+methodHeader = method
+
+objectHeader = object
+
+extraHeader = extra