diff --git a/packages/browser-extension/docs/README.md b/packages/browser-extension/docs/README.md index 61ebe54..c116634 100644 --- a/packages/browser-extension/docs/README.md +++ b/packages/browser-extension/docs/README.md @@ -14,7 +14,7 @@ - All browsers based on Chromium 88+ (Blisk, Brave, Colibri, Epic Browser, Iron Browser, Vivaldi and many more) - Google Chrome 109+ - Microsoft Edge 109+ -- Mozilla Firefox 113+ +- Mozilla Firefox 126+ - Mozilla Firefox Mobile 126+ ## Installation (for Mozilla Firefox users) diff --git a/packages/browser-extension/src/manifest.json b/packages/browser-extension/src/manifest.json index 9ed3b0a..50f4035 100644 --- a/packages/browser-extension/src/manifest.json +++ b/packages/browser-extension/src/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "Cookie Dialog Monster", - "version": "7.2.4", + "version": "7.3.0", "default_locale": "en", "description": "__MSG_appDesc__", "icons": { @@ -22,7 +22,7 @@ "browser_specific_settings": { "gecko": { "id": "{77e2c00b-e173-4604-863d-01645d8d2826}", - "strict_min_version": "113.0", + "strict_min_version": "126.0", "update_url": "https://www.cookie-dialog-monster.com/mozilla/updates.json" } }, diff --git a/packages/browser-extension/src/scripts/background.js b/packages/browser-extension/src/scripts/background.js index 5ae7192..c1f1057 100644 --- a/packages/browser-extension/src/scripts/background.js +++ b/packages/browser-extension/src/scripts/background.js @@ -115,7 +115,6 @@ browser.runtime.onMessage.addListener((message, sender, callback) => { case 'DISABLE_ICON': if (isPage && tabId !== undefined) { browser.action.setIcon({ path: '/assets/icons/disabled.png', tabId }, suppressLastError); - browser.action.setBadgeText({ tabId, text: '' }); } break; case 'ENABLE_ICON': @@ -130,11 +129,8 @@ browser.runtime.onMessage.addListener((message, sender, callback) => { break; case 'GET_DATA': storage.get('data', ({ data }) => { - if (data) { - callback(data); - } else { - refreshData(callback); - } + if (data) callback(data); + else refreshData(callback); }); return true; case 'GET_EXCLUSION_LIST': @@ -163,9 +159,19 @@ browser.runtime.onMessage.addListener((message, sender, callback) => { script.insertCSS({ files: ['styles/dialog.css'], target: { tabId } }); } break; + case 'INSERT_EXTENSION_CSS': + if (isPage && tabId !== undefined) { + script.insertCSS({ files: ['styles/extension.css'], target: { tabId } }); + } + break; case 'REFRESH_DATA': refreshData(callback); return true; + case 'RELOAD_TAB': + if (tabId !== undefined) { + browser.tabs.reload(tabId, { bypassCache: true }); + } + break; case 'REPORT': if (tabId !== undefined) { report(message, sender.tab, callback); @@ -173,18 +179,15 @@ browser.runtime.onMessage.addListener((message, sender, callback) => { } break; case 'SET_BADGE': - if (tabId !== undefined) { + if (isPage && tabId !== undefined) { browser.action.setBadgeBackgroundColor({ color: '#6b7280' }); - browser.action.setBadgeText({ tabId, text: message.value }); + browser.action.setBadgeText({ tabId, text: message.value ? `${message.value}` : null }); } break; case 'SET_HOSTNAME_STATE': if (hostname) { - if (message.state.enabled === false) { - storage.set({ [hostname]: message.state }); - } else { - storage.remove(hostname); - } + if (message.state.enabled === false) storage.set({ [hostname]: message.state }); + else storage.remove(hostname); } break; default: @@ -252,22 +255,20 @@ browser.webRequest.onBeforeRequest.addListener( return; } - const hostname = url.split('.').slice(-3).join('.').replace('www.', ''); - const store = await storage.get(hostname); + const hostname = new URL(url).hostname.split('.').slice(-3).join('.').replace('www.', ''); + const { data, ...store } = await storage.get(['data', hostname]); const state = store[hostname] ?? { enabled: true }; - if (state.enabled) { - const { data } = await storage.get('data'); - - if (data?.rules?.length) { - browser.declarativeNetRequest.updateSessionRules({ - addRules: data.rules.map((rule) => ({ - ...rule, - condition: { ...rule.condition, tabIds: [tabId] }, - })), - removeRuleIds: data.rules.map((rule) => rule.id), - }); - } + if (data?.rules?.length) { + browser.declarativeNetRequest.updateSessionRules({ + addRules: state.enabled + ? data.rules.map((rule) => ({ + ...rule, + condition: { ...rule.condition, tabIds: [tabId] }, + })) + : undefined, + removeRuleIds: data.rules.map((rule) => rule.id), + }); } } }, diff --git a/packages/browser-extension/src/scripts/content.js b/packages/browser-extension/src/scripts/content.js index ca9b188..029252c 100644 --- a/packages/browser-extension/src/scripts/content.js +++ b/packages/browser-extension/src/scripts/content.js @@ -37,10 +37,10 @@ if (typeof browser === 'undefined') { } /** - * @description Matched elements count - * @type {number} + * @description Actions done by the extension + * @type {Set} */ -let count = 0; +let actions = new Set(); /** * @description Data object with all the necessary information @@ -90,9 +90,9 @@ const options = { childList: true, subtree: true }; /** * @description Elements that were already matched and are removable - * @type {HTMLElement[]} + * @type {Set} */ -const removables = []; +const removables = new Set(); /** * @description Elements that were already seen @@ -123,26 +123,12 @@ function clean(elements, skipMatch) { const element = elements[index]; if (match(element, skipMatch)) { - const observer = new MutationObserver(forceElementStyles); + if (element instanceof HTMLDialogElement) element.close(); + else element.setAttribute(dataAttributeName, 'true'); - if (element instanceof HTMLDialogElement) { - element.close(); - } else { - element.setAttribute(dataAttributeName, 'true'); - element.style.setProperty('display', 'none', 'important'); - } - - observer.observe(element, { - attributes: true, - attributeFilter: [dataAttributeName, 'class', 'style'], - }); - - count += 1; - dispatch({ type: 'SET_BADGE', value: `${count}` }); - - if (!removables.includes(element)) { - removables.push(element); - } + actions.add(new Date().getTime().toString()); + dispatch({ type: 'SET_BADGE', value: actions.size }); + removables.add(element); } seen.push(element); @@ -178,23 +164,6 @@ function forceClean(from) { } } -/** - * @description Force element to have these styles - * @type {MutationCallback} - */ -function forceElementStyles(mutations, observer) { - for (const mutation of mutations) { - const element = mutation.target; - const value = element.getAttribute(dataAttributeName); - - if (value === null) { - observer.disconnect(); - } else { - element.style.setProperty('display', 'none', 'important'); - } - } -} - /** * Get all elements that match the selector * @param {string | string[]} [selector] @@ -341,46 +310,9 @@ function fix() { const domains = skips.domains.map((x) => (x.split('.').length < 3 ? `*${x}` : x)); for (const backdrop of backdrops) { - if (backdrop.children.length === 0 && backdrop.style.display !== 'none') { - backdrop.style.setProperty('display', 'none'); - count += 1; - dispatch({ type: 'SET_BADGE', value: `${count}` }); - } - } - - // 2024-08-02: fix #644 temporarily - document.getElementsByTagName('ion-router-outlet')[0]?.removeAttribute('inert'); - - for (const fix of fixes) { - const { action, domain, property, selector } = fix; - - if (hostname.includes(domain)) { - switch (action) { - case 'click': { - const element = document.querySelector(selector); - element?.click(); - break; - } - case 'remove': { - const element = document.querySelector(selector); - element?.style?.removeProperty(property); - break; - } - case 'reload': { - window.location.reload(); - break; - } - case 'reset': { - const element = document.querySelector(selector); - element?.style?.setProperty(property, 'initial', 'important'); - break; - } - case 'resetAll': { - const elements = getElements(selector); - elements.forEach((e) => e?.style?.setProperty(property, 'initial', 'important')); - break; - } - } + if (backdrop.children.length === 0 && !backdrop.hasAttribute(dataAttributeName)) { + actions.add(new Date().getTime().toString()); + backdrop.setAttribute(dataAttributeName, 'true'); } } @@ -391,37 +323,65 @@ function fix() { element?.style.setProperty('overflow-y', 'initial', 'important'); } } -} -/** - * @description Restore DOM to its previous state - * @returns {void} - */ -function restoreDOM() { - const backdrops = getElements(tokens.backdrops); + for (const fix of fixes) { + const { action, domain, property, selector } = fix; - for (const backdrop of backdrops) { - if (backdrop.children.length === 0 && backdrop.hasAttribute(dataAttributeName)) { - backdrop.style.removeProperty('display'); + if (hostname.includes(domain)) { + switch (action) { + case 'click': { + const element = document.querySelector(selector); + + actions.add('click'); + element?.click(); + break; + } + case 'remove': { + const element = document.querySelector(selector); + + actions.add('remove'); + element?.style?.removeProperty(property); + break; + } + case 'reload': { + window.location.reload(); + break; + } + case 'reset': { + const element = document.querySelector(selector); + + actions.add('reset'); + element?.style?.setProperty(property, 'initial', 'important'); + break; + } + case 'resetAll': { + const elements = getElements(selector); + + actions.add('resetAll'); + elements.forEach((e) => e?.style?.setProperty(property, 'initial', 'important')); + break; + } + } } } - for (const element of removables) { - element.removeAttribute(dataAttributeName); - element.style.removeProperty('display'); + const ionRouterOutlet = document.getElementsByTagName('ion-router-outlet')[0]; - if (element instanceof HTMLDialogElement) { - element.showModal(); - } + if (ionRouterOutlet) { + actions.add('ion-router-outlet'); + // 2024-08-02: fix #644 temporarily + ionRouterOutlet.removeAttribute('inert'); } - for (const element of [document.body, document.documentElement]) { - element?.style.removeProperty('position'); - element?.style.removeProperty('overflow-y'); + const t4Wrapper = document.getElementsByClassName('t4-wrapper')[0]; + + if (t4Wrapper) { + actions.add('t4-wrapper'); + // 2024-09-12: fix #945 temporarily + t4Wrapper.removeAttribute('inert'); } - count = 0; - seen.splice(0, seen.length); + dispatch({ type: 'SET_BADGE', value: actions.size }); } /** @@ -462,18 +422,14 @@ async function setUp(params = {}) { skips = data?.skips ?? skips; tokens = data?.tokens ?? tokens; - if (count > 0) { - dispatch({ type: 'SET_BADGE', value: `${count}` }); - } - dispatch({ type: 'ENABLE_ICON' }); + dispatch({ type: 'INSERT_EXTENSION_CSS' }); + dispatch({ type: 'SET_BADGE', value: actions.size }); observer.observe(document.body ?? document.documentElement, options); - - if (!params.skipRunFn) { - run({ containers: tokens.containers }); - } + if (!params.skipRunFn) run({ containers: tokens.containers }); } else { dispatch({ type: 'DISABLE_ICON' }); + dispatch({ type: 'SET_BADGE', value: actions.size }); observer.disconnect(); } } @@ -500,13 +456,12 @@ const observer = new MutationObserver((mutations) => { browser.runtime.onMessage.addListener(async (message) => { switch (message.type) { case 'RESTORE': { - restoreDOM(); - await setUp({ skipRunFn: true }); + await dispatch({ type: 'RELOAD_TAB' }); break; } case 'RUN': { - await setUp({ skipRunFn: !!removables.length }); - run({ elements: removables, skipMatch: true }); + await setUp({ skipRunFn: !!removables.size }); + run({ elements: [...removables], skipMatch: true }); break; } } diff --git a/packages/browser-extension/src/scripts/dialog.js b/packages/browser-extension/src/scripts/dialog.js index 64db741..211ac15 100644 --- a/packages/browser-extension/src/scripts/dialog.js +++ b/packages/browser-extension/src/scripts/dialog.js @@ -40,16 +40,12 @@ const reportDialogHtml = ` ${browser.i18n.getMessage('reportDialog_urlInputLabel')} * -
+ />
${browser.i18n.getMessage('reportDialog_urlInputError')}
@@ -59,19 +55,13 @@ const reportDialogHtml = ` ${browser.i18n.getMessage('reportDialog_reasonInputLabel')} * -
- ${browser.i18n.getMessage('reportDialog_reasonInputPlaceholder')} -
+ rows="4" + >${browser.i18n.getMessage('reportDialog_reasonInputPlaceholder')}
${browser.i18n.getMessage('reportDialog_reasonInputError')}
@@ -146,22 +136,6 @@ function inputKeyDownHandler(event) { } } -/** - * @description Input paste handler - * @param {ClipboardEvent} event - */ -function inputPasteHandler(event) { - event.preventDefault(); - const text = event.clipboardData?.getData('text').replace(/\r?\n|\r/g, ' '); - - const selection = window.getSelection(); - - if (selection.rangeCount) { - selection.deleteFromDocument(); - selection.getRangeAt(0).insertNode(document.createTextNode(text)); - } -} - /** * @description Show report dialog */ @@ -174,7 +148,7 @@ function showReportDialog() { existingDialog.showModal(); submitButton.setAttribute('aria-disabled', 'false'); - urlInput.textContent = window.location.origin + window.location.pathname; + urlInput.setAttribute('value', window.location.origin + window.location.pathname); return; } @@ -188,18 +162,15 @@ function showReportDialog() { const urlInput = dialog?.querySelector('#report-dialog-input-url'); closeButton.addEventListener('click', closeButtonClickHandler); - dialog.querySelector('#report-dialog-input-url').textContent = - window.location.origin + window.location.pathname; + urlInput.setAttribute('value', window.location.origin + window.location.pathname); link.setAttribute('href', 'https://fonts.googleapis.com/css?family=Inter'); link.setAttribute('id', 'report-dialog-font'); link.setAttribute('rel', 'stylesheet'); reasonInput.addEventListener('input', inputChangeHandler); reasonInput.addEventListener('keydown', inputKeyDownHandler); - reasonInput.addEventListener('paste', inputPasteHandler); submitButton.addEventListener('click', submitButtonClickHandler); urlInput.addEventListener('input', inputChangeHandler); urlInput.addEventListener('keydown', inputKeyDownHandler); - urlInput.addEventListener('paste', inputPasteHandler); dispatch({ type: 'INSERT_DIALOG_CSS' }); document.body.appendChild(dialog); @@ -222,9 +193,9 @@ async function submitButtonClickHandler(event) { const dialog = document.getElementById(reportDialogId); const reasonInput = dialog?.querySelector('#report-dialog-input-reason'); - const reasonText = reasonInput?.textContent.trim(); + const reasonText = reasonInput?.value.trim(); const urlInput = dialog?.querySelector('#report-dialog-input-url'); - const urlText = urlInput?.textContent.trim(); + const urlText = urlInput?.value.trim(); const errors = validateForm({ reason: reasonText, url: urlText }); diff --git a/packages/browser-extension/src/styles/dialog.css b/packages/browser-extension/src/styles/dialog.css index f4934e3..091fa3a 100644 --- a/packages/browser-extension/src/styles/dialog.css +++ b/packages/browser-extension/src/styles/dialog.css @@ -126,6 +126,7 @@ } #report-dialog .report-dialog-input { + all: unset; border: 1px solid var(--cookie-dialog-monster-color-tertiary); border-radius: 4px; color: var(--cookie-dialog-monster-color-secondary); @@ -213,7 +214,7 @@ display: flex; font-family: Inter, Arial, Helvetica, sans-serif; font-size: 14px; - height: 39px; + height: 42px; justify-content: center; line-height: 1.2; outline: none; diff --git a/packages/browser-extension/src/styles/extension.css b/packages/browser-extension/src/styles/extension.css new file mode 100644 index 0000000..a794fc0 --- /dev/null +++ b/packages/browser-extension/src/styles/extension.css @@ -0,0 +1,3 @@ +*[data-cookie-dialog-monster='true'] { + clip-path: circle(0px) !important; +} diff --git a/packages/web/src/mozilla-mobile/updates.json b/packages/web/src/mozilla-mobile/updates.json index 4df7299..1849b1e 100644 --- a/packages/web/src/mozilla-mobile/updates.json +++ b/packages/web/src/mozilla-mobile/updates.json @@ -13,6 +13,10 @@ { "version": "7.2.4", "update_link": "https://www.cookie-dialog-monster.com/releases/7.2.4-mozilla-mobile.xpi" + }, + { + "version": "7.3.0", + "update_link": "https://www.cookie-dialog-monster.com/releases/7.3.0-mozilla-mobile.xpi" } ] } diff --git a/packages/web/src/mozilla/updates.json b/packages/web/src/mozilla/updates.json index 8680779..6da0c66 100644 --- a/packages/web/src/mozilla/updates.json +++ b/packages/web/src/mozilla/updates.json @@ -45,6 +45,10 @@ { "version": "7.2.4", "update_link": "https://www.cookie-dialog-monster.com/releases/7.2.4.xpi" + }, + { + "version": "7.3.0", + "update_link": "https://www.cookie-dialog-monster.com/releases/7.3.0.xpi" } ] } diff --git a/packages/web/src/releases/7.3.0-mozilla-mobile.xpi b/packages/web/src/releases/7.3.0-mozilla-mobile.xpi new file mode 100644 index 0000000..2960844 Binary files /dev/null and b/packages/web/src/releases/7.3.0-mozilla-mobile.xpi differ diff --git a/packages/web/src/releases/7.3.0.xpi b/packages/web/src/releases/7.3.0.xpi new file mode 100644 index 0000000..270ed49 Binary files /dev/null and b/packages/web/src/releases/7.3.0.xpi differ diff --git a/packages/web/src/releases/7.3.0.zip b/packages/web/src/releases/7.3.0.zip new file mode 100644 index 0000000..d6ff3c8 Binary files /dev/null and b/packages/web/src/releases/7.3.0.zip differ diff --git a/packages/web/src/releases/latest-mozilla-mobile.xpi b/packages/web/src/releases/latest-mozilla-mobile.xpi index e6a9009..2960844 100644 Binary files a/packages/web/src/releases/latest-mozilla-mobile.xpi and b/packages/web/src/releases/latest-mozilla-mobile.xpi differ diff --git a/packages/web/src/releases/latest.xpi b/packages/web/src/releases/latest.xpi index a229a6f..270ed49 100644 Binary files a/packages/web/src/releases/latest.xpi and b/packages/web/src/releases/latest.xpi differ diff --git a/packages/web/src/releases/latest.zip b/packages/web/src/releases/latest.zip index 350b857..d6ff3c8 100644 Binary files a/packages/web/src/releases/latest.zip and b/packages/web/src/releases/latest.zip differ