From 22d2ecc472d1f67b5197d1572dd6f2fa368cef3d Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Sat, 11 Oct 2025 14:46:35 -0400 Subject: [PATCH] [mv3][safari] Workaround for user styles issue with bfcache Related issue: https://github.com/uBlockOrigin/uBOL-home/issues/518 --- .../mv3/extension/js/scripting-manager.js | 6 +- .../mv3/extension/js/scripting/css-api.js | 33 ++++++++++ .../mv3/extension/js/scripting/css-generic.js | 12 +--- .../js/scripting/css-procedural-api.js | 10 +-- .../extension/js/scripting/css-procedural.js | 6 +- .../extension/js/scripting/css-specific.js | 6 +- platform/mv3/safari/css-api.js | 46 ++++++++++++++ platform/mv3/safari/css-user.js | 62 +++++++++++++++++++ tools/make-mv3.sh | 2 + 9 files changed, 150 insertions(+), 33 deletions(-) create mode 100644 platform/mv3/extension/js/scripting/css-api.js create mode 100644 platform/mv3/safari/css-api.js create mode 100644 platform/mv3/safari/css-user.js diff --git a/platform/mv3/extension/js/scripting-manager.js b/platform/mv3/extension/js/scripting-manager.js index 9a899aafd..78200d47b 100644 --- a/platform/mv3/extension/js/scripting-manager.js +++ b/platform/mv3/extension/js/scripting-manager.js @@ -194,7 +194,7 @@ function registerGeneric(context, genericDetails) { if ( js.length === 0 ) { return; } - js.unshift('/js/scripting/isolated-api.js'); + js.unshift('/js/scripting/css-api.js', '/js/scripting/isolated-api.js'); js.push('/js/scripting/css-generic.js'); const { none, basic, optimal, complete } = filteringModeDetails; @@ -306,7 +306,7 @@ function registerProcedural(context) { normalizeMatches(matches); - js.unshift('/js/scripting/isolated-api.js'); + js.unshift('/js/scripting/css-api.js', '/js/scripting/isolated-api.js'); js.push('/js/scripting/css-procedural.js'); const excludeMatches = []; @@ -373,7 +373,7 @@ function registerSpecific(context) { normalizeMatches(matches); - js.unshift('/js/scripting/isolated-api.js'); + js.unshift('/js/scripting/css-api.js', '/js/scripting/isolated-api.js'); js.push('/js/scripting/css-specific.js'); const excludeMatches = []; diff --git a/platform/mv3/extension/js/scripting/css-api.js b/platform/mv3/extension/js/scripting/css-api.js new file mode 100644 index 000000000..13f322d11 --- /dev/null +++ b/platform/mv3/extension/js/scripting/css-api.js @@ -0,0 +1,33 @@ +/******************************************************************************* + + uBlock Origin Lite - a comprehensive, MV3-compliant content blocker + Copyright (C) 2025-present Raymond Hill + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see {http://www.gnu.org/licenses/}. + + Home: https://github.com/gorhill/uBlock +*/ + +(api => { + if ( typeof api === 'object' ) { return; } + self.cssAPI = { + insert(css) { + chrome.runtime.sendMessage({ + what: 'insertCSS', + css, + }).catch(( ) => { + }); + }, + }; +})(self.cssAPI); diff --git a/platform/mv3/extension/js/scripting/css-generic.js b/platform/mv3/extension/js/scripting/css-generic.js index 6891aecf0..52c3781a2 100644 --- a/platform/mv3/extension/js/scripting/css-generic.js +++ b/platform/mv3/extension/js/scripting/css-generic.js @@ -188,7 +188,7 @@ const uBOL_processNodes = ( ) => { if ( styleSheetTimer !== undefined ) { return; } styleSheetTimer = self.requestAnimationFrame(( ) => { styleSheetTimer = undefined; - uBOL_injectCSS(`${styleSheetSelectors.join(',')}{display:none!important;}`); + self.cssAPI.insert(`${styleSheetSelectors.join(',')}{display:none!important;}`); styleSheetSelectors.length = 0; }); }; @@ -214,16 +214,6 @@ const uBOL_processChanges = mutations => { /******************************************************************************/ -const uBOL_injectCSS = css => { - chrome.runtime.sendMessage({ - what: 'insertCSS', - css, - }).catch(( ) => { - }); -}; - -/******************************************************************************/ - const stopAll = ( ) => { if ( domChangeTimer !== undefined ) { self.clearTimeout(domChangeTimer); diff --git a/platform/mv3/extension/js/scripting/css-procedural-api.js b/platform/mv3/extension/js/scripting/css-procedural-api.js index af3abf1e9..256e42720 100644 --- a/platform/mv3/extension/js/scripting/css-procedural-api.js +++ b/platform/mv3/extension/js/scripting/css-procedural-api.js @@ -29,14 +29,6 @@ if ( self.ProceduralFiltererAPI !== undefined ) { /******************************************************************************/ -const uBOL_injectCSS = css => { - chrome.runtime.sendMessage({ - what: 'insertCSS', - css, - }).catch(( ) => { - }); -}; - const nonVisualElements = { head: true, link: true, @@ -688,7 +680,7 @@ class ProceduralFilterer { if ( styleToken !== undefined ) { return styleToken; } styleToken = randomToken(); this.styleTokenMap.set(style, styleToken); - uBOL_injectCSS(`[${styleToken}]\n{${style}}\n`); + self.cssAPI.insert(`[${styleToken}]\n{${style}}\n`); return styleToken; } diff --git a/platform/mv3/extension/js/scripting/css-procedural.js b/platform/mv3/extension/js/scripting/css-procedural.js index 3e0b2600b..28c2d516b 100644 --- a/platform/mv3/extension/js/scripting/css-procedural.js +++ b/platform/mv3/extension/js/scripting/css-procedural.js @@ -103,11 +103,7 @@ if ( declaratives.length !== 0 ) { sheetText.push(ruleText); } if ( sheetText.length !== 0 ) { - chrome.runtime.sendMessage({ - what: 'insertCSS', - css: sheetText.join('\n'), - }).catch(( ) => { - }); + self.cssAPI.insert(sheetText.join('\n')); } } diff --git a/platform/mv3/extension/js/scripting/css-specific.js b/platform/mv3/extension/js/scripting/css-specific.js index eee90a04d..e0117e7c3 100644 --- a/platform/mv3/extension/js/scripting/css-specific.js +++ b/platform/mv3/extension/js/scripting/css-specific.js @@ -65,11 +65,7 @@ const exceptedSelectors = exceptions.length !== 0 : selectors; if ( exceptedSelectors.length === 0 ) { return; } -chrome.runtime.sendMessage({ - what: 'insertCSS', - css: `${exceptedSelectors.join(',')}{display:none!important;}`, -}).catch(( ) => { -}); +self.cssAPI.insert(`${exceptedSelectors.join(',')}{display:none!important;}`); /******************************************************************************/ diff --git a/platform/mv3/safari/css-api.js b/platform/mv3/safari/css-api.js new file mode 100644 index 000000000..e9b8817f4 --- /dev/null +++ b/platform/mv3/safari/css-api.js @@ -0,0 +1,46 @@ +/******************************************************************************* + + uBlock Origin Lite - a comprehensive, MV3-compliant content blocker + Copyright (C) 2025-present Raymond Hill + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see {http://www.gnu.org/licenses/}. + + Home: https://github.com/gorhill/uBlock +*/ + +(api => { + if ( typeof api === 'object' ) { return; } + + const inserted = new Set(); + + self.cssAPI = { + insert(css) { + chrome.runtime.sendMessage({ + what: 'insertCSS', + css, + }).catch(( ) => { + }); + inserted.add(css); + }, + }; + + self.addEventListener('pageshow', ( ) => { + chrome.runtime.sendMessage({ + what: 'insertCSS', + css: Array.from(inserted).join('\n'), + }).catch(( ) => { + }); + }); + +})(self.cssAPI); diff --git a/platform/mv3/safari/css-user.js b/platform/mv3/safari/css-user.js new file mode 100644 index 000000000..d994e4430 --- /dev/null +++ b/platform/mv3/safari/css-user.js @@ -0,0 +1,62 @@ +/******************************************************************************* + + uBlock Origin Lite - a comprehensive, MV3-compliant content blocker + Copyright (C) 2019-present Raymond Hill + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see {http://www.gnu.org/licenses/}. + + Home: https://github.com/gorhill/uBlock +*/ + +(async function uBOL_cssUser() { + +/******************************************************************************/ + +const docURL = new URL(document.baseURI); +const details = await chrome.runtime.sendMessage({ + what: 'injectCustomFilters', + hostname: docURL.hostname, +}).catch(( ) => { +}); + +if ( details?.proceduralSelectors?.length ) { + if ( self.ProceduralFiltererAPI ) { + self.customProceduralFiltererAPI = new self.ProceduralFiltererAPI(); + self.customProceduralFiltererAPI.addSelectors( + details.proceduralSelectors.map(a => JSON.parse(a)) + ); + } +} + +const inserted = new Set(); + +if ( Array.isArray(details?.plainSelectors) ) { + inserted.add(`${details.plainSelectors.join(',\n')}{display:none!important;}`); +} + +self.addEventListener('pageshow', ( ) => { + chrome.runtime.sendMessage({ + what: 'insertCSS', + css: Array.from(inserted).join('\n'), + }).catch(( ) => { + }); +}); + +self.customFilters = details; + +/******************************************************************************/ + +})(); + +void 0; diff --git a/tools/make-mv3.sh b/tools/make-mv3.sh index 8f850f22b..403ad7e66 100755 --- a/tools/make-mv3.sh +++ b/tools/make-mv3.sh @@ -101,6 +101,8 @@ cp platform/mv3/extension/*.json "$UBOL_DIR"/ cp platform/mv3/extension/css/* "$UBOL_DIR"/css/ cp -R platform/mv3/extension/js/* "$UBOL_DIR"/js/ cp platform/mv3/"$PLATFORM"/ext-compat.js "$UBOL_DIR"/js/ 2>/dev/null || : +cp platform/mv3/"$PLATFORM"/css-api.js "$UBOL_DIR"/js/scripting/ 2>/dev/null || : +cp platform/mv3/"$PLATFORM"/css-user.js "$UBOL_DIR"/js/scripting/ 2>/dev/null || : cp platform/mv3/extension/img/* "$UBOL_DIR"/img/ cp platform/mv3/"$PLATFORM"/img/* "$UBOL_DIR"/img/ 2>/dev/null || : cp -R platform/mv3/extension/_locales "$UBOL_DIR"/