From 475a6b9e9ab5a47f8ea15c5b7e17f38d596b51a4 Mon Sep 17 00:00:00 2001 From: hackademix Date: Sep 18 2018 21:43:28 +0000 Subject: [PATCH 1/3] Initial refactoring and unhiding of contact finder / complaint UI. --- diff --git a/contact_finder.js b/contact_finder.js deleted file mode 100644 index 48f9c27..0000000 --- a/contact_finder.js +++ /dev/null @@ -1,297 +0,0 @@ -/** -* GNU LibreJS - A browser add-on to block nonfree nontrivial JavaScript. -* * -* Copyright (C) 2017 Nathan Nichols, Loic J. Duros, Nik Nyby -* -* This file is part of GNU LibreJS. -* -* GNU LibreJS is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* GNU LibreJS 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 General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with GNU LibreJS. If not, see . -*/ - -// TO TEST THE CONTACT FINDER: -// - open the manifest.json -// - add a comma after the closing bracket of the key "background" -// - Copy and paste this after it: -/* - "content_scripts": [{"matches": [""],"js": ["contact_finder.js"]}] -*/ -// Now, the contact finder will load on every page and you can test it where ever you want. - - -//********************************************************************************************* -//Regexes taken from "contact_regex.js" in the current LibreJS -//Copyright (C) 2011, 2012, 2014 Loic J. Duros -//Copyright (C) 2014, 2015 Nik Nyby - -console.log("contact_finder.js"); - -// email address regexp -var reEmail = /^mailto\:(admin|feedback|webmaster|info|contact|support|comments|team|help)\@[a-z0-9.\-]+\.[a-z]{2,4}$/i; - -var reAnyEmail = /^mailto\:.*?\@[a-z0-9\.\-]+\.[a-z]{2,4}$/i; - -// twitter address regexp -var reTwitter = /twitter\.com\/(\!?#\/)?[a-z0-9]*/i; - -// identi.ca address regexp -var reIdentiCa = /identi\.ca\/(?!notice\/)[a-z0-9]*/i; - -/** - * contactSearchStrings - * Contains arrays of strings classified by language - * and by degree of certainty. - */ -var contactStr = { - 'da': { - 'certain': [ - '^[\\s]*Kontakt os[\\s]*$', - '^[\\s]*Email Os[\\s]*$', - '^[\\s]*Kontakt[\\s]*$' - ], - 'probable': ['^[\\s]Kontakt', '^[\\s]*Email'], - 'uncertain': [ - '^[\\s]*Om Us', - '^[\\s]*Om', - 'Hvem vi er' - ] - }, - 'en': { - 'certain': [ - '^[\\s]*Contact Us[\\s]*$', - '^[\\s]*Email Us[\\s]*$', - '^[\\s]*Contact[\\s]*$', - '^[\\s]*Feedback[\\s]*$', - '^[\\s]*Web.?site Feedback[\\s]*$' - ], - 'probable': ['^[\\s]Contact', '^[\\s]*Email'], - 'uncertain': [ - '^[\\s]*About Us', - '^[\\s]*About', - 'Who we are', - 'Who I am', - 'Company Info', - 'Customer Service' - ] - }, - 'es': { - 'certain': [ - '^[\\s]*contáctenos[\\s]*$', - '^[\\s]*Email[\\s]*$' - ], - 'probable': ['^[\\s]contáctenos', '^[\\s]*Email'], - 'uncertain': [ - 'Acerca de nosotros' - ] - }, - 'fr': { - 'certain': [ - '^[\\s]*Contactez nous[\\s]*$', - '^[\\s]*(Nous )?contacter[\\s]*$', - '^[\\s]*Email[\\s]*$', - '^[\\s]*Contact[\\s]*$', - '^[\\s]*Commentaires[\\s]*$' - ], - 'probable': ['^[\\s]Contact', '^[\\s]*Email'], - 'uncertain': [ - '^[\\s]*(A|À) propos', - 'Qui nous sommes', - 'Qui suis(-| )?je', - 'Info', - 'Service Client(e|è)le' - ] - } -}; - -var usaPhoneNumber = new RegExp(/(?:\+ ?1 ?)?\(?[2-9]{1}[0-9]{2}\)?(?:\-|\.| )?[0-9]{3}(?:\-|\.| )[0-9]{4}(?:[^0-9])/mg); -// Taken from http://emailregex.com/ -var email_regex = new RegExp(/(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/g); -//********************************************************************************************* - -var prefs; - -/** -* -* Creates a transparent floating button from a name string and a callback -* -* -*/ -function new_debug_button(name_text,callback){ - if(document.getElementById("abc123_main_div") !== null){ - document.getElementById("abc123_main_div").remove(); - } - console.log("adding button"); - if(document.getElementById("abc123_main_div") === null){ - var to_insert = '
'; - document.body.insertAdjacentHTML('afterbegin', to_insert); - } - var button_html = '
'; - document.getElementById("abc123_main_div").insertAdjacentHTML('afterbegin', button_html); document.getElementById("abc123_button_complain").addEventListener("click",callback); - -} -/** -* returns input with all elements not of type string removed -*/ -function remove_not_str(a){ - var new_a = []; - for(var i in a){ - if(typeof(a[i]) == "string"){ - new_a.push(a[i]) - } - } - return new_a; -} -/** -* Tests all links on the page for regexes under a certain certainty level. -* -* Will return either the first regex match from the selected certainty level or all regexes that -* match on that certainty level. -* -* certainty_lvl can be "certain" > "probable" > "uncertain" -*/ -function attempt(certainty_lvl, first=true){ - // There needs to be some kind of max so that people can't troll by for example leaving a comment with a bunch of emails - // to cause LibreJS users to slow down. - var fail_flag = true; - var flag; - var matches = []; - var result = []; - var str_under_test = ""; - for(var i in document.links){ - if( typeof(document.links[i].innerText) != "string" || typeof(document.links[i].href) != "string"){ - continue; - } - str_under_test = document.links[i].innerText + " " + document.links[i].href; - flag = true; - for(var j in contactStr){ - for(var k in contactStr[j][certainty_lvl]){ - if(flag){ - result = []; - result = str_under_test.match(new RegExp(contactStr[j][certainty_lvl][k],"g")); - result = remove_not_str(result); - if(result !== undefined && typeof(result[0]) == "string" ){ - if(first){ - return {"fail":false,"result":document.links[i]}; - } else{ - //console.log(document.links[i].href + " matched " + contactStr[j][certainty_lvl][k]); - matches.push(document.links[i]); - fail_flag = false; - flag = false; - } - } - } - } - } - } - return {"fail":fail_flag,"result":matches}; -} - -/** -* "LibreJS detects contact pages, email addresses that are likely to be owned by the -* maintainer of the site, Twitter and identi.ca links, and phone numbers." -*/ -function find_contacts(){ - var all = document.documentElement.innerText; - var phone_num = []; - var twitlinks = []; - var identi = []; - var contact_pages = []; - var res = attempt("certain"); - var flag = true; - var type = ""; - if(res["fail"] == false){ - type = "certain"; - res = res["result"]; - flag = false; - } - if(flag){ - res = attempt("probable"); - if(res["fail"] == false){ - type = "probable"; - res = res["result"]; - flag = false; - } - } - if(flag){ - res = attempt("uncertain"); - if(res["fail"] == false){ - type = "uncertain"; - res = res["result"]; - flag = false; - } - } - if(flag){ - return res; - } - return [type,res]; -} -// need to have this so the handler doesn't take too long -function handler(){ - var res = find_contacts(); - if(document.getElementById("librejs_contactfinder") != null){ - document.getElementById("librejs_contactfinder").remove(); - } - var to_insert; - if("fail" in res){ - to_insert = '
'+ - "Contact finder failed."; - } else{ - if(typeof(res[1]) == "string"){ - to_insert = ''; - - setTimeout(function(){document.getElementById("librejs_contactfinder").remove()}, 7500); - document.body.insertAdjacentHTML("afterbegin",to_insert); - return 0; - -} - -function main(){ - new_debug_button("Complain to website",handler); -} - -var myPort = browser.runtime.connect({name:"contact_finder"}); - -myPort.onMessage.addListener(function(m) { - prefs = m; - main(); -}); diff --git a/content/contactFinder.css b/content/contactFinder.css new file mode 100644 index 0000000..e9ce93e --- /dev/null +++ b/content/contactFinder.css @@ -0,0 +1,56 @@ +#_LibreJS_CF_panel { + opacity: 0.8 !important; + font-family: sans-serif !important; + font-size: 1.2em !important; + color: #000 !important; + z-index: 2147483647 !important; + background-color: #eee !important; + position: fixed !important; + display:inline-block !important; + border: 2px solid #444 !important; + text-align: center !important; + width: 50% !important; + top: 25% !important; + bottom: 25% !important; + left: 25% !important; + right: 25% !important; + transition: width .5s !important; +} +#_LibreJS_CF_panel:hover { + opacity: 1 !important; +} +#_LibreJS_CF_panel h3, #LibreJS_CF_panel h4, #LibreJS_CF_panel h5 { + font-family: sans-serif !important; + color: #000 !important; + background: transparent !important; + font-weight: bold !important; + text-align: center !important; + border: none !important; + padding: 0 !important; + margin: .8em !important; +} + +#_libreJS_CF_panel a { + text-decoration: none !important; + color: #840 !important; + border: none !important; +} + +#_libreJS_CF_panel a:hover { + text-decoration: none !important; + color: #c60 !important; + border-bottom: 1px solid #840 !important; +} + + +#_LibreJS_CF_panel h3 { + font-size: 2em !important; +} + +#_LibreJS_CF_panel h4 { + font-size: 1.8em !important; +} + +#_LibreJS_CF_panel h5 { + font-size: 1.5em !important; +} diff --git a/content/contactFinder.js b/content/contactFinder.js new file mode 100644 index 0000000..48f9c27 --- /dev/null +++ b/content/contactFinder.js @@ -0,0 +1,297 @@ +/** +* GNU LibreJS - A browser add-on to block nonfree nontrivial JavaScript. +* * +* Copyright (C) 2017 Nathan Nichols, Loic J. Duros, Nik Nyby +* +* This file is part of GNU LibreJS. +* +* GNU LibreJS is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* GNU LibreJS 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 General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with GNU LibreJS. If not, see . +*/ + +// TO TEST THE CONTACT FINDER: +// - open the manifest.json +// - add a comma after the closing bracket of the key "background" +// - Copy and paste this after it: +/* + "content_scripts": [{"matches": [""],"js": ["contact_finder.js"]}] +*/ +// Now, the contact finder will load on every page and you can test it where ever you want. + + +//********************************************************************************************* +//Regexes taken from "contact_regex.js" in the current LibreJS +//Copyright (C) 2011, 2012, 2014 Loic J. Duros +//Copyright (C) 2014, 2015 Nik Nyby + +console.log("contact_finder.js"); + +// email address regexp +var reEmail = /^mailto\:(admin|feedback|webmaster|info|contact|support|comments|team|help)\@[a-z0-9.\-]+\.[a-z]{2,4}$/i; + +var reAnyEmail = /^mailto\:.*?\@[a-z0-9\.\-]+\.[a-z]{2,4}$/i; + +// twitter address regexp +var reTwitter = /twitter\.com\/(\!?#\/)?[a-z0-9]*/i; + +// identi.ca address regexp +var reIdentiCa = /identi\.ca\/(?!notice\/)[a-z0-9]*/i; + +/** + * contactSearchStrings + * Contains arrays of strings classified by language + * and by degree of certainty. + */ +var contactStr = { + 'da': { + 'certain': [ + '^[\\s]*Kontakt os[\\s]*$', + '^[\\s]*Email Os[\\s]*$', + '^[\\s]*Kontakt[\\s]*$' + ], + 'probable': ['^[\\s]Kontakt', '^[\\s]*Email'], + 'uncertain': [ + '^[\\s]*Om Us', + '^[\\s]*Om', + 'Hvem vi er' + ] + }, + 'en': { + 'certain': [ + '^[\\s]*Contact Us[\\s]*$', + '^[\\s]*Email Us[\\s]*$', + '^[\\s]*Contact[\\s]*$', + '^[\\s]*Feedback[\\s]*$', + '^[\\s]*Web.?site Feedback[\\s]*$' + ], + 'probable': ['^[\\s]Contact', '^[\\s]*Email'], + 'uncertain': [ + '^[\\s]*About Us', + '^[\\s]*About', + 'Who we are', + 'Who I am', + 'Company Info', + 'Customer Service' + ] + }, + 'es': { + 'certain': [ + '^[\\s]*contáctenos[\\s]*$', + '^[\\s]*Email[\\s]*$' + ], + 'probable': ['^[\\s]contáctenos', '^[\\s]*Email'], + 'uncertain': [ + 'Acerca de nosotros' + ] + }, + 'fr': { + 'certain': [ + '^[\\s]*Contactez nous[\\s]*$', + '^[\\s]*(Nous )?contacter[\\s]*$', + '^[\\s]*Email[\\s]*$', + '^[\\s]*Contact[\\s]*$', + '^[\\s]*Commentaires[\\s]*$' + ], + 'probable': ['^[\\s]Contact', '^[\\s]*Email'], + 'uncertain': [ + '^[\\s]*(A|À) propos', + 'Qui nous sommes', + 'Qui suis(-| )?je', + 'Info', + 'Service Client(e|è)le' + ] + } +}; + +var usaPhoneNumber = new RegExp(/(?:\+ ?1 ?)?\(?[2-9]{1}[0-9]{2}\)?(?:\-|\.| )?[0-9]{3}(?:\-|\.| )[0-9]{4}(?:[^0-9])/mg); +// Taken from http://emailregex.com/ +var email_regex = new RegExp(/(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/g); +//********************************************************************************************* + +var prefs; + +/** +* +* Creates a transparent floating button from a name string and a callback +* +* +*/ +function new_debug_button(name_text,callback){ + if(document.getElementById("abc123_main_div") !== null){ + document.getElementById("abc123_main_div").remove(); + } + console.log("adding button"); + if(document.getElementById("abc123_main_div") === null){ + var to_insert = '
'; + document.body.insertAdjacentHTML('afterbegin', to_insert); + } + var button_html = '
'; + document.getElementById("abc123_main_div").insertAdjacentHTML('afterbegin', button_html); document.getElementById("abc123_button_complain").addEventListener("click",callback); + +} +/** +* returns input with all elements not of type string removed +*/ +function remove_not_str(a){ + var new_a = []; + for(var i in a){ + if(typeof(a[i]) == "string"){ + new_a.push(a[i]) + } + } + return new_a; +} +/** +* Tests all links on the page for regexes under a certain certainty level. +* +* Will return either the first regex match from the selected certainty level or all regexes that +* match on that certainty level. +* +* certainty_lvl can be "certain" > "probable" > "uncertain" +*/ +function attempt(certainty_lvl, first=true){ + // There needs to be some kind of max so that people can't troll by for example leaving a comment with a bunch of emails + // to cause LibreJS users to slow down. + var fail_flag = true; + var flag; + var matches = []; + var result = []; + var str_under_test = ""; + for(var i in document.links){ + if( typeof(document.links[i].innerText) != "string" || typeof(document.links[i].href) != "string"){ + continue; + } + str_under_test = document.links[i].innerText + " " + document.links[i].href; + flag = true; + for(var j in contactStr){ + for(var k in contactStr[j][certainty_lvl]){ + if(flag){ + result = []; + result = str_under_test.match(new RegExp(contactStr[j][certainty_lvl][k],"g")); + result = remove_not_str(result); + if(result !== undefined && typeof(result[0]) == "string" ){ + if(first){ + return {"fail":false,"result":document.links[i]}; + } else{ + //console.log(document.links[i].href + " matched " + contactStr[j][certainty_lvl][k]); + matches.push(document.links[i]); + fail_flag = false; + flag = false; + } + } + } + } + } + } + return {"fail":fail_flag,"result":matches}; +} + +/** +* "LibreJS detects contact pages, email addresses that are likely to be owned by the +* maintainer of the site, Twitter and identi.ca links, and phone numbers." +*/ +function find_contacts(){ + var all = document.documentElement.innerText; + var phone_num = []; + var twitlinks = []; + var identi = []; + var contact_pages = []; + var res = attempt("certain"); + var flag = true; + var type = ""; + if(res["fail"] == false){ + type = "certain"; + res = res["result"]; + flag = false; + } + if(flag){ + res = attempt("probable"); + if(res["fail"] == false){ + type = "probable"; + res = res["result"]; + flag = false; + } + } + if(flag){ + res = attempt("uncertain"); + if(res["fail"] == false){ + type = "uncertain"; + res = res["result"]; + flag = false; + } + } + if(flag){ + return res; + } + return [type,res]; +} +// need to have this so the handler doesn't take too long +function handler(){ + var res = find_contacts(); + if(document.getElementById("librejs_contactfinder") != null){ + document.getElementById("librejs_contactfinder").remove(); + } + var to_insert; + if("fail" in res){ + to_insert = '
'+ + "Contact finder failed."; + } else{ + if(typeof(res[1]) == "string"){ + to_insert = ''; + + setTimeout(function(){document.getElementById("librejs_contactfinder").remove()}, 7500); + document.body.insertAdjacentHTML("afterbegin",to_insert); + return 0; + +} + +function main(){ + new_debug_button("Complain to website",handler); +} + +var myPort = browser.runtime.connect({name:"contact_finder"}); + +myPort.onMessage.addListener(function(m) { + prefs = m; + main(); +}); diff --git a/html/display_panel/content/panel-styles.css b/html/display_panel/content/panel-styles.css index cbf5cf5..0d849e4 100644 --- a/html/display_panel/content/panel-styles.css +++ b/html/display_panel/content/panel-styles.css @@ -149,9 +149,3 @@ span.blocked { width: 100%; text-align: center; } - - - -#complain { - display: none; /* TODO: Complaint to owner UI */ -} diff --git a/html/preferences_panel/preferences_panel.html b/html/preferences_panel/preferences_panel.html index effb724..70d3b86 100644 --- a/html/preferences_panel/preferences_panel.html +++ b/html/preferences_panel/preferences_panel.html @@ -71,15 +71,9 @@
Complaint email defaults - + - +
diff --git a/html/preferences_panel/prefs.css b/html/preferences_panel/prefs.css index b52d6c5..3ac498e 100644 --- a/html/preferences_panel/prefs.css +++ b/html/preferences_panel/prefs.css @@ -85,7 +85,3 @@ input[type="text"] { background: #ffe; color: #800; } - -#section-complaint { - display: none; /* TODO: Complaint to owner UI */ -} diff --git a/main_background.js b/main_background.js index 5b745c1..fdd895e 100644 --- a/main_background.js +++ b/main_background.js @@ -372,7 +372,7 @@ function connected(p) { // invoke_contact_finder if(m["invoke_contact_finder"] !== undefined){ contact_finder = true; - inject_contact_finder(); + await injectContactFinder(); } // a debug feature (maybe give the user an option to do this?) if(m["deletelocalstorage"] !== undefined){ @@ -1120,11 +1120,35 @@ var listManager = new ListManager(whitelist, blacklist, .map(script => script.hash) ); + +async function initDefaults() { + let defaults = { + pref_subject: "Issues with Javascript on your website", + pref_body: `Please consider using a free license for the Javascript on your website. + +[Message generated by LibreJS. See https://www.gnu.org/software/librejs/ for more information] +` + }; + let keys = Object.keys(defaults); + let prefs = await browser.storage.local.get(keys); + let changed = false; + for (let k of keys) { + if (!(k in prefs)) { + prefs[k] = defaults[k]; + changed = true; + } + } + if (changed) { + await browser.storage.local.set(prefs); + } +} + /** * Initializes various add-on functions * only meant to be called once when the script starts */ -async function init_addon(){ +async function init_addon() { + await initDefaults(); await whitelist.load(); browser.runtime.onConnect.addListener(connected); browser.storage.onChanged.addListener(options_listener); @@ -1154,11 +1178,11 @@ async function init_addon(){ /** * Loads the contact finder on the given tab ID. */ -function inject_contact_finder(tab_id){ - function executed(result) { - dbg_print("[TABID:"+tab_id+"]"+"finished executing contact finder: " + result); - } - var executing = browser.tabs.executeScript(tab_id, {file: "/contact_finder.js"}, executed); +async function injectContactFinder(tabId){ + await Promise.all([ + browser.tabs.executeScript(tabId, {file: "/content/contactFinder.js"}), + browser.tabs.insertCSS(tabId, {file: "/content/contactFinder.css", cssOrigin: "user"}) + ]); } init_addon(); From 73a485fa81071cb293e9676e2ee8cdb570523b11 Mon Sep 17 00:00:00 2001 From: hackademix Date: Sep 18 2018 21:45:37 +0000 Subject: [PATCH 2/3] Contact finder / complaint UI overhaul. --- diff --git a/content/contactFinder.js b/content/contactFinder.js index 48f9c27..320bd2e 100644 --- a/content/contactFinder.js +++ b/content/contactFinder.js @@ -2,6 +2,7 @@ * GNU LibreJS - A browser add-on to block nonfree nontrivial JavaScript. * * * Copyright (C) 2017 Nathan Nichols, Loic J. Duros, Nik Nyby +* Copyright (C) 2018 Giorgio Maone * * This file is part of GNU LibreJS. * @@ -23,8 +24,12 @@ // - open the manifest.json // - add a comma after the closing bracket of the key "background" // - Copy and paste this after it: -/* - "content_scripts": [{"matches": [""],"js": ["contact_finder.js"]}] +/* + "content_scripts": [{ + "matches": [""], + "js": ["/content/contactFinder.js"], + "css": ["/content/contactFinder.css"] + }] */ // Now, the contact finder will load on every page and you can test it where ever you want. @@ -34,7 +39,7 @@ //Copyright (C) 2011, 2012, 2014 Loic J. Duros //Copyright (C) 2014, 2015 Nik Nyby -console.log("contact_finder.js"); +console.debug("Injecting contact finder in %s", document.URL); // email address regexp var reEmail = /^mailto\:(admin|feedback|webmaster|info|contact|support|comments|team|help)\@[a-z0-9.\-]+\.[a-z]{2,4}$/i; @@ -121,33 +126,14 @@ var email_regex = new RegExp(/(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'* var prefs; /** -* -* Creates a transparent floating button from a name string and a callback -* -* -*/ -function new_debug_button(name_text,callback){ - if(document.getElementById("abc123_main_div") !== null){ - document.getElementById("abc123_main_div").remove(); - } - console.log("adding button"); - if(document.getElementById("abc123_main_div") === null){ - var to_insert = '
'; - document.body.insertAdjacentHTML('afterbegin', to_insert); - } - var button_html = '
'; - document.getElementById("abc123_main_div").insertAdjacentHTML('afterbegin', button_html); document.getElementById("abc123_button_complain").addEventListener("click",callback); - -} -/** * returns input with all elements not of type string removed */ function remove_not_str(a){ - var new_a = []; + var new_a = []; for(var i in a){ if(typeof(a[i]) == "string"){ new_a.push(a[i]) - } + } } return new_a; } @@ -157,7 +143,7 @@ function remove_not_str(a){ * Will return either the first regex match from the selected certainty level or all regexes that * match on that certainty level. * -* certainty_lvl can be "certain" > "probable" > "uncertain" +* certainty_lvl can be "certain" > "probable" > "uncertain" */ function attempt(certainty_lvl, first=true){ // There needs to be some kind of max so that people can't troll by for example leaving a comment with a bunch of emails @@ -165,8 +151,8 @@ function attempt(certainty_lvl, first=true){ var fail_flag = true; var flag; var matches = []; - var result = []; - var str_under_test = ""; + var result = []; + var str_under_test = ""; for(var i in document.links){ if( typeof(document.links[i].innerText) != "string" || typeof(document.links[i].href) != "string"){ continue; @@ -176,10 +162,10 @@ function attempt(certainty_lvl, first=true){ for(var j in contactStr){ for(var k in contactStr[j][certainty_lvl]){ if(flag){ - result = []; + result = []; result = str_under_test.match(new RegExp(contactStr[j][certainty_lvl][k],"g")); result = remove_not_str(result); - if(result !== undefined && typeof(result[0]) == "string" ){ + if(result !== undefined && typeof(result[0]) == "string" ){ if(first){ return {"fail":false,"result":document.links[i]}; } else{ @@ -197,7 +183,7 @@ function attempt(certainty_lvl, first=true){ } /** -* "LibreJS detects contact pages, email addresses that are likely to be owned by the +* "LibreJS detects contact pages, email addresses that are likely to be owned by the * maintainer of the site, Twitter and identi.ca links, and phone numbers." */ function find_contacts(){ @@ -207,19 +193,19 @@ function find_contacts(){ var identi = []; var contact_pages = []; var res = attempt("certain"); - var flag = true; + var flag = true; var type = ""; if(res["fail"] == false){ type = "certain"; res = res["result"]; - flag = false; + flag = false; } if(flag){ res = attempt("probable"); if(res["fail"] == false){ type = "probable"; res = res["result"]; - flag = false; + flag = false; } } if(flag){ @@ -227,7 +213,7 @@ function find_contacts(){ if(res["fail"] == false){ type = "uncertain"; res = res["result"]; - flag = false; + flag = false; } } if(flag){ @@ -235,63 +221,73 @@ function find_contacts(){ } return [type,res]; } -// need to have this so the handler doesn't take too long -function handler(){ - var res = find_contacts(); - if(document.getElementById("librejs_contactfinder") != null){ - document.getElementById("librejs_contactfinder").remove(); - } - var to_insert; - if("fail" in res){ - to_insert = '
'+ - "Contact finder failed."; - } else{ - if(typeof(res[1]) == "string"){ - to_insert = '
Result:
'+ - res[0] + ": " + 'Result:
'+ - res[0]+": "+res[1].outerHTML; + +function createWidget(id, tag) { + let widget = document.getElementById(id); + if (widget) widget.remove(); + widget = document.body.appendChild(document.createElement(tag)); + widget.id = id; + return widget; +} + +/** +* +* Creates the contact finder / complain UI as a semi-transparent overlay +* +*/ + +function createOverlay() { + let res = find_contacts(); + let widget = createWidget("_LibreJS_CF_panel", "div"); + let addHTML = s => widget.insertAdjacentHTML("beforeend", s); + widget.innerHTML = "

LibreJS Complaint

"; + if ("fail" in res){ + widget.classList.toggle("_LibreJS_CF_fail", true) + addHTML("
Contact finder failed.
"); + } else { + addHTML("

LibreJS

Contact info guessed for this site

"); + if(typeof(res[1]) === "string") { + let a = document.createElement("a"); + a.href = a.textContent = res[1]; + widget.appendChild(a); + } else if (typeof(res[1]) === "object"){ + addHTML(`${res[0]}: ${res[1].outerHTML}`); } } - var email = document.documentElement.innerText.match(email_regex); - if(email != null){ - var max_i = 0; - if(email.length >= 10){ - max_i = 10; - } else{ - max_i = email.length; - } - for(var i = 0; i < max_i; i++){ - var mailto = "mailto:"+email[i]+"?subject="+encodeURI(prefs["pref_subject"])+"&body="+encodeURI(prefs["pref_body"]); - to_insert += '
' + 'Possible email:
'+email[i]+''; + let email = document.documentElement.innerText.match(email_regex); + if (email != null) { + addHTML("
Possible email addresses:
"); + let list = document.createElement("ul"); + let max = Math.max(email.length, 10); + for (let i = 0; i < max; i++) { + let recipient = email[i]; + let a = document.createElement("a"); + a.href = `mailto:${recipient}?subject${ + encodeURIComponent(prefs["pref_subject"]) + }&body=${ + encodeURIComponent(prefs["pref_body"]) + }`; + a.textContent = recipient; + list.appendChild(document.createElement("li")).appendChild(a); } + widget.appendChild(list); } - to_insert += '
'; - - setTimeout(function(){document.getElementById("librejs_contactfinder").remove()}, 7500); - document.body.insertAdjacentHTML("afterbegin",to_insert); - return 0; - + let closeListener = e => { + if (!widget.contains(e.target)) { + widget.remove(); + window.removeEventListener("click", closeListener); + } + }; + window.addEventListener("click", closeListener); } -function main(){ - new_debug_button("Complain to website",handler); -} var myPort = browser.runtime.connect({name:"contact_finder"}); myPort.onMessage.addListener(function(m) { prefs = m; - main(); + createOverlay(); }); From 08f01213cc2e3929bfd0ae55514b2e3bd2e5d6f3 Mon Sep 17 00:00:00 2001 From: hackademix Date: Sep 26 2018 13:04:20 +0000 Subject: [PATCH 3/3] Improved and partially refactored floating dialog. --- diff --git a/content/contactFinder.css b/content/contactFinder.css deleted file mode 100644 index e9ce93e..0000000 --- a/content/contactFinder.css +++ /dev/null @@ -1,56 +0,0 @@ -#_LibreJS_CF_panel { - opacity: 0.8 !important; - font-family: sans-serif !important; - font-size: 1.2em !important; - color: #000 !important; - z-index: 2147483647 !important; - background-color: #eee !important; - position: fixed !important; - display:inline-block !important; - border: 2px solid #444 !important; - text-align: center !important; - width: 50% !important; - top: 25% !important; - bottom: 25% !important; - left: 25% !important; - right: 25% !important; - transition: width .5s !important; -} -#_LibreJS_CF_panel:hover { - opacity: 1 !important; -} -#_LibreJS_CF_panel h3, #LibreJS_CF_panel h4, #LibreJS_CF_panel h5 { - font-family: sans-serif !important; - color: #000 !important; - background: transparent !important; - font-weight: bold !important; - text-align: center !important; - border: none !important; - padding: 0 !important; - margin: .8em !important; -} - -#_libreJS_CF_panel a { - text-decoration: none !important; - color: #840 !important; - border: none !important; -} - -#_libreJS_CF_panel a:hover { - text-decoration: none !important; - color: #c60 !important; - border-bottom: 1px solid #840 !important; -} - - -#_LibreJS_CF_panel h3 { - font-size: 2em !important; -} - -#_LibreJS_CF_panel h4 { - font-size: 1.8em !important; -} - -#_LibreJS_CF_panel h5 { - font-size: 1.5em !important; -} diff --git a/content/contactFinder.js b/content/contactFinder.js index 320bd2e..22bf2fc 100644 --- a/content/contactFinder.js +++ b/content/contactFinder.js @@ -39,7 +39,13 @@ //Copyright (C) 2011, 2012, 2014 Loic J. Duros //Copyright (C) 2014, 2015 Nik Nyby -console.debug("Injecting contact finder in %s", document.URL); +function debug(format, ...args) { + console.debug(`LibreJS - ${format}`, ...args); +} + +var myPort; + +debug("Injecting contact finder in %s", document.URL); // email address regexp var reEmail = /^mailto\:(admin|feedback|webmaster|info|contact|support|comments|team|help)\@[a-z0-9.\-]+\.[a-z]{2,4}$/i; @@ -223,10 +229,10 @@ function find_contacts(){ } -function createWidget(id, tag) { +function createWidget(id, tag, parent = document.body) { let widget = document.getElementById(id); if (widget) widget.remove(); - widget = document.body.appendChild(document.createElement(tag)); + widget = parent.appendChild(document.createElement(tag)); widget.id = id; return widget; } @@ -237,57 +243,86 @@ function createWidget(id, tag) { * */ -function createOverlay() { - let res = find_contacts(); - let widget = createWidget("_LibreJS_CF_panel", "div"); - let addHTML = s => widget.insertAdjacentHTML("beforeend", s); - widget.innerHTML = "

LibreJS Complaint

"; - if ("fail" in res){ - widget.classList.toggle("_LibreJS_CF_fail", true) - addHTML("
Contact finder failed.
"); - } else { - addHTML("

LibreJS

Contact info guessed for this site

"); - if(typeof(res[1]) === "string") { - let a = document.createElement("a"); - a.href = a.textContent = res[1]; - widget.appendChild(a); - } else if (typeof(res[1]) === "object"){ - addHTML(`${res[0]}: ${res[1].outerHTML}`); - } - } +function main() { + let overlay = createWidget("_LibreJS_overlay", "div"); + let frame = createWidget("_LibreJS_frame", "iframe"); - let email = document.documentElement.innerText.match(email_regex); - if (email != null) { - addHTML("
Possible email addresses:
"); - let list = document.createElement("ul"); - let max = Math.max(email.length, 10); - for (let i = 0; i < max; i++) { - let recipient = email[i]; - let a = document.createElement("a"); - a.href = `mailto:${recipient}?subject${ - encodeURIComponent(prefs["pref_subject"]) - }&body=${ - encodeURIComponent(prefs["pref_body"]) - }`; - a.textContent = recipient; - list.appendChild(document.createElement("li")).appendChild(a); - } - widget.appendChild(list); - } + let close = () => { + frame.remove(); + overlay.remove(); + }; let closeListener = e => { - if (!widget.contains(e.target)) { - widget.remove(); - window.removeEventListener("click", closeListener); + let t = e.currentTarget; + if (t.href) { // link navigation + if (t.href !== document.URL) { + if (t.href.includes("#")) { + window.addEventListener("hashchange", close); + } + return; + } } + close(); }; - window.addEventListener("click", closeListener); -} + let makeCloser = clickable => clickable.addEventListener("click", closeListener); + + makeCloser(overlay); + + let initFrame = () => { + debug("initFrame"); + let res = find_contacts(); + let contentDoc = frame.contentWindow.document; + let {body} = contentDoc; + body.id = "_LibreJS_dialog"; + body.innerHTML = `

LibreJS Complaint

`; + contentDoc.documentElement.appendChild(contentDoc.createElement("base")).target = "_top"; + let content = body.appendChild(contentDoc.createElement("div")); + content.id = "content"; + let addHTML = s => content.insertAdjacentHTML("beforeend", s); + if ("fail" in res) { + content.classList.toggle("_LibreJS_fail", true) + addHTML("
Could not guess any contact page for this site.
"); + } else { + addHTML("

Contact info guessed for this site

"); + if(typeof(res[1]) === "string") { + let a = contentDoc.createElement("a"); + a.href = a.textContent = res[1]; + content.appendChild(a); + } else if (typeof(res[1]) === "object"){ + addHTML(`${res[0]}: ${res[1].outerHTML}`); + } + } + let emails = document.documentElement.textContent.match(email_regex); + if (emails && (emails = Array.filter(emails, e => !!e)).length) { + addHTML("
Possible email addresses:
"); + let list = contentDoc.createElement("ul"); + for (let i = 0, max = Math.min(emails.length, 10); i < max; i++) { + let recipient = emails[i]; + let a = contentDoc.createElement("a"); + a.href = `mailto:${recipient}?subject${ + encodeURIComponent(prefs["pref_subject"]) + }&body=${ + encodeURIComponent(prefs["pref_body"]) + }`; + a.textContent = recipient; + list.appendChild(contentDoc.createElement("li")).appendChild(a); + } + content.appendChild(list); + } + Array.forEach(contentDoc.querySelectorAll(".close, a"), makeCloser); + debug("frame initialized"); + } -var myPort = browser.runtime.connect({name:"contact_finder"}); -myPort.onMessage.addListener(function(m) { - prefs = m; - createOverlay(); -}); + + frame.addEventListener("load", e => { + debug("frame loaded"); + myPort = browser.runtime.connect({name: "contact_finder"}).onMessage.addListener(m => { + prefs = m; + initFrame(); + }); + }); +} + +main(); diff --git a/content/dialog.css b/content/dialog.css new file mode 100644 index 0000000..38b6634 --- /dev/null +++ b/content/dialog.css @@ -0,0 +1,91 @@ +#_LibreJS_dialog { + font-family: sans-serif; + font-size: 1.2em; + color: #000; + background-color: #eee; + margin: 0; + padding: 0; + text-align: center; +} +#_LibreJS_dialog .close { + -moz-appearance: none; + border: 0; + position: fixed; + top: .2em; + right: .2em; + font-size: 1em; + font-weight: bold; + text-transform: uppercase; + color: white; + background: black; + border-radius: 1em; + cursor: pointer; + display: block; + width: 1.5em; + height: 1.5em; + text-align: center; + vertical-align: middle; + padding: 0; +} +#_LibreJS_dialog .close:hover { + background: #800; +} + + #_LibreJS_dialog h1, #_LibreJS_dialog h2, #_LibreJS_dialog h3 { + font-family: sans-serif; + color: #000; + font-weight: bold; + text-align: center; + border: none; + padding: .2em; + margin: .2em; + display: block; +} + +#_LibreJS_dialog a { + text-decoration: none; + color: #048; + border: none; +} + +#_LibreJS_dialog a:hover { + text-decoration: none; + color: #06c; + border-bottom: 1px solid #048; +} + +#_LibreJS_dialog h1 { + font-size: 1.5em; + background: #666; + color: white; + position: fixed; + top: 0; + left: 0; + width: 100%; + margin: 0; + padding: .2em; +} + +#_LibreJS_dialog h3 { + font-size: 1.2em !important +} + +#_LibreJS_dialog h4 { + font-size: 1em; +} + +#_LibreJS_dialog #content { + position: fixed; + overflow: auto; + top: 2.5em; + bottom: 0; + left: 0; + right: 0; + width: 100%; +} + +#_LibreJS_dialog #content ul { + list-style: none; + margin: 0; + padding: 0;" +} diff --git a/content/overlay.css b/content/overlay.css new file mode 100644 index 0000000..fa0a294 --- /dev/null +++ b/content/overlay.css @@ -0,0 +1,28 @@ +#_LibreJS_overlay { + z-index: 2147483647 !important; + background-color: #000; + opacity: 0.7 !important; + display: block !important; + position: fixed !important; + margin: 0 !important; + padding: 0 !important; + top: 0 !important; + bottom: 0 !important; + left: 0 !important; + right: 0 !important; +} + +#_LibreJS_frame { + width: 60% !important; + height: 80% !important; + top: 10% !important; + bottom: 10% !important; + left: 20% !important; + right: 20% !important; + overflow: auto !important; + position: fixed !important; + display:inline-block !important; + border: 2px solid #444 !important; + z-index: 2147483647 !important; + background: #eee; +} diff --git a/main_background.js b/main_background.js index fdd895e..a145cc5 100644 --- a/main_background.js +++ b/main_background.js @@ -339,13 +339,18 @@ function get_domain(url){ * */ var portFromCS; -function connected(p) { - if(p["name"] == "contact_finder"){ +async function connected(p) { + if(p.name === "contact_finder"){ + // style the contact finder panel + await browser.tabs.insertCSS(p.sender.tab.id, { + file: "/content/dialog.css", + cssOrigin: "user", + matchAboutBlank: true, + allFrames: true + }); + // Send a message back with the relevant settings - function cb(items){ - p.postMessage(items); - } - browser.storage.local.get(cb); + p.postMessage(await browser.storage.local.get(["prefs_subject", "prefs_body"])); return; } p.onMessage.addListener(async function(m) { @@ -1180,9 +1185,9 @@ async function init_addon() { */ async function injectContactFinder(tabId){ await Promise.all([ + browser.tabs.insertCSS(tabId, {file: "/content/overlay.css", cssOrigin: "user"}), browser.tabs.executeScript(tabId, {file: "/content/contactFinder.js"}), - browser.tabs.insertCSS(tabId, {file: "/content/contactFinder.css", cssOrigin: "user"}) - ]); + ]); } init_addon();