diff options
Diffstat (limited to 'content')
-rw-r--r-- | content/contactFinder.js | 384 |
1 files changed, 191 insertions, 193 deletions
diff --git a/content/contactFinder.js b/content/contactFinder.js index bbb79db..439f1b1 100644 --- a/content/contactFinder.js +++ b/content/contactFinder.js @@ -36,226 +36,224 @@ //********************************************************************************************* -function debug(format, ...args) { - console.debug(`LibreJS - ${format}`, ...args); -} +(() => { + function debug(format, ...args) { + console.debug(`LibreJS - ${format}`, ...args); + } -debug("Injecting contact finder in %s", document.URL); + debug("Injecting contact finder in %s", document.URL); -/** - * contactSearchStrings - * Contains arrays of strings classified by language - * and by degree of certainty. - */ -function contactFrags() { - return [ - // de - { - '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' - ] - } - ]; -} + /** + * contactSearchStrings + * Contains arrays of strings classified by language + * and by degree of certainty. + */ + const CONTACT_FRAGS = + [ + // de + { + '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' + ] + } + ]; -function contactLinkLimit() { - return 5; -} + const CONTACT_LINK_LIMIT = 5; -// Taken from http://emailregex.com/ -function emailRegex() { - return 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); -} -//********************************************************************************************* + // Taken from http://emailregex.com/ + const 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); + //********************************************************************************************* -function findMatch(link, frag) { - const result = (link.innerText.match(new RegExp(frag, "g")) || []).filter(x => typeof x == "string"); - if (result.length) return true; - return false; -} + function findMatch(link, frag) { + const result = (link.innerText.match(new RegExp(frag, "g")) || []).filter(x => typeof x == "string"); + if (result.length) return true; + return false; + } -/** -* Tests all links on the page for regexes under a certain certainty level. -* -* Will return either all regex matches from the selected certainty level, -* up to a limit. -* -* certainty can be "certain" > "probable" > "uncertain" -*/ -function attempt(certainty, limit) { - // 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. - const matches = []; - const links = Array.from(document.links).filter(link => (typeof (link.innerText) === "string" || typeof (link.href) === "string")); - for (const link of links) { - for (const byLevel of contactFrags()) { - for (const frag of byLevel[certainty]) { - findMatch(link, frag) && matches.push(link); - if (matches.length >= limit) return { 'fail': false, 'result': [link] }; + /** + * Tests all links on the page for regexes under a certain certainty level. + * + * Will return either all regex matches from the selected certainty level, + * up to a limit. + * + * certainty can be "certain" > "probable" > "uncertain" + */ + function attempt(certainty, limit) { + // 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. + const matches = []; + const links = Array.from(document.links).filter(link => (typeof (link.innerText) === "string" || typeof (link.href) === "string")); + for (const link of links) { + for (const byLevel of CONTACT_FRAGS) { + for (const frag of byLevel[certainty]) { + findMatch(link, frag) && matches.push(link); + if (matches.length >= limit) return { 'fail': false, 'result': [link] }; + } } } + return { "fail": matches.length === 0, "result": matches }; } - return { "fail": matches.length === 0, "result": matches }; -} -/** -* "LibreJS detects contact pages and email addresses that are likely to be owned by the -* maintainer of the site." -*/ -function findContacts() { - for (const type of ["certain", "probable", "uncertain"]) { - const attempted = attempt(type, contactLinkLimit()); - if (!attempted["fail"]) { - return [type, attempted["result"]]; + /** + * "LibreJS detects contact pages and email addresses that are likely to be owned by the + * maintainer of the site." + */ + function findContacts() { + for (const type of ["certain", "probable", "uncertain"]) { + const attempted = attempt(type, CONTACT_LINK_LIMIT); + if (!attempted["fail"]) { + return [type, attempted["result"]]; + } } + return null; } - return null; -} -function createWidget(id, tag, parent = document.body) { - const oldWidget = document.getElementById(id); - if (oldWidget) oldWidget.remove(); - const widget = parent.appendChild(document.createElement(tag)); - widget.id = id; - return widget; -} + function createWidget(id, tag, parent = document.body) { + const oldWidget = document.getElementById(id); + if (oldWidget) oldWidget.remove(); + const widget = parent.appendChild(document.createElement(tag)); + widget.id = id; + return widget; + } -/** -* -* Creates the contact finder / complain UI as a semi-transparent overlay -* -*/ + /** + * + * Creates the contact finder / complain UI as a semi-transparent overlay + * + */ -function main() { - const overlay = createWidget("_LibreJS_overlay", "div"); - const frame = createWidget("_LibreJS_frame", "iframe"); + function main() { + const overlay = createWidget("_LibreJS_overlay", "div"); + const frame = createWidget("_LibreJS_frame", "iframe"); - const close = () => { - frame.remove(); - overlay.remove(); - }; + const close = () => { + frame.remove(); + overlay.remove(); + }; - // Clicking the "outer area" closes the dialog. - overlay.addEventListener("click", close); + // Clicking the "outer area" closes the dialog. + overlay.addEventListener("click", close); - const initFrame = prefs => { - debug("initFrame"); - const contentDoc = frame.contentWindow.document; + const initFrame = prefs => { + debug("initFrame"); + const contentDoc = frame.contentWindow.document; - const addText = (text, tag, wherein) => { - el = wherein.appendChild(contentDoc.createElement(tag)); - el.textContent = text; - } + const addText = (text, tag, wherein) => { + el = wherein.appendChild(contentDoc.createElement(tag)); + el.textContent = text; + } - // Header of the dialog - const { body } = contentDoc; - body.id = "_LibreJS_dialog"; - addText('LibreJS Complaint', 'h1', body); - const closeButton = body.appendChild(contentDoc.createElement('button')); - closeButton.classList.toggle('close', true); - closeButton.textContent = 'x'; - closeButton.addEventListener("click", close); + // Header of the dialog + const { body } = contentDoc; + body.id = "_LibreJS_dialog"; + addText('LibreJS Complaint', 'h1', body); + const closeButton = body.appendChild(contentDoc.createElement('button')); + closeButton.classList.toggle('close', true); + closeButton.textContent = 'x'; + closeButton.addEventListener("click", close); - const content = body.appendChild(contentDoc.createElement("div")); - content.id = "content"; + const content = body.appendChild(contentDoc.createElement("div")); + content.id = "content"; - // Add list of contact links - const res = findContacts(); - if (!res) { - content.classList.toggle("_LibreJS_fail", true); - addText('Could not guess any contact page for this site.', 'div', content); - } else { - addText('Contact info guessed for this site', 'h3', content); - addText(res[0] + ':', 'span', content); - const list = content.appendChild(contentDoc.createElement("ul")); - for (const link of res[1]) { - const a = contentDoc.createElement("a"); - a.href = link.href; - a.textContent = link.textContent; - list.appendChild(contentDoc.createElement("li")).appendChild(a); + // Add list of contact links + const res = findContacts(); + if (!res) { + content.classList.toggle("_LibreJS_fail", true); + addText('Could not guess any contact page for this site.', 'div', content); + } else { + addText('Contact info guessed for this site', 'h3', content); + addText(res[0] + ':', 'span', content); + const list = content.appendChild(contentDoc.createElement("ul")); + for (const link of res[1]) { + const a = contentDoc.createElement("a"); + a.href = link.href; + a.textContent = link.textContent; + list.appendChild(contentDoc.createElement("li")).appendChild(a); + } } - } - // Add list of emails - const emails = (document.documentElement.textContent.match(emailRegex()) || []).filter(e => !!e); - if (emails.length) { - addText("Possible email addresses:", 'h5', content); - const list = content.appendChild(contentDoc.createElement("ul")); - for (const recipient of emails.slice(0, 10)) { - const 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); + // Add list of emails + const emails = (document.documentElement.textContent.match(EMAIL_REGEX) || []).filter(e => !!e); + if (emails.length) { + addText("Possible email addresses:", 'h5', content); + const list = content.appendChild(contentDoc.createElement("ul")); + for (const recipient of emails.slice(0, 10)) { + const 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); + } } + + // contentDoc.querySelectorAll(".close, a").forEach(makeCloser); + debug("frame initialized"); } - // contentDoc.querySelectorAll(".close, a").forEach(makeCloser); - debug("frame initialized"); + frame.addEventListener("load", _ => { + debug("frame loaded"); + browser.runtime.connect({ name: "contact_finder" }).onMessage.addListener(initFrame); + }); } - frame.addEventListener("load", _ => { - debug("frame loaded"); - browser.runtime.connect({ name: "contact_finder" }).onMessage.addListener(initFrame); - }); -} - -main(); + main(); +})(); |