--- 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 gProcessTypes = ["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");
@@ -274,18 +277,17 @@ var PingPicker = {
let pingPicker = document.getElementById("ping-picker");
pingPicker.addEventListener("mouseenter", () => pingPickerNeedHide = false);
pingPicker.addEventListener("mouseleave", () => pingPickerNeedHide = true);
document.addEventListener("click", (ev) => {
if (pingPickerNeedHide) {
pingPicker.classList.add("hidden");
}
});
- document.getElementById("processes")
- .addEventListener("change", () => displayPingData(gPingData));
+
Array.from(document.querySelectorAll(".change-ping")).forEach(el => {
el.addEventListener("click", (event) => {
if (!pingPicker.classList.contains("hidden")) {
pingPicker.classList.add("hidden");
} else {
pingPicker.classList.remove("hidden");
event.stopPropagation();
}
@@ -1700,31 +1702,52 @@ 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.addSubsectionsForProcessData("scalars-section", aPayload);
+ },
+
+ addSubsectionsForProcessData(aId, aPayload) {
+ let processNames = [];
+ for (let processType of gProcessTypes) {
+ if (processType === "parent" && aPayload.scalars) {
+ processNames.push(processType);
+ } else if ("processes" in aPayload &&
+ processType in aPayload.processes &&
+ "scalars" in aPayload.processes[processType]) {
+ let scalars = aPayload.processes[processType].scalars;
+ if (Object.keys(scalars).length > 0 && scalars) {
+ processNames.push(processType);
+ }
+ }
+ }
+
+ addSubSection(aId, aPayload, processNames, 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 = gProcessTypes.some((option) => {
+ let value = aProcess;
let sclrs = aPayload.processes[value].scalars;
return sclrs && Object.keys(sclrs).length > 0;
});
setHasData("scalars-section", hasData);
if (Object.keys(scalars).length > 0) {
const headings = [
"namesHeader",
"valuesHeader",
@@ -1736,31 +1759,52 @@ 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.addSubsectionsForProcessData("keyed-scalars-section", aPayload);
+ },
+
+ addSubsectionsForProcessData(aId, aPayload) {
+ let processNames = [];
+ for (let processType of gProcessTypes) {
+ if (processType === "parent" && aPayload.keyedScalars) {
+ processNames.push(processType);
+ } else if ("processes" in aPayload &&
+ processType in aPayload.processes &&
+ "keyedScalars" in aPayload.processes[processType]) {
+ let keyedScalars = aPayload.processes[processType].keyedScalars;
+ if (Object.keys(keyedScalars).length > 0 && keyedScalars) {
+ processNames.push(processType);
+ }
+ }
+ }
+
+ addSubSection(aId, aPayload, processNames, 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 = gProcessTypes.some((option) => {
+ let value = aProcess;
let keyedS = aPayload.processes[value].keyedScalars;
return keyedS && Object.keys(keyedS).length > 0;
});
setHasData("keyed-scalars-section", hasData);
if (!Object.keys(keyedScalars).length > 0) {
return;
}
@@ -1786,31 +1830,52 @@ 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.addSubsectionsForProcessData("events-section", aPayload);
+ },
+
+ addSubsectionsForProcessData(aId, aPayload) {
+ let processNames = [];
+ for (let processType of gProcessTypes) {
+ if (processType === "parent" && aPayload.events) {
+ processNames.push(processType);
+ } else if ("processes" in aPayload &&
+ processType in aPayload.processes &&
+ "events" in aPayload.processes[processType]) {
+ let events = aPayload.processes[processType].events;
+ if (Object.keys(events).length > 0 && events) {
+ processNames.push(processType);
+ }
+ }
+ }
+
+ addSubSection(aId, aPayload, processNames, 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 = gProcessTypes.some((option) => {
+ let value = aProcess;
let evts = aPayload.processes[value].events;
return evts && Object.keys(evts).length > 0;
});
setHasData("events-section", hasData);
if (Object.keys(events).length > 0) {
const headings = [
"timestampHeader",
"categoryHeader",
@@ -1859,28 +1924,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 +2042,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, aProcessNames, aCallFunc) {
+ let category = document.querySelector("#categories > [value=" + aId + "]");
+ category.classList.add("has-subsection");
+ for (let f of aProcessNames) {
+ 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,33 +2282,54 @@ var LateWritesSingleton = {
let memoryMap = lateWrites.memoryMap;
StackRenderer.renderStacks("late-writes", stacks, memoryMap,
LateWritesSingleton.renderHeader);
},
};
var HistogramSection = {
render(aPayload) {
+ this.histogramSelect("parent", aPayload);
+ this.addSubsectionsForProcessData("histograms-section", aPayload);
+ },
+
+ addSubsectionsForProcessData(aId, aPayload) {
+ let processNames = [];
+ for (let processType of gProcessTypes) {
+ if (processType === "parent" && aPayload.histograms) {
+ processNames.push(processType);
+ } else if ("processes" in aPayload &&
+ processType in aPayload.processes &&
+ "histograms" in aPayload.processes[processType]) {
+ let histograms = aPayload.processes[processType].histograms;
+ if (Object.keys(histograms).length > 0 && histograms) {
+ processNames.push(processType);
+ }
+ }
+ }
+
+ addSubSection(aId, aPayload, processNames, 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 = gProcessTypes.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);
@@ -2229,32 +2338,54 @@ var HistogramSection = {
Histogram.render(hgramDiv, name, hgram, {unpacked: true});
}
}
},
};
var KeyedHistogramSection = {
render(aPayload) {
+ this.keyedHistogramSelect("parent", aPayload);
+ this.addSubsectionsForProcessData("keyed-histograms-section", aPayload);
+ },
+
+ addSubsectionsForProcessData(aId, aPayload) {
+ let processNames = [];
+ for (let processType of gProcessTypes) {
+ if (processType === "parent" && aPayload.keyedHistograms) {
+ processNames.push(processType);
+ } else if ("processes" in aPayload &&
+ processType in aPayload.processes &&
+ "keyedHistograms" in aPayload.processes[processType]) {
+ let keyedHistograms = aPayload.processes[processType].keyedHistograms;
+ if (Object.keys(keyedHistograms).length > 0 && keyedHistograms) {
+ processNames.push(processType);
+ }
+ }
+ }
+
+ addSubSection(aId, aPayload, processNames, 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 = gProcessTypes.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;
});
setHasData("keyed-histograms-section", hasData);
if (Object.keys(keyedHistograms).length > 0) {
@@ -2338,43 +2469,16 @@ var SimpleMeasurements = {
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;
- selectEl.appendChild(option);
-
- if (!("processes" in ping.payload)) {
- selectEl.disabled = true;
- return;
- }
- selectEl.disabled = false;
-
- for (let process of Object.keys(ping.payload.processes)) {
- // TODO: parent hgrams are on root payload, not in payload.processes.parent
- // When/If that gets moved, you'll need to remove this
- if (process === "parent") {
- continue;
- }
- option = document.createElement("option");
- option.appendChild(document.createTextNode(process));
- option.setAttribute("value", process);
- selectEl.appendChild(option);
- }
-}
-
function togglePingSections(isMainPing) {
// We always show the sections that are "common" to all pings.
let commonSections = new Set(["heading",
"home-section",
"general-data-section",
"environment-data-section",
"raw-json-viewer"]);
@@ -2401,21 +2505,16 @@ function displayPingData(ping, updatePay
refreshSearch();
} catch (err) {
console.log(err);
PingPicker._showRawPingData();
}
}
function displayRichPingData(ping, updatePayloadList) {
- // Update the payload list and process lists
- if (updatePayloadList) {
- renderProcessList(ping, document.getElementById("processes"));
- }
-
// Show general data.
GeneralData.render(ping);
// Show environment data.
EnvironmentData.render(ping);
RawPayloadData.render(ping);