From 2b67d9214058f5d6e370c60fc20bb8b15d71d2b9 Mon Sep 17 00:00:00 2001
From: Thomas Rientjes <synzvato@protonmail.com>
Date: Mon, 6 Nov 2017 00:04:30 -0300
Subject: [PATCH] Refactor existing codebase

---
 .eslintrc                | 17 ++++----------
 audit/.eslintrc          |  7 ++++++
 core/constants.js        | 51 ++++++++++++++++++++++++++++++----------
 core/interceptor.js      | 12 +++++-----
 core/main.js             |  3 ++-
 core/request-analyzer.js | 26 ++++++++++----------
 core/state-manager.js    | 20 ++++++++--------
 pages/options/options.js | 22 ++++++++---------
 pages/popup/popup.js     | 14 +++++------
 9 files changed, 100 insertions(+), 72 deletions(-)

diff --git a/.eslintrc b/.eslintrc
index f898349..b703040 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -6,25 +6,18 @@
   },
   "extends": "eslint:recommended",
   "globals": {
+    "Address": true,
     "files": true,
     "helpers": true,
-    "HOST_PREFIX": true,
-    "HOST_SUFFIX": true,
-    "HTTP_EXPRESSION": true,
     "interceptor": true,
-    "MAPPING_FILE_EXPRESSION": true,
     "mappings": true,
-    "REQUEST_BLOCKING": true,
-    "REQUEST_HEADERS": true,
     "requestAnalyzer": true,
+    "Resource": true,
     "resources": true,
+    "Setting": true,
     "stateManager": true,
-    "VALUE_SEPARATOR": true,
-    "VERSION_EXPRESSION": true,
-    "VERSION_PLACEHOLDER": true,
-    "WEB_DOMAIN_EXPRESSION": true,
-    "WEB_PREFIX_LENGTH": true,
-    "WEB_PREFIX_VALUE": true
+    "WebRequest": true,
+    "Whitelist": true
   },
   "overrides": {
     "files": [
diff --git a/audit/.eslintrc b/audit/.eslintrc
index c5501dd..7a386a6 100644
--- a/audit/.eslintrc
+++ b/audit/.eslintrc
@@ -17,6 +17,13 @@
       "unix"
     ],
     "no-console": "off",
+    "no-multiple-empty-lines": [
+      "error", {
+        "max": 1,
+        "maxEOF": 1,
+        "maxBOF": 0
+      }
+    ],
     "no-use-before-define": "error",
     "operator-assignment": "error",
     "prefer-template": "error",
diff --git a/core/constants.js b/core/constants.js
index e68440d..07ddd42 100644
--- a/core/constants.js
+++ b/core/constants.js
@@ -17,15 +17,42 @@
  * Constants
  */
 
-const HOST_PREFIX = '*://';
-const HOST_SUFFIX = '/*';
-const HTTP_EXPRESSION = /^http?:\/\//;
-const MAPPING_FILE_EXPRESSION = /\.map$/i;
-const REQUEST_BLOCKING = 'blocking';
-const REQUEST_HEADERS = 'requestHeaders';
-const VALUE_SEPARATOR = ';';
-const VERSION_EXPRESSION = /(?:\d{1,2}\.){1,3}\d{1,2}/;
-const VERSION_PLACEHOLDER = '{version}';
-const WEB_DOMAIN_EXPRESSION = /:\/\/(.[^/]+)(.*)/;
-const WEB_PREFIX_LENGTH = 4;
-const WEB_PREFIX_VALUE = 'www.';
+const Address = {
+    'ANY': '*://*/*',
+    'ANY_PATH': '/*',
+    'ANY_PROTOCOL': '*://',
+    'DOMAIN_EXPRESSION': /:\/\/(.[^/]+)(.*)/,
+    'EXAMPLE': 'example.org',
+    'HTTP_EXPRESSION': /^http?:\/\//,
+    'HTTPS': 'https://',
+    'WWW_PREFIX': 'www.',
+    'WWW_PREFIX_LENGTH': 4
+};
+
+const Resource = {
+    'MAPPING_EXPRESSION': /\.map$/i,
+    'VERSION_EXPRESSION': /(?:\d{1,2}\.){1,3}\d{1,2}/,
+    'VERSION_PLACEHOLDER': '{version}'
+};
+
+const Setting = {
+    'AMOUNT_INJECTED': 'amountInjected',
+    'BLOCK_MISSING': 'blockMissing',
+    'DISABLE_PREFETCH': 'disablePrefetch',
+    'SHOW_ICON_BADGE': 'showIconBadge',
+    'STRIP_METADATA': 'stripMetadata',
+    'WHITELISTED_DOMAINS': 'whitelistedDomains'
+};
+
+const WebRequest = {
+    'GET': 'GET',
+    'BLOCKING': 'blocking',
+    'HEADERS': 'requestHeaders',
+    'ORIGIN_HEADER': 'Origin',
+    'REFERER_HEADER': 'Referer'
+};
+
+const Whitelist = {
+    'TRIM_EXPRESSION': /^;+|;+$/g,
+    'VALUE_SEPARATOR': ';'
+};
diff --git a/core/interceptor.js b/core/interceptor.js
index bc125f6..e9b28ce 100644
--- a/core/interceptor.js
+++ b/core/interceptor.js
@@ -37,10 +37,10 @@ interceptor.handleRequest = function (requestDetails, tabIdentifier, tab) {
     }
 
     try {
-        tabDomain = tab.url.match(WEB_DOMAIN_EXPRESSION)[1];
+        tabDomain = tab.url.match(Address.DOMAIN_EXPRESSION)[1];
         tabDomain = requestAnalyzer._normalizeDomain(tabDomain);
     } catch (exception) {
-        tabDomain = 'example.org';
+        tabDomain = Address.EXAMPLE;
     }
 
     // Temporary list of undetectable tainted domains.
@@ -98,9 +98,9 @@ interceptor._handleMissingCandidate = function (requestUrl) {
         };
     }
 
