mirror of
https://gitlab.com/KevinRoebert/ClearUrls
synced 2025-12-16 06:05:37 +07:00
ClearURLs v.1.6
- Added listener to the browser history to prevent tracking with the [history.pushState method](https://developer.mozilla.org/en-US/docs/Web/API/History_API) - Added webNavigation and tabs permissions, for the new feature - Added switches in settings to enable and disable the context menu entry and the history listener - Added tool to clean URLs, that was pasted into a textbox - Added icon for new tool to clean URLs - Fixed [#40](https://gitlab.com/KevinRoebert/ClearUrls/issues/40), see also https://curl.kevinroebert.de - Fixed [#103](https://gitlab.com/KevinRoebert/ClearUrls/issues/103), see also https://curl.kevinroebert.de - Changed clipboard-helper.js path to be absolute to prevent problems - Changed rewrite of old GitHub links to the new data.min.json and rules.min.hash - Config icon is now bigger and above the config label - Update Traditional Chinese Translation by [@yipinghuang](https://gitlab.com/yipinghuang) #161 #162 #157 #40 #103 #158
This commit is contained in:
81
core_js/cleaning_tool.js
Normal file
81
core_js/cleaning_tool.js
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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 */
|
||||
var cleanedURLs = [];
|
||||
var i = 0;
|
||||
var length = 0;
|
||||
|
||||
/**
|
||||
* Load only when document is ready
|
||||
*/
|
||||
$(document).ready(function(){
|
||||
setText();
|
||||
$('#cleaning_tool_btn').on("click", cleanURLs);
|
||||
});
|
||||
|
||||
/**
|
||||
* 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');
|
||||
cleanedURLs = [];
|
||||
length = urls.length;
|
||||
|
||||
for(i=0; i < length; i++) {
|
||||
browser.runtime.sendMessage({
|
||||
function: "pureCleaning",
|
||||
params: [urls[i]]
|
||||
}).then((data) => {
|
||||
cleanedURLs.push(data.response);
|
||||
if(i >= length-1) {
|
||||
console.log("End of loop.");
|
||||
cleanTArea.val(cleanedURLs.join('\n'));
|
||||
}
|
||||
}, handleError);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text for the UI.
|
||||
*/
|
||||
function setText()
|
||||
{
|
||||
document.title = translate('cleaning_tool_page_title');
|
||||
$('#page_title').text(translate('cleaning_tool_page_title'));
|
||||
$('#cleaning_tool_description').text(translate('cleaning_tool_description'));
|
||||
$('#cleaning_tool_btn').text(translate('cleaning_tool_btn'));
|
||||
$('#cleaning_tool_dirty_urls_label').text(translate('cleaning_tool_dirty_urls_label'));
|
||||
$('#cleaning_tool_clean_urls_label').text(translate('cleaning_tool_clean_urls_label'));
|
||||
}
|
||||
|
||||
function handleError(error) {
|
||||
console.log(`Error: ${error}`);
|
||||
}
|
||||
@@ -22,69 +22,36 @@
|
||||
* and based on: https://github.com/mdn/webextensions-examples/tree/master/context-menu-copy-link-with-types
|
||||
*/
|
||||
|
||||
browser.contextMenus.create({
|
||||
id: "copy-link-to-clipboard",
|
||||
title: translate("clipboard_copy_link"),
|
||||
contexts: ["link"]
|
||||
});
|
||||
function contextMenuStart() {
|
||||
if(storage.contextMenuEnabled) {
|
||||
browser.contextMenus.create({
|
||||
id: "copy-link-to-clipboard",
|
||||
title: translate("clipboard_copy_link"),
|
||||
contexts: ["link"]
|
||||
});
|
||||
|
||||
browser.contextMenus.onClicked.addListener((info, tab) => {
|
||||
if (info.menuItemId === "copy-link-to-clipboard") {
|
||||
const url = contextCleaning(info.linkUrl);
|
||||
const code = "copyToClipboard(" +
|
||||
JSON.stringify(url)+");";
|
||||
browser.contextMenus.onClicked.addListener((info, tab) => {
|
||||
if (info.menuItemId === "copy-link-to-clipboard") {
|
||||
const url = pureCleaning(info.linkUrl);
|
||||
const code = "copyToClipboard(" +
|
||||
JSON.stringify(url)+");";
|
||||
|
||||
browser.tabs.executeScript({
|
||||
code: "typeof copyToClipboard === 'function';",
|
||||
}).then((results) => {
|
||||
if (!results || results[0] !== true) {
|
||||
return browser.tabs.executeScript(tab.id, {
|
||||
file: "external_js/clipboard-helper.js",
|
||||
browser.tabs.executeScript({
|
||||
code: "typeof copyToClipboard === 'function';",
|
||||
}).then((results) => {
|
||||
if (!results || results[0] !== true) {
|
||||
return browser.tabs.executeScript(tab.id, {
|
||||
file: "/external_js/clipboard-helper.js",
|
||||
});
|
||||
}
|
||||
}).then(() => {
|
||||
return browser.tabs.executeScript(tab.id, {
|
||||
code,
|
||||
});
|
||||
}).catch((error) => {
|
||||
console.error("Failed to copy text: " + error);
|
||||
});
|
||||
}
|
||||
}).then(() => {
|
||||
return browser.tabs.executeScript(tab.id, {
|
||||
code,
|
||||
});
|
||||
}).catch((error) => {
|
||||
console.error("Failed to copy text: " + error);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Cleans links for the context menue. Also do automatic redirection.
|
||||
*
|
||||
* @param {[type]} url url as string
|
||||
* @return {Array} redirectUrl or none
|
||||
*/
|
||||
function contextCleaning(url) {
|
||||
// The URL is already cleaned
|
||||
if(lastVisited === url) {
|
||||
return url;
|
||||
}
|
||||
|
||||
var cleanURL = url;
|
||||
|
||||
for (var i = 0; i < providers.length; i++) {
|
||||
var result = {
|
||||
"changes": false,
|
||||
"url": "",
|
||||
"redirect": false,
|
||||
"cancel": false
|
||||
};
|
||||
|
||||
if(providers[i].matchURL(cleanURL))
|
||||
{
|
||||
result = removeFieldsFormURL(providers[i], cleanURL);
|
||||
cleanURL = result.url;
|
||||
}
|
||||
|
||||
if(result.redirect)
|
||||
{
|
||||
return result.url;
|
||||
}
|
||||
}
|
||||
|
||||
return cleanURL;
|
||||
}
|
||||
|
||||
53
core_js/historyListener.js
Normal file
53
core_js/historyListener.js
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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 listen on history changes.
|
||||
* This technique is often used to inject tracking code into the location bar,
|
||||
* because all feature events will use the updated URL.
|
||||
*/
|
||||
|
||||
function historyListenerStart() {
|
||||
if(storage.historyListenerEnabled) {
|
||||
browser.webNavigation.onHistoryStateUpdated.addListener(historyCleaner);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function that is triggered on history changes. Injects script into page
|
||||
* to clean links that were pushed to the history stack with the
|
||||
* history.pushState method.
|
||||
* @param {state object} details The state object is a JavaScript object
|
||||
* which is associated with the new history entry created by pushState()
|
||||
*/
|
||||
function historyCleaner(details) {
|
||||
var urlBefore = details.url;
|
||||
var urlAfter = pureCleaning(details.url);
|
||||
|
||||
if(urlBefore != urlAfter) {
|
||||
browser.tabs.executeScript(details.tabId, {
|
||||
frameId: details.frameId,
|
||||
code: 'history.pushState({state: "cleaned_history"},"",'+JSON.stringify(urlAfter)+');'
|
||||
}).then(() => {}, onError);
|
||||
}
|
||||
}
|
||||
|
||||
function onError(error) {
|
||||
console.log(`[ClearURLs] Error: ${error}`);
|
||||
}
|
||||
@@ -250,6 +250,7 @@ $(document).ready(function(){
|
||||
changeSwitchButton("statistics", "statisticsStatus");
|
||||
$('#loggingPage').attr('href', browser.extension.getURL('./html/log.html'));
|
||||
$('#settings').attr('href', browser.extension.getURL('./html/settings.html'));
|
||||
$('#cleaning_tools').attr('href', browser.extension.getURL('./html/cleaningTool.html'));
|
||||
setText();
|
||||
});
|
||||
|
||||
@@ -272,7 +273,6 @@ function setText()
|
||||
injectText('configs_switch_filter','popup_html_configs_switch_filter');
|
||||
injectText('configs_head','popup_html_configs_head');
|
||||
injectText('configs_switch_statistics','configs_switch_statistics');
|
||||
injectText('reportButton', 'popup_html_report_button', true);
|
||||
$('#donate').prop('title', translate('donate_button'));
|
||||
}
|
||||
|
||||
|
||||
56
core_js/pureCleaning.js
Normal file
56
core_js/pureCleaning.js
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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 */
|
||||
|
||||
/**
|
||||
* Cleans given links. Also do automatic redirection.
|
||||
*
|
||||
* @param {[type]} url url as string
|
||||
* @return {Array} redirectUrl or none
|
||||
*/
|
||||
function pureCleaning(url) {
|
||||
// The URL is already cleaned
|
||||
if(lastVisited === url) {
|
||||
return url;
|
||||
}
|
||||
|
||||
var cleanURL = url;
|
||||
|
||||
for (var i = 0; i < providers.length; i++) {
|
||||
var result = {
|
||||
"changes": false,
|
||||
"url": "",
|
||||
"redirect": false,
|
||||
"cancel": false
|
||||
};
|
||||
|
||||
if(providers[i].matchURL(cleanURL))
|
||||
{
|
||||
result = removeFieldsFormURL(providers[i], cleanURL);
|
||||
cleanURL = result.url;
|
||||
}
|
||||
|
||||
if(result.redirect)
|
||||
{
|
||||
return result.url;
|
||||
}
|
||||
}
|
||||
|
||||
return cleanURL;
|
||||
}
|
||||
@@ -1,20 +1,20 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
var settings = [];
|
||||
|
||||
@@ -50,9 +50,9 @@ $(document).ready(function(){
|
||||
});
|
||||
|
||||
/**
|
||||
* Reset everything.
|
||||
* Set everthing to the default values.
|
||||
*/
|
||||
* Reset everything.
|
||||
* Set everthing to the default values.
|
||||
*/
|
||||
function reset()
|
||||
{
|
||||
browser.runtime.sendMessage({
|
||||
@@ -72,8 +72,8 @@ function reset()
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the settings.
|
||||
*/
|
||||
* Saves the settings.
|
||||
*/
|
||||
function save()
|
||||
{
|
||||
browser.runtime.sendMessage({
|
||||
@@ -125,8 +125,8 @@ function translate(string)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data.
|
||||
*/
|
||||
* Get the data.
|
||||
*/
|
||||
function getData()
|
||||
{
|
||||
browser.runtime.sendMessage({
|
||||
@@ -148,11 +148,28 @@ function getData()
|
||||
function: "getData",
|
||||
params: ["types"]
|
||||
}).then((data) => handleResponseData(data, "types", "types"), handleError);
|
||||
|
||||
browser.runtime.sendMessage({
|
||||
function: "getData",
|
||||
params: ["contextMenuEnabled"]
|
||||
}).then((data) => {
|
||||
handleResponseData(data, "contextMenuEnabled", "contextMenuEnabled");
|
||||
browser.runtime.sendMessage({
|
||||
function: "getData",
|
||||
params: ["historyListenerEnabled"]
|
||||
}).then((data) => {
|
||||
handleResponseData(data, "historyListenerEnabled", "historyListenerEnabled");
|
||||
changeSwitchButton("contextMenuEnabled", "contextMenuEnabled");
|
||||
changeSwitchButton("historyListenerEnabled", "historyListenerEnabled");
|
||||
}, handleError);
|
||||
}, handleError);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text for the UI.
|
||||
*/
|
||||
* Set the text for the UI.
|
||||
*/
|
||||
function setText()
|
||||
{
|
||||
document.title = translate('settings_html_page_title');
|
||||
@@ -165,12 +182,14 @@ function setText()
|
||||
$('#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'));
|
||||
injectText("context_menu_enabled", "context_menu_enabled");
|
||||
$('#history_listener_enabled').html(translate('history_listener_enabled'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the response from the storage and saves the data.
|
||||
* @param {JSON-Object} data Data JSON-Object
|
||||
*/
|
||||
* Handle the response from the storage and saves the data.
|
||||
* @param {JSON-Object} data Data JSON-Object
|
||||
*/
|
||||
function handleResponseData(data, varName, inputID)
|
||||
{
|
||||
settings[varName] = data.response;
|
||||
@@ -178,9 +197,74 @@ function handleResponseData(data, varName, inputID)
|
||||
}
|
||||
|
||||
function handleResponse(message) {
|
||||
console.log(`Message from the background script: ${message.response}`);
|
||||
console.log(`Message from the background script: ${message.response}`);
|
||||
}
|
||||
|
||||
function handleError(error) {
|
||||
console.log(`Error: ${error}`);
|
||||
console.log(`Error: ${error}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the value of a switch button.
|
||||
* @param {string} id HTML id
|
||||
* @param {string} storageID storage internal id
|
||||
*/
|
||||
function changeSwitchButton(id, storageID)
|
||||
{
|
||||
var element = $('#'+id);
|
||||
|
||||
element.on('change', function(){
|
||||
browser.runtime.sendMessage({
|
||||
function: "setData",
|
||||
params: [storageID, element.is(':checked')]
|
||||
}).then((data) => {
|
||||
if(storageID == "globalStatus"){
|
||||
browser.runtime.sendMessage({
|
||||
function: "changeIcon",
|
||||
params: []
|
||||
});
|
||||
}
|
||||
|
||||
browser.runtime.sendMessage({
|
||||
function: "saveOnExit",
|
||||
params: []
|
||||
});
|
||||
});
|
||||
});
|
||||
setSwitchButton(id, storageID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to inject the translated text and tooltip.
|
||||
*
|
||||
* @param {string} id ID of the HTML element
|
||||
* @param {string} attribute Name of the attribute used for localization
|
||||
* @param {boolean} tooltip
|
||||
*/
|
||||
function injectText(id, attribute, tooltip)
|
||||
{
|
||||
object = $('#'+id);
|
||||
object.text(translate(attribute));
|
||||
|
||||
/*
|
||||
This function will throw an error if no translation
|
||||
is found for the tooltip. This is a planned error.
|
||||
*/
|
||||
tooltip = translate(attribute+"_title");
|
||||
|
||||
if(tooltip != "")
|
||||
{
|
||||
object.prop('title', tooltip);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of a switch button.
|
||||
* @param {string} id HTML id
|
||||
* @param {string} varname js internal variable name
|
||||
*/
|
||||
function setSwitchButton(id, varname)
|
||||
{
|
||||
var element = $('#'+id);
|
||||
element.prop('checked', settings[varname]);
|
||||
}
|
||||
|
||||
@@ -132,6 +132,12 @@ function initStorage(items)
|
||||
|
||||
// Start the clearurls.js
|
||||
start();
|
||||
|
||||
// Start the context_menu
|
||||
contextMenuStart();
|
||||
|
||||
// Start history listener
|
||||
historyListenerStart();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -153,6 +159,8 @@ function initSettings()
|
||||
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.reportServer = "https://clearurls.xn--rb-fka.it";
|
||||
storage.contextMenuEnabled = true;
|
||||
storage.historyListenerEnabled = true;
|
||||
|
||||
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"];
|
||||
@@ -169,9 +177,9 @@ 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/raw/master/data/rules.hash";
|
||||
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.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";
|
||||
case "https://gitlab.com/KevinRoebert/ClearUrls/raw/master/data/data.json":
|
||||
|
||||
Reference in New Issue
Block a user