refactor(scripts): completely redesign scripts moving logic to background and improving content

This commit is contained in:
wanhose 2021-06-23 00:01:56 +02:00
parent 115312c732
commit cbe54df40c
2 changed files with 162 additions and 149 deletions

View File

@ -1,3 +1,14 @@
/**
* @var cacheInitialState
* @description Cache initial state
* @type {{ enabled: boolean, matches: string[] }}
*/
const cacheInitialState = {
enabled: true,
matches: [],
};
/** /**
* @function disableIcon * @function disableIcon
* @description Disables icon * @description Disables icon
@ -8,7 +19,7 @@
const disableIcon = (tabId) => { const disableIcon = (tabId) => {
chrome.browserAction.setIcon({ chrome.browserAction.setIcon({
path: "assets/icons/disabled.png", path: "assets/icons/disabled.png",
tabId: tabId, tabId,
}); });
}; };
@ -22,7 +33,7 @@ const disableIcon = (tabId) => {
const disablePopup = (tabId) => { const disablePopup = (tabId) => {
chrome.browserAction.setPopup({ chrome.browserAction.setPopup({
popup: "", popup: "",
tabId: tabId, tabId,
}); });
}; };
@ -36,7 +47,7 @@ const disablePopup = (tabId) => {
const enableIcon = (tabId) => { const enableIcon = (tabId) => {
chrome.browserAction.setIcon({ chrome.browserAction.setIcon({
path: "assets/icons/enabled.png", path: "assets/icons/enabled.png",
tabId: tabId, tabId,
}); });
}; };
@ -50,15 +61,78 @@ const enableIcon = (tabId) => {
const enablePopup = (tabId) => { const enablePopup = (tabId) => {
chrome.browserAction.setPopup({ chrome.browserAction.setPopup({
popup: "popup.html", popup: "popup.html",
tabId: tabId, tabId,
}); });
}; };
/**
* @async
* @function getCache
* @description Retrieves cache state
*
* @returns {Promise<{ enabled: boolean, matches: string[] }>} Cache state
*/
const getCache = async (hostname, responseCallback) => {
chrome.storage.local.get(null, (store) => {
const cache = store[hostname];
if (cache) {
responseCallback(cache);
} else {
chrome.storage.local.set({ [hostname]: cacheInitialState });
responseCallback(cacheInitialState);
}
});
};
/**
* @async
* @function updateCache
* @description Update cache state
*/
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])],
},
});
});
};
/**
* @async
* @function getList
* @description Retrieves selectors list
*
* @returns {Promise<{ matches: string[] }>} A selectors list
*/
const getList = async (responseCallback) => {
try {
const url =
"https://raw.githubusercontent.com/wanhose/do-not-consent/master/data/elements.txt";
const response = await fetch(url);
const data = await response.text();
if (response.status !== 200) throw new Error();
responseCallback({ matches: data.split("\n") });
} catch {
responseCallback({ matches: [] });
}
};
/** /**
* @description Listens to content messages * @description Listens to content messages
*/ */
chrome.runtime.onMessage.addListener((request) => { chrome.runtime.onMessage.addListener((request, sender, responseCallback) => {
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
const tab = tabs[0]; const tab = tabs[0];
const tabId = tab.id; const tabId = tab.id;
@ -76,8 +150,19 @@ chrome.runtime.onMessage.addListener((request) => {
case "ENABLE_POPUP": case "ENABLE_POPUP":
enablePopup(tabId); enablePopup(tabId);
break; break;
case "GET_CACHE":
getCache(request.hostname, responseCallback);
break;
case "GET_LIST":
getList(responseCallback);
break;
case "UPDATE_CACHE":
updateCache(request.hostname, request.selector);
break;
default: default:
break; break;
} }
}); });
return true;
}); });

View File

