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:
Kevin Röbert 2019-04-11 16:40:48 +02:00
parent a76ecb17b3
commit 91d46a7b70
15 changed files with 605 additions and 153 deletions

View File

@ -4,6 +4,29 @@ 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.6] - 2019-04-11
### Compatibility note
- Require Firefox >= 55
- Require Chrome >= 28
### Added
- 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
- [#103](https://gitlab.com/KevinRoebert/ClearUrls/issues/103), see also https://curl.kevinroebert.de
### Changed
- 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)
## [[1.5.8] - 2019-04-10](https://gitlab.com/KevinRoebert/ClearUrls/commit/1b6cc37bdd23011d006bf7ef6824463e7c96067a)
### Compatibility note

View File

@ -249,7 +249,35 @@
"description": ""
},
"clipboard_copy_link": {
"message": "Link-Adresse kopieren",
"message": "Gesäuberte Link-Adresse kopieren",
"description": ""
},
"context_menu_enabled": {
"message": "Kontextmenü-Eintrag anzeigen",
"description": ""
},
"history_listener_enabled": {
"message": "Verhindere Tracking über die History-API (Siehe auch: <a href='https://developer.mozilla.org/en-US/docs/Web/API/History_API#The_pushState()_method' target='_blank'>The pushState() method</a>)",
"description": ""
},
"cleaning_tool_page_title": {
"message": "Säuberungswerkzeug von ClearURLs",
"description": ""
},
"cleaning_tool_description": {
"message": "Mit diesem Werkzeug können Sie URLs in die Textbox einfügen. Nach einem klick auf den grünen Button reinigt ClearURLs die Links. Sie können mehrer URLs auf einmal einfügen, jede URL muss aber in einer eigenen Zeile stehen.",
"description": ""
},
"cleaning_tool_btn": {
"message": "URLs säubern",
"description": ""
},
"cleaning_tool_dirty_urls_label": {
"message": "Hier können Sie die ungesäuberten URLs einfügen:",
"description": ""
},
"cleaning_tool_clean_urls_label": {
"message": "Hier finden Sie die gesäuberten URLs:",
"description": ""
}
}

View File

@ -249,7 +249,35 @@
"description": ""
},
"clipboard_copy_link": {
"message": "Copy Link Location",
"message": "Copy Clean Link Location",
"description": ""
},
"context_menu_enabled": {
"message": "Display context menu entry",
"description": ""
},
"history_listener_enabled": {
"message": "Prevent tracking injection over history API (See also: <a href='https://developer.mozilla.org/en-US/docs/Web/API/History_API#The_pushState()_method' target='_blank'>The pushState() method</a>)",
"description": ""
},
"cleaning_tool_page_title": {
"message": "Cleaning tool from ClearURLs",
"description": ""
},
"cleaning_tool_description": {
"message": "With this tool you can paste in URLs and ClearURLs will cleaned the URLs after a click on the green button. You can paste in multiple URLs at once, but every URL must be in a separate line.",
"description": ""
},
"cleaning_tool_btn": {
"message": "Clean URLs",
"description": ""
},
"cleaning_tool_dirty_urls_label": {
"message": "Here you can paste in the dirty URLs:",
"description": ""
},
"cleaning_tool_clean_urls_label": {
"message": "Here you can find the cleaned URLs:",
"description": ""
}
}

81
core_js/cleaning_tool.js Normal file
View 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}`);
}

View File

@ -22,6 +22,8 @@
* and based on: https://github.com/mdn/webextensions-examples/tree/master/context-menu-copy-link-with-types
*/
function contextMenuStart() {
if(storage.contextMenuEnabled) {
browser.contextMenus.create({
id: "copy-link-to-clipboard",
title: translate("clipboard_copy_link"),
@ -30,7 +32,7 @@ browser.contextMenus.create({
browser.contextMenus.onClicked.addListener((info, tab) => {
if (info.menuItemId === "copy-link-to-clipboard") {
const url = contextCleaning(info.linkUrl);
const url = pureCleaning(info.linkUrl);
const code = "copyToClipboard(" +
JSON.stringify(url)+");";
@ -39,7 +41,7 @@ browser.contextMenus.onClicked.addListener((info, tab) => {
}).then((results) => {
if (!results || results[0] !== true) {
return browser.tabs.executeScript(tab.id, {
file: "external_js/clipboard-helper.js",
file: "/external_js/clipboard-helper.js",
});
}
}).then(() => {
@ -51,40 +53,5 @@ browser.contextMenus.onClicked.addListener((info, tab) => {
});
}
});
/**
* 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;
}

View 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}`);
}

View File

@ -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
View 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;
}

View File

