From 9884643742b54b88f94111d62f5e89a12a60e604 Mon Sep 17 00:00:00 2001 From: hackademix Date: Tue, 26 Mar 2019 22:45:37 +0100 Subject: Subdomain wildcard support. --- html/display_panel/content/main_panel.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'html/display_panel') diff --git a/html/display_panel/content/main_panel.js b/html/display_panel/content/main_panel.js index 83c3a6b..9172265 100644 --- a/html/display_panel/content/main_panel.js +++ b/html/display_panel/content/main_panel.js @@ -59,6 +59,7 @@ document.querySelector("#info").addEventListener("click", e => { setTimeout(close, 100); return; } + if (!button.tagName === "BUTTON") button = button.closest("button"); if (button.matches(".toggle-source")) { let parent = button.parentNode; if (!parent.querySelector(".source").textContent) { @@ -69,10 +70,13 @@ document.querySelector("#info").addEventListener("click", e => { return; } if (!button.matches(".buttons > button")) return; + let domain = button.querySelector(".domain"); + let li = button.closest("li"); let entry = li && li._scriptEntry || [currentReport.url, "Page's site"]; let action = button.className; - let site = button.name === "*"; + let site = domain ? domain.textContent : button.name === "*" ? currentReport.site : ""; + if (site) { ([action] = action.split("-")); } -- cgit v1.2.3 From f128d868d319c45222e451af75e3aa397b7f8144 Mon Sep 17 00:00:00 2001 From: hackademix Date: Mon, 8 Apr 2019 18:37:54 +0200 Subject: Add permanent reload button in the popup UI (in the "whole site" information line). --- html/display_panel/content/display-panel.html | 3 ++- html/display_panel/content/main_panel.js | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'html/display_panel') diff --git a/html/display_panel/content/display-panel.html b/html/display_panel/content/display-panel.html index 5b9f99f..3221ded 100644 --- a/html/display_panel/content/display-panel.html +++ b/html/display_panel/content/display-panel.html @@ -64,12 +64,13 @@ +

- LibreJS will decide whether blocking these scripts next time this page is loaded. + LibreJS will decide whether blocking these scripts next time this page is loaded.

  • diff --git a/html/display_panel/content/main_panel.js b/html/display_panel/content/main_panel.js index 83c3a6b..85c9474 100644 --- a/html/display_panel/content/main_panel.js +++ b/html/display_panel/content/main_panel.js @@ -94,13 +94,14 @@ document.querySelector("#open-options").onclick = e => { close(); } -document.querySelector("#reload").onclick = async e => { +document.body.addEventListener("click", async e => { + if (!e.target.matches(".reload")) return; let {tabId} = currentReport; if (tabId) { await browser.tabs.reload(tabId); myPort.postMessage({"update": true, tabId}); } -}; +}); /* * Takes in the [[file_id, reason],...] array and the group name for one group -- cgit v1.2.3 From 2bee3260b45b559eb3bc75c6421dc7e573571cdb Mon Sep 17 00:00:00 2001 From: hackademix Date: Mon, 8 Apr 2019 21:37:35 +0200 Subject: Fixed UI inconsistencies when whitelisting/blacklisting through wide wildcard matching. --- html/display_panel/content/display-panel.html | 1 + html/display_panel/content/main_panel.js | 13 +++++++++++-- html/display_panel/content/panel-styles.css | 7 +++++-- main_background.js | 6 +++++- 4 files changed, 22 insertions(+), 5 deletions(-) (limited to 'html/display_panel') diff --git a/html/display_panel/content/display-panel.html b/html/display_panel/content/display-panel.html index 5b9f99f..2e705ab 100644 --- a/html/display_panel/content/display-panel.html +++ b/html/display_panel/content/display-panel.html @@ -60,6 +60,7 @@

    This whole site

    +
    diff --git a/html/display_panel/content/main_panel.js b/html/display_panel/content/main_panel.js index 9172265..75de6aa 100644 --- a/html/display_panel/content/main_panel.js +++ b/html/display_panel/content/main_panel.js @@ -173,8 +173,8 @@ function createList(data, group){ */ function refreshUI(report) { currentReport = report; - - document.querySelector("#site").className = report.siteStatus || ""; + let {siteStatus, listedSite} = report; + document.querySelector("#site").className = siteStatus || ""; document.querySelector("#site h2").textContent = `This site ${report.site}`; @@ -198,6 +198,15 @@ function refreshUI(report) { b.disabled = true; } + if (siteStatus && siteStatus !== "unknown") { + let statusLabel = siteStatus; + if (listedSite && listedSite !== report.site) statusLabel += ` via ${listedSite}`; + let status = document.querySelector("#site .status"); + status.classList.add(siteStatus); + document.querySelector("#site .status").textContent = statusLabel; + document.querySelector("#site .forget").disabled = true; + } + let noscript = scriptsCount === 0; document.body.classList.toggle("empty", noscript); } diff --git a/html/display_panel/content/panel-styles.css b/html/display_panel/content/panel-styles.css index 502323f..3257192 100644 --- a/html/display_panel/content/panel-styles.css +++ b/html/display_panel/content/panel-styles.css @@ -94,11 +94,14 @@ ul { display: initial; } +.status { + margin: .2em; +} -button.whitelist { +button.whitelist, .status.whitelisted { color: #080; } -button.blacklist { +button.blacklist, .status.blacklisted { color: #800; } button.forget { diff --git a/main_background.js b/main_background.js index 5943fb8..ba88f15 100644 --- a/main_background.js +++ b/main_background.js @@ -134,6 +134,10 @@ async function createReport(initializer) { template.url = url; template.site = ListStore.siteItem(url); template.siteStatus = listManager.getStatus(template.site); + let list = {"whitelisted": whitelist, "blacklisted": blacklist}[template.siteStatus]; + if (list) { + template.listedSite = ListManager.siteMatch(template.site, list); + } return template; } @@ -750,7 +754,7 @@ async function get_script(response, url, tabId = -1, whitelisted = false, index let reason = site ? `All ${site} whitelisted by user` : "Address whitelisted by user"; - addReportEntry(tabId, url, {"whitelisted": [site, reason], url}); + addReportEntry(tabId, url, {"whitelisted": [site || url, reason], url}); } if (response.startsWith("javascript:")) return result(response); -- cgit v1.2.3 From 0aacfa705e307286aa87861de5442785b1b51f65 Mon Sep 17 00:00:00 2001 From: hackademix Date: Fri, 12 Apr 2019 01:26:11 +0200 Subject: More consistent and efficient blacklisting. --- bg/ResponseProcessor.js | 2 +- html/display_panel/content/main_panel.js | 15 ++++-- main_background.js | 79 +++++++++++++++++--------------- 3 files changed, 52 insertions(+), 44 deletions(-) (limited to 'html/display_panel') diff --git a/bg/ResponseProcessor.js b/bg/ResponseProcessor.js index 1aa89de..2c613c9 100644 --- a/bg/ResponseProcessor.js +++ b/bg/ResponseProcessor.js @@ -78,7 +78,7 @@ class ResponseTextFilter { let res = await handler.pre(response); if (res) return res; if (handler.post) handler = handler.post; - if (typeof handler !== "function") ResponseProcessor.ACCEPT; + if (typeof handler !== "function") return ResponseProcessor.ACCEPT; } let {requestId, responseHeaders} = request; diff --git a/html/display_panel/content/main_panel.js b/html/display_panel/content/main_panel.js index 75de6aa..32d1bda 100644 --- a/html/display_panel/content/main_panel.js +++ b/html/display_panel/content/main_panel.js @@ -59,7 +59,7 @@ document.querySelector("#info").addEventListener("click", e => { setTimeout(close, 100); return; } - if (!button.tagName === "BUTTON") button = button.closest("button"); + if (button.tagName !== "BUTTON") button = button.closest("button"); if (button.matches(".toggle-source")) { let parent = button.parentNode; if (!parent.querySelector(".source").textContent) { @@ -199,12 +199,17 @@ function refreshUI(report) { } if (siteStatus && siteStatus !== "unknown") { + let siteContainer = document.querySelector("#site"); let statusLabel = siteStatus; - if (listedSite && listedSite !== report.site) statusLabel += ` via ${listedSite}`; - let status = document.querySelector("#site .status"); + if (listedSite && listedSite !== report.site) { + statusLabel += ` via ${listedSite}`; + siteContainer.querySelector(".forget").disabled = true; + } + let status = siteContainer.querySelector(".status"); status.classList.add(siteStatus); - document.querySelector("#site .status").textContent = statusLabel; - document.querySelector("#site .forget").disabled = true; + status.textContent = statusLabel; + } else { + document.querySelector("#site .status").textContent = ""; } let noscript = scriptsCount === 0; diff --git a/main_background.js b/main_background.js index ba88f15..f9e7521 100644 --- a/main_background.js +++ b/main_background.js @@ -805,42 +805,28 @@ function updateBadge(tabId, report = null, forceRed = false) { } } -/** -* Tests if a request is google analytics or not -*/ -function test_GA(a){ // TODO: DRY me - // This is just an HTML page - if(a.url == 'https://www.google.com/analytics/#?modal_active=none'){ - return false; - } - else if(a.url.match(/https:\/\/www\.google\.com\/analytics\//g)){ - dbg_print("%c Google analytics (1)","color:red"); - return {cancel: true}; - } - else if(a.url == 'https://www.google-analytics.com/analytics.js'){ - dbg_print("%c Google analytics (2)","color:red"); - return {cancel: true}; +function blockGoogleAnalytics(request) { + let {url} = request; + let res = {}; + if (url === 'https://www.google-analytics.com/analytics.js' || + /^https:\/\/www\.google\.com\/analytics\/[^#]/.test(url) + ) { + res.cancel = true; } - else if(a.url == 'https://www.google.com/analytics/js/analytics.min.js'){ - dbg_print("%c Google analytics (3)","color:red"); - return {cancel: true}; - } - else return false; + return res; } -/** -* A callback that every type of request invokes. -*/ -function block_ga(a){ - var GA = test_GA(a); - if(GA != false){ - return GA; - } - else return {}; +async function blockBlacklistedScripts(request) { + let {url, tabId, documentUrl} = request; + url = ListStore.urlItem(url); + let status = listManager.getStatus(url); + if (status !== "blacklisted") return {}; + let blacklistedSite = ListManager.siteMatch(url, blacklist); + await addReportEntry(tabId, url, {url: documentUrl, + "blacklisted": [url, /\*/.test(blacklistedSite) ? `User blacklisted ${blacklistedSite}` : "Blacklisted by user"]}); + return {cancel: true}; } - - /** * This listener gets called as soon as we've got all the HTTP headers, can guess * content type and encoding, and therefore correctly parse HTML documents @@ -861,20 +847,27 @@ var ResponseHandler = { let blacklistedSite = ListManager.siteMatch(site, blacklist); let blacklisted = blacklistedSite || blacklist.contains(url); - let topUrl = request.frameAncestors && request.frameAncestors.pop() || documentUrl; + let topUrl = type === "sub_frame" && request.frameAncestors && request.frameAncestors.pop() || documentUrl; if (blacklisted) { if (type === "script") { - // abort the request before the response gets fetched - addReportEntry(tabId, url, {url: topUrl, - "blacklisted": [url, blacklistedSite ? `User blacklisted ${blacklistedSite}` : "Blacklisted by user"]}); + // this shouldn't happen, because we intercept earlier in blockBlacklistedScripts() return ResponseProcessor.REJECT; } + if (type === "main_frame") { // we handle the page change here too, since we won't call edit_html() + activityReports[tabId] = await createReport({url: fullUrl, tabId}); + // Go on without parsing the page: it was explicitly blacklisted + let reason = blacklistedSite + ? `All ${blacklistedSite} blacklisted by user` + : "Address blacklisted by user"; + await addReportEntry(tabId, url, {"blacklisted": [blacklistedSite || url, reason], url: fullUrl}); + } // use CSP to restrict JavaScript execution in the page request.responseHeaders.unshift({ name: `Content-security-policy`, - value: `script-src '${blacklistedSite ? 'self' : 'none'}';` + value: `script-src 'none';` }); + return {responseHeaders: request.responseHeaders}; // let's skip the inline script parsing, since we block by CSP } else { let whitelistedSite = ListManager.siteMatch(site, whitelist); let whitelisted = response.whitelisted = whitelistedSite || whitelist.contains(url); @@ -1193,11 +1186,21 @@ async function init_addon() { "web_manifest", "websocket", "xbl", "xml_dtd", "xmlhttprequest", "xslt", "other" ]; - browser.webRequest.onBeforeRequest.addListener( - block_ga, + browser.webRequest.onBeforeRequest.addListener(blockGoogleAnalytics, {urls: [""], types: all_types}, ["blocking"] ); + browser.webRequest.onBeforeRequest.addListener(blockBlacklistedScripts, + {urls: [""], types: ["script"]}, + ["blocking"] + ); + browser.webRequest.onResponseStarted.addListener(request => { + let {tabId} = request; + let report = activityReports[tabId]; + if (report) { + updateBadge(tabId, activityReports[tabId]); + } + }, {urls: [""], types: ["main_frame"]}); // Analyzes all the html documents and external scripts as they're loaded ResponseProcessor.install(ResponseHandler); -- cgit v1.2.3