Improve `remove-class` behavior

Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/2750
This commit is contained in:
Raymond Hill 2023-07-24 07:33:33 -04:00
parent c23a9ada33
commit fa489fdb87
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
1 changed files with 10 additions and 6 deletions

View File

@ -1476,6 +1476,7 @@ builtinScriptlets.push({
'rc.js', 'rc.js',
], ],
fn: removeClass, fn: removeClass,
world: 'ISOLATED',
dependencies: [ dependencies: [
'run-at.fn', 'run-at.fn',
], ],
@ -1487,20 +1488,24 @@ function removeClass(
) { ) {
if ( typeof token !== 'string' ) { return; } if ( typeof token !== 'string' ) { return; }
if ( token === '' ) { return; } if ( token === '' ) { return; }
const tokens = token.split(/\s*\|\s*/); const classTokens = token.split(/\s*\|\s*/);
if ( selector === '' ) { if ( selector === '' ) {
selector = '.' + tokens.map(a => CSS.escape(a)).join(',.'); selector = '.' + classTokens.map(a => CSS.escape(a)).join(',.');
} }
const mustStay = /\bstay\b/.test(behavior);
let timer; let timer;
const rmclass = function() { const rmclass = function() {
timer = undefined; timer = undefined;
try { try {
const nodes = document.querySelectorAll(selector); const nodes = document.querySelectorAll(selector);
for ( const node of nodes ) { for ( const node of nodes ) {
node.classList.remove(...tokens); node.classList.remove(...classTokens);
} }
} catch(ex) { } catch(ex) {
} }
if ( mustStay ) { return; }
if ( document.readyState !== 'complete' ) { return; }
observer.disconnect();
}; };
const mutationHandler = mutations => { const mutationHandler = mutations => {
if ( timer !== undefined ) { return; } if ( timer !== undefined ) { return; }
@ -1518,10 +1523,9 @@ function removeClass(
if ( skip ) { return; } if ( skip ) { return; }
timer = self.requestIdleCallback(rmclass, { timeout: 67 }); timer = self.requestIdleCallback(rmclass, { timeout: 67 });
}; };
const observer = new MutationObserver(mutationHandler);
const start = ( ) => { const start = ( ) => {
rmclass(); rmclass();
if ( /\bstay\b/.test(behavior) === false ) { return; }
const observer = new MutationObserver(mutationHandler);
observer.observe(document, { observer.observe(document, {
attributes: true, attributes: true,
attributeFilter: [ 'class' ], attributeFilter: [ 'class' ],
@ -1531,7 +1535,7 @@ function removeClass(
}; };
runAt(( ) => { runAt(( ) => {
start(); start();
}, /\bcomplete\b/.test(behavior) ? 'idle' : 'interactive'); }, /\bcomplete\b/.test(behavior) ? 'idle' : 'loading');
} }
/******************************************************************************/ /******************************************************************************/