mirror of
https://github.com/gorhill/uBlock.git
synced 2026-03-11 09:04:36 +00:00
[mv3] Mind id/class attribute changes in generic cosmetic filterer
Related issue: https://github.com/uBlockOrigin/uBlock-issues/issues/3904
This commit is contained in:
parent
00b79d9023
commit
c975fbb9d7
1 changed files with 29 additions and 20 deletions
|
|
@ -74,7 +74,7 @@ const hashFromStr = (type, s) => {
|
|||
// http://www.w3.org/TR/2014/REC-html5-20141028/infrastructure.html#space-separated-tokens
|
||||
// http://jsperf.com/enumerate-classes/6
|
||||
|
||||
const uBOL_idFromNode = (node, out) => {
|
||||
const uBOL_idFromNode = node => {
|
||||
const raw = node.id;
|
||||
if ( typeof raw !== 'string' || raw.length === 0 ) { return; }
|
||||
const hash = hashFromStr(0x23 /* '#' */, raw.trim());
|
||||
|
|
@ -82,15 +82,15 @@ const uBOL_idFromNode = (node, out) => {
|
|||
if ( selectorList === undefined ) { return; }
|
||||
genericSelectorMap.delete(hash);
|
||||
if ( genericExceptionSieve.has(hash) ) {
|
||||
applyExceptions(selectorList, out);
|
||||
applyExceptions(selectorList);
|
||||
} else {
|
||||
out.push(selectorList);
|
||||
styleSheetSelectors.push(selectorList);
|
||||
}
|
||||
};
|
||||
|
||||
// https://github.com/uBlockOrigin/uBlock-issues/discussions/2076
|
||||
// Performance: avoid using Element.classList
|
||||
const uBOL_classesFromNode = (node, out) => {
|
||||
const uBOL_classesFromNode = node => {
|
||||
const s = node.getAttribute('class');
|
||||
if ( typeof s !== 'string' ) { return; }
|
||||
const len = s.length;
|
||||
|
|
@ -106,14 +106,14 @@ const uBOL_classesFromNode = (node, out) => {
|
|||
if ( selectorList === undefined ) { continue; }
|
||||
genericSelectorMap.delete(hash);
|
||||
if ( genericExceptionSieve.has(hash) ) {
|
||||
applyExceptions(selectorList, out);
|
||||
applyExceptions(selectorList);
|
||||
} else {
|
||||
out.push(selectorList);
|
||||
styleSheetSelectors.push(selectorList);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const applyExceptions = (selectorList, out) => {
|
||||
const applyExceptions = selectorList => {
|
||||
const selectors = new Set(selectorList.split(',\n'));
|
||||
self.isolatedAPI.forEachHostname(hostname => {
|
||||
const exceptions = genericExceptionMap.get(hostname);
|
||||
|
|
@ -124,7 +124,7 @@ const applyExceptions = (selectorList, out) => {
|
|||
if ( selectors.size === 0 ) { return true; }
|
||||
}, { hasEntities: true });
|
||||
if ( selectors.size === 0 ) { return; }
|
||||
out.push(Array.from(selectors).join(',\n'));
|
||||
styleSheetSelectors.push(Array.from(selectors).join(',\n'));
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
@ -138,9 +138,7 @@ const pendingNodes = {
|
|||
next(out) {
|
||||
for ( const added of this.addedNodes ) {
|
||||
if ( this.nodeSet.has(added) ) { continue; }
|
||||
if ( added.nodeType === 1 ) {
|
||||
this.nodeSet.add(added);
|
||||
}
|
||||
this.nodeSet.add(added);
|
||||
if ( added.firstElementChild === null ) { continue; }
|
||||
for ( const descendant of added.querySelectorAll('[id],[class]') ) {
|
||||
this.nodeSet.add(descendant);
|
||||
|
|
@ -168,8 +166,8 @@ const uBOL_processNodes = ( ) => {
|
|||
pendingNodes.next(nodes);
|
||||
if ( nodes.length === 0 ) { break; }
|
||||
for ( const node of nodes ) {
|
||||
uBOL_idFromNode(node, styleSheetSelectors);
|
||||
uBOL_classesFromNode(node, styleSheetSelectors);
|
||||
uBOL_idFromNode(node);
|
||||
uBOL_classesFromNode(node);
|
||||
}
|
||||
nodes.length = 0;
|
||||
if ( performance.now() >= deadline ) { break; }
|
||||
|
|
@ -196,14 +194,22 @@ const uBOL_processNodes = ( ) => {
|
|||
/******************************************************************************/
|
||||
|
||||
const uBOL_processChanges = mutations => {
|
||||
for ( let i = 0; i < mutations.length; i++ ) {
|
||||
const mutation = mutations[i];
|
||||
for ( const added of mutation.addedNodes ) {
|
||||
if ( added.nodeType !== 1 ) { continue; }
|
||||
pendingNodes.add(added);
|
||||
for ( const mutation of mutations ) {
|
||||
if ( mutation.type === 'childList' ) {
|
||||
for ( const added of mutation.addedNodes ) {
|
||||
if ( added.nodeType !== 1 ) { continue; }
|
||||
if ( added.parentElement === null ) { continue; }
|
||||
pendingNodes.add(added);
|
||||
}
|
||||
} else if ( mutation.attributeName === 'class' ) {
|
||||
uBOL_classesFromNode(mutation.target);
|
||||
} else {
|
||||
uBOL_idFromNode(mutation.target);
|
||||
}
|
||||
}
|
||||
if ( pendingNodes.hasNodes() === false ) { return; }
|
||||
if ( pendingNodes.hasNodes() === false ) {
|
||||
if ( styleSheetSelectors.length === 0 ) { return; }
|
||||
}
|
||||
lastDomChange = Date.now();
|
||||
if ( processTimer !== undefined ) { return; }
|
||||
processTimer = self.setTimeout(( ) => {
|
||||
|
|
@ -227,11 +233,14 @@ const stopAll = ( ) => {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
pendingNodes.add(document);
|
||||
if ( document.documentElement === null ) { return; }
|
||||
pendingNodes.add(document.documentElement);
|
||||
uBOL_processNodes();
|
||||
|
||||
let domMutationObserver = new MutationObserver(uBOL_processChanges);
|
||||
domMutationObserver.observe(document, {
|
||||
attributeFilter: [ 'class', 'id' ],
|
||||
attributes: true,
|
||||
childList: true,
|
||||
subtree: true,
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue