From c4b7ee80ea7b22d1f870f9a0e09be9de225cf0b3 Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Thu, 7 Oct 2021 14:41:29 -0400 Subject: [PATCH] Further work on JS modules Related issue: - https://github.com/uBlockOrigin/uBlock-issues/issues/1664 --- .jshintrc | 4 -- platform/chromium/webext.js | 8 +--- platform/common/vapi-background.js | 45 +----------------- platform/firefox/webext.js | 2 +- src/background.html | 10 ---- src/js/benchmarks.js | 47 +++++++++++++++++++ src/js/cachestorage.js | 1 + src/js/commands.js | 2 +- src/js/cosmetic-filtering.js | 1 + src/js/messaging.js | 8 +++- src/js/pagestore.js | 6 ++- src/js/start.js | 14 +++++- src/js/tab.js | 1 + src/js/traffic.js | 4 +- src/js/ublock.js | 75 +----------------------------- 15 files changed, 83 insertions(+), 145 deletions(-) diff --git a/.jshintrc b/.jshintrc index 5d43f6df9..d2fe2c38f 100644 --- a/.jshintrc +++ b/.jshintrc @@ -6,12 +6,8 @@ "globals": { "browser": false, // global variable in Firefox, Edge "chrome": false, // global variable in Chromium, Chrome, Opera - "log": false, - "safari": false, "self": false, "vAPI": false, - "webext": false, - "µBlock": false, "URLSearchParams": false, "WebAssembly": false }, diff --git a/platform/chromium/webext.js b/platform/chromium/webext.js index 1acb1ee56..c96c3de82 100644 --- a/platform/chromium/webext.js +++ b/platform/chromium/webext.js @@ -24,9 +24,6 @@ // `webext` is a promisified api of `chrome`. Entries are added as // the promisification of uBO progress. -const webext = (( ) => { // jshint ignore:line -// >>>>> start of private scope - const promisifyNoFail = function(thisArg, fnName, outFn = r => r) { const fn = thisArg[fnName]; return function() { @@ -164,7 +161,4 @@ if ( chrome.tabs.removeCSS instanceof Function ) { webext.tabs.removeCSS = promisifyNoFail(chrome.tabs, 'removeCSS'); } -return webext; - -// <<<<< end of private scope -})(); +export default webext; diff --git a/platform/common/vapi-background.js b/platform/common/vapi-background.js index 8558a1ea9..b9b425944 100644 --- a/platform/common/vapi-background.js +++ b/platform/common/vapi-background.js @@ -26,6 +26,7 @@ /******************************************************************************/ +import webext from './webext.js'; import { ubolog } from './console.js'; /******************************************************************************/ @@ -1252,50 +1253,6 @@ vAPI.Net = class { canSuspend() { return false; } - async benchmark() { - if ( typeof µBlock !== 'object' ) { return; } - const requests = await µBlock.loadBenchmarkDataset(); - if ( Array.isArray(requests) === false || requests.length === 0 ) { - console.info('No requests found to benchmark'); - return; - } - const mappedTypes = new Map([ - [ 'document', 'main_frame' ], - [ 'subdocument', 'sub_frame' ], - ]); - console.info('vAPI.net.onBeforeSuspendableRequest()...'); - const t0 = self.performance.now(); - const promises = []; - const details = { - documentUrl: '', - tabId: -1, - parentFrameId: -1, - frameId: 0, - type: '', - url: '', - }; - for ( const request of requests ) { - details.documentUrl = request.frameUrl; - details.tabId = -1; - details.parentFrameId = -1; - details.frameId = 0; - details.type = mappedTypes.get(request.cpt) || request.cpt; - details.url = request.url; - if ( details.type === 'main_frame' ) { continue; } - promises.push(this.onBeforeSuspendableRequest(details)); - } - return Promise.all(promises).then(results => { - let blockCount = 0; - for ( const r of results ) { - if ( r !== undefined ) { blockCount += 1; } - } - const t1 = self.performance.now(); - const dur = t1 - t0; - console.info(`Evaluated ${requests.length} requests in ${dur.toFixed(0)} ms`); - console.info(`\tBlocked ${blockCount} requests`); - console.info(`\tAverage: ${(dur / requests.length).toFixed(3)} ms per request`); - }); - } }; /******************************************************************************/ diff --git a/platform/firefox/webext.js b/platform/firefox/webext.js index 4729e7c17..761da61c4 100644 --- a/platform/firefox/webext.js +++ b/platform/firefox/webext.js @@ -21,4 +21,4 @@ 'use strict'; -const webext = browser; // jshint ignore:line +export default browser; diff --git a/src/background.html b/src/background.html index 9f085da94..da1c03b01 100644 --- a/src/background.html +++ b/src/background.html @@ -6,17 +6,7 @@ - - - - - - - - - - diff --git a/src/js/benchmarks.js b/src/js/benchmarks.js index b478bf9b4..b5ec030a8 100644 --- a/src/js/benchmarks.js +++ b/src/js/benchmarks.js @@ -28,6 +28,7 @@ import io from './assets.js'; import scriptletFilteringEngine from './scriptlet-filtering.js'; import staticNetFilteringEngine from './static-net-filtering.js'; import µb from './background.js'; +import webRequest from './traffic.js'; import { FilteringContext } from './filtering-context.js'; import { LineIterator } from './text-utils.js'; import { sessionFirewall } from './filtering-engines.js'; @@ -336,3 +337,49 @@ const loadBenchmarkDataset = (( ) => { }; /******************************************************************************/ + +µb.benchmarkOnBeforeRequest = async function() { + const requests = await loadBenchmarkDataset(); + if ( Array.isArray(requests) === false || requests.length === 0 ) { + console.info('No requests found to benchmark'); + return; + } + const mappedTypes = new Map([ + [ 'document', 'main_frame' ], + [ 'subdocument', 'sub_frame' ], + ]); + console.info('webRequest.onBeforeRequest()...'); + const t0 = self.performance.now(); + const promises = []; + const details = { + documentUrl: '', + tabId: -1, + parentFrameId: -1, + frameId: 0, + type: '', + url: '', + }; + for ( const request of requests ) { + details.documentUrl = request.frameUrl; + details.tabId = -1; + details.parentFrameId = -1; + details.frameId = 0; + details.type = mappedTypes.get(request.cpt) || request.cpt; + details.url = request.url; + if ( details.type === 'main_frame' ) { continue; } + promises.push(webRequest.onBeforeRequest(details)); + } + return Promise.all(promises).then(results => { + let blockCount = 0; + for ( const r of results ) { + if ( r !== undefined ) { blockCount += 1; } + } + const t1 = self.performance.now(); + const dur = t1 - t0; + console.info(`Evaluated ${requests.length} requests in ${dur.toFixed(0)} ms`); + console.info(`\tBlocked ${blockCount} requests`); + console.info(`\tAverage: ${(dur / requests.length).toFixed(3)} ms per request`); + }); +}; + +/******************************************************************************/ diff --git a/src/js/cachestorage.js b/src/js/cachestorage.js index 2c2e60957..798f7f1af 100644 --- a/src/js/cachestorage.js +++ b/src/js/cachestorage.js @@ -27,6 +27,7 @@ import lz4Codec from './lz4.js'; import µb from './background.js'; +import webext from './webext.js'; /******************************************************************************/ diff --git a/src/js/commands.js b/src/js/commands.js index 19583799a..553f2abf2 100644 --- a/src/js/commands.js +++ b/src/js/commands.js @@ -23,8 +23,8 @@ /******************************************************************************/ -import { hostnameFromURI } from './uri-utils.js'; import µb from './background.js'; +import { hostnameFromURI } from './uri-utils.js'; /******************************************************************************/ diff --git a/src/js/cosmetic-filtering.js b/src/js/cosmetic-filtering.js index 229d88bfd..a2fad4a7e 100644 --- a/src/js/cosmetic-filtering.js +++ b/src/js/cosmetic-filtering.js @@ -23,6 +23,7 @@ /******************************************************************************/ +import './utils.js'; import logger from './logger.js'; import µb from './background.js'; diff --git a/src/js/messaging.js b/src/js/messaging.js index d163cb7c0..06b612c60 100644 --- a/src/js/messaging.js +++ b/src/js/messaging.js @@ -36,10 +36,10 @@ import staticExtFilteringEngine from './static-ext-filtering.js'; import staticFilteringReverseLookup from './reverselookup.js'; import staticNetFilteringEngine from './static-net-filtering.js'; import µb from './background.js'; +import webRequest from './traffic.js'; import { denseBase64 } from './base64-custom.js'; import { redirectEngine } from './redirect-engine.js'; import { StaticFilteringParser } from './static-filtering-parser.js'; -import { webRequest } from './traffic.js'; import { permanentFirewall, @@ -129,7 +129,11 @@ const onMessage = function(request, sender, callback) { return; case 'scriptlet': - µb.scriptlets.inject(request.tabId, request.scriptlet, callback); + vAPI.tabs.executeScript(request.tabId, { + file: `/js/scriptlets/${request.scriptlet}.js` + }).then(result => { + callback(result); + }); return; case 'sfneBenchmark': diff --git a/src/js/pagestore.js b/src/js/pagestore.js index c6bc6cd19..d9987012d 100644 --- a/src/js/pagestore.js +++ b/src/js/pagestore.js @@ -27,6 +27,7 @@ import contextMenu from './contextmenu.js'; import logger from './logger.js'; import staticNetFilteringEngine from './static-net-filtering.js'; import µb from './background.js'; +import webext from './webext.js'; import { orphanizeString } from './text-utils.js'; import { redirectEngine } from './redirect-engine.js'; @@ -639,7 +640,10 @@ const PageStore = class { } else { this.allowLargeMediaElementsUntil = Date.now(); } - µb.scriptlets.injectDeep(this.tabId, 'load-large-media-all'); + vAPI.tabs.executeScript(this.tabId, { + file: '/js/scriptlets/load-large-media-all.js', + allFrames: true, + }); } // https://github.com/gorhill/uBlock/issues/2053 diff --git a/src/js/start.js b/src/js/start.js index a1c50c1fb..54a7caefa 100644 --- a/src/js/start.js +++ b/src/js/start.js @@ -23,6 +23,18 @@ /******************************************************************************/ +import './vapi-common.js'; +import './vapi-background.js'; +import './vapi-background-ext.js'; + +// The following modules are loaded here until their content is better organized +import './commands.js'; +import './messaging.js'; +import './storage.js'; +import './tab.js'; +import './ublock.js'; +import './utils.js'; + import cacheStorage from './cachestorage.js'; import contextMenu from './contextmenu.js'; import io from './assets.js'; @@ -31,9 +43,9 @@ import staticExtFilteringEngine from './static-ext-filtering.js'; import staticFilteringReverseLookup from './reverselookup.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 { webRequest } from './traffic.js'; import { permanentFirewall, diff --git a/src/js/tab.js b/src/js/tab.js index 9d1e7e2ce..f239f25e2 100644 --- a/src/js/tab.js +++ b/src/js/tab.js @@ -28,6 +28,7 @@ import logger from './logger.js'; import scriptletFilteringEngine from './scriptlet-filtering.js'; import staticNetFilteringEngine from './static-net-filtering.js'; import µb from './background.js'; +import webext from './webext.js'; import { PageStore } from './pagestore.js'; import { diff --git a/src/js/traffic.js b/src/js/traffic.js index 9d372d6c1..0e22bbddc 100644 --- a/src/js/traffic.js +++ b/src/js/traffic.js @@ -1132,6 +1132,8 @@ const strictBlockBypasser = { /******************************************************************************/ const webRequest = { + onBeforeRequest, + start: (( ) => { vAPI.net = new vAPI.Net(); vAPI.net.suspend(); @@ -1155,6 +1157,6 @@ const webRequest = { /******************************************************************************/ -export { webRequest }; +export default webRequest; /******************************************************************************/ diff --git a/src/js/ublock.js b/src/js/ublock.js index f9db09e2b..f73b8f25d 100644 --- a/src/js/ublock.js +++ b/src/js/ublock.js @@ -627,7 +627,7 @@ const matchBucket = function(url, hostname, bucket, start) { return bits; }; -µb.parseBlockingProfiles = (( ) => { +{ const parse = function() { const s = µb.hiddenSettings.blockingProfiles; const profiles = []; @@ -648,77 +648,6 @@ const matchBucket = function(url, hostname, bucket, start) { parse(); self.addEventListener('hiddenSettingsChanged', ( ) => { parse(); }); - - return parse; -})(); - -/******************************************************************************/ - -µb.scriptlets = (function() { - const pendingEntries = new Map(); - - const Entry = class { - constructor(tabId, scriptlet, callback) { - this.tabId = tabId; - this.scriptlet = scriptlet; - this.callback = callback; - this.timer = vAPI.setTimeout(this.service.bind(this), 1000); - } - service(response) { - if ( this.timer !== null ) { - clearTimeout(this.timer); - this.timer = null; - } - pendingEntries.delete(makeKey(this.tabId, this.scriptlet)); - this.callback(response); - } - }; - - const makeKey = function(tabId, scriptlet) { - return tabId + ' ' + scriptlet; - }; - - const report = function(tabId, scriptlet, response) { - const key = makeKey(tabId, scriptlet); - const entry = pendingEntries.get(key); - if ( entry === undefined ) { return; } - entry.service(response); - }; - - const inject = function(tabId, scriptlet, callback) { - if ( typeof callback === 'function' ) { - if ( vAPI.isBehindTheSceneTabId(tabId) ) { - callback(); - return; - } - const key = makeKey(tabId, scriptlet); - const entry = pendingEntries.get(key); - if ( entry !== undefined ) { - if ( callback !== entry.callback ) { - callback(); - } - return; - } - pendingEntries.set(key, new Entry(tabId, scriptlet, callback)); - } - vAPI.tabs.executeScript(tabId, { - file: `/js/scriptlets/${scriptlet}.js` - }); - }; - - // TODO: think about a callback mechanism. - const injectDeep = function(tabId, scriptlet) { - vAPI.tabs.executeScript(tabId, { - file: `/js/scriptlets/${scriptlet}.js`, - allFrames: true - }); - }; - - return { - inject: inject, - injectDeep: injectDeep, - report: report - }; -})(); +} /******************************************************************************/