From d3fae27017a1ce65fcba35ef7ca59b6a22ad2bde Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Sat, 27 May 2023 09:14:19 -0400 Subject: [PATCH] Add support for xhr in xml-prune Related issue: - https://github.com/uBlockOrigin/uAssets/issues/18244 --- assets/resources/scriptlets.js | 51 +++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/assets/resources/scriptlets.js b/assets/resources/scriptlets.js index c55f627c63376..d645ebe19e032 100644 --- a/assets/resources/scriptlets.js +++ b/assets/resources/scriptlets.js @@ -2009,26 +2009,33 @@ function xmlPrune( if ( typeof selector !== 'string' ) { return; } if ( selector === '' ) { return; } const reUrl = patternToRegex(urlPattern); - const pruner = text => { - if ( (/^\s*\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*\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); + } + }); } /******************************************************************************/