/**
* GNU LibreJSXUL - A browser add-on to block nonfree nontrivial JavaScript.
* *
* Copyright (C) 2011, 2012, 2014 Loic J. Duros
* Copyright (C) 2014, 2015 Nik Nyby
*
* This file is part of GNU LibreJSXUL.
*
* GNU LibreJSXUL 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 LibreJSXUL 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 LibreJSXUL. If not, see .
*/
var displayPanel = {
complainButton: null,
button1: null,
button2: null,
pageURL: null,
urlData: null,
isComplainButtonSet: false,
init: function () {
// add the buttons to the panel dynamically.
$('body').prepend(
'' +
'Complain to site owner' +
'' +
'' +
'Allow all scripts in this page' +
'' +
'' +
'' +
'Block all nonfree/nontrivial scripts from this page' +
'' +
'' +
'Open this report in a new tab' +
''
);
// assign properties to these new elements.
this.complainButton = $('#complain-contact');
this.button1 = $('#allow-button');
this.button2 = $('#disallow-button');
// start listening for messages sent from modules.
this.messageListen();
this.startEventHandlers();
},
startEventHandlers: function () {
$('#open-in-tab').click(function (e) {
try {
var html = $("#info").html();
var text = window.btoa(unescape(encodeURIComponent(html)));
self.port.emit('openInTab', text);
} catch (x) {
console.debug("error", x.lineNumber, x.message);
}
return false;
});
$("#ljs-settings").click(function (e) {
e.preventDefault();
self.port.emit('openSesame');
});
$(document).on('click', 'a', function(e) {
self.port.emit('hideMainPanel');
});
},
messageListen: function () {
var that = this;
self.on('message', function (message) {
that.handleMessage(message);
});
},
getHostname: function (str) {
var re = new RegExp('^(http(?:s)?://[^/]+)', 'im');
return str.match(re)[1].toString();
},
/**
* formatListScript
* Depending on the type of script in the item,
* will return a preformatted code element with
* on-page JavaScript or a link to an external
* JavaScript file.
*/
formatListScript: function (item, canWhitelist) {
var li, pre, code, a, reason = '';
li = $("
");
if (item.reason !== undefined) {
reason = item.reason;
}
if (item.inline === true) {
pre = $('');
pre.css('white-space', 'pre-wrap');
code = $('
');
reason_obj = $('').text(reason);
code.text(item.contents);
code.prepend($('
'));
code.prepend(reason_obj);
pre.append(code);
li.append(pre);
} else {
console.debug("item url is %s", item.url);
reason_obj = $('').text(reason);
li.text(item.contents);
li.prepend($('
'));
li.prepend(reason_obj);
a = $('');
a.attr('href', item.url);
a.attr('target', '_blank');
a.text(item.url);
li.append(a);
}
var $el;
if (canWhitelist) {
$el = $(
'Whitelist');
$el.data('librejs-hash', item.hash);
$el.data('librejs-url', item.url);
li.prepend($el);
} else if (item.reason.indexOf('whitelisted by user') > -1) {
// a hack until LibreJSXUL version 6.1. Need to have a value attached
// to item.whitelisted for this.
$el = $(
'' +
'Remove from Whitelist');
$el.data('librejs-hash', item.hash);
$el.data('librejs-url', item.url);
li.prepend($el);
}
return li;
},
resetButtons: function (message) {
if (!this.isComplainButtonSet) {
this.complainButton.hide();
}
if (message.contact === undefined) {
this.button1.hide();
this.button2.hide();
}
},
siteContactFound: function (url) {
this.complainButton.show();
this.isComplainButtonSet = true;
this.complainButton.off('click');
this.complainButton.click(function(e) {
e.preventDefault();
self.port.emit('hideMainPanel');
window.open(url, '_blank');
});
},
handleMessage: function (message) {
var removedLen, acceptedLen;
if (message.event === 'complaintSearch') {
return;
}
this.resetButtons(message);
// Add complain button with most certain link found
if (message.event === 'certainLinkFound' ||
message.event === 'contactLinkFound' ||
(!this.isComplainButtonSet &&
(message.event === 'probableLinkFound' ||
message.event === 'uncertainLinkFound'))
) {
var url = false;
if (message.contact && message.contact.link) {
url = message.contact.link;
} else if (message.absolute) {
url = message.absolute;
}
if (url) {
this.siteContactFound(url);
}
return;
} else if (message.event === 'contactLinkNotFound') {
// no contact link was found.
this.complainButton.hide();
}
if (message.isAllowed !== undefined) {
this.button2.show();
} else if (message.contact === undefined) {
this.button1.show();
}
var li, code, pre, len, i;
if (message.pageURL !== undefined) {
// Unset complain button on a new site
this.complainButton.off('click').hide();
this.isComplainButtonSet = false;
this.button1.attr('href', message.pageURL);
this.button2.attr('href', message.pageURL);
if (message.pageURL ===
'resource://jid1-ktlzuoiikvffew-at-jetpack/librejs/data/settings/index.html'
) {
message.pageURL = "LibreJSXUL Whitelist";
}
$('#info').css({'opacity': 0});
$('h2.blocked-js').html(
"List of blocked JavaScript in " +
$('').text(message.pageURL).html());
$('#dryrun').hide();
$('ul.blocked-js').empty();
$('ul.accepted-js').empty();
$('ul.dryrun-js').empty();
jsLabelsPagesVisited = message.urlData.jsLabelsPagesVisited;
removedLen = message.urlData.removed.length;
acceptedLen = message.urlData.accepted.length;
dryRunLen = message.urlData.dryRun.length;
// Add Web Labels info to main display panel
var $myList = $('#librejs-web-labels-pages>ul');
var idx = 0;
for (var key in jsLabelsPagesVisited) {
// Initialize and reset the element on first iteration
if (idx === 0) {
$('#librejs-web-labels-pages>h2')
.html('Web Labels pages being used for this session');
$myList.html('');
}
if (typeof key !== 'string') {
continue;
}
var myUrl = key.replace(/#librejs=true$/, '');
var $el = $(
'' +
'' +
myUrl +
'' +
'');
$myList.append($el);
idx++;
}
if (dryRunLen > 0) {
$dryRun = $("#dryrun");
$dryRun.show();
$('h2.dryrun-js')
.html("List of loaded scripts that should be blocked (but were allowed by you) in " +
$('').text(message.pageURL).html());
for (i = 0; i < dryRunLen; i++) {
li = this.formatListScript(message.urlData.dryRun[i],
true);
$('ul.dryrun-js').append(li);
}
}
if (removedLen > 0) {
$("#blocked").insertBefore($('#accepted'));
for (i = 0; i < removedLen; i++) {
this.button1.fadeIn();
li = this.formatListScript(message.urlData.removed[i],
true);
$('ul.blocked-js').append(li);
}
} else {
this.button1.hide();
$('ul.blocked-js').append('LibreJSXUL did not block any scripts on this page: \n\n- There may be no scripts on this page (check source, C-u).
- All the scripts on this page may be trivial and/or free.
- You may have whitelisted this domain name or url from the preferences (Type about:addons in your location bar to check)
- You may have clicked the "allow all scripts" button, which causes LibreJSXUL to load all JavaScript on a page regardless of whether it is free, trivial, nontrivial or nonfree. This policy is effective for the entire duration of a Firefox session.
- If for any reason you think LibreJSXUL should have blocked JavaScript code on this page, please report this issue to: bug-librejs@gnu.org
');
$('#report').attr(
'href',
'mailto:bug-librejs@gnu.org' +
'?subject=LibreJSXUL bug report' +
'&body=LibreJSXUL issue with page: ' +
message.pageURL);
}
// get accepted scripts.
$('h2.accepted-js')
.html("List of accepted " +
"JavaScript in " +
$('').text(message.pageURL).html());
if (acceptedLen > 0) {
$('#accepted').insertBefore($('#blocked'));
for (i = 0; i < acceptedLen; i++) {
li = this.formatListScript(message.urlData.accepted[i],
false);
$('ul.accepted-js').append(li);
}
} else {
$('ul.accepted-js').append(
'LibreJSXUL did not allow the execution of any scripts on this page: \n\n\'' +
'' +
'- There may be no scripts on this page (check source, C-u)
' +
'- The inline and on-page JavaScript code may not be free and/or may not have proper license information and external scripts (if present) may have been removed by default.
' +
'- External scripts may not be free and/or may not have proper licensing and are not part of the whitelist of free JavaScript libraries.
');
}
$('#info').animate({opacity: 1});
// emit allowAllClicked when button is clicked.
this.button1.click(function(e) {
console.debug('clicked allow button');
e.preventDefault();
var url = $(this).attr('href');
var urlForDisplay = (url.length > 100) ?
url.substr(0,100) + '…' : url;
var areYouSure = window.confirm(
"Allow all nonfree/nontrivial scripts on this page?\n\n" +
urlForDisplay);
if (areYouSure) {
self.port.emit('allowAllClicked', url);
}
});
this.button2.click(function(e) {
e.preventDefault();
var url = $(this).attr('href');
self.port.emit('disallowAllClicked', url);
});
var that = this;
// whitelist a script
$('.whitelist').click(function (e) {
e.preventDefault();
var $this = $(this);
// get the url of the page from main button.
var url = that.button1.attr('href');
var hash = $this.data('librejs-hash');
var reason = $this.parent('li').children('.reason').text();
if (!reason) {
reason = $this.parent('li').children('pre')
.find('.reason').text();
}
// URL of the JS file
var jsUrl = $this.data('librejs-url');
var filename = '';
if (jsUrl) {
filename = jsUrl.split('/').pop();
}
self.port.emit('whitelistByHash',
hash, url, filename, reason);
$this.parent().append(
$('')
.text("Reload page to take effect"));
$this.remove();
// Don't propagate event and call hideMainPanel.
return false;
});
$('.rm-whitelist').click(function (e) {
e.preventDefault();
var $this = $(this);
var hash = $this.data('librejs-hash');
self.port.emit('removeFromWhitelistByHash', hash);
$this.parent().append(
$('')
.text("Reload page to take effect"));
$this.remove();
// Don't propagate event and call hideMainPanel.
return false;
});
}
}
};
displayPanel.init();