diff --git a/packages/browser-extension/src/scripts/background.js b/packages/browser-extension/src/scripts/background.js index 8a7cba7..1a0a104 100644 --- a/packages/browser-extension/src/scripts/background.js +++ b/packages/browser-extension/src/scripts/background.js @@ -64,24 +64,36 @@ const getCache = (hostname, callback) => { /** * @async - * @description Retrieves data from GitHub - * @param {string} key + * @description Get all data from GitHub * @param {void} callback - * @returns {Promise<{ any: string[] }>} + * @returns {Promise<{ attributes: string[], classes: string[], fixes: string[], selectors: string[], skips: [] }>} */ -const query = async (key, callback) => { - try { - const url = `${baseDataUrl}/${key}.txt`; - const response = await fetch(url); - const data = await response.text(); +const getData = async (callback) => { + const data = await Promise.all([ + query('classes'), + query('elements'), + query('fixes'), + query('skips'), + ]); - if (response.status !== 200) throw new Error(); + callback({ + attributes: [ + ...new Set( + data[1].elements.flatMap((element) => { + const attributes = element.match(/(?<=\[)[^(){}[\]]+(?=\])/g); - callback({ [key]: data.split('\n') }); - } catch { - callback({ [key]: [] }); - } + return attributes?.length + ? [...attributes.map((attribute) => attribute.replace(/\".*\"|(=|\^|\*|\$)/g, ''))] + : []; + }) + ), + ], + classes: data[0].classes, + fixes: data[2].fixes, + selectors: data[1].elements, + skips: data[3].skips, + }); }; /** @@ -90,7 +102,7 @@ const query = async (key, callback) => { * @returns {Promise<{ id: string, location: string }>} */ -const queryTab = (callback) => { +const getTab = (callback) => { chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { callback({ id: tabs[0]?.id, @@ -99,6 +111,27 @@ const queryTab = (callback) => { }); }; +/** + * @async + * @description Retrieves data from GitHub + * @param {string} key + * @returns {Promise<{ [key]: string[] }>} + */ + +const query = async (key) => { + try { + const url = `${baseDataUrl}/${key}.txt`; + const response = await fetch(url); + const data = await response.text(); + + if (response.status !== 200) throw new Error(); + + return { [key]: [...new Set(data.split('\n'))] }; + } catch { + return { [key]: [] }; + } +}; + /** * @description Reports active tab URL */ @@ -165,20 +198,11 @@ chrome.runtime.onMessage.addListener((request, sender, callback) => { case 'GET_CACHE': getCache(hostname, callback); break; - case 'GET_CLASSES': - query('classes', callback); - break; - case 'GET_SKIPS': - query('skips', callback); - break; - case 'GET_FIXES': - query('fixes', callback); - break; - case 'GET_SELECTORS': - query('elements', callback); + case 'GET_DATA': + getData(callback); break; case 'GET_TAB': - queryTab(callback); + getTab(callback); break; case 'UPDATE_CACHE': updateCache(hostname, state); diff --git a/packages/browser-extension/src/scripts/content.js b/packages/browser-extension/src/scripts/content.js index f54d039..fdb3936 100644 --- a/packages/browser-extension/src/scripts/content.js +++ b/packages/browser-extension/src/scripts/content.js @@ -32,18 +32,18 @@ const fixes = []; const hostname = document.location.hostname.split('.').slice(-2).join('.'); -/** - * @description Is consent preview page? - */ - -const preview = hostname.startsWith('consent.') || hostname.startsWith('myprivacy.'); - /** * @description Options provided to observer * @type {MutationObserverInit} */ -const options = { attributes: true, childList: true, subtree: true }; +const options = { childList: true, subtree: true }; + +/** + * @description Is consent preview page? + */ + +const preview = hostname.startsWith('consent.') || hostname.startsWith('myprivacy.'); /** * @description Selectors list @@ -138,19 +138,6 @@ const observer = new MutationObserver((mutations, instance) => { instance.observe(target, options); }); -/** - * @description Gets data - * @returns {Promise} - */ - -const promiseAll = () => - Promise.all([ - new Promise((resolve) => dispatch({ type: 'GET_CLASSES' }, null, resolve)), - new Promise((resolve) => dispatch({ type: 'GET_FIXES' }, null, resolve)), - new Promise((resolve) => dispatch({ type: 'GET_SELECTORS' }, null, resolve)), - new Promise((resolve) => dispatch({ type: 'GET_SKIPS' }, null, resolve)), - ]); - /** * @description Cleans DOM again after all * @listens document#readystatechange @@ -179,17 +166,18 @@ window.addEventListener('unload', () => {}); * @description Setups everything and starts to observe if enabled */ -dispatch({ hostname, type: 'GET_CACHE' }, null, async ({ enabled }) => { +dispatch({ hostname, type: 'GET_CACHE' }, null, ({ enabled }) => { dispatch({ type: 'ENABLE_POPUP' }); if (enabled) { - const results = await promiseAll(); - - classes.push(...(results[0]?.classes ?? [])); - fixes.push(...(results[1]?.fixes ?? [])); - selectors.push(...(results[2]?.elements ?? [])); - skips.push(...(results[3]?.skips ?? [])); - observer.observe(target, options); - dispatch({ type: 'ENABLE_ICON' }); + dispatch({ type: 'GET_DATA' }, null, (data) => { + classes.push(...data.classes); + fixes.push(...data.fixes); + options.attributeFilter = data.attributes; + selectors.push(...data.selectors); + skips.push(...data.skips); + observer.observe(target, options); + dispatch({ type: 'ENABLE_ICON' }); + }); } });