From 1835e90125702ac0098692a2f98c8276ace92346 Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Thu, 30 Mar 2023 12:30:44 -0400 Subject: [PATCH] Avoid using `!` toolbar icon badge when inconsequential uBO will now verify that at least one unprocessed network requests at launch should have been blocked in order to warn users of unprocessed network requests through the `!` toolbar icon badge. For example, with default filter lists, there is nothing to block on `wikipedia.org`, and hence in this case it's not useful to present the user with the `!` badge. Therefore uBO will not show the badge *only* when at least one unprocessed network requests should have been blocked had uBO been ready when it was fired by the browser. Related commit: - https://github.com/gorhill/uBlock/commit/769b8da664be --- platform/common/vapi-background.js | 22 ++++++++++++++++--- src/js/start.js | 35 ++++++++++++++++-------------- 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/platform/common/vapi-background.js b/platform/common/vapi-background.js index d57628849..aa60cda58 100644 --- a/platform/common/vapi-background.js +++ b/platform/common/vapi-background.js @@ -1191,7 +1191,7 @@ vAPI.Net = class { this.deferredSuspendableListener = undefined; this.listenerMap = new WeakMap(); this.suspendDepth = 0; - this.unprocessedTabs = new Set(); + this.unprocessedTabs = new Map(); browser.webRequest.onBeforeRequest.addListener( details => { @@ -1252,6 +1252,17 @@ vAPI.Net = class { this.onUnprocessedRequest(details); } setSuspendableListener(listener) { + for ( const [ tabId, requests ] of this.unprocessedTabs ) { + let i = requests.length; + while ( i-- ) { + const r = listener(requests[i]); + if ( r === undefined || r.cancel === false ) { + requests.splice(i, 1); + } + } + if ( requests.length !== 0 ) { continue; } + this.unprocessedTabs.delete(tabId); + } if ( this.unprocessedTabs.size !== 0 ) { this.deferredSuspendableListener = listener; listener = details => { @@ -1285,11 +1296,16 @@ vAPI.Net = class { return actualListener; } onUnprocessedRequest(details) { - if ( details.tabId === -1 ) { return; } + const { tabId } = details; + if ( tabId === -1 ) { return; } if ( this.unprocessedTabs.size === 0 ) { vAPI.setDefaultIcon('-loading', '!'); } - this.unprocessedTabs.add(details.tabId); + let requests = this.unprocessedTabs.get(tabId); + if ( requests === undefined ) { + this.unprocessedTabs.set(tabId, (requests = [])); + } + requests.push(Object.assign({}, details)); } hasUnprocessedRequest(tabId) { return this.unprocessedTabs.size !== 0 && diff --git a/src/js/start.js b/src/js/start.js index 6565e916e..abf54e96e 100644 --- a/src/js/start.js +++ b/src/js/start.js @@ -103,6 +103,7 @@ const initializeTabs = async ( ) => { const tabs = await vAPI.tabs.query({ url: '' }); for ( const tab of tabs ) { if ( tab.discarded === true ) { continue; } + if ( tab.status === 'unloaded' ) { continue; } const { id, url } = tab; µb.tabContextManager.commit(id, url); µb.bindTabToPageStore(id, 'tabCommitted', tab); @@ -118,21 +119,23 @@ const initializeTabs = async ( ) => { tabIds.push(id); } } - const results = await Promise.all(toCheck); - for ( let i = 0; i < results.length; i++ ) { - const result = results[i]; - if ( result.length === 0 || result[0] !== true ) { continue; } - // Inject declarative content scripts programmatically. - for ( const contentScript of manifest.content_scripts ) { - for ( const file of contentScript.js ) { - vAPI.tabs.executeScript(tabIds[i], { - file: file, - allFrames: contentScript.all_frames, - runAt: contentScript.run_at - }); + // We do not want to block on content scripts injection + Promise.all(toCheck).then(results => { + for ( let i = 0; i < results.length; i++ ) { + const result = results[i]; + if ( result.length === 0 || result[0] !== true ) { continue; } + // Inject declarative content scripts programmatically. + for ( const contentScript of manifest.content_scripts ) { + for ( const file of contentScript.js ) { + vAPI.tabs.executeScript(tabIds[i], { + file: file, + allFrames: contentScript.all_frames, + runAt: contentScript.run_at + }); + } } } - } + }); }; /******************************************************************************/ @@ -462,6 +465,9 @@ if ( selfieIsValid !== true ) { // This can be used to defer filtering decision-making. µb.readyToFilter = true; +// Initialize internal state with maybe already existing tabs. +await initializeTabs(); + // Start network observers. webRequest.start(); @@ -472,9 +478,6 @@ webRequest.start(); // as possible ensure minimal memory usage baseline. lz4Codec.relinquish(); -// Initialize internal state with maybe already existing tabs. -initializeTabs(); - // https://github.com/chrisaljoudi/uBlock/issues/184 // Check for updates not too far in the future. io.addObserver(µb.assetObserver.bind(µb));