aboutsummaryrefslogtreecommitdiffstats
path: root/data/complain
diff options
context:
space:
mode:
Diffstat (limited to 'data/complain')
-rw-r--r--data/complain/contact_finder.js434
-rw-r--r--data/complain/contact_regex.js98
-rw-r--r--data/complain/link_types.js42
-rw-r--r--data/complain/pagemod_finder.js348
-rw-r--r--data/complain/worker_finder.js35
5 files changed, 957 insertions, 0 deletions
diff --git a/data/complain/contact_finder.js b/data/complain/contact_finder.js
new file mode 100644
index 0000000..aece488
--- /dev/null
+++ b/data/complain/contact_finder.js
@@ -0,0 +1,434 @@
+/**
+ * GNU LibreJS - A browser add-on to block nonfree nontrivial JavaScript.
+ * *
+ * Copyright (C) 2011, 2012, 2014 Loic J. Duros
+ *
+ * This program 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.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+var ContactFinder = function(options) {
+ if (typeof options === 'undefined') {
+ options = {};
+ }
+ this.complaintEmailSubject = options.complaintEmailSubject;
+ this.complaintEmailBody = options.complaintEmailBody;
+
+ // initial full list of links
+ // on a page.
+ this.pageLinks = null;
+
+ // arrays of links.
+ this.certainLinks = null;
+ this.probableLinks = null;
+ this.uncertainLinks = null;
+
+ // if not page worker,
+ // then allow to trigger a page worker.
+ this.isPageWorker = false;
+
+ // keep track of links already visited.
+ this.visitedLinks = {};
+
+ // keep track of the hostname of the original page.
+ this.originalHostname = null;
+};
+
+ContactFinder.prototype.init = function(isPageWorker) {
+ if (isPageWorker) {
+ this.isPageWorker = true;
+ console.debug('visiting', document.location.href);
+ }
+
+ this.convertStringToRegexp();
+};
+
+/**
+ * searchForContactLink Main interface method to call from outside
+ * the object.
+ */
+ContactFinder.prototype.searchForContactLink = function (originalUrl) {
+ // find hostname of original page.
+ this.originalHostname = this.getHostname(originalUrl);
+
+ // initialize arrays of links to keep.
+ this.certainLinks = [];
+ this.probableLinks = [];
+ this.uncertainLinks = [];
+
+ // select all a tags.
+ this.pageLinks = $('a').get();
+
+ this.searchForUSPhoneNumber($('body').text());
+
+ // run through list of links.
+ this.processLinks();
+};
+
+/**
+ * loopThroughLanguages
+ * Select strings for all languages.
+ */
+ContactFinder.prototype.loopThroughLanguages = function (callback) {
+ var le;
+
+ for (var language in contactStr) {
+ for (var degree in contactStr[language]) {
+ le = contactStr[language][degree].length;
+ callback(degree, contactStr[language][degree], le);
+ }
+ }
+};
+
+/**
+ * convertStringToRegexp
+ *
+ */
+ContactFinder.prototype.convertStringToRegexp = function () {
+ var regexpList, i, le;
+ this.loopThroughLanguages(function (degreeName, arr, le) {
+ for (i = 0; i < le; i++) {
+ try {
+ arr[i] = new RegExp(arr[i], 'i');
+ } catch (e) {}
+ }
+ });
+};
+
+/**
+ * processLinks
+ *
+ * Run through the list of links in a page
+ * and call the method that checks the regexs
+ * for each of them.
+ *
+ */
+ContactFinder.prototype.processLinks = function () {
+ var start = Date.now();
+ var currentLink;
+
+ while (this.pageLinks.length) {
+ currentLink = this.pageLinks.pop();
+
+ if (currentLink !== undefined) {
+ this.matchContact(currentLink);
+ }
+
+ var end = Date.now();
+
+ if (this.pageLinks.length) {
+ if ((end - start) > 8) {
+ setTimeout(this.processLinks.bind(this), 100);
+ return;
+ }
+ } else if (this.isPageWorker) {
+ self.postMessage({event: 'destroy'});
+ return;
+ }
+ }
+};
+
+/**
+ * searchForUSPhoneNumber
+ *
+ */
+ContactFinder.prototype.searchForUSPhoneNumber = function (str) {
+ var phoneMatch, phone;
+ var regClutter = /[\(\)\-\. ]+/gm;
+
+ while ((phoneMatch = usaPhoneNumber.exec(str)) !== null) {
+ phone = $.trim(phoneMatch)
+ .replace(regClutter, '-').replace(/^\-/, '');
+ phone = phone.replace(/[^0-9]$/, '');
+
+ self.postMessage({
+ event: linkTypes.PHONE_NUMBER_FOUND,
+ contact: {
+ 'label': phone,
+ 'link': 'javascript:void("' + phone + '")'
+ }
+ });
+ }
+};
+
+/**
+ * searchForSocialMedia
+ *
+ * Match a Twitter or identi.ca url.
+ *
+ */
+ContactFinder.prototype.searchForSocialMedia = function (link) {
+ var elem = $(link),
+ eventType;
+
+ var text = this.notEmptyOrUri(link);
+
+ if (reTwitter.test(elem.attr('href'))) {
+ eventType = linkTypes.TWITTER_LINK_FOUND;
+ }
+
+ else if (reIdentiCa.test(elem.attr('href'))) {
+ eventType = linkTypes.IDENTICA_LINK_FOUND;
+ }
+
+ if (eventType) {
+ self.postMessage({
+ event: eventType,
+ contact: {
+ 'label': text,
+ 'link': elem.attr('href')
+ }
+ });
+ return true;
+ }
+
+ return false;
+};
+
+/**
+ * notEmptyOrUri
+ *
+ * If link has text, use it, if not,
+ * then return uri.
+ *
+ */
+ContactFinder.prototype.notEmptyOrUri = function (link) {
+
+ var elem = $(link);
+
+ if (/([^\s]*)]/.test(elem.text())) {
+ // contains something else than just space.
+ // It is valid.
+ return elem.text();
+ } else {
+ return link.href;
+ }
+};
+
+/**
+ * searchForContactEmail
+ *
+ * Sends a particular message if a matching email
+ * is found.
+ *
+ */
+ContactFinder.prototype.searchForContactEmail = function (link) {
+ var elem = $(link),
+ eventType;
+
+ if (reEmail.test(elem.attr('href'))) {
+ console.debug('found an email address', elem.attr('href'));
+ if (this.isSameHostname(elem.attr('href'))) {
+ // this is a good email with same hostname, priceless!
+ eventType = linkTypes.CERTAIN_EMAIL_ADDRESS_FOUND;
+ } else {
+ // not the same hostname... we'll keep it just in case.
+ eventType = linkTypes.UNCERTAIN_EMAIL_ADDRESS_FOUND;
+ }
+ } else if (reAnyEmail.test(elem.attr('href'))) {
+ if (this.isSameHostname(elem.attr('href'))) {
+ eventType = linkTypes.UNCERTAIN_EMAIL_ADDRESS_FOUND;
+ }
+ }
+
+ if (eventType) {
+ var label = elem.attr('href').replace('mailto:', '');
+ var myLink = elem.attr('href');
+
+ // Add customizable complaintEmailSubject and complaintEmailBody to
+ // mailto link
+ if (this.complaintEmailSubject && this.complaintEmailBody) {
+ myLink = myLink + '?subject=' + this.complaintEmailSubject +
+ '&body=' + this.complaintEmailBody;
+ }
+
+ // we found an email address.
+ // send message with whatever event type was found.
+ self.postMessage({
+ event: eventType,
+ contact: {
+ 'label': label,
+ 'link': myLink
+ }
+ });
+ return true;
+ } else {
+ // not an email address.
+ return false;
+ }
+};
+
+/**
+ * matchContact
+ *
+ * Loop through the regexp and try to find a match.
+ *
+ */
+ContactFinder.prototype.matchContact = function (currentLink) {
+ // search for an email address.
+ if (this.searchForContactEmail(currentLink)) {
+ return true;
+ }
+ if (this.searchForSocialMedia(currentLink)) {
+ return true;
+ }
+
+ // check all contact link strings.
+ this.matchContactLink(currentLink);
+
+ // this link is worth nothing.
+ //return false;
+
+};
+
+/**
+ * matchContactLink
+ *
+ * loop through regexp for a contact link.
+ * And send a message to trigger a page worker
+ * if not currently a page worker.
+ *
+ */
+ContactFinder.prototype.matchContactLink = function (currentLink) {
+
+ var that = this;
+
+ this.loopThroughLanguages(
+ function (degreeName, arr, le) {
+ var text, j, href;
+
+ for (j = 0; j < le; j++) {
+ text = $(currentLink).text();
+ href = currentLink.href;
+
+ if (arr[j].test(text)) {
+
+ if (degreeName === 'certain') {
+
+ self.postMessage({
+ event: linkTypes.CERTAIN_LINK_FOUND,
+ contact: {
+ 'label': text,
+ 'link': href
+ }
+ });
+
+ if (!that.isPageWorker) {
+ that.complaintSearch(linkTypes.CERTAIN_LINK_FOUND, href);
+ }
+
+ } else if (degreeName === 'probable'){
+
+ self.postMessage({
+ event: linkTypes.PROBABLE_LINK_FOUND,
+ contact: {
+ 'label': text,
+ 'link': href
+ }
+ });
+
+ if (!that.isPageWorker) {
+ that.complaintSearch(linkTypes.PROBABLE_LINK_FOUND, href);
+ }
+ } else if (degreeName === 'uncertain') {
+ self.postMessage({
+ event: linkTypes.UNCERTAIN_LINK_FOUND,
+ contact: {
+ 'label': text,
+ 'link': href
+ }
+ });
+
+ if (!that.isPageWorker) {
+ that.complaintSearch(
+ linkTypes.UNCERTAIN_LINK_FOUND, href);
+ }
+ }
+ }
+ }
+ });
+};
+
+/**
+ * complaintSearch
+ * returns to ui_info a link to open.
+ */
+ContactFinder.prototype.complaintSearch = function (linkType, link) {
+ if (!this.isEmailLink(link)) {
+ // we don't want to "visit" mailto links.
+ self.postMessage({
+ event: 'complaintSearch',
+ urlSearch: {
+ 'type': linkType,
+ 'linkValue': link
+ }
+ });
+ }
+};
+
+/**
+ * getHostname
+ * small regex taken from
+ * http://beardscratchers.com/journal/using-javascript-to-get-the-hostname-of-a-url
+ * to extract hostname from url.
+ * do not consider www as subdomain.
+ *
+ */
+ContactFinder.prototype.getHostname = function (str) {
+ // remove www, but not other kind of subdomains (which most likely
+ // may not be the same site than the domain itself.)
+ str = this.removeWWW(str);
+ var urlHostname = /^(?:f|ht)tp(?:s)?\:\/\/([^\/]+)/im;
+ var emailHostname = /^mailto:[A-Z0-9\.\_\+\-]+\@([A-Z0-9\.\-]+\.[A-Z]{2,6})$/im;
+ var match1 = urlHostname.exec(str);
+ var match2 = emailHostname.exec(str);
+
+ if (match1) {
+ return match1[1];
+ } else if (match2) {
+ return match2[1];
+ }
+
+ // no match.
+ return false;
+};
+
+/**
+ * isSameHostname
+ *
+ * Checks a link has the same hostname than the original url.
+ *
+ */
+ContactFinder.prototype.isSameHostname = function (url) {
+ return this.getHostname(url) === this.originalHostname;
+};
+
+/**
+ * remove www from hostname.
+ */
+ContactFinder.prototype.removeWWW = function (str) {
+ if (typeof str !== 'string') {
+ return '';
+ }
+ return str.replace("www.", "", 'i');
+};
+
+ContactFinder.prototype.isEmailLink = function (str) {
+ if (typeof str !== 'string') {
+ return '';
+ }
+ return /^mailto:/i.test(str);
+};
+
+var contactFinder = new ContactFinder();
diff --git a/data/complain/contact_regex.js b/data/complain/contact_regex.js
new file mode 100644
index 0000000..d91735b
--- /dev/null
+++ b/data/complain/contact_regex.js
@@ -0,0 +1,98 @@
+/**
+ * GNU LibreJS - A browser add-on to block nonfree nontrivial JavaScript.
+ * *
+ * Copyright (C) 2011, 2012, 2014 Loic J. Duros
+ *
+ * This program 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.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+// 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 =
+ /(?:\+ ?1 ?)?\(?[2-9]{1}[0-9]{2}\)?(?:\-|\.| )?[0-9]{3}(?:\-|\.| )[0-9]{4}(?:[^0-9])/mg;
diff --git a/data/complain/link_types.js b/data/complain/link_types.js
new file mode 100644
index 0000000..fefd4fd
--- /dev/null
+++ b/data/complain/link_types.js
@@ -0,0 +1,42 @@
+/**
+ * GNU LibreJS - A browser add-on to block nonfree nontrivial JavaScript.
+ * *
+ * Copyright (C) 2011, 2012 Loic J. Duros
+ *
+ * This program 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.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+var linkTypes = {
+
+ // constants. Also available in lib/ui_info.js
+ 'CERTAIN_EMAIL_ADDRESS_FOUND': 'certainEmailAddressFound',
+ 'UNCERTAIN_EMAIL_ADDRESS_FOUND': 'uncertainEmailAddressFound',
+
+ // Looking for contact links
+ 'CERTAIN_LINK_FOUND': 'certainLinkFound',
+ 'PROBABLE_LINK_FOUND': 'probableLinkFound',
+ 'UNCERTAIN_LINK_FOUND': 'uncertainLinkFound',
+ 'LINK_NOT_FOUND': 'contactLinkNotFound',
+
+ // Looking for identi.ca and twitter accounts.
+ 'TWITTER_LINK_FOUND': 'twitterLinkFound',
+ 'IDENTICA_LINK_FOUND': 'identicaLinkFound',
+
+ // phone number and address
+ 'PHONE_NUMBER_FOUND': 'phoneNumberFound',
+ 'SNAIL_ADDRESS_FOUND': 'snailAddressFound'
+
+};
+
diff --git a/data/complain/pagemod_finder.js b/data/complain/pagemod_finder.js
new file mode 100644
index 0000000..e74bda6
--- /dev/null
+++ b/data/complain/pagemod_finder.js
@@ -0,0 +1,348 @@
+/**
+ * GNU LibreJS - A browser add-on to block nonfree nontrivial JavaScript.
+ * *
+ * Copyright (C) 2011, 2012, 2014 Loic J. Duros
+ *
+ * This program 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.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/**
+ * PageModFinder controls the complaint panel appearance.
+ * @class
+ */
+var PageModFinder = function() {
+ this.stylesheet = null;
+ this.displayPanel = false;
+ this.links = null;
+ this.$box = null;
+
+ this.$button = null;
+ this.buttonTop = 40;
+
+ this.$infoBox = null;
+
+ this.isMinimized = true;
+ this.isDragging = false;
+};
+
+PageModFinder.prototype.init = function() {
+ var that = this, le;
+
+ this.links = [];
+
+ var complaintEmailSubject;
+ var complaintEmailBody;
+
+ self.port.on('prefs', function(payload) {
+ if (payload.complaintEmailSubject) {
+ complaintEmailSubject = payload.complaintEmailSubject;
+ }
+ if (payload.complaintEmailBody) {
+ complaintEmailBody = payload.complaintEmailBody;
+ }
+ });
+
+ self.port.on('complaintLinkFound', function(payload) {
+ if (payload.contact !== undefined) {
+ that.displayLinkByPriority(payload);
+ }
+ });
+
+ self.port.on('assetsUri', function(payload) {
+ that.setComplaintPanel(payload.value);
+ });
+
+ self.port.on('pageUrl', function(payload) {
+ // search for contact list. Top level.
+ contactFinder = new ContactFinder({
+ complaintEmailSubject: complaintEmailSubject,
+ complaintEmailBody: complaintEmailBody
+ });
+ contactFinder.init();
+ contactFinder.searchForContactLink(payload.value);
+ });
+};
+
+/**
+ * setComplaintPanel
+ *
+ * Create complaint panel and assign properties to the
+ * dom elements.
+ *
+ */
+PageModFinder.prototype.setComplaintPanel = function (uri) {
+ // provide uri of stylesheet
+ this.stylesheet = uri + 'css/style.css';
+
+ // add stylesheet.
+ $('head').append($('<link/>').attr({
+ 'rel': 'stylesheet',
+ 'href': this.stylesheet,
+ 'type': 'text/css'
+ }));
+
+ $('body').prepend(
+ '<div id="librejs-complaint-box" style="display:none;">' +
+
+ '<div id="librejs-tab-button">' +
+ '<div class="librejs-complain-button" ' +
+ 'title="LibreJS -- Complain to this site"></div>' +
+ '<div class="librejs-complain-separator"></div>' +
+ '</div>' +
+
+ '<div id="librejs-complaint-info">' +
+ '<div class="librejs-hide-button" title="Hide">' +
+ '&times;</div>' +
+ '<h1 title="Nonfree JavaScript -- Complain">\n' +
+ 'Nonfree JavaScript Complain</h1>' +
+ '<p id="librejs-time-mention">' +
+ 'Searching for contact links in this website&hellip;</p>' +
+
+ '<div id="librejs-complaint-info-text">' +
+
+ '<h2>Emails you should use</h2>' +
+ '<ul id="librejs-certain-emails"></ul>' +
+
+ '<h2>Non-webmaster Emails you might want to use</h2>' +
+ '<ul id="librejs-uncertain-emails"></ul>' +
+
+ '<h2>Contact form or useful Contact Information</h2>' +
+ '<ul id="librejs-certain-links"></ul>' +
+
+ '<h2>Twitter Links</h2>' +
+ '<ul id="librejs-twitter-links"></ul>' +
+
+ '<h2>Identi.ca Links</h2>' +
+ '<ul id="librejs-identica-links"></ul>' +
+
+ '<h2>May be of interest</h2>' +
+ '<ul id="librejs-uncertain-links"></ul>' +
+
+ '<h2>May be of interest</h2>' +
+ '<ul id="librejs-probable-links"></ul>' +
+
+ '<h2>Phone Numbers</h2>' +
+ '<ul id="librejs-phone-numbers"></ul>' +
+
+ '<h2>Snail Mail Addresses</h2>' +
+ '<ul id="librejs-snail-addresses"></ul>' +
+
+ '</div>' + // end #librejs-complaint-info-text
+ '</div>' + // end #librejs-complaint-info
+ '</div>' // end #librejs-complaint-box
+ );
+
+ // main elements of the complaint panel.
+ this.$infoBox = $('#librejs-complaint-info');
+ this.$infoBoxText = $('#librejs-complaint-info-text');
+
+ // all lists.
+ this.$certainEmails = $("#librejs-certain-emails");
+ this.$uncertainEmails = $("#librejs-uncertain-emails");
+ this.$certainLinks = $("#librejs-certain-links");
+ this.$uncertainLinks = $("#librejs-uncertain-links");
+ this.$probablLinks = $("#librejs-probable-links");
+ this.$twitterLinks = $("#librejs-twitter-links");
+ this.$identicaLinks = $("#librejs-identica-links");
+ this.$phoneNumbers = $("#librejs-phone-numbers");
+ this.$snailAddresses = $("#librejs-snail-addresses");
+
+ this.$button = $('#librejs-tab-button');
+ this.$box = $('#librejs-complaint-box');
+
+ this.$infoBox.height($(window).height() - this.buttonTop);
+ this.$infoBoxText.height(this.$infoBox.height() - 154);
+};
+
+/**
+ * displayLinkByPriority
+ *
+ * Place the link in the correct list depending
+ * on the correct
+ */
+PageModFinder.prototype.displayLinkByPriority = function(respData) {
+ // we have a link to show. Add it to the button.
+ // first time finalLinkFound is triggered.
+ if (this.displayPanel === false) {
+
+ this.addComplaintOverlay();
+ this.displayPanel = true;
+ this.hideBox(true);
+ }
+
+ // check link isn't already added.
+ if (respData.contact !== undefined &&
+ !this.isInLinks(respData.contact.link)) {
+
+ // push link to list.
+ le = this.links.push(respData);
+
+ // making sure this is the latest link added.
+ this.addALinkToPanel(this.links[le -1]);
+ }
+};
+
+PageModFinder.prototype.isInLinks = function(searchValue) {
+ var i = 0,
+ le = this.links.length;
+
+ for (; i < le; i++) {
+ if (this.links[i].contact.link.replace(/\/$/, '') ===
+ searchValue.replace(/\/$/, '')
+ ) {
+ return true;
+ }
+ }
+
+ // no match has been found.
+ return false;
+};
+
+/**
+ * addALinkToPanel
+ *
+ * Check the type of link and place it in the
+ * appropriate list in the complaint panel.
+ */
+PageModFinder.prototype.addALinkToPanel = function(link) {
+ var listElem;
+
+ switch (link.event) {
+ case linkTypes.CERTAIN_EMAIL_ADDRESS_FOUND:
+ listElem = this.$certainEmails;
+ break;
+
+ case linkTypes.UNCERTAIN_EMAIL_ADDRESS_FOUND:
+ listElem = this.$uncertainEmails;
+ break;
+
+ case linkTypes.CERTAIN_LINK_FOUND:
+ listElem = this.$certainLinks;
+ break;
+
+ case linkTypes.PROBABLE_LINK_FOUND:
+ listElem = this.$probablLinks;
+ break;
+
+ case linkTypes.UNCERTAIN_LINK_FOUND:
+ listElem = this.$uncertainLinks;
+ break;
+
+ case linkTypes.TWITTER_LINK_FOUND:
+ listElem = this.$twitterLinks;
+ break;
+
+ case linkTypes.IDENTICA_LINK_FOUND:
+ listElem = this.$identicaLinks;
+ break;
+
+ case linkTypes.PHONE_NUMBER_FOUND:
+ listElem = this.$phoneNumbers;
+ break;
+
+ case linkTypes.SNAIL_ADDRESS_FOUND:
+ listElem = this.$snailAddresses;
+ break;
+ }
+
+ listElem.prev('h2').css({'display': 'block'});
+ listElem.append($('<li/>').append($('<a/>').attr({
+ 'href': link.contact.link,
+ 'target': '_blank'
+ }).text(link.contact.label)));
+};
+
+PageModFinder.prototype.addComplaintOverlay = function() {
+ var that = this;
+
+ this.$button.click(function() {
+ if (!that.isDragging) {
+ that.showBox();
+ }
+ return false;
+ });
+
+ this.$button.on('mousedown', function(e) {
+ var startPageY = e.pageY;
+ var baseY = that.$button.offset().top - startPageY;
+ var windowHeight = $(window).height();
+ var buttonHeight = that.$button.height();
+
+ $(document).on('mousemove.librejs', function(e2) {
+ if (that.isDragging || e2.pageY !== startPageY) {
+ var top = baseY + e2.clientY;
+ if (top < 0) {
+ top = 0;
+ } else if (
+ top + buttonHeight + that.buttonTop - 6 > windowHeight
+ ) {
+ top = windowHeight - buttonHeight - that.buttonTop + 6;
+ }
+ that.$button.css({top: top});
+ that.isDragging = true;
+ }
+ });
+ return false;
+ });
+
+ $(document).on('mouseup', function() {
+ $(document).off('mousemove.librejs');
+ if (that.isDragging) {
+ setTimeout(function() {
+ that.isDragging = false;
+ }, 10);
+ return false;
+ }
+ });
+
+ $(document).keyup(function(e) {
+ if (that.isMinimized === false) {
+ e.preventDefault();
+ if (e.which === 27) {
+ // Escape was pressed
+ that.hideBox();
+ }
+ }
+ });
+
+ this.$box.find('.librejs-hide-button').on('click', function() {
+ that.hideBox();
+ });
+
+ this.$button.on('focus', function() { that.showBox(); });
+ this.$box.on('blur', function() { that.hideBox(); });
+
+ this.$box.css({'display': 'block'});
+};
+
+PageModFinder.prototype.showBox = function() {
+ this.$box.css({right: '-2px'});
+ this.isMinimized = false;
+ this.$button.hide();
+
+ var that = this;
+ $('#librejs-complaint-info').mouseleave(function() {
+ that.hideBox();
+ });
+};
+
+PageModFinder.prototype.hideBox = function() {
+ this.$box.css({right: '-465px'});
+ this.isMinimized = true;
+ this.$button.show();
+ $('#librejs-complaint-info').off('mouseleave');
+};
+
+var pageModFinder = new PageModFinder();
diff --git a/data/complain/worker_finder.js b/data/complain/worker_finder.js
new file mode 100644
index 0000000..2cda32e
--- /dev/null
+++ b/data/complain/worker_finder.js
@@ -0,0 +1,35 @@
+/**
+ * GNU LibreJS - A browser add-on to block nonfree nontrivial JavaScript.
+ * *
+ * Copyright (C) 2011, 2012 Loic J. Duros
+ *
+ * This program 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.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+var workerFinder = {
+
+ init: function () {
+
+ var that = this;
+ console.debug('searching with pageworker');
+
+ contactFinder.init(true);
+ contactFinder.searchForContactLink(window.location.href);
+
+ }
+
+};
+
+workerFinder.init();