Support shadow-piercing combinator `>>>` in `trusted-click-element`

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

Example usage:

...##+js(trusted-trusted-click-element, #cmpwrapper >>> .cmpboxbtnyes)

The substring before ` >>> ` must select an element with a non-null
shadow root, in which case the substring after ` >>> ` will be used
to find the element in the targeted shadow root. ` >>> ` can be used
recursively when multiple shadow root must be pierced.
This commit is contained in:
Raymond Hill 2023-12-04 08:02:07 -05:00
parent f15f1b3937
commit 941077a25c
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
1 changed files with 13 additions and 2 deletions

View File

@ -4077,10 +4077,21 @@ function trustedClickElement(
? ((...args) => { safe.uboLog(...args); }) ? ((...args) => { safe.uboLog(...args); })
: (( ) => { }); : (( ) => { });
const querySelectorEx = (selector, context = document) => {
const pos = selector.indexOf(' >>> ');
if ( pos === -1 ) { return context.querySelector(selector); }
const outside = selector.slice(0, pos).trim();
const inside = selector.slice(pos + 5).trim();
const elem = context.querySelector(outside);
if ( elem === null ) { return null; }
const shadowRoot = elem.shadowRoot;
return shadowRoot && querySelectorEx(inside, shadowRoot);
};
const selectorList = selectors.split(/\s*,\s*/) const selectorList = selectors.split(/\s*,\s*/)
.filter(s => { .filter(s => {
try { try {
void document.querySelector(s); void querySelectorEx(s);
} catch(_) { } catch(_) {
return false; return false;
} }
@ -4154,7 +4165,7 @@ function trustedClickElement(
if ( Date.now() < tnext ) { return next(); } if ( Date.now() < tnext ) { return next(); }
const selector = selectorList.shift(); const selector = selectorList.shift();
if ( selector === undefined ) { return terminate(); } if ( selector === undefined ) { return terminate(); }
const elem = document.querySelector(selector); const elem = querySelectorEx(selector);
if ( elem === null ) { if ( elem === null ) {
selectorList.unshift(selector); selectorList.unshift(selector);
return next(true); return next(true);