Add `elements` vararg to `prevent-addEventListener` scriptlet

If present, `elements` vararg must be a valid CSS selector, which will
be used to apply the scriptlet to only elements matching the
selector.

Related issue:
https://github.com/uBlockOrigin/uBlock-issues/issues/3061

Example of usage:

[...]##+js(aeld, click, return"undefined", elements, a.indirect)
This commit is contained in:
Raymond Hill 2024-01-10 12:46:23 -05:00
parent a9eb9630cf
commit 060f9d68fc
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
1 changed files with 18 additions and 11 deletions

View File

@ -1476,6 +1476,23 @@ function addEventListenerDefuser(
const rePattern = safe.patternToRegex(pattern); const rePattern = safe.patternToRegex(pattern);
const log = shouldLog(extraArgs); const log = shouldLog(extraArgs);
const debug = shouldDebug(extraArgs); const debug = shouldDebug(extraArgs);
const targetElements = extraArgs.elements || undefined;
const shouldPrevent = (thisArg, type, handler) => {
const matchesInstance = targetElements === undefined ||
Array.from(document.querySelectorAll(targetElements)).includes(thisArg);
if ( matchesInstance === false ) { return false; }
const matchesType = safe.RegExp_test.call(reType, type);
const matchesHandler = safe.RegExp_test.call(rePattern, handler);
const matchesEither = matchesType || matchesHandler;
const matchesBoth = matchesType && matchesHandler;
if ( log === 1 && matchesBoth || log === 2 && matchesEither || log === 3 ) {
safe.uboLog(`addEventListener('${type}', ${handler})`);
}
if ( debug === 1 && matchesBoth || debug === 2 && matchesEither ) {
debugger; // jshint ignore:line
}
return matchesBoth;
};
const trapEddEventListeners = ( ) => { const trapEddEventListeners = ( ) => {
const eventListenerHandler = { const eventListenerHandler = {
apply: function(target, thisArg, args) { apply: function(target, thisArg, args) {
@ -1487,17 +1504,7 @@ function addEventListenerDefuser(
: String(args[1]); : String(args[1]);
} catch(ex) { } catch(ex) {
} }
const matchesType = safe.RegExp_test.call(reType, type); if ( shouldPrevent(thisArg, type, handler) ) { return; }
const matchesHandler = safe.RegExp_test.call(rePattern, handler);
const matchesEither = matchesType || matchesHandler;
const matchesBoth = matchesType && matchesHandler;
if ( log === 1 && matchesBoth || log === 2 && matchesEither || log === 3 ) {
safe.uboLog(`addEventListener('${type}', ${handler})`);
}
if ( debug === 1 && matchesBoth || debug === 2 && matchesEither ) {
debugger; // jshint ignore:line
}
if ( matchesBoth ) { return; }
return Reflect.apply(target, thisArg, args); return Reflect.apply(target, thisArg, args);
}, },
get(target, prop, receiver) { get(target, prop, receiver) {