-    if (requestUrl.match(HTTP_EXPRESSION)) {
+    if (requestUrl.match(Address.HTTP_EXPRESSION)) {
 
-        let secureRequestUrl = requestUrl.replace(HTTP_EXPRESSION, 'https://');
+        let secureRequestUrl = requestUrl.replace(Address.HTTP_EXPRESSION, Address.HTTPS);
 
         return {
             'redirectUrl': secureRequestUrl
@@ -116,7 +116,7 @@ interceptor._handleMissingCandidate = function (requestUrl) {
 
 interceptor._handleStorageChanged = function (changes) {
 
-    if ('blockMissing' in changes) {
+    if (Setting.BLOCK_MISSING in changes) {
         interceptor.blockMissing = changes.blockMissing.newValue;
     }
 };
@@ -128,7 +128,7 @@ interceptor._handleStorageChanged = function (changes) {
 interceptor.amountInjected = 0;
 interceptor.blockMissing = false;
 
-chrome.storage.local.get(['amountInjected', 'blockMissing'], function (items) {
+chrome.storage.local.get([Setting.AMOUNT_INJECTED, Setting.BLOCK_MISSING], function (items) {
 
     interceptor.amountInjected = items.amountInjected || 0;
     interceptor.blockMissing = items.blockMissing || false;
diff --git a/core/main.js b/core/main.js
index 9bfc787..55632cd 100644
--- a/core/main.js
+++ b/core/main.js
@@ -54,7 +54,8 @@ main._showReleaseNotes = function (details) {
 
     let location = chrome.extension.getURL('pages/welcome/welcome.html');
 
-    if (details.reason === 'install' || details.reason === 'update') {
+    if (details.reason === chrome.runtime.OnInstalledReason.INSTALL ||
+        details.reason === chrome.runtime.OnInstalledReason.UPDATE) {
 
         if (details.temporary !== true) {
 
diff --git a/core/request-analyzer.js b/core/request-analyzer.js
index 70b41cb..d84a327 100644
--- a/core/request-analyzer.js
+++ b/core/request-analyzer.js
@@ -28,9 +28,9 @@ requestAnalyzer.isValidCandidate = function (requestDetails, tabDetails) {
     let initiatorHost;
 
     try {
-        initiatorHost = tabDetails.url.match(WEB_DOMAIN_EXPRESSION)[1];
+        initiatorHost = tabDetails.url.match(Address.DOMAIN_EXPRESSION)[1];
     } catch (exception) {
-        initiatorHost = 'example.org';
+        initiatorHost = Address.EXAMPLE;
     }
 
     if (initiatorHost && requestAnalyzer.whitelistedDomains[requestAnalyzer._normalizeDomain(initiatorHost)]) {
@@ -38,21 +38,21 @@ requestAnalyzer.isValidCandidate = function (requestDetails, tabDetails) {
     }
 
     // Only requests of type GET can be valid candidates.
-    return requestDetails.method === 'GET';
+    return requestDetails.method === WebRequest.GET;
 };
 
 requestAnalyzer.getLocalTarget = function (requestDetails) {
 
     let destinationHost, destinationPath, hostMappings, basePath, resourceMappings;
 
-    destinationHost = requestDetails.url.match(WEB_DOMAIN_EXPRESSION)[1];
-    destinationPath = requestDetails.url.match(WEB_DOMAIN_EXPRESSION)[2];
+    destinationHost = requestDetails.url.match(Address.DOMAIN_EXPRESSION)[1];
+    destinationPath = requestDetails.url.match(Address.DOMAIN_EXPRESSION)[2];
 
     // Use the proper mappings for the targeted host.
     hostMappings = mappings[destinationHost];
 
     // Resource mapping files are never locally available.
-    if (MAPPING_FILE_EXPRESSION.test(destinationPath)) {
+    if (Resource.MAPPING_EXPRESSION.test(destinationPath)) {
         return false;
     }
 
@@ -89,8 +89,8 @@ requestAnalyzer._findLocalTarget = function (resourceMappings, basePath, channel
 
     resourcePath = channelPath.replace(basePath, '');
 
-    versionNumber = resourcePath.match(VERSION_EXPRESSION);
-    resourcePattern = resourcePath.replace(versionNumber, VERSION_PLACEHOLDER);
+    versionNumber = resourcePath.match(Resource.VERSION_EXPRESSION);
+    resourcePattern = resourcePath.replace(versionNumber, Resource.VERSION_PLACEHOLDER);
 
     for (let resourceMold of Object.keys(resourceMappings)) {
 
@@ -99,9 +99,9 @@ requestAnalyzer._findLocalTarget = function (resourceMappings, basePath, channel
             let targetPath, version;
 
             targetPath = resourceMappings[resourceMold].path;
-            targetPath = targetPath.replace(VERSION_PLACEHOLDER, versionNumber);
+            targetPath = targetPath.replace(Resource.VERSION_PLACEHOLDER, versionNumber);
 
-            version = versionNumber && versionNumber[0] || targetPath.match(VERSION_EXPRESSION);
+            version = versionNumber && versionNumber[0] || targetPath.match(Resource.VERSION_EXPRESSION);
 
             // Prepare and return a local target.
             return {
@@ -117,7 +117,7 @@ requestAnalyzer._findLocalTarget = function (resourceMappings, basePath, channel
 
 requestAnalyzer._applyWhitelistedDomains = function () {
 
-    chrome.storage.local.get('whitelistedDomains', function (items) {
+    chrome.storage.local.get(Setting.WHITELISTED_DOMAINS, function (items) {
         requestAnalyzer.whitelistedDomains = items.whitelistedDomains || {};
     });
 };
@@ -126,8 +126,8 @@ requestAnalyzer._normalizeDomain = function (domain) {
 
     domain = domain.toLowerCase().trim();
 
-    if (domain.startsWith(WEB_PREFIX_VALUE)) {
-        domain = domain.slice(WEB_PREFIX_LENGTH);
+    if (domain.startsWith(Address.WWW_PREFIX)) {
+        domain = domain.slice(Address.WWW_PREFIX_LENGTH);
     }
 
     return domain;
diff --git a/core/state-manager.js b/core/state-manager.js
index bfe475d..6a4c798 100644
--- a/core/state-manager.js
+++ b/core/state-manager.js
@@ -53,7 +53,7 @@ stateManager.registerInjection = function (tabIdentifier, injection) {
 
     if (isNaN(interceptor.amountInjected)) {
 
-        chrome.storage.local.get('amountInjected', function (items) {
+        chrome.storage.local.get(Setting.AMOUNT_INJECTED, function (items) {
 
             interceptor.amountInjected = items.amountInjected;
 
@@ -121,7 +121,7 @@ stateManager._createTab = function (tab) {
             });
         });
 
-    }, requestFilters, [REQUEST_BLOCKING]);
+    }, requestFilters, [WebRequest.BLOCKING]);
 };
 
 stateManager._removeTab = function (tabIdentifier) {
@@ -156,9 +156,9 @@ stateManager._stripMetadata = function (requestDetails) {
 
     for (let i = 0; i < requestDetails.requestHeaders.length; ++i) {
 
-        if (requestDetails.requestHeaders[i].name === 'Origin') {
+        if (requestDetails.requestHeaders[i].name === WebRequest.ORIGIN_HEADER) {
             requestDetails.requestHeaders.splice(i--, 1);
-        } else if (requestDetails.requestHeaders[i].name === 'Referer') {
+        } else if (requestDetails.requestHeaders[i].name === WebRequest.REFERER_HEADER) {
             requestDetails.requestHeaders.splice(i--, 1);
         }
     }
@@ -190,13 +190,13 @@ stateManager._handleStorageChanged = function (changes) {
 
         onBeforeSendHeaders.removeListener(stateManager._stripMetadata, {
             'urls': stateManager.validHosts
-        }, [REQUEST_BLOCKING, REQUEST_HEADERS]);
+        }, [WebRequest.BLOCKING, WebRequest.HEADERS]);
 
         if (changes.stripMetadata.newValue !== false) {
 
             onBeforeSendHeaders.addListener(stateManager._stripMetadata, {
                 'urls': stateManager.validHosts
-            }, [REQUEST_BLOCKING, REQUEST_HEADERS]);
+            }, [WebRequest.BLOCKING, WebRequest.HEADERS]);
         }
     }
 };
@@ -219,7 +219,7 @@ stateManager.validHosts = [];
 
 for (let mapping in mappings) {
 
-    let supportedHost = HOST_PREFIX + mapping + HOST_SUFFIX;
+    let supportedHost = Address.ANY_PROTOCOL + mapping + Address.ANY_PATH;
     stateManager.validHosts.push(supportedHost);
 }
 
@@ -248,7 +248,7 @@ chrome.webRequest.onErrorOccurred.addListener(function (requestDetails) {
         delete stateManager.requests[requestDetails.requestId];
     }
 
-}, {'urls': ['*://*/*']});
+}, {'urls': [Address.ANY]});
 
 chrome.webRequest.onBeforeRedirect.addListener(function (requestDetails) {
 
@@ -260,10 +260,10 @@ chrome.webRequest.onBeforeRedirect.addListener(function (requestDetails) {
         delete stateManager.requests[requestDetails.requestId];
     }
 
-}, {'urls': ['*://*/*']});
+}, {'urls': [Address.ANY]});
 
 chrome.webRequest.onBeforeSendHeaders.addListener(stateManager._stripMetadata, {
     'urls': stateManager.validHosts
-}, [REQUEST_BLOCKING, REQUEST_HEADERS]);
+}, [WebRequest.BLOCKING, WebRequest.HEADERS]);
 
 chrome.storage.onChanged.addListener(stateManager._handleStorageChanged);
diff --git a/pages/options/options.js b/pages/options/options.js
index d91d2cc..ed6e8e2 100644
--- a/pages/options/options.js
+++ b/pages/options/options.js
@@ -31,8 +31,8 @@ function _normalizeDomain (domain) {
 
     domain = domain.toLowerCase().trim();
 
-    if (domain.startsWith(WEB_PREFIX_VALUE)) {
-        domain = domain.slice(WEB_PREFIX_LENGTH);
+    if (domain.startsWith(Address.WWW_PREFIX)) {
+        domain = domain.slice(Address.WWW_PREFIX_LENGTH);
     }
 
     return domain;
@@ -60,11 +60,11 @@ document.addEventListener('DOMContentLoaded', function () {
     helpers.insertI18nContentIntoDocument(document);
 
     optionElements = {
-        'showIconBadge': options._getOptionElement('showIconBadge'),
-        'blockMissing': options._getOptionElement('blockMissing'),
-        'disablePrefetch': options._getOptionElement('disablePrefetch'),
-        'stripMetadata': options._getOptionElement('stripMetadata'),
-        'whitelistedDomains': options._getOptionElement('whitelistedDomains')
+        'showIconBadge': options._getOptionElement(Setting.SHOW_ICON_BADGE),
+        'blockMissing': options._getOptionElement(Setting.BLOCK_MISSING),
+        'disablePrefetch': options._getOptionElement(Setting.DISABLE_PREFETCH),
+        'stripMetadata': options._getOptionElement(Setting.STRIP_METADATA),
+        'whitelistedDomains': options._getOptionElement(Setting.WHITELISTED_DOMAINS)
     };
 
     chrome.storage.local.get(Object.keys(optionElements), function (items) {
@@ -79,7 +79,7 @@ document.addEventListener('DOMContentLoaded', function () {
         });
 
         domainWhitelist = domainWhitelist.slice(0, -1);
-        domainWhitelist = domainWhitelist.replace(/^;+|;+$/g, '');
+        domainWhitelist = domainWhitelist.replace(Whitelist.TRIM_EXPRESSION, '');
 
         optionElements.showIconBadge.checked = items.showIconBadge;
         optionElements.blockMissing.checked = items.blockMissing;
@@ -103,7 +103,7 @@ document.addEventListener('DOMContentLoaded', function () {
             optionValue = target.value;
         }
 
-        if (optionKey === 'disablePrefetch') {
+        if (optionKey === Setting.DISABLE_PREFETCH) {
 
             if (optionValue === false) {
 
@@ -118,13 +118,13 @@ document.addEventListener('DOMContentLoaded', function () {
             }
         }
 
-        if (optionKey === 'whitelistedDomains') {
+        if (optionKey === Setting.WHITELISTED_DOMAINS) {
 
             let domainWhitelist = optionValue;
 
             optionValue = {};
 
-            domainWhitelist.split(VALUE_SEPARATOR).forEach(function (domain) {
+            domainWhitelist.split(Whitelist.VALUE_SEPARATOR).forEach(function (domain) {
                 optionValue[_normalizeDomain(domain)] = true;
             });
         }
diff --git a/pages/popup/popup.js b/pages/popup/popup.js
index cda7eaf..73ddce6 100644
--- a/pages/popup/popup.js
+++ b/pages/popup/popup.js
@@ -51,7 +51,7 @@ document.addEventListener('DOMContentLoaded', function () {
 
                 popup.backgroundPage = backgroundPage;
 
-                if (backgroundPage.main.operatingSystem === 'android') {
+                if (backgroundPage.main.operatingSystem === chrome.runtime.PlatformOs.ANDROID) {
 
                     browser.tabs.getCurrent().then(function (tab) {
 
@@ -67,7 +67,7 @@ document.addEventListener('DOMContentLoaded', function () {
                 injectionOverview = {};
 
                 try {
-                    domain = tabs[0].url.match(WEB_DOMAIN_EXPRESSION)[1];
+                    domain = tabs[0].url.match(Address.DOMAIN_EXPRESSION)[1];
                 } catch (exception) {
                     domain = null;
                 }
@@ -80,8 +80,8 @@ document.addEventListener('DOMContentLoaded', function () {
                     protectionToggleElement = document.getElementById('protection-toggle-button');
                     domainIndicatorElement = document.getElementById('domain-indicator');
 
-                    if (domain.startsWith(WEB_PREFIX_VALUE)) {
-                        domain = domain.slice(WEB_PREFIX_LENGTH);
+                    if (domain.startsWith(Address.WWW_PREFIX)) {
+                        domain = domain.slice(Address.WWW_PREFIX_LENGTH);
                     }
 
                     domainIndicatorElement.innerText = domain;
@@ -99,7 +99,7 @@ document.addEventListener('DOMContentLoaded', function () {
 
                                 chrome.tabs.reload(tabs[0].id);
 
-                                if (backgroundPage.main.operatingSystem === 'android') {
+                                if (backgroundPage.main.operatingSystem === chrome.runtime.PlatformOs.ANDROID) {
 
                                     return browser.tabs.getCurrent().then(function (tab) {
                                         browser.tabs.remove(tab.id);
@@ -125,7 +125,7 @@ document.addEventListener('DOMContentLoaded', function () {
 
                                 chrome.tabs.reload(tabs[0].id);
 
-                                if (backgroundPage.main.operatingSystem === 'android') {
+                                if (backgroundPage.main.operatingSystem === chrome.runtime.PlatformOs.ANDROID) {
 
                                     return browser.tabs.getCurrent().then(function (tab) {
                                         browser.tabs.remove(tab.id);
@@ -225,7 +225,7 @@ document.addEventListener('DOMContentLoaded', function () {
 
     optionsButtonElement.addEventListener('mouseup', function () {
 
-        if (popup.backgroundPage.main.operatingSystem === 'android') {
+        if (popup.backgroundPage.main.operatingSystem === chrome.runtime.PlatformOs.ANDROID) {
 
             return chrome.tabs.create({
                 'url': chrome.extension.getURL('pages/options/options.html')
-- 
GitLab