diff options
Diffstat (limited to 'html')
-rw-r--r-- | html/display_panel/content/display-panel.html | 68 | ||||
-rw-r--r-- | html/display_panel/content/main_panel.js | 341 | ||||
-rw-r--r-- | html/display_panel/content/panel-styles.css | 124 |
3 files changed, 241 insertions, 292 deletions
diff --git a/html/display_panel/content/display-panel.html b/html/display_panel/content/display-panel.html index 0fc18a7..2ed0c9c 100644 --- a/html/display_panel/content/display-panel.html +++ b/html/display_panel/content/display-panel.html @@ -41,35 +41,61 @@ <h1 class="libre">LibreJS</h1> </a> </div> - <div> - <a target="_blank" href="https://www.gnu.org/software/librejs/" - id="librejs-web-link">gnu.org/software/librejs</a> - </div> - <div> - <strong>LibreJS <span id="version"></span></strong> - </div> </div> <div id="buttons" class="title-area"> - <table id="buttons_table"> - </table> + <div> + <a target="_blank" href="https://www.gnu.org/software/librejs/" + id="librejs-web-link">gnu.org/software/librejs</a> + </div> + <div> + <strong>LibreJS <span id="version"></span></strong> + </div> + <button id="complain">Complain to site owner</button> + <button id="report-tab">Show this report in a new tab</button> </div> </div> <div id="info"> - <div id="whitelisted"> - <h2 class="blocked-js"></h2> - <ul class="blocked-js"></ul> + <div id="site"> + <h2 class="site">This whole site <span></span></h2> + <div class="buttons"> + <button class="whitelist" name="*">Whitelist</button> + <button class="blacklist" name="*">Blacklist</button> + <button class="forget" name="*">Forget</button> + </div> + </div> + <div id="unknown" class="unknown-js"> + <h2></h2> + <p id="must-reload"> + LibreJS will decide whether blocking these scripts next time this page is loaded. <button id="reload">Reload it now</button> + </p> + <ul> + <li id="li-template"> + <a class="script-url" href="#"></a>: + <p class="reason"></p> + <div class="buttons"> + <button class="whitelist">Whitelist</button> + <button class="blacklist">Blacklist</button> + <button class="forget">Forget</button> + <button class="forget" name="*">Forget <span class="domain"></span></button> + </div> + </li> + </ul> + </div> + <div id="whitelisted" class="accepted-js"> + <h2></h2> + <ul></ul> </div> - <div id="accepted"> - <h2 class="blocked-js"></h2> - <ul class="blocked-js"></ul> + <div id="accepted" class="accepted-js"> + <h2></h2> + <ul></ul> </div> - <div id="blocked"> - <h2 class="blocked-js"></h2> - <ul class="blocked-js"></ul> + <div id="blocked" class="blocked-js"> + <h2></h2> + <ul></ul> </div> - <div id="blacklisted"> - <h2 class="blocked-js"></h2> - <ul class="blocked-js"></ul> + <div id="blacklisted" class="blocked-js"> + <h2></h2> + <ul></ul> </div> </div> </body> diff --git a/html/display_panel/content/main_panel.js b/html/display_panel/content/main_panel.js index 8622493..a6e19dc 100644 --- a/html/display_panel/content/main_panel.js +++ b/html/display_panel/content/main_panel.js @@ -1,247 +1,172 @@ - /** - * GNU LibreJS - A browser add-on to block nonfree nontrivial JavaScript. - * * - * Copyright (C) 2017, 2018 NateN1222 <nathannichols454@gmail.com> - * Copyright (C) 2018 Ruben Rodriguez <ruben@gnu.org> - * Copyright (C) 2018 Giorgio Maone <giorgio@maone.net> - * - * 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/>. - * - */ - /** -* -* Sets global variable "webex" to either "chrome" or "browser" for -* use on Chrome or a Firefox variant. +* GNU LibreJS - A browser add-on to block nonfree nontrivial JavaScript. +* * +* Copyright (C) 2017, 2018 NateN1222 <nathannichols454@gmail.com> +* Copyright (C) 2018 Ruben Rodriguez <ruben@gnu.org> +* Copyright (C) 2018 Giorgio Maone <giorgio@maone.net> +* +* 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. * -* Change this to support a new browser that isn't Chrome or Firefox, -* given that it supports webExtensions. +* 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/>. * -* (Use the variable "webex" for all API calls after calling this) */ -var PRINT_DEBUG = false; -function dbg_print(a,b){ - if(PRINT_DEBUG == true){ - if(b === undefined){ - console.log(a); - } else{ - console.log(a,b); - } - } -} - -var webex; -function set_webex(){ - if(typeof(browser) == "undefined"){ - webex = chrome; - } else{ - webex = browser; - } +var fromTab = window.location.hash.match(/^#fromTab=(\d+)/) && RegExp.$1; +if (fromTab) { + let browserStyle = document.createElement("link"); + browserStyle.rel = "stylesheet"; + browserStyle.href = "chrome://browser/content/extension.css"; + document.head.appendChild(browserStyle); + document.documentElement.classList.add("tab"); } -set_webex(); - -var myPort = webex.runtime.connect({name:"port-from-cs"}); -var current_blocked_data; +var myPort = browser.runtime.connect({name: "port-from-cs"}); +var currentReport; +// Sends a message that tells the background script the window is open +myPort.postMessage({"update": true, tabId: parseInt(currentReport && currentReport.tabId || fromTab) || ""}); // Display the actual extension version Number document.querySelector("#version").textContent = browser.runtime.getManifest().version; -/* -* Makes a button appear that calls a function when you press it. -* -* I copied and pasted this from something else I wrote. It's quite useful. -* -*/ -var button_i = 0; -function new_debug_button(name_text,callback){ - 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_' + button_i + '" value="' + name_text +'"type="button"></input><br>'; - document.getElementById("abc123_main_div").insertAdjacentHTML('afterbegin', button_html); - document.getElementById("abc123_button_"+button_i).addEventListener("click",callback); - button_i = button_i + 1; -} - - +var liTemplate = document.querySelector("#li-template"); +liTemplate.remove(); + +document.querySelector("#info").addEventListener("click", e => { + let button = e.target; + if (!button.matches(".buttons > button")) return; + let li = button.closest("li"); + let entry = li && li._scriptEntry || [currentReport.url, "Page's site"]; + let action = button.className; + let site = button.name === "*"; + if (site) { + ([action] = action.split("-")); + } + myPort.postMessage({[action]: entry, site}); +}); +document.querySelector("#report-tab").onclick = e => { + myPort.postMessage({report_tab: currentReport}); + close(); +} +document.querySelector("#complain").onclick = e => { + myPort.postMessage({invoke_contact_finder: currentReport}); + close(); +} +document.querySelector("#reload").onclick = async e => { + let {tabId} = currentReport; + if (tabId) { + await browser.tabs.reload(tabId); + } +}; /* -* Takes in the script data and color of h2 element -* Writes to category specified by "name" as used in HTML -* (name will probably either be "blacklisted", "whitelisted", "accepted", or "blocked") +* Takes in the [[file_id, reason],...] array and the group name for one group +* of scripts found in this tab, rendering it as a list with management buttons. +* Groups are "unknown", "blacklisted", "whitelisted", "accepted", and "blocked". */ -function write_elements(data,name,color){ - var url = data["url"]; - var button_html = '<div style="float:left;"><input id="temp" type="button" value="blacklist"></input></div>'; - var button_html_2 = '<div style="float:left;"><input id="temp2" type="button" value="whitelist"></input></div>'; - var button_html_3 = '<div style="float:left;"><input id="temp3" type="button" value="forget preference"></input></div>'; - var heading = document.getElementById(name).getElementsByTagName("h2")[0]; - var list = document.getElementById(name).getElementsByTagName("ul")[0]; - if(typeof(data[name]) == "undefined" || data[name].length == 0){ - // default message - list.innerHTML = "<li>No "+ name +" scripts on this page.</li>" - data[name] = []; - } else{ - heading.innerHTML = "<h2 class='blocked-js'>List of <div style='display:inline; color:"+color+";'>" + name.toUpperCase() + "</div> javascript in " + data["url"]+":</h2>"; - } - // Iterate over data[name] and generate list - for(var i = 0; i < data[name].length; i++){ - list.innerHTML += "<li><a href='"+data[name][i][0]+"'><b>"+data[name][i][0]+ "</a>:</b><br>" + data[name][i][1]+"<br>"+button_html+"\n"+button_html_2+"\n"+button_html_3+"</li>"; - document.getElementById("temp").id = name+"_"+i; - document.getElementById("temp2").id = name+"_2_"+i; - document.getElementById("temp3").id = name+"_3_"+i; - } - if(data[name].length != 0){ - // add click listeners to the buttons - for(var i = 0; i < data[name].length; i++){ - // Make sure this causes generate_html to get called again with updated data - document.getElementById(name+"_"+i).addEventListener("click",function(info){ - var temp = current_blocked_data[name][parseInt(info.target.id.match(/\d/g)[0])]; - console.log("Moving script " + temp[0] + " to blacklist"); - var script_name = this.parentElement.parentElement.parentElement.parentElement.id; - myPort.postMessage({"blacklist": temp}); - }); - document.getElementById(name+"_2_"+i).addEventListener("click",function(info){ - var temp = current_blocked_data[name][parseInt(info.target.id.match(/\d+/g)[1])]; - console.log("Moving script " + temp[0] + " to whitelist"); - var script_name = this.parentElement.parentElement.parentElement.parentElement.id; - myPort.postMessage({"whitelist": temp}); - }); - - document.getElementById(name+"_3_"+i).addEventListener("click",function(info){ - var temp = current_blocked_data[name][parseInt(info.target.id.match(/\d/g)[1])]; - console.log("Forget preferences for script " + temp[0]); - var script_name = this.parentElement.parentElement.parentElement.parentElement.id; - //this.parentElement.parentElement.getElementsByTagName("b")[0].insertAdjacentHTML("beforebegin","<h3>Refresh the page to revaluate this script.</h3>"); - myPort.postMessage({"forget": temp}); - }); - } - } +function createList(data, group){ + var {url} = data; + let entries = data[group]; + let container = document.getElementById(group); + let heading = container.querySelector("h2"); + var list = container.querySelector("ul"); + list.classList.toggle(group, true); + if (Array.isArray(entries) && entries.length) { + heading.innerHTML = `<span class="type-name">${group}</span> scripts in ${url}:`; + container.classList.remove("empty"); + } else { + // default message + list.innerHTML = `<li>No <span class="type-name">${group}</span> scripts on this page.</li>` + entries = data[group] = []; + container.classList.add("empty"); + } + // generate list + for (let entry of entries) { + let [scriptId, reason] = entry; + let li = liTemplate.cloneNode(true); + let a = li.querySelector("a"); + a.href = scriptId.split("(")[0]; + a.textContent = scriptId; + li.querySelector(".reason").textContent = reason; + let bySite = !!reason.match(/https?:\/\/[^/]+\/\*/); + li.classList.toggle("by-site", bySite); + if (bySite) { + let domain = li.querySelector(".forget .domain"); + if (domain) domain.textContent = RegExp.lastMatch; + } + li._scriptEntry = entry; + list.appendChild(li); + } } /** -* displays the button specified by HTML string "button" -*/ -var template = '<tr><td id="c1"></td><td id="c2"></td></tr>'; -var lr_flag = true; -var button_num = 0; -function write_button(button,callback){ - if(document.getElementById("buttons_table").innerHTML.indexOf(button) != -1){ - return; - } - var id = "buttonno_"+button_num; - if(lr_flag){ - document.getElementById("buttons_table").insertAdjacentHTML("beforeend",template); - document.getElementById("c1").insertAdjacentHTML("beforeend","<div id='"+id+"'>" + button + "</div>"); - document.getElementById("c1").id = "cell_"+button_num; - }else{ - var temp = document.getElementById("c2"); - temp.id = "cell_"+button_num; - temp.insertAdjacentHTML("beforeend","<div id='"+id+"'>" + button + "</div>"); - } - - button_num = button_num+1; - lr_flag = !lr_flag; - - document.getElementById(id).addEventListener("click",callback); -} -/** -* update the HTML of the pop-up window. +* Updates scripts lists and buttons to act on them. * If return_HTML is true, it returns the HTML of the popup window without updating it. -* example input: -* -* var example_input = { +* example report argument: +* { * "accepted": [["FILENAME 1","REASON 1"],["FILENAME 2","REASON 2"]], * "blocked": [["FILENAME 1","REASON 1"],["FILENAME 2","REASON 2"]], * "whitelisted": [["FILENAME 1","REASON 1"],["FILENAME 2","REASON 2"]], * "blacklisted": [["FILENAME 1","REASON 1"],["FILENAME 2","REASON 2"]], +* "unknown": [["FILENAME 1","REASON 1"],["FILENAME 2","REASON 2"]], * "url":"example.com" * }; * */ -function generate_HTML(blocked_data){ - current_blocked_data = blocked_data;//unused? - - // This should send a message to invoke the content finder - var button_complain = '<a id="complain-contact" class="button white" href="#">Complain to site owner</a>'; - // This should update the persistent options - var button_allow_all = '<a id="allow-button" class="button white" href="#">'+"Add page's domain to whitelist"+'</a>'; - // This will call "Forget preferences" on every script. - var button_block_nonfree = '<a id="disallow-button" class="button white" href="#">'+"Remove page's domain from whitelist"+'</a>'; - // This should send a message that calls "open_popup_tab()" in the background script - var button_new_tab = '<a id="open-in-tab" class="button white" href="#">Open this report in a new tab</a>'; - - var to_clr = document.getElementsByClassName("blocked-js"); - - for(var i = 0; i < to_clr.length; i++){ - to_clr[i].innerHTML = ""; - } - dbg_print("REGEN HTML:"); - dbg_print(blocked_data); - write_elements(blocked_data,"accepted","green"); - write_elements(blocked_data,"whitelisted","green"); - write_elements(blocked_data,"blocked","red"); - write_elements(blocked_data,"blacklisted","red"); - - if( blocked_data["blacklisted"].length != 0 || blocked_data["blocked"].length != 0 || - blocked_data["whitelisted"].length != 0 || blocked_data["accepted"].length != 0){ - write_button(button_allow_all,function(){ - myPort.postMessage({"allow_all": blocked_data}); - }); - write_button(button_block_nonfree,function(){ - myPort.postMessage({"block_all": blocked_data}); - - }); - write_button(button_complain,function(){ - myPort.postMessage({"invoke_contact_finder": blocked_data}); - }); - write_button(button_new_tab,function(){ - myPort.postMessage({"open_popup_tab": blocked_data}); - }); - } else{ - write_button(button_new_tab,function(){ - myPort.postMessage({"open_popup_tab": blocked_data}); - }); - } +function refreshUI(report){ + console.debug("refreshUI", report); + currentReport = report; + + document.querySelector("#site").className = report.siteStatus || ""; + document.querySelector("#site h2").textContent = + `This site ${report.site}`; + + for (let toBeErased of document.querySelectorAll("#info h2:not(.site) > *, #info ul > *")) { + toBeErased.remove(); + } + + let scriptsCount = 0; + for (let group of ["unknown", "accepted", "whitelisted", "blocked", "blacklisted"]) { + if (group in report) createList(report, group); + scriptsCount += report[group].length; + } + + for (let b of document.querySelectorAll(`.forget, .whitelist, .blacklist`)) { + b.disabled = false; + } + for (let b of document.querySelectorAll( + `.unknown .forget, .accepted .forget, .blocked .forget, + .whitelisted .whitelist, .blacklisted .blacklist` + )) { + b.disabled = true; + } + + let noscript = scriptsCount === 0; + document.body.classList.toggle("empty", noscript); } -myPort.onMessage.addListener(function(m) { - if(m["show_info"] !== undefined){ - generate_HTML(m["show_info"]); - } +myPort.onMessage.addListener(m => { + if (m.show_info) { + refreshUI(m.show_info); + } }); -// Sends a message that tells the background script the window is open -function onGot(tabInfo) { - myPort.postMessage({"tab_info": tabInfo}); -} -var gettingCurrent = webex.tabs.getCurrent(onGot); - function print_local_storage(){ - myPort.postMessage({"printlocalstorage": true}); + myPort.postMessage({"printlocalstorage": true}); } function delete_local_storage(){ - myPort.postMessage({"deletelocalstorage":true}); + myPort.postMessage({"deletelocalstorage":true}); } - -//new_debug_button("Print local storage",print_local_storage); -//new_debug_button("Clear local storage",delete_local_storage); diff --git a/html/display_panel/content/panel-styles.css b/html/display_panel/content/panel-styles.css index c077a31..745c67f 100644 --- a/html/display_panel/content/panel-styles.css +++ b/html/display_panel/content/panel-styles.css @@ -68,17 +68,18 @@ ul { padding:0; list-style:none; } -ul.blocked-js li, ul.accepted-js li, ul.dryrun-js li { +#info li { padding:5px; border-bottom:2px solid #CCC; margin:0; + overflow: hidden; } -ul ul { +#info ul ul { margin:10px; list-style:disc; } -ul.blocked-js ul li, ul.accepted-js ul li, ul.dryrun-js ul li { +#info ul ul li { padding:5px; border-bottom:0; } @@ -86,63 +87,48 @@ ul.blocked-js ul li, ul.accepted-js ul li, ul.dryrun-js ul li { clear:both; } -/* - Pure JS button styles below taken from: - http://webdesignerwall.com/tutorials/css3-gradient-buttons - */ -.button { - display: inline-block; - outline: none; - cursor: pointer; - text-align: center; - text-decoration: none; - font-size: 1 em; - border-radius: .5em; - float:right; - padding:10px; -} -.small.button { - font-size:11px; - padding:.5em .5em; - margin-top:10px; -} -.button:hover { - text-decoration: none; -} -.button:active { - position: relative; - top: 1px; -} -.orange { - color: #fef4e9; - border: solid 1px #da7c0c; - background: #f78d1d; - background: -webkit-gradient(linear, left top, left bottom, from(#faa51a), to(#f47a20)); - background: -moz-linear-gradient(top, #faa51a, #f47a20); -} -.orange:hover { - background: #f47c20; - background: -webkit-gradient(linear, left top, left bottom, from(#f88e11), to(#f06015)); - background: -moz-linear-gradient(top, #f88e11, #f06015); -} -.orange:active { - color: #fcd3a5; - background: -webkit-gradient(linear, left top, left bottom, from(#f47a20), to(#faa51a)); - background: -moz-linear-gradient(top, #f47a20, #faa51a); -} -.white { - background: -moz-linear-gradient(center top , #FFFFFF, #EDEDED) repeat scroll 0 0 transparent; - border: 1px solid #B7B7B7; - /* color: #606060;*/ - color:#9d0d0d; -} -.white:hover { - background: -moz-linear-gradient(center top , #FFFFFF, #DCDCDC) repeat scroll 0 0 transparent; -} -.white:active { - background: -moz-linear-gradient(center top , #EDEDED, #FFFFFF) repeat scroll 0 0 transparent; -/*color: #999999;*/ - +#info .type-name { + text-transform: uppercase; + font-weight: bold; +} + +#info .accepted-js .type-name { + color: #080; +} + +#info .blocked-js .type-name { + color: #800; +} + +#info .unknown-js .type-name { + color: #008; +} + +#info .unknown-js .reason { + display: none; +} + +.by-site button.forget, button.forget[name="*"] { + display: none; +} + +.by-site button.forget[name="*"], #site .forget[name="*"] { + display: initial; +} + + +button.whitelist { + color: #080; +} +button.blacklist { + color: #800; +} +button.forget { + color: #008; +} + +button:disabled { + color: #888 !important; } span.accepted, span.blocked { @@ -151,9 +137,7 @@ span.accepted, span.blocked { font-variant:small-caps; font-weight:bold; } -ul.blocked-js li { - overflow:hidden; -} + span.blocked { color:#8e0000; } @@ -173,3 +157,17 @@ span.blocked { font-size: 14px; list-style-type: disc; } + + +.empty #site, .unknown-js.empty { + display: none; +} + +.tab #must-reload, .tab #buttons, .empty #buttons { + display: none; +} + +#buttons button { + width: 100%; + text-align: center; +} |