--- 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 pOptions = ["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,60 @@ 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);
+ let sectionid = "scalars-section";
+ this.checkProcessData(sectionid, aPayload);
+ },
+
+ checkProcessData(id, aPayload) {
+ let prOptions = [];
+ var i = 0;
+ for (let f of pOptions) {
+ if (f === "parent") {
+ 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(id, aPayload, prOptions, Scalars.scalarSelect);
+ },
+
+ scalarSelect(hprocess, aPayload) {
let scalarsSection = document.getElementById("scalars");
removeAllChildNodes(scalarsSection);
- let processesSelect = document.getElementById("processes");
- let selectedProcess = processesSelect.selectedOptions.item(0).getAttribute("value");
+ let selectedProcess = hprocess;
+ let scalarOptions = pOptions;
if (!aPayload.processes ||
!selectedProcess ||
!(selectedProcess in aPayload.processes)) {
return;
}
let scalars = aPayload.processes[selectedProcess].scalars || {};
- let hasData = Array.from(processesSelect.options).some((option) => {
- let value = option.getAttribute("value");
+ let hasData = scalarOptions.some((option) => {
+ let value = selectedProcess;
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 +1764,59 @@ 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);
+ let sectionid = "keyed-scalars-section";
+ this.checkProcessData(sectionid, aPayload);
+ },
+
+ checkProcessData(id, aPayload) {
+ let prOptions = [];
+ var i = 0;
+ for (let f of pOptions) {
+ if (f === "parent") {
+ 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(id, aPayload, prOptions, KeyedScalars.keyedScalarSelect);
+ },
+ keyedScalarSelect(hprocess, aPayload) {
let scalarsSection = document.getElementById("keyed-scalars");
removeAllChildNodes(scalarsSection);
- let processesSelect = document.getElementById("processes");
- let selectedProcess = processesSelect.selectedOptions.item(0).getAttribute("value");
+ let selectedProcess = hprocess;
+ let keyedScalarOptions = pOptions;
if (!aPayload.processes ||
!selectedProcess ||
!(selectedProcess in aPayload.processes)) {
return;
}
let keyedScalars = aPayload.processes[selectedProcess].keyedScalars || {};
- let hasData = Array.from(processesSelect.options).some((option) => {
- let value = option.getAttribute("value");
+ let hasData = keyedScalarOptions.some((option) => {
+ let value = selectedProcess;
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));
@@ -1836,16 +1888,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);
@@ -1861,20 +1918,16 @@ function setupPageHeader() {
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();
@@ -1994,16 +2047,50 @@ function show(selected) {
selected_section.classList.add("active");
adjustHeaderState();
displayProcessesSelector(selectedValue);
adjustSearchState();
changeUrlPath(selectedValue);
}
+/**
+ * Shows the selected sub-section
+ */
+function showSection(sectionid) {
+ if (!sectionid) {
+ return;
+ }
+ let current_selection = document.querySelector(".category-subsection.selected");
+ if (current_selection)
+ current_selection.classList.remove("selected");
+ document.getElementById(sectionid).classList.add("selected");
+}
+
+/**
+ * Adds sub-sections
+ */
+function addSubSection(id, aPayload, processList, callFunc) {
+ let category = document.querySelector("#categories > [value=" + id + "]");
+ category.classList.add("has-subsection");
+ for (let f of processList) {
+ let subCategory = document.createElement("div");
+ subCategory.classList.add("category-subsection");
+ subCategory.setAttribute("value", id + "-" + f);
+ subCategory.setAttribute("id", id + "-" + f);
+ subCategory.addEventListener("click", () => {
+ let sectionId = id + "-" + f;
+ showSection(sectionId);
+ callFunc(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 +2281,123 @@ var LateWritesSingleton = {
let memoryMap = lateWrites.memoryMap;
StackRenderer.renderStacks("late-writes", stacks, memoryMap,
LateWritesSingleton.renderHeader);
},
};
var HistogramSection = {
render(aPayload) {
+ this.histogramSelect("parent", aPayload);
+ let sectionid = "histograms-section";
+ this.checkProcessData(sectionid, aPayload);
+ },
+
+ checkProcessData(id, aPayload) {
+ let prOptions = [];
+ var i = 0;
+ for (let f of pOptions) {
+ if (f === "parent") {
+ 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(id, aPayload, prOptions, HistogramSection.histogramSelect);
+ },
+
+ histogramSelect(hprocess, 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");
+ let hgramsProcess = hprocess;
+ let hgramsOptions = pOptions;
if (hgramsProcess === "parent") {
histograms = aPayload.histograms;
} else if ("processes" in aPayload && hgramsProcess in aPayload.processes &&
"histograms" in aPayload.processes[hgramsProcess]) {
histograms = aPayload.processes[hgramsProcess].histograms;
}
- let hasData = Array.from(hgramsSelect.options).some((option) => {
- let value = option.getAttribute("value");
+ let hasData = hgramsOptions.some((option) => {
+ let value = hgramsProcess;
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);
+ let sectionid = "keyed-histograms-section";
+ this.checkProcessData(sectionid, aPayload);
+ },
+
+ checkProcessData(id, aPayload) {
+ let prOptions = [];
+ var i = 0;
+ for (let f of pOptions) {
+ if (f === "parent") {
+ 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(id, aPayload, prOptions, KeyedHistogramSection.keyedHistogramSelect);
+ },
+
+ keyedHistogramSelect(hprocess, 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");
+ let keyedHgramsProcess = hprocess;
+ let keyedHgramsOptions = pOptions;
+
if (keyedHgramsProcess === "parent") {
keyedHistograms = aPayload.keyedHistograms;
} else if ("processes" in aPayload && keyedHgramsProcess in aPayload.processes &&
"keyedHistograms" in aPayload.processes[keyedHgramsProcess]) {
keyedHistograms = aPayload.processes[keyedHgramsProcess].keyedHistograms;
}
- let hasData = Array.from(keyedHgramsSelect.options).some((option) => {
- let value = option.getAttribute("value");
+ let hasData = keyedHgramsOptions.some((option) => {
+ let value = keyedHgramsProcess;
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});
}
}
}
},