uBlock/platform/mv3/extension/js/scripting/css-procedural.js
Raymond Hill 0fb845d1ac
[mv3] Load specific cosmetic filtering data on-demand only
The cosmetic filtering data embedded in the content scripts has been
extracted in corresponding JSON files. When a list is enabled, the
corresponding cosmetic filtering data from the JSON files, if any, is
persisted into the extension's local storage.

The cosmetic filtering-related content scripts will load the data
from these JSON files on-demand only and matching cosmetic filters
will be extracted, then the result is cached in the session storage,
ensuring there is no longer a need to perform lookup for the rest
of the browser session.

As a result this further reduces the time to First Contentful Paint.

Related issue:
https://github.com/uBlockOrigin/uBOL-home/issues/557
2025-12-09 15:32:02 -05:00

105 lines
3.7 KiB
JavaScript

/*******************************************************************************
uBlock Origin Lite - a comprehensive, MV3-compliant content blocker
Copyright (C) 2014-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
*/
// Important!
// Isolate from global scope
(async function uBOL_cssProcedural() {
/******************************************************************************/
const proceduralImports = self.proceduralImports || [];
self.proceduralImports = undefined;
/******************************************************************************/
const selectors = await self.cosmeticAPI.getSelectors('procedural', proceduralImports);
self.cosmeticAPI.release();
if ( selectors.length === 0 ) { return; }
proceduralImports.length = 0;
const declaratives = selectors.filter(a => a.cssable);
if ( declaratives.length !== 0 ) {
const cssRuleFromProcedural = details => {
const { tasks, action } = details;
let mq, selector;
if ( Array.isArray(tasks) ) {
if ( tasks[0][0] !== 'matches-media' ) { return; }
mq = tasks[0][1];
if ( tasks.length > 2 ) { return; }
if ( tasks.length === 2 ) {
if ( tasks[1][0] !== 'spath' ) { return; }
selector = tasks[1][1];
}
}
let style;
if ( Array.isArray(action) ) {
if ( action[0] !== 'style' ) { return; }
selector = selector || details.selector;
style = action[1];
}
if ( mq === undefined && style === undefined && selector === undefined ) { return; }
if ( mq === undefined ) {
return `${selector}\n{${style}}`;
}
if ( style === undefined ) {
return `@media ${mq} {\n${selector}\n{display:none!important;}\n}`;
}
return `@media ${mq} {\n${selector}\n{${style}}\n}`;
};
const sheetText = [];
for ( const details of declaratives ) {
const ruleText = cssRuleFromProcedural(details);
if ( ruleText === undefined ) { continue; }
sheetText.push(ruleText);
}
if ( sheetText.length !== 0 ) {
self.cssAPI.insert(sheetText.join('\n'));
}
}
const procedurals = selectors.filter(a => a.cssable === undefined);
if ( procedurals.length !== 0 ) {
const addSelectors = selectors => {
if ( self.listsProceduralFiltererAPI instanceof Object === false ) { return; }
self.listsProceduralFiltererAPI.addSelectors(selectors);
};
if ( self.ProceduralFiltererAPI === undefined ) {
self.ProceduralFiltererAPI = chrome.runtime.sendMessage({
what: 'injectCSSProceduralAPI'
}).catch(( ) => {
});
}
if ( self.ProceduralFiltererAPI instanceof Promise ) {
self.ProceduralFiltererAPI.then(( ) => {
self.listsProceduralFiltererAPI = new self.ProceduralFiltererAPI();
addSelectors(procedurals);
});
} else {
addSelectors(procedurals);
}
}
/******************************************************************************/
})();
void 0;