From 060f9d68fc641d08642a42a3903ccc89634735dc Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Wed, 10 Jan 2024 12:46:23 -0500 Subject: [PATCH] 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) --- assets/resources/scriptlets.js | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/assets/resources/scriptlets.js b/assets/resources/scriptlets.js index 6e2654fc1dc4b..1e6dde27bad58 100644 --- a/assets/resources/scriptlets.js +++ b/assets/resources/scriptlets.js @@ -1476,6 +1476,23 @@ function addEventListenerDefuser( const rePattern = safe.patternToRegex(pattern); const log = shouldLog(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 eventListenerHandler = { apply: function(target, thisArg, args) { @@ -1487,17 +1504,7 @@ function addEventListenerDefuser( : String(args[1]); } catch(ex) { } - 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 - } - if ( matchesBoth ) { return; } + if ( shouldPrevent(thisArg, type, handler) ) { return; } return Reflect.apply(target, thisArg, args); }, get(target, prop, receiver) {