Skip to content

Commit

Permalink
Improve prevent-addEventListener scriptlet
Browse files Browse the repository at this point in the history
  • Loading branch information
gorhill committed Feb 14, 2024
1 parent 068b625 commit b22b3d7
Showing 1 changed file with 37 additions and 10 deletions.
47 changes: 37 additions & 10 deletions assets/resources/scriptlets.js
Original file line number Diff line number Diff line change
Expand Up @@ -1587,24 +1587,45 @@ function addEventListenerDefuser(
pattern = ''
) {
const safe = safeSelf();
const logPrefix = safe.makeLogPrefix('prevent-addEventListener', type, pattern);
const extraArgs = safe.getExtraArgs(Array.from(arguments), 2);
const logPrefix = safe.makeLogPrefix('prevent-addEventListener', type, pattern);
const reType = safe.patternToRegex(type, undefined, true);
const rePattern = safe.patternToRegex(pattern);
const debug = shouldDebug(extraArgs);
const targetSelector = extraArgs.elements || undefined;
const shouldPrevent = (thisArg, type, handler) => {
if ( targetSelector !== undefined ) {
const elems = Array.from(document.querySelectorAll(targetSelector));
if ( elems.includes(thisArg) === false ) { return false; }
const elementMatches = elem => {
if ( elem && elem.matches && elem.matches(targetSelector) ) { return true; }
const elems = Array.from(document.querySelectorAll(targetSelector));
return elems.includes(elem);
};
const elementDetails = elem => {
if ( elem instanceof Window ) { return 'window'; }
if ( elem instanceof Document ) { return 'document'; }
if ( elem instanceof Element === false ) { return '?'; }
const parts = [];
if ( elem.id !== '' ) { parts.push(`#${CSS.escape(elem.id)}`); }
for ( let i = 0; i < elem.classList.length; i++ ) {
parts.push(`.${CSS.escape(elem.classList.item(i))}`);
}
for ( let i = 0; i < elem.attributes.length; i++ ) {
const attr = elem.attributes.item(i);
if ( attr.name === 'id' ) { continue; }
if ( attr.name === 'class' ) { continue; }
parts.push(`[${CSS.escape(attr.name)}="${attr.value}"]`);
}
return parts.join('');
};
const shouldPrevent = (thisArg, type, handler) => {
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 ( debug === 1 && matchesBoth || debug === 2 && matchesEither ) {
debugger; // jshint ignore:line
}
if ( matchesBoth && targetSelector !== undefined ) {
if ( elementMatches(thisArg) === false ) { return false; }
}
return matchesBoth;
};
const trapEddEventListeners = ( ) => {
Expand All @@ -1613,15 +1634,21 @@ function addEventListenerDefuser(
let t, h;
try {
t = String(args[0]);
h = args[1] instanceof Function
? String(safe.Function_toString(args[1]))
: String(args[1]);
if ( typeof args[1] === 'function' ) {
h = String(safe.Function_toString(args[1]));
} else if ( typeof args[1] === 'object' && args[1] !== null ) {
if ( typeof args[1].handleEvent === 'function' ) {
h = String(safe.Function_toString(args[1].handleEvent));
}
} else {
h = String(args[1]);
}
} catch(ex) {
}
if ( type === '' && pattern === '' ) {
safe.uboLog(logPrefix, `Called: ${t}\n${h}`);
safe.uboLog(logPrefix, `Called: ${t}\n${h}\n${elementDetails(thisArg)}`);
} else if ( shouldPrevent(thisArg, t, h) ) {
return safe.uboLog(logPrefix, `Prevented: ${t}\n${h}`);
return safe.uboLog(logPrefix, `Prevented: ${t}\n${h}\n${elementDetails(thisArg)}`);
}
return Reflect.apply(target, thisArg, args);
},
Expand Down

0 comments on commit b22b3d7

Please sign in to comment.