diff --git a/_locales/en/messages.json b/_locales/en/messages.json
index ec921e741..7b98b7bba 100644
--- a/_locales/en/messages.json
+++ b/_locales/en/messages.json
@@ -2207,6 +2207,24 @@
"panel_stats_pitch_modal_tooltip": {
"message": "Erase all statistics history up until this point in time."
},
+ "cookie": {
+ "message": "cookie"
+ },
+ "cookies": {
+ "message": "cookies"
+ },
+ "fingerprint": {
+ "message": "fingerprint"
+ },
+ "fingerprints": {
+ "message": "fingerprints"
+ },
+ "ad": {
+ "message": "ad"
+ },
+ "ads": {
+ "message": "ads"
+ },
"cliqz_feature_status_on": {
"message": "On"
},
diff --git a/app/images/panel/tracker-detail-cliqz-ads-icon.svg b/app/images/panel/tracker-detail-cliqz-ads-icon.svg
new file mode 100644
index 000000000..2674f8621
--- /dev/null
+++ b/app/images/panel/tracker-detail-cliqz-ads-icon.svg
@@ -0,0 +1,7 @@
+
+
diff --git a/app/images/panel/tracker-detail-cliqz-cookies-and-fingerprints-icon.svg b/app/images/panel/tracker-detail-cliqz-cookies-and-fingerprints-icon.svg
new file mode 100644
index 000000000..8a5c467ad
--- /dev/null
+++ b/app/images/panel/tracker-detail-cliqz-cookies-and-fingerprints-icon.svg
@@ -0,0 +1,4 @@
+
+
\ No newline at end of file
diff --git a/app/panel/components/Blocking/Tracker.jsx b/app/panel/components/Blocking/Tracker.jsx
index 84b839908..5486858a7 100644
--- a/app/panel/components/Blocking/Tracker.jsx
+++ b/app/panel/components/Blocking/Tracker.jsx
@@ -14,6 +14,7 @@
/* eslint react/no-array-index-key: 0 */
import React from 'react';
+import ReactSVG from 'react-svg';
import globals from '../../../../src/classes/Globals';
import { log } from '../../../../src/utils/common';
import { sendMessageInPromise } from '../../utils/msg';
@@ -200,6 +201,57 @@ class Tracker extends React.Component {
reload: true,
});
}
+
+ _renderCliqzStatsContainer() {
+ const { tracker } = this.props;
+ const { cliqzAdCount, cliqzCookieCount, cliqzFingerprintCount } = tracker;
+
+ const oneOrMoreCookies = cliqzCookieCount >= 1;
+ const oneOrMoreFingerprints = cliqzFingerprintCount >= 1;
+ const oneOrMoreAds = cliqzAdCount >= 1;
+
+ return (
+
diff --git a/app/scss/partials/_blocking_tracker.scss b/app/scss/partials/_blocking_tracker.scss
index 3aef6b1a3..08668f579 100644
--- a/app/scss/partials/_blocking_tracker.scss
+++ b/app/scss/partials/_blocking_tracker.scss
@@ -19,17 +19,52 @@
border-top: none;
}
.trk-header {
- padding-top: 5px;
- padding-bottom: 5px;
- height: 39px;
+ height: 54px;
.trk-name {
@extend %pointer;
font-size: 14px;
- line-height: 19px;
+ line-height: 25px;
font-weight: 400;
color: #4a4a4a;
@extend %nowrap;
}
+ .trk-cliqz-stats-outer-container {
+ // prevent jitter from breaking to new line
+ // if all three of cookies fingerprints and ads are present
+ // and we hover over the ad icon while the cookies & fingerprints section is expanded
+ white-space: nowrap;
+
+ font-size: 10px;
+ font-family: "Open Sans", "Roboto", Arial, Helvetica, sans-serif;
+ font-weight: 600;
+ }
+ .trk-cliqz-stats-icon {
+ // vertical alignment with text label
+ position: relative;
+ top: -2px;
+
+ display: inline-block;
+ padding-right: 6px;
+ }
+ .trk-cliqz-stat {
+ color: #1dafed;
+ text-transform: capitalize;
+ display: inline-block;
+ max-width: 0px;
+ padding-right: 0px;
+ transition: max-width 0.6s, padding 0.6s;
+ transition-delay: 0.2s;
+ overflow-x: hidden;
+ white-space: nowrap;
+ }
+ .trk-cliqz-stats-container {
+ display: inline-block;
+ }
+ .trk-cliqz-stats-container:hover .trk-cliqz-stat {
+ max-width: 100px;
+ padding-right: 4px;
+ }
+
.svg-container {
height: 20px;
}
diff --git a/src/classes/FoundBugs.js b/src/classes/FoundBugs.js
index 759b91554..452d362b0 100644
--- a/src/classes/FoundBugs.js
+++ b/src/classes/FoundBugs.js
@@ -276,6 +276,23 @@ class FoundBugs {
return apps_arr;
}
+ /**
+ * Returns an object where the keys are the ids of the apps found on this tab
+ * and the values are their indices in the array returned by #getApps
+ *
+ * @param {number} tab_id tab id
+ * @return {Object} object of app-id-to-#getApps-array-index mappings
+ */
+ getAppsById(tab_id) {
+ if (!this._ensure(tab_id)) {
+ return [];
+ }
+
+ const { appsById } = this._foundApps[tab_id];
+
+ return appsById;
+ }
+
/**
* Get the categories from BugsDb that match bugs found
* on a tab_id.
diff --git a/src/classes/PanelData.js b/src/classes/PanelData.js
index 750e4bfc7..2145acd09 100644
--- a/src/classes/PanelData.js
+++ b/src/classes/PanelData.js
@@ -26,7 +26,7 @@ import tabInfo from './TabInfo';
import rewards from './Rewards';
import account from './Account';
import dispatcher from './Dispatcher';
-import { sendCliqzModulesData } from '../utils/cliqzModulesData';
+import { getCliqzGhosteryStats, sendCliqzModulesData } from '../utils/cliqzModulesData';
import { getActiveTab, flushChromeMemoryCache, processUrl } from '../utils/utils';
import { objectEntries, log } from '../utils/common';
@@ -738,7 +738,16 @@ class PanelData {
*/
_buildTracker(tracker, trackerState, smartBlock) {
const {
- id, name, cat, sources, hasCompatibilityIssue, hasInsecureIssue, hasLatencyIssue
+ cat,
+ cliqzAdCount,
+ cliqzCookieCount,
+ cliqzFingerprintCount,
+ hasCompatibilityIssue,
+ hasInsecureIssue,
+ hasLatencyIssue,
+ id,
+ name,
+ sources,
} = tracker;
const { blocked, ss_allowed, ss_blocked } = trackerState;
@@ -755,7 +764,10 @@ class PanelData {
warningCompatibility: hasCompatibilityIssue,
warningInsecure: hasInsecureIssue,
warningSlow: hasLatencyIssue,
- warningSmartBlock: (smartBlock.blocked.hasOwnProperty(id) && 'blocked') || (smartBlock.unblocked.hasOwnProperty(id) && 'unblocked') || false
+ warningSmartBlock: (smartBlock.blocked.hasOwnProperty(id) && 'blocked') || (smartBlock.unblocked.hasOwnProperty(id) && 'unblocked') || false,
+ cliqzAdCount,
+ cliqzCookieCount,
+ cliqzFingerprintCount,
};
}
@@ -807,7 +819,7 @@ class PanelData {
}
/**
- * Store the tracker list and categories values to reduce code duplicdation between the blocking and summary data getters,
+ * Store the tracker list and categories values to reduce code duplication between the blocking and summary data getters,
* and since these values may be accessed 2+ times in a single updatePanelUI call
*/
_setTrackerListAndCategories() {
@@ -816,6 +828,27 @@ class PanelData {
const { id, url } = this._activeTab;
this._trackerList = foundBugs.getApps(id, false, url) || [];
+
+ const ghosteryStats = getCliqzGhosteryStats(id);
+
+ if (ghosteryStats && ghosteryStats.bugs) {
+ const gsBugs = ghosteryStats.bugs;
+ const bugsIds = Object.keys(gsBugs);
+ const appsById = foundBugs.getAppsById(id);
+
+ bugsIds.forEach((bugsId) => {
+ const trackerId = conf.bugs.bugs[bugsId];
+ if (!trackerId) return;
+
+ const trackerListIndex = appsById[trackerId.aid];
+ if (!trackerListIndex) return;
+
+ this._trackerList[trackerListIndex].cliqzCookieCount = gsBugs[bugsId].cookies;
+ this._trackerList[trackerListIndex].cliqzFingerprintCount = gsBugs[bugsId].fingerprints;
+ this._trackerList[trackerListIndex].cliqzAdCount = gsBugs[bugsId].ads;
+ });
+ }
+
this._categories = this._buildCategories();
}
// [/DATA SETTING]
diff --git a/src/utils/cliqzModulesData.js b/src/utils/cliqzModulesData.js
index 57cc2512f..46e6485c9 100644
--- a/src/utils/cliqzModulesData.js
+++ b/src/utils/cliqzModulesData.js
@@ -57,10 +57,46 @@ export function getCliqzAdblockingData(tabId) {
return adBlocking || { totalCount: 0 };
}
+/**
+ * TODO: Add a test that verifies the following structure so that we automatically know if Cliqz changes it and we need to updated it
+ The returned object has the following structure:
+ {
+ bugs: {
+ 4147: { cookies: 3, fingerprints: 4, ads: 0 },
+ another_bug_id: { cookies: 2, .....
+ ....
+ },
+ others: {
+ CloudFlare: {
+ ads: 0,
+ cat: "cdn",
+ cookies: 3,
+ domains: ["cdnjs.cloudlare.com", ...],
+ fingerprints: 4,
+ name: "CloudFlare",
+ wtm: "cloudflare",
+ },
+ ...
+ }
+ }
+ */
+export function getCliqzGhosteryStats(tabId) {
+ if (!conf.enable_anti_tracking) {
+ return {
+ bugs: {},
+ others: {},
+ };
+ }
+
+ const ghosteryStats = antitracking.background.actions.getGhosteryStats(tabId);
+ return ghosteryStats;
+}
+
export function sendCliqzModulesData(tabId, callback) {
const modules = { adblock: {}, antitracking: {} };
modules.adblock = getCliqzAdblockingData(tabId);
+
// TODO convert to use finally to avoid duplication (does our Babel transpile it?)
getCliqzAntitrackingData(tabId).then((antitrackingData) => {
modules.antitracking = antitrackingData;