diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 47419c6..f22bf71 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -4,6 +4,7 @@ before_script:
- export DEBIAN_FRONTEND= noninteractive
- apt-get update -y
- apt-get install -y zip unzip jq
+ - apt-get install nodejs
stages:
- build
@@ -13,9 +14,13 @@ hash rules:
stage: build
script:
- sha256sum data/data.min.json | awk '{print $1}' > rules.min.hash
+ - node build_tools/minifyDataJSON.js "..\data\data.min.json" "..\data\data.minify.json"
+ - sha256sum data/data.minify.json | awk '{print $1}' > rules.minify.hash
artifacts:
paths:
- rules.min.hash
+ - data.minify.json
+ - rules.minify.hash
build firefox:
stage: build
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 448de33..8c8919d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,21 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [1.9.2] - 2019-11-09
+
+### Compatibility note
+- Require Firefox >= 55
+- Require Chrome >= 22
+
+### Fixed
+- Fixed [#290](https://gitlab.com/KevinRoebert/ClearUrls/issues/290)
+
+## Changed
+- Updated some strings of Italian translation by [@gioxx](https://gitlab.com/gioxx)
+
+### Added
+- Added a minimal version of the data.min.json file where all line breaks and spaces, as well as default values and empty lists are removed.
+
## [1.9.1] - 2019-10-24
### Compatibility note
diff --git a/build_tools/minifyDataJSON.js b/build_tools/minifyDataJSON.js
new file mode 100644
index 0000000..fd30972
--- /dev/null
+++ b/build_tools/minifyDataJSON.js
@@ -0,0 +1,87 @@
+/*
+* ClearURLs
+* Copyright (c) 2017-2019 Kevin Röbert
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*/
+
+/*jshint esversion: 6 */
+/*
+* This script is responsible for minification of the data.min.json file and deletes also empty entries.
+*/
+let fs = require('fs');
+const inFileLocation = process.argv.slice(2)[0];
+const outFileLocation = process.argv.slice(2)[1];
+
+if(inFileLocation === undefined || outFileLocation === undefined) {
+ throw "in- and output must be set!";
+}
+
+const fileContent = fs.readFileSync(inFileLocation).toString();
+
+/**
+ * Builds a minify version of the data.min.json file.
+ */
+function build() {
+ const data = JSON.parse(fileContent);
+ let minifiedData = {"providers":{}};
+
+ for(let provider in data.providers) {
+ minifiedData.providers[provider] = {};
+ let self = minifiedData.providers[provider];
+
+ if(data.providers[provider].completeProvider === true) {
+ self.completeProvider = true;
+ }
+
+ if(data.providers[provider].forceRedirection === true) {
+ self.forceRedirection = true;
+ }
+
+ if(data.providers[provider].urlPattern !== "") {
+ self.urlPattern = data.providers[provider].urlPattern;
+ }
+
+ if(data.providers[provider].rules.length !== 0) {
+ self.rules = data.providers[provider].rules;
+ }
+
+ if(data.providers[provider].rawRules.length !== 0) {
+ self.rawRules = data.providers[provider].rawRules;
+ }
+
+ if(data.providers[provider].referralMarketing.length !== 0) {
+ self.referralMarketing = data.providers[provider].referralMarketing;
+ }
+
+ if(data.providers[provider].exceptions.length !== 0) {
+ self.exceptions = data.providers[provider].exceptions;
+ }
+
+ if(data.providers[provider].redirections.length !== 0) {
+ self.redirections = data.providers[provider].redirections;
+ }
+ }
+
+ fs.writeFile(outFileLocation, JSON.stringify(minifiedData), function(err) {
+
+ if(err) {
+ return console.log(err);
+ }
+
+ console.log("The file was saved!");
+ });
+}
+
+build();
\ No newline at end of file
diff --git a/clearurls.js b/clearurls.js
index 3b8c26f..95476ea 100644
--- a/clearurls.js
+++ b/clearurls.js
@@ -39,8 +39,7 @@ var currentURL;
* @param {boolean} quiet if the action should be displayed in log and statistics
* @return {Array} Array with changes and url fields
*/
-function removeFieldsFormURL(provider, pureUrl, quiet = false)
-{
+function removeFieldsFormURL(provider, pureUrl, quiet = false) {
let url = pureUrl;
let domain = "";
let fragments = "";
@@ -50,7 +49,7 @@ function removeFieldsFormURL(provider, pureUrl, quiet = false)
let cancel = false;
let rawRules = provider.getRawRules();
- if(storage.localHostsSkipping && checkLocalURL(pureUrl)) {
+ if (storage.localHostsSkipping && checkLocalURL(pureUrl)) {
return {
"changes": false,
"url": url,
@@ -61,28 +60,25 @@ function removeFieldsFormURL(provider, pureUrl, quiet = false)
/*
* Apply raw rules to the URL.
*/
- rawRules.forEach(function(rawRule) {
+ rawRules.forEach(function (rawRule) {
let beforeReplace = url;
url = url.replace(new RegExp(rawRule, "gi"), "");
- if(beforeReplace !== url) {
+ if (beforeReplace !== url) {
//Log the action
- if(storage.loggingStatus && !quiet)
- {
+ if (storage.loggingStatus && !quiet) {
pushToLog(beforeReplace, url, rawRule);
}
- if(badges[tabid] == null) badges[tabid] = 0;
+ if (badges[tabid] == null) badges[tabid] = 0;
- if(!quiet) increaseURLCounter();
+ if (!quiet) increaseURLCounter();
checkOSAndroid().then((res) => {
- if(!res) {
- if(storage.badgedStatus && !quiet) {
+ if (!res) {
+ if (storage.badgedStatus && !quiet) {
browser.browserAction.setBadgeText({text: (++badges[tabid]).toString(), tabId: tabid});
- }
- else
- {
+ } else {
browser.browserAction.setBadgeText({text: "", tabId: tabid});
}
}
@@ -92,10 +88,10 @@ function removeFieldsFormURL(provider, pureUrl, quiet = false)
}
});
- if(existsFragments(url)) {
+ if (existsFragments(url)) {
domain = url.replace(new RegExp("#.*", "i"), "");
}
- if(existsFields(url)) {
+ if (existsFields(url)) {
domain = url.replace(new RegExp("\\?.*", "i"), "");
}
@@ -104,12 +100,11 @@ function removeFieldsFormURL(provider, pureUrl, quiet = false)
* url redirections form sites to sites.
*/
let re = provider.getRedirection(url);
- if(re !== null)
- {
+ if (re !== null) {
url = decodeURL(re);
//Log the action
- if(!quiet) pushToLog(pureUrl, url, translate('log_redirect'));
+ if (!quiet) pushToLog(pureUrl, url, translate('log_redirect'));
return {
"redirect": true,
@@ -117,52 +112,47 @@ function removeFieldsFormURL(provider, pureUrl, quiet = false)
};
}
- if(existsFields(url)) {
- fields = "?"+extractFileds(url).rmEmpty().join("&");
+ if (existsFields(url)) {
+ fields = "?" + extractFileds(url).rmEmpty().join("&");
}
- if(existsFragments(url)) {
- fragments = "#"+extractFragments(url).rmEmpty().join("&");
+ if (existsFragments(url)) {
+ fragments = "#" + extractFragments(url).rmEmpty().join("&");
}
/**
- * Only test for matches, if there are fields or fragments that can be cleaned.
- */
- if(fields !== "" || fragments !== "")
- {
- rules.forEach(function(rule) {
+ * Only test for matches, if there are fields or fragments that can be cleaned.
+ */
+ if (fields !== "" || fragments !== "") {
+ rules.forEach(function (rule) {
let beforeReplace = fields;
let beforeReplaceFragments = fragments;
fields = fields.replace(new RegExp(rule, "gi"), "");
fragments = fragments.replace(new RegExp(rule, "gi"), "");
- if(beforeReplace !== fields || beforeReplaceFragments !== fragments)
- {
+ if (beforeReplace !== fields || beforeReplaceFragments !== fragments) {
//Log the action
- if(storage.loggingStatus)
- {
+ if (storage.loggingStatus) {
let tempURL = domain;
let tempBeforeURL = domain;
- if(fields !== "") tempURL += "?"+fields.replace("?&", "?").replace("?", "");
- if(fragments !== "") tempURL += "#"+fragments.replace("#&","#").replace("#", "");
- if(beforeReplace !== "") tempBeforeURL += "?"+beforeReplace.replace("?&", "?").replace("?", "");
- if(beforeReplaceFragments !== "") tempBeforeURL += "#"+beforeReplaceFragments.replace("#&","#").replace("#", "");
+ if (fields !== "") tempURL += "?" + fields.replace("?&", "?").replace("?", "");
+ if (fragments !== "") tempURL += "#" + fragments.replace("#&", "#").replace("#", "");
+ if (beforeReplace !== "") tempBeforeURL += "?" + beforeReplace.replace("?&", "?").replace("?", "");
+ if (beforeReplaceFragments !== "") tempBeforeURL += "#" + beforeReplaceFragments.replace("#&", "#").replace("#", "");
- if(!quiet) pushToLog(tempBeforeURL, tempURL, rule);
+ if (!quiet) pushToLog(tempBeforeURL, tempURL, rule);
}
- if(badges[tabid] == null) badges[tabid] = 0;
+ if (badges[tabid] == null) badges[tabid] = 0;
- if(!quiet) increaseURLCounter();
+ if (!quiet) increaseURLCounter();
checkOSAndroid().then((res) => {
- if(!res) {
- if(storage.badgedStatus && !quiet) {
+ if (!res) {
+ if (storage.badgedStatus && !quiet) {
browser.browserAction.setBadgeText({text: (++badges[tabid]).toString(), tabId: tabid});
- }
- else
- {
+ } else {
browser.browserAction.setBadgeText({text: "", tabId: tabid});
}
}
@@ -174,28 +164,25 @@ function removeFieldsFormURL(provider, pureUrl, quiet = false)
let finalURL = domain;
- if(fields !== "") finalURL += "?"+fields.replace("?", "");
- if(fragments !== "") finalURL += "#"+fragments.replace("#", "");
+ if (fields !== "") finalURL += "?" + fields.replace("?", "");
+ if (fragments !== "") finalURL += "#" + fragments.replace("#", "");
url = finalURL.replace(new RegExp("\\?&"), "?").replace(new RegExp("#&"), "#");
}
- if(provider.isCaneling()){
- if(!quiet) pushToLog(pureUrl, pureUrl, translate('log_domain_blocked'));
- if(badges[tabid] == null)
- {
+ if (provider.isCaneling()) {
+ if (!quiet) pushToLog(pureUrl, pureUrl, translate('log_domain_blocked'));
+ if (badges[tabid] == null) {
badges[tabid] = 0;
}
- if(!quiet) increaseURLCounter();
+ if (!quiet) increaseURLCounter();
checkOSAndroid().then((res) => {
- if(!res) {
- if(storage.badgedStatus && !quiet) {
+ if (!res) {
+ if (storage.badgedStatus && !quiet) {
browser.browserAction.setBadgeText({text: (++badges[tabid]).toString(), tabId: tabid});
- }
- else
- {
+ } else {
browser.browserAction.setBadgeText({text: "", tabId: tabid});
}
}
@@ -211,90 +198,86 @@ function removeFieldsFormURL(provider, pureUrl, quiet = false)
};
}
-function start()
-{
+function start() {
/**
- * Initialize the JSON provider object keys.
- *
- * @param {JSON Object} obj
- */
- function getKeys(obj){
- for(const key in obj){
+ * Initialize the JSON provider object keys.
+ *
+ * @param {object} obj
+ */
+ function getKeys(obj) {
+ for (const key in obj) {
prvKeys.push(key);
}
}
/**
- * Initialize the providers form the JSON object.
- *
- */
- function createProviders()
- {
+ * Initialize the providers form the JSON object.
+ *
+ */
+ function createProviders() {
let data = storage.ClearURLsData;
- for(let p = 0; p < prvKeys.length; p++)
- {
+ for (let p = 0; p < prvKeys.length; p++) {
//Create new provider
- providers.push(new Provider(prvKeys[p], data.providers[prvKeys[p]].completeProvider,
- data.providers[prvKeys[p]].forceRedirection));
+ providers.push(new Provider(prvKeys[p], data.providers[prvKeys[p]].getOrDefault('completeProvider', false),
+ data.providers[prvKeys[p]].getOrDefault('forceRedirection', false)));
- //Add URL Pattern
- providers[p].setURLPattern(data.providers[prvKeys[p]].urlPattern);
+ //Add URL Pattern
+ providers[p].setURLPattern(data.providers[prvKeys[p]].getOrDefault('urlPattern', ''));
- //Add rules to provider
- for(let r = 0; r < data.providers[prvKeys[p]].rules.length; r++)
- {
- providers[p].addRule(data.providers[prvKeys[p]].rules[r]);
- }
+ let rules = data.providers[prvKeys[p]].getOrDefault('rules', []);
+ //Add rules to provider
+ for (let r = 0; r < rules.length; r++) {
+ providers[p].addRule(rules[r]);
+ }
- //Add raw rules to provider
- for(let raw = 0; raw < data.providers[prvKeys[p]].rawRules.length; raw++)
- {
- providers[p].addRawRule(data.providers[prvKeys[p]].rawRules[raw]);
- }
+ let rawRules = data.providers[prvKeys[p]].getOrDefault('rawRules', []);
+ //Add raw rules to provider
+ for (let raw = 0; raw < rawRules.length; raw++) {
+ providers[p].addRawRule(rawRules[raw]);
+ }
- //Add referral marketing rules to provider
- for(let referralMarketing = 0; referralMarketing < data.providers[prvKeys[p]].referralMarketing.length; referralMarketing++)
- {
- providers[p].addReferralMarketing(data.providers[prvKeys[p]].referralMarketing[referralMarketing]);
- }
+ let referralMarketingRules = data.providers[prvKeys[p]].getOrDefault('referralMarketing', []);
+ //Add referral marketing rules to provider
+ for (let referralMarketing = 0; referralMarketing < referralMarketingRules.length; referralMarketing++) {
+ providers[p].addReferralMarketing(referralMarketingRules[referralMarketing]);
+ }
- //Add exceptions to provider
- for(let e = 0; e < data.providers[prvKeys[p]].exceptions.length; e++)
- {
- providers[p].addException(data.providers[prvKeys[p]].exceptions[e]);
- }
+ let exceptions = data.providers[prvKeys[p]].getOrDefault('exceptions', []);
+ //Add exceptions to provider
+ for (let e = 0; e < exceptions.length; e++) {
+ providers[p].addException(exceptions[e]);
+ }
- //Add redirections to provider
- for(let re = 0; re < data.providers[prvKeys[p]].redirections.length; re++)
- {
- providers[p].addRedirection(data.providers[prvKeys[p]].redirections[re]);
- }
+ let redirections = data.providers[prvKeys[p]].getOrDefault('redirections', []);
+ //Add redirections to provider
+ for (let re = 0; re < redirections.length; re++) {
+ providers[p].addRedirection(redirections[re]);
}
}
+ }
- /**
- * Convert the external data to Objects and
- * call the create provider function.
- *
- * @param {String} retrievedText - pure data form github
- */
- function toObject(retrievedText) {
- getKeys(storage.ClearURLsData.providers);
- createProviders();
- }
+ /**
+ * Convert the external data to Objects and
+ * call the create provider function.
+ *
+ * @param {String} retrievedText - pure data form github
+ */
+ function toObject(retrievedText) {
+ getKeys(storage.ClearURLsData.providers);
+ createProviders();
+ }
- /**
- * Get the hash for the rule file on github.
- * Check the hash with the hash form the local file.
- * If the hash has changed, then download the new rule file.
- * Else do nothing.
- */
- function getHash()
- {
- //Get the target hash from github
- fetch(storage.hashURL)
- .then(function(response){
+ /**
+ * Get the hash for the rule file on github.
+ * Check the hash with the hash form the local file.
+ * If the hash has changed, then download the new rule file.
+ * Else do nothing.
+ */
+ function getHash() {
+ //Get the target hash from github
+ fetch(storage.hashURL)
+ .then(function (response) {
const responseTextHash = response.clone().text().then(function (responseTextHash) {
if (response.ok && $.trim(responseTextHash)) {
dataHash = responseTextHash;
@@ -311,491 +294,470 @@ function start()
}
});
});
- }
+ }
- /*
- * ##################################################################
- * # Fetch Rules & Exception from URL #
- * ##################################################################
- */
- function fetchFromURL()
- {
- fetch(storage.ruleURL)
+ /*
+ * ##################################################################
+ * # Fetch Rules & Exception from URL #
+ * ##################################################################
+ */
+ function fetchFromURL() {
+ fetch(storage.ruleURL)
.then(checkResponse);
- function checkResponse(response)
- {
- const responseText = response.clone().text().then(function (responseText) {
- if (response.ok && $.trim(responseText)) {
- const downloadedFileHash = $.sha256(responseText);
+ function checkResponse(response) {
+ const responseText = response.clone().text().then(function (responseText) {
+ if (response.ok && $.trim(responseText)) {
+ const downloadedFileHash = $.sha256(responseText);
- if ($.trim(downloadedFileHash) === $.trim(dataHash)) {
- storage.ClearURLsData = responseText;
- storage.dataHash = downloadedFileHash;
- storeHashStatus(2);
- } else {
- storeHashStatus(3);
- }
- storage.ClearURLsData = JSON.parse(storage.ClearURLsData);
- toObject(storage.ClearURLsData);
- saveOnDisk(['ClearURLsData', 'dataHash', 'hashStatus']);
- }
- });
- }
- }
-
- // ##################################################################
-
- /*
- * ##################################################################
- * # Supertyp Provider #
- * ##################################################################
- */
- /**
- * Declare constructor
- *
- * @param {String} _name Provider name
- * @param {boolean} _completeProvider Set URL Pattern as rule
- * @param {boolean} _forceRedirection Whether redirects should be enforced via a "tabs.update"
- * @param {boolean} _isActive Is the provider active?
- */
- function Provider(_name, _completeProvider = false, _forceRedirection = false, _isActive = true){
- let name = _name;
- let urlPattern;
- let enabled_rules = {};
- let disabled_rules = {};
- let enabled_exceptions = {};
- let disabled_exceptions = {};
- let canceling = _completeProvider;
- let enabled_redirections = {};
- let disabled_redirections = {};
- let active = _isActive;
- let enabled_rawRules = {};
- let disabled_rawRules = {};
- let enabled_referralMarketing = {};
- let disabled_referralMarketing = {};
-
- if(_completeProvider){
- enabled_rules[".*"] = true;
- }
-
- /**
- * Returns whether redirects should be enforced via a "tabs.update"
- * @return {boolean} whether redirects should be enforced
- */
- this.shouldForceRedirect = function() {
- return _forceRedirection;
- };
-
- /**
- * Returns the provider name.
- * @return {String}
- */
- this.getName = function() {
- return name;
- };
-
- /**
- * Add URL pattern.
- *
- * @require urlPatterns as RegExp
- */
- this.setURLPattern = function(urlPatterns) {
- urlPattern = new RegExp(urlPatterns, "i");
- };
-
- /**
- * Return if the Provider Request is canceled
- * @return {Boolean} isCanceled
- */
- this.isCaneling = function() {
- return canceling;
- };
-
- /**
- * Check the url is matching the ProviderURL.
- *
- * @return {boolean} ProviderURL as RegExp
- */
- this.matchURL = function(url) {
- return urlPattern.test(url) && !(this.matchException(url));
- };
-
- /**
- * Apply a rule to a given tuple of rule array.
- * @param enabledRuleArray array for enabled rules
- * @param disabledRulesArray array for disabled rules
- * @param {String} rule RegExp as string
- * @param {boolean} isActive Is this rule active?
- */
- this.applyRule = (enabledRuleArray, disabledRulesArray, rule, isActive = true) => {
- if(isActive)
- {
- enabledRuleArray[rule] = true;
-
- if(disabledRulesArray[rule] !== undefined)
- {
- delete disabledRulesArray[rule];
+ if ($.trim(downloadedFileHash) === $.trim(dataHash)) {
+ storage.ClearURLsData = responseText;
+ storage.dataHash = downloadedFileHash;
+ storeHashStatus(2);
+ } else {
+ storeHashStatus(3);
}
+ storage.ClearURLsData = JSON.parse(storage.ClearURLsData);
+ toObject(storage.ClearURLsData);
+ saveOnDisk(['ClearURLsData', 'dataHash', 'hashStatus']);
}
- else {
- disabledRulesArray[rule] = true;
-
- if(enabledRuleArray[rule] !== undefined)
- {
- delete enabledRuleArray[rule];
- }
- }
- };
-
- /**
- * Add a rule to the rule array
- * and replace old rule with new rule.
- *
- * @param {String} rule RegExp as string
- * @param {boolean} isActive Is this rule active?
- */
- this.addRule = function(rule, isActive = true) {
- rule = "([\\/|\\?|#]|(&|&))+("+rule+"=[^\\/|\\?|&]*)";
-
- this.applyRule(enabled_rules, disabled_rules, rule, isActive);
- };
-
- /**
- * Return all active rules as an array.
- *
- * @return Array RegExp strings
- */
- this.getRules = function() {
- return Object.keys(enabled_rules);
- };
-
- /**
- * Add a raw rule to the raw rule array
- * and replace old raw rule with new raw rule.
- *
- * @param {String} rule RegExp as string
- * @param {boolean} isActive Is this rule active?
- */
- this.addRawRule = function(rule, isActive = true) {
- this.applyRule(enabled_rawRules, disabled_rawRules, rule, isActive);
- };
-
- /**
- * Return all active raw rules as an array.
- *
- * @return Array RegExp strings
- */
- this.getRawRules = function() {
- if(!storage.referralMarketing) {
- return Object.keys(Object.assign(enabled_rawRules, enabled_referralMarketing));
- }
-
- return Object.keys(enabled_rawRules);
- };
-
- /**
- * Add a referral marketing rule to the referral marketing array
- * and replace old referral marketing rule with new referral marketing rule.
- *
- * @param {String} rule RegExp as string
- * @param {boolean} isActive Is this rule active?
- */
- this.addReferralMarketing = function(rule, isActive = true) {
- this.applyRule(enabled_referralMarketing, disabled_referralMarketing, rule, isActive);
- };
-
- /**
- * Add a exception to the exceptions array
- * and replace old with new exception.
- *
- * @param {String} exception RegExp as string
- * @param {Boolean} isActive Is this exception acitve?
- */
- this.addException = function(exception, isActive = true) {
- if(isActive)
- {
- enabled_exceptions[exception] = true;
-
- if(disabled_exceptions[exception] !== undefined)
- {
- delete disabled_exceptions[exception];
- }
- }
- else {
- disabled_exceptions[exception] = true;
-
- if(enabled_exceptions[exception] !== undefined)
- {
- delete enabled_exceptions[exception];
- }
- }
- };
-
- /**
- * Private helper method to check if the url
- * an exception.
- *
- * @param {String} url RegExp as string
- * @return {boolean} if matching? true: false
- */
- this.matchException = function(url) {
- let result = false;
-
- //Add the site blocked alert to every exception
- if(url === siteBlockedAlert) return true;
-
- for(const exception in enabled_exceptions) {
- if(result) break;
-
- let exception_regex = new RegExp(exception, "i");
- result = exception_regex.test(url);
- }
-
- return result;
- };
-
- /**
- * Add a redirection to the redirections array
- * and replace old with new redirection.
- *
- * @param {String} redirection RegExp as string
- * @param {Boolean} isActive Is this redirection active?
- */
- this.addRedirection = function(redirection, isActive = true) {
- if(isActive)
- {
- enabled_redirections[redirection] = true;
-
- if(disabled_redirections[redirection] !== undefined)
- {
- delete disabled_redirections[redirection];
- }
- }
- else {
- disabled_redirections[redirection] = true;
-
- if(enabled_redirections[redirection] !== undefined)
- {
- delete enabled_redirections[redirection];
- }
- }
- };
-
- /**
- * Return all redirection.
- *
- * @return url
- */
- this.getRedirection = function(url) {
- let re = null;
-
- for(const redirection in enabled_redirections) {
- let result = (url.match(new RegExp(redirection, "i")));
-
- if (result && result.length > 0 && redirection)
- {
- re = (new RegExp(redirection, "i")).exec(url)[1];
-
- break;
- }
- }
-
- return re;
- };
- }
- // ##################################################################
-
- /**
- * Function which called from the webRequest to
- * remove the tracking fields from the url.
- *
- * @param {webRequest} request webRequest-Object
- * @return {Array} redirectUrl or none
- */
- function clearUrl(request)
- {
- const URLbeforeReplaceCount = countFields(request.url);
-
- //Add Fields form Request to global url counter
- increaseGlobalURLCounter(URLbeforeReplaceCount);
-
- if(storage.globalStatus){
- let result = {
- "changes": false,
- "url": "",
- "redirect": false,
- "cancel": false
- };
-
- /*
- * Call for every provider the removeFieldsFormURL method.
- */
- for (let i = 0; i < providers.length; i++) {
-
- if(providers[i].matchURL(request.url))
- {
- result = removeFieldsFormURL(providers[i], request.url);
- }
-
- /*
- * Expand urls and bypass tracking.
- * Cancel the active request.
- */
- if(result.redirect)
- {
- if(providers[i].shouldForceRedirect() &&
- request.type === 'main_frame') {
- browser.tabs.update(request.tabId, {url: result.url});
- return {cancel: true};
- }
-
- return {
- redirectUrl: result.url
- };
- }
-
- /*
- * Cancel the Request and redirect to the site blocked alert page,
- * to inform the user about the full url blocking.
- */
- if(result.cancel){
- if(request.type === 'main_frame') {
- const blockingPage = browser.extension.getURL("html/siteBlockedAlert.html?source="+encodeURIComponent(request.url));
- browser.tabs.update(request.tabId, {url: blockingPage});
-
- return {cancel: true};
- } else {
- return {
- redirectUrl: siteBlockedAlert
- };
- }
- }
-
- /*
- * Ensure that the function go not into
- * a loop.
- */
- if(result.changes){
- return {
- redirectUrl: result.url
- };
- }
- }
- }
-
- // Default case
- return {};
- }
-
- /**
- * Call loadOldDataFromStore, getHash, counter, status and log functions
- */
-
- loadOldDataFromStore();
- getHash();
- setBadgedStatus();
-
- /**
- * Call by each tab is updated.
- * And if url has changed.
- */
- function handleUpdated(tabId, changeInfo, tabInfo) {
- if(changeInfo.url)
- {
- delete badges[tabId];
- }
- currentURL = tabInfo.url;
- }
-
- /**
- * Call by each tab is updated.
- */
- browser.tabs.onUpdated.addListener(handleUpdated);
-
- /**
- * Call by each tab change to set the actual tab id
- */
- function handleActivated(activeInfo) {
- tabid = activeInfo.tabId;
- browser.tabs.get(tabid).then(function (tab) {
- currentURL = tab.url;
});
}
+ }
- /**
- * Call by each tab change.
- */
- browser.tabs.onActivated.addListener(handleActivated);
+ // ##################################################################
- /**
- * Check the request.
- */
- function promise(requestDetails)
- {
- if(isDataURL(requestDetails))
- {
- return {};
- }
- else {
- return clearUrl(requestDetails);
- }
+ /*
+ * ##################################################################
+ * # Supertyp Provider #
+ * ##################################################################
+ */
+ /**
+ * Declare constructor
+ *
+ * @param {String} _name Provider name
+ * @param {boolean} _completeProvider Set URL Pattern as rule
+ * @param {boolean} _forceRedirection Whether redirects should be enforced via a "tabs.update"
+ * @param {boolean} _isActive Is the provider active?
+ */
+ function Provider(_name, _completeProvider = false, _forceRedirection = false, _isActive = true) {
+ let name = _name;
+ let urlPattern;
+ let enabled_rules = {};
+ let disabled_rules = {};
+ let enabled_exceptions = {};
+ let disabled_exceptions = {};
+ let canceling = _completeProvider;
+ let enabled_redirections = {};
+ let disabled_redirections = {};
+ let active = _isActive;
+ let enabled_rawRules = {};
+ let disabled_rawRules = {};
+ let enabled_referralMarketing = {};
+ let disabled_referralMarketing = {};
+
+ if (_completeProvider) {
+ enabled_rules[".*"] = true;
}
/**
- * To prevent long loading on data urls
- * we will check here for data urls.
- *
- * @type {requestDetails}
- * @return {boolean}
- */
- function isDataURL(requestDetails) {
- const s = requestDetails.url;
-
- return s.substring(0,4) === "data";
- }
+ * Returns whether redirects should be enforced via a "tabs.update"
+ * @return {boolean} whether redirects should be enforced
+ */
+ this.shouldForceRedirect = function () {
+ return _forceRedirection;
+ };
/**
- * Call by each Request and checking the url.
- *
- * @type {Array}
- */
- browser.webRequest.onBeforeRequest.addListener(
- promise,
- {urls: [""], types: getData("types")},
- ["blocking"]
- );
+ * Returns the provider name.
+ * @return {String}
+ */
+ this.getName = function () {
+ return name;
+ };
+
+ /**
+ * Add URL pattern.
+ *
+ * @require urlPatterns as RegExp
+ */
+ this.setURLPattern = function (urlPatterns) {
+ urlPattern = new RegExp(urlPatterns, "i");
+ };
+
+ /**
+ * Return if the Provider Request is canceled
+ * @return {Boolean} isCanceled
+ */
+ this.isCaneling = function () {
+ return canceling;
+ };
+
+ /**
+ * Check the url is matching the ProviderURL.
+ *
+ * @return {boolean} ProviderURL as RegExp
+ */
+ this.matchURL = function (url) {
+ return urlPattern.test(url) && !(this.matchException(url));
+ };
+
+ /**
+ * Apply a rule to a given tuple of rule array.
+ * @param enabledRuleArray array for enabled rules
+ * @param disabledRulesArray array for disabled rules
+ * @param {String} rule RegExp as string
+ * @param {boolean} isActive Is this rule active?
+ */
+ this.applyRule = (enabledRuleArray, disabledRulesArray, rule, isActive = true) => {
+ if (isActive) {
+ enabledRuleArray[rule] = true;
+
+ if (disabledRulesArray[rule] !== undefined) {
+ delete disabledRulesArray[rule];
+ }
+ } else {
+ disabledRulesArray[rule] = true;
+
+ if (enabledRuleArray[rule] !== undefined) {
+ delete enabledRuleArray[rule];
+ }
+ }
+ };
+
+ /**
+ * Add a rule to the rule array
+ * and replace old rule with new rule.
+ *
+ * @param {String} rule RegExp as string
+ * @param {boolean} isActive Is this rule active?
+ */
+ this.addRule = function (rule, isActive = true) {
+ rule = "([\\/|\\?|#]|(&|&))+(" + rule + "=[^\\/|\\?|&]*)";
+
+ this.applyRule(enabled_rules, disabled_rules, rule, isActive);
+ };
+
+ /**
+ * Return all active rules as an array.
+ *
+ * @return Array RegExp strings
+ */
+ this.getRules = function () {
+ if (!storage.referralMarketing) {
+ return Object.keys(Object.assign(enabled_rules, enabled_referralMarketing));
+ }
+
+ return Object.keys(enabled_rules);
+ };
+
+ /**
+ * Add a raw rule to the raw rule array
+ * and replace old raw rule with new raw rule.
+ *
+ * @param {String} rule RegExp as string
+ * @param {boolean} isActive Is this rule active?
+ */
+ this.addRawRule = function (rule, isActive = true) {
+ this.applyRule(enabled_rawRules, disabled_rawRules, rule, isActive);
+ };
+
+ /**
+ * Return all active raw rules as an array.
+ *
+ * @return Array RegExp strings
+ */
+ this.getRawRules = function () {
+ return Object.keys(enabled_rawRules);
+ };
+
+ /**
+ * Add a referral marketing rule to the referral marketing array
+ * and replace old referral marketing rule with new referral marketing rule.
+ *
+ * @param {String} rule RegExp as string
+ * @param {boolean} isActive Is this rule active?
+ */
+ this.addReferralMarketing = function (rule, isActive = true) {
+ rule = "([\\/|\\?|#]|(&|&))+(" + rule + "=[^\\/|\\?|&]*)";
+
+ this.applyRule(enabled_referralMarketing, disabled_referralMarketing, rule, isActive);
+ };
+
+ /**
+ * Add a exception to the exceptions array
+ * and replace old with new exception.
+ *
+ * @param {String} exception RegExp as string
+ * @param {Boolean} isActive Is this exception acitve?
+ */
+ this.addException = function (exception, isActive = true) {
+ if (isActive) {
+ enabled_exceptions[exception] = true;
+
+ if (disabled_exceptions[exception] !== undefined) {
+ delete disabled_exceptions[exception];
+ }
+ } else {
+ disabled_exceptions[exception] = true;
+
+ if (enabled_exceptions[exception] !== undefined) {
+ delete enabled_exceptions[exception];
+ }
+ }
+ };
+
+ /**
+ * Private helper method to check if the url
+ * an exception.
+ *
+ * @param {String} url RegExp as string
+ * @return {boolean} if matching? true: false
+ */
+ this.matchException = function (url) {
+ let result = false;
+
+ //Add the site blocked alert to every exception
+ if (url === siteBlockedAlert) return true;
+
+ for (const exception in enabled_exceptions) {
+ if (result) break;
+
+ let exception_regex = new RegExp(exception, "i");
+ result = exception_regex.test(url);
+ }
+
+ return result;
+ };
+
+ /**
+ * Add a redirection to the redirections array
+ * and replace old with new redirection.
+ *
+ * @param {String} redirection RegExp as string
+ * @param {Boolean} isActive Is this redirection active?
+ */
+ this.addRedirection = function (redirection, isActive = true) {
+ if (isActive) {
+ enabled_redirections[redirection] = true;
+
+ if (disabled_redirections[redirection] !== undefined) {
+ delete disabled_redirections[redirection];
+ }
+ } else {
+ disabled_redirections[redirection] = true;
+
+ if (enabled_redirections[redirection] !== undefined) {
+ delete enabled_redirections[redirection];
+ }
+ }
+ };
+
+ /**
+ * Return all redirection.
+ *
+ * @return url
+ */
+ this.getRedirection = function (url) {
+ let re = null;
+
+ for (const redirection in enabled_redirections) {
+ let result = (url.match(new RegExp(redirection, "i")));
+
+ if (result && result.length > 0 && redirection) {
+ re = (new RegExp(redirection, "i")).exec(url)[1];
+
+ break;
+ }
+ }
+
+ return re;
+ };
+ }
+
+ // ##################################################################
+
+ /**
+ * Function which called from the webRequest to
+ * remove the tracking fields from the url.
+ *
+ * @param {webRequest} request webRequest-Object
+ * @return {Array} redirectUrl or none
+ */
+ function clearUrl(request) {
+ const URLbeforeReplaceCount = countFields(request.url);
+
+ //Add Fields form Request to global url counter
+ increaseGlobalURLCounter(URLbeforeReplaceCount);
+
+ if (storage.globalStatus) {
+ let result = {
+ "changes": false,
+ "url": "",
+ "redirect": false,
+ "cancel": false
+ };
+
+ /*
+ * Call for every provider the removeFieldsFormURL method.
+ */
+ for (let i = 0; i < providers.length; i++) {
+
+ if (providers[i].matchURL(request.url)) {
+ result = removeFieldsFormURL(providers[i], request.url);
+ }
+
+ /*
+ * Expand urls and bypass tracking.
+ * Cancel the active request.
+ */
+ if (result.redirect) {
+ if (providers[i].shouldForceRedirect() &&
+ request.type === 'main_frame') {
+ browser.tabs.update(request.tabId, {url: result.url});
+ return {cancel: true};
+ }
+
+ return {
+ redirectUrl: result.url
+ };
+ }
+
+ /*
+ * Cancel the Request and redirect to the site blocked alert page,
+ * to inform the user about the full url blocking.
+ */
+ if (result.cancel) {
+ if (request.type === 'main_frame') {
+ const blockingPage = browser.extension.getURL("html/siteBlockedAlert.html?source=" + encodeURIComponent(request.url));
+ browser.tabs.update(request.tabId, {url: blockingPage});
+
+ return {cancel: true};
+ } else {
+ return {
+ redirectUrl: siteBlockedAlert
+ };
+ }
+ }
+
+ /*
+ * Ensure that the function go not into
+ * a loop.
+ */
+ if (result.changes) {
+ return {
+ redirectUrl: result.url
+ };
+ }
+ }
+ }
+
+ // Default case
+ return {};
}
/**
- * Function to log all activities from ClearUrls.
- * Only logging when activated.
- * The log is only temporary saved in the cache and will
- * permanently saved with the saveLogOnClose function.
- *
- * @param beforeProcessing the url before the clear process
- * @param afterProcessing the url after the clear process
- * @param rule the rule that triggered the process
- */
- function pushToLog(beforeProcessing, afterProcessing, rule)
- {
- const limit = storage.logLimit;
- if(storage.loggingStatus && limit !== 0)
- {
- if(limit > 0 && !isNaN(limit)) {
- while(storage.log.log.length >= limit) {
- storage.log.log.shift();
- }
- }
+ * Call loadOldDataFromStore, getHash, counter, status and log functions
+ */
- storage.log.log.push(
- {
- "before": beforeProcessing,
- "after": afterProcessing,
- "rule": rule,
- "timestamp": Date.now()
- }
- );
- deferSaveOnDisk('log');
+ loadOldDataFromStore();
+ getHash();
+ setBadgedStatus();
+
+ /**
+ * Call by each tab is updated.
+ * And if url has changed.
+ */
+ function handleUpdated(tabId, changeInfo, tabInfo) {
+ if (changeInfo.url) {
+ delete badges[tabId];
+ }
+ currentURL = tabInfo.url;
+ }
+
+ /**
+ * Call by each tab is updated.
+ */
+ browser.tabs.onUpdated.addListener(handleUpdated);
+
+ /**
+ * Call by each tab change to set the actual tab id
+ */
+ function handleActivated(activeInfo) {
+ tabid = activeInfo.tabId;
+ browser.tabs.get(tabid).then(function (tab) {
+ currentURL = tab.url;
+ });
+ }
+
+ /**
+ * Call by each tab change.
+ */
+ browser.tabs.onActivated.addListener(handleActivated);
+
+ /**
+ * Check the request.
+ */
+ function promise(requestDetails) {
+ if (isDataURL(requestDetails)) {
+ return {};
+ } else {
+ return clearUrl(requestDetails);
}
}
+
+ /**
+ * To prevent long loading on data urls
+ * we will check here for data urls.
+ *
+ * @type {requestDetails}
+ * @return {boolean}
+ */
+ function isDataURL(requestDetails) {
+ const s = requestDetails.url;
+
+ return s.substring(0, 4) === "data";
+ }
+
+ /**
+ * Call by each Request and checking the url.
+ *
+ * @type {Array}
+ */
+ browser.webRequest.onBeforeRequest.addListener(
+ promise,
+ {urls: [""], types: getData("types")},
+ ["blocking"]
+ );
+}
+
+/**
+ * Function to log all activities from ClearUrls.
+ * Only logging when activated.
+ * The log is only temporary saved in the cache and will
+ * permanently saved with the saveLogOnClose function.
+ *
+ * @param beforeProcessing the url before the clear process
+ * @param afterProcessing the url after the clear process
+ * @param rule the rule that triggered the process
+ */
+function pushToLog(beforeProcessing, afterProcessing, rule) {
+ const limit = storage.logLimit;
+ if (storage.loggingStatus && limit !== 0) {
+ if (limit > 0 && !isNaN(limit)) {
+ while (storage.log.log.length >= limit) {
+ storage.log.log.shift();
+ }
+ }
+
+ storage.log.log.push(
+ {
+ "before": beforeProcessing,
+ "after": afterProcessing,
+ "rule": rule,
+ "timestamp": Date.now()
+ }
+ );
+ deferSaveOnDisk('log');
+ }
+}
diff --git a/core_js/storage.js b/core_js/storage.js
index 68c3f59..59c3995 100644
--- a/core_js/storage.js
+++ b/core_js/storage.js
@@ -25,10 +25,9 @@ var hasPendingSaves = false;
var pendingSaves = new Set();
/**
-* Writes the storage variable to the disk.
-*/
-function saveOnExit()
-{
+ * Writes the storage variable to the disk.
+ */
+function saveOnExit() {
saveOnDisk(Object.keys(storage));
}
@@ -65,14 +64,13 @@ function storageDataAsString(key) {
}
/**
-* Save multiple keys on the disk.
-* @param {String[]} keys
-*/
-function saveOnDisk(keys)
-{
+ * Save multiple keys on the disk.
+ * @param {String[]} keys
+ */
+function saveOnDisk(keys) {
let json = {};
- keys.forEach(function(key) {
+ keys.forEach(function (key) {
json[key] = storageDataAsString(key);
});
@@ -81,17 +79,16 @@ function saveOnDisk(keys)
}
/**
-* Schedule to save a key to disk in 30 seconds.
-* @param {String} key
-*/
-function deferSaveOnDisk(key)
-{
+ * Schedule to save a key to disk in 30 seconds.
+ * @param {String} key
+ */
+function deferSaveOnDisk(key) {
if (hasPendingSaves) {
pendingSaves.add(key);
return;
}
- setTimeout(function() {
+ setTimeout(function () {
saveOnDisk(Array.from(pendingSaves));
pendingSaves.clear();
hasPendingSaves = false;
@@ -100,10 +97,9 @@ function deferSaveOnDisk(key)
}
/**
-* Start sequence for ClearURLs.
-*/
-function genesis()
-{
+ * Start sequence for ClearURLs.
+ */
+function genesis() {
browser.storage.local.get(null).then((items) => {
initStorage(items);
@@ -119,35 +115,32 @@ function genesis()
}
/**
-* Return the value under the key.
-* @param {String} key
-* @return {Object}
-*/
-function getData(key)
-{
+ * Return the value under the key.
+ * @param {String} key
+ * @return {Object}
+ */
+function getData(key) {
return storage[key];
}
/**
-* Return the entire storage object.
-* @return {Object}
-*/
-function getEntireData()
-{
+ * Return the entire storage object.
+ * @return {Object}
+ */
+function getEntireData() {
return storage;
}
/**
-* Save the value under the key on the RAM.
-*
-* Note: To store the data on the hard disk, one of
-* deferSaveOnDisk(), saveOnDisk(), or saveOnExit()
-* must be called.
-* @param {String} key
-* @param {Object} value
-*/
-function setData(key, value)
-{
+ * Save the value under the key on the RAM.
+ *
+ * Note: To store the data on the hard disk, one of
+ * deferSaveOnDisk(), saveOnDisk(), or saveOnExit()
+ * must be called.
+ * @param {String} key
+ * @param {Object} value
+ */
+function setData(key, value) {
switch (key) {
case "ClearURLsData":
case "log":
@@ -169,23 +162,21 @@ function setData(key, value)
}
/**
-* Write error on console.
-*/
-function error(e)
-{
+ * Write error on console.
+ */
+function error(e) {
console.log(translate('core_error'));
console.error(e);
}
/**
-* Set default values, if the storage is empty.
-* @param {Object} items
-*/
-function initStorage(items)
-{
+ * Set default values, if the storage is empty.
+ * @param {Object} items
+ */
+function initStorage(items) {
initSettings();
- if(!isEmpty(items)) {
+ if (!isEmpty(items)) {
Object.entries(items).forEach(([key, value]) => {
setData(key, value);
});
@@ -193,10 +184,9 @@ function initStorage(items)
}
/**
-* Set default values for the settings.
-*/
-function initSettings()
-{
+ * Set default values for the settings.
+ */
+function initSettings() {
storage.ClearURLsData = [];
storage.dataHash = "";
storage.badgedStatus = true;
@@ -208,15 +198,15 @@ function initSettings()
storage.log = {"log": []};
storage.statisticsStatus = true;
storage.badged_color = "ffa500";
- storage.hashURL = "https://gitlab.com/KevinRoebert/ClearUrls/-/jobs/artifacts/master/raw/rules.min.hash?job=hash%20rules";
- storage.ruleURL = "https://gitlab.com/KevinRoebert/ClearUrls/raw/master/data/data.min.json";
+ storage.hashURL = "https://gitlab.com/KevinRoebert/ClearUrls/-/jobs/artifacts/master/raw/rules.minify.hash?job=hash%20rules";
+ storage.ruleURL = "https://gitlab.com/KevinRoebert/ClearUrls/raw/master/data/data.minify.json";
storage.contextMenuEnabled = true;
storage.historyListenerEnabled = true;
storage.localHostsSkipping = true;
storage.referralMarketing = false;
storage.logLimit = -1;
- if(getBrowser() === "Firefox") {
+ if (getBrowser() === "Firefox") {
storage.types = ["font", "image", "imageset", "main_frame", "media", "object", "object_subrequest", "other", "script", "stylesheet", "sub_frame", "websocket", "xbl", "xml_dtd", "xmlhttprequest", "xslt"];
} else if (getBrowser() === "Chrome") {
storage.types = ["main_frame", "sub_frame", "stylesheet", "script", "image", "font", "object", "xmlhttprequest", "ping", "csp_report", "media", "websocket", "other"];
@@ -224,53 +214,57 @@ function initSettings()
}
/**
-* Replace the old URLs with the
-* new GitLab URLs.
-*/
-function replaceOldURLs(url)
-{
+ * Replace the old URLs with the
+ * new GitLab URLs.
+ */
+function replaceOldURLs(url) {
switch (url) {
case "https://raw.githubusercontent.com/KevinRoebert/ClearUrls/master/data/rules.hash?flush_cache=true":
- return "https://gitlab.com/KevinRoebert/ClearUrls/-/jobs/artifacts/master/raw/rules.min.hash?job=hash%20rules";
+ return "https://gitlab.com/KevinRoebert/ClearUrls/-/jobs/artifacts/master/raw/rules.min.hash?job=hash%20rules";
case "https://raw.githubusercontent.com/KevinRoebert/ClearUrls/master/data/data.json?flush_cache=true":
- return "https://gitlab.com/KevinRoebert/ClearUrls/raw/master/data/data.min.json";
+ return "https://gitlab.com/KevinRoebert/ClearUrls/raw/master/data/data.min.json";
case "https://gitlab.com/KevinRoebert/ClearUrls/raw/master/data/rules.hash":
- return "https://gitlab.com/KevinRoebert/ClearUrls/-/jobs/artifacts/master/raw/rules.min.hash?job=hash%20rules";
+ return "https://gitlab.com/KevinRoebert/ClearUrls/-/jobs/artifacts/master/raw/rules.min.hash?job=hash%20rules";
case "https://gitlab.com/KevinRoebert/ClearUrls/raw/master/data/data.json":
- return "https://gitlab.com/KevinRoebert/ClearUrls/raw/master/data/data.min.json";
+ return "https://gitlab.com/KevinRoebert/ClearUrls/raw/master/data/data.min.json";
+ case "https://gitlab.com/KevinRoebert/ClearUrls/-/jobs/artifacts/master/raw/rules.min.hash?job=hash%20rules":
+ return "https://gitlab.com/KevinRoebert/ClearUrls/-/jobs/artifacts/master/raw/rules.minify.hash?job=hash%20rules";
+ case "https://gitlab.com/KevinRoebert/ClearUrls/raw/master/data/data.min.json":
+ return "https://gitlab.com/KevinRoebert/ClearUrls/-/jobs/artifacts/master/raw/data.minify.json?job=hash%20rules";
default:
- return url;
+ return url;
}
}
/**
-* Load local saved data, if the browser is offline or
-* some other network trouble.
-*/
-function loadOldDataFromStore()
-{
+ * Load local saved data, if the browser is offline or
+ * some other network trouble.
+ */
+function loadOldDataFromStore() {
localDataHash = storage.dataHash;
}
/**
-* Save the hash status to the local storage (RAM).
-* The status can have the following values:
-* 1 "up to date"
-* 2 "updated"
-* 3 "update available"
-* @param status_code the number for the status
-*/
-function storeHashStatus(status_code)
-{
- switch(status_code)
- {
- case 1: status_code = "hash_status_code_1";
- break;
- case 2: status_code = "hash_status_code_2";
- break;
- case 3: status_code = "hash_status_code_3";
- break;
- default: status_code = "hash_status_code_4";
+ * Save the hash status to the local storage (RAM).
+ * The status can have the following values:
+ * 1 "up to date"
+ * 2 "updated"
+ * 3 "update available"
+ * @param status_code the number for the status
+ */
+function storeHashStatus(status_code) {
+ switch (status_code) {
+ case 1:
+ status_code = "hash_status_code_1";
+ break;
+ case 2:
+ status_code = "hash_status_code_2";
+ break;
+ case 3:
+ status_code = "hash_status_code_3";
+ break;
+ default:
+ status_code = "hash_status_code_4";
}
storage.hashStatus = status_code;
diff --git a/core_js/tools.js b/core_js/tools.js
index 3be2d6e..566e486 100644
--- a/core_js/tools.js
+++ b/core_js/tools.js
@@ -24,53 +24,49 @@
/*
* To support Waterfox.
*/
-Array.prototype.rmEmpty = function() {
+Array.prototype.rmEmpty = function () {
return this.filter(v => v);
};
/*
* To support Waterfox.
*/
-Array.prototype.flatten = function() {
+Array.prototype.flatten = function () {
return this.reduce((a, b) => a.concat(b), []);
};
/**
-* Check if an object is empty.
-* @param {Object} obj
-* @return {Boolean}
-*/
-function isEmpty(obj)
-{
+ * Check if an object is empty.
+ * @param {Object} obj
+ * @return {Boolean}
+ */
+function isEmpty(obj) {
return (Object.getOwnPropertyNames(obj).length === 0);
}
/**
-* Translate a string with the i18n API.
-*
-* @param {string} string Name of the attribute used for localization
-*/
-function translate(string)
-{
+ * Translate a string with the i18n API.
+ *
+ * @param {string} string Name of the attribute used for localization
+ */
+function translate(string) {
return browser.i18n.getMessage(string);
}
/**
-* Reloads the extension.
-*/
-function reload()
-{
+ * Reloads the extension.
+ */
+function reload() {
browser.runtime.reload();
}
/**
-* Check if it is an android device.
-* @return bool
-*/
-async function checkOSAndroid()
-{
- if(os === undefined || os === null || os === "") {
- await chrome.runtime.getPlatformInfo(function(info) {
+ * Check if it is an android device.
+ * @return bool
+ */
+async function checkOSAndroid() {
+ if (os === undefined || os === null || os === "") {
+ await chrome.runtime.getPlatformInfo(function (info) {
os = info.os;
});
}
@@ -79,10 +75,10 @@ async function checkOSAndroid()
}
/**
-* Extract the host without port from an url.
-* @param {String} url URL as String
-* @return {String} host as string
-*/
+ * Extract the host without port from an url.
+ * @param {String} url URL as String
+ * @return {String} host as string
+ */
function extractHost(url) {
let parsed_url = new URL(url);
@@ -90,36 +86,34 @@ function extractHost(url) {
}
/**
-* Returns true if the url has a local host.
-* @param {String} url URL as String
-* @return {boolean}
-*/
+ * Returns true if the url has a local host.
+ * @param {String} url URL as String
+ * @return {boolean}
+ */
function checkLocalURL(url) {
let host = extractHost(url);
return ipRangeCheck(host, ["10.0.0.0/8", "172.16.0.0/12",
- "192.168.0.0/16", "100.64.0.0/10",
- "169.254.0.0/16", "127.0.0.1"])||
- host === 'localhost';
+ "192.168.0.0/16", "100.64.0.0/10",
+ "169.254.0.0/16", "127.0.0.1"]) ||
+ host === 'localhost';
}
/**
-* Return the number of parameters query strings.
-* @param {String} url URL as String
-* @return {int} Number of Parameters
-*/
-function countFields(url)
-{
+ * Return the number of parameters query strings.
+ * @param {String} url URL as String
+ * @return {int} Number of Parameters
+ */
+function countFields(url) {
return extractFileds(url).length;
}
/**
-* Returns true if fields exists.
-* @param {String} url URL as String
-* @return {boolean}
-*/
-function existsFields(url)
-{
+ * Returns true if fields exists.
+ * @param {String} url URL as String
+ * @return {boolean}
+ */
+function existsFields(url) {
let matches = (url.match(/\?.+/i) || []);
let count = matches.length;
@@ -127,15 +121,14 @@ function existsFields(url)
}
/**
-* Extract the fields from an url.
-* @param {String} url URL as String
-* @return {Array} Fields as array
-*/
-function extractFileds(url)
-{
- if(existsFields(url)) {
+ * Extract the fields from an url.
+ * @param {String} url URL as String
+ * @return {Array} Fields as array
+ */
+function extractFileds(url) {
+ if (existsFields(url)) {
let fields = url.replace(new RegExp(".*?\\?", "i"), "");
- if(existsFragments(url)) {
+ if (existsFragments(url)) {
fields = fields.replace(new RegExp("#.*", "i"), "");
}
@@ -146,23 +139,21 @@ function extractFileds(url)
}
/**
-* Return the number of fragments query strings.
-* @param {String} url URL as String
-* @return {int} Number of fragments
-*/
-function countFragments(url)
-{
+ * Return the number of fragments query strings.
+ * @param {String} url URL as String
+ * @return {int} Number of fragments
+ */
+function countFragments(url) {
return extractFragments(url).length;
}
/**
-* Extract the fragments from an url.
-* @param {String} url URL as String
-* @return {Array} fragments as array
-*/
-function extractFragments(url)
-{
- if(existsFragments(url)) {
+ * Extract the fragments from an url.
+ * @param {String} url URL as String
+ * @return {Array} fragments as array
+ */
+function extractFragments(url) {
+ if (existsFragments(url)) {
let fragments = url.replace(new RegExp(".*?#", "i"), "");
return (fragments.match(/[^&]+=?[^&]*/gi) || []);
}
@@ -171,12 +162,11 @@ function extractFragments(url)
}
/**
-* Returns true if fragments exists.
-* @param {String} url URL as String
-* @return {boolean}
-*/
-function existsFragments(url)
-{
+ * Returns true if fragments exists.
+ * @param {String} url URL as String
+ * @return {boolean}
+ */
+function existsFragments(url) {
let matches = (url.match(/\#.+/i) || []);
let count = matches.length;
@@ -184,73 +174,69 @@ function existsFragments(url)
}
/**
-* Load local saved data, if the browser is offline or
-* some other network trouble.
-*/
-function loadOldDataFromStore()
-{
+ * Load local saved data, if the browser is offline or
+ * some other network trouble.
+ */
+function loadOldDataFromStore() {
localDataHash = storage.dataHash;
}
/**
-* Save the hash status to the local storage (RAM).
-* The status can have the following values:
-* 1 "up to date"
-* 2 "updated"
-* 3 "update available"
-* @param status_code the number for the status
-*/
-function storeHashStatus(status_code)
-{
- switch(status_code)
- {
- case 1: status_code = "hash_status_code_1";
- break;
- case 2: status_code = "hash_status_code_2";
- break;
- case 3: status_code = "hash_status_code_3";
- break;
- default: status_code = "hash_status_code_4";
+ * Save the hash status to the local storage (RAM).
+ * The status can have the following values:
+ * 1 "up to date"
+ * 2 "updated"
+ * 3 "update available"
+ * @param status_code the number for the status
+ */
+function storeHashStatus(status_code) {
+ switch (status_code) {
+ case 1:
+ status_code = "hash_status_code_1";
+ break;
+ case 2:
+ status_code = "hash_status_code_2";
+ break;
+ case 3:
+ status_code = "hash_status_code_3";
+ break;
+ default:
+ status_code = "hash_status_code_4";
}
storage.hashStatus = status_code;
}
/**
-* Increase by {number} the GlobalURLCounter
-* @param {int} number
-*/
-function increaseGlobalURLCounter(number)
-{
- if(storage.statisticsStatus)
- {
+ * Increase by {number} the GlobalURLCounter
+ * @param {int} number
+ */
+function increaseGlobalURLCounter(number) {
+ if (storage.statisticsStatus) {
storage.globalurlcounter += number;
deferSaveOnDisk('globalurlcounter');
}
}
/**
-* Increase by one the URLCounter
-*/
-function increaseURLCounter()
-{
- if(storage.statisticsStatus)
- {
+ * Increase by one the URLCounter
+ */
+function increaseURLCounter() {
+ if (storage.statisticsStatus) {
storage.globalCounter++;
deferSaveOnDisk('globalCounter');
}
}
/**
-* Change the icon.
-*/
-function changeIcon()
-{
+ * Change the icon.
+ */
+function changeIcon() {
checkOSAndroid().then((res) => {
- if(!res) {
- if(storage.globalStatus){
+ if (!res) {
+ if (storage.globalStatus) {
browser.browserAction.setIcon({path: "img/clearurls_128x128.png"});
- } else{
+ } else {
browser.browserAction.setIcon({path: "img/clearurls_gray_128x128.png"});
}
}
@@ -258,35 +244,33 @@ function changeIcon()
}
/**
-* Get the badged status from the browser storage and put the value
-* into a local variable.
-*
-*/
-function setBadgedStatus()
-{
+ * Get the badged status from the browser storage and put the value
+ * into a local variable.
+ *
+ */
+function setBadgedStatus() {
checkOSAndroid().then((res) => {
- if(!res && storage.badgedStatus) {
+ if (!res && storage.badgedStatus) {
browser.browserAction.setBadgeBackgroundColor({
- 'color': '#'+storage.badged_color
+ 'color': '#' + storage.badged_color
});
}
});
}
/**
-* Returns the current URL.
-* @return {String} [description]
-*/
-function getCurrentURL()
-{
+ * Returns the current URL.
+ * @return {String} [description]
+ */
+function getCurrentURL() {
return currentURL;
}
/**
-* Check for browser.
-*/
+ * Check for browser.
+ */
function getBrowser() {
- if(typeof InstallTrigger !== 'undefined') {
+ if (typeof InstallTrigger !== 'undefined') {
return "Firefox";
} else {
return "Chrome";
@@ -299,9 +283,19 @@ function getBrowser() {
*/
function decodeURL(url) {
const rtn = decodeURIComponent(url);
- if(rtn.indexOf("http://") === -1 && rtn.indexOf("https://") === -1) {
+ if (rtn.indexOf("http://") === -1 && rtn.indexOf("https://") === -1) {
return decodeURL(rtn);
}
return rtn;
-}
\ No newline at end of file
+}
+
+/*
+* Gets the value of at `key` an object. If the resolved value is `undefined`, the `defaultValue` is returned in its place.
+*
+* @param {string} key the key of the object
+* @param {object} defaultValue the default value
+*/
+Object.prototype.getOrDefault = function (key, defaultValue) {
+ return this[key] === undefined ? defaultValue : this[key];
+};
\ No newline at end of file
diff --git a/data/data.min.json b/data/data.min.json
index 4040394..197f24e 100644
--- a/data/data.min.json
+++ b/data/data.min.json
@@ -36,7 +36,7 @@
"rnid"
],
"referralMarketing": [
- "([\\/|\\?|#]|(&|&))+(tag=[^\\/|\\?|&]*)"
+ "tag"
],
"exceptions": [
".*(amazon\\.).*(\\/gp).*\\/redirector.html\\/.*",
diff --git a/manifest.json b/manifest.json
index a327cb9..7073921 100644
--- a/manifest.json
+++ b/manifest.json
@@ -1,7 +1,7 @@
{
"manifest_version": 2,
"name": "ClearURLs",
- "version": "1.9.1",
+ "version": "1.9.2",
"author": "Kevin Röbert",
"description": "Remove tracking elements from URLs.",
"homepage_url": "https://gitlab.com/KevinRoebert/ClearUrls",