Bug 1385350 - Add a Search on the home of about:telemetry r?chutten
This allow to search in any section for data.
MozReview-Commit-ID: D0aWj427Mhf
--- a/toolkit/content/aboutTelemetry.css
+++ b/toolkit/content/aboutTelemetry.css
@@ -15,16 +15,20 @@ body {
}
#categories {
min-width: 250px;
padding-top: 0px;
overflow-y: auto;
}
+.main-content.search > section > *:not(.data) {
+ display: none;
+}
+
#category-raw {
background-color: var(--in-content-page-background);
box-sizing: border-box;
min-width: inherit;
position: absolute;
bottom: 0;
left: 0;
}
--- a/toolkit/content/aboutTelemetry.js
+++ b/toolkit/content/aboutTelemetry.js
@@ -1384,55 +1384,78 @@ var Search = {
searchHandler(e) {
if (this.idleTimeout) {
clearTimeout(this.idleTimeout);
}
this.idleTimeout = setTimeout(() => Search.search(e.target.value), FILTER_IDLE_TIMEOUT);
},
- search(text) {
- let selectedSection = document.querySelector("section.active");
- if (selectedSection.id === "histograms-section") {
- let histograms = selectedSection.getElementsByClassName("histogram");
+ search(text, section = null) {
+ if (!section) {
+ let sectionId = document.querySelector(".category.selected").getAttribute("value");
+ section = document.getElementById(sectionId);
+ }
+ if (section.id === "home-section") {
+ this.homeSearch(text);
+ } else if (section.id === "histograms-section") {
+ let histograms = section.getElementsByClassName("histogram");
this.filterElements(histograms, text);
- } else if (selectedSection.id === "keyed-histograms-section") {
+ } else if (section.id === "keyed-histograms-section") {
let keyedElements = [];
- let keyedHistograms = selectedSection.getElementsByClassName("keyed-histogram");
+ let keyedHistograms = section.getElementsByClassName("keyed-histogram");
for (let key of keyedHistograms) {
let datas = key.getElementsByClassName("histogram");
keyedElements.push({key, datas});
}
this.filterKeyedElements(keyedElements, text);
- } else if (selectedSection.id === "keyed-scalars-section") {
+ } else if (section.id === "keyed-scalars-section") {
let keyedElements = [];
- let keyedScalars = selectedSection.getElementsByClassName("keyed-scalar");
+ let keyedScalars = section.getElementsByClassName("keyed-scalar");
for (let key of keyedScalars) {
let datas = key.querySelector("table").rows;
keyedElements.push({key, datas});
}
this.filterKeyedElements(keyedElements, text);
- } else if (selectedSection.id === "thread-hang-stats-section") {
- let keyedElements = [];
- let threads = selectedSection.children[0].children;
- for (let key of threads) {
- let datas = key.getElementsByClassName("histogram");
- keyedElements.push({key, datas});
- }
- this.filterKeyedElements(keyedElements, text);
} else {
- let tables = selectedSection.querySelectorAll("table");
+ let tables = section.querySelectorAll("table");
for (let table of tables) {
let allElementsHidden = this.filterElements(table.rows, text);
if (table.caption) {
table.caption.hidden = allElementsHidden;
}
}
}
},
+
+ resetHome() {
+ document.getElementById("main").classList.remove("search");
+ adjustHeaderState();
+ Array.from(document.querySelectorAll("section")).forEach((section) => {
+ section.classList.toggle("active", section.id == "home-section");
+ });
+ },
+
+ homeSearch(text) {
+ if (text === "") {
+ this.resetHome();
+ return;
+ }
+ document.getElementById("main").classList.add("search");
+ let title = bundle.formatStringFromName("resultsForSearch", [text], 1);
+ adjustHeaderState(title);
+ Array.from(document.querySelectorAll("section")).forEach((section) => {
+ if (section.id == "home-section" || section.id == "raw-payload-section") {
+ section.classList.remove("active");
+ return;
+ }
+ section.classList.add("active");
+ this.search(text, section);
+ });
+ }
}
/*
* Helper function to render JS objects with white space between top level elements
* so that they look better in the browser
* @param aObject JavaScript object or array to render
* @return String
*/
@@ -1625,24 +1648,24 @@ var AddonDetails = {
let addonDetails = aPing.payload.addonDetails;
const hasData = addonDetails && Object.keys(addonDetails).length > 0;
setHasData("addon-details-section", hasData);
if (!hasData) {
return;
}
for (let provider in addonDetails) {
- let providerSection = document.createElement("h2");
+ let providerSection = document.createElement("caption");
let titleText = bundle.formatStringFromName("addonProvider", [provider], 1);
providerSection.appendChild(document.createTextNode(titleText));
- addonSection.appendChild(providerSection);
let headingStrings = [this.tableIDTitle, this.tableDetailsTitle ]
let table = GenericTable.render(explodeObject(addonDetails[provider]),
headingStrings);
+ table.appendChild(providerSection);
addonSection.appendChild(table);
}
},
};
var Scalars = {
/**
* Render the scalar data - if present - from the payload in a simple key-value table.
@@ -1805,37 +1828,44 @@ function displayProcessesSelector(select
"keyed-histograms-section",
"events-section"
];
let processes = document.getElementById("processes");
processes.hidden = !whitelist.includes(selectedSection);
}
function adjustSearchState() {
- let selectedSection = document.querySelector("section.active").id;
+ let selectedSection = document.querySelector(".category.selected").getAttribute("value");
let blacklist = [
- "home-section",
"raw-payload-section"
];
- // TODO: Implement global search for the Home section
let search = document.getElementById("search");
search.hidden = blacklist.includes(selectedSection);
// Filter element on section change.
if (!blacklist.includes(selectedSection)) {
Search.search(search.value);
}
}
function adjustSection() {
let selectedCategory = document.querySelector(".category.selected");
if (!selectedCategory.classList.contains("has-data")) {
PingPicker._showStructuredPingData();
}
}
+function adjustHeaderState(title = null) {
+ let selected = document.querySelector(".category.selected .category-name");
+ let selectedTitle = selected.textContent.trim();
+ document.getElementById("sectionTitle").textContent = title ? title : selectedTitle;
+ let search = document.getElementById("search");
+ let placeholder = bundle.formatStringFromName("filterPlaceholder", [ selectedTitle ], 1);
+ search.setAttribute("placeholder", placeholder);
+}
+
/**
* Change the url according to the current section displayed
* e.g about:telemetry#general-data
*/
function changeUrlPath(selectedSection, subSection) {
if (subSection) {
let hash = window.location.hash.split("_")[0] + "_" + selectedSection;
window.location.hash = hash;
@@ -1849,46 +1879,44 @@ function changeUrlPath(selectedSection,
*/
function show(selected) {
let selectedValue = selected.getAttribute("value");
if (selectedValue === "raw-json-viewer") {
openJsonInFirefoxJsonViewer(JSON.stringify(gPingData, null, 2));
return;
}
- let current_button = document.querySelector(".category.selected");
- current_button.classList.remove("selected");
- if (current_button.classList.contains("has-subsection")) {
- for (let subsection of current_button.children) {
+ let selected_section = document.getElementById(selectedValue);
+ let subsections = selected_section.querySelectorAll(".sub-section");
+ if (selected.classList.contains("has-subsection")) {
+ for (let subsection of selected.children) {
subsection.classList.remove("selected");
}
}
- selected.classList.add("selected");
- // Hack because subsection text appear selected. See Bug 1375114.
- document.getSelection().empty();
-
- let current_section = document.querySelector("section.active");
- let selected_section = document.getElementById(selectedValue);
- let subsections = current_section.querySelectorAll(".sub-section");
if (subsections) {
for (let subsection of subsections) {
subsection.hidden = false;
}
}
- if (current_section == selected_section)
+
+ let current_button = document.querySelector(".category.selected");
+ if (current_button == selected)
return;
- current_section.classList.remove("active");
+ current_button.classList.remove("selected");
+ selected.classList.add("selected");
+
+ document.querySelectorAll("section").forEach((section) => {
+ section.classList.remove("active")
+ });
selected_section.classList.add("active");
- let title = selected.querySelector(".category-name").textContent.trim();
- document.getElementById("sectionTitle").textContent = title;
+ // Hack because subsection text appear selected. See Bug 1375114.
+ document.getSelection().empty();
- let search = document.getElementById("search");
- let placeholder = bundle.formatStringFromName("filterPlaceholder", [ title ], 1);
- search.setAttribute("placeholder", placeholder);
+ adjustHeaderState();
displayProcessesSelector(selectedValue);
adjustSearchState();
changeUrlPath(selectedValue);
}
function showSubSection(selected) {
let current_selection = document.querySelector(".category-subsection.selected");
if (current_selection)
@@ -2030,16 +2058,18 @@ function onLoad() {
setupPageHeader();
// Set up event listeners
setupListeners();
// Render settings.
Settings.render();
+ adjustHeaderState();
+
// Update ping data when async Telemetry init is finished.
Telemetry.asyncFetchTelemetryData(async () => {
await PingPicker.update();
urlStateRestore();
});
}
var LateWritesSingleton = {
--- a/toolkit/content/aboutTelemetry.xhtml
+++ b/toolkit/content/aboutTelemetry.xhtml
@@ -84,17 +84,17 @@
<div class="category has-data" value="raw-payload-section">
<span class="category-name">&aboutTelemetry.rawPayloadSection;</span>
</div>
<div id="category-raw" class="category has-data" value="raw-json-viewer">
<span class="category-name">&aboutTelemetry.raw;</span>
</div>
</div>
- <div class="main-content">
+ <div id="main" class="main-content">
<div id="ping-picker" class="hidden">
<div id="ping-source-picker">
<h4 class="title">&aboutTelemetry.pingDataSource;</h4>
<div>
<input type="radio" id="ping-source-current" name="choose-ping-source" value="current" checked="checked" />
&aboutTelemetry.showCurrentPingData;
</div>
@@ -129,17 +129,17 @@
<select id="choose-payload"></select>
</div>
</div>
<div class="header">
<div id="sectionTitle" class="header-name">
&aboutTelemetry.pageTitle;
</div>
- <input type="text" id="search" placeholder="" hidden="true"/>
+ <input type="text" id="search" placeholder=""/>
<select id="processes" hidden="true"></select>
</div>
<section id="home-section" class="active">
<h3 id="page-subtitle"></h3>
<p id="home-explanation"></p>
<p id="ping-explanation"></p>
</section>
@@ -185,19 +185,18 @@
<div id="simple-measurements" class="data"></div>
</section>
<section id="telemetry-log-section">
<div id="telemetry-log" class="data"></div>
</section>
<section id="slow-sql-section">
- <div id="slow-sql-tables" class="data">
- <p id="sql-warning" class="hidden">&aboutTelemetry.fullSqlWarning;</p>
- </div>
+ <p id="sql-warning" class="hidden">&aboutTelemetry.fullSqlWarning;</p>
+ <div id="slow-sql-tables" class="data"></div>
</section>
<section id="chrome-hangs-section">
<a id="chrome-hangs-fetch-symbols" href="">&aboutTelemetry.fetchStackSymbols;</a>
<a id="chrome-hangs-hide-symbols" class="hidden" href="">&aboutTelemetry.hideStackSymbols;</a>
<div id="chrome-hangs" class="data"></div>
</section>
--- a/toolkit/locales/en-US/chrome/global/aboutTelemetry.properties
+++ b/toolkit/locales/en-US/chrome/global/aboutTelemetry.properties
@@ -37,16 +37,20 @@ extendedTelemetryEnabled = enabled
extendedTelemetryDisabled = disabled
currentPing = current
# Used as a tooltip for the "current" ping title in the sidebar
currentPingSidebar = current ping
+# Note to translators:
+# - %1$S will be replaced by the current text in the search input
+resultsForSearch = Results for ā%1$Sā
+
telemetryPingTypeAll = all
telemetryLogTitle = Telemetry Log
telemetryLogHeadingId = Id
telemetryLogHeadingTimestamp = Timestamp