1
0
mirror of https://github.com/gorhill/uBlock.git synced 2024-10-04 08:37:11 +02:00

Change approach to ...-xhr-response scriptlets

Related commit:
3152896d42
This commit is contained in:
Raymond Hill 2023-09-05 14:11:33 -04:00
parent 0f82471ee2
commit abe41034f6
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2

View File

@ -1344,11 +1344,10 @@ function jsonPruneXhrResponse(
const propNeedles = parsePropertiesToMatch(extraArgs.propsToMatch, 'url'); const propNeedles = parsePropertiesToMatch(extraArgs.propsToMatch, 'url');
self.XMLHttpRequest = class extends self.XMLHttpRequest { self.XMLHttpRequest = class extends self.XMLHttpRequest {
open(method, url, ...args) { open(method, url, ...args) {
const outerXhr = this; const xhrDetails = { method, url };
const xhrDetails = { method, url, args: [ ...args ] };
let outcome = 'match'; let outcome = 'match';
if ( propNeedles.size !== 0 ) { if ( propNeedles.size !== 0 ) {
if ( matchObjectProperties(propNeedles, { method, url }) === false ) { if ( matchObjectProperties(propNeedles, xhrDetails) === false ) {
outcome = 'nomatch'; outcome = 'nomatch';
} }
} }
@ -1356,72 +1355,35 @@ function jsonPruneXhrResponse(
log(`xhr.open(${method}, ${url}, ${args.join(', ')})`); log(`xhr.open(${method}, ${url}, ${args.join(', ')})`);
} }
if ( outcome === 'match' ) { if ( outcome === 'match' ) {
xhrInstances.set(outerXhr, xhrDetails); xhrInstances.set(this, xhrDetails);
} }
return super.open(method, url, ...args); return super.open(method, url, ...args);
} }
send(...args) { get response() {
const outerXhr = this; const innerResponse = super.response;
const xhrDetails = xhrInstances.get(outerXhr); const xhrDetails = xhrInstances.get(this);
if ( xhrDetails === undefined ) { if ( xhrDetails === undefined ) {
return super.send(...args); return innerResponse;
} }
switch ( outerXhr.responseType ) { if ( typeof innerResponse !== 'object' ) {
case '': xhrDetails.response = innerResponse;
case 'json':
case 'text':
break;
default:
return super.send(...args);
} }
const innerXhr = new safe.XMLHttpRequest(); let outerResponse = xhrDetails.response;
innerXhr.open(xhrDetails.method, xhrDetails.url, ...xhrDetails.args); if ( outerResponse !== undefined ) {
innerXhr.responseType = outerXhr.responseType; return outerResponse;
innerXhr.onloadend = function() {
let objBefore;
switch ( outerXhr.responseType ) {
case '':
case 'text':
try {
objBefore = safe.jsonParse(innerXhr.responseText);
} catch(ex) {
} }
break; outerResponse = objectPrune(
case 'json': innerResponse,
objBefore = innerXhr.response;
break;
default:
break;
}
let objAfter;
if ( typeof objBefore === 'object' ) {
objAfter = objectPrune(
objBefore,
rawPrunePaths, rawPrunePaths,
rawNeedlePaths, rawNeedlePaths,
{ matchAll: true }, { matchAll: true },
extraArgs extraArgs
); );
if ( typeof outerResponse !== 'object' ) {
outerResponse = innerResponse;
} }
let response = objAfter || objBefore; xhrDetails.response = outerResponse;
let responseText = ''; return outerResponse;
if ( typeof response === 'object' && outerXhr.responseType !== 'json' ) {
response = responseText = safe.jsonStringify(response);
}
Object.defineProperties(outerXhr, {
readyState: { value: 4 },
response: { value: response },
responseText: { value: responseText },
responseXML: { value: null },
responseURL: { value: innerXhr.url },
status: { value: innerXhr.status },
statusText: { value: innerXhr.statusText },
});
outerXhr.dispatchEvent(new Event('readystatechange'));
outerXhr.dispatchEvent(new Event('load'));
outerXhr.dispatchEvent(new Event('loadend'));
};
innerXhr.send(...args);
} }
}; };
} }
@ -3732,6 +3694,7 @@ function trustedReplaceFetchResponse(
builtinScriptlets.push({ builtinScriptlets.push({
name: 'trusted-replace-xhr-response.js', name: 'trusted-replace-xhr-response.js',
requiresTrust: true,
fn: trustedReplaceXhrResponse, fn: trustedReplaceXhrResponse,
dependencies: [ dependencies: [
'match-object-properties.fn', 'match-object-properties.fn',
@ -3758,10 +3721,10 @@ function trustedReplaceXhrResponse(
self.XMLHttpRequest = class extends self.XMLHttpRequest { self.XMLHttpRequest = class extends self.XMLHttpRequest {
open(method, url, ...args) { open(method, url, ...args) {
const outerXhr = this; const outerXhr = this;
const xhrDetails = { method, url, args: [ ...args ] }; const xhrDetails = { method, url };
let outcome = 'match'; let outcome = 'match';
if ( propNeedles.size !== 0 ) { if ( propNeedles.size !== 0 ) {
if ( matchObjectProperties(propNeedles, { method, url }) === false ) { if ( matchObjectProperties(propNeedles, xhrDetails) === false ) {
outcome = 'nomatch'; outcome = 'nomatch';
} }
} }
@ -3773,25 +3736,20 @@ function trustedReplaceXhrResponse(
} }
return super.open(method, url, ...args); return super.open(method, url, ...args);
} }
send(...args) { get response() {
const outerXhr = this; const innerResponse = super.response;
const xhrDetails = xhrInstances.get(outerXhr); const xhrDetails = xhrInstances.get(this);
if ( xhrDetails === undefined ) { if ( xhrDetails === undefined ) {
return super.send(...args); return innerResponse;
} }
switch ( outerXhr.responseType ) { if ( typeof innerResponse !== 'string' ) {
case '': xhrDetails.response = innerResponse;
case 'json':
case 'text':
break;
default:
return super.send(...args);
} }
const innerXhr = new safe.XMLHttpRequest(); let outerResponse = xhrDetails.response;
innerXhr.open(xhrDetails.method, xhrDetails.url, ...xhrDetails.args); if ( outerResponse !== undefined ) {
innerXhr.responseType = outerXhr.responseType; return outerResponse;
innerXhr.onloadend = function() { }
const textBefore = innerXhr.responseText; const textBefore = innerResponse;
const textAfter = textBefore.replace(rePattern, replacement); const textAfter = textBefore.replace(rePattern, replacement);
const outcome = textAfter !== textBefore ? 'match' : 'nomatch'; const outcome = textAfter !== textBefore ? 'match' : 'nomatch';
if ( outcome === logLevel || logLevel === 'all' ) { if ( outcome === logLevel || logLevel === 'all' ) {
@ -3801,28 +3759,11 @@ function trustedReplaceXhrResponse(
`\n\treplacement: ${replacement}`, `\n\treplacement: ${replacement}`,
); );
} }
let response = innerXhr.responseText; xhrDetails.response = textAfter;
if ( outerXhr.responseType === 'json' ) { return textAfter;
try {
response = safe.jsonParse(innerXhr.responseText);
} catch(ex) {
response = innerXhr.response;
} }
} get responseText() {
Object.defineProperties(outerXhr, { return this.response;
readyState: { value: 4 },
response: { value: response },
responseText: { value: textAfter },
responseXML: { value: null },
responseURL: { value: innerXhr.url },
status: { value: innerXhr.status },
statusText: { value: innerXhr.statusText },
});
outerXhr.dispatchEvent(new Event('readystatechange'));
outerXhr.dispatchEvent(new Event('load'));
outerXhr.dispatchEvent(new Event('loadend'));
};
innerXhr.send(...args);
} }
}; };
} }