mirror of
https://gitlab.com/KevinRoebert/ClearUrls
synced 2025-12-16 14:15:36 +07:00
Version 1.24.0
This commit is contained in:
13
CHANGELOG.md
13
CHANGELOG.md
@@ -15,6 +15,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Require Firefox >= 55
|
- Require Firefox >= 55
|
||||||
- Require Chrome >= 37
|
- Require Chrome >= 37
|
||||||
|
|
||||||
|
## [1.24.0] - 2022-03-25
|
||||||
|
|
||||||
|
### Compatibility note
|
||||||
|
- Require Firefox >= 55
|
||||||
|
- Require Chrome >= 37
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Replaced self-written URL parser through `URL` and `URLSearchParams` from the Web API
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Fixed [185](https://github.com/ClearURLs/Addon/issues/185)
|
||||||
|
- Fixed [186](https://github.com/ClearURLs/Addon/issues/186)
|
||||||
|
|
||||||
## [1.23.1] - 2022-03-23
|
## [1.23.1] - 2022-03-23
|
||||||
|
|
||||||
### Compatibility note
|
### Compatibility note
|
||||||
|
|||||||
70
clearurls.js
70
clearurls.js
@@ -46,8 +46,9 @@ function removeFieldsFormURL(provider, pureUrl, quiet = false, request = null) {
|
|||||||
let changes = false;
|
let changes = false;
|
||||||
let cancel = false;
|
let cancel = false;
|
||||||
let rawRules = provider.getRawRules();
|
let rawRules = provider.getRawRules();
|
||||||
|
let urlObject = new URL(url);
|
||||||
|
|
||||||
if (storage.localHostsSkipping && checkLocalURL(pureUrl)) {
|
if (storage.localHostsSkipping && checkLocalURL(urlObject)) {
|
||||||
return {
|
return {
|
||||||
"changes": false,
|
"changes": false,
|
||||||
"url": url,
|
"url": url,
|
||||||
@@ -73,12 +74,7 @@ function removeFieldsFormURL(provider, pureUrl, quiet = false, request = null) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (existsFragments(url)) {
|
urlObject = new URL(url);
|
||||||
domain = url.replace(new RegExp("#.*", "i"), "");
|
|
||||||
}
|
|
||||||
if (existsFields(url)) {
|
|
||||||
domain = url.replace(new RegExp("\\?.*", "i"), "");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Expand the url by provider redirections. So no tracking on
|
* Expand the url by provider redirections. So no tracking on
|
||||||
@@ -101,47 +97,55 @@ function removeFieldsFormURL(provider, pureUrl, quiet = false, request = null) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (existsFields(url)) {
|
fields = urlObject.searchParams;
|
||||||
fields = "?" + extractFileds(url).rmEmpty().join("&");
|
fragments = extractFragments(urlObject);
|
||||||
}
|
domain = urlWithoutParamsAndHash(urlObject).toString();
|
||||||
|
|
||||||
if (existsFragments(url)) {
|
|
||||||
fragments = "#" + extractFragments(url).rmEmpty().join("&");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Only test for matches, if there are fields or fragments that can be cleaned.
|
* Only test for matches, if there are fields or fragments that can be cleaned.
|
||||||
*/
|
*/
|
||||||
if (fields !== "" || fragments !== "") {
|
if (fields.toString() !== "" || fragments.toString() !== "") {
|
||||||
rules.forEach(function (rule) {
|
rules.forEach(rule => {
|
||||||
let beforeReplace = fields;
|
const beforeFields = fields.toString();
|
||||||
let beforeReplaceFragments = fragments;
|
const beforeFragments = fragments.toString();
|
||||||
fields = fields.replace(new RegExp(rule, "gi"), "");
|
let localChange = false;
|
||||||
fragments = fragments.replace(new RegExp(rule, "gi"), "");
|
|
||||||
|
for (const field of fields.keys()) {
|
||||||
|
if (new RegExp(rule, "gi").test(field)) {
|
||||||
|
fields.delete(field);
|
||||||
|
changes = true;
|
||||||
|
localChange = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const fragment of fragments.keys()) {
|
||||||
|
if (new RegExp(rule, "gi").test(fragment)) {
|
||||||
|
fragments.delete(fragment);
|
||||||
|
changes = true;
|
||||||
|
localChange = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (beforeReplace !== fields || beforeReplaceFragments !== fragments) {
|
|
||||||
//Log the action
|
//Log the action
|
||||||
if (storage.loggingStatus) {
|
if (localChange && storage.loggingStatus) {
|
||||||
let tempURL = domain;
|
let tempURL = domain;
|
||||||
let tempBeforeURL = domain;
|
let tempBeforeURL = domain;
|
||||||
|
|
||||||
if (fields !== "") tempURL += "?" + fields.replace("?&", "?").replace("?", "");
|
if (fields.toString() !== "") tempURL += "?" + fields.toString();
|
||||||
if (fragments !== "") tempURL += "#" + fragments.replace("#&", "#").replace("#", "");
|
if (fragments.toString() !== "") tempURL += "#" + fragments.toString();
|
||||||
if (beforeReplace !== "") tempBeforeURL += "?" + beforeReplace.replace("?&", "?").replace("?", "");
|
if (beforeFields.toString() !== "") tempBeforeURL += "?" + beforeFields.toString();
|
||||||
if (beforeReplaceFragments !== "") tempBeforeURL += "#" + beforeReplaceFragments.replace("#&", "#").replace("#", "");
|
if (beforeFragments.toString() !== "") tempBeforeURL += "#" + beforeFragments.toString();
|
||||||
|
|
||||||
if (!quiet) pushToLog(tempBeforeURL, tempURL, rule);
|
if (!quiet) pushToLog(tempBeforeURL, tempURL, rule);
|
||||||
}
|
|
||||||
|
|
||||||
increaseBadged(quiet, request);
|
increaseBadged(quiet, request);
|
||||||
changes = true;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let finalURL = domain;
|
let finalURL = domain;
|
||||||
|
|
||||||
if (fields !== "") finalURL += "?" + fields.replace("?", "");
|
if (fields.toString() !== "") finalURL += "?" + fields.toString();
|
||||||
if (fragments !== "") finalURL += "#" + fragments.replace("#", "");
|
if (fragments.toString() !== "") finalURL += "#" + fragments.toString();
|
||||||
|
|
||||||
url = finalURL.replace(new RegExp("\\?&"), "?").replace(new RegExp("#&"), "#");
|
url = finalURL.replace(new RegExp("\\?&"), "?").replace(new RegExp("#&"), "#");
|
||||||
}
|
}
|
||||||
@@ -240,7 +244,7 @@ function start() {
|
|||||||
* Deactivates ClearURLs, if no rules can be downloaded and also no old rules in storage
|
* Deactivates ClearURLs, if no rules can be downloaded and also no old rules in storage
|
||||||
*/
|
*/
|
||||||
function deactivateOnFailure() {
|
function deactivateOnFailure() {
|
||||||
if(storage.ClearURLsData.length === 0) {
|
if (storage.ClearURLsData.length === 0) {
|
||||||
storage.globalStatus = false;
|
storage.globalStatus = false;
|
||||||
storage.dataHash = "";
|
storage.dataHash = "";
|
||||||
changeIcon();
|
changeIcon();
|
||||||
@@ -430,8 +434,6 @@ function start() {
|
|||||||
* @param {boolean} isActive Is this rule active?
|
* @param {boolean} isActive Is this rule active?
|
||||||
*/
|
*/
|
||||||
this.addRule = function (rule, isActive = true) {
|
this.addRule = function (rule, isActive = true) {
|
||||||
rule = "([\\/\\?#]|(&|&))+(" + rule + "=[^&]*)";
|
|
||||||
|
|
||||||
this.applyRule(enabled_rules, disabled_rules, rule, isActive);
|
this.applyRule(enabled_rules, disabled_rules, rule, isActive);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -476,8 +478,6 @@ function start() {
|
|||||||
* @param {boolean} isActive Is this rule active?
|
* @param {boolean} isActive Is this rule active?
|
||||||
*/
|
*/
|
||||||
this.addReferralMarketing = function (rule, isActive = true) {
|
this.addReferralMarketing = function (rule, isActive = true) {
|
||||||
rule = "([\\/\\?#]|(&|&))+(" + rule + "=[^&]*)";
|
|
||||||
|
|
||||||
this.applyRule(enabled_referralMarketing, disabled_referralMarketing, rule, isActive);
|
this.applyRule(enabled_referralMarketing, disabled_referralMarketing, rule, isActive);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
*/
|
*/
|
||||||
function eTagFilter(requestDetails) {
|
function eTagFilter(requestDetails) {
|
||||||
if(!requestDetails.responseHeaders || !storage.eTagFiltering
|
if(!requestDetails.responseHeaders || !storage.eTagFiltering
|
||||||
|| storage.localHostsSkipping && checkLocalURL(requestDetails.url)) return {};
|
|| storage.localHostsSkipping && checkLocalURL(new URL(requestDetails.url))) return {};
|
||||||
const responseHeaders = requestDetails.responseHeaders;
|
const responseHeaders = requestDetails.responseHeaders;
|
||||||
|
|
||||||
const filteredHeaders = responseHeaders.filter(header => {
|
const filteredHeaders = responseHeaders.filter(header => {
|
||||||
|
|||||||
@@ -56,8 +56,7 @@ function isEmpty(obj) {
|
|||||||
* @param {string} string Name of the attribute used for localization
|
* @param {string} string Name of the attribute used for localization
|
||||||
* @param {string[]} placeholders Array of placeholders
|
* @param {string[]} placeholders Array of placeholders
|
||||||
*/
|
*/
|
||||||
function translate(string, ...placeholders)
|
function translate(string, ...placeholders) {
|
||||||
{
|
|
||||||
return browser.i18n.getMessage(string, placeholders);
|
return browser.i18n.getMessage(string, placeholders);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,24 +83,22 @@ async function checkOSAndroid() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract the host without port from an url.
|
* Extract the host without port from an url.
|
||||||
* @param {String} url URL as String
|
* @param {URL} url URL as String
|
||||||
* @return {String} host as string
|
* @return {String} host as string
|
||||||
*/
|
*/
|
||||||
function extractHost(url) {
|
function extractHost(url) {
|
||||||
let parsed_url = new URL(url);
|
return url.hostname;
|
||||||
|
|
||||||
return parsed_url.hostname;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the url has a local host.
|
* Returns true if the url has a local host.
|
||||||
* @param {String} url URL as String
|
* @param {URL} url URL as object
|
||||||
* @return {boolean}
|
* @return {boolean}
|
||||||
*/
|
*/
|
||||||
function checkLocalURL(url) {
|
function checkLocalURL(url) {
|
||||||
let host = extractHost(url);
|
let host = extractHost(url);
|
||||||
|
|
||||||
if(!host.match(/^\d/) && host !== 'localhost') {
|
if (!host.match(/^\d/) && host !== 'localhost') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,72 +114,39 @@ function checkLocalURL(url) {
|
|||||||
* @return {int} Number of Parameters
|
* @return {int} Number of Parameters
|
||||||
*/
|
*/
|
||||||
function countFields(url) {
|
function countFields(url) {
|
||||||
return extractFileds(url).length;
|
return new URL(url).searchParams.entries.length;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
return (count > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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)) {
|
|
||||||
fields = fields.replace(new RegExp("#.*", "i"), "");
|
|
||||||
}
|
|
||||||
|
|
||||||
return (fields.match(/[^\/|\?|&]+=?[^&]*/gi) || []);
|
|
||||||
}
|
|
||||||
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
* Extract the fragments from an url.
|
||||||
* @param {String} url URL as String
|
* @param {URL} url URL as object
|
||||||
* @return {Array} fragments as array
|
* @return {URLSearchParams} fragments as URLSearchParams object
|
||||||
*/
|
*/
|
||||||
function extractFragments(url) {
|
function extractFragments(url) {
|
||||||
if (existsFragments(url)) {
|
if (url.hash) {
|
||||||
let fragments = url.replace(new RegExp(".*?#", "i"), "");
|
return new URLSearchParams(url.hash.slice(1));
|
||||||
return (fragments.match(/[^&]+=?[^&]*/gi) || []);
|
} else {
|
||||||
|
return new URLSearchParams();
|
||||||
}
|
}
|
||||||
|
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if fragments exists.
|
* Returns the given URL without searchParams and hash.
|
||||||
* @param {String} url URL as String
|
* @param {URL} url the URL as object
|
||||||
* @return {boolean}
|
* @return {URL} the url without searchParams and hash
|
||||||
*/
|
*/
|
||||||
function existsFragments(url) {
|
function urlWithoutParamsAndHash(url) {
|
||||||
let matches = (url.match(/\#.+/i) || []);
|
let newURL = url.toString();
|
||||||
let count = matches.length;
|
|
||||||
|
|
||||||
return (count > 0);
|
if (url.search) {
|
||||||
|
newURL = newURL.replace(url.search, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (url.hash) {
|
||||||
|
newURL = newURL.replace(url.hash, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new URL(newURL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -283,13 +247,13 @@ function getBrowser() {
|
|||||||
function decodeURL(url) {
|
function decodeURL(url) {
|
||||||
let rtn = decodeURIComponent(url);
|
let rtn = decodeURIComponent(url);
|
||||||
|
|
||||||
while(isEncodedURI(rtn)) {
|
while (isEncodedURI(rtn)) {
|
||||||
rtn = decodeURIComponent(rtn);
|
rtn = decodeURIComponent(rtn);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Required (e.g., to fix https://github.com/ClearURLs/Addon/issues/71)
|
// Required (e.g., to fix https://github.com/ClearURLs/Addon/issues/71)
|
||||||
if(!rtn.startsWith('http')) {
|
if (!rtn.startsWith('http')) {
|
||||||
rtn = 'http://'+rtn
|
rtn = 'http://' + rtn
|
||||||
}
|
}
|
||||||
|
|
||||||
return rtn;
|
return rtn;
|
||||||
|
|||||||
@@ -25,13 +25,12 @@
|
|||||||
* This watchdog restarts the whole Add-on, when the check fails.
|
* This watchdog restarts the whole Add-on, when the check fails.
|
||||||
*/
|
*/
|
||||||
const CHECK_INTERVAL = 60000;
|
const CHECK_INTERVAL = 60000;
|
||||||
|
const __dirtyURL = "https://clearurls.roebert.eu?utm_source=addon";
|
||||||
|
const __cleanURL = new URL("https://clearurls.roebert.eu").toString();
|
||||||
|
|
||||||
setInterval(function() {
|
setInterval(function() {
|
||||||
if(isStorageAvailable() && storage.globalStatus) {
|
if(isStorageAvailable() && storage.globalStatus) {
|
||||||
const dirtyURL = "https://clearurls.roebert.eu?utm_source=addon";
|
if(new URL(pureCleaning(__dirtyURL, true)).toString() !== __cleanURL) {
|
||||||
const cleanURL = "https://clearurls.roebert.eu";
|
|
||||||
|
|
||||||
if(pureCleaning(dirtyURL, true) !== cleanURL) {
|
|
||||||
storage.watchDogErrorCount += 1;
|
storage.watchDogErrorCount += 1;
|
||||||
console.log(translate('watchdog', storage.watchDogErrorCount));
|
console.log(translate('watchdog', storage.watchDogErrorCount));
|
||||||
saveOnExit();
|
saveOnExit();
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"name": "ClearURLs",
|
"name": "ClearURLs",
|
||||||
"version": "1.23.1",
|
"version": "1.24.0",
|
||||||
"author": "Kevin Roebert",
|
"author": "Kevin Roebert",
|
||||||
"description": "__MSG_extension_description__",
|
"description": "__MSG_extension_description__",
|
||||||
"homepage_url": "https://docs.clearurls.xyz",
|
"homepage_url": "https://docs.clearurls.xyz",
|
||||||
|
|||||||
Reference in New Issue
Block a user