diff --git a/platform/chromium/vapi-webrequest.js b/platform/chromium/vapi-webrequest.js index e949b01dd..d999b56b9 100644 --- a/platform/chromium/vapi-webrequest.js +++ b/platform/chromium/vapi-webrequest.js @@ -148,3 +148,44 @@ })(); /******************************************************************************/ + +// https://github.com/gorhill/uBlock/issues/2067 +// Experimental: Block everything until uBO is fully ready. + +vAPI.net.onBeforeReady = (function() { + let pendings; + + const handler = function(details) { + if ( pendings === undefined ) { return; } + if ( details.tabId < 0 ) { return; } + + pendings.add(details.tabId); + + return { cancel: true }; + }; + + return { + experimental: true, + start: function() { + pendings = new Set(); + browser.webRequest.onBeforeRequest.addListener( + handler, + { urls: [ 'http://*/*', 'https://*/*' ] }, + [ 'blocking' ] + ); + }, + // https://github.com/gorhill/uBlock/issues/2067 + // Force-reload tabs for which network requests were blocked + // during launch. This can happen only if tabs were "suspended". + stop: function() { + if ( pendings === undefined ) { return; } + browser.webRequest.onBeforeRequest.removeListener(handler); + for ( const tabId of pendings ) { + vAPI.tabs.reload(tabId); + } + pendings = undefined; + }, + }; +})(); + +/******************************************************************************/ diff --git a/platform/firefox/vapi-webrequest.js b/platform/firefox/vapi-webrequest.js index 812c9655b..0ba557708 100644 --- a/platform/firefox/vapi-webrequest.js +++ b/platform/firefox/vapi-webrequest.js @@ -130,3 +130,52 @@ })(); /******************************************************************************/ + +// Related issues: +// - https://github.com/gorhill/uBlock/issues/2067 +// - https://github.com/uBlockOrigin/uBlock-issues/issues/128 +// - https://bugzilla.mozilla.org/show_bug.cgi?id=1503721 + +vAPI.net.onBeforeReady = (function() { + let pendings; + + const handler = function(details) { + if ( pendings === undefined ) { return; } + if ( details.tabId < 0 ) { return; } + + const pending = { + details: Object.assign({}, details), + resolve: undefined, + promise: undefined + }; + + pending.promise = new Promise(function(resolve) { + pending.resolve = resolve; + }); + + pendings.push(pending); + + return pending.promise; + }; + + return { + start: function() { + pendings = []; + browser.webRequest.onBeforeRequest.addListener( + handler, + { urls: [ 'http://*/*', 'https://*/*' ] }, + [ 'blocking' ] + ); + }, + stop: function(resolver) { + if ( pendings === undefined ) { return; } + for ( const pending of pendings ) { + const result = resolver(pending.details); + pending.resolve(result); + } + pendings = undefined; + }, + }; +})(); + +/******************************************************************************/ diff --git a/src/js/start.js b/src/js/start.js index 827c59b02..ad7ba5e73 100644 --- a/src/js/start.js +++ b/src/js/start.js @@ -53,6 +53,8 @@ vAPI.app.onShutdown = function() { // - Schedule next update operation. var onAllReady = function() { + µb.webRequest.start(); + // Ensure that the resources allocated for decompression purpose (likely // large buffers) are garbage-collectable immediately after launch. // Otherwise I have observed that it may take quite a while before the @@ -60,7 +62,6 @@ var onAllReady = function() { // as possible ensure minimal memory usage baseline. µb.lz4Codec.relinquish(); - µb.webRequest.start(); initializeTabs(); // https://github.com/chrisaljoudi/uBlock/issues/184 diff --git a/src/js/traffic.js b/src/js/traffic.js index bf84bd17d..cc211e1be 100644 --- a/src/js/traffic.js +++ b/src/js/traffic.js @@ -992,28 +992,17 @@ const strictBlockBypasser = { return { start: (function() { - const suspendedTabs = new Set(); - const onBeforeReady = function(details) { - if ( details.type !== 'main_frame' && details.tabId > 0 ) { - suspendedTabs.add(details.tabId); - console.info('uBO suspend tab %d, block %s', details.tabId, details.url); - return { cancel: true }; - } - }; - // https://github.com/gorhill/uBlock/issues/2067 - // Experimental: Block everything until uBO is fully ready. - // https://github.com/gorhill/uBlock/issues/3130 - // Don't block root frame. - if ( µBlock.hiddenSettings.suspendTabsUntilReady ) { - vAPI.net.addListener( - 'onBeforeRequest', - onBeforeReady, - { urls: [ 'http://*/*', 'https://*/*' ] }, - [ 'blocking' ] - ); + if ( + vAPI.net.onBeforeReady instanceof Object && + ( + vAPI.net.onBeforeReady.experimental !== true || + µBlock.hiddenSettings.suspendTabsUntilReady + ) + ) { + vAPI.net.onBeforeReady.start(); } + return function() { - vAPI.net.removeListener('onBeforeRequest', onBeforeReady); vAPI.net.addListener( 'onBeforeRequest', onBeforeRequest, @@ -1040,14 +1029,9 @@ return { [ 'blocking', 'requestBody' ] ); } - // https://github.com/gorhill/uBlock/issues/2067 - // Force-reload tabs for which network requests were blocked - // during launch. This can happen only if tabs were "suspended". - for ( const tabId of suspendedTabs ) { - console.info('uBO suspend tab %d, force reload', tabId); - vAPI.tabs.reload(tabId); + if ( vAPI.net.onBeforeReady instanceof Object ) { + vAPI.net.onBeforeReady.stop(onBeforeRequest); } - suspendedTabs.clear(); }; })(),