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));