Bug 1557049 - Create graph and tabs UI. r=nhnt11
authorErica Wright <ewright@mozilla.com>
Wed, 26 Jun 2019 14:59:27 +0000
changeset 543001 ab93b6bc57590d7f965c1ec72981419171a840c8
parent 543000 378f90fe8bfa897ccb2af0753cfcc6a129a4ba93
child 543002 e996920037965b669fe3fd6306d6f8bee0ebc8bf
push id2131
push userffxbld-merge
push dateMon, 26 Aug 2019 18:30:20 +0000
treeherdermozilla-release@b19ffb3ca153 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnhnt11
bugs1557049
milestone69.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1557049 - Create graph and tabs UI. r=nhnt11 Differential Revision: https://phabricator.services.mozilla.com/D35736
browser/components/protections/content/protections.css
browser/components/protections/content/protections.html
browser/components/protections/content/protections.js
--- a/browser/components/protections/content/protections.css
+++ b/browser/components/protections/content/protections.css
@@ -1,27 +1,58 @@
 /* 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/. */
- :root {
-   --card-box-shadow: 0 1px 4px 0 rgba(12,12,13,0.1), 0 1px 0 0 rgba(0,0,0,0.05);
-   --card-background:  #FFF;
-   --clickable-text-hover: hsla(0,0%,70%,.2);
-   --clickable-text-active: hsla(0,0%,70%,.3);
-   --card-divider: rgba(12,12,13,0.1) 1px solid;
-   --report-background: #FAFAFC;
-   --card-padding: 22px;
- }
+:root {
+  --card-box-shadow: 0 1px 4px 0 rgba(12,12,13,0.1), 0 1px 0 0 rgba(0,0,0,0.05);
+  --card-background:  #FFF;
+  --clickable-text-hover: hsla(0,0%,70%,.2);
+  --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;
+  --crossSite-color: #0090F4;
+  --crossSite-color-darker: #0073C3;
+  --tracker-color: #2AC3A2;
+  --tracker-color-darker: #229C82;
+  --fingerprinter-color: #FFBD4F;
+  --fingerprinter-color-darker: #ffA40C;
+  --cryptominer-color: #AFAFBB;
+  --cryptominer-color-darker: #88889A;
+  --tab-highlight: var(--social-color); /* start with social selected */
+}
 
 body {
   background-color: var(--report-background);
   font: message-box;
   margin-top: 82px;
 }
 
+body[focuseddatatype=social] {
+  --tab-highlight: var(--social-color);
+}
+
+body[focuseddatatype=crossSite] {
+  --tab-highlight: var(--crossSite-color);
+}
+
+body[focuseddatatype=tracker] {
+  --tab-highlight: var(--tracker-color);
+}
+
+body[focuseddatatype=fingerprinter] {
+  --tab-highlight: var(--fingerprinter-color);
+}
+
+body[focuseddatatype=cryptominer] {
+  --tab-highlight: var(--cryptominer-color);
+}
+
 #report-title {
   font-size: 20px;
   font-weight: 300;
   margin-bottom: 22px;
 }
 
 #report-content {
   width: 763px;
@@ -40,55 +71,216 @@ body {
   display: grid;
   grid-template-columns: 100%;
   grid-template-rows: 20% auto;
   border-radius: 3px;
   background-color: var(--card-background);
   box-shadow: var(--card-box-shadow);
 }
 
-.report-card .card-header {
+.report-card .card-header,
+.report-card .card-body {
   display: grid;
   grid-template-columns: 1fr 7fr;
   padding: var(--card-padding);
   grid-gap: var(--card-padding);
 }
 
 .report-card .card-title {
-  font-size: 16px;
+  font-size: 1rem;
   line-height: 22px;
   margin: 0;
   cursor: default;
 }
 
 .report-card .content {
   margin-bottom: 24px;
   margin-top: 5px;
-  font-size: 14px;
+  font-size: 0.85rem;
   cursor: default;
 }
 
 #protection-details {
   background: url("chrome://browser/skin/settings.svg") no-repeat 3px 3px;
   padding: 4px 4px 4px 24px;
-  font-size: 12px;
+  font-size: 0.75rem;
   display: inline;
   cursor: default;
 }
 
 #protection-details:hover {
   background-color: var(--clickable-text-hover);
 }
 
 #protection-details:hover:active {
   background-color: var(--clickable-text-active);
 }
 
 #protection-details span {
   font-weight: bold;
 }
 
