mirror of
https://gitlab.com/KevinRoebert/ClearUrls
synced 2025-12-16 14:15:36 +07:00
Compare commits
12 Commits
c19dcc1716
...
refactorin
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
81d5b35fe2 | ||
|
|
2f8403f1ce | ||
|
|
9cf1704100 | ||
|
|
dc23257632 | ||
|
|
7c8d6b0eee | ||
|
|
6d904144ec | ||
|
|
d16a571d3a | ||
|
|
2d4711e548 | ||
|
|
bef2dd5fe6 | ||
|
|
1baab2488c | ||
|
|
79770d2aab | ||
|
|
d8da43ac29 |
22
CHANGELOG.md
22
CHANGELOG.md
@@ -15,6 +15,28 @@ 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.27.3] - 2025-02-05
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Google Search `window.rwt` detection
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Google Docs
|
||||||
|
- [#134](https://github.com/ClearURLs/Addon/issues/134)
|
||||||
|
- [#187](https://gitlab.com/ClearURLs/rules/-/issues/187)
|
||||||
|
- [#387](https://github.com/ClearURLs/Addon/issues/387)
|
||||||
|
- [#393](https://github.com/ClearURLs/Addon/issues/393)
|
||||||
|
- [#978](https://gitlab.com/ClearURLs/ClearUrls/-/issues/978)
|
||||||
|
- [#980](https://gitlab.com/ClearURLs/ClearUrls/-/issues/980)
|
||||||
|
- [#1301](https://gitlab.com/ClearURLs/ClearUrls/-/issues/1301)
|
||||||
|
- [#1302](https://gitlab.com/ClearURLs/ClearUrls/-/issues/1302)
|
||||||
|
- [#1305](https://gitlab.com/ClearURLs/ClearUrls/-/issues/1305)
|
||||||
|
|
||||||
|
### Compatibility note
|
||||||
|
- Require Firefox >= 55
|
||||||
|
- Require Chrome >= 37
|
||||||
|
|
||||||
## [1.27.2] - 2025-01-27
|
## [1.27.2] - 2025-01-27
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|||||||
11
README.md
11
README.md
@@ -77,6 +77,8 @@ Please push your translation into the folder `_locales/{language code}/messages.
|
|||||||
* [Unalix](https://github.com/AmanoTeam/Unalix) small, dependency-free, fast Python package for removing tracking fields from URLs
|
* [Unalix](https://github.com/AmanoTeam/Unalix) small, dependency-free, fast Python package for removing tracking fields from URLs
|
||||||
* [Unalix-nim](https://github.com/AmanoTeam/Unalix-nim) small, dependency-free, fast Nim package and CLI tool for removing tracking fields from URLs
|
* [Unalix-nim](https://github.com/AmanoTeam/Unalix-nim) small, dependency-free, fast Nim package and CLI tool for removing tracking fields from URLs
|
||||||
* [UnalixAndroid](https://github.com/AmanoTeam/UnalixAndroid) simple Android app that removes link masking/tracking and optionally resolves shortened links
|
* [UnalixAndroid](https://github.com/AmanoTeam/UnalixAndroid) simple Android app that removes link masking/tracking and optionally resolves shortened links
|
||||||
|
* [pl-fe](https://github.com/mkljczk/pl-fe) is a Fediverse client which uses ClearURLs code to clean URLs from displayed posts and recommend cleaning URLs from created posts
|
||||||
|
* [URLCheck](https://github.com/TrianguloY/URLCheck) is an Android app to review and edit URLs before opening them. Allows to use the ClearURLs catalog.
|
||||||
|
|
||||||
## Recommended by...
|
## Recommended by...
|
||||||
* [ghacks-user.js](https://github.com/ghacksuserjs/ghacks-user.js/wiki/4.1-Extensions)
|
* [ghacks-user.js](https://github.com/ghacksuserjs/ghacks-user.js/wiki/4.1-Extensions)
|
||||||
@@ -104,3 +106,12 @@ We use some third-party scripts in our add-on. The authors and licenses are list
|
|||||||
[MIT](https://github.com/Simonwep/pickr/blob/master/LICENSE)
|
[MIT](https://github.com/Simonwep/pickr/blob/master/LICENSE)
|
||||||
- [Font Awesome](https://github.com/FortAwesome/Font-Awesome/) | Copyright (c) @fontawesome |
|
- [Font Awesome](https://github.com/FortAwesome/Font-Awesome/) | Copyright (c) @fontawesome |
|
||||||
[Font Awesome Free License](https://github.com/FortAwesome/Font-Awesome/blob/master/LICENSE.txt)
|
[Font Awesome Free License](https://github.com/FortAwesome/Font-Awesome/blob/master/LICENSE.txt)
|
||||||
|
|
||||||
|
|
||||||
|
## Star History
|
||||||
|
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=ClearURLs/Addon&type=Date&theme=dark" />
|
||||||
|
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=ClearURLs/Addon&type=Date" />
|
||||||
|
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=ClearURLs/Addon&type=Date" />
|
||||||
|
</picture>
|
||||||
|
|||||||
196
clearurls.js
196
clearurls.js
@@ -21,6 +21,8 @@
|
|||||||
* This script is responsible for the core functionalities.
|
* This script is responsible for the core functionalities.
|
||||||
*/
|
*/
|
||||||
var providers = [];
|
var providers = [];
|
||||||
|
var providersByToken = {}; // Map<string, Provider[]>
|
||||||
|
var globalProviders = []; // Provider[]
|
||||||
var prvKeys = [];
|
var prvKeys = [];
|
||||||
var siteBlockedAlert = 'javascript:void(0)';
|
var siteBlockedAlert = 'javascript:void(0)';
|
||||||
var dataHash;
|
var dataHash;
|
||||||
@@ -89,14 +91,14 @@ function removeFieldsFormURL(provider, pureUrl, quiet = false, request = null) {
|
|||||||
/*
|
/*
|
||||||
* Apply raw rules to the URL.
|
* Apply raw rules to the URL.
|
||||||
*/
|
*/
|
||||||
rawRules.forEach(function (rawRule) {
|
rawRules.forEach(function ({ rule: rawRuleStr, regex: rawRuleRegex }) {
|
||||||
let beforeReplace = url;
|
let beforeReplace = url;
|
||||||
url = url.replace(new RegExp(rawRule, "gi"), "");
|
url = url.replace(rawRuleRegex, "");
|
||||||
|
|
||||||
if (beforeReplace !== url) {
|
if (beforeReplace !== url) {
|
||||||
//Log the action
|
//Log the action
|
||||||
if (storage.loggingStatus && !quiet) {
|
if (storage.loggingStatus && !quiet) {
|
||||||
pushToLog(beforeReplace, url, rawRule);
|
pushToLog(beforeReplace, url, rawRuleStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
increaseBadged(quiet, request);
|
increaseBadged(quiet, request);
|
||||||
@@ -113,13 +115,13 @@ function removeFieldsFormURL(provider, pureUrl, quiet = false, request = null) {
|
|||||||
* 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.toString() !== "" || fragments.toString() !== "") {
|
if (fields.toString() !== "" || fragments.toString() !== "") {
|
||||||
rules.forEach(rule => {
|
rules.forEach(({ rule, regex }) => {
|
||||||
const beforeFields = fields.toString();
|
const beforeFields = fields.toString();
|
||||||
const beforeFragments = fragments.toString();
|
const beforeFragments = fragments.toString();
|
||||||
let localChange = false;
|
let localChange = false;
|
||||||
|
|
||||||
for (const field of fields.keys()) {
|
for (const field of fields.keys()) {
|
||||||
if (new RegExp("^"+rule+"$", "gi").test(field)) {
|
if (regex.test(field)) {
|
||||||
fields.delete(field);
|
fields.delete(field);
|
||||||
changes = true;
|
changes = true;
|
||||||
localChange = true;
|
localChange = true;
|
||||||
@@ -127,7 +129,7 @@ function removeFieldsFormURL(provider, pureUrl, quiet = false, request = null) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const fragment of fragments.keys()) {
|
for (const fragment of fragments.keys()) {
|
||||||
if (new RegExp("^"+rule+"$", "gi").test(fragment)) {
|
if (regex.test(fragment)) {
|
||||||
fragments.delete(fragment);
|
fragments.delete(fragment);
|
||||||
changes = true;
|
changes = true;
|
||||||
localChange = true;
|
localChange = true;
|
||||||
@@ -228,6 +230,17 @@ function start() {
|
|||||||
for (let re = 0; re < methods.length; re++) {
|
for (let re = 0; re < methods.length; re++) {
|
||||||
providers[p].addMethod(methods[re]);
|
providers[p].addMethod(methods[re]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Indexing logic
|
||||||
|
const token = providers[p].getLookupToken();
|
||||||
|
if (token) {
|
||||||
|
if (!providersByToken[token]) {
|
||||||
|
providersByToken[token] = [];
|
||||||
|
}
|
||||||
|
providersByToken[token].push(providers[p]);
|
||||||
|
} else {
|
||||||
|
globalProviders.push(providers[p]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,7 +373,7 @@ function start() {
|
|||||||
let methods = [];
|
let methods = [];
|
||||||
|
|
||||||
if (_completeProvider) {
|
if (_completeProvider) {
|
||||||
enabled_rules[".*"] = true;
|
enabled_rules[".*"] = new RegExp("^.*$", "i");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -379,6 +392,38 @@ function start() {
|
|||||||
return name;
|
return name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the lookup token for this provider, or null if global.
|
||||||
|
* Extracts "domain" from patterns like ^https?://(?:[a-z0-9-]+\.)*?domain...
|
||||||
|
* @return {String|null}
|
||||||
|
*/
|
||||||
|
this.getLookupToken = function () {
|
||||||
|
if (!urlPattern) return null;
|
||||||
|
const source = urlPattern.source;
|
||||||
|
|
||||||
|
// Case 1: Wildcard prefix pattern (e.g. ...*?amazon...)
|
||||||
|
const wildcardMatch = source.match(/\*\?([a-z0-9-]+)/i);
|
||||||
|
if (wildcardMatch && wildcardMatch[1]) {
|
||||||
|
return wildcardMatch[1].toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Case 2: Explicit start pattern (e.g. ^https?://vk.com...)
|
||||||
|
// Matches ^https?://(optional www.)token
|
||||||
|
// We strip standard regex start structure to find the first meaningful domain token.
|
||||||
|
// This regex handles:
|
||||||
|
// - ^https?:// (start)
|
||||||
|
// - \/\/ or // (slashes, potentially escaped)
|
||||||
|
// - www. (optional www prefix, potentially escaped)
|
||||||
|
// - [a-z0-9-]+ (the token)
|
||||||
|
// It deliberately fails on patterns with groups (?:...) at the start, falling back to global.
|
||||||
|
const explicitMatch = source.match(/^(\^?https?:\\?\/\\?\/)(?:www(?:\\?\.))?([a-z0-9-]+)/i);
|
||||||
|
if (explicitMatch && explicitMatch[2]) {
|
||||||
|
return explicitMatch[2].toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add URL pattern.
|
* Add URL pattern.
|
||||||
*
|
*
|
||||||
@@ -406,25 +451,21 @@ function start() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply a rule to a given tuple of rule array.
|
* Helper to update rule maps with compiled regexes.
|
||||||
* @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) => {
|
const updateRule = (enabledMap, disabledMap, rule, isActive, compileFn) => {
|
||||||
if (isActive) {
|
if (isActive) {
|
||||||
enabledRuleArray[rule] = true;
|
if (!enabledMap[rule]) {
|
||||||
|
try {
|
||||||
if (disabledRulesArray[rule] !== undefined) {
|
enabledMap[rule] = compileFn(rule);
|
||||||
delete disabledRulesArray[rule];
|
} catch (e) {
|
||||||
|
console.error("Invalid regex", rule, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (disabledMap[rule]) delete disabledMap[rule];
|
||||||
} else {
|
} else {
|
||||||
disabledRulesArray[rule] = true;
|
disabledMap[rule] = true;
|
||||||
|
if (enabledMap[rule]) delete enabledMap[rule];
|
||||||
if (enabledRuleArray[rule] !== undefined) {
|
|
||||||
delete enabledRuleArray[rule];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -436,20 +477,22 @@ 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) {
|
||||||
this.applyRule(enabled_rules, disabled_rules, rule, isActive);
|
updateRule(enabled_rules, disabled_rules, rule, isActive, r => new RegExp("^" + r + "$", "i"));
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all active rules as an array.
|
* Return all active rules as an array of {rule, regex}.
|
||||||
*
|
*
|
||||||
* @return Array RegExp strings
|
* @return Array Objects
|
||||||
*/
|
*/
|
||||||
this.getRules = function () {
|
this.getRules = function () {
|
||||||
|
let source = enabled_rules;
|
||||||
if (!storage.referralMarketing) {
|
if (!storage.referralMarketing) {
|
||||||
return Object.keys(Object.assign(enabled_rules, enabled_referralMarketing));
|
// Determine if we need to merge referral marketing rules
|
||||||
|
// We use a new object to avoid mutating enabled_rules via Object.assign if that was happening
|
||||||
|
source = Object.assign({}, enabled_rules, enabled_referralMarketing);
|
||||||
}
|
}
|
||||||
|
return Object.entries(source).map(([rule, regex]) => ({ rule, regex }));
|
||||||
return Object.keys(enabled_rules);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -460,16 +503,17 @@ function start() {
|
|||||||
* @param {boolean} isActive Is this rule active?
|
* @param {boolean} isActive Is this rule active?
|
||||||
*/
|
*/
|
||||||
this.addRawRule = function (rule, isActive = true) {
|
this.addRawRule = function (rule, isActive = true) {
|
||||||
this.applyRule(enabled_rawRules, disabled_rawRules, rule, isActive);
|
updateRule(enabled_rawRules, disabled_rawRules, rule, isActive, r => new RegExp(r, "gi"));
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all active raw rules as an array.
|
* Return all active raw rules as an array.
|
||||||
*
|
*
|
||||||
* @return Array RegExp strings
|
* @return Array Objects {rule, regex}
|
||||||
*/
|
*/
|
||||||
this.getRawRules = function () {
|
this.getRawRules = function () {
|
||||||
return Object.keys(enabled_rawRules);
|
// return Object.keys(enabled_rawRules);
|
||||||
|
return Object.entries(enabled_rawRules).map(([rule, regex]) => ({ rule, regex }));
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -480,7 +524,7 @@ 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) {
|
||||||
this.applyRule(enabled_referralMarketing, disabled_referralMarketing, rule, isActive);
|
updateRule(enabled_referralMarketing, disabled_referralMarketing, rule, isActive, r => new RegExp("^" + r + "$", "i"));
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -491,19 +535,7 @@ function start() {
|
|||||||
* @param {Boolean} isActive Is this exception active?
|
* @param {Boolean} isActive Is this exception active?
|
||||||
*/
|
*/
|
||||||
this.addException = function (exception, isActive = true) {
|
this.addException = function (exception, isActive = true) {
|
||||||
if (isActive) {
|
updateRule(enabled_exceptions, disabled_exceptions, exception, isActive, r => new RegExp(r, "i"));
|
||||||
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];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -541,11 +573,9 @@ function start() {
|
|||||||
//Add the site blocked alert to every exception
|
//Add the site blocked alert to every exception
|
||||||
if (url === siteBlockedAlert) return true;
|
if (url === siteBlockedAlert) return true;
|
||||||
|
|
||||||
for (const exception in enabled_exceptions) {
|
for (const [exception, regex] of Object.entries(enabled_exceptions)) {
|
||||||
if (result) break;
|
if (result) break;
|
||||||
|
result = regex.test(url);
|
||||||
let exception_regex = new RegExp(exception, "i");
|
|
||||||
result = exception_regex.test(url);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -559,19 +589,7 @@ function start() {
|
|||||||
* @param {Boolean} isActive Is this redirection active?
|
* @param {Boolean} isActive Is this redirection active?
|
||||||
*/
|
*/
|
||||||
this.addRedirection = function (redirection, isActive = true) {
|
this.addRedirection = function (redirection, isActive = true) {
|
||||||
if (isActive) {
|
updateRule(enabled_redirections, disabled_redirections, redirection, isActive, r => new RegExp(r, "i"));
|
||||||
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];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -582,11 +600,11 @@ function start() {
|
|||||||
this.getRedirection = function (url) {
|
this.getRedirection = function (url) {
|
||||||
let re = null;
|
let re = null;
|
||||||
|
|
||||||
for (const redirection in enabled_redirections) {
|
for (const [redirection, regex] of Object.entries(enabled_redirections)) {
|
||||||
let result = (url.match(new RegExp(redirection, "i")));
|
let result = url.match(regex);
|
||||||
|
|
||||||
if (result && result.length > 0 && redirection) {
|
if (result && result.length > 0 && redirection) {
|
||||||
re = (new RegExp(redirection, "i")).exec(url)[1];
|
re = result[1];
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -623,16 +641,42 @@ function start() {
|
|||||||
pushToLog(request.url, request.url, translate('log_ping_blocked'));
|
pushToLog(request.url, request.url, translate('log_ping_blocked'));
|
||||||
increaseBadged(false, request);
|
increaseBadged(false, request);
|
||||||
increaseTotalCounter(1);
|
increaseTotalCounter(1);
|
||||||
return {cancel: true};
|
return { cancel: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let host = "";
|
||||||
|
try {
|
||||||
|
host = extractHost(new URL(request.url));
|
||||||
|
} catch (e) {
|
||||||
|
// If URL parsing fails, we falls back to empty host, relying on global providers or skipping
|
||||||
|
}
|
||||||
|
|
||||||
|
const hostTokens = host.split('.').map(t => t.toLowerCase());
|
||||||
|
|
||||||
|
// Collect candidate providers: Global + Key Matches
|
||||||
|
// Use a Set to avoid duplicates if multiple tokens map to same provider (unlikely but safe)
|
||||||
|
let candidateProviders = new Set(globalProviders);
|
||||||
|
|
||||||
|
for (const token of hostTokens) {
|
||||||
|
if (providersByToken[token]) {
|
||||||
|
for (const p of providersByToken[token]) {
|
||||||
|
candidateProviders.add(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// "providers" global var is still used for legacy, but here we iterate candidates
|
||||||
|
// Converting Set to Array for iteration
|
||||||
|
const candidates = Array.from(candidateProviders);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Call for every provider the removeFieldsFormURL method.
|
* Call for every provider the removeFieldsFormURL method.
|
||||||
*/
|
*/
|
||||||
for (let i = 0; i < providers.length; i++) {
|
for (let i = 0; i < candidates.length; i++) {
|
||||||
if (!providers[i].matchMethod(request)) continue;
|
const provider = candidates[i];
|
||||||
if (providers[i].matchURL(request.url)) {
|
if (!provider.matchMethod(request)) continue;
|
||||||
result = removeFieldsFormURL(providers[i], request.url, false, request);
|
if (provider.matchURL(request.url)) {
|
||||||
|
result = removeFieldsFormURL(provider, request.url, false, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -640,10 +684,10 @@ function start() {
|
|||||||
* Cancel the active request.
|
* Cancel the active request.
|
||||||
*/
|
*/
|
||||||
if (result.redirect) {
|
if (result.redirect) {
|
||||||
if (providers[i].shouldForceRedirect() &&
|
if (provider.shouldForceRedirect() &&
|
||||||
request.type === 'main_frame') {
|
request.type === 'main_frame') {
|
||||||
browser.tabs.update(request.tabId, {url: result.url}).catch(handleError);
|
browser.tabs.update(request.tabId, { url: result.url }).catch(handleError);
|
||||||
return {cancel: true};
|
return { cancel: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -658,9 +702,9 @@ function start() {
|
|||||||
if (result.cancel) {
|
if (result.cancel) {
|
||||||
if (request.type === 'main_frame') {
|
if (request.type === 'main_frame') {
|
||||||
const blockingPage = browser.runtime.getURL("html/siteBlockedAlert.html?source=" + encodeURIComponent(request.url));
|
const blockingPage = browser.runtime.getURL("html/siteBlockedAlert.html?source=" + encodeURIComponent(request.url));
|
||||||
browser.tabs.update(request.tabId, {url: blockingPage}).catch(handleError);
|
browser.tabs.update(request.tabId, { url: blockingPage }).catch(handleError);
|
||||||
|
|
||||||
return {cancel: true};
|
return { cancel: true };
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
redirectUrl: siteBlockedAlert
|
redirectUrl: siteBlockedAlert
|
||||||
@@ -723,7 +767,7 @@ function start() {
|
|||||||
*/
|
*/
|
||||||
browser.webRequest.onBeforeRequest.addListener(
|
browser.webRequest.onBeforeRequest.addListener(
|
||||||
promise,
|
promise,
|
||||||
{urls: ["<all_urls>"], types: getData("types").concat(getData("pingRequestTypes"))},
|
{ urls: ["<all_urls>"], types: getData("types").concat(getData("pingRequestTypes")) },
|
||||||
["blocking"]
|
["blocking"]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,19 +26,36 @@
|
|||||||
|
|
||||||
function injectFunction() {
|
function injectFunction() {
|
||||||
let ele = document.createElement('script');
|
let ele = document.createElement('script');
|
||||||
let s = document.getElementsByTagName('script')[0];
|
|
||||||
if (s === undefined) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ele.type = 'text/javascript';
|
ele.type = 'text/javascript';
|
||||||
ele.textContent = "Object.defineProperty(window, 'rwt', {" +
|
ele.textContent = `
|
||||||
" value: function() { return true; }," +
|
(function() {
|
||||||
" writable: false," +
|
"use strict";
|
||||||
" configurable: false" +
|
|
||||||
"});";
|
${hookRwtProperty.toString()}
|
||||||
|
|
||||||
s.parentNode.insertBefore(ele, s);
|
const rwtDescriptor = Object.getOwnPropertyDescriptor(window, 'rwt');
|
||||||
|
if (!('rwt' in window) || (rwtDescriptor && rwtDescriptor.configurable)) {
|
||||||
|
hookRwtProperty();
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
`;
|
||||||
|
|
||||||
|
let s = document.getElementsByTagName('script')[0];
|
||||||
|
if (s !== undefined) {
|
||||||
|
s.parentNode.insertBefore(ele, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hookRwtProperty() {
|
||||||
|
try {
|
||||||
|
Object.defineProperty(window, 'rwt', {
|
||||||
|
configurable: false,
|
||||||
|
writable: false,
|
||||||
|
value: function() { return true; }
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.debug('ClearURLs: Failed to hook rwt property', e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -65,6 +82,6 @@
|
|||||||
}
|
}
|
||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
main();
|
main();
|
||||||
})(window);
|
})(window);
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ function initSettings() {
|
|||||||
storage.contextMenuEnabled = true;
|
storage.contextMenuEnabled = true;
|
||||||
storage.historyListenerEnabled = true;
|
storage.historyListenerEnabled = true;
|
||||||
storage.localHostsSkipping = true;
|
storage.localHostsSkipping = true;
|
||||||
storage.referralMarketing = false;
|
storage.referralMarketing = true;
|
||||||
storage.logLimit = 100;
|
storage.logLimit = 100;
|
||||||
storage.domainBlocking = true;
|
storage.domainBlocking = true;
|
||||||
storage.pingBlocking = true;
|
storage.pingBlocking = true;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"name": "ClearURLs",
|
"name": "ClearURLs",
|
||||||
"version": "1.27.2",
|
"version": "1.28.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",
|
||||||
@@ -270,6 +270,18 @@
|
|||||||
"*://*.google.co.zw/*",
|
"*://*.google.co.zw/*",
|
||||||
"*://*.google.cat/*"
|
"*://*.google.cat/*"
|
||||||
],
|
],
|
||||||
|
"include_globs": [
|
||||||
|
"http?://www.google.*/",
|
||||||
|
"http?://www.google.*/#hl=*",
|
||||||
|
"http?://www.google.*/search*",
|
||||||
|
"http?://www.google.*/webhp?hl=*",
|
||||||
|
"https://encrypted.google.*/",
|
||||||
|
"https://encrypted.google.*/#hl=*",
|
||||||
|
"https://encrypted.google.*/search*",
|
||||||
|
"https://encrypted.google.*/webhp?hl=*",
|
||||||
|
"http?://ipv6.google.com/",
|
||||||
|
"http?://ipv6.google.com/search*"
|
||||||
|
],
|
||||||
"js": [
|
"js": [
|
||||||
"core_js/google_link_fix.js"
|
"core_js/google_link_fix.js"
|
||||||
],
|
],
|
||||||
@@ -291,4 +303,4 @@
|
|||||||
"options_ui": {
|
"options_ui": {
|
||||||
"page": "html/settings.html"
|
"page": "html/settings.html"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user