@ -7,48 +7,36 @@
let attempts = 1; let attempts = 1;
/** /**
* @var enabled * @var intervalId
* @description Is extension enabled? * @description Task interval identifier
* @type {number}
*/
let intervalId = 0;
/**
* @var ready
* @description Is extension ready?
* @type {boolean} * @type {boolean}
*/ */
let enabled = true; let ready = false;
/** /**
* @var selectors * @var selectorsFromCache
* @description Array of selectors * @description Array of selectors
* @type {string[]} * @type {string[]}
*/ */
let selectors = []; let selectorsFromCache = [];
/** /**
* @constant url * @var selectorsFromNetwork
* @description Database link * @description Array of selectors
* @type {string} * @type {string[]}
*/ */
const url = let selectorsFromNetwork = [];
"https://raw.githubusercontent.com/wanhose/do-not-consent/master/data/elements.txt";
/**
* @function commit
* @description Commits selector to cache
* @param {string} selector
*/
const commit = (selector) => {
chrome.storage.local.get(null, (cache) => {
const current = cache[document.location.hostname];
chrome.storage.local.set({
[document.location.hostname]: {
...current,
matches: [...new Set([...cache.matches, selector])],
},
});
});
};
/** /**
* @function fix * @function fix
@ -58,11 +46,12 @@ const commit = (selector) => {
const fix = () => { const fix = () => {
const html = document.documentElement; const html = document.documentElement;
const body = document.body; const body = document.body;
const facebook = document.querySelector("._31e"); const facebook = document.getElementsByClassName("._31e")[0];
html.style.setProperty("overflow-y", "unset", "important"); if (body) body.style.setProperty("overflow-y", "unset", "important");
body.style.setProperty("overflow-y", "unset", "important"); if (facebook) facebook.style.setProperty("position", "unset", "important");
if (facebook) root.style.setProperty("position", "unset", "important"); if (html) html.style.setProperty("overflow-y", "unset", "important");
if (ready) html.style.setProperty("opacity", "1", "important");
}; };
/** /**
@ -89,47 +78,14 @@ const search = (selector) => {
return null; return null;
}; };
/**
* @async
* @function check
* @description Checks if extension is enabled
* @returns {Promise<boolean>}
*/
const check = () =>
new Promise((resolve) => {
chrome.storage.local.get(null, (store) => {
try {
const cache = store[document.location.hostname];
resolve(cache.enabled);
} catch {
chrome.storage.local.set(
{
[document.location.hostname]: {
enabled: true,
matches: [],
},
},
() => resolve(true)
);
}
});
});
/** /**
* @function removeFromCache * @function removeFromCache
* @description Removes matched elements from cache results * @description Removes matched elements from cache results
*/ */
const removeFromCache = () => { const removeFromCache = () => {
chrome.storage.local.get(null, (store) => { for (let i = selectorsFromCache.length; i--; ) {
const cache = store[document.location.hostname]; const selector = selectorsFromCache[i];
const matches = cache.matches;
if (!!matches.length) {
for (let i = matches.length; i--; ) {
const selector = selectors[i];
const element = search(selector); const element = search(selector);
if (element) { if (element) {
@ -137,11 +93,10 @@ const removeFromCache = () => {
if (!["BODY", "HTML"].includes(tagName)) { if (!["BODY", "HTML"].includes(tagName)) {
element.remove(); element.remove();
ready = true;
} }
} }
} }
}
});
}; };
/** /**
@ -150,8 +105,8 @@ const removeFromCache = () => {
*/ */
const removeFromNetwork = () => { const removeFromNetwork = () => {
for (let i = selectors.length; i--; ) { for (let i = selectorsFromNetwork.length; i--; ) {
const selector = selectors[i]; const selector = selectorsFromNetwork[i];
const element = search(selector); const element = search(selector);
if (element) { if (element) {
@ -159,88 +114,61 @@ const removeFromNetwork = () => {
if (!["BODY", "HTML"].includes(tagName)) { if (!["BODY", "HTML"].includes(tagName)) {
element.remove(); element.remove();
commit(selector); ready = true;
chrome.runtime.sendMessage({
hostname: document.location.hostname,
selector,
type: "UPDATE_CACHE",
});
} }
} }
} }
}; };
/** /**
* @async * @function runTasks
* @function query * @description Starts running tasks
* @description Retrieves selectors list
*
* @returns {Promise<string[]>} A selectors list
*/ */
const query = async () => { const runTasks = () => {
try { if (attempts >= 5 || selectorsFromCache.length === 0) ready = true;
const response = await fetch(url, { cache: "no-cache" });
const data = await response.text();
if (response.status !== 200) throw new Error(); if (attempts <= 20) {
return data.split("\n");
} catch {
return [];
}
};
/**
* @constant observer
* @description Observer instance
* @type {MutationObserver}
*/
const observer = new MutationObserver((_, instance) => {
instance.disconnect();
fix(); fix();
removeFromCache(); removeFromCache();
if (attempts <= 5) removeFromNetwork(); if (attempts <= 5) removeFromNetwork();
attempts += 1; attempts += 1;
observe(); }
});
/** if (attempts > 20) {
* @function observe clearInterval(intervalId);
* @description Starts observing document.body element }
*/
const observe = () => {
observer.observe(document.body, {
attributes: true,
childList: true,
});
}; };
/** /**
* @async * @description Setup extension context
* @function handleContentLoaded
* @description Cleans, fixes scroll issues and observes document.body element
*/ */
const handleContentLoaded = async () => { chrome.runtime.sendMessage(
{ hostname: document.location.hostname, type: "GET_CACHE" },
null,
async (cacheResponse) => {
console.log(cacheResponse);
chrome.runtime.sendMessage({ type: "ENABLE_POPUP" }); chrome.runtime.sendMessage({ type: "ENABLE_POPUP" });
enabled = await check();
if (enabled) { if (cacheResponse.enabled) {
selectorsFromCache = cacheResponse.matches;
chrome.runtime.sendMessage({ type: "ENABLE_ICON" }); chrome.runtime.sendMessage({ type: "ENABLE_ICON" });
selectors = await query(); chrome.runtime.sendMessage(
{ type: "GET_LIST" },
if (selectors.length > 0) { null,
fix(); async (networkResponse) => {
removeFromCache(); selectorsFromNetwork = networkResponse.matches;
removeFromNetwork(); intervalId = setInterval(runTasks, 500);
observe(); }
);
} else {
document.documentElement.style.setProperty("opacity", "1", "important");
} }
} }
}; );
/**
* @description Listen to document ready
*
* @type {Document}
* @listens document#ready
*/
document.addEventListener("DOMContentLoaded", handleContentLoaded);