зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1557061 - Add summary information to the protection report. r=fluent-reviewers,mtigley,flod
Differential Revision: https://phabricator.services.mozilla.com/D38110 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
ac4f9f002c
Коммит
b8a1874706
|
@ -123,26 +123,30 @@ var AboutProtectionsHandler = {
|
|||
win.openTrustedLinkIn("about:preferences#sync", "tab");
|
||||
break;
|
||||
case "FetchContentBlockingEvents":
|
||||
TrackingDBService.getEventsByDateRange(
|
||||
let sumEvents = await TrackingDBService.sumAllEvents();
|
||||
let earliestDate = await TrackingDBService.getEarliestRecordedDate();
|
||||
let eventsByDate = await TrackingDBService.getEventsByDateRange(
|
||||
aMessage.data.from,
|
||||
aMessage.data.to
|
||||
).then(results => {
|
||||
let dataToSend = {};
|
||||
let largest = 0;
|
||||
for (let result of results) {
|
||||
let count = result.getResultByName("count");
|
||||
let type = result.getResultByName("type");
|
||||
let timestamp = result.getResultByName("timestamp");
|
||||
dataToSend[timestamp] = dataToSend[timestamp] || { total: 0 };
|
||||
dataToSend[timestamp][idToTextMap.get(type)] = count;
|
||||
dataToSend[timestamp].total += count;
|
||||
// Record the largest amount of tracking events found per day,
|
||||
// to create the tallest column on the graph and compare other days to.
|
||||
if (largest < dataToSend[timestamp].total) {
|
||||
largest = dataToSend[timestamp].total;
|
||||
}
|
||||
);
|
||||
let dataToSend = {};
|
||||
let largest = 0;
|
||||
|
||||
for (let result of eventsByDate) {
|
||||
let count = result.getResultByName("count");
|
||||
let type = result.getResultByName("type");
|
||||
let timestamp = result.getResultByName("timestamp");
|
||||
dataToSend[timestamp] = dataToSend[timestamp] || { total: 0 };
|
||||
dataToSend[timestamp][idToTextMap.get(type)] = count;
|
||||
dataToSend[timestamp].total += count;
|
||||
// Record the largest amount of tracking events found per day,
|
||||
// to create the tallest column on the graph and compare other days to.
|
||||
if (largest < dataToSend[timestamp].total) {
|
||||
largest = dataToSend[timestamp].total;
|
||||
}
|
||||
dataToSend.largest = largest;
|
||||
dataToSend.earliestDate = earliestDate;
|
||||
dataToSend.sumEvents = sumEvents;
|
||||
this.sendMessage(
|
||||
aMessage.target,
|
||||
"SendContentBlockingRecords",
|
||||
|
|
|
@ -8,17 +8,17 @@
|
|||
--clickable-text-active: hsla(0,0%,70%,.3);
|
||||
--card-divider: rgba(12,12,13,0.1) 1px solid;
|
||||
--report-background: #FAFAFC;
|
||||
--card-padding: 22px;
|
||||
--social-color: #AB71FF;
|
||||
--social-color-darker: #7F27FF;
|
||||
--card-padding: 24px;
|
||||
--social-color: #9059FF;
|
||||
--social-color-darker: #7F40FF;
|
||||
--cookie-color: #0090F4;
|
||||
--cookie-color-darker: #0073C3;
|
||||
--tracker-color: #2AC3A2;
|
||||
--tracker-color-darker: #229C82;
|
||||
--orange: #FFA436;
|
||||
--dark-orange: #ffA40C;
|
||||
--grey: #AFAFBB;
|
||||
--dark-grey: #88889A;
|
||||
--dark-orange: #FF981D;
|
||||
--grey: #8F8F9D;
|
||||
--dark-grey: #818191;
|
||||
--tab-highlight: var(--social-color); /* start with social selected */
|
||||
--blue-60: #0060DF;
|
||||
--blue-70: #003eaa;
|
||||
|
@ -172,15 +172,14 @@ body[focuseddatatype=cryptominer] {
|
|||
border-top: var(--card-divider);
|
||||
grid-column: span 2;
|
||||
grid-row: 2;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.body-wrapper {
|
||||
grid-column: 2;
|
||||
}
|
||||
|
||||
.graph-week-summary,
|
||||
.graph-total-summary {
|
||||
#graph-week-summary,
|
||||
#graph-total-summary {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
|
@ -191,6 +190,7 @@ body[focuseddatatype=cryptominer] {
|
|||
#graph-wrapper {
|
||||
width: 100%;
|
||||
margin-top: 40px;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
#graph {
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
### This file is not in a locales directory to prevent it from
|
||||
### being translated as the feature is still in heavy development
|
||||
### and strings are likely to change often.
|
||||
|
||||
# Variables:
|
||||
# $count (Number) - Number of tracking events blocked.
|
||||
graph-week-summary =
|
||||
{ $count ->
|
||||
[one] { -brand-short-name } blocked { $count } tracker over the past week
|
||||
*[other] { -brand-short-name } blocked { $count } trackers over the past week
|
||||
}
|
||||
|
||||
# Variables:
|
||||
# $count (Number) - Number of tracking events blocked.
|
||||
# $earliestDate (Number) - Unix timestamp in ms, representing a date. The
|
||||
# earliest date recorded in the database.
|
||||
graph-total-summary =
|
||||
{ $count ->
|
||||
[one] { $count } tracker blocked since { DATETIME($earliestDate, day: "numeric", month: "long", year: "numeric") }
|
||||
*[other] { $count } trackers blocked since { DATETIME($earliestDate, day: "numeric", month: "long", year: "numeric") }
|
||||
}
|
|
@ -7,6 +7,8 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src chrome: blob:">
|
||||
<link rel="localization" href="branding/brand.ftl"/>
|
||||
<link rel="localization" href="browser/protections.ftl">
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="chrome://browser/content/protections.css">
|
||||
<link rel="icon" href="chrome://global/skin/icons/warning.svg">
|
||||
|
@ -35,26 +37,24 @@
|
|||
</div>
|
||||
<div class="card-body">
|
||||
<div class="body-wrapper">
|
||||
<p class="graph-week-summary">
|
||||
Firefox blocked 970 trackers over the past week
|
||||
</p>
|
||||
<p id="graph-week-summary"></p>
|
||||
<div id="graph-wrapper">
|
||||
<div id="graph"></div>
|
||||
<div id="legend">
|
||||
<input id="tab-social" data-type="social" type="radio" name="tabs" checked>
|
||||
<label for="tab-social" data-type="social">345</label>
|
||||
<label for="tab-social" data-type="social"></label>
|
||||
|
||||
<input id="tab-cookie" data-type="cookie" type="radio" name="tabs">
|
||||
<label for="tab-cookie" data-type="cookie">123</label>
|
||||
<label for="tab-cookie" data-type="cookie"></label>
|
||||
|
||||
<input id="tab-tracker" data-type="tracker" type="radio" name="tabs">
|
||||
<label for="tab-tracker" data-type="tracker">1</label>
|
||||
<label for="tab-tracker" data-type="tracker"></label>
|
||||
|
||||
<input id="tab-fingerprinter" data-type="fingerprinter" type="radio" name="tabs">
|
||||
<label for="tab-fingerprinter" data-type="fingerprinter">45666</label>
|
||||
<label for="tab-fingerprinter" data-type="fingerprinter"></label>
|
||||
|
||||
<input id="tab-cryptominer" data-type="cryptominer" type="radio" name="tabs">
|
||||
<label for="tab-cryptominer" data-type="cryptominer">7</label>
|
||||
<label for="tab-cryptominer" data-type="cryptominer"></label>
|
||||
|
||||
<div id="social" class="tab-content">
|
||||
<p class="content-title">Social Media Trackers</p>
|
||||
|
@ -78,9 +78,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="graph-total-summary">
|
||||
125,324 trackers blocked since August, 2018
|
||||
</p>
|
||||
<div id="graph-total-summary"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -32,12 +32,31 @@ document.addEventListener("DOMContentLoaded", e => {
|
|||
RPMSendAsyncMessage("GetEnabledLockwiseCard");
|
||||
|
||||
let createGraph = data => {
|
||||
let dateInMS = data.earliestDate
|
||||
? new Date(data.earliestDate).getTime()
|
||||
: Date.now();
|
||||
|
||||
let summary = document.getElementById("graph-total-summary");
|
||||
summary.setAttribute(
|
||||
"data-l10n-args",
|
||||
`{"earliestDate": ${dateInMS}, "count": ${data.sumEvents}}`
|
||||
);
|
||||
summary.setAttribute("data-l10n-id", "graph-total-summary");
|
||||
|
||||
// Set a default top size for the height of the graph bars so that small
|
||||
// numbers don't fill the whole graph.
|
||||
let largest = 100;
|
||||
if (largest < data.largest) {
|
||||
largest = data.largest;
|
||||
}
|
||||
let weekCount = 0;
|
||||
let weekTypeCounts = {
|
||||
social: 0,
|
||||
cookie: 0,
|
||||
tracker: 0,
|
||||
fingerprinter: 0,
|
||||
cryptominer: 0,
|
||||
};
|
||||
|
||||
let graph = document.getElementById("graph");
|
||||
for (let i = weekdays.length - 1; i >= 0; i--) {
|
||||
|
@ -54,6 +73,7 @@ document.addEventListener("DOMContentLoaded", e => {
|
|||
count.textContent = content.total;
|
||||
bar.appendChild(count);
|
||||
let barHeight = (content.total / largest) * 100;
|
||||
weekCount += content.total;
|
||||
bar.style.height = `${barHeight}%`;
|
||||
for (let type of dataTypes) {
|
||||
if (content[type]) {
|
||||
|
@ -62,6 +82,7 @@ document.addEventListener("DOMContentLoaded", e => {
|
|||
div.className = `${type}-bar inner-bar`;
|
||||
div.setAttribute("data-type", type);
|
||||
div.style.height = `${dataHeight}%`;
|
||||
weekTypeCounts[type] += content[type];
|
||||
bar.appendChild(div);
|
||||
}
|
||||
}
|
||||
|
@ -70,6 +91,14 @@ document.addEventListener("DOMContentLoaded", e => {
|
|||
bar.classList.add("empty");
|
||||
}
|
||||
graph.appendChild(bar);
|
||||
let weekSummary = document.getElementById("graph-week-summary");
|
||||
weekSummary.setAttribute("data-l10n-args", `{"count": ${weekCount}}`);
|
||||
weekSummary.setAttribute("data-l10n-id", "graph-week-summary");
|
||||
|
||||
for (let type of dataTypes) {
|
||||
document.querySelector(`label[data-type=${type}]`).textContent =
|
||||
weekTypeCounts[type];
|
||||
}
|
||||
|
||||
let label = document.createElement("span");
|
||||
label.className = "column-label";
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
# having to create the same entry for each locale.
|
||||
|
||||
[localization] @AB_CD@.jar:
|
||||
browser/protections.ftl (../components/protections/content/protections.ftl)
|
||||
browser/aboutLogins.ftl (../components/aboutlogins/content/aboutLogins.ftl)
|
||||
toolkit/certviewer.ftl (../../toolkit/components/certviewer/content/certviewer.ftl)
|
||||
browser (%browser/**/*.ftl)
|
||||
|
|
|
@ -56,6 +56,11 @@ const SQL = {
|
|||
selectByDateRange:
|
||||
"SELECT * FROM events " +
|
||||
"WHERE timestamp BETWEEN date(:dateFrom) AND date(:dateTo);",
|
||||
|
||||
sumAllEvents: "SELECT sum(count) FROM events;",
|
||||
|
||||
getEarliestDate:
|
||||
"SELECT timestamp FROM events ORDER BY timestamp DESC LIMIT 1;",
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -256,6 +261,26 @@ TrackingDBService.prototype = {
|
|||
dateTo = new Date(dateTo).toISOString();
|
||||
return db.execute(SQL.selectByDateRange, { dateFrom, dateTo });
|
||||
},
|
||||
|
||||
async sumAllEvents() {
|
||||
let db = await this.ensureDB();
|
||||
let results = await db.execute(SQL.sumAllEvents);
|
||||
if (!results[0]) {
|
||||
return 0;
|
||||
}
|
||||
let total = results[0].getResultByName("sum(count)");
|
||||
return total || 0;
|
||||
},
|
||||
|
||||
async getEarliestRecordedDate() {
|
||||
let db = await this.ensureDB();
|
||||
let date = await db.execute(SQL.getEarliestDate);
|
||||
if (!date[0]) {
|
||||
return null;
|
||||
}
|
||||
let earliestDate = date[0].getResultByName("timestamp");
|
||||
return earliestDate || null;
|
||||
},
|
||||
};
|
||||
|
||||
var EXPORTED_SYMBOLS = ["TrackingDBService"];
|
||||
|
|
|
@ -45,6 +45,16 @@ interface nsITrackingDBService : nsISupports
|
|||
*/
|
||||
Promise getEventsByDateRange(in int64_t dateFrom, in int64_t dateTo);
|
||||
|
||||
/**
|
||||
* Return a count of all tracking events.
|
||||
*/
|
||||
Promise sumAllEvents();
|
||||
|
||||
/**
|
||||
* Return the earliest recorded date.
|
||||
*/
|
||||
Promise getEarliestRecordedDate();
|
||||
|
||||
const unsigned long OTHER_COOKIES_BLOCKED_ID = 0;
|
||||
const unsigned long TRACKERS_ID = 1;
|
||||
const unsigned long TRACKING_COOKIES_ID = 2;
|
||||
|
|
|
@ -273,14 +273,7 @@ add_task(async function test_timestamp_aggragation() {
|
|||
Services.prefs.clearUserPref("browser.contentblocking.database.enabled");
|
||||
});
|
||||
|
||||
// This tests that TrackingDBService.getEventsByDateRange can accept two timestamps in unix epoch time
|
||||
// and return entries that occur within the timestamps, rounded to the nearest day and inclusive.
|
||||
add_task(async function test_getEventsByDateRange() {
|
||||
Services.prefs.setBoolPref("browser.contentblocking.database.enabled", true);
|
||||
// This creates the schema.
|
||||
await TrackingDBService.saveEvents(JSON.stringify({}));
|
||||
let db = await Sqlite.openConnection({ path: DB_PATH });
|
||||
|
||||
let addEventsToDB = async db => {
|
||||
let d = new Date(1521009000000);
|
||||
let date = d.toISOString();
|
||||
await db.execute(SQL.insertCustomTimeEvent, {
|
||||
|
@ -316,7 +309,18 @@ add_task(async function test_getEventsByDateRange() {
|
|||
count: 2,
|
||||
timestamp: date,
|
||||
});
|
||||
};
|
||||
|
||||
// This tests that TrackingDBService.getEventsByDateRange can accept two timestamps in unix epoch time
|
||||
// and return entries that occur within the timestamps, rounded to the nearest day and inclusive.
|
||||
add_task(async function test_getEventsByDateRange() {
|
||||
Services.prefs.setBoolPref("browser.contentblocking.database.enabled", true);
|
||||
// This creates the schema.
|
||||
await TrackingDBService.saveEvents(JSON.stringify({}));
|
||||
let db = await Sqlite.openConnection({ path: DB_PATH });
|
||||
await addEventsToDB(db);
|
||||
|
||||
let d = new Date(1521009000000);
|
||||
let daysBefore1 = new Date(d - 24 * 60 * 60 * 1000);
|
||||
let daysBefore4 = new Date(d - 4 * 24 * 60 * 60 * 1000);
|
||||
let daysBefore9 = new Date(d - 9 * 24 * 60 * 60 * 1000);
|
||||
|
@ -349,3 +353,47 @@ add_task(async function test_getEventsByDateRange() {
|
|||
await db.close();
|
||||
Services.prefs.clearUserPref("browser.contentblocking.database.enabled");
|
||||
});
|
||||
|
||||
// This tests that TrackingDBService.sumAllEvents returns the number of
|
||||
// tracking events in the database, and can handle 0 entries.
|
||||
add_task(async function test_sumAllEvents() {
|
||||
Services.prefs.setBoolPref("browser.contentblocking.database.enabled", true);
|
||||
// This creates the schema.
|
||||
await TrackingDBService.saveEvents(JSON.stringify({}));
|
||||
let db = await Sqlite.openConnection({ path: DB_PATH });
|
||||
|
||||
let sum = await TrackingDBService.sumAllEvents();
|
||||
equal(sum, 0, "There have been 0 events recorded");
|
||||
|
||||
// populate the database
|
||||
await addEventsToDB(db);
|
||||
|
||||
sum = await TrackingDBService.sumAllEvents();
|
||||
equal(sum, 11, "There have been 11 events recorded");
|
||||
|
||||
await TrackingDBService.clearAll();
|
||||
await db.close();
|
||||
Services.prefs.clearUserPref("browser.contentblocking.database.enabled");
|
||||
});
|
||||
|
||||
// This tests that TrackingDBService.getEarliestRecordedDate returns the
|
||||
// earliest date recorded and can handle 0 entries.
|
||||
add_task(async function test_getEarliestRecordedDate() {
|
||||
Services.prefs.setBoolPref("browser.contentblocking.database.enabled", true);
|
||||
// This creates the schema.
|
||||
await TrackingDBService.saveEvents(JSON.stringify({}));
|
||||
let db = await Sqlite.openConnection({ path: DB_PATH });
|
||||
|
||||
let date = await TrackingDBService.getEarliestRecordedDate();
|
||||
equal(date, null, "There is no earliest recorded date");
|
||||
|
||||
// populate the database
|
||||
await addEventsToDB(db);
|
||||
|
||||
date = await TrackingDBService.getEarliestRecordedDate();
|
||||
equal(date, "2018-03-14", "The earliest recorded event is 2018-03-14");
|
||||
|
||||
await TrackingDBService.clearAll();
|
||||
await db.close();
|
||||
Services.prefs.clearUserPref("browser.contentblocking.database.enabled");
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче