commit
ac2a6750d9
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 3,
|
"manifest_version": 3,
|
||||||
"name": "Cookie Dialog Monster",
|
"name": "Cookie Dialog Monster",
|
||||||
"version": "6.4.8",
|
"version": "7.0.0",
|
||||||
"default_locale": "en",
|
"default_locale": "en",
|
||||||
"description": "__MSG_appDesc__",
|
"description": "__MSG_appDesc__",
|
||||||
"icons": {
|
"icons": {
|
||||||
|
@ -107,6 +107,7 @@ chrome.runtime.onMessage.addListener((message, sender, callback) => {
|
|||||||
case 'DISABLE_ICON':
|
case 'DISABLE_ICON':
|
||||||
if (isPage && tabId) {
|
if (isPage && tabId) {
|
||||||
chrome.action.setIcon({ path: '/assets/icons/disabled.png', tabId }, suppressLastError);
|
chrome.action.setIcon({ path: '/assets/icons/disabled.png', tabId }, suppressLastError);
|
||||||
|
chrome.action.setBadgeText({ tabId, text: '' });
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'ENABLE_ICON':
|
case 'ENABLE_ICON':
|
||||||
@ -158,6 +159,12 @@ chrome.runtime.onMessage.addListener((message, sender, callback) => {
|
|||||||
report(message, sender.tab);
|
report(message, sender.tab);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'SET_BADGE':
|
||||||
|
if (tabId) {
|
||||||
|
chrome.action.setBadgeBackgroundColor({ color: '#6b7280' });
|
||||||
|
chrome.action.setBadgeText({ tabId, text: message.value });
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'SET_HOSTNAME_STATE':
|
case 'SET_HOSTNAME_STATE':
|
||||||
if (hostname && message.state.enabled === false) {
|
if (hostname && message.state.enabled === false) {
|
||||||
storage.set({ [hostname]: message.state });
|
storage.set({ [hostname]: message.state });
|
||||||
|
@ -1,3 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* @description Attribute name
|
||||||
|
*/
|
||||||
|
const dataAttributeName = 'data-cookie-dialog-monster';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Matched elements count
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
let count = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Data properties
|
* @description Data properties
|
||||||
* @type {{ classes: string[], commonWords?: string[], fixes: string[], elements: string[], skips: string[], tags: string[] }?}
|
* @type {{ classes: string[], commonWords?: string[], fixes: string[], elements: string[], skips: string[], tags: string[] }?}
|
||||||
@ -9,12 +20,23 @@ let data = null;
|
|||||||
*/
|
*/
|
||||||
const dispatch = chrome.runtime.sendMessage;
|
const dispatch = chrome.runtime.sendMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Event name
|
||||||
|
*/
|
||||||
|
const setupEventName = 'cookie-dialog-monster';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Current hostname
|
* @description Current hostname
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
const hostname = getHostname();
|
const hostname = getHostname();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Elements that were already matched and are removable
|
||||||
|
* @type {HTMLElement[]}
|
||||||
|
*/
|
||||||
|
const removables = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Options provided to observer
|
* @description Options provided to observer
|
||||||
* @type {MutationObserverInit}
|
* @type {MutationObserverInit}
|
||||||
@ -47,13 +69,23 @@ let state = { enabled: true };
|
|||||||
function clean(elements, skipMatch) {
|
function clean(elements, skipMatch) {
|
||||||
for (const element of elements) {
|
for (const element of elements) {
|
||||||
if (match(element, skipMatch)) {
|
if (match(element, skipMatch)) {
|
||||||
const observer = new MutationObserver(() => forceElementStyles(element));
|
const observer = new MutationObserver(forceElementStyles);
|
||||||
|
const options = { attributes: true, attributeFilter: [dataAttributeName, 'class', 'style'] };
|
||||||
|
|
||||||
element.setAttribute('data-cookie-dialog-monster', 'true');
|
element.setAttribute(dataAttributeName, 'true');
|
||||||
element.style.setProperty('display', 'none', 'important');
|
element.style.setProperty('display', 'none', 'important');
|
||||||
observer.observe(element, { attributes: true, attributeFilter: ['class', 'style'] });
|
observer.observe(element, options);
|
||||||
|
|
||||||
|
count += 1;
|
||||||
|
dispatch({ type: 'SET_BADGE', value: `${count}` });
|
||||||
|
|
||||||
|
if (!removables.includes(element)) {
|
||||||
|
removables.push(element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
seen.push(element);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -70,11 +102,23 @@ function forceClean(element) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Force element to have these styles
|
* @description Force element to have these styles
|
||||||
* @param {HTMLElement} element
|
* @type {MutationCallback}
|
||||||
* @returns {void}
|
|
||||||
*/
|
*/
|
||||||
function forceElementStyles(element) {
|
function forceElementStyles(mutations, observer) {
|
||||||
|
for (const mutation of mutations) {
|
||||||
|
if (mutation.type === 'attributes' && dataAttributeName === mutation.attributeName) {
|
||||||
|
const element = mutation.target;
|
||||||
|
const value = element.getAttribute(dataAttributeName);
|
||||||
|
|
||||||
|
if (value === null) {
|
||||||
|
observer.disconnect();
|
||||||
|
element.removeAttribute(dataAttributeName);
|
||||||
|
element.style.removeProperty('display');
|
||||||
|
} else {
|
||||||
element.style.setProperty('display', 'none', 'important');
|
element.style.setProperty('display', 'none', 'important');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -119,7 +163,11 @@ function match(element, skipMatch) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (element.getAttribute('data-cookie-dialog-monster')) {
|
if (element.getAttribute(dataAttributeName)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seen.includes(element)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,12 +177,6 @@ function match(element, skipMatch) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (seen.includes(element)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
seen.push(element);
|
|
||||||
|
|
||||||
if (element.hasAttributes()) {
|
if (element.hasAttributes()) {
|
||||||
// 2023-06-10: twitch.tv temporary fix
|
// 2023-06-10: twitch.tv temporary fix
|
||||||
if (element.classList.contains('chat-line__message')) {
|
if (element.classList.contains('chat-line__message')) {
|
||||||
@ -167,8 +209,10 @@ function fix() {
|
|||||||
const fixes = data?.fixes ?? [];
|
const fixes = data?.fixes ?? [];
|
||||||
const skips = (data?.skips ?? []).map((x) => (x.split('.').length < 3 ? `*${x}` : x));
|
const skips = (data?.skips ?? []).map((x) => (x.split('.').length < 3 ? `*${x}` : x));
|
||||||
|
|
||||||
if (backdrop?.children.length === 0) {
|
if (backdrop?.children.length === 0 && backdrop.style.display !== 'none') {
|
||||||
backdrop.remove();
|
backdrop.style.setProperty('display', 'none');
|
||||||
|
count += 1;
|
||||||
|
dispatch({ type: 'SET_BADGE', value: `${count}` });
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const fix of fixes) {
|
for (const fix of fixes) {
|
||||||
@ -176,25 +220,29 @@ function fix() {
|
|||||||
|
|
||||||
if (hostname.includes(match)) {
|
if (hostname.includes(match)) {
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case 'click':
|
case 'click': {
|
||||||
document.querySelector(selector)?.click();
|
const element = document.querySelector(selector);
|
||||||
|
element?.click();
|
||||||
break;
|
break;
|
||||||
case 'remove':
|
}
|
||||||
document.querySelector(selector)?.style?.removeProperty(property);
|
case 'remove': {
|
||||||
|
const element = document.querySelector(selector);
|
||||||
|
element?.style?.removeProperty(property);
|
||||||
break;
|
break;
|
||||||
case 'reset':
|
}
|
||||||
document.querySelector(selector)?.style?.setProperty(property, 'initial', 'important');
|
case 'reset': {
|
||||||
break;
|
const element = document.querySelector(selector);
|
||||||
case 'resetAll':
|
|
||||||
document.querySelectorAll(selector).forEach((element) => {
|
|
||||||
element?.style?.setProperty(property, 'initial', 'important');
|
element?.style?.setProperty(property, 'initial', 'important');
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
default:
|
}
|
||||||
|
case 'resetAll': {
|
||||||
|
const elements = document.querySelectorAll(selector);
|
||||||
|
elements.forEach((e) => e?.style?.setProperty(property, 'initial', 'important'));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (skips.every((x) => !hostname.match(x.replaceAll(/\*/g, '[^ ]*')))) {
|
if (skips.every((x) => !hostname.match(x.replaceAll(/\*/g, '[^ ]*')))) {
|
||||||
for (const element of [document.body, document.documentElement]) {
|
for (const element of [document.body, document.documentElement]) {
|
||||||
@ -218,12 +266,38 @@ function readingTime() {
|
|||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Restore DOM to its previous state
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function restoreDOM() {
|
||||||
|
const backdrop = document.getElementsByClassName('modal-backdrop')[0];
|
||||||
|
|
||||||
|
if (backdrop?.children.length === 0) {
|
||||||
|
backdrop.style.removeProperty('display');
|
||||||
|
}
|
||||||
|
|
||||||
|
const elements = [...document.querySelectorAll(`[${dataAttributeName}]`)];
|
||||||
|
|
||||||
|
for (const element of elements) {
|
||||||
|
element.removeAttribute(dataAttributeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const element of [document.body, document.documentElement]) {
|
||||||
|
element?.style.removeProperty('position');
|
||||||
|
element?.style.removeProperty('overflow-y');
|
||||||
|
}
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
seen.splice(0, seen.length);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @async
|
* @async
|
||||||
* @description Set up everything
|
* @description Set up everything
|
||||||
* @param {boolean} skipReadyStateHack
|
* @param {boolean} skipReadyStateHack
|
||||||
*/
|
*/
|
||||||
async function runSetup(skipReadyStateHack) {
|
async function setup(skipReadyStateHack) {
|
||||||
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' });
|
||||||
|
|
||||||
@ -232,11 +306,14 @@ async function runSetup(skipReadyStateHack) {
|
|||||||
|
|
||||||
// 2023-06-13: hack to force clean when data request takes too long and there are no changes later
|
// 2023-06-13: hack to force clean when data request takes too long and there are no changes later
|
||||||
if (document.readyState === 'complete' && !skipReadyStateHack) {
|
if (document.readyState === 'complete' && !skipReadyStateHack) {
|
||||||
window.dispatchEvent(new Event('run'));
|
window.dispatchEvent(new Event(setupEventName));
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch({ type: 'ENABLE_ICON' });
|
dispatch({ type: 'ENABLE_ICON' });
|
||||||
observer.observe(document.body ?? document.documentElement, options);
|
observer.observe(document.body ?? document.documentElement, options);
|
||||||
|
} else {
|
||||||
|
dispatch({ type: 'DISABLE_ICON' });
|
||||||
|
observer.disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,15 +328,34 @@ const observer = new MutationObserver((mutations) => {
|
|||||||
if (data?.elements.length && !preview) clean(elements);
|
if (data?.elements.length && !preview) clean(elements);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Listen to messages from any other scripts
|
||||||
|
* @listens chrome.tabs#onMessage
|
||||||
|
*/
|
||||||
|
chrome.runtime.onMessage.addListener((message) => {
|
||||||
|
switch (message.type) {
|
||||||
|
case 'RESTORE': {
|
||||||
|
restoreDOM();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'RUN': {
|
||||||
|
if (removables.length) clean(removables, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setup();
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @async
|
* @async
|
||||||
* @description Run setup if the page wasn't focused yet
|
* @description Run setup if the page wasn't visible yet
|
||||||
* @listens window#focus
|
* @listens window#visibilitychange
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
window.addEventListener('focus', async () => {
|
window.addEventListener('visibilitychange', async () => {
|
||||||
if (document.body && !data) {
|
if (document.body?.children.length && !data) {
|
||||||
await runSetup(true);
|
await setup(true);
|
||||||
clean([...document.body.children]);
|
clean([...document.body.children]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -270,8 +366,8 @@ window.addEventListener('focus', async () => {
|
|||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
window.addEventListener('load', () => {
|
window.addEventListener('load', () => {
|
||||||
if (document.hasFocus()) {
|
if (document.visibilityState === 'visible') {
|
||||||
window.dispatchEvent(new Event('run'));
|
window.dispatchEvent(new Event(setupEventName));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -281,8 +377,8 @@ window.addEventListener('load', () => {
|
|||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
window.addEventListener('pageshow', (event) => {
|
window.addEventListener('pageshow', (event) => {
|
||||||
if (document.hasFocus() && event.persisted) {
|
if (document.visibilityState === 'visible' && event.persisted) {
|
||||||
window.dispatchEvent(new Event('run'));
|
window.dispatchEvent(new Event(setupEventName));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -291,8 +387,8 @@ window.addEventListener('pageshow', (event) => {
|
|||||||
* @listens window#run
|
* @listens window#run
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
window.addEventListener('run', () => {
|
window.addEventListener(setupEventName, () => {
|
||||||
if (data?.elements.length && document.body && state.enabled && !preview) {
|
if (data?.elements.length && document.body?.children.length && state.enabled && !preview) {
|
||||||
if (readingTime() < 4) {
|
if (readingTime() < 4) {
|
||||||
forceClean(document.body);
|
forceClean(document.body);
|
||||||
} else {
|
} else {
|
||||||
@ -302,6 +398,6 @@ window.addEventListener('run', () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (document.hasFocus()) {
|
if (document.visibilityState === 'visible') {
|
||||||
runSetup();
|
setup();
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,6 @@
|
|||||||
*/
|
*/
|
||||||
const chromeUrl = 'https://chrome.google.com/webstore/detail/djcbfpkdhdkaflcigibkbpboflaplabg';
|
const chromeUrl = 'https://chrome.google.com/webstore/detail/djcbfpkdhdkaflcigibkbpboflaplabg';
|
||||||
|
|
||||||
/**
|
|
||||||
* @description Shortcut to send messages to background script
|
|
||||||
*/
|
|
||||||
const dispatch = chrome.runtime.sendMessage;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Edge Add-ons link
|
* @description Edge Add-ons link
|
||||||
* @type {string}
|
* @type {string}
|
||||||
@ -48,9 +43,9 @@ const isFirefox = navigator.userAgent.indexOf('Firefox') !== -1;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Extension state
|
* @description Extension state
|
||||||
* @type {{ enabled: boolean }}
|
* @type {{ enabled: boolean, tabId: number | undefined }}
|
||||||
*/
|
*/
|
||||||
let state = { enabled: true };
|
let state = { enabled: true, tabId: undefined };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @async
|
* @async
|
||||||
@ -58,12 +53,14 @@ let state = { enabled: true };
|
|||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
async function handleContentLoaded() {
|
async function handleContentLoaded() {
|
||||||
const tab = await dispatch({ type: 'GET_TAB' });
|
const tab = await chrome.runtime.sendMessage({ type: 'GET_TAB' });
|
||||||
|
|
||||||
hostname = tab?.url
|
hostname = tab?.url
|
||||||
? new URL(tab.url).hostname.split('.').slice(-3).join('.').replace('www.', '')
|
? new URL(tab.url).hostname.split('.').slice(-3).join('.').replace('www.', '')
|
||||||
: undefined;
|
: undefined;
|
||||||
state = (await dispatch({ hostname, type: 'GET_HOSTNAME_STATE' })) ?? state;
|
|
||||||
|
const next = await chrome.runtime.sendMessage({ hostname, type: 'GET_HOSTNAME_STATE' });
|
||||||
|
state = { ...(next ?? state), tabId: tab?.id };
|
||||||
|
|
||||||
const hostTextElement = document.getElementById('host');
|
const hostTextElement = document.getElementById('host');
|
||||||
hostTextElement.innerText = hostname ?? 'unknown';
|
hostTextElement.innerText = hostname ?? 'unknown';
|
||||||
@ -112,11 +109,13 @@ async function handleLinkRedirect(event) {
|
|||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
async function handlePowerToggle(event) {
|
async function handlePowerToggle(event) {
|
||||||
state = { enabled: !state.enabled };
|
const element = event.currentTarget;
|
||||||
dispatch({ hostname, state, type: 'SET_HOSTNAME_STATE' });
|
const next = { enabled: !state.enabled };
|
||||||
if (state.enabled) event.currentTarget.setAttribute('data-value', 'on');
|
|
||||||
else event.currentTarget.setAttribute('data-value', 'off');
|
chrome.runtime.sendMessage({ hostname, state: next, type: 'SET_HOSTNAME_STATE' });
|
||||||
await chrome.tabs.reload({ bypassCache: true });
|
chrome.tabs.sendMessage(state.tabId, { type: next.enabled ? 'RUN' : 'RESTORE' });
|
||||||
|
element.setAttribute('disabled', 'true');
|
||||||
|
element.setAttribute('data-value', next.enabled ? 'on' : 'off');
|
||||||
window.close();
|
window.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user