-.card-body {
+.report-card .card-body {
   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 {
+  font-size: 0.8rem;
+}
+
+.graph-week-summary {
+  font-weight: bold;
+}
+
+#graph-wrapper {
+  width: 100%;
+  margin-top: 30px;
+}
+
+#graph {
+  display: grid;
+  grid: repeat(10, 1fr) max-content / repeat(7, 1fr);
+  height: 200px;
+  margin-bottom: 10px;
+}
+
+/* Graph Bars */
+.graph-bar {
+  grid-row: 1 / -2;
+  justify-self: center;
+  align-self: flex-end;
+  width: 16px;
+  border-radius: 4px;
+  overflow: hidden;
+}
+
+.graph-bar:hover {
+  cursor: pointer;
+}
+
+.social-bar {
+  background-color: var(--social-color);
+}
+
+.hover-social .social-bar {
+  background-color: var(--social-color-darker);
+}
+
+.crossSite-bar {
+  background-color: var(--crossSite-color);
+}
+
+.hover-crossSite .crossSite-bar {
+  background-color: var(--crossSite-color-darker);
+}
+
+.tracker-bar {
+  background-color: var(--tracker-color);
+}
+
+.hover-tracker .tracker-bar {
+  background-color: var(--tracker-color-darker);
+}
+
+.fingerprinter-bar {
+  background-color: var(--fingerprinter-color);
+}
+
+.hover-fingerprinter .fingerprinter-bar {
+  background-color: var(--fingerprinter-color-darker);
+}
+
+.cryptominer-bar {
+  background-color: var(--cryptominer-color);
+}
+
+.hover-cryptominer .cryptominer-bar {
+  background-color: var(--cryptominer-color-darker);
+}
+
+.column-label {
+  justify-self: center;
+  margin-top: 5px;
+  font-size: 0.9rem;
+}
+
+/* Legend */
+input {
+  display: none;
+}
+
+label {
+  display: inline-block;
+  margin: 0 0 -1px;
+  padding: 15px 25px;
+  font-weight: 600;
+  text-align: center;
+  border: 1px solid transparent;
+}
+
+label[data-type="social"] {
+  color: var(--social-color);
+}
+
+label[data-type="crossSite"] {
+  color: var(--crossSite-color);
+}
+
+label[data-type="tracker"] {
+  color: var(--tracker-color);
+}
+
+label[data-type="fingerprinter"] {
+  color: var(--fingerprinter-color);
+}
+
+label[data-type="cryptominer"] {
+  color: var(--cryptominer-color);
+}
+
+.hover-social label[for="tab-social"],
+.hover-crossSite label[for="tab-crossSite"],
+.hover-tracker label[for="tab-tracker"],
+.hover-fingerprinter label[for="tab-fingerprinter"],
+.hover-cryptominer label[for="tab-cryptominer"],
+label:hover {
+  background-color: var(--clickable-text-hover);
+  cursor: pointer;
+}
+
+input:checked + label {
+  border-bottom: 3px solid var(--tab-highlight);
+}
+
+.tab-content {
+  display: none;
+  padding: 22px 20px 20px;
+  border-top: 1px solid var(--tab-highlight);
+  background-color: #F9F9FB;
+  color: #737373;
+  font-size: 0.8rem;
+  line-height: 20px;
+  min-height: 130px;
+}
+
+.tab-content .content-title {
+  font-weight: bold;
+}
+
+.tab-content p {
+  margin: 0;
+}
+
+#tab-social:checked ~ #social,
+#tab-crossSite:checked ~ #crossSite,
+#tab-tracker:checked ~ #tracker,
+#tab-fingerprinter:checked ~ #fingerprinter,
+#tab-cryptominer:checked ~ #cryptominer {
+  display: block;
+}
--- a/browser/components/protections/content/protections.html
+++ b/browser/components/protections/content/protections.html
@@ -28,13 +28,61 @@
               Trackers follow you around online to collect information about your browsing habits and interests. Firefox blocks many of these trackers and other malicious scripts.
             </p>
             <p id="protection-details">
               Protection Level is set to <span>Standard</span>
             </p>
           </div>
         </div>
         <div class="card-body">
+          <div class="body-wrapper">
+            <p class="graph-week-summary">
+              Firefox blocked 970 trackers over the past week
+            </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">Social</label>
+
+                <input id="tab-crossSite" data-type="crossSite" type="radio" name="tabs">
+                <label for="tab-crossSite" data-type="crossSite">cross-site-tracker</label>
+
+                <input id="tab-tracker" data-type="tracker" type="radio" name="tabs">
+                <label for="tab-tracker" data-type="tracker">ad-tracker</label>
+
+                <input id="tab-fingerprinter" data-type="fingerprinter" type="radio" name="tabs">
+                <label for="tab-fingerprinter" data-type="fingerprinter">fingerprinter</label>
+
+                <input id="tab-cryptominer" data-type="cryptominer" type="radio" name="tabs">
+                <label for="tab-cryptominer" data-type="cryptominer">cryptominer</label>
+
+                <div id="social" class="tab-content">
+                  <p class="content-title">Social Media Trackers</p>
+                  <p>Social media like, post, and comment buttons on other websites can track you — even if you don’t use them. Logging in to sites using your Facebook or Twitter account is another way they can track what you do on those sites. We remove these trackers so Facebook and Twitter see less of what you do online.</p>
+                </div>
+                <div id="crossSite" class="tab-content">
+                  <p class="content-title">Cross-Site Tracking Cookies</p>
+                  <p>Cross-site tracking cookies follow you from site to site to collect data about your browsing habits. Advertisers and analytics companies gather this data to create a profile of your interests across many sites. Blocking them reduces the number of personalized ads that follow you around.</p>
+                </div>
+                <div id="tracker" class="tab-content">
+                  <p class="content-title">Tracking Content</p>
+                  <p>Websites may load outside ads, videos, and other content that contain hidden trackers. Blocking tracking content can make websites load faster, but some buttons, forms, and login fields might not work.</p>
+                </div>
+                <div id="fingerprinter" class="tab-content">
+                  <p class="content-title">Fingerprinters</p>
+                  <p>Fingerprinting is a form of online tracking that’s different from your real fingerprints. Companies use it to create a unique profile of you using data about your browser, device, and other settings. We block ad trackers from fingerprinting your device.</p>
+                </div>
+                <div id="cryptominer" class="tab-content">
+                  <p class="content-title">Cryptominers</p>
+                  <p>Some websites host hidden malware that secretly uses your system’s computing power to mine cryptocurrency, or digital money. It drains your battery, slows down your computer, and increases your energy bill. We block known cryptominers from using your computing resources to make money.</p>
+                </div>
+              </div>
+            </div>
+            <p class="graph-total-summary">
+              125,324 trackers blocked since August, 2018
+            </p>
+          </div>
         </div>
       </div>
     </div>
   </body>
 </html>
