8.0.0 #3
@ -1,7 +1,49 @@
|
|||||||
|
/**
|
||||||
|
* @typedef {Object} ExtensionIssue
|
||||||
|
* @property {number} [expiresIn]
|
||||||
|
* @property {string[]} [flags]
|
||||||
|
* @property {string} [url]
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} ExtensionState
|
||||||
|
* @property {ExtensionIssue} issue
|
||||||
|
* @property {boolean} on
|
||||||
|
*/
|
||||||
|
|
||||||
if (typeof browser === 'undefined') {
|
if (typeof browser === 'undefined') {
|
||||||
browser = chrome;
|
browser = chrome;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Class for request batching
|
||||||
|
*/
|
||||||
|
class RequestManager {
|
||||||
|
constructor() {
|
||||||
|
this.requests = new Map(); // Store ongoing requests
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Fetch wrapper to play with the request map
|
||||||
|
* @param {string} input
|
||||||
|
* @param {RequestInit} [init]
|
||||||
|
* @returns {Promise<any>}
|
||||||
|
*/
|
||||||
|
fetchData(input, init) {
|
||||||
|
if (this.requests.has(input)) {
|
||||||
|
return this.requests.get(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
const promise = fetch(input, init)
|
||||||
|
.then((response) => response.json())
|
||||||
|
.finally(() => this.requests.delete(input));
|
||||||
|
|
||||||
|
this.requests.set(input, promise);
|
||||||
|
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description API URL
|
* @description API URL
|
||||||
* @type {string}
|
* @type {string}
|
||||||
@ -20,6 +62,11 @@ const extensionMenuItemId = 'CDM-MENU';
|
|||||||
*/
|
*/
|
||||||
const reportMenuItemId = 'CDM-REPORT';
|
const reportMenuItemId = 'CDM-REPORT';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Request manager instance
|
||||||
|
*/
|
||||||
|
const requestManager = new RequestManager();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Context menu identifier
|
* @description Context menu identifier
|
||||||
* @type {string}
|
* @type {string}
|
||||||
@ -32,6 +79,12 @@ const settingsMenuItemId = 'CDM-SETTINGS';
|
|||||||
*/
|
*/
|
||||||
const script = browser.scripting;
|
const script = browser.scripting;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Default value for extension state
|
||||||
|
* @type {ExtensionState}
|
||||||
|
*/
|
||||||
|
const stateByDefault = { issue: { expiresIn: 0 }, on: true };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description The storage to use
|
* @description The storage to use
|
||||||
* @type {browser.storage.LocalStorageArea}
|
* @type {browser.storage.LocalStorageArea}
|
||||||
@ -43,6 +96,34 @@ const storage = browser.storage.local;
|
|||||||
*/
|
*/
|
||||||
const suppressLastError = () => void browser.runtime.lastError;
|
const suppressLastError = () => void browser.runtime.lastError;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @async
|
||||||
|
* @description Enable extension icon
|
||||||
|
* @param {number} tabId
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async function enableIcon(hostname, tabId) {
|
||||||
|
const state = await getState(hostname);
|
||||||
|
const path = state.issue.url ? '/assets/icons/warn.png' : '/assets/icons/on.png';
|
||||||
|
|
||||||
|
await browser.action.setIcon({ path, tabId }, suppressLastError);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @async
|
||||||
|
* @description Get database
|
||||||
|
* @returns {Promise<Object>}
|
||||||
|
*/
|
||||||
|
async function getData() {
|
||||||
|
const { data } = await storage.get('data');
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
return await refreshData();
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Calculate current hostname
|
* @description Calculate current hostname
|
||||||
* @param {string} url
|
* @param {string} url
|
||||||
@ -52,6 +133,22 @@ function getHostname(url) {
|
|||||||
return new URL(url).hostname.split('.').slice(-3).join('.').replace('www.', '');
|
return new URL(url).hostname.split('.').slice(-3).join('.').replace('www.', '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @async
|
||||||
|
* @description Get state for the given hostname
|
||||||
|
* @param {string} hostname
|
||||||
|
* @returns {Promise<ExtensionState>}
|
||||||
|
*/
|
||||||
|
async function getState(hostname) {
|
||||||
|
const { [hostname]: state = stateByDefault } = await storage.get(hostname);
|
||||||
|
|
||||||
|
if ((state.issue && Date.now() > state.issue.expiresIn) || !state.issue?.expiresIn) {
|
||||||
|
state.issue = await refreshIssue(hostname);
|
||||||
|
}
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Format number to avoid errors
|
* @description Format number to avoid errors
|
||||||
* @param {number} [value]
|
* @param {number} [value]
|
||||||
@ -81,20 +178,45 @@ function matchToPattern(match) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @async
|
||||||
* @description Refresh data
|
* @description Refresh data
|
||||||
* @param {void?} callback
|
* @returns {Promise<void>}
|
||||||
* @returns {void}
|
|
||||||
*/
|
*/
|
||||||
function refreshData(callback) {
|
async function refreshData() {
|
||||||
try {
|
try {
|
||||||
fetch(`${apiUrl}/data/`).then((result) => {
|
const { data } = await requestManager.fetchData(`${apiUrl}/data/`);
|
||||||
result.json().then(({ data }) => {
|
|
||||||
storage.set({ data }, suppressLastError);
|
await triggerStoreUpdate('data', data);
|
||||||
callback?.(data);
|
|
||||||
});
|
return data;
|
||||||
});
|
|
||||||
} catch {
|
} catch {
|
||||||
refreshData(callback);
|
return await refreshData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @async
|
||||||
|
* @description Refresh issues for the given hostname
|
||||||
|
* @param {string} hostname
|
||||||
|
* @returns {Promise<ExtensionIssue | undefined>}
|
||||||
|
*/
|
||||||
|
async function refreshIssue(hostname) {
|
||||||
|
try {
|
||||||
|
const { data } = await requestManager.fetchData(`${apiUrl}/issues/${hostname}`);
|
||||||
|
|
||||||
|
if (Object.keys(data).length === 0) {
|
||||||
|
await triggerStoreUpdate(hostname, { issue: { expiresIn: Date.now() + 8 * 60 * 60 * 1000 } });
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const issue = { expiresIn: Date.now() + 4 * 60 * 60 * 1000, flags: data.flags, url: data.url };
|
||||||
|
|
||||||
|
await triggerStoreUpdate(hostname, { issue });
|
||||||
|
|
||||||
|
return data;
|
||||||
|
} catch {
|
||||||
|
return await refreshData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,9 +226,9 @@ function refreshData(callback) {
|
|||||||
* @param {any} message
|
* @param {any} message
|
||||||
* @param {browser.tabs.Tab} tab
|
* @param {browser.tabs.Tab} tab
|
||||||
* @param {void?} callback
|
* @param {void?} callback
|
||||||
* @returns {void}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
async function report(message, tab, callback) {
|
async function report(message) {
|
||||||
try {
|
try {
|
||||||
const reason = message.reason;
|
const reason = message.reason;
|
||||||
const url = message.url;
|
const url = message.url;
|
||||||
@ -114,14 +236,29 @@ async function report(message, tab, callback) {
|
|||||||
const version = browser.runtime.getManifest().version;
|
const version = browser.runtime.getManifest().version;
|
||||||
const body = JSON.stringify({ reason, url, userAgent, version });
|
const body = JSON.stringify({ reason, url, userAgent, version });
|
||||||
const headers = { 'Cache-Control': 'no-cache', 'Content-type': 'application/json' };
|
const headers = { 'Cache-Control': 'no-cache', 'Content-type': 'application/json' };
|
||||||
|
const requestInit = { body, headers, method: 'POST' };
|
||||||
|
|
||||||
const response = await fetch(`${apiUrl}/report/`, { body, headers, method: 'POST' });
|
return (await requestManager.fetchData(`${apiUrl}/report/`, requestInit)).data;
|
||||||
callback?.((await response.json()).data);
|
|
||||||
} catch {
|
} catch {
|
||||||
console.error("Can't send report");
|
console.error("Can't send report");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @async
|
||||||
|
* @description Update extension store for a given key
|
||||||
|
* @param {string} [key]
|
||||||
|
* @param {Object} value
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async function triggerStoreUpdate(key, value) {
|
||||||
|
if (key) {
|
||||||
|
const { [key]: prev } = await storage.get(key);
|
||||||
|
|
||||||
|
await storage.set({ [key]: { ...prev, ...value } }, suppressLastError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Listen to context menus clicked
|
* @description Listen to context menus clicked
|
||||||
*/
|
*/
|
||||||
@ -153,13 +290,11 @@ browser.runtime.onMessage.addListener((message, sender, callback) => {
|
|||||||
switch (message.type) {
|
switch (message.type) {
|
||||||
case 'DISABLE_ICON':
|
case 'DISABLE_ICON':
|
||||||
if (isPage && tabId !== undefined) {
|
if (isPage && tabId !== undefined) {
|
||||||
browser.action.setIcon({ path: '/assets/icons/disabled.png', tabId }, suppressLastError);
|
browser.action.setIcon({ path: '/assets/icons/off.png', tabId }, suppressLastError);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'ENABLE_ICON':
|
case 'ENABLE_ICON':
|
||||||
if (isPage && tabId !== undefined) {
|
if (isPage && tabId !== undefined) enableIcon(hostname, tabId);
|
||||||
browser.action.setIcon({ path: '/assets/icons/enabled.png', tabId }, suppressLastError);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'ENABLE_POPUP':
|
case 'ENABLE_POPUP':
|
||||||
if (isPage && tabId !== undefined) {
|
if (isPage && tabId !== undefined) {
|
||||||
@ -167,24 +302,19 @@ browser.runtime.onMessage.addListener((message, sender, callback) => {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'GET_DATA':
|
case 'GET_DATA':
|
||||||
storage.get('data', ({ data }) => {
|
getData().then(callback);
|
||||||
if (data) callback(data);
|
|
||||||
else refreshData(callback);
|
|
||||||
});
|
|
||||||
return true;
|
return true;
|
||||||
case 'GET_EXCLUSION_LIST':
|
case 'GET_EXCLUSION_LIST':
|
||||||
storage.get(null, (exclusions) => {
|
storage.get(null, (exclusions) => {
|
||||||
const exclusionList = Object.entries(exclusions || {}).flatMap((exclusion) =>
|
const exclusionList = Object.entries(exclusions || {}).flatMap((exclusion) =>
|
||||||
exclusion[0] !== 'data' && !exclusion[1]?.enabled ? [exclusion[0]] : []
|
exclusion[0] !== 'data' && !exclusion[1]?.on ? [exclusion[0]] : []
|
||||||
);
|
);
|
||||||
callback(exclusionList);
|
callback(exclusionList);
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
case 'GET_HOSTNAME_STATE':
|
case 'GET_STATE':
|
||||||
if (hostname) {
|
if (hostname) {
|
||||||
storage.get(hostname, (state) => {
|
getState(hostname).then(callback);
|
||||||
callback(state[hostname] ?? { enabled: true });
|
|
||||||
});
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -199,25 +329,22 @@ browser.runtime.onMessage.addListener((message, sender, callback) => {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'REFRESH_DATA':
|
case 'REFRESH_DATA':
|
||||||
refreshData(callback);
|
refreshData().then(callback);
|
||||||
return true;
|
return true;
|
||||||
case 'REPORT':
|
case 'REPORT':
|
||||||
if (tabId !== undefined) {
|
if (tabId !== undefined) {
|
||||||
report(message, sender.tab, callback);
|
report(message).then(callback);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'SET_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: formatNumber(message.value) });
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'SET_HOSTNAME_STATE':
|
case 'UPDATE_STORE':
|
||||||
if (hostname) {
|
triggerStoreUpdate(hostname, message.state);
|
||||||
if (message.state.enabled === false) storage.set({ [hostname]: message.state });
|
|
||||||
else storage.remove(hostname);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -285,8 +412,9 @@ browser.webRequest.onBeforeRequest.addListener(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const data = await getData();
|
||||||
const hostname = getHostname(url);
|
const hostname = getHostname(url);
|
||||||
const { data, [hostname]: state = { enabled: true } } = await storage.get(['data', hostname]);
|
const state = await getState(hostname);
|
||||||
|
|
||||||
if (data?.rules?.length) {
|
if (data?.rules?.length) {
|
||||||
const rules = data.rules.map((rule) => ({
|
const rules = data.rules.map((rule) => ({
|
||||||
@ -295,7 +423,7 @@ browser.webRequest.onBeforeRequest.addListener(
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
await browser.declarativeNetRequest.updateSessionRules({
|
await browser.declarativeNetRequest.updateSessionRules({
|
||||||
addRules: state.enabled ? rules : undefined,
|
addRules: state.on ? rules : undefined,
|
||||||
removeRuleIds: data.rules.map((rule) => rule.id),
|
removeRuleIds: data.rules.map((rule) => rule.id),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -313,9 +441,9 @@ browser.webRequest.onErrorOccurred.addListener(
|
|||||||
|
|
||||||
if (error === 'net::ERR_BLOCKED_BY_CLIENT' && tabId > -1) {
|
if (error === 'net::ERR_BLOCKED_BY_CLIENT' && tabId > -1) {
|
||||||
const hostname = getHostname(url);
|
const hostname = getHostname(url);
|
||||||
const { [hostname]: state = { enabled: true } } = await storage.get(hostname);
|
const state = await getState(hostname);
|
||||||
|
|
||||||
if (state.enabled) {
|
if (state.on) {
|
||||||
await browser.tabs.sendMessage(tabId, { type: 'INCREASE_ACTIONS_COUNT' });
|
await browser.tabs.sendMessage(tabId, { type: 'INCREASE_ACTIONS_COUNT' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,12 @@
|
|||||||
* @property {{ backdrops: string[], classes: string[], containers: string[], selectors: string[] }} tokens
|
* @property {{ backdrops: string[], classes: string[], containers: string[], selectors: string[] }} tokens
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} ExtensionState
|
||||||
|
* @property {boolean} on
|
||||||
|
* @property {ExtensionIssue} [issue]
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} Fix
|
* @typedef {Object} Fix
|
||||||
* @property {string} action
|
* @property {string} action
|
||||||
@ -91,9 +97,9 @@ const seen = new Set();
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Extension state
|
* @description Extension state
|
||||||
* @type {{ enabled: boolean }}
|
* @type {ExtensionState}
|
||||||
*/
|
*/
|
||||||
let state = { enabled: true };
|
let state = { on: true };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Clean DOM
|
* @description Clean DOM
|
||||||
@ -115,8 +121,8 @@ function clean(elements, skipMatch) {
|
|||||||
if (element instanceof HTMLDialogElement) element.close();
|
if (element instanceof HTMLDialogElement) element.close();
|
||||||
hide(element);
|
hide(element);
|
||||||
|
|
||||||
actions.add(new Date().getTime().toString());
|
actions.add(`${Date.now()}`);
|
||||||
dispatch({ type: 'SET_BADGE', value: actions.size });
|
dispatch({ type: 'UPDATE_BADGE', value: actions.size });
|
||||||
}
|
}
|
||||||
|
|
||||||
seen.add(element);
|
seen.add(element);
|
||||||
@ -295,7 +301,7 @@ function fix() {
|
|||||||
|
|
||||||
for (const backdrop of backdrops) {
|
for (const backdrop of backdrops) {
|
||||||
if (backdrop.children.length === 0 && !seen.has(backdrop)) {
|
if (backdrop.children.length === 0 && !seen.has(backdrop)) {
|
||||||
actions.add(new Date().getTime().toString());
|
actions.add(`${Date.now()}`);
|
||||||
seen.add(backdrop);
|
seen.add(backdrop);
|
||||||
hide(backdrop);
|
hide(backdrop);
|
||||||
}
|
}
|
||||||
@ -366,7 +372,7 @@ function fix() {
|
|||||||
t4Wrapper.removeAttribute('inert');
|
t4Wrapper.removeAttribute('inert');
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch({ type: 'SET_BADGE', value: actions.size });
|
dispatch({ type: 'UPDATE_BADGE', value: actions.size });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -390,7 +396,7 @@ function hide(element) {
|
|||||||
function run(params = {}) {
|
function run(params = {}) {
|
||||||
const { containers, elements, skipMatch } = params;
|
const { containers, elements, skipMatch } = params;
|
||||||
|
|
||||||
if (document.body?.children.length && state.enabled && tokens.selectors.length) {
|
if (document.body?.children.length && state.on && tokens.selectors.length) {
|
||||||
fix();
|
fix();
|
||||||
|
|
||||||
if (elements?.length) {
|
if (elements?.length) {
|
||||||
@ -409,10 +415,10 @@ function run(params = {}) {
|
|||||||
* @param {SetUpParams} [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_STATE' })) ?? state;
|
||||||
dispatch({ type: 'ENABLE_POPUP' });
|
dispatch({ type: 'ENABLE_POPUP' });
|
||||||
|
|
||||||
if (state.enabled) {
|
if (state.on) {
|
||||||
const data = await dispatch({ hostname, type: 'GET_DATA' });
|
const data = await dispatch({ hostname, type: 'GET_DATA' });
|
||||||
|
|
||||||
commonWords = data?.commonWords ?? commonWords;
|
commonWords = data?.commonWords ?? commonWords;
|
||||||
@ -420,13 +426,13 @@ async function setUp(params = {}) {
|
|||||||
skips = data?.skips ?? skips;
|
skips = data?.skips ?? skips;
|
||||||
tokens = data?.tokens ?? tokens;
|
tokens = data?.tokens ?? tokens;
|
||||||
|
|
||||||
dispatch({ type: 'ENABLE_ICON' });
|
dispatch({ hostname, type: 'ENABLE_ICON' });
|
||||||
dispatch({ type: 'SET_BADGE', value: actions.size });
|
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 {
|
} else {
|
||||||
dispatch({ type: 'DISABLE_ICON' });
|
dispatch({ type: 'DISABLE_ICON' });
|
||||||
dispatch({ type: 'SET_BADGE', value: actions.size });
|
dispatch({ type: 'UPDATE_BADGE', value: actions.size });
|
||||||
observer.disconnect();
|
observer.disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -449,7 +455,7 @@ async function setUpAfterWaitForBody() {
|
|||||||
* @type {MutationObserver}
|
* @type {MutationObserver}
|
||||||
*/
|
*/
|
||||||
const observer = new MutationObserver((mutations) => {
|
const observer = new MutationObserver((mutations) => {
|
||||||
if (!state.enabled || !tokens.selectors.length) {
|
if (!state.on || !tokens.selectors.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -466,7 +472,7 @@ const observer = new MutationObserver((mutations) => {
|
|||||||
browser.runtime.onMessage.addListener(async (message) => {
|
browser.runtime.onMessage.addListener(async (message) => {
|
||||||
switch (message.type) {
|
switch (message.type) {
|
||||||
case 'INCREASE_ACTIONS_COUNT': {
|
case 'INCREASE_ACTIONS_COUNT': {
|
||||||
actions.add(new Date().getTime().toString());
|
actions.add(`${Date.now()}`);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,8 +62,8 @@ async function handleAddClick() {
|
|||||||
|
|
||||||
if (exclusionValue?.trim() && (domainRx.test(exclusionValue) || exclusionValue === 'localhost')) {
|
if (exclusionValue?.trim() && (domainRx.test(exclusionValue) || exclusionValue === 'localhost')) {
|
||||||
const filterInputElement = document.getElementById('filter-input');
|
const filterInputElement = document.getElementById('filter-input');
|
||||||
const state = { enabled: false };
|
const state = { on: false };
|
||||||
await dispatch({ hostname: exclusionValue, state, type: 'SET_HOSTNAME_STATE' });
|
await dispatch({ hostname: exclusionValue, state, type: 'UPDATE_STORE' });
|
||||||
|
|
||||||
exclusionList = [...new Set([...exclusionList, exclusionValue])].sort();
|
exclusionList = [...new Set([...exclusionList, exclusionValue])].sort();
|
||||||
createList();
|
createList();
|
||||||
@ -80,8 +80,8 @@ async function handleClearClick() {
|
|||||||
const filterInputElement = document.getElementById('filter-input');
|
const filterInputElement = document.getElementById('filter-input');
|
||||||
|
|
||||||
for (const exclusionValue of exclusionList) {
|
for (const exclusionValue of exclusionList) {
|
||||||
const state = { enabled: true };
|
const state = { on: true };
|
||||||
await dispatch({ hostname: exclusionValue, state, type: 'SET_HOSTNAME_STATE' });
|
await dispatch({ hostname: exclusionValue, state, type: 'UPDATE_STORE' });
|
||||||
}
|
}
|
||||||
|
|
||||||
exclusionList = [];
|
exclusionList = [];
|
||||||
@ -128,9 +128,9 @@ async function handleDeleteClick(event) {
|
|||||||
const filterInputElement = document.getElementById('filter-input');
|
const filterInputElement = document.getElementById('filter-input');
|
||||||
const { value } = event.currentTarget.parentElement.dataset;
|
const { value } = event.currentTarget.parentElement.dataset;
|
||||||
const itemElement = document.querySelector(`[data-value="${value}"]`);
|
const itemElement = document.querySelector(`[data-value="${value}"]`);
|
||||||
const state = { enabled: true };
|
const state = { on: true };
|
||||||
|
|
||||||
await dispatch({ hostname: value, state, type: 'SET_HOSTNAME_STATE' });
|
await dispatch({ hostname: value, state, type: 'UPDATE_STORE' });
|
||||||
exclusionList = exclusionList.filter((exclusionValue) => exclusionValue !== value);
|
exclusionList = exclusionList.filter((exclusionValue) => exclusionValue !== value);
|
||||||
itemElement?.remove();
|
itemElement?.remove();
|
||||||
updateList(filterInputElement.value.trim());
|
updateList(filterInputElement.value.trim());
|
||||||
@ -172,8 +172,8 @@ function handleFileChange(event) {
|
|||||||
const newExclusionList = event.currentTarget.result.split('\n').filter((x) => x.trim());
|
const newExclusionList = event.currentTarget.result.split('\n').filter((x) => x.trim());
|
||||||
|
|
||||||
for (const exclusionValue of newExclusionList) {
|
for (const exclusionValue of newExclusionList) {
|
||||||
const state = { enabled: false };
|
const state = { on: false };
|
||||||
await dispatch({ hostname: exclusionValue, state, type: 'SET_HOSTNAME_STATE' });
|
await dispatch({ hostname: exclusionValue, state, type: 'UPDATE_STORE' });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newExclusionList.length) {
|
if (newExclusionList.length) {
|
||||||
|
Loading…
Reference in New Issue
Block a user