diff --git a/_locales/de/messages.json b/_locales/de/messages.json index 163ddba..1540c25 100644 --- a/_locales/de/messages.json +++ b/_locales/de/messages.json @@ -247,5 +247,9 @@ "donate_button": { "message": "Eine Spende (Schenkung) für den ClearURLs Urheber.", "description": "" + }, + "clipboard.copy-link": { + "message": "Link-Adresse kopieren", + "description": "" } } diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 4bc0c9a..0ac5e94 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -247,5 +247,9 @@ "donate_button": { "message": "A donation for the ClearURLs creator.", "description": "" + }, + "clipboard.copy-link": { + "message": "Copy Link Location", + "description": "" } } diff --git a/clearurls.js b/clearurls.js index afec71b..514ee83 100644 --- a/clearurls.js +++ b/clearurls.js @@ -31,6 +31,129 @@ var os; var currentURL; var lastVisited = ""; +/** +* Helper function which remove the tracking fields +* for each provider given as parameter. +* +* @param {Provider} provider Provider-Object +* @return {Array} Array with changes and url fields +*/ +function removeFieldsFormURL(provider, pureUrl) +{ + var url = pureUrl; + var domain = url.replace(new RegExp("\\?.*", "i"), ""); + var fields = ""; + var rules = provider.getRules(); + var changes = false; + var cancel = false; + + /* + * Expand the url by provider redirections. So no tracking on + * url redirections form sites to sites. + */ + var re = provider.getRedirection(url); + if(re !== null) + { + url = decodeURIComponent(re); + //Log the action + pushToLog(pureUrl, url, translate('log_redirect')); + + return { + "redirect": true, + "url": url + }; + } + + /** + * Only test for matches, if there are fields that can be cleaned. + */ + if(existsFields(url)) + { + /** + * It must be non-greedy, because by default .* will match + * all ? chars. So the replace function delete everything + * before the last ?. With adding a ? on the quantifier *, + * we fixed this problem. + */ + fields = "?"+url.replace(new RegExp(".*?\\?", "i"), ""); + + rules.forEach(function(rule) { + var beforReplace = fields; + fields = fields.replace(new RegExp(rule, "gi"), ""); + + if(beforReplace !== fields) + { + //Log the action + if(storage.loggingStatus) + { + pushToLog(domain+beforReplace, domain+"?"+extractFileds(fields).rmEmpty().join("&"), rule); + } + + if(badges[tabid] == null) badges[tabid] = 0; + + increaseURLCounter(); + + if(!checkOSAndroid()) + { + if(storage.badgedStatus) { + browser.browserAction.setBadgeText({text: (++badges[tabid]).toString(), tabId: tabid}); + } + else + { + browser.browserAction.setBadgeText({text: "", tabId: tabid}); + } + } + changes = true; + } + }); + + var finalFields = extractFileds(fields).rmEmpty(); + if(finalFields.length > 0) + { + url = domain+"?"+finalFields.join("&"); + } + else{ + url = domain; + } + } + else { + if(domain != url) + { + url = domain; + changes = true; + } + } + + if(provider.isCaneling()){ + pushToLog(pureUrl, pureUrl, translate('log_domain_blocked')); + if(badges[tabid] == null) + { + badges[tabid] = 0; + } + + increaseURLCounter(); + + if(!checkOSAndroid()) + { + if(storage.badgedStatus) { + browser.browserAction.setBadgeText({text: (++badges[tabid]).toString(), tabId: tabid}); + } + else + { + browser.browserAction.setBadgeText({text: "", tabId: tabid}); + } + } + + cancel = true; + } + + return { + "changes": changes, + "url": url, + "cancel": cancel + }; +} + function start() { /** @@ -367,130 +490,6 @@ function start() } // ################################################################## - /** - * Helper function which remove the tracking fields - * for each provider given as parameter. - * - * @param {Provider} provider Provider-Object - * @param {webRequest} request webRequest-Object - * @return {Array} Array with changes and url fields - */ - function removeFieldsFormURL(provider, request) - { - var url = request.url; - var domain = url.replace(new RegExp("\\?.*", "i"), ""); - var fields = ""; - var rules = provider.getRules(); - var changes = false; - var cancel = false; - - /* - * Expand the url by provider redirections. So no tracking on - * url redirections form sites to sites. - */ - var re = provider.getRedirection(url); - if(re !== null) - { - url = decodeURIComponent(re); - //Log the action - pushToLog(request.url, url, translate('log_redirect')); - - return { - "redirect": true, - "url": url - }; - } - - /** - * Only test for matches, if there are fields that can be cleaned. - */ - if(existsFields(url)) - { - /** - * It must be non-greedy, because by default .* will match - * all ? chars. So the replace function delete everything - * before the last ?. With adding a ? on the quantifier *, - * we fixed this problem. - */ - fields = "?"+url.replace(new RegExp(".*?\\?", "i"), ""); - - rules.forEach(function(rule) { - var beforReplace = fields; - fields = fields.replace(new RegExp(rule, "gi"), ""); - - if(beforReplace !== fields) - { - //Log the action - if(storage.loggingStatus) - { - pushToLog(domain+beforReplace, domain+"?"+extractFileds(fields).rmEmpty().join("&"), rule); - } - - if(badges[tabid] == null) badges[tabid] = 0; - - increaseURLCounter(); - - if(!checkOSAndroid()) - { - if(storage.badgedStatus) { - browser.browserAction.setBadgeText({text: (++badges[tabid]).toString(), tabId: tabid}); - } - else - { - browser.browserAction.setBadgeText({text: "", tabId: tabid}); - } - } - changes = true; - } - }); - - var finalFields = extractFileds(fields).rmEmpty(); - if(finalFields.length > 0) - { - url = domain+"?"+finalFields.join("&"); - } - else{ - url = domain; - } - } - else { - if(domain != url) - { - url = domain; - changes = true; - } - } - - if(provider.isCaneling()){ - pushToLog(request.url, request.url, translate('log_domain_blocked')); - if(badges[tabid] == null) - { - badges[tabid] = 0; - } - - increaseURLCounter(); - - if(!checkOSAndroid()) - { - if(storage.badgedStatus) { - browser.browserAction.setBadgeText({text: (++badges[tabid]).toString(), tabId: tabid}); - } - else - { - browser.browserAction.setBadgeText({text: "", tabId: tabid}); - } - } - - cancel = true; - } - - return { - "changes": changes, - "url": url, - "cancel": cancel - }; - } - /** * Function which called from the webRequest to * remove the tracking fields from the url. @@ -525,7 +524,7 @@ function start() if(providers[i].matchURL(request.url)) { - result = removeFieldsFormURL(providers[i], request); + result = removeFieldsFormURL(providers[i], request.url); } /* @@ -566,31 +565,6 @@ function start() return {}; } - /** - * Function to log all activities from ClearUrls. - * Only logging when activated. - * The log is only temporary saved in the cache and will - * permanently saved with the saveLogOnClose function. - * - * @param beforeProcessing the url before the clear process - * @param afterProcessing the url after the clear process - * @param rule the rule that triggered the process - */ - function pushToLog(beforeProcessing, afterProcessing, rule) - { - if(storage.loggingStatus) - { - storage.log.log.push( - { - "before": beforeProcessing, - "after": afterProcessing, - "rule": rule, - "timestamp": Date.now() - } - ); - } - } - /** * Call loadOldDataFromStore, getHash, counter, status and log functions */ @@ -671,3 +645,28 @@ function start() ); }); } + +/** +* Function to log all activities from ClearUrls. +* Only logging when activated. +* The log is only temporary saved in the cache and will +* permanently saved with the saveLogOnClose function. +* +* @param beforeProcessing the url before the clear process +* @param afterProcessing the url after the clear process +* @param rule the rule that triggered the process +*/ +function pushToLog(beforeProcessing, afterProcessing, rule) +{ + if(storage.loggingStatus) + { + storage.log.log.push( + { + "before": beforeProcessing, + "after": afterProcessing, + "rule": rule, + "timestamp": Date.now() + } + ); + } +} diff --git a/core_js/context_menu.js b/core_js/context_menu.js new file mode 100644 index 0000000..21c6058 --- /dev/null +++ b/core_js/context_menu.js @@ -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 . +*/ + +/*jshint esversion: 6 */ +/* +* This script is responsible for context menu cleaning functions. +*/ + +browser.contextMenus.create({ + id: "copy-link-to-clipboard", + title: translate("clipboard.copy-link"), + contexts: ["link"], + icons: { + "16": "img/clearurls_16x16.png", + "19": "img/clearurls_19x19.png", + "20": "img/clearurls_20x20.png", + "24": "img/clearurls_24x24.png", + "30": "img/clearurls_30x30.png", + "32": "img/clearurls_32x32.png", + "38": "img/clearurls_38x38.png", + "48": "img/clearurls_48x48.png", + "64": "img/clearurls_64x64.png", + "96": "img/clearurls_96x96.png", + "128": "img/clearurls_128x128.png" + } +}); + +browser.contextMenus.onClicked.addListener((info, tab) => { + if (info.menuItemId === "copy-link-to-clipboard") { + const url = contextCleaning(info.linkUrl); + navigator.clipboard.writeText(url).then(() => { + console.log("[ClearURLs] Copied cleaned url to clipboard."); + }); + } +}); + +/** +* 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; +} diff --git a/manifest.json b/manifest.json index 18131db..040bcdf 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 2, "name": "ClearURLs", - "version": "1.5.4", + "version": "1.5.5", "author": "Kevin R.", "description": "Remove tracking elements form URLs.", "homepage_url": "https://gitlab.com/KevinRoebert/ClearUrls", @@ -48,7 +48,9 @@ "webRequest", "webRequestBlocking", "storage", - "unlimitedStorage" + "unlimitedStorage", + "contextMenus", + "clipboardWrite" ], "background": { "scripts": [ @@ -58,7 +60,8 @@ "core_js/message_handler.js", "core_js/tools.js", "core_js/storage.js", - "clearurls.js" + "clearurls.js", + "core_js/context_menu.js" ] }, "content_scripts": [