feat(browser-extension): move backdrops to database and improve code/documentation
This commit is contained in:
parent
acb6243412
commit
9a12e46796
@ -834,6 +834,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"tokens": {
|
"tokens": {
|
||||||
|
"backdrops": [".modal-backdrop", ".offcanvas-backdrop", ".overlay"],
|
||||||
"classes": [
|
"classes": [
|
||||||
"appconsent_noscroll",
|
"appconsent_noscroll",
|
||||||
"b-modal-banner--disabled",
|
"b-modal-banner--disabled",
|
||||||
|
@ -1,28 +1,28 @@
|
|||||||
/**
|
/**
|
||||||
* @typedef {Object} ExtensionData
|
* @typedef {Object} ExtensionData
|
||||||
* @property {string[] | undefined} commonWords
|
* @property {string[]} commonWords
|
||||||
* @property {Fix[] | undefined} fixes
|
* @property {Fix[]} fixes
|
||||||
* @property {{ domains: string[] | undefined, tags: string[] | undefined } | undefined} skips
|
* @property {{ domains: string[], tags: string[] }} skips
|
||||||
* @property {{ classes: string[] | undefined, selectors: string[] | undefined } | undefined} tokens
|
* @property {{ backdrops: string[], classes: string[], selectors: string[] }} tokens
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} Fix
|
* @typedef {Object} Fix
|
||||||
* @property {string} action
|
* @property {string} action
|
||||||
* @property {string} domain
|
* @property {string} domain
|
||||||
* @property {string | undefined} property
|
* @property {string} [property]
|
||||||
* @property {string} selector
|
* @property {string} selector
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} RunParams
|
* @typedef {Object} RunParams
|
||||||
* @property {HTMLElement[] | undefined} elements
|
* @property {HTMLElement[]} [elements]
|
||||||
* @property {boolean | undefined} skipMatch
|
* @property {boolean} [skipMatch]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} SetUpParams
|
* @typedef {Object} SetUpParams
|
||||||
* @property {boolean | undefined} skipRunFn
|
* @property {boolean} [skipRunFn]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (typeof browser === 'undefined') {
|
if (typeof browser === 'undefined') {
|
||||||
@ -39,7 +39,19 @@ let count = 0;
|
|||||||
* @description Data properties
|
* @description Data properties
|
||||||
* @type {ExtensionData}
|
* @type {ExtensionData}
|
||||||
*/
|
*/
|
||||||
let { commonWords, fixes = [], skips, tokens } = {};
|
let { commonWords, fixes, skips, tokens } = {
|
||||||
|
commonWords: [],
|
||||||
|
fixes: [],
|
||||||
|
skips: {
|
||||||
|
domains: [],
|
||||||
|
tags: [],
|
||||||
|
},
|
||||||
|
tokens: {
|
||||||
|
backdrops: [],
|
||||||
|
classes: [],
|
||||||
|
selectors: [],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Attribute name
|
* @description Attribute name
|
||||||
@ -98,7 +110,7 @@ let state = { enabled: true };
|
|||||||
/**
|
/**
|
||||||
* @description Clean DOM
|
* @description Clean DOM
|
||||||
* @param {Element[]} elements
|
* @param {Element[]} elements
|
||||||
* @param {boolean?} skipMatch
|
* @param {boolean} [skipMatch]
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
function clean(elements, skipMatch) {
|
function clean(elements, skipMatch) {
|
||||||
@ -156,7 +168,7 @@ function containsCommonWord(element) {
|
|||||||
*/
|
*/
|
||||||
function forceClean(element) {
|
function forceClean(element) {
|
||||||
const nodes = [...element.querySelectorAll(tokens.selectors)];
|
const nodes = [...element.querySelectorAll(tokens.selectors)];
|
||||||
const elements = nodes.flatMap((node) => filterMapEarly(node));
|
const elements = nodes.flatMap((node) => filterNodeEarly(node));
|
||||||
|
|
||||||
if (elements.length) {
|
if (elements.length) {
|
||||||
fix();
|
fix();
|
||||||
@ -220,16 +232,11 @@ function isInViewport(element) {
|
|||||||
/**
|
/**
|
||||||
* @description Check if element element is removable
|
* @description Check if element element is removable
|
||||||
* @param {Element} element
|
* @param {Element} element
|
||||||
* @param {boolean?} skipMatch
|
* @param {boolean} [skipMatch]
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
function match(element, skipMatch) {
|
function match(element, skipMatch) {
|
||||||
if (
|
if (!tokens.selectors.length || !skips.tags.length) {
|
||||||
!commonWords.length ||
|
|
||||||
!tokens?.classes?.length ||
|
|
||||||
!tokens?.selectors?.length ||
|
|
||||||
!skips?.tags?.length
|
|
||||||
) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,7 +252,7 @@ function match(element, skipMatch) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tagName = element.tagName?.toUpperCase?.();
|
const tagName = element.tagName.toUpperCase();
|
||||||
|
|
||||||
if (skips.tags.includes(tagName)) {
|
if (skips.tags.includes(tagName)) {
|
||||||
return false;
|
return false;
|
||||||
@ -283,13 +290,13 @@ function match(element, skipMatch) {
|
|||||||
* @param {Node} node
|
* @param {Node} node
|
||||||
* @param {boolean} stopRecursion
|
* @param {boolean} stopRecursion
|
||||||
*/
|
*/
|
||||||
function filterMapEarly(node, stopRecursion) {
|
function filterNodeEarly(node, stopRecursion) {
|
||||||
if (node.nodeType !== Node.ELEMENT_NODE || !(node instanceof HTMLElement)) {
|
if (node.nodeType !== Node.ELEMENT_NODE || !(node instanceof HTMLElement)) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (commonWords && containsCommonWord(node) && !stopRecursion) {
|
if (commonWords && containsCommonWord(node) && !stopRecursion) {
|
||||||
return [node, ...[...node.children].flatMap((node) => filterMapEarly(node, true))];
|
return [node, ...[...node.children].flatMap((node) => filterNodeEarly(node, true))];
|
||||||
}
|
}
|
||||||
|
|
||||||
return [node];
|
return [node];
|
||||||
@ -300,12 +307,8 @@ function filterMapEarly(node, stopRecursion) {
|
|||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
function fix() {
|
function fix() {
|
||||||
const backdrops = document.querySelectorAll([
|
const backdrops = tokens.backdrops.length ? [...document.querySelectorAll(tokens.backdrops)] : [];
|
||||||
'.modal-backdrop',
|
const domains = skips.domains.map((x) => (x.split('.').length < 3 ? `*${x}` : x));
|
||||||
'.offcanvas-backdrop',
|
|
||||||
'.overlay',
|
|
||||||
]);
|
|
||||||
const domains = (skips?.domains ?? []).map((x) => (x.split('.').length < 3 ? `*${x}` : x));
|
|
||||||
|
|
||||||
for (const backdrop of backdrops) {
|
for (const backdrop of backdrops) {
|
||||||
if (backdrop.children.length === 0 && backdrop.style.display !== 'none') {
|
if (backdrop.children.length === 0 && backdrop.style.display !== 'none') {
|
||||||
@ -349,7 +352,7 @@ function fix() {
|
|||||||
|
|
||||||
if (domains.every((x) => !hostname.match(x.replaceAll(/\*/g, '[^ ]*')))) {
|
if (domains.every((x) => !hostname.match(x.replaceAll(/\*/g, '[^ ]*')))) {
|
||||||
for (const element of [document.body, document.documentElement]) {
|
for (const element of [document.body, document.documentElement]) {
|
||||||
element?.classList.remove(...(tokens?.classes ?? []));
|
element?.classList.remove(...(tokens.classes ?? []));
|
||||||
element?.style.setProperty('position', 'initial', 'important');
|
element?.style.setProperty('position', 'initial', 'important');
|
||||||
element?.style.setProperty('overflow-y', 'initial', 'important');
|
element?.style.setProperty('overflow-y', 'initial', 'important');
|
||||||
}
|
}
|
||||||
@ -361,10 +364,12 @@ function fix() {
|
|||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
function restoreDOM() {
|
function restoreDOM() {
|
||||||
const backdrop = document.getElementsByClassName('modal-backdrop')[0];
|
const backdrops = tokens.backdrops.length ? [...document.querySelectorAll(tokens.backdrops)] : [];
|
||||||
|
|
||||||
if (backdrop?.children.length === 0) {
|
for (const backdrop of backdrops) {
|
||||||
backdrop.style.removeProperty('display');
|
if (backdrop.children.length === 0 && backdrop.hasAttribute(dataAttributeName)) {
|
||||||
|
backdrop.style.removeProperty('display');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const elements = [...document.querySelectorAll(`[${dataAttributeName}]`)];
|
const elements = [...document.querySelectorAll(`[${dataAttributeName}]`)];
|
||||||
@ -384,11 +389,11 @@ function restoreDOM() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Clean DOM when this function is called
|
* @description Clean DOM when this function is called
|
||||||
* @param {RunParams} params
|
* @param {RunParams} [params]
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
function run(params = {}) {
|
function run(params = {}) {
|
||||||
if (document.body?.children.length && !preview && state.enabled && tokens?.selectors?.length) {
|
if (document.body?.children.length && !preview && state.enabled && tokens.selectors.length) {
|
||||||
fix();
|
fix();
|
||||||
|
|
||||||
if (params.elements?.length) {
|
if (params.elements?.length) {
|
||||||
@ -408,7 +413,7 @@ function run(params = {}) {
|
|||||||
...[...(document.getElementById('app')?.children ?? [])],
|
...[...(document.getElementById('app')?.children ?? [])],
|
||||||
...[...(document.getElementById('main')?.children ?? [])],
|
...[...(document.getElementById('main')?.children ?? [])],
|
||||||
...[...(document.getElementById('root')?.children ?? [])],
|
...[...(document.getElementById('root')?.children ?? [])],
|
||||||
].flatMap((node) => filterMapEarly(node))
|
].flatMap((node) => filterNodeEarly(node))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -417,19 +422,14 @@ function run(params = {}) {
|
|||||||
/**
|
/**
|
||||||
* @async
|
* @async
|
||||||
* @description Set up the extension
|
* @description Set up the extension
|
||||||
* @param {SetUpParams | undefined} params
|
* @param {SetUpParams} [params]
|
||||||
*/
|
*/
|
||||||
async function setUp(params) {
|
async function setUp(params = {}) {
|
||||||
state = (await dispatch({ hostname, type: 'GET_HOSTNAME_STATE' })) ?? state;
|
state = (await dispatch({ hostname, type: 'GET_HOSTNAME_STATE' })) ?? state;
|
||||||
dispatch({ type: 'ENABLE_POPUP' });
|
dispatch({ type: 'ENABLE_POPUP' });
|
||||||
|
|
||||||
if (state.enabled) {
|
if (state.enabled) {
|
||||||
const data = await dispatch({ hostname, type: 'GET_DATA' });
|
data = await dispatch({ hostname, type: 'GET_DATA' });
|
||||||
|
|
||||||
commonWords = data?.commonWords;
|
|
||||||
fixes = data?.fixes;
|
|
||||||
skips = data?.skips;
|
|
||||||
tokens = data?.tokens;
|
|
||||||
|
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
dispatch({ type: 'SET_BADGE', value: `${count}` });
|
dispatch({ type: 'SET_BADGE', value: `${count}` });
|
||||||
@ -438,7 +438,7 @@ async function setUp(params) {
|
|||||||
dispatch({ type: 'ENABLE_ICON' });
|
dispatch({ type: 'ENABLE_ICON' });
|
||||||
observer.observe(document.body ?? document.documentElement, options);
|
observer.observe(document.body ?? document.documentElement, options);
|
||||||
|
|
||||||
if (!params?.skipRunFn) {
|
if (!params.skipRunFn) {
|
||||||
run();
|
run();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -452,12 +452,12 @@ async function setUp(params) {
|
|||||||
* @type {MutationObserver}
|
* @type {MutationObserver}
|
||||||
*/
|
*/
|
||||||
const observer = new MutationObserver((mutations) => {
|
const observer = new MutationObserver((mutations) => {
|
||||||
if (preview || !state.enabled || !tokens?.selectors.length) {
|
if (preview || !state.enabled || !tokens.selectors.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const nodes = mutations.flatMap((mutation) => [...mutation.addedNodes]);
|
const nodes = mutations.flatMap((mutation) => [...mutation.addedNodes]);
|
||||||
const elements = nodes.flatMap((node) => filterMapEarly(node));
|
const elements = nodes.flatMap((node) => filterNodeEarly(node));
|
||||||
|
|
||||||
run({ elements });
|
run({ elements });
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user