feat(browser-extension): adapt code to database exclusions and fix minor bugs
This commit is contained in:
parent
a5766071fd
commit
7d8d3957ee
@ -49,7 +49,7 @@ class RequestManager {
|
|||||||
* @description API URL
|
* @description API URL
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
const apiUrl = 'https://api.cookie-dialog-monster.com/rest/v5';
|
const apiUrl = 'https://api.cookie-dialog-monster.com/rest/v6';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Context menu identifier
|
* @description Context menu identifier
|
||||||
@ -171,34 +171,6 @@ async function getState(hostname) {
|
|||||||
return { ...stateByDefault, ...state, updateAvailable };
|
return { ...stateByDefault, ...state, updateAvailable };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @description Format number to avoid errors
|
|
||||||
* @param {number} [value]
|
|
||||||
* @returns {string | null}
|
|
||||||
*/
|
|
||||||
function formatNumber(value) {
|
|
||||||
if (value) {
|
|
||||||
if (value >= 1e6) {
|
|
||||||
return `${Math.floor(value / 1e6)}M`;
|
|
||||||
} else if (value >= 1e3) {
|
|
||||||
return `${Math.floor(value / 1e3)}K`;
|
|
||||||
} else {
|
|
||||||
return value.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description Convert match string to pattern string
|
|
||||||
* @param {string} match
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
function matchToPattern(match) {
|
|
||||||
return `^${match.replaceAll('*.', '*(.)?').replaceAll('*', '.*')}$`;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @async
|
* @async
|
||||||
* @description Refresh data
|
* @description Refresh data
|
||||||
@ -370,7 +342,7 @@ browser.runtime.onMessage.addListener((message, sender, callback) => {
|
|||||||
case 'UPDATE_BADGE':
|
case 'UPDATE_BADGE':
|
||||||
if (isPage && tabId !== undefined) {
|
if (isPage && tabId !== undefined) {
|
||||||
browser.action.setBadgeBackgroundColor({ color: '#6b7280' });
|
browser.action.setBadgeBackgroundColor({ color: '#6b7280' });
|
||||||
browser.action.setBadgeText({ tabId, text: formatNumber(message.value) });
|
browser.action.setBadgeText({ tabId, text: message.value ? `${message.value}` : null });
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'UPDATE_STORE':
|
case 'UPDATE_STORE':
|
||||||
@ -419,6 +391,7 @@ browser.runtime.onInstalled.addListener((details) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (details.reason === 'update') {
|
if (details.reason === 'update') {
|
||||||
|
refreshData();
|
||||||
storage.remove('updateAvailable');
|
storage.remove('updateAvailable');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -453,27 +426,24 @@ browser.webRequest.onBeforeRequest.addListener(
|
|||||||
const { tabId, type, url } = details;
|
const { tabId, type, url } = details;
|
||||||
|
|
||||||
if (tabId > -1 && type === 'main_frame') {
|
if (tabId > -1 && type === 'main_frame') {
|
||||||
const manifest = browser.runtime.getManifest();
|
const { exclusions, rules } = await getData();
|
||||||
const excludeMatches = manifest.content_scripts[0].exclude_matches;
|
|
||||||
const excludePatterns = excludeMatches.map(matchToPattern);
|
|
||||||
|
|
||||||
if (excludePatterns.some((pattern) => new RegExp(pattern).test(url))) {
|
if (exclusions.domains.some((x) => location.hostname.match(x.replaceAll(/\*/g, '[^ ]*')))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await getData();
|
|
||||||
const hostname = getHostname(url);
|
const hostname = getHostname(url);
|
||||||
const state = await getState(hostname);
|
const state = await getState(hostname);
|
||||||
|
|
||||||
if (data?.rules?.length) {
|
if (rules?.length) {
|
||||||
const rules = data.rules.map((rule) => ({
|
const rulesWithTabId = rules.map((rule) => ({
|
||||||
...rule,
|
...rule,
|
||||||
condition: { ...rule.condition, tabIds: [tabId] },
|
condition: { ...rule.condition, tabIds: [tabId] },
|
||||||
}));
|
}));
|
||||||
|
|
||||||
await browser.declarativeNetRequest.updateSessionRules({
|
await browser.declarativeNetRequest.updateSessionRules({
|
||||||
addRules: state.on ? rules : undefined,
|
addRules: state.on ? rulesWithTabId : undefined,
|
||||||
removeRuleIds: data.rules.map((rule) => rule.id),
|
removeRuleIds: rules.map((rule) => rule.id),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -486,15 +456,10 @@ browser.webRequest.onBeforeRequest.addListener(
|
|||||||
*/
|
*/
|
||||||
browser.webRequest.onErrorOccurred.addListener(
|
browser.webRequest.onErrorOccurred.addListener(
|
||||||
async (details) => {
|
async (details) => {
|
||||||
const { error, tabId, url } = details;
|
const { error, tabId } = details;
|
||||||
|
|
||||||
if (error === 'net::ERR_BLOCKED_BY_CLIENT' && tabId > -1) {
|
if (error === 'net::ERR_BLOCKED_BY_CLIENT' && tabId > -1) {
|
||||||
const hostname = getHostname(url);
|
await browser.tabs.sendMessage(tabId, { type: 'INCREASE_ACTIONS_COUNT', value: error });
|
||||||
const state = await getState(hostname);
|
|
||||||
|
|
||||||
if (state.on) {
|
|
||||||
await browser.tabs.sendMessage(tabId, { type: 'INCREASE_ACTIONS_COUNT' });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ urls: ['<all_urls>'] }
|
{ urls: ['<all_urls>'] }
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
* @typedef {Object} ExtensionData
|
* @typedef {Object} Action
|
||||||
* @property {string[]} commonWords
|
* @property {string} domain
|
||||||
* @property {Fix[]} fixes
|
* @property {string} name
|
||||||
* @property {{ domains: string[], tags: string[] }} skips
|
* @property {string} [property]
|
||||||
* @property {{ backdrops: string[], classes: string[], containers: string[], selectors: string[] }} tokens
|
* @property {string} selector
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -12,11 +12,24 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} Fix
|
* @typedef {Object} ExclusionMap
|
||||||
* @property {string} action
|
* @property {string[]} domains
|
||||||
* @property {string} domain
|
* @property {string[]} overflows
|
||||||
* @property {string} [property]
|
* @property {string[]} tags
|
||||||
* @property {string} selector
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} ExtensionData
|
||||||
|
* @property {Action[]} actions
|
||||||
|
* @property {ExclusionMap} exclusions
|
||||||
|
* @property {string[]} keywords
|
||||||
|
* @property {TokenMap} tokens
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} GetElementsParams
|
||||||
|
* @property {boolean} [filterEarly]
|
||||||
|
* @property {HTMLElement} [from]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -27,9 +40,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} GetElementsParams
|
* @typedef {Object} TokenMap
|
||||||
* @property {boolean} [filterEarly]
|
* @property {string[]} backdrops
|
||||||
* @property {HTMLElement} [from]
|
* @property {string[]} classes
|
||||||
|
* @property {string[]} containers
|
||||||
|
* @property {string[]} selectors
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -42,22 +57,31 @@ if (typeof browser === 'undefined') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Actions done by the extension
|
* @description Class for request batching
|
||||||
* @type {Set<string>}
|
|
||||||
*/
|
*/
|
||||||
const actions = new Set();
|
class NotifiableSet extends Set {
|
||||||
|
constructor(...args) {
|
||||||
|
super(...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
add(value) {
|
||||||
|
super.add(value);
|
||||||
|
browser.runtime.sendMessage({ type: 'UPDATE_BADGE', value: super.size });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Data object with all the necessary information
|
* @description Data object with all the necessary information
|
||||||
* @type {ExtensionData}
|
* @type {ExtensionData}
|
||||||
*/
|
*/
|
||||||
let { commonWords, fixes, skips, tokens } = {
|
let { actions, exclusions, keywords, tokens } = {
|
||||||
commonWords: [],
|
actions: [],
|
||||||
fixes: [],
|
exclusions: {
|
||||||
skips: {
|
|
||||||
domains: [],
|
domains: [],
|
||||||
|
overflows: [],
|
||||||
tags: [],
|
tags: [],
|
||||||
},
|
},
|
||||||
|
keywords: [],
|
||||||
tokens: {
|
tokens: {
|
||||||
backdrops: [],
|
backdrops: [],
|
||||||
classes: [],
|
classes: [],
|
||||||
@ -80,7 +104,13 @@ const hostname = getHostname();
|
|||||||
* @description Initial visibility state
|
* @description Initial visibility state
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
let initiallyVisible = document.visibilityState === 'visible';
|
let initiallyVisible = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Log of those steps done by the extension
|
||||||
|
* @type {NotifiableSet<string>}
|
||||||
|
*/
|
||||||
|
const log = new NotifiableSet();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Options provided to observer
|
* @description Options provided to observer
|
||||||
@ -96,9 +126,9 @@ const seen = new Set();
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Extension state
|
* @description Extension state
|
||||||
* @type {ContentState}
|
* @type {ContentState | undefined}
|
||||||
*/
|
*/
|
||||||
let state = { on: true };
|
let state = undefined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Clean DOM
|
* @description Clean DOM
|
||||||
@ -120,8 +150,7 @@ function clean(elements, skipMatch) {
|
|||||||
if (element instanceof HTMLDialogElement) element.close();
|
if (element instanceof HTMLDialogElement) element.close();
|
||||||
hide(element);
|
hide(element);
|
||||||
|
|
||||||
actions.add(`${Date.now()}`);
|
log.add(`${Date.now()}`);
|
||||||
dispatch({ type: 'UPDATE_BADGE', value: actions.size });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
seen.add(element);
|
seen.add(element);
|
||||||
@ -136,11 +165,11 @@ function clean(elements, skipMatch) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Check if element contains a common word
|
* @description Check if element contains a keyword
|
||||||
* @param {HTMLElement} element
|
* @param {HTMLElement} element
|
||||||
*/
|
*/
|
||||||
function containsCommonWord(element) {
|
function hasKeyword(element) {
|
||||||
return !!commonWords.length && !!element.outerHTML.match(new RegExp(commonWords.join('|')));
|
return !!keywords?.length && !!element.outerHTML.match(new RegExp(keywords.join('|')));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -203,6 +232,21 @@ function getHostname() {
|
|||||||
return hostname.split('.').slice(-3).join('.').replace('www.', '');
|
return hostname.split('.').slice(-3).join('.').replace('www.', '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @async
|
||||||
|
* @description Run if the page wasn't visited yet
|
||||||
|
* @param {Object} message
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
function handleRuntimeMessage(message) {
|
||||||
|
switch (message.type) {
|
||||||
|
case 'INCREASE_ACTIONS_COUNT': {
|
||||||
|
log.add(message.value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Check if an element is visible in the viewport
|
* @description Check if an element is visible in the viewport
|
||||||
* @param {HTMLElement} element
|
* @param {HTMLElement} element
|
||||||
@ -229,7 +273,7 @@ function isInViewport(element) {
|
|||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
function match(element, skipMatch) {
|
function match(element, skipMatch) {
|
||||||
if (!tokens.selectors.length || !skips.tags.length) {
|
if (!exclusions.tags.length || !tokens.selectors.length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,7 +287,7 @@ function match(element, skipMatch) {
|
|||||||
|
|
||||||
const tagName = element.tagName.toUpperCase();
|
const tagName = element.tagName.toUpperCase();
|
||||||
|
|
||||||
if (skips.tags.includes(tagName)) {
|
if (exclusions.tags.includes(tagName)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,7 +327,7 @@ function filterNodeEarly(node, stopRecursion) {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (commonWords && containsCommonWord(node) && !stopRecursion) {
|
if (hasKeyword(node) && !stopRecursion) {
|
||||||
return [node, ...[...node.children].flatMap((node) => filterNodeEarly(node, true))];
|
return [node, ...[...node.children].flatMap((node) => filterNodeEarly(node, true))];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,46 +335,27 @@ function filterNodeEarly(node, stopRecursion) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Fix data, middle consent page and scroll issues
|
* @description Fix specific cases
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
function fix() {
|
function fix() {
|
||||||
const backdrops = getElements(tokens.backdrops);
|
for (const action of actions) {
|
||||||
const domains = skips.domains.map((x) => (x.split('.').length < 3 ? `*${x}` : x));
|
const { domain, name, property, selector } = action;
|
||||||
|
|
||||||
for (const backdrop of backdrops) {
|
if (hostname.match(domain.replaceAll(/\*/g, '[^ ]*'))) {
|
||||||
if (backdrop.children.length === 0 && !seen.has(backdrop)) {
|
switch (name) {
|
||||||
actions.add(`${Date.now()}`);
|
|
||||||
seen.add(backdrop);
|
|
||||||
hide(backdrop);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (domains.every((x) => !hostname.match(x.replaceAll(/\*/g, '[^ ]*')))) {
|
|
||||||
for (const element of [document.body, document.documentElement]) {
|
|
||||||
element?.classList.remove(...(tokens.classes ?? []));
|
|
||||||
element?.style.setProperty('position', 'initial', 'important');
|
|
||||||
element?.style.setProperty('overflow-y', 'initial', 'important');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const fix of fixes) {
|
|
||||||
const { action, domain, property, selector } = fix;
|
|
||||||
|
|
||||||
if (hostname.includes(domain)) {
|
|
||||||
switch (action) {
|
|
||||||
case 'click': {
|
case 'click': {
|
||||||
const element = document.querySelector(selector);
|
const element = document.querySelector(selector);
|
||||||
|
|
||||||
actions.add('click');
|
|
||||||
element?.click();
|
element?.click();
|
||||||
|
log.add(name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'remove': {
|
case 'remove': {
|
||||||
const element = document.querySelector(selector);
|
const element = document.querySelector(selector);
|
||||||
|
|
||||||
actions.add('remove');
|
|
||||||
element?.style?.removeProperty(property);
|
element?.style?.removeProperty(property);
|
||||||
|
log.add(name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'reload': {
|
case 'reload': {
|
||||||
@ -340,38 +365,56 @@ function fix() {
|
|||||||
case 'reset': {
|
case 'reset': {
|
||||||
const element = document.querySelector(selector);
|
const element = document.querySelector(selector);
|
||||||
|
|
||||||
actions.add('reset');
|
|
||||||
element?.style?.setProperty(property, 'initial', 'important');
|
element?.style?.setProperty(property, 'initial', 'important');
|
||||||
|
log.add(name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'resetAll': {
|
case 'resetAll': {
|
||||||
const elements = getElements(selector);
|
const elements = getElements(selector);
|
||||||
|
|
||||||
actions.add('resetAll');
|
|
||||||
elements.forEach((e) => e?.style?.setProperty(property, 'initial', 'important'));
|
elements.forEach((e) => e?.style?.setProperty(property, 'initial', 'important'));
|
||||||
|
log.add(name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const backdrops = getElements(tokens.backdrops);
|
||||||
|
|
||||||
|
for (const backdrop of backdrops) {
|
||||||
|
if (backdrop.children.length === 0 && !seen.has(backdrop)) {
|
||||||
|
log.add(`${Date.now()}`);
|
||||||
|
seen.add(backdrop);
|
||||||
|
hide(backdrop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const skips = exclusions.overflows.map((x) => (x.split('.').length < 3 ? `*${x}` : x));
|
||||||
|
|
||||||
|
if (!skips.some((x) => hostname.match(x.replaceAll(/\*/g, '[^ ]*')))) {
|
||||||
|
for (const element of [document.body, document.documentElement]) {
|
||||||
|
element?.classList.remove(...(tokens.classes ?? []));
|
||||||
|
element?.style.setProperty('position', 'initial', 'important');
|
||||||
|
element?.style.setProperty('overflow-y', 'initial', 'important');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const ionRouterOutlet = document.getElementsByTagName('ion-router-outlet')[0];
|
const ionRouterOutlet = document.getElementsByTagName('ion-router-outlet')[0];
|
||||||
|
|
||||||
if (ionRouterOutlet) {
|
if (ionRouterOutlet) {
|
||||||
actions.add('ion-router-outlet');
|
|
||||||
// 2024-08-02: fix #644 temporarily
|
// 2024-08-02: fix #644 temporarily
|
||||||
ionRouterOutlet.removeAttribute('inert');
|
ionRouterOutlet.removeAttribute('inert');
|
||||||
|
log.add('ion-router-outlet');
|
||||||
}
|
}
|
||||||
|
|
||||||
const t4Wrapper = document.getElementsByClassName('t4-wrapper')[0];
|
const t4Wrapper = document.getElementsByClassName('t4-wrapper')[0];
|
||||||
|
|
||||||
if (t4Wrapper) {
|
if (t4Wrapper) {
|
||||||
actions.add('t4-wrapper');
|
log.add('t4-wrapper');
|
||||||
// 2024-09-12: fix #945 temporarily
|
// 2024-09-12: fix #945 temporarily
|
||||||
t4Wrapper.removeAttribute('inert');
|
t4Wrapper.removeAttribute('inert');
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch({ type: 'UPDATE_BADGE', value: actions.size });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -412,41 +455,48 @@ function run(params = {}) {
|
|||||||
* @async
|
* @async
|
||||||
* @description Set up the extension
|
* @description Set up the extension
|
||||||
* @param {SetUpParams} [params]
|
* @param {SetUpParams} [params]
|
||||||
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
async function setUp(params = {}) {
|
async function setUp(params = {}) {
|
||||||
state = await dispatch({ hostname, type: 'GET_STATE' });
|
|
||||||
dispatch({ type: 'ENABLE_POPUP' });
|
|
||||||
|
|
||||||
if (state.on) {
|
|
||||||
const data = await dispatch({ hostname, type: 'GET_DATA' });
|
const data = await dispatch({ hostname, type: 'GET_DATA' });
|
||||||
|
|
||||||
commonWords = data?.commonWords ?? commonWords;
|
exclusions = data?.exclusions ?? exclusions;
|
||||||
fixes = data?.fixes ?? fixes;
|
|
||||||
skips = data?.skips ?? skips;
|
if (exclusions.domains.some((x) => location.hostname.match(x.replaceAll(/\*/g, '[^ ]*')))) {
|
||||||
|
dispatch({ type: 'DISABLE_ICON' });
|
||||||
|
observer.disconnect();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
state = await dispatch({ hostname, type: 'GET_STATE' });
|
||||||
|
dispatch({ type: 'ENABLE_POPUP' });
|
||||||
|
dispatch({ type: 'ENABLE_REPORT' });
|
||||||
|
|
||||||
|
if (state.on) {
|
||||||
|
browser.runtime.onMessage.addListener(handleRuntimeMessage);
|
||||||
|
dispatch({ hostname, type: 'ENABLE_ICON' });
|
||||||
|
|
||||||
|
actions = data?.actions ?? actions;
|
||||||
|
keywords = data?.keywords ?? keywords;
|
||||||
tokens = data?.tokens ?? tokens;
|
tokens = data?.tokens ?? tokens;
|
||||||
|
|
||||||
dispatch({ type: 'ENABLE_REPORT' });
|
|
||||||
dispatch({ hostname, type: 'ENABLE_ICON' });
|
|
||||||
dispatch({ type: 'UPDATE_BADGE', value: actions.size });
|
|
||||||
observer.observe(document.body ?? document.documentElement, options);
|
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_REPORT' });
|
|
||||||
dispatch({ type: 'DISABLE_ICON' });
|
|
||||||
dispatch({ type: 'UPDATE_BADGE', value: actions.size });
|
|
||||||
observer.disconnect();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Wait for the body to exist
|
* @description Wait for the body to exist
|
||||||
* @param {void} callback
|
* @returns {Promise<void>}
|
||||||
* @returns {void}
|
|
||||||
*/
|
*/
|
||||||
async function setUpAfterWaitForBody() {
|
async function setUpAfterWaitForBody() {
|
||||||
|
if (document.visibilityState === 'visible' && !initiallyVisible) {
|
||||||
if (document.body) {
|
if (document.body) {
|
||||||
|
initiallyVisible = true;
|
||||||
await setUp();
|
await setUp();
|
||||||
} else {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setTimeout(setUpAfterWaitForBody, 50);
|
setTimeout(setUpAfterWaitForBody, 50);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -466,50 +516,6 @@ const observer = new MutationObserver((mutations) => {
|
|||||||
run({ elements });
|
run({ elements });
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
document.addEventListener('visibilitychange', setUpAfterWaitForBody);
|
||||||
* @description Listen to messages from any other scripts
|
window.addEventListener('pageshow', setUpAfterWaitForBody);
|
||||||
* @listens browser.runtime#onMessage
|
setUpAfterWaitForBody();
|
||||||
*/
|
|
||||||
browser.runtime.onMessage.addListener(async (message) => {
|
|
||||||
switch (message.type) {
|
|
||||||
case 'INCREASE_ACTIONS_COUNT': {
|
|
||||||
actions.add(`${Date.now()}`);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description Fix bfcache issues
|
|
||||||
* @listens window#pageshow
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
window.addEventListener('pageshow', async (event) => {
|
|
||||||
if (document.visibilityState === 'visible' && event.persisted) {
|
|
||||||
await setUp();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @async
|
|
||||||
* @description Run if the page wasn't visited yet
|
|
||||||
* @listens window#visibilitychange
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
window.addEventListener('visibilitychange', async () => {
|
|
||||||
if (document.visibilityState === 'visible') {
|
|
||||||
if (!initiallyVisible) {
|
|
||||||
initiallyVisible = true;
|
|
||||||
await setUp();
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch({ type: state.on ? 'ENABLE_REPORT' : 'DISABLE_REPORT' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description Run as soon as possible, if the user is in front of the page
|
|
||||||
*/
|
|
||||||
if (document.visibilityState === 'visible') {
|
|
||||||
setUpAfterWaitForBody();
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user