From f339268032f189e3da6274940a0daa7bb5683cc4 Mon Sep 17 00:00:00 2001 From: Maxx Crawford Date: Thu, 20 Feb 2020 13:52:29 -0600 Subject: [PATCH 01/18] WIP subdomain --- src/background.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/background.js b/src/background.js index b8f10e8e..59a0ff27 100644 --- a/src/background.js +++ b/src/background.js @@ -268,7 +268,8 @@ async function maybeReopenTab (url, tab, request) { function isFacebookURL (url) { const parsedUrl = new URL(url); - for (let facebookHostRE of facebookHostREs) { + console.log(parsedUrl); + for (let facebookHostRE of facebookHostREs) { if (facebookHostRE.test(parsedUrl.host)) { return true; } @@ -277,13 +278,13 @@ function isFacebookURL (url) { } // TODO: Consider users if accounts.spotify.com already in FBC -async function supportSiteSubdomainCheck (url) { - if (url === "accounts.spotify.com") { - await addDomainToFacebookContainer("https://www.spotify.com"); - await addDomainToFacebookContainer("https://open.spotify.com"); - } - return; -} +// async function supportSiteSubdomainCheck (url) { +// if (url === "accounts.spotify.com") { +// await addDomainToFacebookContainer("https://www.spotify.com"); +// await addDomainToFacebookContainer("https://open.spotify.com"); +// } +// return; +// } // TODO: refactor parsedUrl "up" so new URL doesn't have to be called so much // TODO: refactor fbcStorage "up" so browser.storage.local.get doesn't have to be called so much @@ -292,7 +293,7 @@ async function addDomainToFacebookContainer (url) { const fbcStorage = await browser.storage.local.get(); fbcStorage.domainsAddedToFacebookContainer.push(parsedUrl.host); await browser.storage.local.set({"domainsAddedToFacebookContainer": fbcStorage.domainsAddedToFacebookContainer}); - await supportSiteSubdomainCheck(parsedUrl.host); + // await supportSiteSubdomainCheck(parsedUrl.host); } async function removeDomainFromFacebookContainer (domain) { From a1135597fd560cb5c5b0ece4f355080408d6cad4 Mon Sep 17 00:00:00 2001 From: Maxx Crawford Date: Fri, 21 Feb 2020 15:54:31 -0600 Subject: [PATCH 02/18] Fixed #567 - Updated logic to allow all subdomains of a custom added domain --- src/background.js | 23 ++++++++++++++++++----- src/panel.js | 35 ++++++++++++++++++++++++++++------- 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/src/background.js b/src/background.js index 59a0ff27..08c87fd2 100644 --- a/src/background.js +++ b/src/background.js @@ -266,11 +266,22 @@ async function maybeReopenTab (url, tab, request) { return {cancel: true}; } +function getRootDomain(hostname) { + let parts = hostname.split("."); + // If there's no subdomain, return hostname as is. + if (parts.length < 3) { + return hostname; + } + let subdomain = parts.shift(); + let upperleveldomain = parts.join("."); + return upperleveldomain; +} + function isFacebookURL (url) { const parsedUrl = new URL(url); - console.log(parsedUrl); - for (let facebookHostRE of facebookHostREs) { - if (facebookHostRE.test(parsedUrl.host)) { + let rootDomain = getRootDomain(parsedUrl.host); + for (let facebookHostRE of facebookHostREs) { + if (facebookHostRE.test(rootDomain)) { return true; } } @@ -291,7 +302,8 @@ function isFacebookURL (url) { async function addDomainToFacebookContainer (url) { const parsedUrl = new URL(url); const fbcStorage = await browser.storage.local.get(); - fbcStorage.domainsAddedToFacebookContainer.push(parsedUrl.host); + const rootDomain = getRootDomain(parsedUrl.host); + fbcStorage.domainsAddedToFacebookContainer.push(rootDomain); await browser.storage.local.set({"domainsAddedToFacebookContainer": fbcStorage.domainsAddedToFacebookContainer}); // await supportSiteSubdomainCheck(parsedUrl.host); } @@ -307,7 +319,8 @@ async function removeDomainFromFacebookContainer (domain) { async function isAddedToFacebookContainer (url) { const parsedUrl = new URL(url); const fbcStorage = await browser.storage.local.get(); - if (fbcStorage.domainsAddedToFacebookContainer.includes(parsedUrl.host)) { + const rootDomain = getRootDomain(parsedUrl.host); + if (fbcStorage.domainsAddedToFacebookContainer.includes(rootDomain)) { return true; } return false; diff --git a/src/panel.js b/src/panel.js index 2cf9fa67..837f1875 100644 --- a/src/panel.js +++ b/src/panel.js @@ -117,6 +117,16 @@ const addSpan = (wrapper, stringId) => { setClassAndAppend(wrapper, span); }; +const getRootDomain = (hostname) => { + let parts = hostname.split("."); + if (parts.length < 3) { + return hostname; + } + let subdomain = parts.shift(); + let upperleveldomain = parts.join("."); + return upperleveldomain; +}; + const getActiveHostname = async() => { const tabsQueryResult = await browser.tabs.query({currentWindow: true, active: true}); const currentActiveTab = tabsQueryResult[0]; @@ -125,16 +135,25 @@ const getActiveHostname = async() => { return thisHostname; }; -const isSiteInContainer = async(panelId) => { +const getActiveRootDomain = async() => { + const tabsQueryResult = await browser.tabs.query({currentWindow: true, active: true}); + const currentActiveTab = tabsQueryResult[0]; + const currentActiveURL = new URL(currentActiveTab.url); + const thisHostname = getRootDomain(currentActiveURL.hostname); + return thisHostname; +}; +const isSiteInContainer = async(panelId) => { + console.log("isSiteInContainer"); if (panelId === "on-facebook") { // Site is on default FBC domain. Show the "remove site" button, in a disabled state. return true; } const addedSitesList = await browser.runtime.sendMessage("what-sites-are-added"); - const activeTabHostname = await getActiveHostname(); - + const activeTabHostname = await getActiveRootDomain(); + console.log("addedSitesList", addedSitesList); + console.log("activeTabHostname: ", activeTabHostname); if (addedSitesList.includes(activeTabHostname)) { return true; } @@ -542,16 +561,18 @@ const buildAllowedSitesPanel = async(panelId) => { }; const removeSiteFromContainer = async () => { - const activeHostname = await getActiveHostname(); - await browser.runtime.sendMessage( {removeDomain: activeHostname} ); + const activeRootDomain = await getActiveRootDomain(); + // const activeHostname = await getActiveHostname(); + await browser.runtime.sendMessage( {removeDomain: activeRootDomain} ); browser.tabs.reload(); window.close(); }; const addSiteToContainer = async () => { - const activeHostname = await getActiveHostname(); + const activeRootDomain = await getActiveRootDomain(); + // const activeHostname = await getActiveHostname(); const fbcStorage = await browser.storage.local.get(); - fbcStorage.domainsAddedToFacebookContainer.push(activeHostname); + fbcStorage.domainsAddedToFacebookContainer.push(activeRootDomain); await browser.storage.local.set({"domainsAddedToFacebookContainer": fbcStorage.domainsAddedToFacebookContainer}); browser.tabs.reload(); window.close(); From 484d3b638766e9a7f8885af5183a2fe6401da99b Mon Sep 17 00:00:00 2001 From: Maxx Crawford Date: Fri, 21 Feb 2020 16:49:21 -0600 Subject: [PATCH 03/18] Added support for sites with mulitple subdomains. --- src/background.js | 9 ++++++--- src/panel.js | 23 +++++++---------------- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/src/background.js b/src/background.js index 08c87fd2..93a146be 100644 --- a/src/background.js +++ b/src/background.js @@ -272,9 +272,12 @@ function getRootDomain(hostname) { if (parts.length < 3) { return hostname; } - let subdomain = parts.shift(); - let upperleveldomain = parts.join("."); - return upperleveldomain; + while (parts.length > 2) { + // Trim around down to final domain + parts.shift(); + } + let rootDomain = parts.join("."); + return rootDomain; } function isFacebookURL (url) { diff --git a/src/panel.js b/src/panel.js index 837f1875..3264b52c 100644 --- a/src/panel.js +++ b/src/panel.js @@ -119,20 +119,16 @@ const addSpan = (wrapper, stringId) => { const getRootDomain = (hostname) => { let parts = hostname.split("."); + // If there's no subdomain, return hostname as is. if (parts.length < 3) { return hostname; } - let subdomain = parts.shift(); - let upperleveldomain = parts.join("."); - return upperleveldomain; -}; - -const getActiveHostname = async() => { - const tabsQueryResult = await browser.tabs.query({currentWindow: true, active: true}); - const currentActiveTab = tabsQueryResult[0]; - const currentActiveURL = new URL(currentActiveTab.url); - const thisHostname = currentActiveURL.hostname; - return thisHostname; + while (parts.length > 2) { + // Trim around down to final domain + parts.shift(); + } + let rootDomain = parts.join("."); + return rootDomain; }; const getActiveRootDomain = async() => { @@ -144,7 +140,6 @@ const getActiveRootDomain = async() => { }; const isSiteInContainer = async(panelId) => { - console.log("isSiteInContainer"); if (panelId === "on-facebook") { // Site is on default FBC domain. Show the "remove site" button, in a disabled state. return true; @@ -152,8 +147,6 @@ const isSiteInContainer = async(panelId) => { const addedSitesList = await browser.runtime.sendMessage("what-sites-are-added"); const activeTabHostname = await getActiveRootDomain(); - console.log("addedSitesList", addedSitesList); - console.log("activeTabHostname: ", activeTabHostname); if (addedSitesList.includes(activeTabHostname)) { return true; } @@ -562,7 +555,6 @@ const buildAllowedSitesPanel = async(panelId) => { const removeSiteFromContainer = async () => { const activeRootDomain = await getActiveRootDomain(); - // const activeHostname = await getActiveHostname(); await browser.runtime.sendMessage( {removeDomain: activeRootDomain} ); browser.tabs.reload(); window.close(); @@ -570,7 +562,6 @@ const removeSiteFromContainer = async () => { const addSiteToContainer = async () => { const activeRootDomain = await getActiveRootDomain(); - // const activeHostname = await getActiveHostname(); const fbcStorage = await browser.storage.local.get(); fbcStorage.domainsAddedToFacebookContainer.push(activeRootDomain); await browser.storage.local.set({"domainsAddedToFacebookContainer": fbcStorage.domainsAddedToFacebookContainer}); From 7dff975a6ad7d10114d7cb6b92dc3708bfffcb08 Mon Sep 17 00:00:00 2001 From: Maxx Crawford Date: Mon, 24 Feb 2020 12:04:01 -0600 Subject: [PATCH 04/18] Added third-level domain support logic --- src/background.js | 24 ++++++++++++++++++++++-- src/panel.js | 24 ++++++++++++++++++++++-- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/src/background.js b/src/background.js index 93a146be..b046b955 100644 --- a/src/background.js +++ b/src/background.js @@ -268,14 +268,34 @@ async function maybeReopenTab (url, tab, request) { function getRootDomain(hostname) { let parts = hostname.split("."); + + // Default array length of hostname split + let defaultDomainLength = 3; + // If there's no subdomain, return hostname as is. - if (parts.length < 3) { + if (parts.length < defaultDomainLength) { return hostname; } - while (parts.length > 2) { + + let lastArrayLength = parts[(parts.length - 1)].length; + + + if (lastArrayLength < 3) { + // Returns true if last part of hostname is two-characters, meaning it's a + // country-level domain. + let nextToLastItem = parts[(parts.length - 2)]; + if (nextToLastItem === "co" || nextToLastItem === "com") { + // Checks to see if a third-level domain is present. + // Example: https://www.amazon.co.uk returns "amazon.co.uk" + defaultDomainLength = 4; + } + } + + while (parts.length > (defaultDomainLength - 1)) { // Trim around down to final domain parts.shift(); } + let rootDomain = parts.join("."); return rootDomain; } diff --git a/src/panel.js b/src/panel.js index 3264b52c..99860826 100644 --- a/src/panel.js +++ b/src/panel.js @@ -119,14 +119,34 @@ const addSpan = (wrapper, stringId) => { const getRootDomain = (hostname) => { let parts = hostname.split("."); + + // Default array length of hostname split + let defaultDomainLength = 3; + // If there's no subdomain, return hostname as is. - if (parts.length < 3) { + if (parts.length < defaultDomainLength) { return hostname; } - while (parts.length > 2) { + + let lastArrayLength = parts[(parts.length - 1)].length; + + + if (lastArrayLength < 3) { + // Returns true if last part of hostname is two-characters, meaning it's a + // country-level domain. + let nextToLastItem = parts[(parts.length - 2)]; + if (nextToLastItem === "co" || nextToLastItem === "com") { + // Checks to see if a third-level domain is present. + // Example: https://www.amazon.co.uk returns "amazon.co.uk" + defaultDomainLength = 4; + } + } + + while (parts.length > (defaultDomainLength - 1)) { // Trim around down to final domain parts.shift(); } + let rootDomain = parts.join("."); return rootDomain; }; From cbd31815b571a2fd6247faad562c351352727d25 Mon Sep 17 00:00:00 2001 From: Maxx Crawford Date: Wed, 26 Feb 2020 14:25:34 -0600 Subject: [PATCH 05/18] Add latest PSL library to the project --- package.json | 1 + src/manifest.json | 5 ++++- src/psl.min.js | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 src/psl.min.js diff --git a/package.json b/package.json index b837acfa..4a5c8d56 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "fs-extra": "^8.1.0", "mocha": "^5.0.5", "nyc": "^14.1.1", + "psl": "^1.7.0", "sinon": "^7.3.2", "sinon-chai": "^3.0.0", "webextensions-geckodriver": "^0.6.1", diff --git a/src/manifest.json b/src/manifest.json index e82bb4c3..129dbde5 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -55,7 +55,10 @@ ], "background": { - "scripts": ["background.js"] + "scripts": [ + "psl.min.js", + "background.js" + ] }, "content_scripts": [ diff --git a/src/psl.min.js b/src/psl.min.js new file mode 100644 index 00000000..a07c4781 --- /dev/null +++ b/src/psl.min.js @@ -0,0 +1 @@ +!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).psl=a();}}(function(){return function s(m,t,u){function r(o,a){if(!t[o]){if(!m[o]){var i="function"==typeof require&&require;if(!a&&i)return i(o,!0);if(p)return p(o,!0);var e=new Error("Cannot find module '"+o+"'");throw e.code="MODULE_NOT_FOUND",e;}var n=t[o]={exports:{}};m[o][0].call(n.exports,function(a){return r(m[o][1][a]||a);},n,n.exports,s,m,t,u);}return t[o].exports;}for(var p="function"==typeof require&&require,a=0;a= 0x80 (not a basic code point)","invalid-input":"Invalid input"},c=b-y,x=Math.floor,q=String.fromCharCode;function A(a){throw new RangeError(k[a]);}function l(a,o){for(var i=a.length,e=[];i--;)e[i]=o(a[i]);return e;}function g(a,o){var i=a.split("@"),e="";return 1>>10&1023|55296),a=56320|1023&a),o+=q(a);}).join("");}function L(a,o){return a+22+75*(a<26)-((0!=o)<<5);}function I(a,o,i){var e=0;for(a=i?x(a/t):a>>1,a+=x(a/o);c*f>>1x((d-g)/m))&&A("overflow"),g+=u*m,!(u<(r=t<=j?y:j+f<=t?f:t-j));t+=b)m>x(d/(p=b-r))&&A("overflow"),m*=p;j=I(g-s,o=c.length+1,0==s),x(g/o)>d-h&&A("overflow"),h+=x(g/o),g%=o,c.splice(g++,0,h);}return _(c);}function j(a){var o,i,e,n,s,m,t,u,r,p,k,c,l,g,h,j=[];for(c=(a=O(a)).length,o=w,s=v,m=i=0;mx((d-i)/(l=e+1))&&A("overflow"),i+=(t-o)*l,o=t,m=0;md&&A("overflow"),k==o){for(u=i,r=b;!(u<(p=r<=s?y:s+f<=r?f:r-s));r+=b)h=u-p,g=b-p,j.push(q(L(p+h%g,0))),u=x(h/g);j.push(q(L(u,0))),s=I(i,l,e==n),i=0,++e;}++i,++o;}return j.join("");}if(n={version:"1.4.1",ucs2:{decode:O,encode:_},decode:h,encode:j,toASCII:function(a){return g(a,function(a){return r.test(a)?"xn--"+j(a):a;});},toUnicode:function(a){return g(a,function(a){return u.test(a)?h(a.slice(4).toLowerCase()):a;});}},0,o&&i)if(T.exports==o)i.exports=n;else for(s in n)n.hasOwnProperty(s)&&(o[s]=n[s]);else a.punycode=n;}(this);}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{});},{}]},{},[2])(2);}); From 84f734a42f489589752d67c73d1a136971a569f9 Mon Sep 17 00:00:00 2001 From: Maxx Crawford Date: Wed, 26 Feb 2020 14:27:03 -0600 Subject: [PATCH 06/18] Updated getRootDomain function to use PSL library to parse URL and return domain. --- src/background.js | 41 ++++++++--------------------------------- 1 file changed, 8 insertions(+), 33 deletions(-) diff --git a/src/background.js b/src/background.js index b046b955..50ab4ab6 100644 --- a/src/background.js +++ b/src/background.js @@ -266,43 +266,20 @@ async function maybeReopenTab (url, tab, request) { return {cancel: true}; } -function getRootDomain(hostname) { - let parts = hostname.split("."); +function getRootDomain(url) { - // Default array length of hostname split - let defaultDomainLength = 3; - - // If there's no subdomain, return hostname as is. - if (parts.length < defaultDomainLength) { - return hostname; - } - - let lastArrayLength = parts[(parts.length - 1)].length; + const urlObject = new URL(url); + if (urlObject.hostname === "") { return false; } - if (lastArrayLength < 3) { - // Returns true if last part of hostname is two-characters, meaning it's a - // country-level domain. - let nextToLastItem = parts[(parts.length - 2)]; - if (nextToLastItem === "co" || nextToLastItem === "com") { - // Checks to see if a third-level domain is present. - // Example: https://www.amazon.co.uk returns "amazon.co.uk" - defaultDomainLength = 4; - } - } + const parsedUrl = psl.parse(urlObject.hostname); - while (parts.length > (defaultDomainLength - 1)) { - // Trim around down to final domain - parts.shift(); - } + return parsedUrl.domain; - let rootDomain = parts.join("."); - return rootDomain; } function isFacebookURL (url) { - const parsedUrl = new URL(url); - let rootDomain = getRootDomain(parsedUrl.host); + const rootDomain = getRootDomain(url); for (let facebookHostRE of facebookHostREs) { if (facebookHostRE.test(rootDomain)) { return true; @@ -323,9 +300,8 @@ function isFacebookURL (url) { // TODO: refactor parsedUrl "up" so new URL doesn't have to be called so much // TODO: refactor fbcStorage "up" so browser.storage.local.get doesn't have to be called so much async function addDomainToFacebookContainer (url) { - const parsedUrl = new URL(url); const fbcStorage = await browser.storage.local.get(); - const rootDomain = getRootDomain(parsedUrl.host); + const rootDomain = getRootDomain(url); fbcStorage.domainsAddedToFacebookContainer.push(rootDomain); await browser.storage.local.set({"domainsAddedToFacebookContainer": fbcStorage.domainsAddedToFacebookContainer}); // await supportSiteSubdomainCheck(parsedUrl.host); @@ -340,9 +316,8 @@ async function removeDomainFromFacebookContainer (domain) { // TODO: Add PSL Subdomain Check against current list async function isAddedToFacebookContainer (url) { - const parsedUrl = new URL(url); const fbcStorage = await browser.storage.local.get(); - const rootDomain = getRootDomain(parsedUrl.host); + const rootDomain = getRootDomain(url); if (fbcStorage.domainsAddedToFacebookContainer.includes(rootDomain)) { return true; } From 2e0b241b7873664479c6982cf90f82eb0eb991ff Mon Sep 17 00:00:00 2001 From: Maxx Crawford Date: Wed, 26 Feb 2020 14:28:07 -0600 Subject: [PATCH 07/18] Updated message handler across all the scripts to pass data object, and reject any unknown messages. Also revised panel.js to request parsed domain from PSL through the background. --- src/background.js | 23 +++++++++++++++------- src/content_script.js | 8 ++++++-- src/panel.js | 46 ++++++++++++++++++++++++++++++++----------- 3 files changed, 56 insertions(+), 21 deletions(-) diff --git a/src/background.js b/src/background.js index 50ab4ab6..39a1f2bf 100644 --- a/src/background.js +++ b/src/background.js @@ -581,15 +581,24 @@ function setupWindowsAndTabsListeners() { setupWebRequestListeners(); setupWindowsAndTabsListeners(); - browser.runtime.onMessage.addListener( (message, {url}) => { - if (message === "what-sites-are-added") { + async function messageHandler(request, sender, sendResponse) { + switch (request.message) { + case "what-sites-are-added": return browser.storage.local.get().then(fbcStorage => fbcStorage.domainsAddedToFacebookContainer); - } else if (message.removeDomain) { - removeDomainFromFacebookContainer(message.removeDomain).then( results => results ); - } else { - addDomainToFacebookContainer(url).then( results => results); + case "remove-domain-from-list": + removeDomainFromFacebookContainer(request.removeDomain).then( results => results ); + break; + case "add-domain-to-list": + addDomainToFacebookContainer(sender.url).then( results => results); + break; + case "get-root-domain": + return getRootDomain(request.url); + default: + throw new Error("Unexpected message!"); } - }); + } + + browser.runtime.onMessage.addListener(messageHandler); maybeReopenAlreadyOpenTabs(); diff --git a/src/content_script.js b/src/content_script.js index d18e3a91..96e3a295 100755 --- a/src/content_script.js +++ b/src/content_script.js @@ -210,7 +210,9 @@ function addFacebookBadge (target, badgeClassUId, socialAction) { htmlBadgeFragmentPromptButtonAllow.addEventListener("click", (e) => { e.preventDefault(); allowClickSwitch = true; - browser.runtime.sendMessage("add-to-facebook-container"); + browser.runtime.sendMessage({ + message: "add-domain-to-list" + }); target.click(); }); @@ -608,7 +610,9 @@ function contentScriptInit(resetSwitch, msg) { } async function CheckIfURLShouldBeBlocked() { - const siteList = await browser.runtime.sendMessage("what-sites-are-added"); + const siteList = await browser.runtime.sendMessage({ + message: "what-sites-are-added" + }); if (siteList.includes(window.location.host)) { checkForTrackers = false; diff --git a/src/panel.js b/src/panel.js index 99860826..06736f85 100644 --- a/src/panel.js +++ b/src/panel.js @@ -151,12 +151,18 @@ const getRootDomain = (hostname) => { return rootDomain; }; -const getActiveRootDomain = async() => { +const getActiveRootDomainFromBackground = async() => { + // Get active page URL const tabsQueryResult = await browser.tabs.query({currentWindow: true, active: true}); const currentActiveTab = tabsQueryResult[0]; - const currentActiveURL = new URL(currentActiveTab.url); - const thisHostname = getRootDomain(currentActiveURL.hostname); - return thisHostname; + + // Send request to background to parse URL via PSL + const backgroundResp = await browser.runtime.sendMessage({ + message: "get-root-domain", + url: currentActiveTab.url + }); + + return backgroundResp; }; const isSiteInContainer = async(panelId) => { @@ -165,8 +171,11 @@ const isSiteInContainer = async(panelId) => { return true; } - const addedSitesList = await browser.runtime.sendMessage("what-sites-are-added"); - const activeTabHostname = await getActiveRootDomain(); + const addedSitesList = await browser.runtime.sendMessage({ + message: "what-sites-are-added" + }); + const activeTabHostname = await getActiveRootDomainFromBackground(); + if (addedSitesList.includes(activeTabHostname)) { return true; } @@ -251,7 +260,11 @@ const addDeleteSiteListeners = () => { document.querySelectorAll(".site-added").forEach(btn => { btn.addEventListener("click", async (e) => { // TODO: refactor to remove the domain straight from browser.storage.local? - await browser.runtime.sendMessage({removeDomain: e.dataset.domain}); + + await browser.runtime.sendMessage({ + message: "remove-domain-from-list", + removeDomain: e.dataset.domain + }); }); }); }; @@ -552,7 +565,9 @@ const buildAllowedSitesPanel = async(panelId) => { addLightSubhead(listsWrapper, "sites-included"); makeSiteList(listsWrapper, defaultAllowedSites); - const siteList = await browser.runtime.sendMessage("what-sites-are-added"); + const siteList = await browser.runtime.sendMessage({ + message: "what-sites-are-added" + }); const sitesAllowedSubhead = addLightSubhead(listsWrapper, "sites-allowed"); sitesAllowedSubhead.classList.add("sites-allowed"); makeSiteList(listsWrapper, siteList, true, true); // (...sitesAllowed=true, addX=true) @@ -574,14 +589,18 @@ const buildAllowedSitesPanel = async(panelId) => { }; const removeSiteFromContainer = async () => { - const activeRootDomain = await getActiveRootDomain(); - await browser.runtime.sendMessage( {removeDomain: activeRootDomain} ); + const activeRootDomain = await getActiveRootDomainFromBackground(); + + await browser.runtime.sendMessage({ + message: "remove-domain-from-list", + removeDomain: activeRootDomain + }); browser.tabs.reload(); window.close(); }; const addSiteToContainer = async () => { - const activeRootDomain = await getActiveRootDomain(); + const activeRootDomain = await getActiveRootDomainFromBackground(); const fbcStorage = await browser.storage.local.get(); fbcStorage.domainsAddedToFacebookContainer.push(activeRootDomain); await browser.storage.local.set({"domainsAddedToFacebookContainer": fbcStorage.domainsAddedToFacebookContainer}); @@ -606,7 +625,10 @@ const buildRemoveSitePanel = (siteName) => { blueRemoveButton.classList.add("uiMessage", "remove-btn"); blueRemoveButton.id = "remove"; blueRemoveButton.addEventListener("click", async() => { - await browser.runtime.sendMessage( {removeDomain: siteName} ); + await browser.runtime.sendMessage({ + message: "remove-domain-from-list", + removeDomain: siteName + }); browser.tabs.reload(); window.close(); }); From 1421a6f088518640e9cee3b17efb9c50279d573a Mon Sep 17 00:00:00 2001 From: Maxx Crawford Date: Fri, 28 Feb 2020 10:45:51 -0600 Subject: [PATCH 08/18] Updated package-lock.json file --- package-lock.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 63564ff6..79cdd174 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "contain-facebook", - "version": "2.0.3", + "version": "2.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -6828,9 +6828,9 @@ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" }, "psl": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.4.0.tgz", - "integrity": "sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw==" + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz", + "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==" }, "pump": { "version": "3.0.0", From e22b8d6283dfd2b5769b26f6c87d438d3fa431e4 Mon Sep 17 00:00:00 2001 From: Maxx Crawford Date: Fri, 28 Feb 2020 11:21:24 -0600 Subject: [PATCH 09/18] Added PSL/BG message support to content script --- src/content_script.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/content_script.js b/src/content_script.js index 96e3a295..2dd94cde 100755 --- a/src/content_script.js +++ b/src/content_script.js @@ -609,12 +609,24 @@ function contentScriptInit(resetSwitch, msg) { } } +async function getRootDomainFromBackground(url) { + // Send request to background to parse URL via PSL + const backgroundResp = await browser.runtime.sendMessage({ + message: "get-root-domain", + url + }); + + return backgroundResp; +} + async function CheckIfURLShouldBeBlocked() { const siteList = await browser.runtime.sendMessage({ message: "what-sites-are-added" }); - if (siteList.includes(window.location.host)) { + const site = await getRootDomainFromBackground(window.location.href); + + if (siteList.includes(site)) { checkForTrackers = false; } else { contentScriptInit(false); From 81fd7d8a4326cbd8f6a0d9b74d1a14a713116707 Mon Sep 17 00:00:00 2001 From: Maxx Crawford Date: Fri, 28 Feb 2020 11:22:06 -0600 Subject: [PATCH 10/18] Updated variable name to be more descriptive --- src/panel.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/panel.js b/src/panel.js index 06736f85..921896cd 100644 --- a/src/panel.js +++ b/src/panel.js @@ -174,9 +174,10 @@ const isSiteInContainer = async(panelId) => { const addedSitesList = await browser.runtime.sendMessage({ message: "what-sites-are-added" }); - const activeTabHostname = await getActiveRootDomainFromBackground(); + + const activeRootDomain = await getActiveRootDomainFromBackground(); - if (addedSitesList.includes(activeTabHostname)) { + if (addedSitesList.includes(activeRootDomain)) { return true; } }; From 27b786dcf0594b54f37439fd71184fcefa950775 Mon Sep 17 00:00:00 2001 From: Maxx Crawford Date: Fri, 28 Feb 2020 12:02:31 -0600 Subject: [PATCH 11/18] Added global variable for PSL, reverted isFacebookURL to use URL constructor to reduce performance concerns --- src/background.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/background.js b/src/background.js index 39a1f2bf..bbcd57c3 100644 --- a/src/background.js +++ b/src/background.js @@ -1,3 +1,5 @@ +/* global psl */ + const FACEBOOK_CONTAINER_DETAILS = { name: "Facebook", color: "toolbar", @@ -279,9 +281,9 @@ function getRootDomain(url) { } function isFacebookURL (url) { - const rootDomain = getRootDomain(url); + const parsedUrl = new URL(url); for (let facebookHostRE of facebookHostREs) { - if (facebookHostRE.test(rootDomain)) { + if (facebookHostRE.test(parsedUrl.host)) { return true; } } From 031081fa8cf7af6bdb54878d205d3e9f674e9628 Mon Sep 17 00:00:00 2001 From: Maxx Crawford Date: Fri, 28 Feb 2020 12:03:17 -0600 Subject: [PATCH 12/18] Moved tab logic higher in the statement to fix error when tabID is being called too early. --- src/background.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/background.js b/src/background.js index bbcd57c3..7eb70fd5 100644 --- a/src/background.js +++ b/src/background.js @@ -476,6 +476,13 @@ async function containFacebook (request) { delete tabsWaitingToLoad[request.tabId]; } + // Listen to requests and open Facebook into its Container, + // open other sites into the default tab context + if (request.tabId === -1) { + // Request doesn't belong to a tab + return; + } + const tab = await browser.tabs.get(request.tabId); updateBrowserActionIcon(tab); @@ -484,12 +491,6 @@ async function containFacebook (request) { if (urlSearchParm.has("fbclid")) { return {redirectUrl: stripFbclid(request.url)}; } - // Listen to requests and open Facebook into its Container, - // open other sites into the default tab context - if (request.tabId === -1) { - // Request doesn't belong to a tab - return; - } return maybeReopenTab(request.url, tab, request); } From 7ae83055d06112c00e238b318ea083959289702a Mon Sep 17 00:00:00 2001 From: Maxx Crawford Date: Fri, 28 Feb 2020 12:03:32 -0600 Subject: [PATCH 13/18] Removed commented code. --- src/background.js | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/background.js b/src/background.js index 7eb70fd5..af6b86b8 100644 --- a/src/background.js +++ b/src/background.js @@ -290,15 +290,6 @@ function isFacebookURL (url) { return false; } -// TODO: Consider users if accounts.spotify.com already in FBC -// async function supportSiteSubdomainCheck (url) { -// if (url === "accounts.spotify.com") { -// await addDomainToFacebookContainer("https://www.spotify.com"); -// await addDomainToFacebookContainer("https://open.spotify.com"); -// } -// return; -// } - // TODO: refactor parsedUrl "up" so new URL doesn't have to be called so much // TODO: refactor fbcStorage "up" so browser.storage.local.get doesn't have to be called so much async function addDomainToFacebookContainer (url) { @@ -306,7 +297,6 @@ async function addDomainToFacebookContainer (url) { const rootDomain = getRootDomain(url); fbcStorage.domainsAddedToFacebookContainer.push(rootDomain); await browser.storage.local.set({"domainsAddedToFacebookContainer": fbcStorage.domainsAddedToFacebookContainer}); - // await supportSiteSubdomainCheck(parsedUrl.host); } async function removeDomainFromFacebookContainer (domain) { @@ -316,7 +306,6 @@ async function removeDomainFromFacebookContainer (domain) { await browser.storage.local.set({"domainsAddedToFacebookContainer": fbcStorage.domainsAddedToFacebookContainer}); } -// TODO: Add PSL Subdomain Check against current list async function isAddedToFacebookContainer (url) { const fbcStorage = await browser.storage.local.get(); const rootDomain = getRootDomain(url); From 6f02d95de07b053d85f52f13828c181f4bcfd13e Mon Sep 17 00:00:00 2001 From: Maxx Crawford Date: Fri, 28 Feb 2020 12:27:01 -0600 Subject: [PATCH 14/18] Added memoization logic to getRootDomain function --- src/background.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/background.js b/src/background.js index af6b86b8..63387e32 100644 --- a/src/background.js +++ b/src/background.js @@ -268,14 +268,22 @@ async function maybeReopenTab (url, tab, request) { return {cancel: true}; } +const rootDomainCache = {}; + function getRootDomain(url) { + if (url in rootDomainCache) { + // After storing 128 entries, it will delete the oldest each time. + if (Object.keys(rootDomainCache).length > 128) { + delete rootDomainCache[(Object.keys(rootDomainCache)[0])]; + } + return rootDomainCache[url]; + } const urlObject = new URL(url); - if (urlObject.hostname === "") { return false; } - const parsedUrl = psl.parse(urlObject.hostname); + rootDomainCache[url] = parsedUrl.domain; return parsedUrl.domain; } From 00e8c1f0b4c5dcb2033a08e49f86ce9efc262920 Mon Sep 17 00:00:00 2001 From: Maxx Crawford Date: Fri, 28 Feb 2020 13:39:18 -0600 Subject: [PATCH 15/18] Fixed eslint errors --- src/background.js | 2 +- src/panel.js | 36 +----------------------------------- src/psl.min.js | 1 + 3 files changed, 3 insertions(+), 36 deletions(-) diff --git a/src/background.js b/src/background.js index 52c66a67..6608f763 100644 --- a/src/background.js +++ b/src/background.js @@ -582,7 +582,7 @@ function setupWindowsAndTabsListeners() { setupWebRequestListeners(); setupWindowsAndTabsListeners(); - async function messageHandler(request, sender, sendResponse) { + async function messageHandler(request, sender) { switch (request.message) { case "what-sites-are-added": return browser.storage.local.get().then(fbcStorage => fbcStorage.domainsAddedToFacebookContainer); diff --git a/src/panel.js b/src/panel.js index 4f996753..ff57a182 100644 --- a/src/panel.js +++ b/src/panel.js @@ -117,40 +117,6 @@ const addSpan = (wrapper, stringId) => { setClassAndAppend(wrapper, span); }; -const getRootDomain = (hostname) => { - let parts = hostname.split("."); - - // Default array length of hostname split - let defaultDomainLength = 3; - - // If there's no subdomain, return hostname as is. - if (parts.length < defaultDomainLength) { - return hostname; - } - - let lastArrayLength = parts[(parts.length - 1)].length; - - - if (lastArrayLength < 3) { - // Returns true if last part of hostname is two-characters, meaning it's a - // country-level domain. - let nextToLastItem = parts[(parts.length - 2)]; - if (nextToLastItem === "co" || nextToLastItem === "com") { - // Checks to see if a third-level domain is present. - // Example: https://www.amazon.co.uk returns "amazon.co.uk" - defaultDomainLength = 4; - } - } - - while (parts.length > (defaultDomainLength - 1)) { - // Trim around down to final domain - parts.shift(); - } - - let rootDomain = parts.join("."); - return rootDomain; -}; - const getActiveRootDomainFromBackground = async() => { // Get active page URL const tabsQueryResult = await browser.tabs.query({currentWindow: true, active: true}); @@ -611,7 +577,7 @@ const addSiteToContainer = async () => { const buildAddSitePanel = async (siteName) => { if (!siteName) { - siteName = await getActiveHostname(); + siteName = await getActiveRootDomainFromBackground(); } const panelId = "add-site"; diff --git a/src/psl.min.js b/src/psl.min.js index a07c4781..3abdce6a 100644 --- a/src/psl.min.js +++ b/src/psl.min.js @@ -1 +1,2 @@ +/* eslint-disable */ !function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).psl=a();}}(function(){return function s(m,t,u){function r(o,a){if(!t[o]){if(!m[o]){var i="function"==typeof require&&require;if(!a&&i)return i(o,!0);if(p)return p(o,!0);var e=new Error("Cannot find module '"+o+"'");throw e.code="MODULE_NOT_FOUND",e;}var n=t[o]={exports:{}};m[o][0].call(n.exports,function(a){return r(m[o][1][a]||a);},n,n.exports,s,m,t,u);}return t[o].exports;}for(var p="function"==typeof require&&require,a=0;a= 0x80 (not a basic code point)","invalid-input":"Invalid input"},c=b-y,x=Math.floor,q=String.fromCharCode;function A(a){throw new RangeError(k[a]);}function l(a,o){for(var i=a.length,e=[];i--;)e[i]=o(a[i]);return e;}function g(a,o){var i=a.split("@"),e="";return 1>>10&1023|55296),a=56320|1023&a),o+=q(a);}).join("");}function L(a,o){return a+22+75*(a<26)-((0!=o)<<5);}function I(a,o,i){var e=0;for(a=i?x(a/t):a>>1,a+=x(a/o);c*f>>1x((d-g)/m))&&A("overflow"),g+=u*m,!(u<(r=t<=j?y:j+f<=t?f:t-j));t+=b)m>x(d/(p=b-r))&&A("overflow"),m*=p;j=I(g-s,o=c.length+1,0==s),x(g/o)>d-h&&A("overflow"),h+=x(g/o),g%=o,c.splice(g++,0,h);}return _(c);}function j(a){var o,i,e,n,s,m,t,u,r,p,k,c,l,g,h,j=[];for(c=(a=O(a)).length,o=w,s=v,m=i=0;mx((d-i)/(l=e+1))&&A("overflow"),i+=(t-o)*l,o=t,m=0;md&&A("overflow"),k==o){for(u=i,r=b;!(u<(p=r<=s?y:s+f<=r?f:r-s));r+=b)h=u-p,g=b-p,j.push(q(L(p+h%g,0))),u=x(h/g);j.push(q(L(u,0))),s=I(i,l,e==n),i=0,++e;}++i,++o;}return j.join("");}if(n={version:"1.4.1",ucs2:{decode:O,encode:_},decode:h,encode:j,toASCII:function(a){return g(a,function(a){return r.test(a)?"xn--"+j(a):a;});},toUnicode:function(a){return g(a,function(a){return u.test(a)?h(a.slice(4).toLowerCase()):a;});}},0,o&&i)if(T.exports==o)i.exports=n;else for(s in n)n.hasOwnProperty(s)&&(o[s]=n[s]);else a.punycode=n;}(this);}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{});},{}]},{},[2])(2);}); From 50092537b145c2b73cc87f48f104f7338838d751 Mon Sep 17 00:00:00 2001 From: Maxx Crawford Date: Fri, 28 Feb 2020 13:39:57 -0600 Subject: [PATCH 16/18] Fixed CSS statement issue --- src/panel.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/panel.css b/src/panel.css index c2a7ddb6..dcf872fe 100644 --- a/src/panel.css +++ b/src/panel.css @@ -181,7 +181,7 @@ a:hover { } .highlight-on-hover.remove-site-from-container.disabled-button::after, -.highlight-on-hover.remove-site-from-container.disabled-button span +.highlight-on-hover.remove-site-from-container.disabled-button span, .highlight-on-hover.add-site-to-container.disabled-button::after, .highlight-on-hover.add-site-to-container.disabled-button span { opacity: 0.4; From 9ff67ae3a9a5906e55384b2fe5e5c2ee4618a04e Mon Sep 17 00:00:00 2001 From: Maxx Crawford Date: Fri, 28 Feb 2020 13:52:30 -0600 Subject: [PATCH 17/18] Updated test to use new messages --- test/features/add-domain-to-fbc.test.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/test/features/add-domain-to-fbc.test.js b/test/features/add-domain-to-fbc.test.js index b7317b33..e8d59de1 100644 --- a/test/features/add-domain-to-fbc.test.js +++ b/test/features/add-domain-to-fbc.test.js @@ -6,16 +6,18 @@ describe("Add domain to Facebook Container", () => { background = webExtension.background; }); - describe("runtime message add-to-facebook-container", () => { + describe("runtime message add-domain-to-list", () => { beforeEach(async () => { - await background.browser.runtime.onMessage.addListener.yield("add-to-facebook-container", { + await background.browser.runtime.onMessage.addListener.yield({ + message: "add-domain-to-list" + }, { url: "https://example.com" }); }); describe("runtime message what-sites-are-added", () => { it("should return the added sites", async () => { - const [promise] = await background.browser.runtime.onMessage.addListener.yield("what-sites-are-added", {}); + const [promise] = await background.browser.runtime.onMessage.addListener.yield({message: "what-sites-are-added"}); const sites = await promise; expect(sites.includes("example.com")).to.be.true; }); @@ -25,14 +27,15 @@ describe("Add domain to Facebook Container", () => { describe("runtime message removeDomain", () => { it("should have removed the domain", async () => { await background.browser.runtime.onMessage.addListener.yield({ + message: "remove-domain-from-list", removeDomain: "example.com" - }, {}); + }); - const [promise] = await background.browser.runtime.onMessage.addListener.yield("what-sites-are-added", {}); + const [promise] = await background.browser.runtime.onMessage.addListener.yield({message: "what-sites-are-added"}); const sites = await promise; expect(sites.includes("example.com")).to.be.false; }); }); }); -}); \ No newline at end of file +}); From a663437a5e4885470c2f26208d59e774000e2ba7 Mon Sep 17 00:00:00 2001 From: Maxx Crawford Date: Fri, 28 Feb 2020 14:36:45 -0600 Subject: [PATCH 18/18] Fixed null rootDomainCache Co-Authored-By: luke crouch --- src/background.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/background.js b/src/background.js index 6608f763..739b0867 100644 --- a/src/background.js +++ b/src/background.js @@ -273,10 +273,11 @@ const rootDomainCache = {}; function getRootDomain(url) { if (url in rootDomainCache) { // After storing 128 entries, it will delete the oldest each time. + const returnValue = rootDomainCache[url]; if (Object.keys(rootDomainCache).length > 128) { delete rootDomainCache[(Object.keys(rootDomainCache)[0])]; } - return rootDomainCache[url]; + return returnValue; } const urlObject = new URL(url);