Add support for xhr in xml-prune

Related issue:
- https://github.com/uBlockOrigin/uAssets/issues/18244
This commit is contained in:
Raymond Hill 2023-05-27 09:14:19 -04:00
parent ea15cef524
commit d3fae27017
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
1 changed files with 41 additions and 10 deletions

View File

@ -2009,26 +2009,33 @@ function xmlPrune(
if ( typeof selector !== 'string' ) { return; }
if ( selector === '' ) { return; }
const reUrl = patternToRegex(urlPattern);
const pruner = text => {
if ( (/^\s*</.test(text) && />\s*$/.test(text)) === false ) {
return text;
}
const pruneFromDoc = xmlDoc => {
try {
const xmlParser = new DOMParser();
const xmlDoc = xmlParser.parseFromString(text, 'text/xml');
if ( selectorCheck !== '' && xmlDoc.querySelector(selectorCheck) === null ) {
return text;
return xmlDoc;
}
const elems = xmlDoc.querySelectorAll(selector);
if ( elems.length !== 0 ) {
for ( const elem of elems ) {
elem.remove();
}
const serializer = new XMLSerializer();
text = serializer.serializeToString(xmlDoc);
}
} catch(ex) {
}
return xmlDoc;
};
const pruneFromText = text => {
if ( (/^\s*</.test(text) && />\s*$/.test(text)) === false ) {
return text;
}
try {
const xmlParser = new DOMParser();
const xmlDoc = xmlParser.parseFromString(text, 'text/xml');
pruneFromDoc(xmlDoc);
const serializer = new XMLSerializer();
text = serializer.serializeToString(xmlDoc);
} catch(ex) {
}
return text;
};
const urlFromArg = arg => {
@ -2044,7 +2051,7 @@ function xmlPrune(
}
return realFetch(...args).then(realResponse =>
realResponse.text().then(text =>
new Response(pruner(text), {
new Response(pruneFromText(text), {
status: realResponse.status,
statusText: realResponse.statusText,
headers: realResponse.headers,
@ -2053,6 +2060,30 @@ function xmlPrune(
);
}
});
self.XMLHttpRequest.prototype.open = new Proxy(self.XMLHttpRequest.prototype.open, {
apply: async (target, thisArg, args) => {
if ( reUrl.test(urlFromArg(args[1])) === false ) {
return Reflect.apply(target, thisArg, args);
}
thisArg.addEventListener('readystatechange', function() {
if ( thisArg.readyState !== 4 ) { return; }
const type = thisArg.responseType;
if ( type === 'text' ) {
const textin = thisArg.responseText;
const textout = pruneFromText(textin);
if ( textout === textin ) { return; }
Object.defineProperty(thisArg, 'response', { value: textout });
Object.defineProperty(thisArg, 'responseText', { value: textout });
return;
}
if ( type === 'document' ) {
pruneFromDoc(thisArg.response);
return;
}
});
return Reflect.apply(target, thisArg, args);
}
});
}
/******************************************************************************/