Support pruning by xpath in `xml-prune` scriptlet

Related issue:
- https://github.com/uBlockOrigin/uAssets/issues/18244
This commit is contained in:
Raymond Hill 2023-05-27 17:26:19 -04:00
parent 63273451c6
commit 8ed78cfb23
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
1 changed files with 29 additions and 1 deletions

View File

@ -1998,7 +1998,10 @@ builtinScriptlets.push({
name: 'xml-prune.js', name: 'xml-prune.js',
fn: xmlPrune, fn: xmlPrune,
dependencies: [ dependencies: [
'get-extra-args.fn',
'pattern-to-regex.fn', 'pattern-to-regex.fn',
'safe-self.fn',
'should-log.fn',
], ],
}); });
function xmlPrune( function xmlPrune(
@ -2009,15 +2012,40 @@ function xmlPrune(
if ( typeof selector !== 'string' ) { return; } if ( typeof selector !== 'string' ) { return; }
if ( selector === '' ) { return; } if ( selector === '' ) { return; }
const reUrl = patternToRegex(urlPattern); const reUrl = patternToRegex(urlPattern);
const extraArgs = getExtraArgs(Array.from(arguments), 3);
const log = shouldLog(extraArgs);
const queryAll = (xmlDoc, selector) => {
const isXpath = /^xpath\(.+\)$/.test(selector);
if ( isXpath === false ) {
return Array.from(xmlDoc.querySelectorAll(selector));
}
const xpr = xmlDoc.evaluate(
selector.slice(6, -1),
xmlDoc,
null,
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
null
);
const out = [];
for ( let i = 0; i < xpr.snapshotLength; i++ ) {
const node = xpr.snapshotItem(i);
if ( node.nodeType !== 1 ) { continue; }
out.push(node);
}
return out;
};
const pruneFromDoc = xmlDoc => { const pruneFromDoc = xmlDoc => {
try { try {
if ( selectorCheck !== '' && xmlDoc.querySelector(selectorCheck) === null ) { if ( selectorCheck !== '' && xmlDoc.querySelector(selectorCheck) === null ) {
return xmlDoc; return xmlDoc;
} }
const elems = xmlDoc.querySelectorAll(selector); const elems = queryAll(xmlDoc, selector);
if ( elems.length !== 0 ) { if ( elems.length !== 0 ) {
for ( const elem of elems ) { for ( const elem of elems ) {
elem.remove(); elem.remove();
if ( log ) {
safeSelf().uboLog(`xmlPrune: ${elem.nodeName} removed`);
}
} }
} }
} catch(ex) { } catch(ex) {