mirror of
https://git.axenov.dev/mirrors/cursor-free-vip.git
synced 2026-01-05 02:01:30 +03:00
Big Change Update
This commit is contained in:
365
uBlock0.chromium/js/scriptlets/cosmetic-logger.js
Normal file
365
uBlock0.chromium/js/scriptlets/cosmetic-logger.js
Normal file
@@ -0,0 +1,365 @@
|
||||
/*******************************************************************************
|
||||
|
||||
uBlock Origin - a comprehensive, efficient content blocker
|
||||
Copyright (C) 2015-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
|
||||
*/
|
||||
|
||||
/* globals browser */
|
||||
|
||||
'use strict';
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
(( ) => {
|
||||
// >>>>>>>> start of private namespace
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
if ( typeof vAPI !== 'object' ) { return; }
|
||||
if ( vAPI.domWatcher instanceof Object === false ) { return; }
|
||||
|
||||
const reHasCSSCombinators = /[ >+~]/;
|
||||
const simpleDeclarativeSet = new Set();
|
||||
let simpleDeclarativeStr;
|
||||
const complexDeclarativeSet = new Set();
|
||||
let complexDeclarativeStr;
|
||||
const proceduralDict = new Map();
|
||||
const exceptionDict = new Map();
|
||||
let exceptionStr;
|
||||
const proceduralExceptionDict = new Map();
|
||||
const nodesToProcess = new Set();
|
||||
const loggedSelectors = new Set();
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
const rePseudoElements = /:(?::?after|:?before|:[a-z-]+)$/;
|
||||
|
||||
function hasSelector(selector, context = document) {
|
||||
try {
|
||||
return context.querySelector(selector) !== null;
|
||||
}
|
||||
catch(ex) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function safeMatchSelector(selector, context) {
|
||||
const safeSelector = rePseudoElements.test(selector)
|
||||
? selector.replace(rePseudoElements, '')
|
||||
: selector;
|
||||
try {
|
||||
return context.matches(safeSelector);
|
||||
}
|
||||
catch(ex) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function safeQuerySelector(selector, context = document) {
|
||||
const safeSelector = rePseudoElements.test(selector)
|
||||
? selector.replace(rePseudoElements, '')
|
||||
: selector;
|
||||
try {
|
||||
return context.querySelector(safeSelector);
|
||||
}
|
||||
catch(ex) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function safeGroupSelectors(selectors) {
|
||||
const arr = Array.isArray(selectors)
|
||||
? selectors
|
||||
: Array.from(selectors);
|
||||
return arr.map(s => {
|
||||
return rePseudoElements.test(s)
|
||||
? s.replace(rePseudoElements, '')
|
||||
: s;
|
||||
}).join(',\n');
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
function processDeclarativeSimple(node, out) {
|
||||
if ( simpleDeclarativeSet.size === 0 ) { return; }
|
||||
if ( simpleDeclarativeStr === undefined ) {
|
||||
simpleDeclarativeStr = safeGroupSelectors(simpleDeclarativeSet);
|
||||
}
|
||||
if (
|
||||
(node === document || node.matches(simpleDeclarativeStr) === false) &&
|
||||
(hasSelector(simpleDeclarativeStr, node) === false)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
for ( const selector of simpleDeclarativeSet ) {
|
||||
if (
|
||||
(node === document || safeMatchSelector(selector, node) === false) &&
|
||||
(safeQuerySelector(selector, node) === null)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
out.push(`##${selector}`);
|
||||
simpleDeclarativeSet.delete(selector);
|
||||
simpleDeclarativeStr = undefined;
|
||||
loggedSelectors.add(selector);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
function processDeclarativeComplex(out) {
|
||||
if ( complexDeclarativeSet.size === 0 ) { return; }
|
||||
if ( complexDeclarativeStr === undefined ) {
|
||||
complexDeclarativeStr = safeGroupSelectors(complexDeclarativeSet);
|
||||
}
|
||||
if ( hasSelector(complexDeclarativeStr) === false ) { return; }
|
||||
for ( const selector of complexDeclarativeSet ) {
|
||||
if ( safeQuerySelector(selector) === null ) { continue; }
|
||||
out.push(`##${selector}`);
|
||||
complexDeclarativeSet.delete(selector);
|
||||
complexDeclarativeStr = undefined;
|
||||
loggedSelectors.add(selector);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
function processProcedural(out) {
|
||||
if ( proceduralDict.size === 0 ) { return; }
|
||||
for ( const [ raw, pselector ] of proceduralDict ) {
|
||||
if ( pselector.converted ) {
|
||||
if ( safeQuerySelector(pselector.selector) === null ) { continue; }
|
||||
} else if ( pselector.hit === false && pselector.exec().length === 0 ) {
|
||||
continue;
|
||||
}
|
||||
out.push(`##${raw}`);
|
||||
proceduralDict.delete(raw);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
function processExceptions(out) {
|
||||
if ( exceptionDict.size === 0 ) { return; }
|
||||
if ( exceptionStr === undefined ) {
|
||||
exceptionStr = safeGroupSelectors(exceptionDict.keys());
|
||||
}
|
||||
if ( hasSelector(exceptionStr) === false ) { return; }
|
||||
for ( const [ selector, raw ] of exceptionDict ) {
|
||||
if ( safeQuerySelector(selector) === null ) { continue; }
|
||||
out.push(`#@#${raw}`);
|
||||
exceptionDict.delete(selector);
|
||||
exceptionStr = undefined;
|
||||
loggedSelectors.add(raw);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
function processProceduralExceptions(out) {
|
||||
if ( proceduralExceptionDict.size === 0 ) { return; }
|
||||
for ( const exception of proceduralExceptionDict.values() ) {
|
||||
if ( exception.test() === false ) { continue; }
|
||||
out.push(`#@#${exception.raw}`);
|
||||
proceduralExceptionDict.delete(exception.raw);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
const processTimer = new vAPI.SafeAnimationFrame(( ) => {
|
||||
//console.time('dom logger/scanning for matches');
|
||||
processTimer.clear();
|
||||
if ( nodesToProcess.size === 0 ) { return; }
|
||||
|
||||
if ( nodesToProcess.size !== 1 && nodesToProcess.has(document) ) {
|
||||
nodesToProcess.clear();
|
||||
nodesToProcess.add(document);
|
||||
}
|
||||
|
||||
const toLog = [];
|
||||
if ( simpleDeclarativeSet.size !== 0 ) {
|
||||
for ( const node of nodesToProcess ) {
|
||||
processDeclarativeSimple(node, toLog);
|
||||
}
|
||||
}
|
||||
|
||||
processDeclarativeComplex(toLog);
|
||||
processProcedural(toLog);
|
||||
processExceptions(toLog);
|
||||
processProceduralExceptions(toLog);
|
||||
|
||||
nodesToProcess.clear();
|
||||
|
||||
if ( toLog.length === 0 ) { return; }
|
||||
|
||||
const location = vAPI.effectiveSelf.location;
|
||||
|
||||
vAPI.messaging.send('scriptlets', {
|
||||
what: 'logCosmeticFilteringData',
|
||||
frameURL: location.href,
|
||||
frameHostname: location.hostname,
|
||||
matchedSelectors: toLog,
|
||||
});
|
||||
//console.timeEnd('dom logger/scanning for matches');
|
||||
});
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
const attributeObserver = new MutationObserver(mutations => {
|
||||
if ( nodesToProcess.has(document) ) { return; }
|
||||
for ( const mutation of mutations ) {
|
||||
const node = mutation.target;
|
||||
if ( node.nodeType !== 1 ) { continue; }
|
||||
nodesToProcess.add(node);
|
||||
}
|
||||
if ( nodesToProcess.size !== 0 ) {
|
||||
processTimer.start(100);
|
||||
}
|
||||
});
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
const handlers = {
|
||||
onFiltersetChanged: function(changes) {
|
||||
//console.time('dom logger/filterset changed');
|
||||
for ( const block of (changes.declarative || []) ) {
|
||||
for ( const selector of block.split(',\n') ) {
|
||||
if ( loggedSelectors.has(selector) ) { continue; }
|
||||
if ( reHasCSSCombinators.test(selector) ) {
|
||||
complexDeclarativeSet.add(selector);
|
||||
complexDeclarativeStr = undefined;
|
||||
} else {
|
||||
simpleDeclarativeSet.add(selector);
|
||||
simpleDeclarativeStr = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (
|
||||
Array.isArray(changes.procedural) &&
|
||||
changes.procedural.length !== 0
|
||||
) {
|
||||
for ( const selector of changes.procedural ) {
|
||||
proceduralDict.set(selector.raw, selector);
|
||||
}
|
||||
}
|
||||
if ( Array.isArray(changes.exceptions) ) {
|
||||
for ( const selector of changes.exceptions ) {
|
||||
if ( loggedSelectors.has(selector) ) { continue; }
|
||||
if ( selector.charCodeAt(0) !== 0x7B /* '{' */ ) {
|
||||
exceptionDict.set(selector, selector);
|
||||
continue;
|
||||
}
|
||||
const details = JSON.parse(selector);
|
||||
if (
|
||||
details.action !== undefined &&
|
||||
details.tasks === undefined &&
|
||||
details.action[0] === 'style'
|
||||
) {
|
||||
exceptionDict.set(details.selector, details.raw);
|
||||
continue;
|
||||
}
|
||||
proceduralExceptionDict.set(
|
||||
details.raw,
|
||||
vAPI.domFilterer.createProceduralFilter(details)
|
||||
);
|
||||
}
|
||||
exceptionStr = undefined;
|
||||
}
|
||||
nodesToProcess.clear();
|
||||
nodesToProcess.add(document);
|
||||
processTimer.start(1);
|
||||
//console.timeEnd('dom logger/filterset changed');
|
||||
},
|
||||
|
||||
onDOMCreated: function() {
|
||||
if ( vAPI.domFilterer instanceof Object === false ) {
|
||||
return shutdown();
|
||||
}
|
||||
handlers.onFiltersetChanged(vAPI.domFilterer.getAllSelectors());
|
||||
vAPI.domFilterer.addListener(handlers);
|
||||
attributeObserver.observe(document.body, {
|
||||
attributes: true,
|
||||
subtree: true
|
||||
});
|
||||
},
|
||||
|
||||
onDOMChanged: function(addedNodes) {
|
||||
if ( nodesToProcess.has(document) ) { return; }
|
||||
for ( const node of addedNodes ) {
|
||||
if ( node.parentNode === null ) { continue; }
|
||||
nodesToProcess.add(node);
|
||||
}
|
||||
if ( nodesToProcess.size !== 0 ) {
|
||||
processTimer.start(100);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
vAPI.domWatcher.addListener(handlers);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
const broadcastHandler = msg => {
|
||||
if ( msg.what === 'loggerDisabled' ) {
|
||||
shutdown();
|
||||
}
|
||||
};
|
||||
|
||||
browser.runtime.onMessage.addListener(broadcastHandler);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
function shutdown() {
|
||||
browser.runtime.onMessage.removeListener(broadcastHandler);
|
||||
processTimer.clear();
|
||||
attributeObserver.disconnect();
|
||||
if ( typeof vAPI !== 'object' ) { return; }
|
||||
if ( vAPI.domFilterer instanceof Object ) {
|
||||
vAPI.domFilterer.removeListener(handlers);
|
||||
}
|
||||
if ( vAPI.domWatcher instanceof Object ) {
|
||||
vAPI.domWatcher.removeListener(handlers);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// <<<<<<<< end of private namespace
|
||||
})();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
DO NOT:
|
||||
- Remove the following code
|
||||
- Add code beyond the following code
|
||||
Reason:
|
||||
- https://github.com/gorhill/uBlock/pull/3721
|
||||
- uBO never uses the return value from injected content scripts
|
||||
|
||||
**/
|
||||
|
||||
void 0;
|
||||
|
||||
Reference in New Issue
Block a user