mirror of
https://gitlab.com/KevinRoebert/ClearUrls
synced 2025-12-16 06:05:37 +07:00
Version 1.9.0
- Added #284 - Added #56 - Fixed #241 - Possible fix & workaround for #203 - Fixed bug in "history tracking injection protection". This option was not disabled, when the global filter switch are on off - Added an option to im-/export the log (requires the `downloads` permission) - Added an option to im-/export the settings (requires the `downloads` permission) - Added information page for blocked sites, when they are called in the `main_frame` - Added "multiple times URL encodes" recognition - Refactoring - Changed background script loading sequence to prevent that required functions are not yet loaded.
This commit is contained in:
@@ -33,9 +33,9 @@ $(document).ready(function(){
|
||||
* This function cleans all URLs line by line in the textarea.
|
||||
*/
|
||||
function cleanURLs() {
|
||||
var cleanTArea = $('#cleanURLs');
|
||||
var dirtyTArea = $('#dirtyURLs');
|
||||
var urls = dirtyTArea.val().split('\n');
|
||||
const cleanTArea = $('#cleanURLs');
|
||||
const dirtyTArea = $('#dirtyURLs');
|
||||
const urls = dirtyTArea.val().split('\n');
|
||||
cleanedURLs = [];
|
||||
length = urls.length;
|
||||
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
"use strict";
|
||||
|
||||
function injectFunction() {
|
||||
var ele = document.createElement('script');
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
let ele = document.createElement('script');
|
||||
let s = document.getElementsByTagName('script')[0];
|
||||
|
||||
ele.type = 'text/javascript';
|
||||
ele.textContent = "Object.defineProperty(window, 'rwt', {" +
|
||||
@@ -46,13 +46,13 @@
|
||||
injectFunction();
|
||||
|
||||
document.addEventListener('mouseover', function (event) {
|
||||
var a = event.target, depth = 1;
|
||||
let a = event.target, depth = 1;
|
||||
|
||||
while (a && a.tagName != 'A' && depth-- > 0) {
|
||||
while (a && a.tagName !== 'A' && depth-- > 0) {
|
||||
a = a.parentNode;
|
||||
}
|
||||
|
||||
if (a && a.tagName == 'A') {
|
||||
if (a && a.tagName === 'A') {
|
||||
try {
|
||||
a.removeAttribute('data-cthref');
|
||||
delete a.dataset.cthref;
|
||||
|
||||
@@ -37,14 +37,16 @@ function historyListenerStart() {
|
||||
* which is associated with the new history entry created by replaceState()
|
||||
*/
|
||||
function historyCleaner(details) {
|
||||
var urlBefore = details.url;
|
||||
var urlAfter = pureCleaning(details.url);
|
||||
if(storage.globalStatus) {
|
||||
const urlBefore = details.url;
|
||||
const urlAfter = pureCleaning(details.url);
|
||||
|
||||
if(urlBefore != urlAfter) {
|
||||
browser.tabs.executeScript(details.tabId, {
|
||||
frameId: details.frameId,
|
||||
code: 'history.replaceState({state: "cleaned_history"},"",'+JSON.stringify(urlAfter)+');'
|
||||
}).then(() => {}, onError);
|
||||
if(urlBefore !== urlAfter) {
|
||||
browser.tabs.executeScript(details.tabId, {
|
||||
frameId: details.frameId,
|
||||
code: 'history.replaceState({state: "cleaned_history"},"",'+JSON.stringify(urlAfter)+');'
|
||||
}).then(() => {}, onError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ var log = {};
|
||||
* Reset the global log
|
||||
*/
|
||||
function resetGlobalLog(){
|
||||
obj = {"log": []};
|
||||
let obj = {"log": []};
|
||||
|
||||
browser.runtime.sendMessage({
|
||||
function: "setData",
|
||||
@@ -53,11 +53,11 @@ function getLog()
|
||||
return b.timestamp - a.timestamp;
|
||||
});
|
||||
|
||||
var length = Object.keys(log.log).length;
|
||||
var row;
|
||||
if(length != 0)
|
||||
const length = Object.keys(log.log).length;
|
||||
let row;
|
||||
if(length !== 0)
|
||||
{
|
||||
for(var i=0; i<length;i++)
|
||||
for(let i=0; i<length;i++)
|
||||
{
|
||||
row = "<tr>" +
|
||||
"<td>"+log.log[i].before+"</td>" +
|
||||
@@ -81,11 +81,9 @@ function getLog()
|
||||
*/
|
||||
function getDataTableTranslation()
|
||||
{
|
||||
var lang = browser.i18n.getUILanguage();
|
||||
let lang = browser.i18n.getUILanguage();
|
||||
lang = lang.substring(0,2);
|
||||
var file = browser.extension.getURL('./external_js/dataTables/i18n/'+lang+'.lang');
|
||||
|
||||
return file;
|
||||
return browser.extension.getURL('./external_js/dataTables/i18n/' + lang + '.lang');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,6 +94,42 @@ function toDate(time)
|
||||
return new Date(time).toLocaleString();
|
||||
}
|
||||
|
||||
/**
|
||||
* This function export the global log as json file.
|
||||
*/
|
||||
function exportGlobalLog() {
|
||||
browser.runtime.sendMessage({
|
||||
function: "getData",
|
||||
params: ['log']
|
||||
}).then((data) => {
|
||||
let blob = new Blob([JSON.stringify(data.response)], {type: 'application/json'});
|
||||
|
||||
browser.downloads.download({
|
||||
'url': URL.createObjectURL(blob),
|
||||
'filename': 'ClearURLsLogExport.json',
|
||||
'saveAs': true
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This function imports an exported global log and overwrites the old one.
|
||||
*/
|
||||
function importGlobalLog(evt) {
|
||||
let file = evt.target.files[0];
|
||||
let fileReader = new FileReader();
|
||||
|
||||
fileReader.onload = function(e) {
|
||||
browser.runtime.sendMessage({
|
||||
function: "setData",
|
||||
params: ["log", e.target.result]
|
||||
}).then(() => {
|
||||
location.reload();
|
||||
}, handleError);
|
||||
};
|
||||
fileReader.readAsText(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load only when document is ready
|
||||
*/
|
||||
@@ -103,6 +137,8 @@ $(document).ready(function(){
|
||||
setText();
|
||||
getLog();
|
||||
$('#reset_log_btn').on("click", resetGlobalLog);
|
||||
$('#export_log_btn').on("click", exportGlobalLog);
|
||||
$('#importLog').on("change", importGlobalLog);
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -122,12 +158,16 @@ function setText()
|
||||
{
|
||||
document.title = translate('log_html_page_title');
|
||||
$('#page_title').text(translate('log_html_page_title'));
|
||||
$('#reset_log_btn').text(translate('log_html_reset_button'));
|
||||
$('#log_html_reset_button').prop('title', translate('log_html_reset_button_title'));
|
||||
$('#reset_log_btn').text(translate('log_html_reset_button'))
|
||||
.prop('title', translate('log_html_reset_button_title'));
|
||||
$('#head_1').text(translate('log_html_table_head_1'));
|
||||
$('#head_2').text(translate('log_html_table_head_2'));
|
||||
$('#head_3').text(translate('log_html_table_head_3'));
|
||||
$('#head_4').text(translate('log_html_table_head_4'));
|
||||
$('#export_log_btn_text').text(translate('log_html_export_button'));
|
||||
$('#export_log_btn').prop('title', translate('log_html_export_button_title'));
|
||||
$('#import_log_btn_text').text(translate('log_html_import_button'));
|
||||
$('#import_log_btn').prop('title', translate('log_html_import_button_title'));
|
||||
}
|
||||
|
||||
function handleError(error) {
|
||||
|
||||
@@ -29,11 +29,11 @@
|
||||
*/
|
||||
function handleMessage(request, sender, sendResponse)
|
||||
{
|
||||
var fn = window[request.function];
|
||||
let fn = window[request.function];
|
||||
|
||||
if(typeof fn === "function")
|
||||
{
|
||||
var response = fn.apply(null, request.params);
|
||||
let response = fn.apply(null, request.params);
|
||||
|
||||
return Promise.resolve({response});
|
||||
}
|
||||
|
||||
@@ -107,7 +107,6 @@ function init()
|
||||
|
||||
/**
|
||||
* Get the globalCounter and globalurlcounter value from the storage
|
||||
* @param {(data){} Return value form storage
|
||||
*/
|
||||
function changeStatistics()
|
||||
{
|
||||
@@ -127,7 +126,7 @@ function changeStatistics()
|
||||
*/
|
||||
function setHashStatus()
|
||||
{
|
||||
var element = $('#hashStatus');
|
||||
let element = $('#hashStatus');
|
||||
|
||||
if(hashStatus)
|
||||
{
|
||||
@@ -146,7 +145,7 @@ function setHashStatus()
|
||||
*/
|
||||
function changeSwitchButton(id, storageID)
|
||||
{
|
||||
var element = $('#'+id);
|
||||
let element = $('#'+id);
|
||||
|
||||
changeVisibility(id, storageID);
|
||||
|
||||
@@ -155,7 +154,7 @@ function changeSwitchButton(id, storageID)
|
||||
function: "setData",
|
||||
params: [storageID, element.is(':checked')]
|
||||
}).then((data) => {
|
||||
if(storageID == "globalStatus"){
|
||||
if(storageID === "globalStatus"){
|
||||
browser.runtime.sendMessage({
|
||||
function: "changeIcon",
|
||||
params: []
|
||||
@@ -176,7 +175,7 @@ function changeSwitchButton(id, storageID)
|
||||
*/
|
||||
function changeVisibility(id, storageID)
|
||||
{
|
||||
var element;
|
||||
let element;
|
||||
|
||||
switch(storageID)
|
||||
{
|
||||
@@ -190,7 +189,7 @@ function changeVisibility(id, storageID)
|
||||
element = "undefine";
|
||||
}
|
||||
|
||||
if(element != "undefine")
|
||||
if(element !== "undefine")
|
||||
{
|
||||
if($('#'+id).is(':checked'))
|
||||
{
|
||||
@@ -211,7 +210,7 @@ function changeVisibility(id, storageID)
|
||||
*/
|
||||
function setSwitchButton(id, varname)
|
||||
{
|
||||
var element = $('#'+id);
|
||||
let element = $('#'+id);
|
||||
element.prop('checked', this[varname]);
|
||||
}
|
||||
|
||||
@@ -281,11 +280,11 @@ function setText()
|
||||
*
|
||||
* @param {string} id ID of the HTML element
|
||||
* @param {string} attribute Name of the attribute used for localization
|
||||
* @param {boolean} tooltip
|
||||
* @param {string} tooltip
|
||||
*/
|
||||
function injectText(id, attribute, tooltip)
|
||||
function injectText(id, attribute, tooltip = "")
|
||||
{
|
||||
object = $('#'+id);
|
||||
let object = $('#'+id);
|
||||
object.text(translate(attribute));
|
||||
|
||||
/*
|
||||
@@ -294,7 +293,7 @@ function injectText(id, attribute, tooltip)
|
||||
*/
|
||||
tooltip = translate(attribute+"_title");
|
||||
|
||||
if(tooltip != "")
|
||||
if(tooltip !== "")
|
||||
{
|
||||
object.prop('title', tooltip);
|
||||
}
|
||||
|
||||
@@ -19,20 +19,23 @@
|
||||
/*jshint esversion: 6 */
|
||||
|
||||
/**
|
||||
* Cleans given links. Also do automatic redirection.
|
||||
*
|
||||
* @param {[type]} url url as string
|
||||
* @return {Array} redirectUrl or none
|
||||
*/
|
||||
function pureCleaning(url) {
|
||||
var cleanURL = url;
|
||||
var URLbeforeReplaceCount = countFields(url);
|
||||
* Cleans given links. Also do automatic redirection.
|
||||
*
|
||||
* @param {String} url url as string
|
||||
* @param {boolean} quiet if the action should be displayed in log and statistics
|
||||
* @return {String} redirectUrl or none
|
||||
*/
|
||||
function pureCleaning(url, quiet = false) {
|
||||
let cleanURL = url;
|
||||
const URLbeforeReplaceCount = countFields(url);
|
||||
|
||||
//Add Fields form Request to global url counter
|
||||
increaseGlobalURLCounter(URLbeforeReplaceCount);
|
||||
if(!quiet) {
|
||||
//Add Fields form Request to global url counter
|
||||
increaseGlobalURLCounter(URLbeforeReplaceCount);
|
||||
}
|
||||
|
||||
for (var i = 0; i < providers.length; i++) {
|
||||
var result = {
|
||||
for (let i = 0; i < providers.length; i++) {
|
||||
let result = {
|
||||
"changes": false,
|
||||
"url": "",
|
||||
"redirect": false,
|
||||
@@ -41,7 +44,7 @@ function pureCleaning(url) {
|
||||
|
||||
if(providers[i].matchURL(cleanURL))
|
||||
{
|
||||
result = removeFieldsFormURL(providers[i], cleanURL);
|
||||
result = removeFieldsFormURL(providers[i], cleanURL, quiet);
|
||||
cleanURL = result.url;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@ $(document).ready(function(){
|
||||
setText();
|
||||
$(".pick-a-color").pickAColor();
|
||||
$('#reset_settings_btn').on("click", reset);
|
||||
$('#export_settings_btn').on("click", exportSettings);
|
||||
$('#importSettings').on("change", importSettings);
|
||||
$('#save_settings_btn').on("click", save);
|
||||
|
||||
$("#badged_color input").on("change", function () {
|
||||
@@ -101,6 +103,11 @@ function save()
|
||||
params: ["types", $('input[name=types]').val()]
|
||||
}).then(handleResponse, handleError);
|
||||
|
||||
browser.runtime.sendMessage({
|
||||
function: "setData",
|
||||
params: ["logLimit", $('input[name=logLimit]').val()]
|
||||
}).then(handleResponse, handleError);
|
||||
|
||||
browser.runtime.sendMessage({
|
||||
function: "saveOnExit",
|
||||
params: []
|
||||
@@ -113,13 +120,14 @@ function save()
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate a string with the i18n API.
|
||||
*
|
||||
* @param {string} string Name of the attribute used for localization
|
||||
* Translate a string with the i18n API.
|
||||
*
|
||||
* @param {string} string Name of the attribute used for localization
|
||||
* @param {string[]} placeholders Array of placeholders
|
||||
*/
|
||||
function translate(string)
|
||||
function translate(string, ...placeholders)
|
||||
{
|
||||
return browser.i18n.getMessage(string);
|
||||
return browser.i18n.getMessage(string, placeholders);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -147,6 +155,18 @@ function getData()
|
||||
params: ["types"]
|
||||
}).then((data) => handleResponseData(data, "types", "types"), handleError);
|
||||
|
||||
browser.runtime.sendMessage({
|
||||
function: "getData",
|
||||
params: ["logLimit"]
|
||||
}).then((data) => {
|
||||
handleResponseData(data, "logLimit", "logLimit");
|
||||
if(data.response === undefined || data.response === -1) {
|
||||
$('#logLimit_label').text(translate('setting_log_limit_label', "∞"));
|
||||
} else {
|
||||
$('#logLimit_label').text(translate('setting_log_limit_label', data.response));
|
||||
}
|
||||
}, handleError);
|
||||
|
||||
browser.runtime.sendMessage({
|
||||
function: "getData",
|
||||
params: ["contextMenuEnabled"]
|
||||
@@ -162,9 +182,16 @@ function getData()
|
||||
params: ["localHostsSkipping"]
|
||||
}).then((data) => {
|
||||
handleResponseData(data, "localHostsSkipping", "localHostsSkipping");
|
||||
changeSwitchButton("contextMenuEnabled", "contextMenuEnabled");
|
||||
changeSwitchButton("historyListenerEnabled", "historyListenerEnabled");
|
||||
changeSwitchButton("localHostsSkipping", "localHostsSkipping");
|
||||
browser.runtime.sendMessage({
|
||||
function: "getData",
|
||||
params: ["referralMarketing"]
|
||||
}).then((data) => {
|
||||
handleResponseData(data, "referralMarketing", "referralMarketing");
|
||||
changeSwitchButton("contextMenuEnabled", "contextMenuEnabled");
|
||||
changeSwitchButton("historyListenerEnabled", "historyListenerEnabled");
|
||||
changeSwitchButton("localHostsSkipping", "localHostsSkipping");
|
||||
changeSwitchButton("referralMarketing", "referralMarketing");
|
||||
}, handleError);
|
||||
}, handleError);
|
||||
}, handleError);
|
||||
}, handleError);
|
||||
@@ -178,22 +205,74 @@ function setText()
|
||||
document.title = translate('settings_html_page_title');
|
||||
$('#page_title').text(translate('settings_html_page_title'));
|
||||
$('#badged_color_label').text(translate('badged_color_label'));
|
||||
$('#reset_settings_btn').text(translate('setting_html_reset_button'));
|
||||
$('#reset_settings_btn').prop('title', translate('setting_html_reset_button_title'));
|
||||
$('#reset_settings_btn').text(translate('setting_html_reset_button'))
|
||||
.prop('title', translate('setting_html_reset_button_title'));
|
||||
$('#rule_url_label').text(translate('setting_rule_url_label'));
|
||||
$('#hash_url_label').text(translate('setting_hash_url_label'));
|
||||
$('#types_label').html(translate('setting_types_label'));
|
||||
$('#save_settings_btn').text(translate('settings_html_save_button'));
|
||||
$('#save_settings_btn').prop('title', translate('settings_html_save_button_title'));
|
||||
$('#save_settings_btn').text(translate('settings_html_save_button'))
|
||||
.prop('title', translate('settings_html_save_button_title'));
|
||||
injectText("context_menu_enabled", "context_menu_enabled");
|
||||
$('#history_listener_enabled').html(translate('history_listener_enabled'));
|
||||
injectText("local_hosts_skipping", "local_hosts_skipping");
|
||||
$('#export_settings_btn_text').text(translate('setting_html_export_button'));
|
||||
$('#export_settings_btn').prop('title', translate('setting_html_export_button_title'));
|
||||
$('#import_settings_btn_text').text(translate('setting_html_import_button'));
|
||||
$('#import_settings_btn').prop('title', translate('setting_html_import_button_title'));
|
||||
injectText("referral_marketing_enabled", "referral_marketing_enabled");
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the response from the storage and saves the data.
|
||||
* @param {JSON-Object} data Data JSON-Object
|
||||
*/
|
||||
* This function exports all ClearURLs settings with statistics and rules.
|
||||
*/
|
||||
function exportSettings() {
|
||||
browser.runtime.sendMessage({
|
||||
function: "storageAsJSON",
|
||||
params: []
|
||||
}).then((data) => {
|
||||
let blob = new Blob([JSON.stringify(data.response)], {type: 'application/json'});
|
||||
|
||||
browser.downloads.download({
|
||||
'url': URL.createObjectURL(blob),
|
||||
'filename': 'ClearURLs.conf',
|
||||
'saveAs': true
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This function imports an exported ClearURLs setting and overwrites the old one.
|
||||
*/
|
||||
function importSettings(evt) {
|
||||
let file = evt.target.files[0];
|
||||
let fileReader = new FileReader();
|
||||
|
||||
fileReader.onload = function(e) {
|
||||
let data = JSON.parse(e.target.result);
|
||||
const length = Object.keys(data).length;
|
||||
let i=0;
|
||||
|
||||
Object.entries(data).forEach(([key, value]) => {
|
||||
browser.runtime.sendMessage({
|
||||
function: "setData",
|
||||
params: [key, value]
|
||||
}).then(() => {
|
||||
i++;
|
||||
if(i === length) {
|
||||
location.reload();
|
||||
}
|
||||
}, handleError);
|
||||
});
|
||||
};
|
||||
fileReader.readAsText(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the response from the storage and saves the data.
|
||||
* @param {JSON-Object} data Data JSON-Object
|
||||
* @param varName
|
||||
* @param inputID
|
||||
*/
|
||||
function handleResponseData(data, varName, inputID)
|
||||
{
|
||||
settings[varName] = data.response;
|
||||
@@ -215,14 +294,14 @@ function handleError(error) {
|
||||
*/
|
||||
function changeSwitchButton(id, storageID)
|
||||
{
|
||||
var element = $('#'+id);
|
||||
let element = $('#'+id);
|
||||
|
||||
element.on('change', function(){
|
||||
browser.runtime.sendMessage({
|
||||
function: "setData",
|
||||
params: [storageID, element.is(':checked')]
|
||||
}).then((data) => {
|
||||
if(storageID == "globalStatus"){
|
||||
if(storageID === "globalStatus"){
|
||||
browser.runtime.sendMessage({
|
||||
function: "changeIcon",
|
||||
params: []
|
||||
@@ -245,9 +324,9 @@ function changeSwitchButton(id, storageID)
|
||||
* @param {string} attribute Name of the attribute used for localization
|
||||
* @param {boolean} tooltip
|
||||
*/
|
||||
function injectText(id, attribute, tooltip)
|
||||
function injectText(id, attribute, tooltip = "")
|
||||
{
|
||||
object = $('#'+id);
|
||||
let object = $('#'+id);
|
||||
object.text(translate(attribute));
|
||||
|
||||
/*
|
||||
@@ -256,7 +335,7 @@ function injectText(id, attribute, tooltip)
|
||||
*/
|
||||
tooltip = translate(attribute+"_title");
|
||||
|
||||
if(tooltip != "")
|
||||
if(tooltip !== "")
|
||||
{
|
||||
object.prop('title', tooltip);
|
||||
}
|
||||
@@ -269,6 +348,6 @@ function injectText(id, attribute, tooltip)
|
||||
*/
|
||||
function setSwitchButton(id, varname)
|
||||
{
|
||||
var element = $('#'+id);
|
||||
let element = $('#'+id);
|
||||
element.prop('checked', settings[varname]);
|
||||
}
|
||||
|
||||
51
core_js/siteBlockedAlert.js
Normal file
51
core_js/siteBlockedAlert.js
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*jshint esversion: 6 */
|
||||
/*
|
||||
* This script is responsible for the blocked alert page.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Set the text for the UI.
|
||||
*/
|
||||
function setText()
|
||||
{
|
||||
document.title = translate('blocked_html_title');
|
||||
$('#title').html(translate('blocked_html_title'));
|
||||
$('#body').html(translate('blocked_html_body'));
|
||||
$('#page').text(translate('blocked_html_button'));
|
||||
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
setText();
|
||||
|
||||
let source = new URLSearchParams(window.location.search).get("source");
|
||||
$('#page').attr('href', decodeURIComponent(source));
|
||||
});
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
@@ -29,23 +29,39 @@ var pendingSaves = new Set();
|
||||
*/
|
||||
function saveOnExit()
|
||||
{
|
||||
var json = {};
|
||||
saveOnDisk(Object.keys(storage));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the storage as JSON.
|
||||
*/
|
||||
function storageAsJSON() {
|
||||
let json = {};
|
||||
|
||||
Object.entries(storage).forEach(([key, value]) => {
|
||||
switch (key) {
|
||||
case "ClearURLsData":
|
||||
case "log":
|
||||
json[key] = JSON.stringify(value);
|
||||
break;
|
||||
case "types":
|
||||
json[key] = value.toString();
|
||||
break;
|
||||
default:
|
||||
json[key] = value;
|
||||
}
|
||||
json[key] = storageDataAsString(key);
|
||||
});
|
||||
console.log(translate('core_save_on_disk'));
|
||||
browser.storage.local.set(json);
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a given storage data to its string representation.
|
||||
* @param key key of the storage data
|
||||
* @returns {string} string representation
|
||||
*/
|
||||
function storageDataAsString(key) {
|
||||
let value = storage[key];
|
||||
|
||||
switch (key) {
|
||||
case "ClearURLsData":
|
||||
case "log":
|
||||
return JSON.stringify(value);
|
||||
case "types":
|
||||
return value.toString();
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,22 +70,12 @@ function saveOnExit()
|
||||
*/
|
||||
function saveOnDisk(keys)
|
||||
{
|
||||
var json = {};
|
||||
let json = {};
|
||||
|
||||
keys.forEach(function(key) {
|
||||
var value = storage[key];
|
||||
switch (key) {
|
||||
case "ClearURLsData":
|
||||
case "log":
|
||||
json[key] = JSON.stringify(value);
|
||||
break;
|
||||
case "types":
|
||||
json[key] = value.toString();
|
||||
break;
|
||||
default:
|
||||
json[key] = value;
|
||||
}
|
||||
json[key] = storageDataAsString(key);
|
||||
});
|
||||
|
||||
console.log(translate('core_save_on_disk'));
|
||||
browser.storage.local.set(json);
|
||||
}
|
||||
@@ -145,17 +151,20 @@ function setData(key, value)
|
||||
switch (key) {
|
||||
case "ClearURLsData":
|
||||
case "log":
|
||||
storage[key] = JSON.parse(value);
|
||||
break;
|
||||
storage[key] = JSON.parse(value);
|
||||
break;
|
||||
case "hashURL":
|
||||
case "ruleURL":
|
||||
storage[key] = replaceOldURLs(value);
|
||||
break;
|
||||
storage[key] = replaceOldURLs(value);
|
||||
break;
|
||||
case "types":
|
||||
storage[key] = value.split(',');
|
||||
break;
|
||||
storage[key] = value.split(',');
|
||||
break;
|
||||
case "logLimit":
|
||||
storage[key] = Number(value);
|
||||
break;
|
||||
default:
|
||||
storage[key] = value;
|
||||
storage[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,6 +213,8 @@ function initSettings()
|
||||
storage.contextMenuEnabled = true;
|
||||
storage.historyListenerEnabled = true;
|
||||
storage.localHostsSkipping = true;
|
||||
storage.referralMarketing = false;
|
||||
storage.logLimit = -1;
|
||||
|
||||
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"];
|
||||
|
||||
@@ -75,19 +75,13 @@ async function checkOSAndroid()
|
||||
});
|
||||
}
|
||||
|
||||
if(os == "android")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
return false;
|
||||
}
|
||||
return os === "android";
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the host without port from an url.
|
||||
* @param {String} url URL as String
|
||||
* @return {Array} host as string
|
||||
* @return {String} host as string
|
||||
*/
|
||||
function extractHost(url) {
|
||||
let parsed_url = new URL(url);
|
||||
@@ -126,8 +120,8 @@ function countFields(url)
|
||||
*/
|
||||
function existsFields(url)
|
||||
{
|
||||
var matches = (url.match(/\?.+/i) || []);
|
||||
var count = matches.length;
|
||||
let matches = (url.match(/\?.+/i) || []);
|
||||
let count = matches.length;
|
||||
|
||||
return (count > 0);
|
||||
}
|
||||
@@ -140,7 +134,7 @@ function existsFields(url)
|
||||
function extractFileds(url)
|
||||
{
|
||||
if(existsFields(url)) {
|
||||
var fields = url.replace(new RegExp(".*?\\?", "i"), "");
|
||||
let fields = url.replace(new RegExp(".*?\\?", "i"), "");
|
||||
if(existsFragments(url)) {
|
||||
fields = fields.replace(new RegExp("#.*", "i"), "");
|
||||
}
|
||||
@@ -169,7 +163,7 @@ function countFragments(url)
|
||||
function extractFragments(url)
|
||||
{
|
||||
if(existsFragments(url)) {
|
||||
var fragments = url.replace(new RegExp(".*?#", "i"), "");
|
||||
let fragments = url.replace(new RegExp(".*?#", "i"), "");
|
||||
return (fragments.match(/[^&]+=?[^&]*/gi) || []);
|
||||
}
|
||||
|
||||
@@ -183,8 +177,8 @@ function extractFragments(url)
|
||||
*/
|
||||
function existsFragments(url)
|
||||
{
|
||||
var matches = (url.match(/\#.+/i) || []);
|
||||
var count = matches.length;
|
||||
let matches = (url.match(/\#.+/i) || []);
|
||||
let count = matches.length;
|
||||
|
||||
return (count > 0);
|
||||
}
|
||||
@@ -298,3 +292,16 @@ function getBrowser() {
|
||||
return "Chrome";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes an URL, also one that is encoded multiple times.
|
||||
* @param url the url, that should be decoded
|
||||
*/
|
||||
function decodeURL(url) {
|
||||
const rtn = decodeURIComponent(url);
|
||||
if(rtn.indexOf("http://") === -1 && rtn.indexOf("https://") === -1) {
|
||||
return decodeURL(rtn);
|
||||
}
|
||||
|
||||
return rtn;
|
||||
}
|
||||
38
core_js/watchdog.js
Normal file
38
core_js/watchdog.js
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*jshint esversion: 6 */
|
||||
/*
|
||||
* This script is responsible to check in fixed intervals, that ClearURLs works properly.
|
||||
* In issue #203, some users reported, that ClearURLs filter function doesn't work after
|
||||
* some time, but without any recognizable reason.
|
||||
*
|
||||
* This watchdog restarts the whole Add-on, when the check fails.
|
||||
*/
|
||||
const CHECK_INTERVAL = 15000;
|
||||
|
||||
setInterval(function() {
|
||||
const dirtyURL = "https://clearurls.roebert.eu?utm_source=addon";
|
||||
const cleanURL = "https://clearurls.roebert.eu";
|
||||
|
||||
if(pureCleaning(dirtyURL, true) !== cleanURL) {
|
||||
console.log(translate('watchdog'));
|
||||
saveOnExit();
|
||||
reload();
|
||||
}
|
||||
}, CHECK_INTERVAL);
|
||||
@@ -20,5 +20,5 @@
|
||||
* This file writes only the version into every page.
|
||||
* @return version
|
||||
*/
|
||||
var version = browser.runtime.getManifest().version;
|
||||
const version = browser.runtime.getManifest().version;
|
||||
$('#version').text(version);
|
||||
|
||||
Reference in New Issue
Block a user