aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--content/contactFinder.js (renamed from contact_finder.js)203
-rw-r--r--content/dialog.css91
-rw-r--r--content/overlay.css28
-rw-r--r--html/display_panel/content/panel-styles.css6
-rw-r--r--html/preferences_panel/preferences_panel.html10
-rw-r--r--html/preferences_panel/prefs.css4
-rw-r--r--main_background.js55
7 files changed, 280 insertions, 117 deletions
diff --git a/contact_finder.js b/content/contactFinder.js
index 48f9c27..22bf2fc 100644
--- a/contact_finder.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": ["<all_urls>"],"js": ["contact_finder.js"]}]
+/*
+ "content_scripts": [{
+ "matches": ["<all_urls>"],
+ "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,13 @@
//Copyright (C) 2011, 2012, 2014 Loic J. Duros
//Copyright (C) 2014, 2015 Nik Nyby
-console.log("contact_finder.js");
+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;
@@ -121,33 +132,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 = '<div style="opacity: 0.5; font-size: small; z-index: 2147483647; position: fixed; right: 1%; top: 4%;" id="abc123_main_div"></div>';
- document.body.insertAdjacentHTML('afterbegin', to_insert);
- }
- var button_html = '<input id="abc123_button_complain" value="' + name_text +'" type="button"></input><br>';
- 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 +149,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 +157,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 +168,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 +189,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 +199,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 +219,7 @@ function find_contacts(){
if(res["fail"] == false){
type = "uncertain";
res = res["result"];
- flag = false;
+ flag = false;
}
}
if(flag){
@@ -235,63 +227,102 @@ 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 = '<div style="font-size: small; z-index: 2147483647; background-color: #eeeeee;'+
- 'position: fixed; display:inline-block; border: 3px solid #990000; width: 50%;"'+
- ' id="librejs_contactfinder">'+
- "Contact finder failed.";
- } else{
- if(typeof(res[1]) == "string"){
- to_insert = '<div style="font-size: small; z-index: 2147483647; background-color: #eeeeee;'+
- 'position: fixed; display:inline-block; border: 3px solid #990000; width: 50%;"'+
- ' id="librejs_contactfinder"><b>Result:</b><br>'+
- res[0] + ": " + '<a href="' + res[1] + '>'+res[1]+'</a>';
- }
- if(typeof(res[1]) == "object"){
- to_insert = '<div style="font-size: small; z-index: 2147483647; background-color: #eeeeee;'+
- 'position: fixed; display:inline-block; border: 3px solid #990000; width: 50%;"'+
- ' id="librejs_contactfinder"><b>Result:</b><br>'+
- 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 += '<br>' + 'Possible email: <a href="' + mailto + '">'+email[i]+'</a>';
- }
- }
+function createWidget(id, tag, parent = document.body) {
+ let widget = document.getElementById(id);
+ if (widget) widget.remove();
+ widget = parent.appendChild(document.createElement(tag));
+ widget.id = id;
+ return widget;
+}
- to_insert += '</div>';
+/**
+*
+* Creates the contact finder / complain UI as a semi-transparent overlay
+*
+*/
- setTimeout(function(){document.getElementById("librejs_contactfinder").remove()}, 7500);
- document.body.insertAdjacentHTML("afterbegin",to_insert);
- return 0;
+function main() {
+ let overlay = createWidget("_LibreJS_overlay", "div");
+ let frame = createWidget("_LibreJS_frame", "iframe");
-}
+ let close = () => {
+ frame.remove();
+ overlay.remove();
+ };
-function main(){
- new_debug_button("Complain to website",handler);
-}
+ let closeListener = e => {
+ let t = e.currentTarget;
+ if (t.href) { // link navigation
+ if (t.href !== document.URL) {
+ if (t.href.includes("#")) {
+ window.addEventListener("hashchange", close);
+ }
+ return;
+ }
+ }
+ close();
+ };
+ 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 = `<h1>LibreJS Complaint</h1><button class='close'>x</button>`;
+ 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("<div>Could not guess any contact page for this site.</div>");
+ } else {
+ addHTML("<h3>Contact info guessed for this site</h3>");
+ 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}`);
+ }
+ }
-var myPort = browser.runtime.connect({name:"contact_finder"});
+ let emails = document.documentElement.textContent.match(email_regex);
+ if (emails && (emails = Array.filter(emails, e => !!e)).length) {
+ addHTML("<h5>Possible email addresses:</h5>");
+ 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");
+ }
+
+
+
+ frame.addEventListener("load", e => {
+ debug("frame loaded");
+ myPort = browser.runtime.connect({name: "contact_finder"}).onMessage.addListener(m => {
+ prefs = m;
+ initFrame();
+ });
+ });
+}
-myPort.onMessage.addListener(function(m) {
- prefs = m;
- main();
-});
+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/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 @@
<fieldset id="section-complaint"><legend>Complaint email defaults</legend>
<label for="pref_subject">Subject</label>
- <input id="pref_subject" type="text"
- value="Issues with Javascript on your website"
- />
+ <input id="pref_subject" type="text"/>
<label for="pref_body">Body</label>
- <textarea id="pref_body" rows="5"
->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]
-</textarea>
+ <textarea id="pref_body" rows="5"></textarea>
</fieldset>
</div>
</body>
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..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) {
@@ -372,7 +377,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 +1125,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 +1183,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.insertCSS(tabId, {file: "/content/overlay.css", cssOrigin: "user"}),
+ browser.tabs.executeScript(tabId, {file: "/content/contactFinder.js"}),
+ ]);
}
init_addon();