From 67fb9695728680b3d6bcdd363fd1efcd212e81e0 Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Fri, 1 Dec 2023 14:35:28 -0500 Subject: [PATCH] Refactoring: Replace DOM events with broadcast channels Broadcast channels are more suited to uBO than DOM events to dispatch notifications to different parts of uBO. DOM events can only be dispatched to local context, broadcast channels dispatch to all contexts (i.e. background process, workers, auxiliary pages) -- this last behavior is better suited to uBO to communicate internal changes to all potential listeners, not just those in the local context. Additionally, broadcasting to content scripts is now done through tabs.sendMessage() instead of through potentially opened message ports, this simplifies broadcasting to content scripts, and this doesn't require to have long-lived message ports in content scripts. --- platform/common/vapi-client-extra.js | 54 ++----------------- platform/common/vapi-client.js | 2 + src/js/1p-filters.js | 5 +- src/js/3p-filters.js | 25 +++++---- src/js/assets.js | 9 ++-- src/js/broadcast.js | 75 ++++++++++++++++++++++++++ src/js/diff-updater.js | 2 +- src/js/logger.js | 6 ++- src/js/messaging.js | 3 +- src/js/scriptlet-filtering.js | 11 ++-- src/js/scriptlets/cosmetic-logger.js | 81 ++++++++++++---------------- src/js/start.js | 13 ++--- src/js/storage.js | 30 ++++++----- src/js/support.js | 3 +- src/js/ublock.js | 22 ++++---- src/js/utils.js | 30 ----------- 16 files changed, 186 insertions(+), 185 deletions(-) create mode 100644 src/js/broadcast.js diff --git a/platform/common/vapi-client-extra.js b/platform/common/vapi-client-extra.js index 0328ec7a98a18..a24c1e9c1237c 100644 --- a/platform/common/vapi-client-extra.js +++ b/platform/common/vapi-client-extra.js @@ -30,13 +30,9 @@ (( ) => { // >>>>>>>> start of private namespace -if ( - typeof vAPI !== 'object' || - vAPI.messaging instanceof Object === false || - vAPI.MessagingConnection instanceof Function -) { - return; -} +if ( typeof vAPI !== 'object' ) { return; } +if ( vAPI.messaging instanceof Object === false ) { return; } +if ( vAPI.MessagingConnection instanceof Function ) { return; } const listeners = new Set(); const connections = new Map(); @@ -247,50 +243,6 @@ vAPI.messaging.extensions.push(vAPI.MessagingConnection); /******************************************************************************/ -// Broadcast listening ability - -(( ) => { -// >>>>>>>> start of private namespace - -if ( - typeof vAPI !== 'object' || - vAPI.messaging instanceof Object === false || - vAPI.broadcastListener instanceof Object -) { - return; -} - -const listeners = new Set(); - -vAPI.broadcastListener = { - add: function(listener) { - listeners.add(listener); - vAPI.messaging.getPort(); - }, - remove: function(listener) { - listeners.delete(listener); - }, - canDestroyPort() { - return listeners.size === 0; - }, - mustDestroyPort() { - listeners.clear(); - }, - canProcessMessage(details) { - if ( details.broadcast === false ) { return; } - for ( const listener of listeners ) { - listener(details.msg); - } - }, -}; - -vAPI.messaging.extensions.push(vAPI.broadcastListener); - -// <<<<<<<< end of private namespace -})(); - -/******************************************************************************/ - diff --git a/platform/common/vapi-client.js b/platform/common/vapi-client.js index b87eca0d50e9e..56686b1ff56cd 100644 --- a/platform/common/vapi-client.js +++ b/platform/common/vapi-client.js @@ -22,6 +22,8 @@ // For non-background page +/* globals browser */ + 'use strict'; /******************************************************************************/ diff --git a/src/js/1p-filters.js b/src/js/1p-filters.js index 76be55f914ec0..da3b246855440 100644 --- a/src/js/1p-filters.js +++ b/src/js/1p-filters.js @@ -23,8 +23,9 @@ 'use strict'; -import { i18n$ } from './i18n.js'; +import { onBroadcast } from './broadcast.js'; import { dom, qs$ } from './dom.js'; +import { i18n$ } from './i18n.js'; import './codemirror/ubo-static-filtering.js'; /******************************************************************************/ @@ -310,7 +311,7 @@ dom.on('#userFiltersRevert', 'click', revertChanges); // https://github.com/gorhill/uBlock/issues/3704 // Merge changes to user filters occurring in the background - vAPI.broadcastListener.add(msg => { + onBroadcast(msg => { switch ( msg.what ) { case 'userFiltersUpdated': { cmEditor.startOperation(); diff --git a/src/js/3p-filters.js b/src/js/3p-filters.js index 8003290044d60..e4a110082c1fb 100644 --- a/src/js/3p-filters.js +++ b/src/js/3p-filters.js @@ -21,8 +21,9 @@ 'use strict'; -import { i18n, i18n$ } from './i18n.js'; +import { onBroadcast } from './broadcast.js'; import { dom, qs$, qsa$ } from './dom.js'; +import { i18n, i18n$ } from './i18n.js'; /******************************************************************************/ @@ -35,9 +36,7 @@ let listsetDetails = {}; /******************************************************************************/ -const messaging = vAPI.messaging; - -vAPI.broadcastListener.add(msg => { +onBroadcast(msg => { switch ( msg.what ) { case 'assetUpdated': updateAssetStatus(msg); @@ -277,7 +276,7 @@ const renderFilterLists = ( ) => { renderWidgets(); }; - messaging.send('dashboard', { + vAPI.messaging.send('dashboard', { what: 'getLists', }).then(response => { onListsReceived(response); @@ -510,7 +509,7 @@ const onPurgeClicked = ev => { dom.cl.remove(listLeaf, 'cached'); } - messaging.send('dashboard', { + vAPI.messaging.send('dashboard', { what: 'purgeCaches', assetKeys, }); @@ -534,7 +533,7 @@ dom.on('#lists', 'click', 'span.cache', onPurgeClicked); const selectFilterLists = async ( ) => { // Cosmetic filtering switch let checked = qs$('#parseCosmeticFilters').checked; - messaging.send('dashboard', { + vAPI.messaging.send('dashboard', { what: 'userSettings', name: 'parseAllABPHideFilters', value: checked, @@ -542,7 +541,7 @@ const selectFilterLists = async ( ) => { listsetDetails.parseCosmeticFilters = checked; checked = qs$('#ignoreGenericCosmeticFilters').checked; - messaging.send('dashboard', { + vAPI.messaging.send('dashboard', { what: 'userSettings', name: 'ignoreGenericCosmeticFilters', value: checked, @@ -581,7 +580,7 @@ const selectFilterLists = async ( ) => { hashFromListsetDetails(); - await messaging.send('dashboard', { + await vAPI.messaging.send('dashboard', { what: 'applyFilterListSelection', toSelect, toImport, @@ -596,7 +595,7 @@ const buttonApplyHandler = async ( ) => { dom.cl.add(dom.body, 'working'); dom.cl.remove('#lists .listEntry.stickied', 'stickied'); renderWidgets(); - await messaging.send('dashboard', { what: 'reloadAllFilters' }); + await vAPI.messaging.send('dashboard', { what: 'reloadAllFilters' }); dom.cl.remove(dom.body, 'working'); }; @@ -609,7 +608,7 @@ const buttonUpdateHandler = async ( ) => { await selectFilterLists(); dom.cl.add(dom.body, 'updating'); renderWidgets(); - messaging.send('dashboard', { what: 'forceUpdateAssets' }); + vAPI.messaging.send('dashboard', { what: 'forceUpdateAssets' }); }; dom.on('#buttonUpdate', 'click', ( ) => { buttonUpdateHandler(); }); @@ -617,7 +616,7 @@ dom.on('#buttonUpdate', 'click', ( ) => { buttonUpdateHandler(); }); /******************************************************************************/ const buttonPurgeAllHandler = async hard => { - await messaging.send('dashboard', { + await vAPI.messaging.send('dashboard', { what: 'purgeAllCaches', hard, }); @@ -630,7 +629,7 @@ dom.on('#buttonPurgeAll', 'click', ev => { buttonPurgeAllHandler(ev.shiftKey); } const userSettingCheckboxChanged = ( ) => { const target = event.target; - messaging.send('dashboard', { + vAPI.messaging.send('dashboard', { what: 'userSettings', name: target.id, value: target.checked, diff --git a/src/js/assets.js b/src/js/assets.js index 81b54e632ba9b..78d8644b3dd23 100644 --- a/src/js/assets.js +++ b/src/js/assets.js @@ -23,11 +23,12 @@ /******************************************************************************/ -import cacheStorage from './cachestorage.js'; -import logger from './logger.js'; import µb from './background.js'; +import { broadcast } from './broadcast.js'; +import cacheStorage from './cachestorage.js'; import { ubolog } from './console.js'; import { i18n$ } from './i18n.js'; +import logger from './logger.js'; import * as sfp from './static-filtering-parser.js'; import { orphanizeString, } from './text-utils.js'; @@ -1234,7 +1235,7 @@ async function diffUpdater() { assetCacheSetDetails(data.assetKey, metadata); }; bc.onmessage = ev => { - const data = ev.data; + const data = ev.data || {}; if ( data.what === 'ready' ) { ubolog('Diff updater: hard updating', toHardUpdate.map(v => v.assetKey).join()); while ( toHardUpdate.length !== 0 ) { @@ -1279,7 +1280,7 @@ async function diffUpdater() { } else if ( data.status === 'nopatch-yet' || data.status === 'nodiff' ) { ubolog(`Diff updater: skip update of ${data.assetKey} using ${data.patchPath}\n\treason: ${data.status}`); assetCacheSetDetails(data.assetKey, { writeTime: data.writeTime }); - vAPI.messaging.broadcast({ + broadcast({ what: 'assetUpdated', key: data.assetKey, cached: true, diff --git a/src/js/broadcast.js b/src/js/broadcast.js new file mode 100644 index 0000000000000..efcac57baa59b --- /dev/null +++ b/src/js/broadcast.js @@ -0,0 +1,75 @@ +/******************************************************************************* + + uBlock Origin - a browser extension to block requests. + Copyright (C) 2014-present Raymond Hill + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see {http://www.gnu.org/licenses/}. + + Home: https://github.com/gorhill/uBlock +*/ + +/* globals browser */ + +'use strict'; + +/******************************************************************************/ + +// Broadcast a message to all uBO contexts + +let broadcastChannel; + +export function broadcast(message) { + if ( broadcastChannel === undefined ) { + broadcastChannel = new self.BroadcastChannel('uBO'); + } + broadcastChannel.postMessage(message); +} + +/******************************************************************************/ + +// Broadcast a message to all uBO contexts and all uBO's content scripts + +export async function broadcastToAll(message) { + broadcast(message); + const tabs = await vAPI.tabs.query({ + discarded: false, + }); + const bcmessage = Object.assign({ broadcast: true }, message); + for ( const tab of tabs ) { + browser.tabs.sendMessage(tab.id, bcmessage); + } +} + +/******************************************************************************/ + +export function onBroadcast(listener) { + const bc = new self.BroadcastChannel('uBO'); + bc.onmessage = ev => listener(ev.data || {}); + return bc; +} + +/******************************************************************************/ + +export function filteringBehaviorChanged(details = {}) { + if ( typeof details.direction !== 'number' || details.direction >= 0 ) { + filteringBehaviorChanged.throttle.offon(727); + } + broadcast(Object.assign({ what: 'filteringBehaviorChanged' }, details)); +} + +filteringBehaviorChanged.throttle = vAPI.defer.create(( ) => { + vAPI.net.handlerBehaviorChanged(); +}); + +/******************************************************************************/ diff --git a/src/js/diff-updater.js b/src/js/diff-updater.js index ba91ddef3385c..476295aa37f10 100644 --- a/src/js/diff-updater.js +++ b/src/js/diff-updater.js @@ -271,7 +271,7 @@ async function fetchAndApplyAllPatches(assetDetails) { const bc = new globalThis.BroadcastChannel('diffUpdater'); bc.onmessage = ev => { - const message = ev.data; + const message = ev.data || {}; switch ( message.what ) { case 'update': fetchAndApplyAllPatches(message).then(response => { diff --git a/src/js/logger.js b/src/js/logger.js index 7ff3a3312d28a..55d6afd6346e9 100644 --- a/src/js/logger.js +++ b/src/js/logger.js @@ -23,6 +23,10 @@ /******************************************************************************/ +import { broadcastToAll } from './broadcast.js'; + +/******************************************************************************/ + let buffer = null; let lastReadTime = 0; let writePtr = 0; @@ -40,7 +44,7 @@ const janitorTimer = vAPI.defer.create(( ) => { buffer = null; writePtr = 0; logger.ownerId = undefined; - vAPI.messaging.broadcast({ what: 'loggerDisabled' }); + broadcastToAll({ what: 'loggerDisabled' }); }); const boxEntry = function(details) { diff --git a/src/js/messaging.js b/src/js/messaging.js index 234e29fc259bf..bac70d8106b21 100644 --- a/src/js/messaging.js +++ b/src/js/messaging.js @@ -28,6 +28,7 @@ import publicSuffixList from '../lib/publicsuffixlist/publicsuffixlist.js'; import punycode from '../lib/punycode.js'; +import { filteringBehaviorChanged } from './broadcast.js'; import cacheStorage from './cachestorage.js'; import cosmeticFilteringEngine from './cosmetic-filtering.js'; import htmlFilteringEngine from './html-filtering.js'; @@ -346,7 +347,7 @@ const onMessage = function(request, sender, callback) { case 'setWhitelist': µb.netWhitelist = µb.whitelistFromString(request.whitelist); µb.saveWhitelist(); - µb.filteringBehaviorChanged(); + filteringBehaviorChanged(); break; case 'toggleHostnameSwitch': diff --git a/src/js/scriptlet-filtering.js b/src/js/scriptlet-filtering.js index 71cd6082631e9..a9a82379b3b4e 100644 --- a/src/js/scriptlet-filtering.js +++ b/src/js/scriptlet-filtering.js @@ -26,6 +26,7 @@ /******************************************************************************/ import µb from './background.js'; +import { onBroadcast } from './broadcast.js'; import { redirectEngine as reng } from './redirect-engine.js'; import { sessionFirewall } from './filtering-engines.js'; import { StaticExtFilteringHostnameDB } from './static-ext-filtering-db.js'; @@ -67,12 +68,10 @@ const contentScriptRegisterer = new (class { constructor() { this.hostnameToDetails = new Map(); if ( browser.contentScripts === undefined ) { return; } - µb.onEvent('filteringBehaviorChanged', ev => { - const details = ev.detail; - if ( details instanceof Object ) { - if ( details.direction > 0 ) { return; } - if ( details.hostname ) { return this.flush(details.hostname); } - } + onBroadcast(msg => { + if ( msg.what !== 'filteringBehaviorChanged' ) { return; } + if ( msg.direction > 0 ) { return; } + if ( msg.hostname ) { return this.flush(msg.hostname); } this.reset(); }); } diff --git a/src/js/scriptlets/cosmetic-logger.js b/src/js/scriptlets/cosmetic-logger.js index 181c6e2094223..cd3d5419ebf26 100644 --- a/src/js/scriptlets/cosmetic-logger.js +++ b/src/js/scriptlets/cosmetic-logger.js @@ -19,6 +19,8 @@ Home: https://github.com/gorhill/uBlock */ +/* globals browser */ + 'use strict'; /******************************************************************************/ @@ -28,12 +30,8 @@ /******************************************************************************/ -if ( - typeof vAPI !== 'object' || - vAPI.domWatcher instanceof Object === false -) { - return; -} +if ( typeof vAPI !== 'object' ) { return; } +if ( vAPI.domWatcher instanceof Object === false ) { return; } const reHasCSSCombinators = /[ >+~]/; const simpleDeclarativeSet = new Set(); @@ -51,16 +49,16 @@ const loggedSelectors = new Set(); const rePseudoElements = /:(?::?after|:?before|:[a-z-]+)$/; -const hasSelector = function(selector, context = document) { +function hasSelector(selector, context = document) { try { return context.querySelector(selector) !== null; } catch(ex) { } return false; -}; +} -const safeMatchSelector = function(selector, context) { +function safeMatchSelector(selector, context) { const safeSelector = rePseudoElements.test(selector) ? selector.replace(rePseudoElements, '') : selector; @@ -70,9 +68,9 @@ const safeMatchSelector = function(selector, context) { catch(ex) { } return false; -}; +} -const safeQuerySelector = function(selector, context = document) { +function safeQuerySelector(selector, context = document) { const safeSelector = rePseudoElements.test(selector) ? selector.replace(rePseudoElements, '') : selector; @@ -82,9 +80,9 @@ const safeQuerySelector = function(selector, context = document) { catch(ex) { } return null; -}; +} -const safeGroupSelectors = function(selectors) { +function safeGroupSelectors(selectors) { const arr = Array.isArray(selectors) ? selectors : Array.from(selectors); @@ -93,11 +91,11 @@ const safeGroupSelectors = function(selectors) { ? s.replace(rePseudoElements, '') : s; }).join(',\n'); -}; +} /******************************************************************************/ -const processDeclarativeSimple = function(node, out) { +function processDeclarativeSimple(node, out) { if ( simpleDeclarativeSet.size === 0 ) { return; } if ( simpleDeclarativeStr === undefined ) { simpleDeclarativeStr = safeGroupSelectors(simpleDeclarativeSet); @@ -120,11 +118,11 @@ const processDeclarativeSimple = function(node, out) { simpleDeclarativeStr = undefined; loggedSelectors.add(selector); } -}; +} /******************************************************************************/ -const processDeclarativeComplex = function(out) { +function processDeclarativeComplex(out) { if ( complexDeclarativeSet.size === 0 ) { return; } if ( complexDeclarativeStr === undefined ) { complexDeclarativeStr = safeGroupSelectors(complexDeclarativeSet); @@ -137,7 +135,7 @@ const processDeclarativeComplex = function(out) { complexDeclarativeStr = undefined; loggedSelectors.add(selector); } -}; +} /******************************************************************************/ @@ -156,7 +154,7 @@ function processProcedural(out) { /******************************************************************************/ -const processExceptions = function(out) { +function processExceptions(out) { if ( exceptionDict.size === 0 ) { return; } if ( exceptionStr === undefined ) { exceptionStr = safeGroupSelectors(exceptionDict.keys()); @@ -169,18 +167,18 @@ const processExceptions = function(out) { exceptionStr = undefined; loggedSelectors.add(raw); } -}; +} /******************************************************************************/ -const processProceduralExceptions = function(out) { +function processProceduralExceptions(out) { if ( proceduralExceptionDict.size === 0 ) { return; } for ( const exception of proceduralExceptionDict.values() ) { if ( exception.test() === false ) { continue; } out.push(`#@#${exception.raw}`); proceduralExceptionDict.delete(exception.raw); } -}; +} /******************************************************************************/ @@ -313,41 +311,32 @@ const handlers = { } }; -/******************************************************************************/ - -const shutdown = function() { - processTimer.clear(); - attributeObserver.disconnect(); - if ( typeof vAPI !== 'object' ) { return; } - if ( vAPI.domFilterer instanceof Object ) { - vAPI.domFilterer.removeListener(handlers); - } - if ( vAPI.domWatcher instanceof Object ) { - vAPI.domWatcher.removeListener(handlers); - } - if ( vAPI.broadcastListener instanceof Object ) { - vAPI.broadcastListener.remove(broadcastListener); - } -}; +vAPI.domWatcher.addListener(handlers); /******************************************************************************/ -const broadcastListener = msg => { +const broadcastHandler = msg => { if ( msg.what === 'loggerDisabled' ) { shutdown(); } }; +browser.runtime.onMessage.addListener(broadcastHandler); + /******************************************************************************/ -vAPI.messaging.extend().then(extended => { - if ( extended !== true ) { - return shutdown(); +function shutdown() { + browser.runtime.onMessage.removeListener(broadcastHandler); + processTimer.clear(); + attributeObserver.disconnect(); + if ( typeof vAPI !== 'object' ) { return; } + if ( vAPI.domFilterer instanceof Object ) { + vAPI.domFilterer.removeListener(handlers); } - vAPI.broadcastListener.add(broadcastListener); -}); - -vAPI.domWatcher.addListener(handlers); + if ( vAPI.domWatcher instanceof Object ) { + vAPI.domWatcher.removeListener(handlers); + } +} /******************************************************************************/ diff --git a/src/js/start.js b/src/js/start.js index 6dbaeefc1d1b9..c2182cb9ccee1 100644 --- a/src/js/start.js +++ b/src/js/start.js @@ -39,17 +39,18 @@ import './tab.js'; import './ublock.js'; import './utils.js'; +import io from './assets.js'; +import µb from './background.js'; +import { filteringBehaviorChanged } from './broadcast.js'; import cacheStorage from './cachestorage.js'; +import { ubolog } from './console.js'; import contextMenu from './contextmenu.js'; -import io from './assets.js'; import lz4Codec from './lz4.js'; -import staticExtFilteringEngine from './static-ext-filtering.js'; +import { redirectEngine } from './redirect-engine.js'; import staticFilteringReverseLookup from './reverselookup.js'; +import staticExtFilteringEngine from './static-ext-filtering.js'; import staticNetFilteringEngine from './static-net-filtering.js'; -import µb from './background.js'; import webRequest from './traffic.js'; -import { redirectEngine } from './redirect-engine.js'; -import { ubolog } from './console.js'; import { permanentFirewall, @@ -453,7 +454,7 @@ if ( selfieIsValid !== true ) { // Flush memory cache -- unsure whether the browser does this internally // when loading a new extension. -µb.filteringBehaviorChanged(); +filteringBehaviorChanged(); // Final initialization steps after all needed assets are in memory. diff --git a/src/js/storage.js b/src/js/storage.js index 6c05d5a14fc37..c92842ec2f91d 100644 --- a/src/js/storage.js +++ b/src/js/storage.js @@ -28,8 +28,9 @@ import publicSuffixList from '../lib/publicsuffixlist/publicsuffixlist.js'; import punycode from '../lib/punycode.js'; -import cosmeticFilteringEngine from './cosmetic-filtering.js'; import io from './assets.js'; +import { broadcast, filteringBehaviorChanged, onBroadcast } from './broadcast.js'; +import cosmeticFilteringEngine from './cosmetic-filtering.js'; import logger from './logger.js'; import lz4Codec from './lz4.js'; import staticExtFilteringEngine from './static-ext-filtering.js'; @@ -243,7 +244,7 @@ import { if ( typeof hs[key] !== typeof hsDefault[key] ) { continue; } this.hiddenSettings[key] = hs[key]; } - this.fireEvent('hiddenSettingsChanged'); + broadcast({ what: 'hiddenSettingsChanged' }); }; // Note: Save only the settings which values differ from the default ones. @@ -259,7 +260,8 @@ import { }); }; -µb.onEvent('hiddenSettingsChanged', ( ) => { +onBroadcast(msg => { + if ( msg.what !== 'hiddenSettingsChanged' ) { return; } const µbhs = µb.hiddenSettings; ubologSet(µbhs.consoleLogLevel === 'info'); vAPI.net.setOptions({ @@ -391,7 +393,8 @@ import { return false; }; -µb.onEvent('hiddenSettingsChanged', ( ) => { +onBroadcast(msg => { + if ( msg.what !== 'hiddenSettingsChanged' ) { return; } µb.parsedTrustedListPrefixes = []; }); @@ -614,9 +617,8 @@ import { // https://www.reddit.com/r/uBlockOrigin/comments/cj7g7m/ // https://www.reddit.com/r/uBlockOrigin/comments/cnq0bi/ - µb.filteringBehaviorChanged(); - - vAPI.messaging.broadcast({ what: 'userFiltersUpdated' }); + filteringBehaviorChanged(); + broadcast({ what: 'userFiltersUpdated' }); }; µb.createUserFilters = function(details) { @@ -852,7 +854,7 @@ import { staticExtFilteringEngine.freeze(); redirectEngine.freeze(); vAPI.net.unsuspend(); - µb.filteringBehaviorChanged(); + filteringBehaviorChanged(); vAPI.storage.set({ 'availableFilterLists': µb.availableFilterLists }); @@ -862,7 +864,7 @@ import { text: 'Reloading all filter lists: done' }); - vAPI.messaging.broadcast({ + broadcast({ what: 'staticFilteringDataChanged', parseCosmeticFilters: µb.userSettings.parseAllABPHideFilters, ignoreGenericCosmeticFilters: µb.userSettings.ignoreGenericCosmeticFilters, @@ -1584,10 +1586,10 @@ import { } else if ( details.assetKey === 'ublock-badlists' ) { this.badLists = new Map(); } - vAPI.messaging.broadcast({ + broadcast({ what: 'assetUpdated', key: details.assetKey, - cached: cached + cached, }); // https://github.com/gorhill/uBlock/issues/2585 // Whenever an asset is overwritten, the current selfie is quite @@ -1598,10 +1600,10 @@ import { // Update failed. if ( topic === 'asset-update-failed' ) { - vAPI.messaging.broadcast({ + broadcast({ what: 'assetUpdated', key: details.assetKey, - failed: true + failed: true, }); return; } @@ -1625,7 +1627,7 @@ import { } else { this.scheduleAssetUpdater(0); } - vAPI.messaging.broadcast({ + broadcast({ what: 'assetsUpdated', assetKeys: details.assetKeys }); diff --git a/src/js/support.js b/src/js/support.js index 891842efc6872..42e293bd4cdc9 100644 --- a/src/js/support.js +++ b/src/js/support.js @@ -23,6 +23,7 @@ 'use strict'; +import { onBroadcast } from './broadcast.js'; import { dom, qs$ } from './dom.js'; /******************************************************************************/ @@ -316,7 +317,7 @@ uBlockDashboard.patchCodeMirrorEditor(cmEditor); }); } - vAPI.broadcastListener.add(msg => { + onBroadcast(msg => { if ( msg.what === 'assetsUpdated' ) { dom.cl.remove(dom.body, 'updating'); dom.cl.add(dom.body, 'updated'); diff --git a/src/js/ublock.js b/src/js/ublock.js index 7f902af38e6f2..ed4fe2830b4af 100644 --- a/src/js/ublock.js +++ b/src/js/ublock.js @@ -23,12 +23,13 @@ /******************************************************************************/ -import contextMenu from './contextmenu.js'; -import cosmeticFilteringEngine from './cosmetic-filtering.js'; import io from './assets.js'; import µb from './background.js'; -import { hostnameFromURI } from './uri-utils.js'; +import { broadcast, filteringBehaviorChanged, onBroadcast } from './broadcast.js'; +import contextMenu from './contextmenu.js'; +import cosmeticFilteringEngine from './cosmetic-filtering.js'; import { redirectEngine } from './redirect-engine.js'; +import { hostnameFromURI } from './uri-utils.js'; import { permanentFirewall, @@ -147,7 +148,7 @@ const matchBucket = function(url, hostname, bucket, start) { } bucket.push(directive); this.saveWhitelist(); - µb.filteringBehaviorChanged({ hostname: targetHostname }); + filteringBehaviorChanged({ hostname: targetHostname }); return true; } @@ -188,7 +189,7 @@ const matchBucket = function(url, hostname, bucket, start) { } } this.saveWhitelist(); - µb.filteringBehaviorChanged({ direction: 1 }); + filteringBehaviorChanged({ direction: 1 }); return true; }; @@ -423,7 +424,7 @@ const matchBucket = function(url, hostname, bucket, start) { redirectEngine.invalidateResourcesSelfie(io); this.loadRedirectResources(); } - this.fireEvent('hiddenSettingsChanged'); + broadcast({ what: 'hiddenSettingsChanged' }); }; /******************************************************************************/ @@ -524,7 +525,7 @@ const matchBucket = function(url, hostname, bucket, start) { cosmeticFilteringEngine.removeFromSelectorCache(srcHostname, 'net'); // Flush caches - µb.filteringBehaviorChanged({ + filteringBehaviorChanged({ direction: action === 1 ? 1 : 0, hostname: srcHostname, }); @@ -613,7 +614,7 @@ const matchBucket = function(url, hostname, bucket, start) { switch ( details.name ) { case 'no-scripting': case 'no-remote-fonts': - µb.filteringBehaviorChanged({ + filteringBehaviorChanged({ direction: details.state ? 1 : 0, hostname: details.hostname, }); @@ -677,7 +678,10 @@ const matchBucket = function(url, hostname, bucket, start) { parse(); - µb.onEvent('hiddenSettingsChanged', ( ) => { parse(); }); + onBroadcast(msg => { + if ( msg.what !== 'hiddenSettingsChanged' ) { return; } + parse(); + }); } /******************************************************************************/ diff --git a/src/js/utils.js b/src/js/utils.js index 9f94aeb255903..1c9340e6ea9c7 100644 --- a/src/js/utils.js +++ b/src/js/utils.js @@ -134,36 +134,6 @@ import µb from './background.js'; /******************************************************************************/ -µb.fireEvent = function(name, details = undefined) { - if ( - self instanceof Object && - self.dispatchEvent instanceof Function && - self.CustomEvent instanceof Function - ) { - self.dispatchEvent(new CustomEvent(name, { detail: details })); - } -}; - -µb.onEvent = function(name, fn) { - if ( - self instanceof Object && - self.addEventListener instanceof Function - ) { - self.addEventListener(name, fn); - } -}; - -/******************************************************************************/ - -µb.filteringBehaviorChanged = function(details = {}) { - if ( typeof details.direction !== 'number' || details.direction >= 0 ) { - vAPI.net.handlerBehaviorChanged(); - } - this.fireEvent('filteringBehaviorChanged', details); -}; - -/******************************************************************************/ - // TODO: properly compare arrays µb.getModifiedSettings = function(edit, orig = {}) {