aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorGravatar Étienne Deparis 2020-09-20 16:12:13 +0200
committerGravatar Étienne Deparis 2020-09-20 16:12:13 +0200
commitc19cf73b1e444c7712fc57b3acac0e143f6c04bd (patch)
tree1f5c91a30a2c8334b537fe0380b5868765ff6fe2
parent2653c5825a5b71d12d16cbae5769ddeb9e686bd4 (diff)
parent726a4740115ded77c5090f479e3da526fa90e078 (diff)
downloadsimple_hinting-c19cf73b1e444c7712fc57b3acac0e143f6c04bd.tar.gz
simple_hinting-c19cf73b1e444c7712fc57b3acac0e143f6c04bd.tar.xz
simple_hinting-c19cf73b1e444c7712fc57b3acac0e143f6c04bd.zip
chore: Merge branch 'v0.5.3-dev' into masterv0.5.3
-rw-r--r--README.md27
-rw-r--r--css/hints.css8
-rw-r--r--js/background.js67
-rw-r--r--js/hints.js138
-rw-r--r--manifest.json2
-rw-r--r--package-lock.json35
-rw-r--r--package.json2
7 files changed, 149 insertions, 130 deletions
diff --git a/README.md b/README.md
index d515620..7326307 100644
--- a/README.md
+++ b/README.md
@@ -30,13 +30,28 @@ remove all green labels.
## Privacy
This addon try to protect your privacy by removing unwanted tracking
-attributes from the URL you are trying to go to. The list of the banned
-attributes is customizable in the addon options.
+parameters from the URL you are trying to go to. Another widespread
+privacy invading behavior consists by hiding real links behind a short
+link, which is responsible to track who click on which link, and
+when. In this later case, this addon call an [external web service][2],
+which will expand a tiny URL, before removing its tracking parameters,
+if any. That is why this addon ask for the permission to contact
+`unshorten.umaneti.net` host.
-In order to remove attributes from short URL (e.g. on Twitter), this
-addon call an [external web service][2], which is responsible for
-expanding this kind of links. The source code of this service is
-available [as a git repository][3].
+To avoid asking too frequently to this [same remote web service][2] what
+to do about a link, this addon will download from it two lists:
+
+- a list of known tracking parameters, which will help it to remove
+ them from already expanded URLs without having to contact the remote
+ service;
+- a list of known shorten URL services, for which this addons must
+ contact the remote web service to resolve and clean them.
+
+This two lists are then stored in your web browser addons storage area
+(hence the permission to use it).
+
+The source code of the previously mentioned external web service is
+[available][3] too.
## Credits
diff --git a/css/hints.css b/css/hints.css
index 55a6851..329f8dc 100644
--- a/css/hints.css
+++ b/css/hints.css
@@ -30,6 +30,14 @@
background-color: #E3FF38;
font-size: 15px;
}
+.sh_hint_match {
+ /* add !important to try to overwrite website settings */
+ color: #000000 !important;
+ background-color: #E3FF38 !important;
+ border: 1px solid #E3FF38 !important;
+ padding: 2px !important;
+ text-decoration: none;
+}
.sh_hint_view {
z-index: 999;
diff --git a/js/background.js b/js/background.js
index ee67900..12747cc 100644
--- a/js/background.js
+++ b/js/background.js
@@ -33,32 +33,23 @@ function injectJsAndCssIfNecessary(active_tab_id) {
/**
* Listener for events from the content scripts
*/
-var handled_links = 0;
-var last_update_badge = null;
function answerContentScriptRequests (request, sender) {
if (sender.id != "simple_hinting@umaneti.net") return;
- if (!request.url) return;
if (!request.type) request["type"] = "newtab";
+ if (request.type === "updatebadge") {
+ // Check with typeof as 0 is falsy, thus the badge is never updated
+ // to 0 with a simple check on the existence of request.message.
+ if (typeof(request.message) == "number" && sender.tab && sender.tab.id) {
+ browser.browserAction.setBadgeText(
+ { "text": request.message.toString(), "tabId": sender.tab.id });
+ }
+ return;
+ }
+ if (!request.url) return;
if (request.type === "newwin") {
browser.windows.create({ "url": request.url });
} else if (request.type === "incognito") {
browser.windows.create({ "url": request.url, "incognito": true });
- } else if (request.type === "updatebadge") {
- let now = Date.now()
- /* Some page may generate a lot of subcount we have to add for the
- * badge. But some time later, if the user want to recompute the
- * links, we should not add the new batch to the old one. 2 seconds
- * seems to be a good interval to differentiate machine from human.
- */
- if (last_update_badge && (now - last_update_badge) > 2000) {
- handled_links = 0;
- }
- last_update_badge = now;
- if (request.message && sender.tab && sender.tab.id) {
- handled_links += request.message;
- browser.browserAction.setBadgeText(
- { "text": handled_links.toString(), "tabId": sender.tab.id });
- }
} else {
browser.tabs.create({ "url": request.url });
}
@@ -112,3 +103,41 @@ browser.commands.onCommand.addListener(function(command) {
});
}
});
+
+
+/**
+ * Sync domains and params info
+ */
+function onError(error) {
+ console.error(`[Simple Hinting extension] ${error}`);
+}
+
+function fetchUnwantedParams() {
+ return fetch("https://unshorten.umaneti.net/params").then(function(response) {
+ return response.json();
+ }).then(function(upstream_params) {
+ browser.storage.local.set({ "unwanted_params": upstream_params });
+ }).catch(onError);
+}
+
+function fetchTinyDomains() {
+ return fetch("https://unshorten.umaneti.net/domains").then(function(response) {
+ return response.json();
+ }).then(function(upstream_tiny_domains) {
+ browser.storage.local.set({ "tiny_domains_list": upstream_tiny_domains });
+ }).catch(onError);
+}
+
+let opts = ["sync_dt"];
+browser.storage.local.get(opts).then(function (result) {
+ let last_sync = result.sync_dt || 0;
+ let one_week_in_ms = 7 * 24 * 60 * 60 * 1000;
+ let now_in_ms = Date.now();
+ if ((last_sync + one_week_in_ms) < now_in_ms) {
+ // Time to sync again
+ console.log("[Simple Hinting extension] Synchronizing now params and domains.");
+ fetchTinyDomains();
+ fetchUnwantedParams();
+ browser.storage.local.set({ "sync_dt": now_in_ms });
+ }
+}, onError);
diff --git a/js/hints.js b/js/hints.js
index 20c6e8f..4b0ea6a 100644
--- a/js/hints.js
+++ b/js/hints.js
@@ -13,41 +13,18 @@ const actionkeys = {
"a": "cleanall"
};
-function onError(error) {
- let message = `[Simple Hinting extension] ${error}`;
- let pref_msg_status = document.getElementById("save-status");
- if (pref_msg_status) {
- pref_msg_status.textContent = message;
- pref_msg_status.style.color = "red";
- } else {
- console.error(message);
- }
-}
-
-var unwanted_params = [];
-function fetchUnwantedParams() {
- return fetch("https://unshorten.umaneti.net/params").then(
- function(response) {
- return response.json();
- }, onError
- ).then(
- function(upstream_params) {
- unwanted_params = upstream_params;
- browser.storage.local.set({ "unwanted_params": unwanted_params });
- }, onError
- );
+// Cleaned links counter
+var clean_links_counter = 0;
+function reset_links_counter() {
+ clean_links_counter = 0;
+ browser.runtime.sendMessage({ "message": 0, "type": "updatebadge" });
}
-var tiny_domains = [];
-function fetchTinyDomains() {
- return fetch("https://unshorten.umaneti.net/domains").then(
- function(response) {
- return response.json();
- }, onError
- ).then(function(upstream_tiny_domains) {
- tiny_domains = upstream_tiny_domains;
- browser.storage.local.set({ "tiny_domains_list": tiny_domains });
- }, onError);
+function increment_links_counter() {
+ clean_links_counter += 1;
+ browser.runtime.sendMessage({
+ "message": clean_links_counter, "type": "updatebadge"
+ });
}
@@ -61,19 +38,25 @@ function SimpleHinting () {
// functions
SimpleHinting.prototype.highlight = function () {
- var at_least_one_match = false;
+ var matching_links = 0;
for (const id in this.labels) {
if (this.input && id.match("^" + this.input) !== null) {
- at_least_one_match = true;
+ matching_links++;
this.labels[id].rep.classList.add("sh_hint_hl");
} else {
this.labels[id].rep.classList.remove("sh_hint_hl");
}
+ // Wait for next check to add the sh_hint_match class back
+ this.labels[id].a.classList.remove("sh_hint_match");
if (id !== 1)
this.labels[id].rep.textContent = id;
}
- this.build_info_bar();
- return at_least_one_match;
+ this.build_info_bar(matching_links);
+ if (matching_links == 0) return false;
+ if (matching_links == 1) {
+ this.labels[this.input].a.classList.add("sh_hint_match");
+ }
+ return true;
}
SimpleHinting.prototype.clean_attributes = function (url_part, symbol) {
@@ -106,22 +89,17 @@ SimpleHinting.prototype.clean_link = function (link) {
return link.toString();
}
-SimpleHinting.prototype.unshorten_link = function (link, success) {
- if (tiny_domains.indexOf(link.hostname) === -1) {
- return success.call(this, link);
- }
- try {
- const xhr = new XMLHttpRequest();
- xhr.open("GET", "https://unshorten.umaneti.net/c?url=" + link.href);
- xhr.onload = () => {
- link.href = xhr.responseText.trim();
- success.call(this, link);
- };
- xhr.onerror = () => { throw xhr.statusText; };
- xhr.send();
- } catch (e) {
- onError(`Ajax failed ${e}`);
+SimpleHinting.prototype.unshorten_link = async function (link, success) {
+ const old_link = link.toString();
+ const uri = new URL(old_link);
+ if (tiny_domains.indexOf(uri.hostname) === -1) {
+ return success.call(this, uri, old_link);
}
+ return fetch(
+ "https://unshorten.umaneti.net/c?url=" + uri.toString()
+ ).then(
+ (response) => response.text()
+ ).then((body) => success.call(this, new URL(body.trim()), old_link));
}
SimpleHinting.prototype.update_link = function (link, cl) {
@@ -155,7 +133,7 @@ SimpleHinting.prototype.view_link = function () {
this.labels[id].rep.classList.add("sh_hint_view");
this.labels[id].rep.textContent = base_text + col +
browser.i18n.getMessage("parsingPlaceholder");
- this.unshorten_link(this.labels[id].a, function(long_link) {
+ this.unshorten_link(this.labels[id].a, function(long_link, old_link) {
let cl = this.clean_link(long_link);
if (this.update_link(this.labels[id].a, cl)) {
this.labels[id].rep.textContent = base_text;
@@ -163,12 +141,15 @@ SimpleHinting.prototype.view_link = function () {
} else {
this.labels[id].rep.textContent = base_text + col + cl;
}
+ if (long_link.toString() != old_link) {
+ increment_links_counter();
+ }
});
}
}
}
-SimpleHinting.prototype.open_link = function (keyname) {
+SimpleHinting.prototype.open_link = async function (keyname) {
let a = null;
if (this.labels[this.input]) {
a = this.labels[this.input].a;
@@ -197,6 +178,8 @@ SimpleHinting.prototype.remove_ui = function () {
for (let id in this.labels) {
let pe = this.labels[id].rep.parentElement;
if (pe) pe.removeChild(this.labels[id].rep);
+ if (this.labels[id].a)
+ this.labels[id].a.classList.remove("sh_hint_match");
}
const bar = document.getElementById("simple_hinting_info_bar");
if (bar) bar.remove();
@@ -206,7 +189,7 @@ SimpleHinting.prototype.remove_ui = function () {
}
// Create keybinding info bar
-SimpleHinting.prototype.build_info_bar = function () {
+SimpleHinting.prototype.build_info_bar = async function (matching_links) {
let bar = document.getElementById("simple_hinting_info_bar");
if (bar) bar.remove();
bar = document.createElement("P");
@@ -216,7 +199,7 @@ SimpleHinting.prototype.build_info_bar = function () {
"Clean all links ‘a’",
"Quit ‘Echap’ or ‘c’"
];
- if (this.input !== "") {
+ if (matching_links == 1) {
texts.unshift(
"Follow ‘f’ or ‘Enter’",
"New Window ‘w’",
@@ -252,7 +235,7 @@ SimpleHinting.prototype.create_ui = function () {
for (let i = 0; i < ankers.length; i++) {
const a = ankers[i];
- if (a.tagName === "A" && !a.href) continue;
+ if (a.tagName === "A" && !a.hasAttribute("href")) continue;
// Are you visible?
if (a.hidden || a.style.display === "none" ||
a.style.visibility === "hidden") {
@@ -285,7 +268,7 @@ SimpleHinting.prototype.create_ui = function () {
}
}
}
- this.build_info_bar();
+ this.build_info_bar(0);
this.ui_visible = true;
}
@@ -314,7 +297,7 @@ SimpleHinting.prototype.fix_one_link = function (link_uri) {
d.textContent = browser.i18n.getMessage("parsingPlaceholder");
this.ui_visible = true;
this.labels[i] = { "rep": d };
- this.unshorten_link(link, function(long_link) {
+ this.unshorten_link(link, function(long_link, old_link) {
let cl = this.clean_link(long_link);
d.textContent = cl;
if (this.update_link(link, cl)) {
@@ -323,6 +306,9 @@ SimpleHinting.prototype.fix_one_link = function (link_uri) {
// the hint to avoid repetitive information
this.remove_ui();
}
+ if (long_link.toString() != old_link) {
+ increment_links_counter();
+ }
link.blur();
});
}
@@ -333,8 +319,9 @@ function is_command (key) {
let is_c = false;
try {
is_c = Object.keys(actionkeys).indexOf(key) !== -1;
- } catch (_e) {
- onError(`Failed reading key: ${key}`);
+ } catch {
+ let message = `[Simple Hinting extension] Failed reading key: ${key}`;
+ console.error(message);
}
return is_c;
}
@@ -350,6 +337,7 @@ function input_key_listener (e) {
main_simple_hinting.remove_ui();
} else if (key === viewkey) {
+ reset_links_counter();
main_simple_hinting.view_link(key);
} else if (is_command(key)) {
@@ -385,11 +373,11 @@ function toggle_main_simple_hinting_ui () {
}
function fix_all_links () {
+ reset_links_counter();
const all_page_links = document.querySelectorAll("A");
var already_done = [];
- var totally_done = 0;
for (let i = 0; i < all_page_links.length; i++) {
- let link_uri = all_page_links[i].href.trim();
+ let link_uri = all_page_links[i].toString().trim();
if (link_uri === "" || link_uri[0] == "#") continue;
if (already_done.indexOf(link_uri) !== -1) continue;
already_done.push(link_uri);
@@ -397,44 +385,34 @@ function fix_all_links () {
sh.fix_one_link(link_uri);
// In any case, remove ui to avoid spam
sh.remove_ui();
- totally_done += 1;
}
- browser.runtime.sendMessage({
- "url": document.location.href.toString(),
- "message": totally_done,
- "type": "updatebadge"
- });
}
+var unwanted_params = [];
+var tiny_domains = [];
const main_simple_hinting = new SimpleHinting();
function SimpleHintingManager(callback) {
let opts = ["unwanted_params", "tiny_domains_list"];
browser.storage.local.get(opts).then(function (result) {
- let initMethods = [];
if (result.unwanted_params && Array.isArray(result.unwanted_params)) {
unwanted_params = result.unwanted_params;
- } else {
- initMethods.push(fetchUnwantedParams());
}
if (result.tiny_domains_list && Array.isArray(result.tiny_domains_list)) {
tiny_domains = result.tiny_domains_list;
- } else {
- initMethods.push(fetchTinyDomains());
}
- if (initMethods.length > 0) {
- Promise.all(initMethods).then(callback);
- } else {
- callback.call(null);
- }
- }, onError);
+ callback.call(null);
+ }).catch(function (error) {
+ console.error(`[Simple Hinting extension] ${error}`);
+ });
}
browser.runtime.onMessage.addListener(function(data, sender) {
if (sender.id !== "simple_hinting@umaneti.net") return false;
if (!data["message"]) return false;
if (data.message === "fix_one") {
+ reset_links_counter();
if (!data["link_uri"]) return false;
let link_uri = data.link_uri.trim();
if (link_uri === "" || link_uri[0] === "#") return false;
diff --git a/manifest.json b/manifest.json
index 0e70f10..4e9da80 100644
--- a/manifest.json
+++ b/manifest.json
@@ -1,7 +1,7 @@
{
"manifest_version": 2,
"name": "__MSG_extensionTitle__",
- "version": "0.5.2",
+ "version": "0.5.3",
"default_locale": "en",
"description": "__MSG_extensionDesc__",
"icons": {
diff --git a/package-lock.json b/package-lock.json
index ec9fdcd..ac70cc6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "simple_hinting",
- "version": "0.5.2",
+ "version": "0.5.3",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -713,10 +713,9 @@
"optional": true
},
"bl": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
- "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==",
- "dev": true,
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz",
+ "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==",
"requires": {
"readable-stream": "^2.3.5",
"safe-buffer": "^5.1.1"
@@ -726,7 +725,6 @@
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
- "dev": true,
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
@@ -740,8 +738,7 @@
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
}
}
},
@@ -749,7 +746,6 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "dev": true,
"requires": {
"safe-buffer": "~5.1.0"
},
@@ -757,8 +753,7 @@
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
}
}
}
@@ -1309,8 +1304,7 @@
"core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
- "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
- "dev": true
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
"crc": {
"version": "3.8.0",
@@ -2700,8 +2694,7 @@
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "dev": true
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"ini": {
"version": "1.3.5",
@@ -2991,8 +2984,7 @@
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
},
"isexe": {
"version": "2.0.0",
@@ -4261,8 +4253,7 @@
"process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
- "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
- "dev": true
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
},
"progress": {
"version": "2.0.3",
@@ -4568,8 +4559,7 @@
"safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
- "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
- "dev": true
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
},
"safe-json-stringify": {
"version": "1.2.0",
@@ -5607,8 +5597,7 @@
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
- "dev": true
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
},
"uuid": {
"version": "3.4.0",
diff --git a/package.json b/package.json
index f2a2497..ad06a99 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "simple_hinting",
- "version": "0.5.2",
+ "version": "0.5.3",
"author": "Étienne Deparis",
"scripts": {
"dev": "web-ext run --bc --ignore-files Makefile webextension-polyfill \"package*.json\" \"**/*.xcf\"",