@ -148,6 +148,23 @@ 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);
}
/**
@ -165,6 +182,8 @@ 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'));
}
/**
@ -184,3 +203,68 @@ function handleResponse(message) {
function handleError(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]);
}

View File

@ -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":

View File

@ -191,11 +191,14 @@
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(facebook)(\\.[a-zA-Z]{2,})(.*\\?.*)",
"completeProvider": false,
"rules": [
"hc_[a-zA-Z_\\[\\]0-9]*",
"hc_[a-zA-Z_%\\[\\]0-9]*",
"[a-zA-Z]*ref[a-zA-Z]*",
"__tn__",
"eid",
"__xts__%5B[0-9]%5D"
"__xts__%5B[0-9]%5D",
"__xts__\\[[0-9]\\]",
"comment_tracking",
"dti"
],
"exceptions": [
".*(facebook\\.)\\w{2,}.*(\\/plugins\\/).*"
@ -439,6 +442,16 @@
],
"exceptions": [],
"redirections": []
},
"mozilla.org": {
"urlPattern": "https?://([a-zA-Z0-9-]*\\.)?(mozilla\\.org)(.*\\?.*)",
"completeProvider": false,
"rules": [
"src",
"platform"
],
"exceptions": [],
"redirections": []
}
}
}

87
html/cleaningTool.html Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<title>Cleaning tool from ClearURLs</title>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" sizes="any" type="image/svg+xml" href="/img/clearurls.svg">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="../css/bootstrap.min.css">
<link rel="stylesheet" href="../css/dataTables.bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="../css/core.css">
<style>
td {
word-wrap: break-word;
max-width: 200px;
}
</style>
</head>
<body>
<nav class="navbar navbar-inverse">
<div class="container">
<div class="navbar-header">
<span class="navbar-brand">
<span class="pull-left"><img src="../img/clearurls.svg"
width="30" height="30" alt=""></span>
<span style="color: #FF7800;" class="pull-right" id="page_title"></span><br />
<span class="label label-warning pull-left small-version"
id="version"></span>
</span>
</div>
</div>
</nav>
<div class="row">
<div class="col-md-4 col-md-offset-4 text-center">
<h4 id="cleaning_tool_description"></h4>
<br />
<div class="form-group">
<label for="dirtyURLs" id="cleaning_tool_dirty_urls_label"></label>
<textarea id="dirtyURLs" name="dirtyURLs" class="form-control" rows="8" cols="60"></textarea>
</div>
<br />
<p class="text-center">
<button type="button" id="cleaning_tool_btn"
class="btn btn-success" title="Clean the URLs"></button>
</p>
<br />
<div class="form-group">
<label for="cleanURLs" id="cleaning_tool_clean_urls_label"></label>
<textarea id="cleanURLs" name="cleanURLs" class="form-control" rows="8" cols="60" readonly></textarea>
</div>
</div>
</div>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="../browser-polyfill.js"></script>
<script src="../external_js/jquery-3.2.1.min.js"></script>
<script src="../external_js/bootstrap.min.js"></script>
<script src="../core_js/cleaning_tool.js"></script>
<script src="../core_js/write_version.js"></script>
</body>
</html>

View File

@ -57,8 +57,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
</div>
<div id="dialog"></div>
<div class="row" id="config_section">
<div class="col-sm-1 text-center">
<a id="cleaning_tools" target="_blank"><span class="glyphicon glyphicon-wrench" style="font-size: 1.5em; margin-right: 1em;"></span></a>
<a id="settings" target="_blank"><span class="glyphicon glyphicon-cog" style="font-size: 1.5em"></span></a>
</div>
<div class="col-sm-1">
<a id="settings" target="_blank"><span class="pull-right glyphicon glyphicon-cog"></span></a>
<h5><b id="configs_head"></b></h5>
<label class="switch">
<input type="checkbox" id="globalStatus">

View File

@ -29,6 +29,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="../css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="../css/switchButtons.css">
<link rel="stylesheet" type="text/css" href="../css/core.css">
<link rel="stylesheet" href="../css/pick-a-color-1.2.3.min.css">
<style>
@ -79,6 +80,22 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<p>
<label id="types_label"></label><br />
<input type="text" id="types" value="" name="types" class="form-control" />
<br />
<label id="context_menu_enabled" style="font-weight: bold;"></label><br />
<label class="switch">
<input type="checkbox" id="contextMenuEnabled">
<span class="slider round"></span>
</label>
</p>
<br />
<p>
<label id="history_listener_enabled" style="font-weight: bold;"></label><br />
<label class="switch">
<input type="checkbox" id="historyListenerEnabled">
<span class="slider round"></span>
</label>
</p>
<br />
<p class="text-center">

View File

@ -1,7 +1,7 @@
{
"manifest_version": 2,
"name": "ClearURLs",
"version": "1.5.8",
"version": "1.6",
"author": "Kevin R.",
"description": "Remove tracking elements form URLs.",
"homepage_url": "https://gitlab.com/KevinRoebert/ClearUrls",
@ -50,7 +50,9 @@
"storage",
"unlimitedStorage",
"contextMenus",
"clipboardWrite"
"clipboardWrite",
"webNavigation",
"tabs"
],
"background": {
"scripts": [
@ -61,7 +63,9 @@
"core_js/tools.js",
"core_js/storage.js",
"clearurls.js",
"core_js/context_menu.js"
"core_js/pureCleaning.js",
"core_js/context_menu.js",
"core_js/historyListener.js"
]
},
"content_scripts": [