diff --git a/data/elements.txt b/data/elements.txt index 1c782c0..8ff0fb8 100644 --- a/data/elements.txt +++ b/data/elements.txt @@ -12523,7 +12523,6 @@ script[src="//clickio.mgr.consensu.org/t/consent_216889.js"] #didomi-popup div[style="position: fixed; z-index: 9999; width: 100%; height: 100%; inset: 0px; background-color: rgba(0, 0, 0, 0.5);"] #didomiConsentOverlay -.softMessages-list #acceptationCMPWall .qc-cmp2-container #qc-cmp2-container diff --git a/manifest.json b/manifest.json index 2342898..b16c048 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 2, "name": "Do Not Consent", - "version": "4.0.0", + "version": "4.0.1", "default_locale": "en", "description": "__MSG_appDesc__", "icons": { diff --git a/scripts/background.js b/scripts/background.js index 5f0d3d5..05bf90d 100644 --- a/scripts/background.js +++ b/scripts/background.js @@ -9,11 +9,24 @@ const cacheInitialState = { matches: [], }; +/** + * @function isValid + * @description Check cache validity + * + * @param {object} [cache] + */ + +const isValid = (cache) => + typeof cache.enabled === "boolean" && + Array.isArray(cache.matches) && + cache.matches.every((match) => typeof match === "string"); + /** * @function disableIcon * @description Disables icon * * @param {string} [tabId] + * @returns {boolean} */ const disableIcon = (tabId) => { @@ -70,16 +83,20 @@ const enablePopup = (tabId) => { * @function getCache * @description Retrieves cache state * + * @param {string} [hostname] + * @param {void} [responseCallback] * @returns {Promise<{ enabled: boolean, matches: string[] }>} Cache state */ const getCache = async (hostname, responseCallback) => { chrome.storage.local.get(null, (store) => { - const cache = store[hostname]; + try { + const cache = store[hostname]; + + if (!isValid(cache)) throw new Error(); - if (cache) { responseCallback(cache); - } else { + } catch { chrome.storage.local.set({ [hostname]: cacheInitialState }); responseCallback(cacheInitialState); } @@ -88,19 +105,18 @@ const getCache = async (hostname, responseCallback) => { /** * @async - * @function updateCache - * @description Update cache state + * @function getTab + * @description Retrieves current tab information + * + * @param {void} [responseCallback] + * @returns {Promise<{ id: string, location: string }>} Current tab information */ -const updateCache = async (hostname, selector) => { - chrome.storage.local.get(null, (cache) => { - const current = cache[hostname]; - - chrome.storage.local.set({ - [hostname]: { - ...current, - matches: [...new Set([...current.matches, selector])], - }, +const getTab = (responseCallback) => { + chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { + responseCallback({ + id: tabs[0].id, + hostname: new URL(tabs[0].url).hostname, }); }); }; @@ -110,6 +126,7 @@ const updateCache = async (hostname, selector) => { * @function getList * @description Retrieves selectors list * + * @param {void} [responseCallback] * @returns {Promise<{ matches: string[] }>} A selectors list */ @@ -122,12 +139,40 @@ const getList = async (responseCallback) => { if (response.status !== 200) throw new Error(); - responseCallback({ matches: data.split("\n") }); + responseCallback({ selectors: data.split("\n") }); } catch { - responseCallback({ matches: [] }); + responseCallback({ selectors: [] }); } }; +/** + * @async + * @function updateCache + * @description Update cache state + * + * @param {string} [hostname] + * @param {object} [state] + */ + +const updateCache = async (hostname, state) => { + chrome.storage.local.get(null, (cache) => { + const current = cache[hostname]; + + chrome.storage.local.set({ + [hostname]: { + enabled: + typeof state.enabled === "undefined" + ? current.enabled + : state.enabled, + matches: + typeof state.matches === "undefined" + ? current.matches + : [...new Set([...current.matches, ...state.matches])], + }, + }); + }); +}; + /** * @description Listens to content messages */ @@ -156,8 +201,11 @@ chrome.runtime.onMessage.addListener((request, sender, responseCallback) => { case "GET_LIST": getList(responseCallback); break; + case "GET_TAB": + getTab(responseCallback); + break; case "UPDATE_CACHE": - updateCache(request.hostname, request.selector); + updateCache(request.hostname, request.state); break; default: break; diff --git a/scripts/content.js b/scripts/content.js index 17f64c5..ee35da1 100644 --- a/scripts/content.js +++ b/scripts/content.js @@ -15,12 +15,12 @@ let attempts = 1; let intervalId = 0; /** - * @var ready - * @description Is extension ready? + * @var loading + * @description Is extension loading? * @type {boolean} */ -let ready = false; +let loading = true; /** * @var selectorsFromCache @@ -51,7 +51,7 @@ const fix = () => { if (body) body.style.setProperty("overflow-y", "unset", "important"); if (facebook) facebook.style.setProperty("position", "unset", "important"); if (html) html.style.setProperty("overflow-y", "unset", "important"); - if (ready) html.style.setProperty("opacity", "1", "important"); + if (!loading) html.style.setProperty("opacity", "1", "important"); }; /** @@ -93,7 +93,7 @@ const removeFromCache = () => { if (!["BODY", "HTML"].includes(tagName)) { element.remove(); - ready = true; + loading = false; } } } @@ -114,10 +114,10 @@ const removeFromNetwork = () => { if (!["BODY", "HTML"].includes(tagName)) { element.remove(); - ready = true; + loading = false; chrome.runtime.sendMessage({ hostname: document.location.hostname, - selector, + state: { matches: [selector] }, type: "UPDATE_CACHE", }); } @@ -131,13 +131,15 @@ const removeFromNetwork = () => { */ const runTasks = () => { - if (attempts >= 5 || selectorsFromCache.length === 0) ready = true; + if (attempts >= 5 || selectorsFromCache.length === 0) { + loading = false; + } if (attempts <= 20) { fix(); removeFromCache(); if (attempts <= 5) removeFromNetwork(); - attempts += 1; + if (document.readyState !== "loading") attempts += 1; } if (attempts > 20) { @@ -152,18 +154,17 @@ const runTasks = () => { chrome.runtime.sendMessage( { hostname: document.location.hostname, type: "GET_CACHE" }, null, - async (cacheResponse) => { - console.log(cacheResponse); + async ({ enabled, matches }) => { chrome.runtime.sendMessage({ type: "ENABLE_POPUP" }); - if (cacheResponse.enabled) { - selectorsFromCache = cacheResponse.matches; + if (enabled) { + selectorsFromCache = matches; chrome.runtime.sendMessage({ type: "ENABLE_ICON" }); chrome.runtime.sendMessage( { type: "GET_LIST" }, null, - async (networkResponse) => { - selectorsFromNetwork = networkResponse.matches; + async ({ selectors }) => { + selectorsFromNetwork = selectors; intervalId = setInterval(runTasks, 500); } ); diff --git a/scripts/popup.js b/scripts/popup.js index 4ce43e0..7b76b41 100644 --- a/scripts/popup.js +++ b/scripts/popup.js @@ -24,42 +24,6 @@ const firefoxUrl = const isChromium = chrome.runtime.getURL("").startsWith("chrome-extension://"); -/** - * @async - * @function currentTab - * @description Returns current tab state - * - * @returns {Promise<{ id: string, location: URL }>} - */ - -const currentTab = () => - new Promise((resolve) => { - chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { - resolve({ - id: tabs[0].id, - location: new URL(tabs[0].url), - }); - }); - }); - -/** - * @async - * @function currentState - * @description Returns current extension state - * - * @returns {Promise<{ enabled: boolean, matches: string[] }>}>} - */ - -const currentState = async () => { - const tab = await currentTab(); - - return new Promise((resolve) => { - chrome.storage.local.get(null, (store) => { - resolve(store[tab.location.hostname]); - }); - }); -}; - /** * @async * @function handlePowerChange @@ -67,30 +31,27 @@ const currentState = async () => { */ const handlePowerChange = async () => { - const state = await currentState(); - const tab = await currentTab(); + chrome.runtime.sendMessage({ type: "GET_TAB" }, null, ({ hostname, id }) => { + chrome.runtime.sendMessage( + { hostname, type: "GET_CACHE" }, + null, + ({ enabled }) => { + const power = document.getElementById("power"); - chrome.storage.local.set( - { - [tab.location.hostname]: { - ...state, - enabled: !state.enabled, - }, - }, - () => { - const power = document.getElementById("power"); - - if (!state.enabled === true) { - power.setAttribute("checked", "checked"); - chrome.runtime.sendMessage({ type: "ENABLE_ICON" }); - } else { - power.removeAttribute("checked"); - chrome.runtime.sendMessage({ type: "DISABLE_ICON" }); + chrome.runtime.sendMessage({ + hostname, + state: { enabled: !enabled }, + type: "UPDATE_CACHE", + }); + chrome.runtime.sendMessage({ + type: !enabled === true ? "ENABLE_ICON" : "DISABLE_ICON", + }); + if (!enabled === false) power.removeAttribute("checked"); + if (!enabled === true) power.setAttribute("checked", "checked"); + chrome.tabs.reload(id, { bypassCache: true }); } - - chrome.tabs.reload(tab.id, { bypassCache: true }); - } - ); + ); + }); }; /** @@ -100,9 +61,9 @@ const handlePowerChange = async () => { */ const handleReload = async () => { - const tab = await currentTab(); - - chrome.tabs.reload(tab.id, { bypassCache: true }); + chrome.runtime.sendMessage({ type: "GET_TAB" }, null, ({ id }) => { + chrome.tabs.reload(id, { bypassCache: true }); + }); }; /** @@ -137,23 +98,28 @@ const handleRate = (event) => { */ const handleContentLoaded = async () => { - const host = document.getElementById("host"); - const like = document.getElementById("like"); - const power = document.getElementById("power"); - const reload = document.getElementById("reload"); - const state = await currentState(); - const store = document.getElementById("store"); - const tab = await currentTab(); - const unlike = document.getElementById("unlike"); + chrome.runtime.sendMessage({ type: "GET_TAB" }, null, ({ hostname, id }) => { + chrome.runtime.sendMessage( + { hostname, type: "GET_CACHE" }, + null, + ({ enabled }) => { + const host = document.getElementById("host"); + const like = document.getElementById("like"); + const power = document.getElementById("power"); + const reload = document.getElementById("reload"); + const store = document.getElementById("store"); + const unlike = document.getElementById("unlike"); - like.addEventListener("click", handleRate); - power.addEventListener("change", handlePowerChange); - reload.addEventListener("click", handleReload); - store.setAttribute("href", isChromium ? chromeUrl : firefoxUrl); - unlike.addEventListener("click", handleRate); - - if (tab.location) host.innerText = tab.location.hostname.replace("www.", ""); - if (!state.enabled) power.removeAttribute("checked"); + like.addEventListener("click", handleRate); + power.addEventListener("change", handlePowerChange); + reload.addEventListener("click", handleReload); + store.setAttribute("href", isChromium ? chromeUrl : firefoxUrl); + unlike.addEventListener("click", handleRate); + if (location) host.innerText = hostname.replace("www.", ""); + if (!enabled) power.removeAttribute("checked"); + } + ); + }); }; /**