--- a/browser/components/protections/content/protections.js
+++ b/browser/components/protections/content/protections.js
@@ -1,12 +1,93 @@
 /* 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/. */
 
 /* eslint-env mozilla/frame-script */
 
 document.addEventListener("DOMContentLoaded", (e) => {
+  let dataTypes = ["cryptominer", "fingerprinter", "tracker", "crossSite", "social"];
+  let weekdays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
+  let today = new Date().getDay();
+
   let protectionDetails = document.getElementById("protection-details");
   protectionDetails.addEventListener("click", () => {
     RPMSendAsyncMessage("openContentBlockingPreferences");
   });
+
+  let data = [
+    {total: 41, cryptominer: 1, fingerprinter: 10, tracker: 15, crossSite: 12, social: 3},
+    {total: 246, cryptominer: 5, fingerprinter: 8, tracker: 110, crossSite: 103, social: 20},
+    {total: 59, cryptominer: 0, fingerprinter: 1, tracker: 25, crossSite: 25, social: 8},
+    {total: 177, cryptominer: 0, fingerprinter: 4, tracker: 24, crossSite: 136, social: 13},
+    {total: 16, cryptominer: 1, fingerprinter: 3, tracker: 0, crossSite: 7, social: 5},
+    {total: 232, cryptominer: 0, fingerprinter: 30, tracker: 84, crossSite: 86, social: 32},
+    {total: 153, cryptominer: 0, fingerprinter: 10, tracker: 35, crossSite: 95, social: 13},
+  ];
+
+  // Use this to populate the graph with real data in the future.
+  let createGraph = () => {
+    let largest = 10;
+    for (let day of data) {
+      if (largest < day.total) {
+        largest = day.total;
+      }
+    }
+
+    let graph = document.getElementById("graph");
+    for (let i = 0; i < weekdays.length; i++) {
+      let bar = document.createElement("div");
+      bar.className = "graph-bar";
+      let barHeight = (data[i].total / largest) * 100;
+      bar.style.height =  `${barHeight}%`;
+      for (let type of dataTypes) {
+        let dataHeight = (data[i][type] / data[i].total) * 100;
+        let div = document.createElement("div");
+        div.className = `${type}-bar`;
+        div.setAttribute("data-type", type);
+        div.style.height = `${dataHeight}%`;
+        bar.appendChild(div);
+      }
+      graph.appendChild(bar);
+
+      let label = document.createElement("span");
+      label.className = "column-label";
+      if (i == 6) {
+        label.innerText = "Today";
+      } else {
+        label.innerText = weekdays[(i + today) % 7];
+      }
+      graph.appendChild(label);
+    }
+  };
+
+  let addListeners = () => {
+    let wrapper = document.querySelector(".body-wrapper");
+    wrapper.addEventListener("mouseover", (ev) => {
+      if (ev.originalTarget.dataset) {
+        wrapper.classList.add("hover-" + ev.originalTarget.dataset.type);
+      }
+    });
+
+    wrapper.addEventListener("mouseout", (ev) => {
+      if (ev.originalTarget.dataset) {
+        wrapper.classList.remove("hover-" + ev.originalTarget.dataset.type);
+      }
+    });
+
+    wrapper.addEventListener("click", (ev) => {
+      if (ev.originalTarget.dataset) {
+        document.getElementById(`tab-${ev.target.dataset.type}`).click();
+      }
+    });
+
+    // Change the class on the body to change the color variable.
+    let radios = document.querySelectorAll("#legend input");
+    for (let radio of radios) {
+      radio.addEventListener("change", (ev) => {
+        document.body.setAttribute("focuseddatatype", ev.target.dataset.type);
+      });
+    }
+  };
+  createGraph();
+  addListeners();
 });