зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1754772 - Add a button to get Places database stats to about:support r=mak,fluent-reviewers
Incorporates the "Places Database Statistics" table from `chrome://browser/content/places/interactionsViewer.html` into the `about:support` page, under the existing "Places Database" table. The table is hidden by default, and it can be toggled on/off using a button. Table contents will always be part of the "Copy text to clipboard" export, regardless of visibility. Try Job: https://treeherder.mozilla.org/jobs?revision=923a9df8c477f6e2b1f0a2fee3b0291ddbdd32e3&repo=try Initial state: {F4177493} After clicking "Show Statistics": {F4177495} Text export: {F4177496} Differential Revision: https://phabricator.services.mozilla.com/D158200
This commit is contained in:
Родитель
9f3ba3cc58
Коммит
29347cf647
|
@ -144,3 +144,47 @@ add_task(async function test_remote_configuration() {
|
|||
|
||||
await doCleanup();
|
||||
});
|
||||
|
||||
add_task(async function test_places_db_stats_table() {
|
||||
await BrowserTestUtils.withNewTab(
|
||||
{ gBrowser, url: "about:support" },
|
||||
async function(browser) {
|
||||
const [
|
||||
initialToggleText,
|
||||
toggleTextAfterShow,
|
||||
toggleTextAfterHide,
|
||||
] = await SpecialPowers.spawn(browser, [], async function() {
|
||||
const toggleButton = content.document.getElementById(
|
||||
"place-database-stats-toggle"
|
||||
);
|
||||
const getToggleText = () =>
|
||||
content.document.l10n.getAttributes(toggleButton).id;
|
||||
const toggleTexts = [];
|
||||
const table = content.document.getElementById(
|
||||
"place-database-stats-tbody"
|
||||
);
|
||||
await ContentTaskUtils.waitForCondition(
|
||||
() => table.style.display === "none",
|
||||
"Stats table is hidden initially"
|
||||
);
|
||||
toggleTexts.push(getToggleText());
|
||||
toggleButton.click();
|
||||
await ContentTaskUtils.waitForCondition(
|
||||
() => table.style.display === "",
|
||||
"Stats table is shown after first toggle"
|
||||
);
|
||||
toggleTexts.push(getToggleText());
|
||||
toggleButton.click();
|
||||
await ContentTaskUtils.waitForCondition(
|
||||
() => table.style.display === "none",
|
||||
"Stats table is hidden after second toggle"
|
||||
);
|
||||
toggleTexts.push(getToggleText());
|
||||
return toggleTexts;
|
||||
});
|
||||
Assert.equal(initialToggleText, "place-database-stats-show");
|
||||
Assert.equal(toggleTextAfterShow, "place-database-stats-hide");
|
||||
Assert.equal(toggleTextAfterHide, "place-database-stats-show");
|
||||
}
|
||||
);
|
||||
});
|
||||
|
|
|
@ -430,26 +430,7 @@ const placesStatsHandler = new (class extends TableViewer {
|
|||
* Loads the current metadata from the database and updates the display.
|
||||
*/
|
||||
async updateDisplay() {
|
||||
let stats = await PlacesDBUtils.getEntitiesStats();
|
||||
let data = [];
|
||||
let db = await PlacesUtils.promiseDBConnection();
|
||||
for (let [entity, value] of stats) {
|
||||
let count = "-";
|
||||
try {
|
||||
if (
|
||||
entity.startsWith("moz_") &&
|
||||
!entity.endsWith("index") &&
|
||||
entity != "moz_places_visitcount" /* bug in index name */
|
||||
) {
|
||||
count = (
|
||||
await db.execute(`SELECT count(*) FROM ${entity}`)
|
||||
)[0].getResultByIndex(0);
|
||||
}
|
||||
} catch (ex) {
|
||||
console.error(ex);
|
||||
}
|
||||
data.push(Object.assign(value, { entity, count }));
|
||||
}
|
||||
let data = await PlacesDBUtils.getEntitiesStatsAndCounts();
|
||||
this.displayData(data);
|
||||
}
|
||||
})();
|
||||
|
|
|
@ -1371,6 +1371,38 @@ export var PlacesDBUtils = {
|
|||
return entitiesByName;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets detailed statistics about database entities and their respective row
|
||||
* counts.
|
||||
* @returns {Array} An array that augments each object returned by
|
||||
* {@link getEntitiesStats} with the following extra properties:
|
||||
* - entity: name of the entity
|
||||
* - count: row count of the entity
|
||||
*/
|
||||
async getEntitiesStatsAndCounts() {
|
||||
let stats = await PlacesDBUtils.getEntitiesStats();
|
||||
let data = [];
|
||||
let db = await lazy.PlacesUtils.promiseDBConnection();
|
||||
for (let [entity, value] of stats) {
|
||||
let count = "-";
|
||||
try {
|
||||
if (
|
||||
entity.startsWith("moz_") &&
|
||||
!entity.endsWith("index") &&
|
||||
entity != "moz_places_visitcount" /* bug in index name */
|
||||
) {
|
||||
count = (
|
||||
await db.execute(`SELECT count(*) FROM ${entity}`)
|
||||
)[0].getResultByIndex(0);
|
||||
}
|
||||
} catch (ex) {
|
||||
console.error(ex);
|
||||
}
|
||||
data.push(Object.assign(value, { entity, count }));
|
||||
}
|
||||
return data;
|
||||
},
|
||||
|
||||
/**
|
||||
* Runs a list of tasks, returning a Map when done.
|
||||
*
|
||||
|
|
|
@ -432,6 +432,33 @@ var snapshotFormatters = {
|
|||
$.append($("locked-prefs-tbody"), prefsTable(data));
|
||||
},
|
||||
|
||||
places(data) {
|
||||
const statsBody = $("place-database-stats-tbody");
|
||||
$.append(
|
||||
statsBody,
|
||||
data.map(function(entry) {
|
||||
return $.new("tr", [
|
||||
$.new("td", entry.entity),
|
||||
$.new("td", entry.count),
|
||||
$.new("td", entry.sizeBytes / 1024),
|
||||
$.new("td", entry.sizePerc),
|
||||
$.new("td", entry.efficiencyPerc),
|
||||
$.new("td", entry.sequentialityPerc),
|
||||
]);
|
||||
})
|
||||
);
|
||||
statsBody.style.display = "none";
|
||||
$("place-database-stats-toggle").addEventListener("click", function(event) {
|
||||
if (statsBody.style.display === "none") {
|
||||
document.l10n.setAttributes(event.target, "place-database-stats-hide");
|
||||
statsBody.style.display = "";
|
||||
} else {
|
||||
document.l10n.setAttributes(event.target, "place-database-stats-show");
|
||||
statsBody.style.display = "none";
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
printingPreferences(data) {
|
||||
if (AppConstants.platform == "android") {
|
||||
return;
|
||||
|
|
|
@ -647,11 +647,28 @@
|
|||
<tr class="no-copy">
|
||||
<th class="column" data-l10n-id="place-database-integrity"/>
|
||||
|
||||
<td>
|
||||
<td colspan="5">
|
||||
<button id="verify-place-integrity-button" data-l10n-id="place-database-verify-integrity"/>
|
||||
<pre id="verify-place-result" class="hidden no-copy"></pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="no-copy">
|
||||
<th class="column" data-l10n-id="place-database-stats"/>
|
||||
|
||||
<td colspan="5">
|
||||
<button id="place-database-stats-toggle" data-l10n-id="place-database-stats-show"/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tbody id="place-database-stats-tbody">
|
||||
<tr>
|
||||
<th data-l10n-id="place-database-stats-entity"/>
|
||||
<th data-l10n-id="place-database-stats-count"/>
|
||||
<th data-l10n-id="place-database-stats-size-kib"/>
|
||||
<th data-l10n-id="place-database-stats-size-perc"/>
|
||||
<th data-l10n-id="place-database-stats-efficiency-perc"/>
|
||||
<th data-l10n-id="place-database-stats-sequentiality-perc"/>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
#endif
|
||||
|
|
|
@ -118,6 +118,15 @@ graphics-window-protocol = Window Protocol
|
|||
# Desktop environment in use on Linux (e.g. GNOME, KDE, XFCE, etc).
|
||||
graphics-desktop-environment = Desktop Environment
|
||||
place-database-title = Places Database
|
||||
place-database-stats = Statistics
|
||||
place-database-stats-show = Show Statistics
|
||||
place-database-stats-hide = Hide Statistics
|
||||
place-database-stats-entity = Entity
|
||||
place-database-stats-count = Count
|
||||
place-database-stats-size-kib = Size (KiB)
|
||||
place-database-stats-size-perc = Size (%)
|
||||
place-database-stats-efficiency-perc = Efficiency (%)
|
||||
place-database-stats-sequentiality-perc = Sequentiality (%)
|
||||
place-database-integrity = Integrity
|
||||
place-database-verify-integrity = Verify Integrity
|
||||
a11y-title = Accessibility
|
||||
|
|
|
@ -11,6 +11,9 @@ import { E10SUtils } from "resource://gre/modules/E10SUtils.sys.mjs";
|
|||
const { FeatureGate } = ChromeUtils.import(
|
||||
"resource://featuregates/FeatureGate.jsm"
|
||||
);
|
||||
const { PlacesDBUtils } = ChromeUtils.importESModule(
|
||||
"resource://gre/modules/PlacesDBUtils.sys.mjs"
|
||||
);
|
||||
|
||||
// We use a list of prefs for display to make sure we only show prefs that
|
||||
// are useful for support and won't compromise the user's privacy. Note that
|
||||
|
@ -485,6 +488,10 @@ var dataProviders = {
|
|||
);
|
||||
},
|
||||
|
||||
places: async function places(done) {
|
||||
done(await PlacesDBUtils.getEntitiesStatsAndCounts());
|
||||
},
|
||||
|
||||
printingPreferences: function printingPreferences(done) {
|
||||
let filter = name => Services.prefs.prefHasUserValue(name);
|
||||
let prefs = getPrefList(filter, ["print."]);
|
||||
|
|
Загрузка…
Ссылка в новой задаче