+
diff --git a/package.json b/package.json
index ee161a7d3..ade3fd5ce 100644
--- a/package.json
+++ b/package.json
@@ -19,8 +19,8 @@
"test": "cross-env BABEL_ENV=test jest",
"test.watch": "cross-env BABEL_ENV=test jest --watch",
"test.snapshot": "jest --updateSnapshot",
- "lint": "eslint --ext .js,.jsx ./app ./src",
- "lint.fix": "eslint --ext .js,.jsx ./app ./src --fix",
+ "lint": "eslint --ext .js,.jsx ./app ./src ./test ./tools",
+ "lint.fix": "eslint --ext .js,.jsx ./app ./src ./test ./tools --fix",
"lint.raw": "eslint --ext .js,.jsx",
"docs": "jsdoc -c jsdoc.json -d docs -r",
"leet": "node ./tools/leet/leet-en.js",
diff --git a/src/background.js b/src/background.js
index ae5b3a17b..92e892283 100644
--- a/src/background.js
+++ b/src/background.js
@@ -11,10 +11,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0
*/
-/* eslint consistent-return: 0 */
-/* eslint no-use-before-define: 0 */
-/* eslint no-shadow: 0 */
-
/**
* @namespace Background
*/
@@ -23,6 +19,7 @@ import moment from 'moment/min/moment-with-locales.min';
import cliqz from './classes/Cliqz';
// object class
import Events from './classes/EventHandlers';
+import Policy from './classes/Policy';
// static classes
import panelData from './classes/PanelData';
import bugDb from './classes/BugDb';
@@ -39,7 +36,7 @@ import globals from './classes/Globals';
import surrogatedb from './classes/SurrogateDb';
import tabInfo from './classes/TabInfo';
import metrics from './classes/Metrics';
-import rewards from './classes/Rewards';
+import Rewards from './classes/Rewards';
import account from './classes/Account';
import GhosteryModule from './classes/Module';
import promoModals from './classes/PromoModals';
@@ -49,7 +46,7 @@ import { allowAllwaysC2P } from './utils/click2play';
import * as common from './utils/common';
import * as utils from './utils/utils';
import { _getJSONAPIErrorsObject } from './utils/api';
-import { importCliqzSettings } from './utils/cliqzSettingImport';
+import importCliqzSettings from './utils/cliqzSettingImport';
import { sendCliqzModuleCounts } from './utils/cliqzModulesData';
// For debug purposes, provide Access to the internals of `browser-core`
@@ -71,7 +68,7 @@ const IS_FIREFOX = (BROWSER_INFO.name === 'firefox');
const VERSION_CHECK_URL = `${CDN_BASE_URL}/update/version`;
const REAL_ESTATE_ID = 'ghostery';
const onBeforeRequest = events.onBeforeRequest.bind(events);
-const onHeadersReceived = events.onHeadersReceived.bind(events);
+const { onHeadersReceived } = Events;
// Cliqz Modules
const moduleMock = {
@@ -102,41 +99,6 @@ function setCliqzModuleEnabled(module, enabled) {
return Promise.resolve();
}
-/**
- * Check and fetch a new tracker library every hour as needed
- * @memberOf Background
- */
-function autoUpdateBugDb() {
- if (conf.enable_autoupdate) {
- const result = conf.bugs_last_checked;
- const nowTime = Number((new Date()).getTime());
- // offset by 15min so that we don't double fetch
- if (!result || nowTime > (Number(result) + 900000)) {
- log('autoUpdateBugDb called', new Date());
- checkLibraryVersion();
- }
- }
-}
-
-/**
- * Set Default Blocking: all apps in Advertising, Adult Advertising, and Site Analytics
- */
-function setGhosteryDefaultBlocking() {
- const categoriesBlock = ['advertising', 'pornvertising', 'site_analytics'];
- log('Blocking all trackers in categories:', ...categoriesBlock);
- const selected_app_ids = {};
- for (const app_id in bugDb.db.apps) {
- if (bugDb.db.apps.hasOwnProperty(app_id)) {
- const category = bugDb.db.apps[app_id].cat;
- if (categoriesBlock.indexOf(category) >= 0 &&
- !selected_app_ids.hasOwnProperty(app_id)) {
- selected_app_ids[app_id] = 1;
- }
- }
- }
- panelData.set({ selected_app_ids });
-}
-
/**
* Pulls down latest version.json and triggers
* updates of all db files.
@@ -162,7 +124,13 @@ function checkLibraryVersion() {
conf.bugs_last_updated = nowTime;
}
}
- resolve(result);
+ resolve({
+ ...result,
+ confData: {
+ bugs_last_checked: conf.bugs_last_checked,
+ bugs_last_updated: conf.bugs_last_updated
+ }
+ });
});
}).catch((err) => {
log('Error in checkLibraryVersion', err);
@@ -171,6 +139,41 @@ function checkLibraryVersion() {
}));
}
+/**
+ * Check and fetch a new tracker library every hour as needed
+ * @memberOf Background
+ */
+function autoUpdateBugDb() {
+ if (conf.enable_autoupdate) {
+ const result = conf.bugs_last_checked;
+ const nowTime = Number((new Date()).getTime());
+ // offset by 15min so that we don't double fetch
+ if (!result || nowTime > (Number(result) + 900000)) {
+ log('autoUpdateBugDb called', new Date());
+ checkLibraryVersion();
+ }
+ }
+}
+
+/**
+ * Set Default Blocking: all apps in Advertising, Adult Advertising, and Site Analytics
+ */
+function setGhosteryDefaultBlocking() {
+ const categoriesBlock = ['advertising', 'pornvertising', 'site_analytics'];
+ log('Blocking all trackers in categories:', ...categoriesBlock);
+ const selected_app_ids = {};
+ const app_ids = Object.keys(bugDb.db.apps);
+ for (let i = 0; i < app_ids.length; i++) {
+ const app_id = app_ids[i];
+ const category = bugDb.db.apps[app_id].cat;
+ if (categoriesBlock.indexOf(category) >= 0 &&
+ !selected_app_ids.hasOwnProperty(app_id)) {
+ selected_app_ids[app_id] = 1;
+ }
+ }
+ panelData.set({ selected_app_ids });
+}
+
/**
* Reload an open tab.
* @memberOf Background
@@ -445,6 +448,7 @@ function handleClick2Play(name, message, tab_id, callback) {
return true;
}
}
+ return false;
}
/**
@@ -489,20 +493,21 @@ function handleBlockedRedirect(name, message, tab_id, callback) {
function handleRewards(name, message, callback) {
switch (name) {
case 'rewardSignal': // e.g. hub_open | hub_closed
- rewards.sendSignal(message);
+ Rewards.sendSignal(message);
break;
case 'ping':
metrics.ping(message);
break;
case 'setPanelData':
if (message.hasOwnProperty('enable_offers')) {
- rewards.sendSignal(message.signal);
+ Rewards.sendSignal(message.signal);
panelData.set({ enable_offers: message.enable_offers });
}
return callback();
default:
break;
}
+ return false;
}
/**
@@ -574,7 +579,9 @@ function handleGhosteryHub(name, message, callback) {
case 'BLOCKING_POLICY_EVERYTHING': {
panelData.set({ setup_block: 3 });
const selected_app_ids = {};
- for (const app_id in bugDb.db.apps) {
+ const app_ids = Object.keys(bugDb.db.apps);
+ for (let i = 0; i < app_ids.length; i++) {
+ const app_id = app_ids[i];
if (!selected_app_ids.hasOwnProperty(app_id)) {
selected_app_ids[app_id] = 1;
}
@@ -594,7 +601,7 @@ function handleGhosteryHub(name, message, callback) {
}
case 'SET_GHOSTERY_REWARDS': {
const { enable_ghostery_rewards = true } = message;
- rewards.sendSignal({
+ Rewards.sendSignal({
actionId: `rewards_${enable_ghostery_rewards ? 'on' : 'off'}`,
origin: 'ghostery-setup-flow',
type: 'action-signal',
@@ -659,7 +666,7 @@ function handlePurplebox(name, message) {
*/
function onMessageHandler(request, sender, callback) {
if (request.source === 'cliqz-content-script') {
- return;
+ return false;
}
const {
name, message, origin
@@ -706,13 +713,13 @@ function onMessageHandler(request, sender, callback) {
// The message is still sent by panel-android and by the setup hub as of 8.4.0
if (name === 'getPanelData') {
if (!message.tabId) {
- utils.getActiveTab((tab) => {
- const data = panelData.get(message.view, tab);
+ utils.getActiveTab((activeTab) => {
+ const data = panelData.get(message.view, activeTab);
callback(data);
});
} else {
- chrome.tabs.get(+message.tabId, (tab) => {
- const data = panelData.get(message.view, tab);
+ chrome.tabs.get(+message.tabId, (messageTab) => {
+ const data = panelData.get(message.view, messageTab);
callback(data);
});
}
@@ -726,9 +733,9 @@ function onMessageHandler(request, sender, callback) {
return true;
}
if (name === 'getAllStats') {
- insights.action('getAllDays').then((data) => {
- insights.action('getStatsTimeline', moment(data[0]), moment(), true, true).then((data) => {
- callback(data);
+ insights.action('getAllDays').then((dataDays) => {
+ insights.action('getStatsTimeline', moment(dataDays[0]), moment(), true, true).then((dataTimeline) => {
+ callback(dataTimeline);
});
});
return true;
@@ -754,8 +761,8 @@ function onMessageHandler(request, sender, callback) {
return false;
}
if (name === 'getCliqzModuleData') { // panel-android only
- utils.getActiveTab((tab) => {
- sendCliqzModuleCounts(tab.id, tab.pageHost, callback);
+ utils.getActiveTab((activeTab) => {
+ sendCliqzModuleCounts(activeTab.id, activeTab.pageHost, callback);
});
return true;
}
@@ -879,13 +886,12 @@ function onMessageHandler(request, sender, callback) {
}
if (name === 'account.getUser') {
account.getUser(message)
- .then((user) => {
- if (user) {
- user.plusAccess = account.hasScopesUnverified(['subscriptions:plus'])
- || account.hasScopesUnverified(['subscriptions:premium']);
- user.premiumAccess = account.hasScopesUnverified(['subscriptions:premium']);
+ .then((foundUser) => {
+ const user = { user: { ...foundUser } };
+ if (foundUser) {
+ user.user.premiumAccess = account.hasScopesUnverified(['subscriptions:premium']);
}
- callback({ user });
+ callback(user);
})
.catch((err) => {
callback({ errors: _getJSONAPIErrorsObject(err) });
@@ -926,8 +932,8 @@ function onMessageHandler(request, sender, callback) {
return false;
}
if (name === 'getSettingsForExport') {
- utils.getActiveTab((tab) => {
- if (tab && tab.id && tab.url.startsWith('http')) {
+ utils.getActiveTab((activeTab) => {
+ if (activeTab && activeTab.id && activeTab.url.startsWith('http')) {
const settings = account.buildUserSettings();
// Blacklisted and whitelisted sites are removed from sync array,
// but we want to allow export and import these properties manually
@@ -937,8 +943,8 @@ function onMessageHandler(request, sender, callback) {
try {
const hash = common.hashCode(JSON.stringify({ conf: settings }));
const backup = JSON.stringify({ hash, settings: { conf: settings } });
- utils.injectNotifications(tab.id, true).then(() => {
- sendMessage(tab.id, 'exportFile', backup);
+ utils.injectNotifications(activeTab.id, true).then(() => {
+ sendMessage(activeTab.id, 'exportFile', backup);
});
callback(true);
} catch (e) {
@@ -955,11 +961,11 @@ function onMessageHandler(request, sender, callback) {
return false;
}
if (name === 'showBrowseWindow') {
- utils.getActiveTab((tab) => {
- if (tab && tab.id && tab.url.startsWith('http')) {
- utils.injectNotifications(tab.id, true).then((result) => {
+ utils.getActiveTab((activeTab) => {
+ if (activeTab && activeTab.id && activeTab.url.startsWith('http')) {
+ utils.injectNotifications(activeTab.id, true).then((result) => {
if (result) {
- sendMessage(tab.id, 'showBrowseWindow', {
+ sendMessage(activeTab.id, 'showBrowseWindow', {
translations: {
browse_button_label: t('browse_button_label'), // Browse...
select_file_for_import: t('select_file_for_import'), // Select .ghost file for import
@@ -996,6 +1002,69 @@ function onMessageHandler(request, sender, callback) {
promoModals.turnOffPromos();
return false;
}
+ return false;
+}
+
+/**
+ * Determine Antitracking configuration parameters based
+ * on the results returned from the abtest endpoint.
+ * @memberOf Background
+ *
+ * @return {Object} Antitracking configuration parameters
+ */
+function getAntitrackingTestConfig() {
+ if (abtest.hasTest('antitracking_full')) {
+ return {
+ qsEnabled: true,
+ telemetryMode: 2,
+ };
+ }
+ if (abtest.hasTest('antitracking_half')) {
+ return {
+ qsEnabled: true,
+ telemetryMode: 1,
+ };
+ }
+ if (abtest.hasTest('antitracking_collect')) {
+ return {
+ qsEnabled: false,
+ telemetryMode: 1,
+ };
+ }
+ return {
+ qsEnabled: true,
+ telemetryMode: 1,
+ };
+}
+
+/**
+ * Adjust antitracking parameters based on the current state
+ * of ABTest and availability of Human Web.
+ */
+function setupABTest() {
+ const antitrackingConfig = getAntitrackingTestConfig();
+ if (antitrackingConfig && conf.enable_anti_tracking) {
+ if (!conf.enable_human_web) {
+ // force disable anti-tracking telemetry on humanweb opt-out
+ antitrackingConfig.telemetryMode = 0;
+ }
+ Object.keys(antitrackingConfig).forEach((opt) => {
+ const val = antitrackingConfig[opt];
+ log('antitracking', 'set config option', opt, val);
+ antitracking.action('setConfigOption', opt, val);
+ });
+ }
+ if (abtest.hasTest('antitracking_whitelist2')) {
+ cliqz.prefs.set('attrackBloomFilter', false);
+ }
+ // overlay search AB test
+ // if (abtest.hasTest('overlay_search')) {
+ // cliqz.enableModule('search');
+ // cliqz.enableModule('overlay');
+ // } else {
+ // cliqz.disableModule('search');
+ // cliqz.disableModule('overlay');
+ // }
}
/**
@@ -1075,68 +1144,6 @@ function initializeDispatcher() {
});
}
-/**
- * Determine Antitracking configuration parameters based
- * on the results returned from the abtest endpoint.
- * @memberOf Background
- *
- * @return {Object} Antitracking configuration parameters
- */
-function getAntitrackingTestConfig() {
- if (abtest.hasTest('antitracking_full')) {
- return {
- qsEnabled: true,
- telemetryMode: 2,
- };
- }
- if (abtest.hasTest('antitracking_half')) {
- return {
- qsEnabled: true,
- telemetryMode: 1,
- };
- }
- if (abtest.hasTest('antitracking_collect')) {
- return {
- qsEnabled: false,
- telemetryMode: 1,
- };
- }
- return {
- qsEnabled: true,
- telemetryMode: 1,
- };
-}
-
-/**
- * Adjust antitracking parameters based on the current state
- * of ABTest and availability of Human Web.
- */
-function setupABTest() {
- const antitrackingConfig = getAntitrackingTestConfig();
- if (antitrackingConfig && conf.enable_anti_tracking) {
- if (!conf.enable_human_web) {
- // force disable anti-tracking telemetry on humanweb opt-out
- antitrackingConfig.telemetryMode = 0;
- }
- Object.keys(antitrackingConfig).forEach((opt) => {
- const val = antitrackingConfig[opt];
- log('antitracking', 'set config option', opt, val);
- antitracking.action('setConfigOption', opt, val);
- });
- }
- if (abtest.hasTest('antitracking_whitelist2')) {
- cliqz.prefs.set('attrackBloomFilter', false);
- }
- // overlay search AB test
- // if (abtest.hasTest('overlay_search')) {
- // cliqz.enableModule('search');
- // cliqz.enableModule('overlay');
- // } else {
- // cliqz.disableModule('search');
- // cliqz.disableModule('overlay');
- // }
-}
-
/**
* WebRequest pipeline initialisation: find which Cliqz modules are enabled,
* add their handlers, then put Ghostery event handlers before them all.
@@ -1185,7 +1192,7 @@ function initialiseWebRequestPipeline() {
spec: 'collect',
before: existingSteps.onHeadersReceived,
fn: (state) => {
- events.onHeadersReceived(state);
+ Events.onHeadersReceived(state);
return true;
}
})
@@ -1201,7 +1208,7 @@ function initialiseWebRequestPipeline() {
*/
function isWhitelisted(state) {
// state.ghosteryWhitelisted is sometimes undefined so force to bool
- return Boolean(globals.SESSION.paused_blocking || events.policy.getSitePolicy(state.tabUrl, state.url) === 2 || state.ghosteryWhitelisted);
+ return Boolean(globals.SESSION.paused_blocking || Policy.getSitePolicy(state.tabUrl, state.url) === 2 || state.ghosteryWhitelisted);
}
/**
* Set listener for 'enabled' event for Antitracking module which replaces
@@ -1266,12 +1273,12 @@ insights.on('disabled', () => {
*/
function getDataForGhosteryTab(callback) {
const passedData = {};
- insights.action('getAllDays').then((data) => {
- insights.action('getStatsTimeline', moment(data[0]), moment(), true, true).then((data) => {
+ insights.action('getAllDays').then((dataDays) => {
+ insights.action('getStatsTimeline', moment(dataDays[0]), moment(), true, true).then((dataTimeline) => {
const cumulativeData = {
adsBlocked: 0, cookiesBlocked: 0, dataSaved: 0, fingerprintsRemoved: 0, loadTime: 0, pages: 0, timeSaved: 0, trackerRequestsBlocked: 0, trackersBlocked: 0, trackersDetected: 0
};
- data.forEach((entry) => {
+ dataTimeline.forEach((entry) => {
Object.keys(cumulativeData).forEach((key) => {
cumulativeData[key] += entry[key];
});
@@ -1341,10 +1348,10 @@ function initializeEventListeners() {
chrome.webNavigation.onCommitted.addListener(events.onCommitted.bind(events));
// Fired when the page's DOM is fully constructed, but the referenced resources may not finish loading
- chrome.webNavigation.onDOMContentLoaded.addListener(events.onDOMContentLoaded.bind(events));
+ chrome.webNavigation.onDOMContentLoaded.addListener(Events.onDOMContentLoaded.bind(events));
// Fired when a document, including the resources it refers to, is completely loaded and initialized
- chrome.webNavigation.onCompleted.addListener(events.onNavigationCompleted.bind(events));
+ chrome.webNavigation.onCompleted.addListener(Events.onNavigationCompleted.bind(events));
// Fired when a new window, or a new tab in an existing window, is created to host a navigation.
// chrome.webNavigation.onCreatedNavigationTarget
@@ -1369,7 +1376,7 @@ function initializeEventListeners() {
// chrome.webRequest.onBeforeRequest
// Fires when a request is about to send headers
- chrome.webRequest.onBeforeSendHeaders.addListener(events.onBeforeSendHeaders.bind(events), {
+ chrome.webRequest.onBeforeSendHeaders.addListener(Events.onBeforeSendHeaders.bind(events), {
urls: [
'https://l.ghostery.com/*',
'https://d.ghostery.com/*',
@@ -1397,17 +1404,17 @@ function initializeEventListeners() {
});
// Fires when a request could not be processed successfully
- chrome.webRequest.onErrorOccurred.addListener(events.onRequestErrorOccurred.bind(events), {
+ chrome.webRequest.onErrorOccurred.addListener(Events.onRequestErrorOccurred.bind(events), {
urls: ['http://*/*', 'https://*/*']
});
/** * TABS ** */
// Fired when a new tab is created by user or internally
- chrome.tabs.onCreated.addListener(events.onTabCreated.bind(events));
+ chrome.tabs.onCreated.addListener(Events.onTabCreated.bind(events));
// Fires when the active tab in a window changes
- chrome.tabs.onActivated.addListener(events.onTabActivated.bind(events));
+ chrome.tabs.onActivated.addListener(Events.onTabActivated.bind(events));
// Fired when a tab is replaced with another tab due to prerendering
chrome.tabs.onReplaced.addListener(events.onTabReplaced.bind(events));
@@ -1590,7 +1597,7 @@ function initializeGhosteryModules() {
cliqz.events.subscribe('myoffrz:turnoff', () => {
panelData.set({ enable_offers: false });
- rewards.sendSignal({
+ Rewards.sendSignal({
actionId: 'rewards_off',
type: 'action-signal',
});
@@ -1685,11 +1692,13 @@ function init() {
if (conf.current_theme !== 'default') {
return account.getTheme(conf.current_theme);
}
+ return false;
});
}
if (globals.JUST_INSTALLED) {
setGhosteryDefaultBlocking();
}
+ return true;
})
.catch(err => log(err));
// persist Conf properties to storage only after init has completed
diff --git a/src/classes/Account.js b/src/classes/Account.js
index 59d00f788..ccac43193 100644
--- a/src/classes/Account.js
+++ b/src/classes/Account.js
@@ -40,7 +40,8 @@ class Account {
const opts = {
errorHandler: errors => (
new Promise((resolve, reject) => {
- for (const err of errors) {
+ for (let i = 0; i < errors.length; i++) {
+ const err = errors[i];
switch (err.code) {
case '10020': // token is not valid
case '10060': // user id does not match
@@ -359,10 +360,12 @@ class Account {
// check scopes
if (userScopes.indexOf('god') >= 0) { return true; }
- for (const sArr of required) {
+ for (let i = 0; i < required.length; i++) {
+ const sArr = required[i];
let matches = true;
if (sArr.length > 0) {
- for (const s of sArr) {
+ for (let j = 0; j < sArr.length; j++) {
+ const s = sArr[j];
if (userScopes.indexOf(s) === -1) {
matches = false;
break;
@@ -503,7 +506,7 @@ class Account {
conf.account.themeData = {};
}
const { name } = data;
- conf.account.themeData[name] = Object.assign({ timestamp: Date.now() }, data);
+ conf.account.themeData[name] = { timestamp: Date.now(), ...data };
dispatcher.trigger('conf.save.account');
}
@@ -534,20 +537,21 @@ class Account {
* @return {Promise} user settings json or error
*/
_setConfUserSettings = (settings) => {
- log('SET USER SETTINGS', settings);
+ const returnedSettings = { ...settings };
+ log('SET USER SETTINGS', returnedSettings);
if (IS_CLIQZ) {
- settings.enable_human_web = false;
- settings.enable_offers = false;
- settings.enable_ad_block = false;
- settings.enable_anti_tracking = false;
+ returnedSettings.enable_human_web = false;
+ returnedSettings.enable_offers = false;
+ returnedSettings.enable_ad_block = false;
+ returnedSettings.enable_anti_tracking = false;
}
SYNC_SET.forEach((key) => {
- if (settings[key] !== undefined &&
- !isEqual(conf[key], settings[key])) {
- conf[key] = settings[key];
+ if (returnedSettings[key] !== undefined &&
+ !isEqual(conf[key], returnedSettings[key])) {
+ conf[key] = returnedSettings[key];
}
});
- return settings;
+ return returnedSettings;
}
_removeCookies = () => {
diff --git a/src/classes/BrowserButton.js b/src/classes/BrowserButton.js
index 5037166d1..279cbfd09 100644
--- a/src/classes/BrowserButton.js
+++ b/src/classes/BrowserButton.js
@@ -31,7 +31,6 @@ class BrowserButton {
alert: [255, 157, 0, 230],
default: [51, 0, 51, 230]
};
- this.policy = new Policy();
}
/**
@@ -140,7 +139,7 @@ class BrowserButton {
return;
}
- const { appsCount, appsAlertCount } = this._getTrackerCount(tabId);
+ const { appsCount, appsAlertCount } = BrowserButton._getTrackerCount(tabId);
const adBlockingCount = getCliqzData(tabId, tabHostUrl).trackerCount;
const antiTrackingCount = getCliqzData(tabId, tabHostUrl, true).trackerCount;
@@ -151,7 +150,7 @@ class BrowserButton {
if (trackerCount === '') {
this._setIcon(false, tabId, trackerCount, alert);
} else {
- this._setIcon(!globals.SESSION.paused_blocking && !this.policy.checkSiteWhitelist(tab.url), tabId, trackerCount, alert);
+ this._setIcon(!globals.SESSION.paused_blocking && !Policy.checkSiteWhitelist(tab.url), tabId, trackerCount, alert);
}
}
@@ -161,7 +160,7 @@ class BrowserButton {
* @param {string} tabUrl the Tab URL
* @return {Object} the number of total trackers and alerted trackers in an Object
*/
- _getTrackerCount(tabId, tabUrl) {
+ static _getTrackerCount(tabId, tabUrl) {
const apps = foundBugs.getAppsCountByIssues(tabId, tabUrl);
return {
appsCount: apps.all,
diff --git a/src/classes/BugDb.js b/src/classes/BugDb.js
index ea1885ae6..8b714dbd4 100644
--- a/src/classes/BugDb.js
+++ b/src/classes/BugDb.js
@@ -11,9 +11,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0
*/
-/* eslint no-param-reassign: 0 */
-/* eslint no-shadow: 0 */
-
import {
difference, each, every, keys, reduce, size
} from 'underscore';
@@ -37,7 +34,7 @@ class BugDb extends Updatable {
* @param {Object} old_apps trackers in the original database
* @return {Object} list of all new trackers
*/
- updateNewAppIds(new_apps, old_apps) {
+ static updateNewAppIds(new_apps, old_apps) {
log('updating newAppIds...');
const new_app_ids = difference(
@@ -54,7 +51,7 @@ class BugDb extends Updatable {
* Apply block to all new trackers
* @param {Object} new_app_ids list of new trackers
*/
- applyBlockByDefault(new_app_ids) {
+ static applyBlockByDefault(new_app_ids) {
if (conf.block_by_default) {
log('applying block-by-default...');
const { selected_app_ids } = conf;
@@ -74,7 +71,7 @@ class BugDb extends Updatable {
* @param {Object} db bugs database object
* @return {array} array of categories
*/
- _buildCategories(db) {
+ static _buildCategories(db) {
const selectedApps = conf.selected_app_ids || {};
let appId;
let category;
@@ -84,68 +81,67 @@ class BugDb extends Updatable {
const categoryArray = [];
const categories = {};
- for (appId in db.apps) {
- if (db.apps.hasOwnProperty(appId)) {
- category = db.apps[appId].cat;
- if (t(`category_${category}`) === `category_${category}`) {
- category = 'uncategorized';
- }
- blocked = selectedApps.hasOwnProperty(appId);
+ const appIds = Object.keys(db.apps);
+ for (let i = 0; i < appIds.length; i++) {
+ appId = appIds[i];
+ category = db.apps[appId].cat;
+ if (t(`category_${category}`) === `category_${category}`) {
+ category = 'uncategorized';
+ }
+ blocked = selectedApps.hasOwnProperty(appId);
- // Because we have two trackers in the DB with the same name
- if ((categories[category] && categories[category].trackers[db.apps[appId].name])) {
- // eslint-disable-next-line no-continue
- continue;
- }
+ // Because we have two trackers in the DB with the same name
+ if ((categories[category] && categories[category].trackers[db.apps[appId].name])) {
+ continue; // eslint-disable-line no-continue
+ }
- if (categories.hasOwnProperty(category)) {
- categories[category].num_total++;
- if (blocked) {
- categories[category].num_blocked++;
- }
- } else {
- categories[category] = {
- id: category,
- name: t(`category_${category}`),
- description: t(`category_${category}_desc`),
- img_name: (category === 'advertising') ? 'adv' : // Because AdBlock blocks images with 'advertising' in the name.
- (category === 'social_media') ? 'smed' : category, // Because AdBlock blocks images with 'social' in the name.
- num_total: 1,
- num_blocked: (blocked) ? 1 : 0,
- trackers: []
- };
+ if (categories.hasOwnProperty(category)) {
+ categories[category].num_total++;
+ if (blocked) {
+ categories[category].num_blocked++;
}
- categories[category].trackers.push({
- id: appId,
- name: db.apps[appId].name,
- description: '',
- blocked,
- shouldShow: true,
- catId: category,
- });
+ } else {
+ categories[category] = {
+ id: category,
+ name: t(`category_${category}`),
+ description: t(`category_${category}_desc`),
+ img_name: (category === 'advertising') ? 'adv' : // Because AdBlock blocks images with 'advertising' in the name.
+ (category === 'social_media') ? 'smed' : category, // Because AdBlock blocks images with 'social' in the name.
+ num_total: 1,
+ num_blocked: (blocked) ? 1 : 0,
+ trackers: []
+ };
}
+ categories[category].trackers.push({
+ id: appId,
+ name: db.apps[appId].name,
+ description: '',
+ blocked,
+ shouldShow: true,
+ catId: category,
+ });
}
- for (categoryName in categories) {
- if (categories.hasOwnProperty(categoryName)) {
- const category = categories[categoryName];
- if (category.trackers) {
- category.trackers.sort((a, b) => {
- a = a.name.toLowerCase();
- b = b.name.toLowerCase();
- return (a > b ? 1 : (a < b ? -1 : 0));
- });
- }
-
- categoryArray.push(category);
+ const categoryNames = Object.keys(categories);
+ for (let i = 0; i < categoryNames.length; i++) {
+ categoryName = categoryNames[i];
+ const cat = categories[categoryName];
+ if (cat.trackers) {
+ cat.trackers.sort((a, b) => {
+ const a1 = a.name.toLowerCase();
+ const b1 = b.name.toLowerCase();
+ return (a1 > b1 ? 1 : (a1 < b1 ? -1 : 0));
+ });
}
+
+ categoryArray.push(cat);
}
// Sort categories by tracker numbers
categoryArray.sort((a, b) => {
- a = a.trackers ? a.trackers.length : 0;
- b = b.trackers ? b.trackers.length : 0;
- return (a > b ? -1 : (a < b ? 1 : 0));
+ const a1 = a.trackers ? a.trackers.length : 0;
+ const b1 = b.trackers ? b.trackers.length : 0;
+ return (a1 > b1 ? -1 : (a1 < b1 ? 1 : 0));
});
return categoryArray;
@@ -179,10 +175,10 @@ class BugDb extends Updatable {
log('initializing bugdb regexes...');
- for (const id in regexes) {
- if (regexes.hasOwnProperty(id)) {
- db.patterns.regex[id] = new RegExp(regexes[id], 'i');
- }
+ const regexesKeys = Object.keys(regexes);
+ for (let i = 0; i < regexesKeys.length; i++) {
+ const id = regexesKeys[i];
+ db.patterns.regex[id] = new RegExp(regexes[id], 'i');
}
log('setting bugdb noneSelected/allSelected...');
@@ -192,8 +188,8 @@ class BugDb extends Updatable {
// since allSelected is slow to eval, make it lazy
defineLazyProperty(db, 'allSelected', () => {
- const num_selected = size(conf.selected_app_ids);
- return (!!num_selected && every(db.apps, (app, app_id) => conf.selected_app_ids.hasOwnProperty(app_id)));
+ const num_selected_lazy = size(conf.selected_app_ids);
+ return (!!num_selected_lazy && every(db.apps, (app, app_id) => conf.selected_app_ids.hasOwnProperty(app_id)));
});
log('processed bugdb...');
@@ -205,24 +201,24 @@ class BugDb extends Updatable {
// update newAppIds and apply block-by-default
if (old_bugs) {
if (old_bugs.hasOwnProperty('version') && bugs.version > old_bugs.version) {
- new_app_ids = this.updateNewAppIds(bugs.apps, old_bugs.apps);
+ new_app_ids = BugDb.updateNewAppIds(bugs.apps, old_bugs.apps);
if (new_app_ids.length) {
- this.applyBlockByDefault(new_app_ids);
+ BugDb.applyBlockByDefault(new_app_ids);
db.JUST_UPDATED_WITH_NEW_TRACKERS = true;
}
// pre-trie/legacy db
} else if (old_bugs.hasOwnProperty('bugsVersion') && bugs.version !== old_bugs.bugsVersion) {
- const old_apps = reduce(old_bugs.bugs, (memo, bug) => {
- memo[bug.aid] = true;
- return memo;
+ const old_apps = reduce(old_bugs.bugs, (acc, bug) => {
+ acc[bug.aid] = true;
+ return acc;
}, {});
- new_app_ids = this.updateNewAppIds(bugs.apps, old_apps);
+ new_app_ids = BugDb.updateNewAppIds(bugs.apps, old_apps);
if (new_app_ids.length) {
- this.applyBlockByDefault(new_app_ids);
+ BugDb.applyBlockByDefault(new_app_ids);
// don't claim new trackers when db got downgraded by version
if (bugs.version > old_bugs.bugsVersion) {
@@ -235,7 +231,7 @@ class BugDb extends Updatable {
conf.bugs = bugs;
}
- db.categories = this._buildCategories(db);
+ db.categories = BugDb._buildCategories(db);
this.db = db;
diff --git a/src/classes/CMP.js b/src/classes/CMP.js
index e22ad49d4..f63d3e8f4 100644
--- a/src/classes/CMP.js
+++ b/src/classes/CMP.js
@@ -52,20 +52,20 @@ class CMP {
return getJson(URL).then((data) => {
if (data && (!conf.cmp_version || data.Version > conf.cmp_version)) {
// set default dismiss
- data.Campaigns.forEach((campaign) => {
- if (campaign.Dismiss === 0) {
- campaign.Dismiss = 10;
+ data.Campaigns.forEach((dataEntry) => {
+ if (dataEntry.Dismiss === 0) {
+ dataEntry.Dismiss = 10;
}
- // set last campaign run timestamp to avoid running campaigns more than once
- if (!conf.last_cmp_date || conf.last_cmp_date < campaign.Timestamp) {
- conf.last_cmp_date = campaign.Timestamp;
+ // set last campaign (dataEntry) run timestamp to avoid running campaigns more than once
+ if (!conf.last_cmp_date || conf.last_cmp_date < dataEntry.Timestamp) {
+ conf.last_cmp_date = dataEntry.Timestamp;
}
});
// update Conf and local CMP_DATA
conf.cmp_version = data.Version;
- // eslint-disable-next-line no-multi-assign
- globals.SESSION.cmp_data = this.CMP_DATA = data.Campaigns;
+ globals.SESSION.cmp_data = data.Campaigns;
+ this.CMP_DATA = data.Campaigns;
return this.CMP_DATA;
}
// getJson() returned a 204, meaning no new campaigns available
diff --git a/src/classes/Click2PlayDb.js b/src/classes/Click2PlayDb.js
index 40324e497..16fc6847e 100644
--- a/src/classes/Click2PlayDb.js
+++ b/src/classes/Click2PlayDb.js
@@ -11,8 +11,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0
*/
-/* eslint no-use-before-define: 0 */
-
import conf from './Conf';
import Updatable from './Updatable';
import { log } from '../utils/common';
@@ -43,7 +41,7 @@ class Click2PlayDb extends Updatable {
log('processing c2p...');
try {
- db = this._buildDb(data.click2play, data.click2playVersion);
+ db = Click2PlayDb._buildDb(data.click2play, data.click2playVersion);
} catch (e) {
log('Click2PlayDb processList() error', e);
return false;
@@ -68,9 +66,11 @@ class Click2PlayDb extends Updatable {
reset(tab_id) {
if (!this.allowOnceList.hasOwnProperty(tab_id)) { return; }
- const entries = Object.entries(this.allowOnceList[tab_id]);
let keep = false;
- for (const [appID, count] of entries) {
+ const allowKeys = Object.keys(this.allowOnceList[tab_id]);
+ for (let i = 0; i < allowKeys.length; i++) {
+ const appID = allowKeys[i];
+ const count = this.allowOnceList[tab_id][appID];
const newCount = count - 1;
this.allowOnceList[tab_id][appID] = newCount;
if (newCount > 0) {
@@ -108,7 +108,7 @@ class Click2PlayDb extends Updatable {
* @param {string} version database version
* @return {Object} reconfigured database object
*/
- _buildDb(entries, version) {
+ static _buildDb(entries, version) {
const apps = {};
let allow;
diff --git a/src/classes/CompatibilityDb.js b/src/classes/CompatibilityDb.js
index 914e7d613..94afc446e 100644
--- a/src/classes/CompatibilityDb.js
+++ b/src/classes/CompatibilityDb.js
@@ -36,7 +36,7 @@ class CompatibilityDb extends Updatable {
log('processing comp...');
try {
- db = this._buildDb(comp.compatibility, comp.compatibilityVersion);
+ db = CompatibilityDb._buildDb(comp.compatibility, comp.compatibilityVersion);
} catch (e) {
log('CompatibilityDb processList() error', e);
return false;
@@ -79,7 +79,7 @@ class CompatibilityDb extends Updatable {
* @param {string} version database version
* @return {Object} Refactored database
*/
- _buildDb(bugs, version) {
+ static _buildDb(bugs, version) {
const map = {};
bugs.forEach((s) => {
diff --git a/src/classes/Conf.js b/src/classes/Conf.js
index d572778b6..067ec0b6f 100644
--- a/src/classes/Conf.js
+++ b/src/classes/Conf.js
@@ -23,8 +23,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-/* eslint no-param-reassign: 0 */
-
import { debounce } from 'underscore';
import confData from './ConfData';
import { pref, log } from '../utils/common';
@@ -47,12 +45,13 @@ const { IS_CLIQZ } = globals;
const handler = {
/**
* A trap for setting property values
- * @param {Object} target the target confData object
- * @param {*} value the value of the confData property being set
+ * @param {Object} confMutable the target confData object
+ * @param {*} v the value of the confData property being set
* @param {string} key the name of the confData property being set
- * @return {boolean} always return true, indicating success.
+ * @return {boolean} always return true, indicating success.
*/
- set(target, key, value) {
+ set(confMutable, key, v) {
+ let value = v;
log('Setting update value for', key);
// Ghostery, while running as an extension in the Cliqz browser
// has these functionalities disabled. This is protection from
@@ -75,7 +74,7 @@ const handler = {
}
}
- target[key] = value;
+ confMutable[key] = value;
// Don't save to storage while background::init() called.
// Rather collect properties and save them once init is over.
@@ -88,7 +87,7 @@ const handler = {
// notify specific key subscribers
dispatcher.trigger(`conf.save.${key}`, value);
// notify catch all settings subscribers
- if (target.SYNC_SET.has(key) || key === 'bugs_last_checked') {
+ if (confMutable.SYNC_SET.has(key) || key === 'bugs_last_checked') {
dispatcher.trigger('conf.changed.settings', key);
}
diff --git a/src/classes/ConfData.js b/src/classes/ConfData.js
index cd62556e2..ffdc87225 100644
--- a/src/classes/ConfData.js
+++ b/src/classes/ConfData.js
@@ -16,8 +16,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0
*/
-/* eslint no-use-before-define: 0 */
-
import globals from './Globals';
import { prefsGet } from '../utils/common';
@@ -37,7 +35,7 @@ const IS_FIREFOX = (BROWSER_INFO.name === 'firefox');
class ConfData {
constructor() {
// language does not get persisted
- this.language = this._getDefaultLanguage();
+ this.language = ConfData._getDefaultLanguage();
this.SYNC_SET = new Set(globals.SYNC_ARRAY);
}
@@ -47,8 +45,14 @@ class ConfData {
* This method is called once on startup.
*/
init() {
- return prefsGet().then((data) => {
+ return prefsGet().then((d) => {
+ const data = { ...d };
const nowTime = Number(new Date().getTime());
+ const _setProp = (name, value) => {
+ if (!globals.INIT_COMPLETE) {
+ globals.initProps[name] = value;
+ }
+ };
const _initProperty = (name, value) => {
if (data[name] === null || typeof (data[name]) === 'undefined') {
data[name] = value;
@@ -56,11 +60,6 @@ class ConfData {
}
this[name] = data[name];
};
- const _setProp = (name, value) => {
- if (!globals.INIT_COMPLETE) {
- globals.initProps[name] = value;
- }
- };
// Transfer legacy previous version property to new name
const { previous_version } = data;
@@ -165,7 +164,7 @@ class ConfData {
});
}
- _getDefaultLanguage() {
+ static _getDefaultLanguage() {
const SUPPORTED_LANGUAGES = {
de: 'Deutsch',
en: 'English',
diff --git a/src/classes/Dispatcher.js b/src/classes/Dispatcher.js
index a8e8ed5d3..312a8fdc7 100644
--- a/src/classes/Dispatcher.js
+++ b/src/classes/Dispatcher.js
@@ -14,8 +14,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0
*/
-/* eslint no-param-reassign: 0 */
-
import { log } from '../utils/common';
/**
* Class for dispatching events. Though generic, it is used
@@ -30,11 +28,12 @@ class Dispatcher {
// subscribe
on(event, handler, context) {
+ let c = context;
log('dispatcher.on called from', event);
- if (typeof context === 'undefined') {
- context = handler;
+ if (typeof c === 'undefined') {
+ c = handler;
}
- this.handlers.set(event, handler.bind(context));
+ this.handlers.set(event, handler.bind(c));
}
// publish
diff --git a/src/classes/EventHandlers.js b/src/classes/EventHandlers.js
index f84b7a6db..8d719e0bd 100644
--- a/src/classes/EventHandlers.js
+++ b/src/classes/EventHandlers.js
@@ -72,7 +72,7 @@ class EventHandlers {
log(`❤ ❤ ❤ Tab ${tabId} navigating to ${url} ❤ ❤ ❤`);
this._clearTabData(tabId);
- this._resetNotifications();
+ EventHandlers._resetNotifications();
// TODO understand why this does not work when placed in the 'reload' branch in onCommitted
panelData.clearPageLoadTime(tabId);
@@ -80,7 +80,7 @@ class EventHandlers {
tabInfo.create(tabId, url);
foundBugs.update(tabId);
button.update(tabId);
- this._eventReset(details.tabId);
+ EventHandlers._eventReset(details.tabId);
// Workaround for foundBugs/tabInfo memory leak when the user triggers
// prefetching/prerendering but never loads the page. Wait two minutes
@@ -89,7 +89,7 @@ class EventHandlers {
utils.getTab(tabId, null, () => {
log('Clearing orphan tab data for tab', tabId);
this._clearTabData(tabId);
- this._resetNotifications();
+ EventHandlers._resetNotifications();
});
}, 120000);
}
@@ -143,7 +143,7 @@ class EventHandlers {
*
* @param {Object} details event data
*/
- onDOMContentLoaded(details) {
+ static onDOMContentLoaded(details) {
const tab_id = details.tabId;
// ignore if this is a sub-frame
@@ -280,7 +280,7 @@ class EventHandlers {
*
* @param {Object} details event data
*/
- onNavigationCompleted(details) {
+ static onNavigationCompleted(details) {
if (!utils.isValidTopLevelNavigation(details)) {
return;
}
@@ -289,7 +289,7 @@ class EventHandlers {
log(`foundBugs: ${foundBugs.getAppsCount(details.tabId)}, tab_id: ${details.tabId}`);
// inject page_performance script to display page latency on Summary view
- if (this._isValidUrl(utils.processUrl(details.url))) {
+ if (EventHandlers._isValidUrl(utils.processUrl(details.url))) {
utils.injectScript(details.tabId, 'dist/page_performance.js', '', 'document_idle').catch((err) => {
log('onNavigationCompleted injectScript error', err);
});
@@ -310,13 +310,13 @@ class EventHandlers {
// TODO what other webRequest-restricted pages are out there?
if (details.url.startsWith('https://chrome.google.com/webstore/')) {
this._clearTabData(tab_id);
- this._resetNotifications();
+ EventHandlers._resetNotifications();
}
return;
}
- this._eventReset(tab_id);
+ EventHandlers._eventReset(tab_id);
}
/**
@@ -328,12 +328,12 @@ class EventHandlers {
* + Speed this up by making it asynchronous when blocking is disabled?
* + Also speed it up for blocking-whitelisted pages (by delaying isBug scanning)?
*
- * @param {Object} details event data
- * @return {Object} optionaly return {cancel: true} to force dropping the request
+ * @param {Object} eventMutable event data
+ * @return {Object} optionaly return {cancel: true} to force dropping the request
*/
- onBeforeRequest(details) {
- const tab_id = details.tabId;
- const request_id = details.requestId;
+ onBeforeRequest(eventMutable) {
+ const tab_id = eventMutable.tabId;
+ const request_id = eventMutable.requestId;
// -1 indicates the request isn't related to a tab
if (tab_id <= 0) {
@@ -344,8 +344,8 @@ class EventHandlers {
log(`tabInfo not found for tab ${tab_id}, initializing...`);
// create new tabInfo entry
- if (details.type === 'main_frame') {
- tabInfo.create(tab_id, details.url);
+ if (eventMutable.type === 'main_frame') {
+ tabInfo.create(tab_id, eventMutable.url);
} else {
tabInfo.create(tab_id);
}
@@ -361,24 +361,24 @@ class EventHandlers {
});
}
- if (!this._checkRedirect(details.type, request_id)) {
+ if (!EventHandlers._checkRedirect(eventMutable.type, request_id)) {
return { cancel: false };
}
const page_protocol = tabInfo.getTabInfo(tab_id, 'protocol');
const from_redirect = globals.REDIRECT_MAP.has(request_id);
- const processed = utils.processUrl(details.url);
+ const processed = utils.processUrl(eventMutable.url);
/* ** SMART BLOCKING - Privacy ** */
// block HTTP request on HTTPS page
- if (this.policySmartBlock.isInsecureRequest(tab_id, page_protocol, processed.scheme, processed.hostname)) {
- return this._blockHelper(details, tab_id, null, null, request_id, from_redirect, true);
+ if (PolicySmartBlock.isInsecureRequest(tab_id, page_protocol, processed.scheme, processed.hostname)) {
+ return EventHandlers._blockHelper(eventMutable, tab_id, null, null, request_id, from_redirect, true);
}
// TODO fuse this into a single call to improve performance
const page_url = tabInfo.getTabInfo(tab_id, 'url');
const page_domain = tabInfo.getTabInfo(tab_id, 'domain');
- const bug_id = (page_url ? isBug(details.url, page_url) : isBug(details.url));
+ const bug_id = (page_url ? isBug(eventMutable.url, page_url) : isBug(eventMutable.url));
// allow if not a tracker
if (!bug_id) {
@@ -387,12 +387,12 @@ class EventHandlers {
this._throttleButtonUpdate();
return { cancel: false };
}
- // add the bugId to the details object. This can then be read by other handlers on this pipeline.
- details.ghosteryBug = bug_id;
+ // add the bugId to the eventMutable object. This can then be read by other handlers on this pipeline.
+ eventMutable.ghosteryBug = bug_id;
/* ** SMART BLOCKING - Breakage ** */
// allow first party trackers
- if (this.policySmartBlock.isFirstPartyRequest(tab_id, page_domain, processed.generalDomain)) {
+ if (PolicySmartBlock.isFirstPartyRequest(tab_id, page_domain, processed.generalDomain)) {
return { cancel: false };
}
@@ -401,10 +401,10 @@ class EventHandlers {
const incognito = tabInfo.getTabInfo(tab_id, 'incognito');
const tab_host = tabInfo.getTabInfo(tab_id, 'host');
const fromRedirect = globals.REDIRECT_MAP.has(request_id);
- const { block, reason } = this._checkBlocking(app_id, cat_id, tab_id, tab_host, page_url, request_id);
+ const { block, reason } = EventHandlers._checkBlocking(app_id, cat_id, tab_id, tab_host, page_url, request_id);
if (!block && reason === BLOCK_REASON_SS_UNBLOCKED) {
// The way to pass this flag to Cliqz handlers
- details.ghosteryWhitelisted = true;
+ eventMutable.ghosteryWhitelisted = true;
}
// Latency initialization needs to be synchronous to avoid race condition with onCompleted, etc.
// TODO can URLs repeat within a redirect chain? what are the cases of repeating URLs (trackers only, ...)?
@@ -412,8 +412,8 @@ class EventHandlers {
// Store latency data keyed by URL so that we don't use the wrong latencies in a redirect chain.
latency.latencies[request_id] = latency.latencies[request_id] || {};
- latency.latencies[request_id][details.url] = {
- start_time: Math.round(details.timeStamp),
+ latency.latencies[request_id][eventMutable.url] = {
+ start_time: Math.round(eventMutable.timeStamp),
bug_id,
// these could be undefined
page_url,
@@ -421,8 +421,8 @@ class EventHandlers {
};
}
- const smartBlocked = !block ? this.policySmartBlock.shouldBlock(app_id, cat_id, tab_id, page_url, details.type, details.timeStamp) : false;
- const smartUnblocked = block ? this.policySmartBlock.shouldUnblock(app_id, cat_id, tab_id, page_url, details.type) : false;
+ const smartBlocked = !block ? this.policySmartBlock.shouldBlock(app_id, cat_id, tab_id, page_url, eventMutable.type, eventMutable.timeStamp) : false;
+ const smartUnblocked = block ? this.policySmartBlock.shouldUnblock(app_id, cat_id, tab_id, page_url, eventMutable.type) : false;
// process the tracker asynchronously
// very important to block request processing as little as necessary
@@ -430,17 +430,18 @@ class EventHandlers {
this._processBug({
bug_id,
app_id,
- type: details.type,
- url: details.url,
+ type: eventMutable.type,
+ url: eventMutable.url,
block,
smartBlocked,
tab_id,
- from_frame: details.parentFrameId !== -1
+ from_frame: eventMutable.parentFrameId !== -1,
+ request_id
});
}, 1);
if ((block && !smartUnblocked) || smartBlocked) {
- return this._blockHelper(details, tab_id, app_id, bug_id, request_id, fromRedirect);
+ return EventHandlers._blockHelper(eventMutable, tab_id, app_id, bug_id, request_id, fromRedirect);
}
return { cancel: false };
@@ -450,10 +451,11 @@ class EventHandlers {
* Handler for webRequest.onBeforeSendHeaders event.
* Called each time that an HTTP(S) request is about to send headers
*
- * @param {Object} details event data
+ * @param {Object} d event data
* @return {Object} optionally return headers to send
*/
- onBeforeSendHeaders(details) {
+ static onBeforeSendHeaders(d) {
+ const details = { ...d };
for (let i = 0; i < details.requestHeaders.length; ++i) {
// Fetch requests in Firefox web-extension has a flaw. They attach
// origin: moz-extension//ID , which is specific to a user.
@@ -475,9 +477,9 @@ class EventHandlers {
*
* @param {Object} details event data
*/
- onHeadersReceived(details) {
+ static onHeadersReceived(details) {
// Skip content-length collection if it's a 3XX (redirect)
- if (details.statusCode >> 8 === 1) { } // eslint-disable-line
+ if (details.statusCode >> 8 === 1) { } // eslint-disable-line no-bitwise, no-empty
}
/**
@@ -509,7 +511,7 @@ class EventHandlers {
if (!details || details.tabId <= 0) {
return;
}
- this._clearRedirects(details.requestId);
+ EventHandlers._clearRedirects(details.requestId);
if (details.type !== 'main_frame') {
const appWithLatencyId = latency.logLatency(details);
@@ -527,9 +529,9 @@ class EventHandlers {
*
* @param {Object} details event data
*/
- onRequestErrorOccurred(details) {
+ static onRequestErrorOccurred(details) {
latency.logLatency(details);
- this._clearRedirects(details.requestId);
+ EventHandlers._clearRedirects(details.requestId);
}
/**
@@ -538,7 +540,7 @@ class EventHandlers {
*
* @param {Object} tab Details of the tab that was created
*/
- onTabCreated(tab) {
+ static onTabCreated(tab) {
const { url } = tab;
metrics.handleBrokenPageTrigger(globals.BROKEN_PAGE_NEW_TAB, url);
@@ -550,9 +552,9 @@ class EventHandlers {
*
* @param {Object} activeInfo tab data
*/
- onTabActivated(activeInfo) {
+ static onTabActivated(activeInfo) {
button.update(activeInfo.tabId);
- this._resetNotifications();
+ EventHandlers._resetNotifications();
}
/**
@@ -584,7 +586,7 @@ class EventHandlers {
*/
onTabRemoved(tab_id) {
this._clearTabData(tab_id);
- this._resetNotifications();
+ EventHandlers._resetNotifications();
}
/**
@@ -597,7 +599,7 @@ class EventHandlers {
*/
_processBug(details) {
const {
- bug_id, app_id, type, url, block, smartBlocked, tab_id
+ bug_id, app_id, type, url, block, smartBlocked, tab_id, request_id
} = details;
const tab = tabInfo.getTabInfo(tab_id);
const allowedOnce = c2pDb.allowedOnce(details.tab_id, app_id);
@@ -611,7 +613,7 @@ class EventHandlers {
num_apps_old = foundBugs.getAppsCount(tab_id);
}
- foundBugs.update(tab_id, bug_id, url, block, type);
+ foundBugs.update(tab_id, bug_id, url, block, type, request_id);
this._throttleButtonUpdate(details.tab_id);
@@ -644,7 +646,7 @@ class EventHandlers {
* @param {boolean} fromRedirect
* @return {string|boolean}
*/
- _blockHelper(details, tabId, appId, bugId, requestId, fromRedirect, upgradeInsecure) {
+ static _blockHelper(details, tabId, appId, bugId, requestId, fromRedirect, upgradeInsecure) {
if (upgradeInsecure) {
// attempt to redirect request to HTTPS. NOTE: Redirects from URLs
// with ws:// and wss:// schemes are ignored.
@@ -673,16 +675,13 @@ class EventHandlers {
if (details.type === 'script' && bugId) {
let code = '';
if (appId === 2575) { // Hubspot
- code = this._getHubspotFormSurrogate(details.url);
+ code = EventHandlers._getHubspotFormSurrogate(details.url);
} else {
const ti = tabInfo.getTabInfo(tabId);
const surrogates = surrogatedb.getForTracker(details.url, appId, bugId, ti.host);
if (surrogates.length > 0) {
- code = reduce(surrogates, (memo, s) => {
- memo += s.code; // eslint-disable-line no-param-reassign
- return memo;
- }, '');
+ code = reduce(surrogates, (memo, s) => memo + s.code, '');
}
}
@@ -715,7 +714,7 @@ class EventHandlers {
* @param {URL} parsedURL
* @return {Boolean}
*/
- _isValidUrl(parsedURL) {
+ static _isValidUrl(parsedURL) {
if (parsedURL && parsedURL.protocol.startsWith('http') && parsedURL.isValidHost() && !parsedURL.pathname.includes('_/chrome/newtab')) {
return true;
}
@@ -731,7 +730,7 @@ class EventHandlers {
* @param {string} form request url
* @return {string} surrogate code
*/
- _getHubspotFormSurrogate(url) {
+ static _getHubspotFormSurrogate(url) {
// Hubspot url has a fixed format
// https://forms.hubspot.com/embed/v3/form/532040/95b5de3a-6d4a-4729-bebf-07c41268d773?callback=hs_reqwest_0&hutk=941df50e9277ee76755310cd78647a08
// The following three parameters are privacy-safe:
@@ -740,7 +739,7 @@ class EventHandlers {
// hs_reqwest_0 - function which will be called on the client after the request
//
// hutk=941df50e9277ee76755310cd78647a08 -is user-specific (same every session)
- const tokens = url.substr(8).split(/\/|\&|\?|\#|\=/ig); // eslint-disable-line no-useless-escape
+ const tokens = url.substr(8).split(/\/|&|\?|#|=/ig);
return `${tokens[7]}({"form":{"portalId":${tokens[4]},"guid": "${tokens[5]}","cssClass":"hs-form stacked","formFieldGroups":[{"fields":[{}]}],"metaData":[]},"properties":{}})`;
}
@@ -784,7 +783,7 @@ class EventHandlers {
*
* @param {number} requestId
*/
- _clearRedirects(requestId) {
+ static _clearRedirects(requestId) {
globals.REDIRECT_MAP.delete(requestId);
globals.LET_REDIRECTS_THROUGH = false;
}
@@ -798,7 +797,7 @@ class EventHandlers {
* @param {number} request_id request id
* @return {boolean}
*/
- _checkRedirect(type, request_id) {
+ static _checkRedirect(type, request_id) {
const fromRedirect = globals.REDIRECT_MAP.has(request_id);
// if the request is part of the main_frame and not a redirect, we don't proceed
if (type === 'main_frame' && !fromRedirect) {
@@ -827,7 +826,7 @@ class EventHandlers {
* @param {number} request_id request id
* @return {BlockWithReason} block result with reason
*/
- _checkBlocking(app_id, cat_id, tab_id, tab_host, page_url, request_id) {
+ static _checkBlocking(app_id, cat_id, tab_id, tab_host, page_url, request_id) {
const fromRedirect = globals.REDIRECT_MAP.has(request_id);
let block;
@@ -836,7 +835,7 @@ class EventHandlers {
if (fromRedirect && globals.LET_REDIRECTS_THROUGH) {
block = { block: false, reason: BLOCK_REASON_C2P_ALLOWED_THROUGH };
} else {
- block = this.policy.shouldBlock(app_id, cat_id, tab_id, tab_host, page_url);
+ block = Policy.shouldBlock(app_id, cat_id, tab_id, tab_host, page_url);
}
return block;
@@ -849,7 +848,7 @@ class EventHandlers {
*
* @param {number} tab_id tab id
*/
- _eventReset(tab_id) {
+ static _eventReset(tab_id) {
c2pDb.reset(tab_id);
globals.REDIRECT_MAP.clear();
globals.LET_REDIRECTS_THROUGH = false;
@@ -877,7 +876,7 @@ class EventHandlers {
* @private
*
*/
- _resetNotifications() {
+ static _resetNotifications() {
globals.NOTIFICATIONS_LOADED = false;
}
}
diff --git a/src/classes/ExtMessenger.js b/src/classes/ExtMessenger.js
index badcc0ecc..28367c771 100644
--- a/src/classes/ExtMessenger.js
+++ b/src/classes/ExtMessenger.js
@@ -11,25 +11,22 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0
*/
-/* eslint max-classes-per-file: 0 */
-
-import Spanan from 'spanan';
import { log } from '../utils/common';
/**
* Factory class for messaging handlers
* @memberOf BackgroundClasses
*/
-export class ExtMessenger {
- addListener(fn) {
+export default class ExtMessenger {
+ static addListener(fn) {
chrome.runtime.onMessageExternal.addListener(fn);
}
- removeListener(fn) {
+ static removeListener(fn) {
chrome.runtime.onMessageExternal.removeListener(fn);
}
- sendMessage(extensionId, message) {
+ static sendMessage(extensionId, message) {
chrome.runtime.sendMessage(extensionId, message, () => {
if (chrome.runtime.lastError) {
log('ExtMessenger sendMessage error:', chrome.runtime.lastError);
@@ -37,50 +34,3 @@ export class ExtMessenger {
});
}
}
-
-/**
- * Class for handling cross-extension messaging.
- * @memberOf BackgroundClasses
- */
-export default class KordInjector {
- constructor() {
- this.messenger = new ExtMessenger();
- this.extensionId = 'cliqz@cliqz.com';
- this.moduleWrappers = new Map();
- this._messageHandler = this._messageHandler.bind(this);
- }
-
- init() {
- this.messenger.addListener(this._messageHandler);
- }
-
- unload() {
- this.messenger.removeListener(this._messageHandler);
- }
-
- module(moduleName) {
- if (!this.moduleWrappers.has(moduleName)) {
- this.moduleWrappers.set(moduleName, this._createModuleWrapper(moduleName));
- }
- const wrapper = this.moduleWrappers.get(moduleName);
- return wrapper.createProxy();
- }
-
- _createModuleWrapper(moduleName) {
- return new Spanan((message) => {
- message.moduleName = moduleName;
- this.messenger.sendMessage(this.extensionId, message);
- });
- }
-
- _messageHandler(messageJSON, sender) {
- const message = JSON.parse(messageJSON);
- if (sender.id !== this.extensionId) {
- return;
- }
- if (!this.moduleWrappers.has(message.moduleName)) {
- log('KordInjector error: Unhandled message', message);
- }
- this.moduleWrappers.get(message.moduleName).handleMessage(message);
- }
-}
diff --git a/src/classes/FoundBugs.js b/src/classes/FoundBugs.js
index 2d1dd854a..fd2cd17d4 100644
--- a/src/classes/FoundBugs.js
+++ b/src/classes/FoundBugs.js
@@ -32,7 +32,8 @@ class FoundBugs {
* sources: [{
* src: string,
* blocked: boolean,
- * type: string
+ * type: string,
+ * request_id: string
* }]
* }
* }
@@ -50,7 +51,8 @@ class FoundBugs {
* sources: [{
* src: string,
* blocked: boolean,
- * type: string
+ * type: string,
+ * request_id: string
* }]
* }],
* appsMetadata: {
@@ -88,8 +90,9 @@ class FoundBugs {
* @param {string} src resource url
* @param {boolean} blocked blocking status of the tracker id from this tab_id
* @param {string} type request resource type
+ * @param {string} request_id request_id for the resource to use as a unique id
*/
- update(tab_id, bug_id, src, blocked, type) {
+ update(tab_id, bug_id, src, blocked, type, request_id) {
if (!this._init(tab_id)) {
return;
}
@@ -98,7 +101,7 @@ class FoundBugs {
return;
}
- this._updateFoundBugs(tab_id, bug_id, src, blocked, type);
+ this._updateFoundBugs(tab_id, bug_id, src, blocked, type, request_id);
this._updateFoundApps(tab_id, bug_id);
}
@@ -192,7 +195,7 @@ class FoundBugs {
const { db } = bugDb;
let id;
- let aid;
+ let appid;
let cid; // category id
if (!bugs) {
@@ -200,56 +203,56 @@ class FoundBugs {
}
// squish all the bugs into categories first
- for (id in bugs) {
- if (bugs.hasOwnProperty(id)) {
- aid = db.bugs[id].aid; // eslint-disable-line prefer-destructuring
- cid = db.apps[aid].cat;
-
- if (cats_obj.hasOwnProperty(cid)) {
- if (!cats_obj[cid].appIds.includes(aid)) {
- cats_obj[cid].appIds.push(aid);
- cats_obj[cid].trackers.push({
- id: aid,
- name: db.apps[aid].name,
- blocked: bugs[id].blocked
- });
- if (bugs[id].blocked) {
- cats_obj[cid].blocked++;
- } else {
- cats_obj[cid].allowed++;
- }
- cats_obj[cid].total++;
+ const ids = Object.keys(bugs);
+ for (let i = 0; i < ids.length; i++) {
+ id = ids[i];
+ appid = db.bugs[id].aid;
+ cid = db.apps[appid].cat;
+
+ if (cats_obj.hasOwnProperty(cid)) {
+ if (!cats_obj[cid].appIds.includes(appid)) {
+ cats_obj[cid].appIds.push(appid);
+ cats_obj[cid].trackers.push({
+ id: appid,
+ name: db.apps[appid].name,
+ blocked: bugs[id].blocked
+ });
+ if (bugs[id].blocked) {
+ cats_obj[cid].blocked++;
+ } else {
+ cats_obj[cid].allowed++;
}
- } else {
- cats_obj[cid] = {
- id: cid,
- name: cid,
- appIds: [aid],
- trackers: [{
- id: aid,
- name: db.apps[aid].name,
- blocked: bugs[id].blocked
- }],
- blocked: (bugs[id].blocked ? 1 : 0),
- allowed: (bugs[id].blocked ? 0 : 1),
- total: 1
- };
+ cats_obj[cid].total++;
}
+ } else {
+ cats_obj[cid] = {
+ id: cid,
+ name: cid,
+ appIds: [appid],
+ trackers: [{
+ id: appid,
+ name: db.apps[appid].name,
+ blocked: bugs[id].blocked
+ }],
+ blocked: (bugs[id].blocked ? 1 : 0),
+ allowed: (bugs[id].blocked ? 0 : 1),
+ total: 1
+ };
}
}
// convert categories hash to array
- for (cid in cats_obj) {
- if (cats_obj.hasOwnProperty(cid)) {
- cats_arr.push(cats_obj[cid]);
- }
+ const cids = Object.keys(cats_obj);
+ for (let i = 0; i < cids.length; i++) {
+ cid = cids[i];
+ cats_arr.push(cats_obj[cid]);
}
if (sorted) {
cats_arr.sort((a, b) => {
- a = a.name.toLowerCase();
- b = b.name.toLowerCase();
- return (a > b ? 1 : (a < b ? -1 : 0));
+ const a1 = a.name.toLowerCase();
+ const b1 = b.name.toLowerCase();
+ return (a1 > b1 ? 1 : (a1 < b1 ? -1 : 0));
});
}
@@ -420,11 +423,11 @@ class FoundBugs {
*/
_checkForCompatibilityIssues(tab_id, tab_url) {
const { apps, appsMetadata, issueCounts } = this._foundApps[tab_id];
- apps.forEach((app) => {
- const { id } = app;
+ apps.forEach((appEntry) => {
+ const { id } = appEntry;
if (appsMetadata[id].needsCompatibilityCheck) {
- app.hasCompatibilityIssue = app.blocked ? compDb.hasIssue(id, tab_url) : false;
- if (app.hasCompatibilityIssue) { issueCounts.compatibility++; }
+ appEntry.hasCompatibilityIssue = appEntry.blocked ? compDb.hasIssue(id, tab_url) : false;
+ if (appEntry.hasCompatibilityIssue) { issueCounts.compatibility++; }
appsMetadata[id].needsCompatibilityCheck = false;
}
});
@@ -438,8 +441,9 @@ class FoundBugs {
* @param {string} src source urls for the bug
* @param {boolean} blocked
* @param {string} type
+ * @param {string} request_id request_id for the resource to use as a unique id
*/
- _updateFoundBugs(tab_id, bug_id, src, blocked, type) {
+ _updateFoundBugs(tab_id, bug_id, src, blocked, type, request_id) {
if (!this._foundBugs[tab_id].hasOwnProperty(bug_id)) {
this._foundBugs[tab_id][bug_id] = {
sources: [],
@@ -453,7 +457,8 @@ class FoundBugs {
bug.sources.push({
src,
blocked,
- type: type.toLowerCase()
+ type: type.toLowerCase(),
+ request_id
});
// Check for insecure tag loading in secure page
diff --git a/src/classes/KordInjector.js b/src/classes/KordInjector.js
new file mode 100644
index 000000000..ac956f0d4
--- /dev/null
+++ b/src/classes/KordInjector.js
@@ -0,0 +1,63 @@
+/**
+ * Kord Injector
+ *
+ * Ghostery Browser Extension
+ * https://www.ghostery.com/
+ *
+ * Copyright 2019 Ghostery, Inc. All rights reserved.
+ *
+ * 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
+ */
+
+import Spanan from 'spanan';
+import ExtMessenger from './ExtMessenger';
+import { log } from '../utils/common';
+
+/**
+ * Class for handling cross-extension messaging.
+ * @memberOf BackgroundClasses
+ */
+export default class KordInjector {
+ constructor() {
+ this.extensionId = 'cliqz@cliqz.com';
+ this.moduleWrappers = new Map();
+ this._messageHandler = this._messageHandler.bind(this);
+ }
+
+ init() {
+ ExtMessenger.addListener(this._messageHandler);
+ }
+
+ unload() {
+ ExtMessenger.removeListener(this._messageHandler);
+ }
+
+ module(moduleName) {
+ if (!this.moduleWrappers.has(moduleName)) {
+ this.moduleWrappers.set(moduleName, this._createModuleWrapper(moduleName));
+ }
+ const wrapper = this.moduleWrappers.get(moduleName);
+ return wrapper.createProxy();
+ }
+
+ _createModuleWrapper(moduleName) {
+ return new Spanan((m) => {
+ const message = { ...m };
+ message.moduleName = moduleName;
+ ExtMessenger.sendMessage(this.extensionId, message);
+ });
+ }
+
+ _messageHandler(messageJSON, sender) {
+ const message = JSON.parse(messageJSON);
+ if (sender.id !== this.extensionId) {
+ return;
+ }
+ if (!this.moduleWrappers.has(message.moduleName)) {
+ log('KordInjector error: Unhandled message', message);
+ }
+ this.moduleWrappers.get(message.moduleName).handleMessage(message);
+ }
+}
diff --git a/src/classes/Metrics.js b/src/classes/Metrics.js
index 1ef073f08..6de30756c 100644
--- a/src/classes/Metrics.js
+++ b/src/classes/Metrics.js
@@ -132,13 +132,13 @@ class Metrics {
getActiveTab((tab) => {
const tabUrl = tab && tab.url ? tab.url : '';
- this._brokenPageWatcher = Object.assign({}, {
+ this._brokenPageWatcher = {
on: true,
triggerId,
triggerTime: Date.now(),
timeoutId: setTimeout(this._clearBrokenPageWatcherTimeout.bind(this), BROKEN_PAGE_METRICS_THRESHOLD),
- url: tabUrl,
- });
+ url: tabUrl
+ };
});
}
@@ -149,13 +149,13 @@ class Metrics {
_unplugBrokenPageWatcher() {
this._clearBrokenPageWatcherTimeout();
- this._brokenPageWatcher = Object.assign({}, {
+ this._brokenPageWatcher = {
on: false,
triggerId: '',
triggerTime: '',
timeoutId: null,
- url: '',
- });
+ url: ''
+ };
}
_clearBrokenPageWatcherTimeout() {
@@ -346,21 +346,21 @@ class Metrics {
// Type of blocking selected during setup
`&sb=${encodeURIComponent(conf.setup_block.toString())}` +
// Recency, days since last active daily ping
- `&rc=${encodeURIComponent(this._getRecencyActive(type, frequency).toString())}` +
+ `&rc=${encodeURIComponent(Metrics._getRecencyActive(type, frequency).toString())}` +
// New parameters to Ghostery 8.3
// Subscription Type
- `&st=${encodeURIComponent(this._getSubscriptionType().toString())}` +
+ `&st=${encodeURIComponent(Metrics._getSubscriptionType().toString())}` +
// Whether the computer ever had a Paid Subscription
`&ps=${encodeURIComponent(conf.paid_subscription ? '1' : '0')}` +
// Active Velocity
- `&va=${encodeURIComponent(this._getVelocityActive(type).toString())}` +
+ `&va=${encodeURIComponent(Metrics._getVelocityActive(type).toString())}` +
// Engaged Recency
- `&re=${encodeURIComponent(this._getRecencyEngaged(type, frequency).toString())}` +
+ `&re=${encodeURIComponent(Metrics._getRecencyEngaged(type, frequency).toString())}` +
// Engaged Velocity
- `&ve=${encodeURIComponent(this._getVelocityEngaged(type).toString())}` +
+ `&ve=${encodeURIComponent(Metrics._getVelocityEngaged(type).toString())}` +
// Theme
- `&th=${encodeURIComponent(this._getThemeValue().toString())}`;
+ `&th=${encodeURIComponent(Metrics._getThemeValue().toString())}`;
if (CAMPAIGN_METRICS.includes(type)) {
// only send campaign attribution when necessary
@@ -385,14 +385,11 @@ class Metrics {
*
* @private
*
- * @param {string} type ping type
+ * @param {string} type ping type
* @param {array} [frequencies = ['all']] array of ping frequencies
*/
- _sendReq(type, frequencies) {
+ _sendReq(type, frequencies = ['all']) {
let options = {};
- if (typeof frequencies === 'undefined') {
- frequencies = ['all']; // eslint-disable-line no-param-reassign
- }
if (typeof fetch === 'function') {
const headers = new Headers();
@@ -439,7 +436,7 @@ class Metrics {
*
* @return {number} in days since the last daily active ping
*/
- _getRecencyActive(type, frequency) {
+ static _getRecencyActive(type, frequency) {
if (conf.metrics.active_daily && (type === 'active' || type === 'engaged') && frequency === 'daily') {
return Math.floor((Number(new Date().getTime()) - conf.metrics.active_daily) / 86400000);
}
@@ -453,7 +450,7 @@ class Metrics {
*
* @return {number} in days since the last daily engaged ping
*/
- _getRecencyEngaged(type, frequency) {
+ static _getRecencyEngaged(type, frequency) {
if (conf.metrics.engaged_daily && (type === 'active' || type === 'engaged') && frequency === 'daily') {
return Math.floor((Number(new Date().getTime()) - conf.metrics.engaged_daily) / 86400000);
}
@@ -465,7 +462,7 @@ class Metrics {
* @private
* @return {number} The Active Velocity
*/
- _getVelocityActive(type) {
+ static _getVelocityActive(type) {
if (type !== 'active' && type !== 'engaged') {
return -1;
}
@@ -479,7 +476,7 @@ class Metrics {
* @private
* @return {number} The Engaged Velocity
*/
- _getVelocityEngaged(type) {
+ static _getVelocityEngaged(type) {
if (type !== 'active' && type !== 'engaged') {
return -1;
}
@@ -492,7 +489,7 @@ class Metrics {
* Get the Subscription Type
* @return {string} Subscription Name
*/
- _getSubscriptionType() {
+ static _getSubscriptionType() {
if (!conf.account) {
return -1;
}
@@ -508,7 +505,7 @@ class Metrics {
* @private
* @return {number} value associated with the Current Theme
*/
- _getThemeValue() {
+ static _getThemeValue() {
const { current_theme } = conf;
switch (current_theme) {
case 'midnight-theme':
@@ -531,7 +528,7 @@ class Metrics {
* @param {string} frequency one of 'all', 'daily', 'weekly'
* @return {number} number in milliseconds over the frequency since the last ping
*/
- _timeToExpired(type, frequency) {
+ static _timeToExpired(type, frequency) {
if (frequency === 'all') {
return 0;
}
@@ -552,7 +549,7 @@ class Metrics {
* @return {boolean} true/false
*/
_checkPing(type, frequency) {
- const result = this._timeToExpired(type, frequency);
+ const result = Metrics._timeToExpired(type, frequency);
if (result > 0) {
return false;
}
@@ -629,7 +626,7 @@ class Metrics {
}
conf.metrics.active_daily_velocity = active_daily_velocity;
- const daily = this._timeToExpired('active', 'daily');
+ const daily = Metrics._timeToExpired('active', 'daily');
if (daily > 0) {
setTimeout(() => {
this._sendReq('active', ['daily']);
@@ -644,7 +641,7 @@ class Metrics {
}, FREQUENCIES.daily);
}
- const weekly = this._timeToExpired('active', 'weekly');
+ const weekly = Metrics._timeToExpired('active', 'weekly');
if (weekly > 0) {
setTimeout(() => {
this._sendReq('active', ['weekly']);
@@ -659,7 +656,7 @@ class Metrics {
}, FREQUENCIES.weekly);
}
- const monthly = this._timeToExpired('active', 'monthly');
+ const monthly = Metrics._timeToExpired('active', 'monthly');
if (monthly > 0) {
if (monthly <= FREQUENCIES.biweekly) {
setTimeout(() => {
diff --git a/src/classes/Module.js b/src/classes/Module.js
index 60170f87b..427d83b7c 100644
--- a/src/classes/Module.js
+++ b/src/classes/Module.js
@@ -11,8 +11,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0
*/
-/* eslint max-classes-per-file: 0 */
-
import Module from 'browser-core/build/core/app/module';
import baseBackground from 'browser-core/build/core/base/background';
import globals from './Globals';
@@ -30,7 +28,7 @@ const background = baseBackground({
});
class GhosteryModule extends Module {
- get _module() {
+ get _module() { // eslint-disable-line class-methods-use-this
return background;
}
}
diff --git a/src/classes/PanelData.js b/src/classes/PanelData.js
index 3a99b8b5e..7bc8881aa 100644
--- a/src/classes/PanelData.js
+++ b/src/classes/PanelData.js
@@ -23,17 +23,16 @@ import globals from './Globals';
import metrics from './Metrics';
import Policy from './Policy';
import tabInfo from './TabInfo';
-import rewards from './Rewards';
+import Rewards from './Rewards';
import account from './Account';
import dispatcher from './Dispatcher';
import promoModals from './PromoModals';
import { getCliqzGhosteryBugs, sendCliqzModuleCounts } from '../utils/cliqzModulesData';
import { getActiveTab, flushChromeMemoryCache, processUrl } from '../utils/utils';
-import { objectEntries, log } from '../utils/common';
+import { log } from '../utils/common';
const SYNC_SET = new Set(globals.SYNC_ARRAY);
const { IS_CLIQZ } = globals;
-const policy = new Policy();
/**
* PanelData coordinates the assembly and transmission of data to the extension panel
@@ -76,7 +75,7 @@ class PanelData {
const { url } = tab;
this._activeTab = tab;
- this._activeTab.pageHost = url && processUrl(url).hostname || '';
+ this._activeTab.pageHost = (url && processUrl(url).hostname) || '';
this._attachListeners();
@@ -118,16 +117,16 @@ class PanelData {
break;
case 'RewardsComponentDidMount':
this._mountedComponents.rewards = true;
- this._panelPort.onDisconnect.addListener(rewards.panelHubClosedListener);
+ this._panelPort.onDisconnect.addListener(Rewards.panelHubClosedListener);
this._postRewardsData();
break;
case 'RewardsComponentWillUnmount':
this._mountedComponents.rewards = false;
- this._panelPort.onDisconnect.removeListener(rewards.panelHubClosedListener);
+ this._panelPort.onDisconnect.removeListener(Rewards.panelHubClosedListener);
break;
case 'SettingsComponentDidMount':
this._mountedComponents.settings = true;
- this._postMessage('settings', this._getSettingsData());
+ this._postMessage('settings', PanelData._getSettingsData());
break;
case 'SettingsComponentWillUnmount':
this._mountedComponents.settings = false;
@@ -167,13 +166,13 @@ class PanelData {
get(view, tab) {
// Hub and Android panel
if (view === 'settings') {
- return this._getSettingsData();
+ return PanelData._getSettingsData();
}
// Android panel only
const { url } = tab;
this._activeTab = tab;
- this._activeTab.pageHost = url && processUrl(url).hostname || '';
+ this._activeTab.pageHost = (url && processUrl(url).hostname) || '';
this._setTrackerListAndCategories();
switch (view) {
case 'panel':
@@ -247,21 +246,22 @@ class PanelData {
site_specific_blocks, site_specific_unblocks, toggle_individual_trackers,
} = conf;
- return Object.assign({}, {
+ return {
expand_all_trackers,
selected_app_ids,
show_tracker_urls,
site_specific_blocks,
site_specific_unblocks,
- toggle_individual_trackers
- }, this._getDynamicBlockingData());
+ toggle_individual_trackers,
+ ...this._getDynamicBlockingData()
+ };
}
/**
* Helper that retrieves the current account information
* @return {Object|null} the current account object or null
*/
- _getCurrentAccount() {
+ static _getCurrentAccount() {
const currentAccount = conf.account;
if (currentAccount && currentAccount.user) {
currentAccount.user.plusAccess = account.hasScopesUnverified(['subscriptions:plus'])
@@ -303,7 +303,7 @@ class PanelData {
return {
needsReload: needsReload || { changes: {} },
smartBlock,
- account: this._getCurrentAccount(),
+ account: PanelData._getCurrentAccount(),
};
}
@@ -338,7 +338,7 @@ class PanelData {
trackers_banner_status,
} = conf;
- return Object.assign({}, {
+ return {
current_theme,
enable_ad_block,
enable_anti_tracking,
@@ -352,7 +352,8 @@ class PanelData {
reload_banner_status,
tab_id,
trackers_banner_status,
- }, this._getDynamicPanelData(tab_id));
+ ...this._getDynamicPanelData(tab_id)
+ };
}
/**
@@ -371,7 +372,7 @@ class PanelData {
* Get rewards data for the Rewards View
* @return {Object} Rewards view data
*/
- _getRewardsData() {
+ static _getRewardsData() {
return {
enable_offers: conf.enable_offers,
};
@@ -382,25 +383,24 @@ class PanelData {
* Called when and only when the Settings component is mounted
* @return {Object} Settings View data
*/
- _getSettingsData() {
+ static _getSettingsData() {
const {
- bugs_last_updated, language, new_app_ids,
+ bugs_last_updated, bugs_last_checked, language, new_app_ids,
settings_last_exported, settings_last_imported
} = conf;
- return Object.assign(
- {},
- {
- bugs_last_updated,
- categories: this._buildGlobalCategories(),
- language, // required for the setup page that does not have access to panelView data
- new_app_ids,
- offer_human_web: true,
- settings_last_exported,
- settings_last_imported,
- },
- this._getUserSettingsForSettingsView(conf),
- );
+ return {
+
+ bugs_last_updated,
+ bugs_last_checked,
+ categories: PanelData._buildGlobalCategories(),
+ language, // required for the setup page that does not have access to panelView data
+ new_app_ids,
+ offer_human_web: true,
+ settings_last_exported,
+ settings_last_imported,
+ ...PanelData._getUserSettingsForSettingsView(conf),
+ };
}
/**
@@ -414,20 +414,18 @@ class PanelData {
const { paused_blocking, paused_blocking_timeout } = globals.SESSION;
const { site_blacklist, site_whitelist } = conf;
- return Object.assign(
- {},
- {
- paused_blocking,
- paused_blocking_timeout,
- site_blacklist,
- site_whitelist,
- pageHost,
- pageUrl: url || '',
- siteNotScanned: !this._trackerList || false,
- sitePolicy: policy.getSitePolicy(url) || false,
- },
- this._getDynamicSummaryData()
- );
+ return {
+
+ paused_blocking,
+ paused_blocking_timeout,
+ site_blacklist,
+ site_whitelist,
+ pageHost,
+ pageUrl: url || '',
+ siteNotScanned: !this._trackerList || false,
+ sitePolicy: Policy.getSitePolicy(url) || false,
+ ...this._getDynamicSummaryData()
+ };
}
/**
@@ -435,7 +433,7 @@ class PanelData {
* Invoked if Blocking component is mounted when account.getUserSettings() resolves, max one time per panel open.
* @param {Object} userSettings the settings retrieved by account.getUserSettings() in _initPort
*/
- _getUserSettingsForBlockingView(userSettings) {
+ static _getUserSettingsForBlockingView(userSettings) {
const {
expand_all_trackers, selected_app_ids, show_tracker_urls,
site_specific_blocks, site_specific_unblocks, toggle_individual_trackers,
@@ -456,7 +454,7 @@ class PanelData {
* Invoked if Panel is still open account.getUserSettings() resolves, max one time per panel open.
* @param {Object} userSettings the settings retrieved by account.getUserSettings() in _initPort
*/
- _getUserSettingsForPanelView(userSettings) {
+ static _getUserSettingsForPanelView(userSettings) {
const {
current_theme, enable_ad_block, enable_anti_tracking, enable_smart_block,
enable_offers, is_expanded, is_expert, reload_banner_status, trackers_banner_status,
@@ -472,7 +470,7 @@ class PanelData {
is_expert,
reload_banner_status,
trackers_banner_status,
- account: this._getCurrentAccount(),
+ account: PanelData._getCurrentAccount(),
};
}
@@ -481,7 +479,7 @@ class PanelData {
* Invoked if Settings component is mounted when account.getUserSettings() resolves, max one time per panel open.
* @param {Object} userSettings the settings retrieved by account.getUserSettings() in _initPort, or the conf object provided by getSettings
*/
- _getUserSettingsForSettingsView(userSettingsSource) {
+ static _getUserSettingsForSettingsView(userSettingsSource) {
const {
alert_bubble_pos, alert_bubble_timeout, block_by_default, cliqz_adb_mode, enable_autoupdate,
enable_click2play, enable_click2play_social, enable_human_web, enable_offers,
@@ -547,7 +545,7 @@ class PanelData {
* @private
*/
_postRewardsData() {
- this._postMessage('rewards', this._getRewardsData());
+ this._postMessage('rewards', PanelData._getRewardsData());
}
/**
@@ -558,16 +556,16 @@ class PanelData {
_postUserSettings(userSettings) {
if (!this._panelPort || !this._activeTab) { return; }
- this._postMessage('panel', this._getUserSettingsForPanelView(userSettings));
+ this._postMessage('panel', PanelData._getUserSettingsForPanelView(userSettings));
const { blocking, settings } = this._mountedComponents;
if (blocking) {
- this._postMessage('blocking', this._getUserSettingsForBlockingView(userSettings));
+ this._postMessage('blocking', PanelData._getUserSettingsForBlockingView(userSettings));
}
if (settings) {
- this._postMessage('settings', this._getUserSettingsForSettingsView(userSettings));
+ this._postMessage('settings', PanelData._getUserSettingsForSettingsView(userSettings));
}
}
// [/DATA TRANSFER]
@@ -577,9 +575,10 @@ class PanelData {
/**
* Update Conf properties with new data from the UI.
* Called via setPanelData message.
- * @param {Object} data
+ * @param {Object} d
*/
- set(data) {
+ set(d) {
+ const data = { ...d };
let syncSetDataChanged = false;
if (IS_CLIQZ) {
@@ -590,8 +589,10 @@ class PanelData {
}
// Set the conf from data
- // TODO can this now be replaced by Object.entries?
- for (const [key, value] of objectEntries(data)) {
+ const dataKeys = Object.keys(data);
+ for (let i = 0; i < dataKeys.length; i++) {
+ const key = dataKeys[i];
+ const value = data[key];
if (conf.hasOwnProperty(key) && !isEqual(conf[key], value)) {
conf[key] = value;
syncSetDataChanged = SYNC_SET.has(key) ? true : syncSetDataChanged;
@@ -604,13 +605,13 @@ class PanelData {
setTimeout(() => {
globals.SESSION.paused_blocking = false;
- this._toggleBlockingHelper();
+ PanelData._toggleBlockingHelper();
}, value);
} else {
globals.SESSION.paused_blocking = value;
globals.SESSION.paused_blocking_timeout = 0;
}
- this._toggleBlockingHelper();
+ PanelData._toggleBlockingHelper();
}
}
@@ -635,7 +636,7 @@ class PanelData {
/**
* Notifies interested parties when blocking is paused / unpaused
*/
- _toggleBlockingHelper() {
+ static _toggleBlockingHelper() {
button.update();
flushChromeMemoryCache();
dispatcher.trigger('globals.save.paused_blocking');
@@ -663,19 +664,19 @@ class PanelData {
if (categories.hasOwnProperty(cat)) {
categories[cat].num_total++;
- if (this._addsUpToBlocked(trackerState)) { categories[cat].num_blocked++; }
+ if (PanelData._addsUpToBlocked(trackerState)) { categories[cat].num_blocked++; }
} else {
- categories[cat] = this._buildCategory(cat, trackerState);
+ categories[cat] = PanelData._buildCategory(cat, trackerState);
}
- categories[cat].trackers.push(this._buildTracker(tracker, trackerState, smartBlock));
+ categories[cat].trackers.push(PanelData._buildTracker(tracker, trackerState, smartBlock));
});
const categoryArray = Object.values(categories);
categoryArray.sort((a, b) => {
- a = a.name.toLowerCase(); // eslint-disable-line no-param-reassign
- b = b.name.toLowerCase(); // eslint-disable-line no-param-reassign
- return (a > b ? 1 : (a < b ? -1 : 0));
+ const a1 = a.name.toLowerCase();
+ const b1 = b.name.toLowerCase();
+ return (a1 > b1 ? 1 : (a1 < b1 ? -1 : 0));
});
return categoryArray;
@@ -686,7 +687,7 @@ class PanelData {
* @param {Object} trackerState object containing various block/allow states of a tracker
* @return {boolean} is the tracker blocked in one of the possible ways?
*/
- _addsUpToBlocked({
+ static _addsUpToBlocked({
ss_blocked, sb_blocked, blocked, ss_allowed, sb_allowed
}) {
return (ss_blocked || sb_blocked || (blocked && !ss_allowed && !sb_allowed));
@@ -698,7 +699,7 @@ class PanelData {
* @param {Object} trackerState object containing various block/allow states of a tracker
* @return {Object} an object with data for a new category
*/
- _buildCategory(category, trackerState) {
+ static _buildCategory(category, trackerState) {
return {
id: category,
name: t(`category_${category}`),
@@ -706,7 +707,7 @@ class PanelData {
img_name: (category === 'advertising') ? 'adv' : // Because AdBlock blocks images with 'advertising' in the name.
(category === 'social_media') ? 'smed' : category, // Because AdBlock blocks images with 'social' in the name.
num_total: 1,
- num_blocked: this._addsUpToBlocked(trackerState) ? 1 : 0,
+ num_blocked: PanelData._addsUpToBlocked(trackerState) ? 1 : 0,
trackers: []
};
}
@@ -720,7 +721,7 @@ class PanelData {
* @param {Object} smartBlock smart blocking stats for the active tab
* @return {Object} object of tracker data
*/
- _buildTracker(tracker, trackerState, smartBlock) {
+ static _buildTracker(tracker, trackerState, smartBlock) {
const {
cat,
cliqzAdCount,
@@ -786,16 +787,16 @@ class PanelData {
* @private
* @return {array} array of categories
*/
- _buildGlobalCategories() {
+ static _buildGlobalCategories() {
const categories = bugDb.db.categories || [];
const selectedApps = conf.selected_app_ids || {};
- categories.forEach((category) => {
- const { trackers } = category;
- category.num_blocked = 0;
- trackers.forEach((tracker) => {
- tracker.blocked = selectedApps.hasOwnProperty(tracker.id);
- if (tracker.blocked) {
- category.num_blocked++;
+ categories.forEach((categoryEl) => {
+ const { trackers } = categoryEl;
+ categoryEl.num_blocked = 0;
+ trackers.forEach((trackerEl) => {
+ trackerEl.blocked = selectedApps.hasOwnProperty(trackerEl.id);
+ if (trackerEl.blocked) {
+ categoryEl.num_blocked++;
}
});
});
diff --git a/src/classes/Policy.js b/src/classes/Policy.js
index d8b30f814..d304f1c03 100644
--- a/src/classes/Policy.js
+++ b/src/classes/Policy.js
@@ -13,7 +13,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0
*/
-/* eslint no-param-reassign: 0 */
import c2pDb from './Click2PlayDb';
import conf from './Conf';
import globals from './Globals';
@@ -45,11 +44,11 @@ class Policy {
* @param {string} url site url
* @return {boolean}
*/
- getSitePolicy(hostUrl, trackerUrl) {
- if (this.blacklisted(hostUrl)) {
+ static getSitePolicy(hostUrl, trackerUrl) {
+ if (Policy.blacklisted(hostUrl)) {
return globals.BLACKLISTED;
}
- if (this.checkSiteWhitelist(hostUrl) || this.checkCliqzModuleWhitelist(hostUrl, trackerUrl)) {
+ if (Policy.checkSiteWhitelist(hostUrl) || Policy.checkCliqzModuleWhitelist(hostUrl, trackerUrl)) {
return globals.WHITELISTED;
}
return false;
@@ -60,7 +59,7 @@ class Policy {
* @param {string} url site url
* @return {string|boolean} corresponding whitelist entry or false, if none
*/
- checkSiteWhitelist(url) {
+ static checkSiteWhitelist(url) {
const hostUrl = processUrl(url).host;
if (hostUrl) {
const replacedUrl = hostUrl.replace(/^www\./, '');
@@ -73,7 +72,7 @@ class Policy {
if (!sites[i].includes('*') && replacedUrl === sites[i]) {
return sites[i];
}
- if (this.matchesWildcard(replacedUrl, sites[i])) {
+ if (Policy.matchesWildcard(replacedUrl, sites[i])) {
return sites[i];
}
}
@@ -87,7 +86,7 @@ class Policy {
* @param {string} url site url
* @return {string|boolean} corresponding whitelist entry or false, if none
*/
- checkCliqzModuleWhitelist(hostUrl, trackerUrl) {
+ static checkCliqzModuleWhitelist(hostUrl, trackerUrl) {
let isWhitelisted = false;
const processedHostUrl = processUrl(hostUrl).host;
const processedTrackerUrl = processUrl(trackerUrl).host;
@@ -111,7 +110,7 @@ class Policy {
* @param {string} url site url
* @return {string|boolean} corresponding blacklist entry or false, if none
*/
- blacklisted(url) {
+ static blacklisted(url) {
const hostUrl = processUrl(url).host;
if (hostUrl) {
const replacedUrl = hostUrl.replace(/^www\./, '');
@@ -124,7 +123,7 @@ class Policy {
if (!sites[i].includes('*') && replacedUrl === sites[i]) {
return sites[i];
}
- if (this.matchesWildcard(replacedUrl, sites[i])) {
+ if (Policy.matchesWildcard(replacedUrl, sites[i])) {
return sites[i];
}
}
@@ -149,7 +148,7 @@ class Policy {
* @param {string} tab_url tab url
* @return {BlockWithReason} block result with reason
*/
- shouldBlock(app_id, cat_id, tab_id, tab_host, tab_url) {
+ static shouldBlock(app_id, cat_id, tab_id, tab_host, tab_url) {
if (globals.SESSION.paused_blocking) {
return { block: false, reason: BLOCK_REASON_BLOCK_PAUSED };
}
@@ -160,13 +159,13 @@ class Policy {
// The app_id is on the site-specific allow list for this tab_host
if (conf.toggle_individual_trackers && conf.site_specific_unblocks.hasOwnProperty(tab_host) && conf.site_specific_unblocks[tab_host].includes(+app_id)) {
// Site blacklist overrides all block settings except C2P allow once
- if (this.blacklisted(tab_url)) {
+ if (Policy.blacklisted(tab_url)) {
return { block: !allowedOnce, reason: allowedOnce ? BLOCK_REASON_C2P_ALLOWED_ONCE : BLOCK_REASON_BLACKLISTED };
}
return { block: false, reason: BLOCK_REASON_SS_UNBLOCKED };
}
// Check for site white-listing
- if (this.checkSiteWhitelist(tab_url)) {
+ if (Policy.checkSiteWhitelist(tab_url)) {
return { block: false, reason: BLOCK_REASON_WHITELISTED };
}
// The app_id is globally blocked
@@ -177,7 +176,7 @@ class Policy {
// Check to see if the app_id is on the site-specific block list for this tab_host
if (conf.toggle_individual_trackers && conf.site_specific_blocks.hasOwnProperty(tab_host) && conf.site_specific_blocks[tab_host].includes(+app_id)) {
// Site white-listing overrides blocking settings
- if (this.checkSiteWhitelist(tab_url)) {
+ if (Policy.checkSiteWhitelist(tab_url)) {
return { block: false, reason: BLOCK_REASON_WHITELISTED };
}
return { block: !allowedOnce, reason: allowedOnce ? BLOCK_REASON_C2P_ALLOWED_ONCE : BLOCK_REASON_SS_BLOCKED };
@@ -185,13 +184,13 @@ class Policy {
// Check to see if the app_id is on the site-specific allow list for this tab_host
if (conf.toggle_individual_trackers && conf.site_specific_unblocks.hasOwnProperty(tab_host) && conf.site_specific_unblocks[tab_host].includes(+app_id)) {
// Site blacklist overrides all block settings except C2P allow once
- if (this.blacklisted(tab_url)) {
+ if (Policy.blacklisted(tab_url)) {
return { block: !allowedOnce, reason: allowedOnce ? BLOCK_REASON_C2P_ALLOWED_ONCE : BLOCK_REASON_BLACKLISTED };
}
return { block: false, reason: BLOCK_REASON_SS_UNBLOCKED };
}
// Check for site black-listing
- if (this.blacklisted(tab_url)) {
+ if (Policy.blacklisted(tab_url)) {
return { block: !allowedOnce, reason: allowedOnce ? BLOCK_REASON_C2P_ALLOWED_ONCE : BLOCK_REASON_BLACKLISTED };
}
// The app_id is globally unblocked
@@ -204,7 +203,7 @@ class Policy {
* @param {string} pattern regex pattern
* @return {boolean}
*/
- matchesWildcard(url, pattern) {
+ static matchesWildcard(url, pattern) {
if (pattern && pattern.includes('*')) {
const wildcardPattern = pattern.replace(/\*/g, '.*');
try {
diff --git a/src/classes/PolicySmartBlock.js b/src/classes/PolicySmartBlock.js
index 8bed9ea1d..9df337c35 100644
--- a/src/classes/PolicySmartBlock.js
+++ b/src/classes/PolicySmartBlock.js
@@ -51,17 +51,17 @@ class PolicySmartBlock {
* applicable to this url, or none are met.
*/
shouldUnblock(appId, catId, tabId, pageURL, requestType) {
- if (!this.shouldCheck(tabId, appId)) { return false; }
+ if (!PolicySmartBlock.shouldCheck(tabId, appId)) { return false; }
let reason;
- if (this._appHasKnownIssue(tabId, appId, pageURL)) {
+ if (PolicySmartBlock._appHasKnownIssue(tabId, appId, pageURL)) {
reason = 'hasIssue'; // allow if tracker is in compatibility list
} else if (this._allowedCategories(tabId, appId, catId)) {
reason = 'allowedCategory'; // allow if tracker is in breaking category
} else if (this._allowedTypes(tabId, appId, requestType)) {
reason = 'allowedType'; // allow if tracker is in breaking type
- } else if (this._pageWasReloaded(tabId, appId)) {
+ } else if (PolicySmartBlock._pageWasReloaded(tabId, appId)) {
reason = 'pageReloaded'; // allow if page has been reloaded recently
}
@@ -85,21 +85,21 @@ class PolicySmartBlock {
* applicable to this url, or none are met.
*/
shouldBlock(appId, catId, tabId, pageURL, requestType, requestTimestamp) {
- if (!this.shouldCheck(tabId, appId)) { return false; }
+ if (!PolicySmartBlock.shouldCheck(tabId, appId)) { return false; }
let reason;
// Block all trackers that load after 5 seconds from when page load started
- if (this._requestWasSlow(tabId, appId, requestTimestamp)) {
+ if (PolicySmartBlock._requestWasSlow(tabId, appId, requestTimestamp)) {
reason = 'slow';
- if (this._appHasKnownIssue(tabId, appId, pageURL)) {
+ if (PolicySmartBlock._appHasKnownIssue(tabId, appId, pageURL)) {
reason = 'hasIssue'; // allow if tracker is in compatibility list
} else if (this._allowedCategories(tabId, appId, catId)) {
reason = 'allowedCategory'; // allow if tracker is in breaking category
} else if (this._allowedTypes(tabId, appId, requestType)) {
reason = 'allowedType'; // allow if tracker is in breaking type
- } else if (this._pageWasReloaded(tabId, appId)) {
+ } else if (PolicySmartBlock._pageWasReloaded(tabId, appId)) {
reason = 'pageReloaded'; // allow if page has been reloaded recently
}
}
@@ -127,14 +127,14 @@ class PolicySmartBlock {
* @param {string | boolean} appId tracker id
* @return {boolean}
*/
- shouldCheck(tabId, appId = false) {
+ static shouldCheck(tabId, appId = false) {
const tabUrl = tabInfo.getTabInfo(tabId, 'url');
const tabHost = tabInfo.getTabInfo(tabId, 'host');
return (
conf.enable_smart_block &&
!globals.SESSION.paused_blocking &&
- !this.policy.getSitePolicy(tabUrl) &&
+ !Policy.getSitePolicy(tabUrl) &&
((appId && (!conf.site_specific_unblocks.hasOwnProperty(tabHost) || !conf.site_specific_unblocks[tabHost].includes(+appId))) || appId === false) &&
((appId && (!conf.site_specific_blocks.hasOwnProperty(tabHost) || !conf.site_specific_blocks[tabHost].includes(+appId))) || appId === false) &&
(c2pDb.db.apps && !c2pDb.db.apps.hasOwnProperty(appId))
@@ -148,8 +148,8 @@ class PolicySmartBlock {
* @param {string} requestDomain domain of the request
* @return {boolean}
*/
- isFirstPartyRequest(tabId, pageDomain = '', requestDomain = '') {
- if (!this.shouldCheck(tabId)) { return false; }
+ static isFirstPartyRequest(tabId, pageDomain = '', requestDomain = '') {
+ if (!PolicySmartBlock.shouldCheck(tabId)) { return false; }
return pageDomain === requestDomain;
}
@@ -159,7 +159,7 @@ class PolicySmartBlock {
* @param {number} tabId tab id
* @return {boolean}
*/
- _pageWasReloaded(tabId) {
+ static _pageWasReloaded(tabId) {
return tabInfo.getTabInfo(tabId, 'reloaded') || false;
}
@@ -170,7 +170,7 @@ class PolicySmartBlock {
* @param {string} pageURL tab url
* @return {boolean}
*/
- _appHasKnownIssue(tabId, appId, pageURL) {
+ static _appHasKnownIssue(tabId, appId, pageURL) {
return compDb.hasIssue(appId, pageURL);
}
@@ -182,8 +182,8 @@ class PolicySmartBlock {
* @param {string} requestHost host of the request url
* @return {boolean}
*/
- isInsecureRequest(tabId, pageProtocol, requestProtocol, requestHost) {
- if (!this.shouldCheck(tabId)) { return false; }
+ static isInsecureRequest(tabId, pageProtocol, requestProtocol, requestHost) {
+ if (!PolicySmartBlock.shouldCheck(tabId)) { return false; }
// don't block mixed content from localhost
if (requestHost === 'localhost' || requestHost === '127.0.0.1' || requestHost === '[::1]') {
@@ -192,7 +192,7 @@ class PolicySmartBlock {
return (
pageProtocol === 'https' &&
- (requestProtocol === 'http' || requestProtocol === 'ws') || false
+ ((requestProtocol === 'http' || requestProtocol === 'ws') || false)
);
}
@@ -223,8 +223,8 @@ class PolicySmartBlock {
* @param {string} tabId tab id
* @return {boolean}
*/
- checkReloadThreshold(tabId) {
- if (!this.shouldCheck(tabId)) { return false; }
+ static checkReloadThreshold(tabId) {
+ if (!PolicySmartBlock.shouldCheck(tabId)) { return false; }
// Note that this threshold is different from the broken page ping threshold in Metrics, which is 60 seconds
// see GH-1797 for more details
@@ -232,7 +232,7 @@ class PolicySmartBlock {
return (
tabInfo.getTabInfoPersist(tabId, 'numOfReloads') > 1 &&
- ((Date.now() - tabInfo.getTabInfoPersist(tabId, 'firstLoadTimestamp')) < SMART_BLOCK_BEHAVIOR_THRESHOLD) || false
+ (((Date.now() - tabInfo.getTabInfoPersist(tabId, 'firstLoadTimestamp')) < SMART_BLOCK_BEHAVIOR_THRESHOLD) || false)
);
}
@@ -243,7 +243,7 @@ class PolicySmartBlock {
* @param {number} requestTimestamp timestamp of the request
* @return {boolean}
*/
- _requestWasSlow(tabId, appId, requestTimestamp) {
+ static _requestWasSlow(tabId, appId, requestTimestamp) {
const THRESHHOLD = 5000; // 5 seconds
const pageTimestamp = tabInfo.getTabInfo(tabId, 'timestamp');
// TODO: account for lazy-load or widgets triggered by user interaction beyond 5sec
diff --git a/src/classes/PromoModals.js b/src/classes/PromoModals.js
index 2f49320a9..292ea0d9c 100644
--- a/src/classes/PromoModals.js
+++ b/src/classes/PromoModals.js
@@ -102,7 +102,7 @@ class PromoModals {
static _hasEngagedFrequently() {
const { engaged_daily_count } = conf.metrics || [];
- const very_engaged_days = engaged_daily_count.reduce((acc, count) => (count >= DAILY_INSIGHTS_TARGET ? ++acc : acc), 0);
+ const very_engaged_days = engaged_daily_count.reduce((acc, count) => (count >= DAILY_INSIGHTS_TARGET ? acc + 1 : acc), 0);
return very_engaged_days >= WEEKLY_INSIGHTS_TARGET;
}
diff --git a/src/classes/PurpleBox.js b/src/classes/PurpleBox.js
index 8f3cf7bbb..685c3b72b 100644
--- a/src/classes/PurpleBox.js
+++ b/src/classes/PurpleBox.js
@@ -11,8 +11,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0
*/
-/* eslint consistent-return: 0 */
-
import conf from './Conf';
import foundBugs from './FoundBugs';
import tabInfo from './TabInfo';
@@ -30,7 +28,6 @@ const t = chrome.i18n.getMessage;
*/
class PurpleBox {
constructor() {
- this.policy = new Policy();
this.channelsSupported = (typeof chrome.runtime.onConnect === 'object');
this.ports = new Map();
}
@@ -48,7 +45,7 @@ class PurpleBox {
// Skip in the event of pause, trust, prefetching, newtab page, or Firefox about:pages
if (!conf.show_alert ||
globals.SESSION.paused_blocking ||
- (conf.hide_alert_trusted && !!this.policy.checkSiteWhitelist(tab.url)) ||
+ (conf.hide_alert_trusted && !!Policy.checkSiteWhitelist(tab.url)) ||
!tab || tab.purplebox || tab.path.includes('_/chrome/newtab') || tab.protocol === 'about' || globals.EXCLUDES.includes(tab.host)) {
return Promise.resolve(false);
}
@@ -168,6 +165,7 @@ class PurpleBox {
log('updateBox sendMessage failed', chrome.runtime.lastError, tab);
}
});
+ return true;
}
/**
@@ -186,9 +184,6 @@ class PurpleBox {
}
}
tabInfo.setTabInfo(tab_id, 'purplebox', false);
-
-
- return true;
}
}
diff --git a/src/classes/Rewards.js b/src/classes/Rewards.js
index b38c06cbb..e8182648a 100644
--- a/src/classes/Rewards.js
+++ b/src/classes/Rewards.js
@@ -20,11 +20,7 @@ import { log } from '../utils/common';
* @memberOf BackgroundClasses
*/
class Rewards {
- constructor() {
- this.panelHubClosedListener = this.panelHubClosedListener.bind(this);
- }
-
- sendSignal(message) {
+ static sendSignal(message) {
if (!conf.enable_offers) {
return;
}
@@ -45,8 +41,8 @@ class Rewards {
cliqz.modules['offers-v2'].background.actions.processRealEstateMessage(signal);
}
- panelHubClosedListener() {
- this.sendSignal({
+ static panelHubClosedListener() {
+ Rewards.sendSignal({
offerId: null,
actionId: 'hub_closed',
origin: 'rewards-hub',
@@ -55,4 +51,4 @@ class Rewards {
}
}
-export default new Rewards();
+export default Rewards;
diff --git a/src/classes/SurrogateDb.js b/src/classes/SurrogateDb.js
index 5fc99ba05..48c1df7c1 100644
--- a/src/classes/SurrogateDb.js
+++ b/src/classes/SurrogateDb.js
@@ -47,7 +47,7 @@ class SurrogateDb extends Updatable {
* @override
*
*/
- update() {}
+ static update() {}
/**
* Process surrogates from fetched json
@@ -57,7 +57,8 @@ class SurrogateDb extends Updatable {
processList(fromMemory, data) {
log('processing surrogates...');
- data.mappings.forEach((s) => {
+ data.mappings.forEach((souragate) => {
+ const s = { ...souragate };
s.code = data.surrogates[s.sid];
// convert single values to arrays first
diff --git a/src/classes/TabInfo.js b/src/classes/TabInfo.js
index accadfdea..24731c7fb 100644
--- a/src/classes/TabInfo.js
+++ b/src/classes/TabInfo.js
@@ -39,8 +39,6 @@ import { processUrl } from '../utils/utils';
*/
class TabInfo {
constructor() {
- this.policySmartBlock = new PolicySmartBlock();
-
// @private
this._tabInfo = {};
this._tabInfoPersist = {};
@@ -62,8 +60,8 @@ class TabInfo {
timestamp: Date.now(),
// assign only when smartBlock is enabled so avoid false positives
// when enabling smartBlock is enabled for the first time
- firstLoadTimestamp: this.policySmartBlock.shouldCheck(tab_id) && (numOfReloads === 0 ? Date.now() : (this.getTabInfoPersist(tab_id, 'firstLoadTimestamp') || 0)) || 0,
- reloaded: this.policySmartBlock.checkReloadThreshold(tab_id),
+ firstLoadTimestamp: PolicySmartBlock.shouldCheck(tab_id) && (numOfReloads === 0 ? Date.now() : ((this.getTabInfoPersist(tab_id, 'firstLoadTimestamp') || 0)) || 0),
+ reloaded: PolicySmartBlock.checkReloadThreshold(tab_id),
numOfReloads,
smartBlock: {
blocked: {},
diff --git a/src/utils/api.js b/src/utils/api.js
index 64671a0fe..3ebea93d7 100644
--- a/src/utils/api.js
+++ b/src/utils/api.js
@@ -61,7 +61,7 @@ class Api {
}));
}
- _processResponse(res) {
+ static _processResponse(res) {
return new Promise((resolve, reject) => {
const { status } = res;
if (status === 204) {
@@ -95,7 +95,7 @@ class Api {
_sendAuthenticatedRequest(method, path, body) {
return new Promise((resolve, reject) => {
this._sendReq(method, path, body)
- .then(this._processResponse)
+ .then(Api._processResponse)
.then(dataFirstTry => resolve(dataFirstTry))
.catch((data) => {
let shouldRefresh = false;
@@ -122,7 +122,7 @@ class Api {
)).catch(err => reject(err));
}
this._sendReq(method, path, body)
- .then(this._processResponse)
+ .then(Api._processResponse)
.then(dataSecondTry => resolve(dataSecondTry))
.catch((data3) => {
this._errorHandler(data3.errors)
diff --git a/src/utils/click2play.js b/src/utils/click2play.js
index abd0ec7ce..e7a3de6b4 100644
--- a/src/utils/click2play.js
+++ b/src/utils/click2play.js
@@ -11,8 +11,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0
*/
-/* eslint no-use-before-define: 0 */
-
import { reject } from 'underscore';
import bugDb from '../classes/BugDb';
import c2pDb from '../classes/Click2PlayDb';
@@ -25,7 +23,25 @@ import { sendMessage, processUrl, injectScript } from './utils';
import c2p_tpl from '../../app/templates/click2play.html';
import c2p_images from '../../app/data-images/click2play';
-const policy = new Policy();
+/**
+ * Creates selector for hubspot form
+ * @private
+ *
+ * @param {string} url form request url
+ * @return {string} selector
+ */
+function _getHubspotFormSelector(url) {
+ // Hubspot url has a fixed format
+ // https://forms.hubspot.com/embed/v3/form/532040/95b5de3a-6d4a-4729-bebf-07c41268d773?callback=hs_reqwest_0&hutk=941df50e9277ee76755310cd78647a08
+ // The following three parameters are privacy-safe:
+ // 532040 - partner id
+ // 95b5de3a-6d4a-4729-bebf-07c41268d773 - form id on the page
+ // hs_reqwest_0 - function which will be called on the client after the request
+ //
+ // hutk=941df50e9277ee76755310cd78647a08 -is user-specific (same every session)
+ const tokens = url.substr(8).split(/\/|&|\?|#|=/ig);
+ return `form[id="hsForm_${tokens[5]}"]`;
+}
/**
* Builds Click2Play templates for a given tab_id.
@@ -62,7 +78,7 @@ export function buildC2P(details, app_id) {
}
const app_name = bugDb.db.apps[app_id].name;
const c2pHtml = [];
- const blacklisted = !!policy.blacklisted(tab.host);
+ const blacklisted = !!Policy.blacklisted(tab.host);
// Generate the templates for each c2p definition (could be multiple for an app ID)
c2pApp.forEach((c2pAppDef) => {
@@ -105,12 +121,13 @@ export function buildC2P(details, app_id) {
tabInfo.setTabInfo(tab_id, 'c2pStatus', 'loading');
// Push current C2P data into existing queue
if (!tab.c2pQueue.hasOwnProperty(app_id)) {
- tabInfo.setTabInfo(tab_id, 'c2pQueue', Object.assign({}, tab.c2pQueue, {
+ tabInfo.setTabInfo(tab_id, 'c2pQueue', {
+ ...tab.c2pQueue,
[app_id]: {
data: c2pApp,
html: c2pHtml
}
- }));
+ });
}
// Scripts injected at document_idle are guaranteed to run after the DOM is complete
injectScript(tab_id, 'dist/click_to_play.js', '', 'document_idle').then(() => {
@@ -125,12 +142,13 @@ export function buildC2P(details, app_id) {
case 'loading':
// Push C2P data to a holding queue until click_to_play.js has finished loading on the page
if (!tab.c2pQueue.hasOwnProperty(app_id)) {
- tabInfo.setTabInfo(tab_id, 'c2pQueue', Object.assign({}, tab.c2pQueue, {
+ tabInfo.setTabInfo(tab_id, 'c2pQueue', {
+ ...tab.c2pQueue,
[app_id]: {
data: c2pApp,
html: c2pHtml
}
- }));
+ });
}
break;
case 'done':
@@ -164,7 +182,7 @@ export function buildRedirectC2P(redirectUrls, app_id) {
globals.BLOCKED_REDIRECT_DATA = {};
globals.BLOCKED_REDIRECT_DATA.app_id = app_id;
globals.BLOCKED_REDIRECT_DATA.url = redirectUrls.redirectUrl;
- globals.BLOCKED_REDIRECT_DATA.blacklisted = !!policy.blacklisted(host_url);
+ globals.BLOCKED_REDIRECT_DATA.blacklisted = !!Policy.blacklisted(host_url);
globals.BLOCKED_REDIRECT_DATA.translations = {
blocked_redirect_page_title: t('blocked_redirect_page_title'),
@@ -196,7 +214,6 @@ export function allowAllwaysC2P(app_id, tab_host) {
// Remove fron site-specific-blocked
if (conf.site_specific_blocks.hasOwnProperty(tab_host) && conf.site_specific_blocks[tab_host].includes(+app_id)) {
- const index = conf.site_specific_blocks[tab_host].indexOf(+app_id);
const { site_specific_blocks } = conf;
site_specific_blocks[tab_host].splice(0, 1);
conf.site_specific_blocks = site_specific_blocks;
@@ -214,23 +231,3 @@ export function allowAllwaysC2P(app_id, tab_host) {
}
conf.site_specific_unblocks = site_specific_unblocks;
}
-
-/**
- * Creates selector for hubspot form
- * @private
- *
- * @param {string} url form request url
- * @return {string} selector
- */
-function _getHubspotFormSelector(url) {
- // Hubspot url has a fixed format
- // https://forms.hubspot.com/embed/v3/form/532040/95b5de3a-6d4a-4729-bebf-07c41268d773?callback=hs_reqwest_0&hutk=941df50e9277ee76755310cd78647a08
- // The following three parameters are privacy-safe:
- // 532040 - partner id
- // 95b5de3a-6d4a-4729-bebf-07c41268d773 - form id on the page
- // hs_reqwest_0 - function which will be called on the client after the request
- //
- // hutk=941df50e9277ee76755310cd78647a08 -is user-specific (same every session)
- const tokens = url.substr(8).split(/\/|\&|\?|\#|\=/ig); // eslint-disable-line no-useless-escape
- return `form[id="hsForm_${tokens[5]}"]`;
-}
diff --git a/src/utils/cliqzModulesData.js b/src/utils/cliqzModulesData.js
index b28e91a32..1e4555ad4 100644
--- a/src/utils/cliqzModulesData.js
+++ b/src/utils/cliqzModulesData.js
@@ -58,7 +58,8 @@ export function getCliqzData(tabId, tabHostUrl, antiTracking) {
return tracker.ads;
};
- for (const bug of bugsValues) {
+ for (let i = 0; i < bugsValues.length; i++) {
+ const bug = bugsValues[i];
const dataPoints = getDataPoints(bug);
if (dataPoints) {
totalUnsafeCount += dataPoints;
@@ -66,7 +67,8 @@ export function getCliqzData(tabId, tabHostUrl, antiTracking) {
}
}
- for (const other of othersValues) {
+ for (let i = 0; i < othersValues.length; i++) {
+ const other = othersValues[i];
let whitelisted = false;
const dataPoints = getDataPoints(other);
diff --git a/src/utils/cliqzSettingImport.js b/src/utils/cliqzSettingImport.js
index 581409aa3..dba120b93 100644
--- a/src/utils/cliqzSettingImport.js
+++ b/src/utils/cliqzSettingImport.js
@@ -11,7 +11,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0
*/
-import KordInjector from '../classes/ExtMessenger';
+import KordInjector from '../classes/KordInjector';
import { log } from './common';
/**
@@ -34,10 +34,10 @@ function _promiseTimeout(timeout) {
* @private
*
* @param {Object} cliqz
- * @param {Object} conf
+ * @param {Object} confMutable conf
* @return {Promise}
*/
-function _runCliqzSettingsImport(cliqz, conf) {
+function _runCliqzSettingsImport(cliqz, confMutable) {
log('CliqzSettingsImport: Run Cliqz settings importer');
const inject = new KordInjector();
inject.init();
@@ -67,17 +67,17 @@ function _runCliqzSettingsImport(cliqz, conf) {
});
// import site whitelists
- const existingSites = new Set(conf.site_whitelist);
+ const existingSites = new Set(confMutable.site_whitelist);
const newSites = new Set(modules.map(mod => result[mod].whitelistedSites)
.reduce((lst, val) => lst.concat(val), [])
.map(s => s.replace(/^(http[s]?:\/\/)?(www\.)?/, ''))
.filter(s => !existingSites.has(s)));
log('CliqzSettingsImport: add whitelisted sites', [...newSites]);
- const whitelist = conf.site_whitelist;
+ const whitelist = confMutable.site_whitelist;
newSites.forEach((s) => {
whitelist.push(s);
});
- conf.site_whitelist = whitelist;
+ confMutable.site_whitelist = whitelist;
privacyMigration.cleanModuleData();
return Promise.resolve();
}).then(() => {
@@ -90,14 +90,14 @@ function _runCliqzSettingsImport(cliqz, conf) {
* @memberOf BackgroundUtils
*
* @param {Object} cliqz
- * @param {Object} conf
+ * @param {Object} confMutable conf
*/
-export function importCliqzSettings(cliqz, conf) {
- log('checking cliqz import', conf.cliqz_import_state);
- if (!conf.cliqz_import_state) {
- _runCliqzSettingsImport(cliqz, conf).then(() => {
+export default function importCliqzSettings(cliqz, confMutable) {
+ log('checking cliqz import', confMutable.cliqz_import_state);
+ if (!confMutable.cliqz_import_state) {
+ _runCliqzSettingsImport(cliqz, confMutable).then(() => {
log('CliqzSettingsImport: cliqz settings import successful');
- conf.cliqz_import_state = 1;
+ confMutable.cliqz_import_state = 1;
}, (e) => {
log('CliqzSettingsImport: cliqz import not available at present', e);
});
diff --git a/src/utils/common.js b/src/utils/common.js
index 06767279e..d947d25a3 100644
--- a/src/utils/common.js
+++ b/src/utils/common.js
@@ -14,8 +14,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0
*/
-/* eslint no-console: 0 no-bitwise: 0 */
-
// DO NOT IMPORT MODULES TO THIS FILE
const LOG = chrome.runtime.getManifest().log || false;
@@ -38,10 +36,10 @@ export function log(...args) {
args.unshift(`${(new Date()).toLocaleTimeString()}\t`);
if (hasErrors) {
- console.error(...args);
- console.trace();
+ console.error(...args); // eslint-disable-line no-console
+ console.trace(); // eslint-disable-line no-console
} else {
- console.log(...args);
+ console.log(...args); // eslint-disable-line no-console
}
return true;
}
@@ -150,32 +148,13 @@ export function hashCode(str) {
for (i = 0; i < str.length; i++) {
character = str.charCodeAt(i);
- hash = ((hash << 5) - hash) + character;
- hash &= hash;
+ hash = ((hash << 5) - hash) + character; // eslint-disable-line no-bitwise
+ hash &= hash; // eslint-disable-line no-bitwise
}
return hash;
}
-/**
- * Generator which makes object iterable with for...of loop
- * @memberOf BackgroundUtils
- *
- * @param {Object} object over which own enumerable properties we want to iterate
- * @return {Object} Generator object
- */
-
-export function* objectEntries(obj) {
- const propKeys = Object.keys(obj);
-
- for (const propKey of propKeys) {
- // `yield` returns a value and then pauses
- // the generator. Later, execution continues
- // where it was previously paused.
- yield [propKey, obj[propKey]];
- }
-}
-
/**
* Unescape base64-encoded string.
* @private
@@ -184,8 +163,8 @@ export function* objectEntries(obj) {
* @return {string} unescaped str
*/
function _base64urlUnescape(str) {
- str += new Array(5 - str.length % 4).join('='); // eslint-disable-line no-param-reassign
- return str.replace(/\-/g, '+').replace(/_/g, '/'); // eslint-disable-line no-useless-escape
+ const returnStr = str + new Array(5 - (str.length % 4)).join('=');
+ return returnStr.replace(/-/g, '+').replace(/_/g, '/');
}
/**
@@ -196,7 +175,7 @@ function _base64urlUnescape(str) {
* @return {string} decoded string
*/
function _base64urlDecode(str) {
- return new Buffer(_base64urlUnescape(str), 'base64').toString(); // eslint-disable-line no-buffer-constructor
+ return Buffer.from(_base64urlUnescape(str), 'base64').toString();
}
/**
diff --git a/src/utils/matcher.js b/src/utils/matcher.js
index 0e3118639..c5394ebcc 100644
--- a/src/utils/matcher.js
+++ b/src/utils/matcher.js
@@ -11,8 +11,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0
*/
-/* eslint no-use-before-define: 0 */
-
import bugDb from '../classes/BugDb';
import conf from '../classes/Conf';
import { processUrl, processFpeUrl } from './utils';
@@ -20,45 +18,6 @@ import { log } from './common';
// ALL APIS IN THIS FILE ARE PERFORMANCE-CRITICAL
-/**
- * Determine if web request qualifies as a bug.
- * @memberOf BackgroundUtils
- *
- * @param {string} src url of the request
- * @param {string} tab_url url of the page
- *
- * @return {int|boolean} bug id or false
- */
-export function isBug(src, tab_url) {
- const { db } = bugDb;
- const processedSrc = processUrl(src.toLowerCase());
- let found = false;
-
- const path = processedSrc.pathname ? processedSrc.pathname.substring(1) : '';
-
- found =
- // pattern classification 2: check host+path hash
- _matchesHost(db.patterns.host_path, processedSrc.hostname, path) ||
- // class 1: check host hash
- _matchesHost(db.patterns.host, processedSrc.hostname) ||
- // class 3: check path hash
- _matchesPath(path) ||
- // class 4: check regex patterns
- _matchesRegex(processedSrc.host + processedSrc.pathname);
-
- if (typeof tab_url !== 'undefined') {
- // check firstPartyExceptions
- if (conf.ignore_first_party &&
- found !== false &&
- db.firstPartyExceptions[found] &&
- fuzzyUrlMatcher(tab_url, db.firstPartyExceptions[found])) {
- return false;
- }
- }
-
- return found;
-}
-
/**
* Determine if a url matches an entry in an array urls.
* The matching is permissive.
@@ -196,7 +155,9 @@ function _matchesHost(root, src_host, src_path) {
function _matchesRegex(src) {
const regexes = bugDb.db.patterns.regex;
- for (const bug_id in regexes) {
+ const bug_ids = Object.keys(regexes);
+ for (let i = 0; i < bug_ids.length; i++) {
+ const bug_id = bug_ids[i];
if (regexes[bug_id].test(src)) {
return +bug_id;
}
@@ -219,7 +180,9 @@ function _matchesPath(src_path) {
// NOTE: we re-add the "/" in order to match patterns that include "/"
const srcPath = `/${src_path}`;
- for (const path in paths) {
+ const pathArr = Object.keys(paths);
+ for (let i = 0; i < pathArr.length; i++) {
+ const path = pathArr[i];
if (srcPath.includes(path)) {
return paths[path];
}
@@ -227,3 +190,42 @@ function _matchesPath(src_path) {
return false;
}
+
+/**
+ * Determine if web request qualifies as a bug.
+ * @memberOf BackgroundUtils
+ *
+ * @param {string} src url of the request
+ * @param {string} tab_url url of the page
+ *
+ * @return {int|boolean} bug id or false
+ */
+export function isBug(src, tab_url) {
+ const { db } = bugDb;
+ const processedSrc = processUrl(src.toLowerCase());
+ let found = false;
+
+ const path = processedSrc.pathname ? processedSrc.pathname.substring(1) : '';
+
+ found =
+ // pattern classification 2: check host+path hash
+ _matchesHost(db.patterns.host_path, processedSrc.hostname, path) ||
+ // class 1: check host hash
+ _matchesHost(db.patterns.host, processedSrc.hostname) ||
+ // class 3: check path hash
+ _matchesPath(path) ||
+ // class 4: check regex patterns
+ _matchesRegex(processedSrc.host + processedSrc.pathname);
+
+ if (typeof tab_url !== 'undefined') {
+ // check firstPartyExceptions
+ if (conf.ignore_first_party &&
+ found !== false &&
+ db.firstPartyExceptions[found] &&
+ fuzzyUrlMatcher(tab_url, db.firstPartyExceptions[found])) {
+ return false;
+ }
+ }
+
+ return found;
+}
diff --git a/src/utils/utils.js b/src/utils/utils.js
index 363753e70..965681395 100644
--- a/src/utils/utils.js
+++ b/src/utils/utils.js
@@ -13,8 +13,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0
*/
-/* eslint no-shadow: 0 */
-
/**
* @namespace BackgroundUtils
*/
@@ -22,7 +20,7 @@ import { debounce } from 'underscore';
import { URL } from '@cliqz/url-parser';
import tabInfo from '../classes/TabInfo';
import globals from '../classes/Globals';
-import { log, objectEntries } from './common';
+import { log } from './common';
const { BROWSER_INFO } = globals;
const IS_FIREFOX = (BROWSER_INFO.name === 'firefox');
@@ -194,7 +192,7 @@ export function processUrlQuery(src) {
try {
const res = {};
- for (const [key, value] of new URL(src).searchParams.entries()) {
+ for (const [key, value] of new URL(src).searchParams.entries()) { // eslint-disable-line no-restricted-syntax
res[key] = value;
}
return res;
@@ -355,7 +353,10 @@ function _fetchJson(method, url, query, extraHeaders, referrer = 'no-referrer',
Accept: 'application/json'
});
if (extraHeaders) {
- for (const [key, value] of objectEntries(extraHeaders)) {
+ const extraHeadersKeys = Object.keys(extraHeaders);
+ for (let i = 0; i < extraHeadersKeys.length; i++) {
+ const key = extraHeadersKeys[i];
+ const value = extraHeaders[key];
headers.append(key, value);
}
}
@@ -448,7 +449,10 @@ function _fetchJson(method, url, query, extraHeaders, referrer = 'no-referrer',
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Accept', 'application/json');
if (extraHeaders) {
- for (const [key, value] of objectEntries(extraHeaders)) {
+ const extraHeadersKeys = Object.keys(extraHeaders);
+ for (let i = 0; i < extraHeadersKeys.length; i++) {
+ const key = extraHeadersKeys[i];
+ const value = extraHeaders[key];
xhr.setRequestHeader(key, value);
}
}
@@ -593,7 +597,7 @@ export function injectNotifications(tab_id, importExport = false) {
}
const tab = tabInfo.getTabInfo(tab_id);
// check for prefetching, chrome new tab page and Firefox about:pages
- if (tab && tab.prefetched === true || tab.path.includes('_/chrome/newtab') || tab.protocol === 'about' || (!importExport && globals.EXCLUDES.includes(tab.host))) {
+ if (tab && (tab.prefetched === true || tab.path.includes('_/chrome/newtab') || tab.protocol === 'about' || (!importExport && globals.EXCLUDES.includes(tab.host)))) {
// return false to prevent sendMessage calls
return Promise.resolve(false);
}
diff --git a/test/src/Foundbugs.test.js b/test/src/Foundbugs.test.js
index e9a822e71..71b0567b6 100644
--- a/test/src/Foundbugs.test.js
+++ b/test/src/Foundbugs.test.js
@@ -47,7 +47,7 @@ describe('src/classes/FoundBugs.js', () => {
"614": {"name": "New Relic","cat": "site_analytics","tags": [48]}},
"bugs": {"2": {"aid": 13},"935": {"aid": 13},"1982": {"aid": 13},"719": {"aid": 464},"1009": {"aid": 614}},
"firstPartyExceptions": {'something': true},
- "patterns": {'something': true},
+ "patterns": { regex: { 'something': true} },
"version":416
});
// Mock bugDb fetch response
diff --git a/test/src/Policy.test.js b/test/src/Policy.test.js
index fc1619bb4..d08dc5b8b 100644
--- a/test/src/Policy.test.js
+++ b/test/src/Policy.test.js
@@ -77,22 +77,22 @@ describe('src/classes/Policy.js', () => {
globals.SESSION.paused_blocking = false;
});
test('a blocked tracker is unblocked with reason BLOCK_REASON_BLOCK_PAUSED', () => {
- const { block, reason } = policy.shouldBlock(41, 'advertising', 1, 'www.cnn.com', 'https://www.cnn.com/');
+ const { block, reason } = Policy.shouldBlock(41, 'advertising', 1, 'www.cnn.com', 'https://www.cnn.com/');
expect(block).toBeFalsy();
expect(reason).toBe(BLOCK_REASON_BLOCK_PAUSED);
});
test('an unblocked tracker remains unblocked with reason BLOCK_REASON_BLOCK_PAUSED', () => {
- const { block, reason } = policy.shouldBlock(50, 'essential', 1, 'www.cnn.com', 'https://www.cnn.com/');
+ const { block, reason } = Policy.shouldBlock(50, 'essential', 1, 'www.cnn.com', 'https://www.cnn.com/');
expect(block).toBeFalsy();
expect(reason).toBe(BLOCK_REASON_BLOCK_PAUSED);
});
test('a tracker on a white-listed site is unblocked with reason BLOCK_REASON_BLOCK_PAUSED', () => {
- const { block, reason } = policy.shouldBlock(41, 'advertising', 1, 'www.ghostery.com', 'https://www.ghostery.com/');
+ const { block, reason } = Policy.shouldBlock(41, 'advertising', 1, 'www.ghostery.com', 'https://www.ghostery.com/');
expect(block).toBeFalsy();
expect(reason).toBe(BLOCK_REASON_BLOCK_PAUSED);
});
test('a tracker on a black-listed site is unblocked with reason BLOCK_REASON_BLOCK_PAUSED', () => {
- const { block, reason } = policy.shouldBlock(50, 'essential', 1, 'www.tmz.com', 'https://www.tmz.com/');
+ const { block, reason } = Policy.shouldBlock(50, 'essential', 1, 'www.tmz.com', 'https://www.tmz.com/');
expect(block).toBeFalsy();
expect(reason).toBe(BLOCK_REASON_BLOCK_PAUSED);
});
@@ -106,32 +106,32 @@ describe('src/classes/Policy.js', () => {
c2pDb.allowedOnce.mockReturnValue(false);
});
test('a blocked tracker on the site-specific allow list on a black-listed site is unblocked with reason BLOCK_REASON_C2P_ALLOWED_ONCE', () => {
- const { block, reason } = policy.shouldBlock(41, 'advertising', 1, 'www.tmz.com', 'https://www.tmz.com/');
+ const { block, reason } = Policy.shouldBlock(41, 'advertising', 1, 'www.tmz.com', 'https://www.tmz.com/');
expect(block).toBeFalsy();
expect(reason).toBe(BLOCK_REASON_C2P_ALLOWED_ONCE);
});
test('a blocked tracker is unblocked with reason BLOCK_REASON_C2P_ALLOWED_ONCE', () => {
- const { block, reason } = policy.shouldBlock(41, 'advertising', 1, 'www.cnn.com', 'https://www.cnn.com/');
+ const { block, reason } = Policy.shouldBlock(41, 'advertising', 1, 'www.cnn.com', 'https://www.cnn.com/');
expect(block).toBeFalsy();
expect(reason).toBe(BLOCK_REASON_C2P_ALLOWED_ONCE);
});
test('an unblocked tracker on the site-specific block list remains unblocked with reason BLOCK_REASON_C2P_ALLOWED_ONCE', () => {
- const { block, reason } = policy.shouldBlock(50, 'essential', 1, 'www.espn.com', 'https://www.espn.com/');
+ const { block, reason } = Policy.shouldBlock(50, 'essential', 1, 'www.espn.com', 'https://www.espn.com/');
expect(block).toBeFalsy();
expect(reason).toBe(BLOCK_REASON_C2P_ALLOWED_ONCE);
});
test('an unblocked tracker on the site-specific allow list on a black-listed site remains unblocked with reason BLOCK_REASON_C2P_ALLOWED_ONCE', () => {
- const { block, reason } = policy.shouldBlock(50, 'essential', 1, 'www.tmz.com', 'https://www.tmz.com/');
+ const { block, reason } = Policy.shouldBlock(50, 'essential', 1, 'www.tmz.com', 'https://www.tmz.com/');
expect(block).toBeFalsy();
expect(reason).toBe(BLOCK_REASON_C2P_ALLOWED_ONCE);
});
test('an unblocked tracker on a black-listed site remains unblocked with reason BLOCK_REASON_C2P_ALLOWED_ONCE', () => {
- const { block, reason } = policy.shouldBlock(55, 'essential', 1, 'www.tmz.com', 'https://www.tmz.com/');
+ const { block, reason } = Policy.shouldBlock(55, 'essential', 1, 'www.tmz.com', 'https://www.tmz.com/');
expect(block).toBeFalsy();
expect(reason).toBe(BLOCK_REASON_C2P_ALLOWED_ONCE);
});
test('an unblocked tracker remains unblocked with reason BLOCK_REASON_C2P_ALLOWED_ONCE', () => {
- const { block, reason } = policy.shouldBlock(55, 'essential', 1, 'www.cnn.com', 'https://www.cnn.com/');
+ const { block, reason } = Policy.shouldBlock(55, 'essential', 1, 'www.cnn.com', 'https://www.cnn.com/');
expect(block).toBeFalsy();
expect(reason).toBe(BLOCK_REASON_C2P_ALLOWED_ONCE);
});
@@ -139,22 +139,22 @@ describe('src/classes/Policy.js', () => {
describe('with a globally blocked tracker', () => {
test('a tracker on the site-specific allow list is unblocked with reason BLOCK_REASON_SS_UNBLOCKED', () => {
- const { block, reason } = policy.shouldBlock(15, 'site_analytics', 1, 'www.cnn.com', 'https://www.cnn.com/');
+ const { block, reason } = Policy.shouldBlock(15, 'site_analytics', 1, 'www.cnn.com', 'https://www.cnn.com/');
expect(block).toBeFalsy();
expect(reason).toBe(BLOCK_REASON_SS_UNBLOCKED);
});
test('a tracker on the site-specific allow list on a black-listed site remains blocked with reason BLOCK_REASON_BLACKLISTED', () => {
- const { block, reason } = policy.shouldBlock(41, 'advertising', 1, 'www.tmz.com', 'https://www.tmz.com/');
+ const { block, reason } = Policy.shouldBlock(41, 'advertising', 1, 'www.tmz.com', 'https://www.tmz.com/');
expect(block).toBeTruthy();
expect(reason).toBe(BLOCK_REASON_BLACKLISTED);
});
test('a tracker on a white-listed site is unblocked with reason BLOCK_REASON_WHITELISTED', () => {
- const { block, reason } = policy.shouldBlock(41, 'advertising', 1, 'www.ghostery.com', 'https://www.ghostery.com/');
+ const { block, reason } = Policy.shouldBlock(41, 'advertising', 1, 'www.ghostery.com', 'https://www.ghostery.com/');
expect(block).toBeFalsy();
expect(reason).toBe(BLOCK_REASON_WHITELISTED);
});
test('a tracker is blocked with reason BLOCK_REASON_GLOBAL_BLOCKED', () => {
- const { block, reason } = policy.shouldBlock(41, 'advertising', 1, 'www.cnn.com', 'https://www.cnn.com/');
+ const { block, reason } = Policy.shouldBlock(41, 'advertising', 1, 'www.cnn.com', 'https://www.cnn.com/');
expect(block).toBeTruthy();
expect(reason).toBe(BLOCK_REASON_GLOBAL_BLOCKED);
});
@@ -162,32 +162,32 @@ describe('src/classes/Policy.js', () => {
describe('with a globally unblocked tracker', () => {
test('a tracker on the site-specific block list is blocked with reason BLOCK_REASON_SS_BLOCKED', () => {
- const { block, reason } = policy.shouldBlock(13, 'site_analytics', 1, 'www.cnn.com', 'https://www.cnn.com/');
+ const { block, reason } = Policy.shouldBlock(13, 'site_analytics', 1, 'www.cnn.com', 'https://www.cnn.com/');
expect(block).toBeTruthy();
expect(reason).toBe(BLOCK_REASON_SS_BLOCKED);
});
test('a tracker on the site-specific block list on a white-listed site is unblocked with reason BLOCK_REASON_WHITELISTED', () => {
- const { block, reason } = policy.shouldBlock(15, 'site_analytics', 1, 'www.ghostery.com', 'https://www.ghostery.com/');
+ const { block, reason } = Policy.shouldBlock(15, 'site_analytics', 1, 'www.ghostery.com', 'https://www.ghostery.com/');
expect(block).toBeFalsy();
expect(reason).toBe(BLOCK_REASON_WHITELISTED);
});
test('a tracker on the site-specific allow list is unblocked with reason BLOCK_REASON_SS_UNBLOCKED', () => {
- const { block, reason } = policy.shouldBlock(50, 'essential', 1, 'www.cnn.com', 'https://www.cnn.com/');
+ const { block, reason } = Policy.shouldBlock(50, 'essential', 1, 'www.cnn.com', 'https://www.cnn.com/');
expect(block).toBeFalsy();
expect(reason).toBe(BLOCK_REASON_SS_UNBLOCKED);
});
test('a tracker on the site-specific allow list on a black-listed site is blocked with reason BLOCK_REASON_BLACKLISTED', () => {
- const { block, reason } = policy.shouldBlock(50, 'essential', 1, 'www.tmz.com', 'https://www.tmz.com/');
+ const { block, reason } = Policy.shouldBlock(50, 'essential', 1, 'www.tmz.com', 'https://www.tmz.com/');
expect(block).toBeTruthy();
expect(reason).toBe(BLOCK_REASON_BLACKLISTED);
});
test('a tracker on a black-listed site is blocked with reason BLOCK_REASON_BLACKLISTED', () => {
- const { block, reason } = policy.shouldBlock(55, 'essential', 1, 'www.tmz.com', 'https://www.tmz.com/');
+ const { block, reason } = Policy.shouldBlock(55, 'essential', 1, 'www.tmz.com', 'https://www.tmz.com/');
expect(block).toBeTruthy();
expect(reason).toBe(BLOCK_REASON_BLACKLISTED);
});
test('a tracker is unblocked with reason BLOCK_REASON_GLOBAL_UNBLOCKED', () => {
- const { block, reason } = policy.shouldBlock(55, 'essential', 1, 'www.cnn.com', 'https://www.cnn.com/');
+ const { block, reason } = Policy.shouldBlock(55, 'essential', 1, 'www.cnn.com', 'https://www.cnn.com/');
expect(block).toBeFalsy();
expect(reason).toBe(BLOCK_REASON_GLOBAL_UNBLOCKED);
});
@@ -198,63 +198,63 @@ describe('src/classes/Policy.js', () => {
test('matchesWildcard should return true with wildcard entered ', () => {
let url = 'developer.mozilla.org';
let input = 'developer.*.org';
- expect(policy.matchesWildcard(url, input)).toBeTruthy();
+ expect(Policy.matchesWildcard(url, input)).toBeTruthy();
url = 'ghostery.com';
input = '*.com';
- expect(policy.matchesWildcard(url, input)).toBeTruthy();
+ expect(Policy.matchesWildcard(url, input)).toBeTruthy();
url = 'ghostery.com'
input = '*';
- expect(policy.matchesWildcard(url, input)).toBeTruthy();
+ expect(Policy.matchesWildcard(url, input)).toBeTruthy();
url = 'developer.mozilla.org';
input = 'developer.*';
- expect(policy.matchesWildcard(url , input)).toBeTruthy();
+ expect(Policy.matchesWildcard(url , input)).toBeTruthy();
url = 'developer.mozilla.org';
input = '****';
- expect(policy.matchesWildcard(url, input)).toBeTruthy();
+ expect(Policy.matchesWildcard(url, input)).toBeTruthy();
});
test('matchesWildcard should return false with wildcard entered ', () => {
let url = 'developer.mozilla.org';
let input = '';
- expect(policy.matchesWildcard(url, input)).toBeFalsy();
+ expect(Policy.matchesWildcard(url, input)).toBeFalsy();
url = 'ghostery.com';
input = '+$@@#$*';
- expect(policy.matchesWildcard(url, input)).toBeFalsy();
+ expect(Policy.matchesWildcard(url, input)).toBeFalsy();
url = 'ghostery.com'
input = 'αράδειγμα.δοκιμ.*';
- expect(policy.matchesWildcard(url, input)).toBeFalsy();
+ expect(Policy.matchesWildcard(url, input)).toBeFalsy();
url = 'SELECT * FROM USERS';
input = 'developer.*';
- expect(policy.matchesWildcard(url , input)).toBeFalsy();
+ expect(Policy.matchesWildcard(url , input)).toBeFalsy();
});
test('matchesWildcard should return false with regex entered', () => {
let url = 'foo.com';
let input = '/foo)]/';
- expect(policy.matchesWildcard(url, input)).toBeFalsy();
+ expect(Policy.matchesWildcard(url, input)).toBeFalsy();
url = 'foo.com';
input = 'test\\';
- expect(policy.matchesWildcard(url, input)).toBeFalsy();
+ expect(Policy.matchesWildcard(url, input)).toBeFalsy();
url = 'foo.com';
input = '/(?<=x*)foo/';
- expect(policy.matchesWildcard(url, input)).toBeFalsy();
+ expect(Policy.matchesWildcard(url, input)).toBeFalsy();
url = 'foo.com';
input = '/foo(?)/';
- expect(policy.matchesWildcard(url, input)).toBeFalsy();
+ expect(Policy.matchesWildcard(url, input)).toBeFalsy();
url = 'foo.com';
input = '';
- expect(policy.matchesWildcard(url, input)).toBeFalsy();
+ expect(Policy.matchesWildcard(url, input)).toBeFalsy();
});
})
});
diff --git a/test/src/PolicySmartBlock.test.js b/test/src/PolicySmartBlock.test.js
index 7534e9f6b..342f7acea 100644
--- a/test/src/PolicySmartBlock.test.js
+++ b/test/src/PolicySmartBlock.test.js
@@ -45,7 +45,7 @@ describe('src/classes/PolicySmartBlock.js', () => {
describe('PolicySmartBlock isFirstPartyRequest tests', () => {
beforeAll(() => {
- policySmartBlock.shouldCheck = jest.fn(() => true);
+ PolicySmartBlock.shouldCheck = jest.fn(() => true);
});
afterAll(() => {
@@ -53,18 +53,18 @@ describe('src/classes/PolicySmartBlock.js', () => {
});
test('PolicySmartBlock isFirstPartyRequest truthy assertion', () => {
- expect(policySmartBlock.isFirstPartyRequest('tabId', 'example.com', 'example.com')).toBeTruthy();
+ expect(PolicySmartBlock.isFirstPartyRequest('tabId', 'example.com', 'example.com')).toBeTruthy();
// isFirstPartyRequest() expects pre-parsed domains, so we should parse the test urls
const parsedPage = processUrl('https://checkout.ghostery.com/insights');
const parsedRequest = processUrl('https://analytics.ghostery.com/piwik.js');
- expect(policySmartBlock.isFirstPartyRequest('tabId', parsedPage.generalDomain, parsedRequest.generalDomain)).toBeTruthy();
+ expect(PolicySmartBlock.isFirstPartyRequest('tabId', parsedPage.generalDomain, parsedRequest.generalDomain)).toBeTruthy();
});
test('PolicySmartBlock isFirstPartyRequest falsy assertion', () => {
- expect(policySmartBlock.isFirstPartyRequest('tabId', 'www.example.com', 'example.com')).toBeFalsy();
- expect(policySmartBlock.isFirstPartyRequest('tabId', 'sub.example.com', 'example.com')).toBeFalsy();
- expect(policySmartBlock.isFirstPartyRequest('tabId', 'example.com', 'test.com')).toBeFalsy();
- expect(policySmartBlock.isFirstPartyRequest('tabId', 'www.example.com', 'www.test.com')).toBeFalsy();
+ expect(PolicySmartBlock.isFirstPartyRequest('tabId', 'www.example.com', 'example.com')).toBeFalsy();
+ expect(PolicySmartBlock.isFirstPartyRequest('tabId', 'sub.example.com', 'example.com')).toBeFalsy();
+ expect(PolicySmartBlock.isFirstPartyRequest('tabId', 'example.com', 'test.com')).toBeFalsy();
+ expect(PolicySmartBlock.isFirstPartyRequest('tabId', 'www.example.com', 'www.test.com')).toBeFalsy();
});
});
});
diff --git a/test/utils/matcher.test.js b/test/utils/matcher.test.js
index 87dc6f432..6c2ea466e 100644
--- a/test/utils/matcher.test.js
+++ b/test/utils/matcher.test.js
@@ -19,6 +19,7 @@ describe('src/utils/matcher.js', () => {
beforeAll(done => {
// Fake the XMLHttpRequest for fetchJson(/daabases/bugs.json)
const bugsJson = JSON.stringify({
+ "apps": {},
"firstPartyExceptions": {
"101": [
"google.com/ig"
@@ -32,6 +33,7 @@ describe('src/utils/matcher.js', () => {
]
},
"patterns": {
+ "regex": {},
"host": {
"com": {
"gmodules": {
diff --git a/tools/leet/leet-en.js b/tools/leet/leet-en.js
index f1c236894..7cf02cdfd 100644
--- a/tools/leet/leet-en.js
+++ b/tools/leet/leet-en.js
@@ -62,14 +62,13 @@ const leet_convert = function(string) {
// 'z': 'z',
};
- let letter;
let output = string || '';
output = output.replace(/cks/g, 'x');
- for (letter in characterMap) {
- if (characterMap.hasOwnProperty(letter)) {
- output = output.replace(new RegExp(letter, 'g'), characterMap[letter]);
- }
+ const characterKeys = Object.keys(characterMap);
+ for (let i = 0; i < characterKeys.length; i++) {
+ const letter = characterKeys[i];
+ output = output.replace(new RegExp(letter, 'g'), characterMap[letter]);
}
return output;
@@ -82,11 +81,12 @@ if (!fs.existsSync('./tools/leet/messages.en.copy.json')) {
// Import the copied messages file
const leet = {};
- let key;
const en = jsonfile.readFileSync('./tools/leet/messages.en.copy.json');
// Create a LEETed version of the messages.json file
- for (key in en) {
+ const enKeys = Object.keys(en);
+ for (let i = 0; i < enKeys.length; i++) {
+ const key = enKeys[i];
if (en[key].hasOwnProperty('message')) {
const message = leet_convert(en[key].message);
const { placeholders } = en[key];