From 9058c3524ec0c534ef4cc699e6f5e327171825bd Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Sat, 17 Sep 2022 11:22:25 -0400 Subject: [PATCH] [mv3] Fix improper usage of scripting.unregisterContentScripts() THis was causing all registered css/scripts to be removed when revoking permission for a single site. --- .../mv3/extension/js/scripting-manager.js | 48 ++++++++++++++++--- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/platform/mv3/extension/js/scripting-manager.js b/platform/mv3/extension/js/scripting-manager.js index 6a07db9eb..16c9a84be 100644 --- a/platform/mv3/extension/js/scripting-manager.js +++ b/platform/mv3/extension/js/scripting-manager.js @@ -83,6 +83,16 @@ const hostnamesFromMatches = origins => { return out; }; +const arrayEq = (a, b) => { + if ( a === undefined ) { return b === undefined; } + if ( b === undefined ) { return false; } + if ( a.length !== b.length ) { return false; } + for ( const i of a ) { + if ( b.includes(i) === false ) { return false; } + } + return true; +}; + /******************************************************************************/ const toRegisterable = (fname, entry) => { @@ -113,6 +123,17 @@ const toRegisterable = (fname, entry) => { return directive; }; +const toMaybeUpdatable = (registered, candidate) => { + const matches = candidate.y && matchesFromHostnames(candidate.y); + if ( arrayEq(registered.matches, matches) === false ) { + return toRegisterable(candidate); + } + const excludeMatches = candidate.n && matchesFromHostnames(candidate.n); + if ( arrayEq(registered.excludeMatches, excludeMatches) === false ) { + return toRegisterable(candidate); + } +}; + /******************************************************************************/ const shouldRegister = (origins, matches) => { @@ -243,26 +264,39 @@ async function registerInjectable() { } } - const before = new Set(registered.map(entry => entry.id)); + const before = new Map(registered.map(entry => [ entry.id, entry ])); + const toAdd = []; + const toUpdate = []; for ( const [ fname, entry ] of toRegister ) { - if ( before.has(fname) ) { continue; } - toAdd.push(toRegisterable(fname, entry)); + if ( before.has(fname) === false ) { + toAdd.push(toRegisterable(fname, entry)); + continue; + } + const updated = toMaybeUpdatable(before.get(fname), entry); + if ( updated !== undefined ) { + toUpdate.push(updated); + } } + const toRemove = []; - for ( const fname of before ) { + for ( const fname of before.keys() ) { if ( toRegister.has(fname) ) { continue; } toRemove.push(fname); } const todo = []; if ( toRemove.length !== 0 ) { - todo.push(browser.scripting.unregisterContentScripts(toRemove)); - console.info(`Unregistered ${toRemove.length} content (css/js)`); + todo.push(browser.scripting.unregisterContentScripts({ ids: toRemove })); + console.info(`Unregistered ${toRemove} content (css/js)`); } if ( toAdd.length !== 0 ) { todo.push(browser.scripting.registerContentScripts(toAdd)); - console.info(`Registered ${toAdd.length} content (css/js)`); + console.info(`Registered ${toAdd.map(v => v.id)} content (css/js)`); + } + if ( toUpdate.length !== 0 ) { + todo.push(browser.scripting.updateContentScripts(toUpdate)); + console.info(`Updated ${toUpdate.map(v => v.id)} content (css/js)`); } if ( todo.length === 0 ) { return; }