mirror of https://github.com/gorhill/uBlock.git
[experimental] Add `json-stringify` scriptlet
Will be evaluated this current dev cycle and as a result might be removed before next stable. Other changes to increase code consistency.
This commit is contained in:
parent
c0ea5ebab5
commit
51359c6585
|
@ -60,8 +60,8 @@ function safeSelf() {
|
||||||
'addEventListener': self.EventTarget.prototype.addEventListener,
|
'addEventListener': self.EventTarget.prototype.addEventListener,
|
||||||
'removeEventListener': self.EventTarget.prototype.removeEventListener,
|
'removeEventListener': self.EventTarget.prototype.removeEventListener,
|
||||||
'fetch': self.fetch,
|
'fetch': self.fetch,
|
||||||
'jsonParse': self.JSON.parse.bind(self.JSON),
|
'JSON_parse': self.JSON.parse.bind(self.JSON),
|
||||||
'jsonStringify': self.JSON.stringify.bind(self.JSON),
|
'JSON_stringify': self.JSON.stringify.bind(self.JSON),
|
||||||
'log': console.log.bind(console),
|
'log': console.log.bind(console),
|
||||||
uboLog(...args) {
|
uboLog(...args) {
|
||||||
if ( scriptletGlobals.has('canDebug') === false ) { return; }
|
if ( scriptletGlobals.has('canDebug') === false ) { return; }
|
||||||
|
@ -428,7 +428,7 @@ function setConstantCore(
|
||||||
if ( Math.abs(cValue) > 0x7FFF ) { return; }
|
if ( Math.abs(cValue) > 0x7FFF ) { return; }
|
||||||
} else if ( trusted ) {
|
} else if ( trusted ) {
|
||||||
if ( cValue.startsWith('{') && cValue.endsWith('}') ) {
|
if ( cValue.startsWith('{') && cValue.endsWith('}') ) {
|
||||||
try { cValue = safe.jsonParse(cValue).value; } catch(ex) { return; }
|
try { cValue = safe.JSON_parse(cValue).value; } catch(ex) { return; }
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
|
@ -544,14 +544,14 @@ function setConstantCore(
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
builtinScriptlets.push({
|
builtinScriptlets.push({
|
||||||
name: 'replace-node-text-core.fn',
|
name: 'replace-node-text.fn',
|
||||||
fn: replaceNodeTextCore,
|
fn: replaceNodeTextFn,
|
||||||
dependencies: [
|
dependencies: [
|
||||||
'run-at.fn',
|
'run-at.fn',
|
||||||
'safe-self.fn',
|
'safe-self.fn',
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
function replaceNodeTextCore(
|
function replaceNodeTextFn(
|
||||||
nodeName = '',
|
nodeName = '',
|
||||||
pattern = '',
|
pattern = '',
|
||||||
replacement = ''
|
replacement = ''
|
||||||
|
@ -581,8 +581,8 @@ function replaceNodeTextCore(
|
||||||
: replacement;
|
: replacement;
|
||||||
node.textContent = after;
|
node.textContent = after;
|
||||||
if ( shouldLog !== 0 ) {
|
if ( shouldLog !== 0 ) {
|
||||||
safe.uboLog('replace-node-text-core.fn before:\n', before);
|
safe.uboLog('replace-node-text.fn before:\n', before);
|
||||||
safe.uboLog('replace-node-text-core.fn after:\n', after);
|
safe.uboLog('replace-node-text.fn after:\n', after);
|
||||||
}
|
}
|
||||||
return sedCount === 0 || (sedCount -= 1) !== 0;
|
return sedCount === 0 || (sedCount -= 1) !== 0;
|
||||||
};
|
};
|
||||||
|
@ -630,10 +630,11 @@ function replaceNodeTextCore(
|
||||||
|
|
||||||
builtinScriptlets.push({
|
builtinScriptlets.push({
|
||||||
name: 'object-prune.fn',
|
name: 'object-prune.fn',
|
||||||
fn: objectPrune,
|
fn: objectPruneFn,
|
||||||
dependencies: [
|
dependencies: [
|
||||||
'matches-stack-trace.fn',
|
'matches-stack-trace.fn',
|
||||||
'safe-self.fn',
|
'safe-self.fn',
|
||||||
|
'should-log.fn',
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
// When no "prune paths" argument is provided, the scriptlet is
|
// When no "prune paths" argument is provided, the scriptlet is
|
||||||
|
@ -642,7 +643,7 @@ builtinScriptlets.push({
|
||||||
//
|
//
|
||||||
// https://github.com/uBlockOrigin/uBlock-issues/issues/1545
|
// https://github.com/uBlockOrigin/uBlock-issues/issues/1545
|
||||||
// - Add support for "remove everything if needle matches" case
|
// - Add support for "remove everything if needle matches" case
|
||||||
function objectPrune(
|
function objectPruneFn(
|
||||||
obj,
|
obj,
|
||||||
rawPrunePaths,
|
rawPrunePaths,
|
||||||
rawNeedlePaths,
|
rawNeedlePaths,
|
||||||
|
@ -664,8 +665,8 @@ function objectPrune(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( objectPrune.findOwner === undefined ) {
|
if ( objectPruneFn.findOwner === undefined ) {
|
||||||
objectPrune.findOwner = (root, path, prune = false) => {
|
objectPruneFn.findOwner = (root, path, prune = false) => {
|
||||||
let owner = root;
|
let owner = root;
|
||||||
let chain = path;
|
let chain = path;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -696,7 +697,7 @@ function objectPrune(
|
||||||
const next = chain.slice(pos + 1);
|
const next = chain.slice(pos + 1);
|
||||||
let found = false;
|
let found = false;
|
||||||
for ( const key of Object.keys(owner) ) {
|
for ( const key of Object.keys(owner) ) {
|
||||||
found = objectPrune.findOwner(owner[key], next, prune) || found;
|
found = objectPruneFn.findOwner(owner[key], next, prune) || found;
|
||||||
}
|
}
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
@ -705,34 +706,34 @@ function objectPrune(
|
||||||
chain = chain.slice(pos + 1);
|
chain = chain.slice(pos + 1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
objectPrune.mustProcess = (root, needlePaths) => {
|
objectPruneFn.mustProcess = (root, needlePaths) => {
|
||||||
for ( const needlePath of needlePaths ) {
|
for ( const needlePath of needlePaths ) {
|
||||||
if ( objectPrune.findOwner(root, needlePath) === false ) {
|
if ( objectPruneFn.findOwner(root, needlePath) === false ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
objectPrune.logJson = (json, msg, reNeedle) => {
|
objectPruneFn.logJson = (json, msg, reNeedle) => {
|
||||||
if ( reNeedle.test(json) === false ) { return; }
|
if ( reNeedle.test(json) === false ) { return; }
|
||||||
safeSelf().uboLog(`objectPrune()`, msg, location.hostname, json);
|
safeSelf().uboLog(`objectPrune()`, msg, location.hostname, json);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const jsonBefore = logLevel ? JSON.stringify(obj, null, 2) : '';
|
const jsonBefore = logLevel ? safe.JSON_stringify(obj, null, 2) : '';
|
||||||
if ( logLevel === true || logLevel === 'all' ) {
|
if ( logLevel === true || logLevel === 'all' ) {
|
||||||
objectPrune.logJson(jsonBefore, `prune:"${rawPrunePaths}" log:"${logLevel}"`, reLogNeedle);
|
objectPruneFn.logJson(jsonBefore, `prune:"${rawPrunePaths}" log:"${logLevel}"`, reLogNeedle);
|
||||||
}
|
}
|
||||||
if ( prunePaths.length === 0 ) { return; }
|
if ( prunePaths.length === 0 ) { return; }
|
||||||
let outcome = 'nomatch';
|
let outcome = 'nomatch';
|
||||||
if ( objectPrune.mustProcess(obj, needlePaths) ) {
|
if ( objectPruneFn.mustProcess(obj, needlePaths) ) {
|
||||||
for ( const path of prunePaths ) {
|
for ( const path of prunePaths ) {
|
||||||
if ( objectPrune.findOwner(obj, path, true) ) {
|
if ( objectPruneFn.findOwner(obj, path, true) ) {
|
||||||
outcome = 'match';
|
outcome = 'match';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( logLevel === outcome ) {
|
if ( logLevel === outcome ) {
|
||||||
objectPrune.logJson(jsonBefore, `prune:"${rawPrunePaths}" log:"${logLevel}"`, reLogNeedle);
|
objectPruneFn.logJson(jsonBefore, `prune:"${rawPrunePaths}" log:"${logLevel}"`, reLogNeedle);
|
||||||
}
|
}
|
||||||
if ( outcome === 'match' ) { return obj; }
|
if ( outcome === 'match' ) { return obj; }
|
||||||
}
|
}
|
||||||
|
@ -1005,7 +1006,7 @@ function jsonPruneFetchResponseFn(
|
||||||
const response = responseBefore.clone();
|
const response = responseBefore.clone();
|
||||||
return response.json().then(objBefore => {
|
return response.json().then(objBefore => {
|
||||||
if ( typeof objBefore !== 'object' ) { return responseBefore; }
|
if ( typeof objBefore !== 'object' ) { return responseBefore; }
|
||||||
const objAfter = objectPrune(
|
const objAfter = objectPruneFn(
|
||||||
objBefore,
|
objBefore,
|
||||||
rawPrunePaths,
|
rawPrunePaths,
|
||||||
rawNeedlePaths,
|
rawNeedlePaths,
|
||||||
|
@ -1390,19 +1391,10 @@ builtinScriptlets.push({
|
||||||
name: 'json-prune.js',
|
name: 'json-prune.js',
|
||||||
fn: jsonPrune,
|
fn: jsonPrune,
|
||||||
dependencies: [
|
dependencies: [
|
||||||
'match-object-properties.fn',
|
|
||||||
'object-prune.fn',
|
'object-prune.fn',
|
||||||
'parse-properties-to-match.fn',
|
|
||||||
'safe-self.fn',
|
'safe-self.fn',
|
||||||
'should-log.fn',
|
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
// When no "prune paths" argument is provided, the scriptlet is
|
|
||||||
// used for logging purpose and the "needle paths" argument is
|
|
||||||
// used to filter logging output.
|
|
||||||
//
|
|
||||||
// https://github.com/uBlockOrigin/uBlock-issues/issues/1545
|
|
||||||
// - Add support for "remove everything if needle matches" case
|
|
||||||
function jsonPrune(
|
function jsonPrune(
|
||||||
rawPrunePaths = '',
|
rawPrunePaths = '',
|
||||||
rawNeedlePaths = '',
|
rawNeedlePaths = '',
|
||||||
|
@ -1414,7 +1406,7 @@ function jsonPrune(
|
||||||
JSON.parse = new Proxy(JSON.parse, {
|
JSON.parse = new Proxy(JSON.parse, {
|
||||||
apply: function(target, thisArg, args) {
|
apply: function(target, thisArg, args) {
|
||||||
const objBefore = Reflect.apply(target, thisArg, args);
|
const objBefore = Reflect.apply(target, thisArg, args);
|
||||||
const objAfter = objectPrune(
|
const objAfter = objectPruneFn(
|
||||||
objBefore,
|
objBefore,
|
||||||
rawPrunePaths,
|
rawPrunePaths,
|
||||||
rawNeedlePaths,
|
rawNeedlePaths,
|
||||||
|
@ -1426,6 +1418,42 @@ function jsonPrune(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
builtinScriptlets.push({
|
||||||
|
name: 'json-prune-stringify.js',
|
||||||
|
fn: jsonPruneStringify,
|
||||||
|
dependencies: [
|
||||||
|
'object-prune.fn',
|
||||||
|
'safe-self.fn',
|
||||||
|
],
|
||||||
|
});
|
||||||
|
function jsonPruneStringify(
|
||||||
|
rawPrunePaths = '',
|
||||||
|
rawNeedlePaths = '',
|
||||||
|
stackNeedle = ''
|
||||||
|
) {
|
||||||
|
const safe = safeSelf();
|
||||||
|
const stackNeedleDetails = safe.initPattern(stackNeedle, { canNegate: true });
|
||||||
|
const extraArgs = safe.getExtraArgs(Array.from(arguments), 3);
|
||||||
|
JSON.stringify = new Proxy(JSON.stringify, {
|
||||||
|
apply: function(target, thisArg, args) {
|
||||||
|
const objBefore = args[0];
|
||||||
|
if ( objBefore instanceof Object ) {
|
||||||
|
const objAfter = objectPruneFn(
|
||||||
|
objBefore,
|
||||||
|
rawPrunePaths,
|
||||||
|
rawNeedlePaths,
|
||||||
|
stackNeedleDetails,
|
||||||
|
extraArgs
|
||||||
|
);
|
||||||
|
args[0] = objAfter || objBefore;
|
||||||
|
}
|
||||||
|
return Reflect.apply(target, thisArg, args);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* json-prune-fetch-response.js
|
* json-prune-fetch-response.js
|
||||||
|
@ -1506,13 +1534,13 @@ function jsonPruneXhrResponse(
|
||||||
if ( typeof innerResponse === 'object' ) {
|
if ( typeof innerResponse === 'object' ) {
|
||||||
objBefore = innerResponse;
|
objBefore = innerResponse;
|
||||||
} else if ( typeof innerResponse === 'string' ) {
|
} else if ( typeof innerResponse === 'string' ) {
|
||||||
try { objBefore = safe.jsonParse(innerResponse); }
|
try { objBefore = safe.JSON_parse(innerResponse); }
|
||||||
catch(ex) { }
|
catch(ex) { }
|
||||||
}
|
}
|
||||||
if ( typeof objBefore !== 'object' ) {
|
if ( typeof objBefore !== 'object' ) {
|
||||||
return (xhrDetails.response = innerResponse);
|
return (xhrDetails.response = innerResponse);
|
||||||
}
|
}
|
||||||
const objAfter = objectPrune(
|
const objAfter = objectPruneFn(
|
||||||
objBefore,
|
objBefore,
|
||||||
rawPrunePaths,
|
rawPrunePaths,
|
||||||
rawNeedlePaths,
|
rawNeedlePaths,
|
||||||
|
@ -1522,7 +1550,7 @@ function jsonPruneXhrResponse(
|
||||||
let outerResponse;
|
let outerResponse;
|
||||||
if ( typeof objAfter === 'object' ) {
|
if ( typeof objAfter === 'object' ) {
|
||||||
outerResponse = typeof innerResponse === 'string'
|
outerResponse = typeof innerResponse === 'string'
|
||||||
? safe.jsonStringify(objAfter)
|
? safe.JSON_stringify(objAfter)
|
||||||
: objAfter;
|
: objAfter;
|
||||||
} else {
|
} else {
|
||||||
outerResponse = innerResponse;
|
outerResponse = innerResponse;
|
||||||
|
@ -1557,7 +1585,7 @@ function evaldataPrune(
|
||||||
apply(target, thisArg, args) {
|
apply(target, thisArg, args) {
|
||||||
const before = Reflect.apply(target, thisArg, args);
|
const before = Reflect.apply(target, thisArg, args);
|
||||||
if ( typeof before === 'object' ) {
|
if ( typeof before === 'object' ) {
|
||||||
const after = objectPrune(before, rawPrunePaths, rawNeedlePaths);
|
const after = objectPruneFn(before, rawPrunePaths, rawNeedlePaths);
|
||||||
return after || before;
|
return after || before;
|
||||||
}
|
}
|
||||||
return before;
|
return before;
|
||||||
|
@ -3305,7 +3333,7 @@ builtinScriptlets.push({
|
||||||
fn: removeNodeText,
|
fn: removeNodeText,
|
||||||
world: 'ISOLATED',
|
world: 'ISOLATED',
|
||||||
dependencies: [
|
dependencies: [
|
||||||
'replace-node-text-core.fn',
|
'replace-node-text.fn',
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
function removeNodeText(
|
function removeNodeText(
|
||||||
|
@ -3313,7 +3341,7 @@ function removeNodeText(
|
||||||
condition,
|
condition,
|
||||||
...extraArgs
|
...extraArgs
|
||||||
) {
|
) {
|
||||||
replaceNodeTextCore(nodeName, '', '', 'condition', condition || '', ...extraArgs);
|
replaceNodeTextFn(nodeName, '', '', 'condition', condition || '', ...extraArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -3648,7 +3676,7 @@ builtinScriptlets.push({
|
||||||
fn: replaceNodeText,
|
fn: replaceNodeText,
|
||||||
world: 'ISOLATED',
|
world: 'ISOLATED',
|
||||||
dependencies: [
|
dependencies: [
|
||||||
'replace-node-text-core.fn',
|
'replace-node-text.fn',
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
function replaceNodeText(
|
function replaceNodeText(
|
||||||
|
@ -3657,7 +3685,7 @@ function replaceNodeText(
|
||||||
replacement,
|
replacement,
|
||||||
...extraArgs
|
...extraArgs
|
||||||
) {
|
) {
|
||||||
replaceNodeTextCore(nodeName, pattern, replacement, ...extraArgs);
|
replaceNodeTextFn(nodeName, pattern, replacement, ...extraArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
Loading…
Reference in New Issue