feat(scripts): improve code structure and performance
This commit is contained in:
parent
1176c2f83e
commit
354e311411
@ -101,6 +101,54 @@ const getCache = (hostname, responseCallback) => {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @async
|
||||
* @function getClasses
|
||||
* @description Retrieves a selectors list
|
||||
*
|
||||
* @param {void} [responseCallback]
|
||||
* @returns {Promise<{ matches: string[] }>} A selectors list
|
||||
*/
|
||||
|
||||
const getClasses = async (responseCallback) => {
|
||||
try {
|
||||
const url =
|
||||
"https://raw.githubusercontent.com/wanhose/do-not-consent/master/data/classes.txt";
|
||||
const response = await fetch(url);
|
||||
const data = await response.text();
|
||||
|
||||
if (response.status !== 200) throw new Error();
|
||||
|
||||
responseCallback({ classes: data.split("\n") });
|
||||
} catch {
|
||||
responseCallback({ classes: [] });
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @async
|
||||
* @function getSelectors
|
||||
* @description Retrieves a selectors list
|
||||
*
|
||||
* @param {void} [responseCallback]
|
||||
* @returns {Promise<{ matches: string[] }>} A selectors list
|
||||
*/
|
||||
|
||||
const getSelectors = 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({ selectors: data.split("\n") });
|
||||
} catch {
|
||||
responseCallback({ selectors: [] });
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @function getTab
|
||||
* @description Retrieves current tab information
|
||||
@ -118,30 +166,6 @@ const getTab = (responseCallback) => {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @async
|
||||
* @function getList
|
||||
* @description Retrieves selectors list
|
||||
*
|
||||
* @param {void} [responseCallback]
|
||||
* @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({ selectors: data.split("\n") });
|
||||
} catch {
|
||||
responseCallback({ selectors: [] });
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @function updateCache
|
||||
* @description Update cache state
|
||||
@ -200,8 +224,11 @@ chrome.runtime.onMessage.addListener((request, sender, responseCallback) => {
|
||||
case "GET_CACHE":
|
||||
getCache(request.hostname, responseCallback);
|
||||
break;
|
||||
case "GET_LIST":
|
||||
getList(responseCallback);
|
||||
case "GET_CLASSES":
|
||||
getClasses(responseCallback);
|
||||
break;
|
||||
case "GET_SELECTORS":
|
||||
getSelectors(responseCallback);
|
||||
break;
|
||||
case "GET_TAB":
|
||||
getTab(responseCallback);
|
||||
|
@ -1,5 +1,4 @@
|
||||
/**
|
||||
* @var attempts
|
||||
* @description Number of attempts
|
||||
* @type {number}
|
||||
*/
|
||||
@ -7,7 +6,13 @@
|
||||
let attempts = 1;
|
||||
|
||||
/**
|
||||
* @constant dispatch
|
||||
* @description Array of selectors
|
||||
* @type {string[]}
|
||||
*/
|
||||
|
||||
let classesFromNetwork = [];
|
||||
|
||||
/**
|
||||
* @description Shortcut to send messages to background script
|
||||
* @type {void}
|
||||
*/
|
||||
@ -15,15 +20,6 @@ let attempts = 1;
|
||||
const dispatch = chrome.runtime.sendMessage;
|
||||
|
||||
/**
|
||||
* @var intervalId
|
||||
* @description Task interval identifier
|
||||
* @type {number}
|
||||
*/
|
||||
|
||||
let intervalId = 0;
|
||||
|
||||
/**
|
||||
* @var selectorsFromCache
|
||||
* @description Array of selectors
|
||||
* @type {string[]}
|
||||
*/
|
||||
@ -31,30 +27,92 @@ let intervalId = 0;
|
||||
let selectorsFromCache = [];
|
||||
|
||||
/**
|
||||
* @var selectorsFromNetwork
|
||||
* @description Array of selectors
|
||||
* @type {string[]}
|
||||
* @type {Promise<string[]>[]}
|
||||
*/
|
||||
|
||||
let selectorsFromNetwork = [];
|
||||
|
||||
/**
|
||||
* @function fix
|
||||
* @description Fix scroll issues
|
||||
* @description Split large arrays into promises
|
||||
* @param {string[]} array
|
||||
*/
|
||||
|
||||
const chunkerize = (array) =>
|
||||
[...Array(Math.ceil(array.length / 300))].map(
|
||||
(_, index) => () =>
|
||||
new Promise((resolve) => {
|
||||
removeElements(array.slice(index * 300, (index + 1) * 300), true);
|
||||
resolve(true);
|
||||
})
|
||||
);
|
||||
|
||||
/**
|
||||
* @description Fixes scroll issues
|
||||
*/
|
||||
|
||||
const fix = () => {
|
||||
const body = document.body;
|
||||
const classListToRemove = ["ta-cc-modal-open"];
|
||||
const classes = classesFromNetwork;
|
||||
const facebook = document.getElementsByClassName("_31e")[0];
|
||||
const html = document.documentElement;
|
||||
|
||||
if (body) body.classList.remove(...classListToRemove);
|
||||
if (body && classes.length > 0) body.classList.remove(...classes);
|
||||
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");
|
||||
};
|
||||
|
||||
/**
|
||||
* @function removeElements
|
||||
* @description Removes matched elements from a selectors array
|
||||
* @param {string[]} selectors
|
||||
* @param {boolean} updateCache
|
||||
*/
|
||||
|
||||
const removeElements = (selectors, updateCache) => {
|
||||
for (let i = selectors.length; i--; ) {
|
||||
const selector = selectors[i];
|
||||
const element = search(selector);
|
||||
|
||||
if (element) {
|
||||
const tagName = element.tagName.toUpperCase();
|
||||
|
||||
if (!["BODY", "HTML"].includes(tagName)) {
|
||||
element.remove();
|
||||
|
||||
if (updateCache) {
|
||||
selectorsFromCache = [...selectorsFromCache, selector];
|
||||
dispatch({
|
||||
hostname: document.location.hostname,
|
||||
state: { matches: [selector] },
|
||||
type: "UPDATE_CACHE",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @function runTasks
|
||||
* @description Starts running tasks
|
||||
*/
|
||||
|
||||
const runTasks = async () => {
|
||||
if (attempts <= 20) {
|
||||
fix();
|
||||
removeElements(selectorsFromCache);
|
||||
|
||||
if (selectorsFromNetwork.length > 0) {
|
||||
const selectors = selectorsFromNetwork;
|
||||
|
||||
if (attempts <= 5) await Promise.all(selectors.map((fn) => fn()));
|
||||
if (document.readyState === "complete") attempts += 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @function search
|
||||
* @description Retrieves HTML element if selector exists
|
||||
@ -80,83 +138,40 @@ const search = (selector) => {
|
||||
};
|
||||
|
||||
/**
|
||||
* @function removeFromCache
|
||||
* @description Removes matched elements from cache results
|
||||
* @description Setups classes selectors
|
||||
* @type {Promise<boolean>}
|
||||
*/
|
||||
|
||||
const removeFromCache = () => {
|
||||
for (let i = selectorsFromCache.length; i--; ) {
|
||||
const selector = selectorsFromCache[i];
|
||||
const element = search(selector);
|
||||
|
||||
if (element) {
|
||||
const tagName = element.tagName.toUpperCase();
|
||||
|
||||
if (!["BODY", "HTML"].includes(tagName)) element.remove();
|
||||
}
|
||||
}
|
||||
};
|
||||
const setupClasses = new Promise((resolve) => {
|
||||
dispatch({ type: "GET_CLASSES" }, null, ({ classes }) => {
|
||||
classesFromNetwork = classes;
|
||||
resolve(true);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* @function removeFromNetwork
|
||||
* @description Removes matched elements from network results
|
||||
* @description Setups elements selectors
|
||||
* @type {Promise<boolean>}
|
||||
*/
|
||||
|
||||
const removeFromNetwork = () => {
|
||||
for (let i = selectorsFromNetwork.length; i--; ) {
|
||||
const selector = selectorsFromNetwork[i];
|
||||
const element = search(selector);
|
||||
|
||||
if (element) {
|
||||
const tagName = element.tagName.toUpperCase();
|
||||
|
||||
if (!["BODY", "HTML"].includes(tagName)) {
|
||||
element.remove();
|
||||
dispatch({
|
||||
hostname: document.location.hostname,
|
||||
state: { matches: [selector] },
|
||||
type: "UPDATE_CACHE",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @function runTasks
|
||||
* @description Starts running tasks
|
||||
*/
|
||||
|
||||
const runTasks = () => {
|
||||
if (attempts <= 20) {
|
||||
fix();
|
||||
removeFromCache();
|
||||
if (attempts <= 5) removeFromNetwork();
|
||||
if (document.readyState === "complete") attempts += 1;
|
||||
}
|
||||
|
||||
if (attempts > 20) {
|
||||
clearInterval(intervalId);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @description Setup extension context
|
||||
*/
|
||||
const setupSelectors = new Promise((resolve) => {
|
||||
dispatch({ type: "GET_SELECTORS" }, null, ({ selectors }) => {
|
||||
selectorsFromNetwork = chunkerize(selectors);
|
||||
resolve(true);
|
||||
});
|
||||
});
|
||||
|
||||
dispatch(
|
||||
{ hostname: document.location.hostname, type: "GET_CACHE" },
|
||||
null,
|
||||
({ enabled, matches }) => {
|
||||
async ({ enabled, matches }) => {
|
||||
dispatch({ type: "ENABLE_POPUP" });
|
||||
|
||||
if (enabled) {
|
||||
selectorsFromCache = matches;
|
||||
dispatch({ type: "ENABLE_ICON" });
|
||||
dispatch({ type: "GET_LIST" }, null, ({ selectors }) => {
|
||||
selectorsFromNetwork = selectors;
|
||||
intervalId = setInterval(runTasks, 500);
|
||||
});
|
||||
await Promise.all([setupClasses, setupSelectors]);
|
||||
setInterval(runTasks, 500);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user