diff --git a/package.json b/package.json
index 6148aca..2bd6c25 100644
--- a/package.json
+++ b/package.json
@@ -5,7 +5,7 @@
"main": "index.js",
"type": "module",
"scripts": {
- "build": "deno build.ts --tagName 1.73.1b0 > ubo.js",
+ "build": "deno build.ts --tagName 1.74.1b4 > ubo.js",
"test": "node --test"
},
"author": {
diff --git a/ubo.js b/ubo.js
index f5ea50e..75dbece 100644
--- a/ubo.js
+++ b/ubo.js
@@ -119,8 +119,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -133,7 +132,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -144,10 +143,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -200,7 +197,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -486,8 +483,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -500,7 +496,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -511,10 +507,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -567,7 +561,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -791,8 +785,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -805,7 +798,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -816,10 +809,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -872,7 +863,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -989,8 +980,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -1003,7 +993,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -1014,10 +1004,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -1070,7 +1058,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -1287,8 +1275,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -1301,7 +1288,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -1312,10 +1299,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -1368,7 +1353,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -1674,8 +1659,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -1688,7 +1672,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -1699,10 +1683,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -1755,7 +1737,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -2012,8 +1994,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -2026,7 +2007,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -2037,10 +2018,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -2093,7 +2072,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -2875,8 +2854,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -2889,7 +2867,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -2900,10 +2878,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -2956,7 +2932,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -3738,8 +3714,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -3752,7 +3727,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -3763,10 +3738,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -3819,7 +3792,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -4600,8 +4573,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -4614,7 +4586,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -4625,10 +4597,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -4681,7 +4651,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -5462,8 +5432,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -5476,7 +5445,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -5487,10 +5456,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -5543,7 +5510,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -6352,8 +6319,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -6366,7 +6332,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -6377,10 +6343,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -6433,7 +6397,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -7242,8 +7206,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -7256,7 +7219,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -7267,10 +7230,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -7323,7 +7284,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -8115,8 +8076,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -8129,7 +8089,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -8140,10 +8100,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -8196,7 +8154,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -9060,8 +9018,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -9074,7 +9031,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -9085,10 +9042,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -9141,7 +9096,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -9905,8 +9860,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -9919,7 +9873,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -9930,10 +9884,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -9986,7 +9938,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -10750,8 +10702,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -10764,7 +10715,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -10775,10 +10726,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -10831,7 +10780,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -11598,8 +11547,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -11612,7 +11560,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -11623,10 +11571,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -11679,7 +11625,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -12389,8 +12335,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -12403,7 +12348,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -12414,10 +12359,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -12470,7 +12413,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -13277,8 +13220,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -13291,7 +13233,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -13302,10 +13244,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -13358,7 +13298,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -14170,8 +14110,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -14184,7 +14123,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -14195,10 +14134,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -14251,7 +14188,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -15014,8 +14951,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -15028,7 +14964,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -15039,10 +14975,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -15095,7 +15029,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -15858,8 +15792,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -15872,7 +15805,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -15883,10 +15816,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -15939,7 +15870,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -16685,8 +16616,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -16699,7 +16629,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -16710,10 +16640,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -16766,7 +16694,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -18177,8 +18105,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -18191,7 +18118,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -18202,10 +18129,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -18258,7 +18183,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -19138,8 +19063,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -19152,7 +19076,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -19163,10 +19087,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -19219,7 +19141,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -20099,8 +20021,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -20113,7 +20034,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -20124,10 +20045,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -20180,7 +20099,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -21057,8 +20976,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -21071,7 +20989,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -21082,10 +21000,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -21138,7 +21054,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -21369,8 +21285,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -21383,7 +21298,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -21394,10 +21309,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -21450,7 +21363,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -22227,8 +22140,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -22241,7 +22153,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -22252,10 +22164,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -22308,7 +22218,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -23753,8 +23663,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -23767,7 +23676,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -23778,10 +23687,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -23834,7 +23741,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -24741,8 +24648,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -24755,7 +24661,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -24766,10 +24672,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -24822,7 +24726,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -25066,8 +24970,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -25080,7 +24983,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -25091,10 +24994,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -25147,7 +25048,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -25424,8 +25325,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -25438,7 +25338,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -25449,10 +25349,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -25505,7 +25403,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -25905,8 +25803,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -25919,7 +25816,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -25930,10 +25827,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -25986,7 +25881,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -26377,8 +26272,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -26391,7 +26285,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -26402,10 +26296,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -26458,7 +26350,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -26899,8 +26791,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -26913,7 +26804,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -26924,10 +26815,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -26980,7 +26869,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -27368,8 +27257,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -27382,7 +27270,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -27393,10 +27281,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -27449,7 +27335,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -27818,8 +27704,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -27832,7 +27717,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -27843,10 +27728,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -27899,7 +27782,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -28118,8 +28001,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -28132,7 +28014,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -28143,10 +28025,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -28199,7 +28079,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -28423,8 +28303,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -28437,7 +28316,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -28448,10 +28327,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -28504,7 +28381,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -28756,8 +28633,8 @@ function preventAddEventListener(
return parts.join('');
};
const shouldPrevent = (thisArg, type, handler) => {
- const matchesType = safe.RegExp_test.call(reType, type);
- const matchesHandler = safe.RegExp_test.call(rePattern, handler);
+ const matchesType = safe.RegExp_test(reType, type);
+ const matchesHandler = safe.RegExp_test(rePattern, handler);
const matchesEither = matchesType || matchesHandler;
const matchesBoth = matchesType && matchesHandler;
if ( safe.logLevel > 1 && matchesEither ) {
@@ -28829,8 +28706,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -28843,7 +28719,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -28854,10 +28730,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -28910,7 +28784,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -29177,8 +29051,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -29191,7 +29064,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -29202,10 +29075,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -29258,7 +29129,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -29451,40 +29322,51 @@ function preventClipboardWrite(matches = '', ...varargs) {
const extraArgs = safe.parseVarargs(varargs);
const excludePattern = extraArgs.excludeMatches &&
safe.initPattern(extraArgs.excludeMatches);
+ const htmlTemplate = [
+ '
',
+ '${warning}\n',
+ '',
+ '
',
+ ].join('');
const domAlert = clipboardText => {
const doc = document;
- const div = doc.createElement('div');
- const span = doc.createElement('span');
- span.style = 'flex-grow:1;padding:0.5em 0 0.5em 0.5em;';
- const { domAlert } = extraArgs;
- const placeholder = /\$\{text\}/.exec(domAlert);
- if ( placeholder ) {
+ const domAlert = extraArgs.domAlert.replace(/\\n/g, '\n');
+ let html;
+ if ( domAlert.includes('${text}') ) {
const code = doc.createElement('code');
- code.style = 'background-color:#ddc;font-family:monospace;padding:0.25em;user-select:none;word-break:break-all';
+ const styles = [
+ 'background-color: #ddc',
+ 'display: inline-block',
+ 'font-family: monospace',
+ 'font-size: 100%',
+ 'max-height: 8em',
+ 'overflow: auto',
+ 'padding: 0.25em',
+ 'width: 100%;',
+ 'word-break: break-all'
+ ];
+ if ( Boolean(extraArgs.selectable ?? true) === false ) {
+ styles.push('user-select: none');
+ }
+ code.style = styles.join(';');
code.textContent = clipboardText;
- span.append(
- domAlert.slice(0, placeholder.index),
- code,
- domAlert.slice(placeholder.index + placeholder[0].length)
+ html = htmlTemplate.replace('${warning}',
+ domAlert.replace('${text}', code.outerHTML)
);
} else {
- span.append(domAlert);
+ html = htmlTemplate.replace('${warning}', domAlert);
}
- const button = doc.createElement('button');
- button.style = 'padding:1em';
- button.textContent = '×';
+ if ( currentAlert ) { currentAlert.remove(); }
+ const domParser = new DOMParser();
+ const fragment = domParser.parseFromString(html, 'text/html');
+ currentAlert = fragment.querySelector('div');
+ const button = currentAlert.querySelector('button');
button.addEventListener('click', ( ) => {
if ( currentAlert === null ) { return; }
currentAlert.remove();
currentAlert = null;
});
- div.append(span, button);
- div.style = 'background-color:beige;color:black;border:1px solid black;display:flex;font-size:medium;position:fixed;text-align:center;top:0;width:100%;z-index:2147483647';
- doc.documentElement.append(div);
- if ( currentAlert ) {
- currentAlert.remove();
- }
- currentAlert = div;
+ doc.documentElement.append(currentAlert);
};
let currentAlert = null;
const prevent = text => {
@@ -29510,7 +29392,7 @@ function preventClipboardWrite(matches = '', ...varargs) {
const { callArgs } = context;
if ( callArgs[0] === 'copy' || callArgs[0] === 'cut' ) {
const text = document.getSelection()?.toString();
- if ( text && prevent(text) ) { return false; }
+ if ( prevent(text) ) { return true; }
}
return context.reflect();
}, { skipToString: true });
@@ -29538,8 +29420,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -29552,7 +29433,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -29563,10 +29444,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -29619,7 +29498,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -29953,8 +29832,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -29967,7 +29845,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -29978,10 +29856,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -30034,7 +29910,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -30460,8 +30336,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -30474,7 +30349,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -30485,10 +30360,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -30541,7 +30414,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -30765,8 +30638,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -30779,7 +30651,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -30790,10 +30662,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -30846,7 +30716,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -31004,8 +30874,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -31018,7 +30887,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -31029,10 +30898,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -31085,7 +30952,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -31249,8 +31116,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -31263,7 +31129,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -31274,10 +31140,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -31330,7 +31194,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -31456,8 +31320,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -31470,7 +31333,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -31481,10 +31344,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -31537,7 +31398,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -31797,8 +31658,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -31811,7 +31671,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -31822,10 +31682,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -31878,7 +31736,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -32138,8 +31996,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -32152,7 +32009,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -32163,10 +32020,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -32219,7 +32074,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -32431,147 +32286,61 @@ preventRequestAnimationFrame(...args);
};
-scriptlets['prevent-xhr.js'] = {
-aliases: ["no-xhr-if.js"],
+scriptlets['set-constant.js'] = {
+aliases: ["set.js"],
requiresTrust: false,
func: function (scriptletGlobals = {}, ...args) {
-function proxyApplyFn(
- target = '',
- handler = '',
- options = {}
-) {
- let context = globalThis;
- let prop = target;
- for (;;) {
- const pos = prop.indexOf('.');
- if ( pos === -1 ) { break; }
- context = context[prop.slice(0, pos)];
- if ( context instanceof Object === false ) { return; }
- prop = prop.slice(pos+1);
- }
- const fn = context[prop];
- if ( typeof fn !== 'function' ) { return; }
- if ( proxyApplyFn.CtorContext === undefined ) {
- proxyApplyFn.ctorContexts = [];
- proxyApplyFn.CtorContext = class {
- constructor(...args) {
- this.init(...args);
- }
- init(callFn, callArgs) {
- this.callFn = callFn;
- this.callArgs = callArgs;
- return this;
- }
- reflect() {
- const r = Reflect.construct(this.callFn, this.callArgs);
- this.callFn = this.callArgs = this.private = undefined;
- proxyApplyFn.ctorContexts.push(this);
- return r;
- }
- static factory(...args) {
- return proxyApplyFn.ctorContexts.length !== 0
- ? proxyApplyFn.ctorContexts.pop().init(...args)
- : new proxyApplyFn.CtorContext(...args);
- }
- };
- proxyApplyFn.applyContexts = [];
- proxyApplyFn.ApplyContext = class {
- constructor(...args) {
- this.init(...args);
- }
- init(callFn, thisArg, callArgs) {
- this.callFn = callFn;
- this.thisArg = thisArg;
- this.callArgs = callArgs;
- return this;
- }
- reflect() {
- const r = Reflect.apply(this.callFn, this.thisArg, this.callArgs);
- this.callFn = this.thisArg = this.callArgs = this.private = undefined;
- proxyApplyFn.applyContexts.push(this);
- return r;
- }
- static factory(...args) {
- return proxyApplyFn.applyContexts.length !== 0
- ? proxyApplyFn.applyContexts.pop().init(...args)
- : new proxyApplyFn.ApplyContext(...args);
- }
- };
- proxyApplyFn.isCtor = new Map();
- proxyApplyFn.proxies = new WeakMap();
- if ( (options.skipToString || proxyApplyFn.skipToString) !== true ) {
- proxyApplyFn.nativeToString = Function.prototype.toString;
- const proxiedToString = new Proxy(Function.prototype.toString, {
- apply(target, thisArg) {
- let proxied = thisArg;
- for(;;) {
- const fn = proxyApplyFn.proxies.get(proxied);
- if ( fn === undefined ) { break; }
- proxied = fn;
- }
- return proxyApplyFn.nativeToString.call(proxied);
- }
- });
- proxyApplyFn.proxies.set(proxiedToString, proxyApplyFn.nativeToString);
- Function.prototype.toString = proxiedToString;
- }
- }
- if ( proxyApplyFn.isCtor.has(target) === false ) {
- proxyApplyFn.isCtor.set(target, fn.prototype?.constructor === fn);
- }
- const proxyDetails = {
- apply(target, thisArg, args) {
- return handler(proxyApplyFn.ApplyContext.factory(target, thisArg, args));
- }
- };
- if ( proxyApplyFn.isCtor.get(target) ) {
- proxyDetails.construct = function(target, args) {
- return handler(proxyApplyFn.CtorContext.factory(target, args));
- };
- }
- const proxiedTarget = new Proxy(fn, proxyDetails);
- proxyApplyFn.proxies.set(proxiedTarget, fn);
- context[prop] = proxiedTarget;
-}
-function parsePropertiesToMatchFn(propsToMatch, implicit = '') {
+function validateConstantFn(trusted, raw, extraArgs = {}) {
const safe = safeSelf();
- const needles = new Map();
- if ( propsToMatch === undefined || propsToMatch === '' ) { return needles; }
- const options = { canNegate: true };
- for ( const needle of safe.String_split.call(propsToMatch, /\s+/) ) {
- let [ prop, pattern ] = safe.String_split.call(needle, ':');
- if ( prop === '' ) { continue; }
- if ( pattern !== undefined && /[^$\w -]/.test(prop) ) {
- prop = `${prop}:${pattern}`;
- pattern = undefined;
- }
- if ( pattern !== undefined ) {
- needles.set(prop, safe.initPattern(pattern, options));
- } else if ( implicit !== '' ) {
- needles.set(implicit, safe.initPattern(prop, options));
+ let value;
+ if ( raw === 'undefined' ) {
+ value = undefined;
+ } else if ( raw === 'false' ) {
+ value = false;
+ } else if ( raw === 'true' ) {
+ value = true;
+ } else if ( raw === 'null' ) {
+ value = null;
+ } else if ( raw === "''" || raw === '' ) {
+ value = '';
+ } else if ( raw === '[]' || raw === 'emptyArr' ) {
+ value = [];
+ } else if ( raw === '{}' || raw === 'emptyObj' ) {
+ value = {};
+ } else if ( raw === 'noopFunc' ) {
+ value = function(){};
+ } else if ( raw === 'trueFunc' ) {
+ value = function(){ return true; };
+ } else if ( raw === 'falseFunc' ) {
+ value = function(){ return false; };
+ } else if ( raw === 'throwFunc' ) {
+ value = function(){ throw ''; };
+ } else if ( /^-?\d+$/.test(raw) ) {
+ value = parseInt(raw);
+ if ( isNaN(raw) ) { return; }
+ if ( Math.abs(raw) > 0x7FFF ) { return; }
+ } else if ( trusted ) {
+ if ( raw.startsWith('json:') ) {
+ try { value = safe.JSON_parse(raw.slice(5)); } catch { return; }
+ } else if ( raw.startsWith('{') && raw.endsWith('}') ) {
+ try { value = safe.JSON_parse(raw).value; } catch { return; }
}
+ } else {
+ return;
}
- return needles;
-}
-function matchObjectPropertiesFn(propNeedles, ...objs) {
- const safe = safeSelf();
- const matched = [];
- for ( const obj of objs ) {
- if ( obj instanceof Object === false ) { continue; }
- for ( const [ prop, details ] of propNeedles ) {
- let value = obj[prop];
- if ( value === undefined ) { continue; }
- if ( typeof value !== 'string' ) {
- try { value = safe.JSON_stringify(value); }
- catch { }
- if ( typeof value !== 'string' ) { continue; }
- }
- if ( safe.testPattern(details, value) === false ) { return; }
- matched.push(`${prop}: ${value}`);
+ if ( extraArgs.as !== undefined ) {
+ if ( extraArgs.as === 'function' ) {
+ return ( ) => value;
+ } else if ( extraArgs.as === 'callback' ) {
+ return ( ) => (( ) => value);
+ } else if ( extraArgs.as === 'resolved' ) {
+ return Promise.resolve(value);
+ } else if ( extraArgs.as === 'rejected' ) {
+ return Promise.reject(value);
}
}
- return matched;
+ return value;
}
function safeSelf() {
if ( safeSelf.safe ) {
@@ -32581,8 +32350,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -32595,7 +32363,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -32606,10 +32374,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -32662,7 +32428,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -32750,387 +32516,249 @@ function safeSelf() {
}
return safe;
}
-function generateContentFn(trusted, directive) {
- const safe = safeSelf();
- const randomize = len => {
- const chunks = [];
- let textSize = 0;
- do {
- const s = safe.Math_random().toString(36).slice(2);
- chunks.push(s);
- textSize += s.length;
+function runAt(fn, when) {
+ const intFromReadyState = state => {
+ const targets = {
+ 'loading': 1, 'asap': 1,
+ 'interactive': 2, 'end': 2, '2': 2,
+ 'complete': 3, 'idle': 3, '3': 3,
+ };
+ const tokens = Array.isArray(state) ? state : [ state ];
+ for ( const token of tokens ) {
+ const prop = `${token}`;
+ if ( Object.hasOwn(targets, prop) === false ) { continue; }
+ return targets[prop];
}
- while ( textSize < len );
- return chunks.join(' ').slice(0, len);
+ return 0;
};
- if ( directive === 'true' ) {
- return randomize(10);
- }
- if ( directive === 'emptyObj' ) {
- return '{}';
- }
- if ( directive === 'emptyArr' ) {
- return '[]';
- }
- if ( directive === 'emptyStr' ) {
- return '';
- }
- if ( directive.startsWith('length:') ) {
- const match = /^length:(\d+)(?:-(\d+))?$/.exec(directive);
- if ( match === null ) { return ''; }
- const min = parseInt(match[1], 10);
- const extent = safe.Math_max(parseInt(match[2], 10) || 0, min) - min;
- const len = safe.Math_min(min + extent * safe.Math_random(), 500000);
- return randomize(len | 0);
- }
- if ( directive.startsWith('war:') ) {
- if ( scriptletGlobals.warOrigin === undefined ) { return ''; }
- return new Promise(resolve => {
- const warOrigin = scriptletGlobals.warOrigin;
- const warName = directive.slice(4);
- const fullpath = [ warOrigin, '/', warName ];
- const warSecret = scriptletGlobals.warSecret;
- if ( warSecret !== undefined ) {
- fullpath.push('?secret=', warSecret);
- }
- const warXHR = new safe.XMLHttpRequest();
- warXHR.responseType = 'text';
- warXHR.onloadend = ev => {
- resolve(ev.target.responseText || '');
- };
- warXHR.open('GET', fullpath.join(''));
- warXHR.send();
- }).catch(( ) => '');
- }
- if ( directive.startsWith('join:') ) {
- const parts = directive.slice(7)
- .split(directive.slice(5, 7))
- .map(a => generateContentFn(trusted, a));
- return parts.some(a => a instanceof Promise)
- ? Promise.all(parts).then(parts => parts.join(''))
- : parts.join('');
- }
- if ( trusted ) {
- return directive;
+ const runAt = intFromReadyState(when);
+ if ( intFromReadyState(document.readyState) >= runAt ) {
+ fn(); return;
}
- return '';
+ const onStateChange = ( ) => {
+ if ( intFromReadyState(document.readyState) < runAt ) { return; }
+ fn();
+ safe.removeEventListener.apply(document, args);
+ };
+ const safe = safeSelf();
+ const args = [ 'readystatechange', onStateChange, { capture: true } ];
+ safe.addEventListener.apply(document, args);
}
-function preventXhrFn(
+function setConstantFn(
trusted = false,
- propsToMatch = '',
- directive = ''
+ chain = '',
+ rawValue = '',
+ ...varargs
) {
- if ( typeof propsToMatch !== 'string' ) { return; }
+ if ( chain === '' ) { return; }
const safe = safeSelf();
- const scriptletName = trusted ? 'trusted-prevent-xhr' : 'prevent-xhr';
- const logPrefix = safe.makeLogPrefix(scriptletName, propsToMatch, directive);
- const xhrInstances = new WeakMap();
- const propNeedles = parsePropertiesToMatchFn(propsToMatch, 'url');
- const warOrigin = scriptletGlobals.warOrigin;
- const safeDispatchEvent = (xhr, type) => {
- try {
- xhr.dispatchEvent(new Event(type));
- } catch {
- }
- };
- proxyApplyFn('XMLHttpRequest.prototype.open', function(context) {
- const { thisArg, callArgs } = context;
- xhrInstances.delete(thisArg);
- const [ method, url, ...args ] = callArgs;
- if ( warOrigin !== undefined && url.startsWith(warOrigin) ) {
- return context.reflect();
- }
- const haystack = { method, url };
- if ( propsToMatch === '' && directive === '' ) {
- safe.uboLog(logPrefix, `Called: ${safe.JSON_stringify(haystack, null, 2)}`);
- return context.reflect();
- }
- if ( matchObjectPropertiesFn(propNeedles, haystack) ) {
- const xhrDetails = Object.assign(haystack, {
- xhr: thisArg,
- defer: args.length === 0 || !!args[0],
- directive,
- headers: {
- 'date': '',
- 'content-type': '',
- 'content-length': '',
+ const logPrefix = safe.makeLogPrefix('set-constant', chain, rawValue);
+ const extraArgs = safe.parseVarargs(varargs);
+ function setConstant(chain, rawValue) {
+ const trappedProp = (( ) => {
+ const pos = chain.lastIndexOf('.');
+ if ( pos === -1 ) { return chain; }
+ return chain.slice(pos+1);
+ })();
+ const cloakFunc = fn => {
+ safe.Object_defineProperty(fn, 'name', { value: trappedProp });
+ return new Proxy(fn, {
+ defineProperty(target, prop) {
+ if ( prop !== 'toString' ) {
+ return Reflect.defineProperty(...arguments);
+ }
+ return true;
},
- url: haystack.url,
- props: {
- response: { value: '' },
- responseText: { value: '' },
- responseXML: { value: null },
+ deleteProperty(target, prop) {
+ if ( prop !== 'toString' ) {
+ return Reflect.deleteProperty(...arguments);
+ }
+ return true;
+ },
+ get(target, prop) {
+ if ( prop === 'toString' ) {
+ return function() {
+ return `function ${trappedProp}() { [native code] }`;
+ }.bind(null);
+ }
+ return Reflect.get(...arguments);
},
});
- xhrInstances.set(thisArg, xhrDetails);
- }
- return context.reflect();
- });
- proxyApplyFn('XMLHttpRequest.prototype.send', function(context) {
- const { thisArg } = context;
- const xhrDetails = xhrInstances.get(thisArg);
- if ( xhrDetails === undefined ) {
- return context.reflect();
- }
- xhrDetails.headers['date'] = (new Date()).toUTCString();
- let xhrText = '';
- switch ( thisArg.responseType ) {
- case 'arraybuffer':
- xhrDetails.props.response.value = new ArrayBuffer(0);
- xhrDetails.headers['content-type'] = 'application/octet-stream';
- break;
- case 'blob':
- xhrDetails.props.response.value = new Blob([]);
- xhrDetails.headers['content-type'] = 'application/octet-stream';
- break;
- case 'document': {
- const parser = new DOMParser();
- const doc = parser.parseFromString('', 'text/html');
- xhrDetails.props.response.value = doc;
- xhrDetails.props.responseXML.value = doc;
- xhrDetails.headers['content-type'] = 'text/html';
- break;
+ };
+ if ( trappedProp === '' ) { return; }
+ const thisScript = document.currentScript;
+ let normalValue = validateConstantFn(trusted, rawValue, extraArgs);
+ if ( rawValue === 'noopFunc' || rawValue === 'trueFunc' || rawValue === 'falseFunc' ) {
+ normalValue = cloakFunc(normalValue);
}
- case 'json':
- xhrDetails.props.response.value = {};
- xhrDetails.props.responseText.value = '{}';
- xhrDetails.headers['content-type'] = 'application/json';
- break;
- default: {
- if ( directive === '' ) { break; }
- xhrText = generateContentFn(trusted, xhrDetails.directive);
- if ( xhrText instanceof Promise ) {
- xhrText = xhrText.then(text => {
- xhrDetails.props.response.value = text;
- xhrDetails.props.responseText.value = text;
+ let aborted = false;
+ const mustAbort = function(v) {
+ if ( trusted ) { return false; }
+ if ( aborted ) { return true; }
+ aborted =
+ (v !== undefined && v !== null) &&
+ (normalValue !== undefined && normalValue !== null) &&
+ (typeof v !== typeof normalValue);
+ if ( aborted ) {
+ safe.uboLog(logPrefix, `Aborted because value set to ${v}`);
+ }
+ return aborted;
+ };
+ // https://github.com/uBlockOrigin/uBlock-issues/issues/156
+ // Support multiple trappers for the same property.
+ const trapProp = function(owner, prop, configurable, handler) {
+ if ( handler.init(configurable ? owner[prop] : normalValue) === false ) { return; }
+ const odesc = safe.Object_getOwnPropertyDescriptor(owner, prop);
+ let prevGetter, prevSetter;
+ if ( odesc instanceof safe.Object ) {
+ owner[prop] = normalValue;
+ if ( odesc.get instanceof Function ) {
+ prevGetter = odesc.get;
+ }
+ if ( odesc.set instanceof Function ) {
+ prevSetter = odesc.set;
+ }
+ }
+ try {
+ safe.Object_defineProperty(owner, prop, {
+ configurable,
+ get() {
+ if ( prevGetter !== undefined ) {
+ prevGetter();
+ }
+ return handler.getter();
+ },
+ set(a) {
+ if ( prevSetter !== undefined ) {
+ prevSetter(a);
+ }
+ handler.setter(a);
+ }
});
- } else {
- xhrDetails.props.response.value = xhrText;
- xhrDetails.props.responseText.value = xhrText;
+ safe.uboLog(logPrefix, 'Trap installed');
+ } catch(ex) {
+ safe.uboErr(logPrefix, ex);
}
- xhrDetails.headers['content-type'] = 'text/plain';
- break;
- }
- }
- if ( xhrDetails.defer === false ) {
- xhrDetails.headers['content-length'] = `${xhrDetails.props.response.value}`.length;
- Object.defineProperties(xhrDetails.xhr, {
- readyState: { value: 4 },
- responseURL: { value: xhrDetails.url },
- status: { value: 200 },
- statusText: { value: 'OK' },
- });
- Object.defineProperties(xhrDetails.xhr, xhrDetails.props);
- return;
- }
- Promise.resolve(xhrText).then(( ) => xhrDetails).then(details => {
- Object.defineProperties(details.xhr, {
- readyState: { value: 1, configurable: true },
- responseURL: { value: xhrDetails.url },
- });
- safeDispatchEvent(details.xhr, 'readystatechange');
- return details;
- }).then(details => {
- xhrDetails.headers['content-length'] = `${details.props.response.value}`.length;
- Object.defineProperties(details.xhr, {
- readyState: { value: 2, configurable: true },
- status: { value: 200 },
- statusText: { value: 'OK' },
+ };
+ const trapChain = function(owner, chain) {
+ const pos = chain.indexOf('.');
+ if ( pos === -1 ) {
+ trapProp(owner, chain, false, {
+ v: undefined,
+ init: function(v) {
+ if ( mustAbort(v) ) { return false; }
+ this.v = v;
+ return true;
+ },
+ getter: function() {
+ if ( document.currentScript === thisScript ) {
+ return this.v;
+ }
+ safe.uboLog(logPrefix, 'Property read');
+ return normalValue;
+ },
+ setter: function(a) {
+ if ( mustAbort(a) === false ) { return; }
+ normalValue = a;
+ }
+ });
+ return;
+ }
+ const prop = chain.slice(0, pos);
+ const v = owner[prop];
+ chain = chain.slice(pos + 1);
+ if ( v instanceof safe.Object || typeof v === 'object' && v !== null ) {
+ trapChain(v, chain);
+ return;
+ }
+ trapProp(owner, prop, true, {
+ v: undefined,
+ init: function(v) {
+ this.v = v;
+ return true;
+ },
+ getter: function() {
+ return this.v;
+ },
+ setter: function(a) {
+ this.v = a;
+ if ( a instanceof safe.Object ) {
+ trapChain(a, chain);
+ }
+ }
});
- safeDispatchEvent(details.xhr, 'readystatechange');
- return details;
- }).then(details => {
- Object.defineProperties(details.xhr, {
- readyState: { value: 3, configurable: true },
- });
- Object.defineProperties(details.xhr, details.props);
- safeDispatchEvent(details.xhr, 'readystatechange');
- return details;
- }).then(details => {
- Object.defineProperties(details.xhr, {
- readyState: { value: 4 },
- });
- safeDispatchEvent(details.xhr, 'readystatechange');
- safeDispatchEvent(details.xhr, 'load');
- safeDispatchEvent(details.xhr, 'loadend');
- safe.uboLog(logPrefix, `Prevented with response:\n${details.xhr.response}`);
- });
- });
- proxyApplyFn('XMLHttpRequest.prototype.getResponseHeader', function(context) {
- const { thisArg } = context;
- const xhrDetails = xhrInstances.get(thisArg);
- if ( xhrDetails === undefined || thisArg.readyState < thisArg.HEADERS_RECEIVED ) {
- return context.reflect();
- }
- const headerName = `${context.callArgs[0]}`;
- const value = xhrDetails.headers[headerName.toLowerCase()];
- if ( value !== undefined && value !== '' ) { return value; }
- return null;
- });
- proxyApplyFn('XMLHttpRequest.prototype.getAllResponseHeaders', function(context) {
- const { thisArg } = context;
- const xhrDetails = xhrInstances.get(thisArg);
- if ( xhrDetails === undefined || thisArg.readyState < thisArg.HEADERS_RECEIVED ) {
- return context.reflect();
- }
- const out = [];
- for ( const [ name, value ] of Object.entries(xhrDetails.headers) ) {
- if ( !value ) { continue; }
- out.push(`${name}: ${value}`);
- }
- if ( out.length !== 0 ) { out.push(''); }
- return out.join('\r\n');
- });
+ };
+ trapChain(window, chain);
+ }
+ runAt(( ) => {
+ setConstant(chain, rawValue);
+ }, extraArgs.runAt);
}
-function preventXhr(...args) {
- preventXhrFn(false, ...args);
+function setConstant(
+ ...args
+) {
+ setConstantFn(false, ...args);
};
-preventXhr(...args);
+setConstant(...args);
},
};
-scriptlets['trusted-prevent-xhr.js'] = {
-aliases: [],
+scriptlets['trusted-set-constant.js'] = {
+aliases: ["trusted-set.js"],
-requiresTrust: false,
+requiresTrust: true,
func: function (scriptletGlobals = {}, ...args) {
-function proxyApplyFn(
- target = '',
- handler = '',
- options = {}
-) {
- let context = globalThis;
- let prop = target;
- for (;;) {
- const pos = prop.indexOf('.');
- if ( pos === -1 ) { break; }
- context = context[prop.slice(0, pos)];
- if ( context instanceof Object === false ) { return; }
- prop = prop.slice(pos+1);
- }
- const fn = context[prop];
- if ( typeof fn !== 'function' ) { return; }
- if ( proxyApplyFn.CtorContext === undefined ) {
- proxyApplyFn.ctorContexts = [];
- proxyApplyFn.CtorContext = class {
- constructor(...args) {
- this.init(...args);
- }
- init(callFn, callArgs) {
- this.callFn = callFn;
- this.callArgs = callArgs;
- return this;
- }
- reflect() {
- const r = Reflect.construct(this.callFn, this.callArgs);
- this.callFn = this.callArgs = this.private = undefined;
- proxyApplyFn.ctorContexts.push(this);
- return r;
- }
- static factory(...args) {
- return proxyApplyFn.ctorContexts.length !== 0
- ? proxyApplyFn.ctorContexts.pop().init(...args)
- : new proxyApplyFn.CtorContext(...args);
- }
- };
- proxyApplyFn.applyContexts = [];
- proxyApplyFn.ApplyContext = class {
- constructor(...args) {
- this.init(...args);
- }
- init(callFn, thisArg, callArgs) {
- this.callFn = callFn;
- this.thisArg = thisArg;
- this.callArgs = callArgs;
- return this;
- }
- reflect() {
- const r = Reflect.apply(this.callFn, this.thisArg, this.callArgs);
- this.callFn = this.thisArg = this.callArgs = this.private = undefined;
- proxyApplyFn.applyContexts.push(this);
- return r;
- }
- static factory(...args) {
- return proxyApplyFn.applyContexts.length !== 0
- ? proxyApplyFn.applyContexts.pop().init(...args)
- : new proxyApplyFn.ApplyContext(...args);
- }
- };
- proxyApplyFn.isCtor = new Map();
- proxyApplyFn.proxies = new WeakMap();
- if ( (options.skipToString || proxyApplyFn.skipToString) !== true ) {
- proxyApplyFn.nativeToString = Function.prototype.toString;
- const proxiedToString = new Proxy(Function.prototype.toString, {
- apply(target, thisArg) {
- let proxied = thisArg;
- for(;;) {
- const fn = proxyApplyFn.proxies.get(proxied);
- if ( fn === undefined ) { break; }
- proxied = fn;
- }
- return proxyApplyFn.nativeToString.call(proxied);
- }
- });
- proxyApplyFn.proxies.set(proxiedToString, proxyApplyFn.nativeToString);
- Function.prototype.toString = proxiedToString;
- }
- }
- if ( proxyApplyFn.isCtor.has(target) === false ) {
- proxyApplyFn.isCtor.set(target, fn.prototype?.constructor === fn);
- }
- const proxyDetails = {
- apply(target, thisArg, args) {
- return handler(proxyApplyFn.ApplyContext.factory(target, thisArg, args));
- }
- };
- if ( proxyApplyFn.isCtor.get(target) ) {
- proxyDetails.construct = function(target, args) {
- return handler(proxyApplyFn.CtorContext.factory(target, args));
- };
- }
- const proxiedTarget = new Proxy(fn, proxyDetails);
- proxyApplyFn.proxies.set(proxiedTarget, fn);
- context[prop] = proxiedTarget;
-}
-function parsePropertiesToMatchFn(propsToMatch, implicit = '') {
+function validateConstantFn(trusted, raw, extraArgs = {}) {
const safe = safeSelf();
- const needles = new Map();
- if ( propsToMatch === undefined || propsToMatch === '' ) { return needles; }
- const options = { canNegate: true };
- for ( const needle of safe.String_split.call(propsToMatch, /\s+/) ) {
- let [ prop, pattern ] = safe.String_split.call(needle, ':');
- if ( prop === '' ) { continue; }
- if ( pattern !== undefined && /[^$\w -]/.test(prop) ) {
- prop = `${prop}:${pattern}`;
- pattern = undefined;
- }
- if ( pattern !== undefined ) {
- needles.set(prop, safe.initPattern(pattern, options));
- } else if ( implicit !== '' ) {
- needles.set(implicit, safe.initPattern(prop, options));
+ let value;
+ if ( raw === 'undefined' ) {
+ value = undefined;
+ } else if ( raw === 'false' ) {
+ value = false;
+ } else if ( raw === 'true' ) {
+ value = true;
+ } else if ( raw === 'null' ) {
+ value = null;
+ } else if ( raw === "''" || raw === '' ) {
+ value = '';
+ } else if ( raw === '[]' || raw === 'emptyArr' ) {
+ value = [];
+ } else if ( raw === '{}' || raw === 'emptyObj' ) {
+ value = {};
+ } else if ( raw === 'noopFunc' ) {
+ value = function(){};
+ } else if ( raw === 'trueFunc' ) {
+ value = function(){ return true; };
+ } else if ( raw === 'falseFunc' ) {
+ value = function(){ return false; };
+ } else if ( raw === 'throwFunc' ) {
+ value = function(){ throw ''; };
+ } else if ( /^-?\d+$/.test(raw) ) {
+ value = parseInt(raw);
+ if ( isNaN(raw) ) { return; }
+ if ( Math.abs(raw) > 0x7FFF ) { return; }
+ } else if ( trusted ) {
+ if ( raw.startsWith('json:') ) {
+ try { value = safe.JSON_parse(raw.slice(5)); } catch { return; }
+ } else if ( raw.startsWith('{') && raw.endsWith('}') ) {
+ try { value = safe.JSON_parse(raw).value; } catch { return; }
}
+ } else {
+ return;
}
- return needles;
-}
-function matchObjectPropertiesFn(propNeedles, ...objs) {
- const safe = safeSelf();
- const matched = [];
- for ( const obj of objs ) {
- if ( obj instanceof Object === false ) { continue; }
- for ( const [ prop, details ] of propNeedles ) {
- let value = obj[prop];
- if ( value === undefined ) { continue; }
- if ( typeof value !== 'string' ) {
- try { value = safe.JSON_stringify(value); }
- catch { }
- if ( typeof value !== 'string' ) { continue; }
- }
- if ( safe.testPattern(details, value) === false ) { return; }
- matched.push(`${prop}: ${value}`);
+ if ( extraArgs.as !== undefined ) {
+ if ( extraArgs.as === 'function' ) {
+ return ( ) => value;
+ } else if ( extraArgs.as === 'callback' ) {
+ return ( ) => (( ) => value);
+ } else if ( extraArgs.as === 'resolved' ) {
+ return Promise.resolve(value);
+ } else if ( extraArgs.as === 'rejected' ) {
+ return Promise.reject(value);
}
}
- return matched;
+ return value;
}
function safeSelf() {
if ( safeSelf.safe ) {
@@ -33140,8 +32768,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -33154,7 +32781,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -33165,10 +32792,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -33221,7 +32846,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -33309,601 +32934,128 @@ function safeSelf() {
}
return safe;
}
-function generateContentFn(trusted, directive) {
- const safe = safeSelf();
- const randomize = len => {
- const chunks = [];
- let textSize = 0;
- do {
- const s = safe.Math_random().toString(36).slice(2);
- chunks.push(s);
- textSize += s.length;
+function runAt(fn, when) {
+ const intFromReadyState = state => {
+ const targets = {
+ 'loading': 1, 'asap': 1,
+ 'interactive': 2, 'end': 2, '2': 2,
+ 'complete': 3, 'idle': 3, '3': 3,
+ };
+ const tokens = Array.isArray(state) ? state : [ state ];
+ for ( const token of tokens ) {
+ const prop = `${token}`;
+ if ( Object.hasOwn(targets, prop) === false ) { continue; }
+ return targets[prop];
}
- while ( textSize < len );
- return chunks.join(' ').slice(0, len);
+ return 0;
};
- if ( directive === 'true' ) {
- return randomize(10);
- }
- if ( directive === 'emptyObj' ) {
- return '{}';
- }
- if ( directive === 'emptyArr' ) {
- return '[]';
- }
- if ( directive === 'emptyStr' ) {
- return '';
- }
- if ( directive.startsWith('length:') ) {
- const match = /^length:(\d+)(?:-(\d+))?$/.exec(directive);
- if ( match === null ) { return ''; }
- const min = parseInt(match[1], 10);
- const extent = safe.Math_max(parseInt(match[2], 10) || 0, min) - min;
- const len = safe.Math_min(min + extent * safe.Math_random(), 500000);
- return randomize(len | 0);
- }
- if ( directive.startsWith('war:') ) {
- if ( scriptletGlobals.warOrigin === undefined ) { return ''; }
- return new Promise(resolve => {
- const warOrigin = scriptletGlobals.warOrigin;
- const warName = directive.slice(4);
- const fullpath = [ warOrigin, '/', warName ];
- const warSecret = scriptletGlobals.warSecret;
- if ( warSecret !== undefined ) {
- fullpath.push('?secret=', warSecret);
- }
- const warXHR = new safe.XMLHttpRequest();
- warXHR.responseType = 'text';
- warXHR.onloadend = ev => {
- resolve(ev.target.responseText || '');
- };
- warXHR.open('GET', fullpath.join(''));
- warXHR.send();
- }).catch(( ) => '');
- }
- if ( directive.startsWith('join:') ) {
- const parts = directive.slice(7)
- .split(directive.slice(5, 7))
- .map(a => generateContentFn(trusted, a));
- return parts.some(a => a instanceof Promise)
- ? Promise.all(parts).then(parts => parts.join(''))
- : parts.join('');
- }
- if ( trusted ) {
- return directive;
+ const runAt = intFromReadyState(when);
+ if ( intFromReadyState(document.readyState) >= runAt ) {
+ fn(); return;
}
- return '';
+ const onStateChange = ( ) => {
+ if ( intFromReadyState(document.readyState) < runAt ) { return; }
+ fn();
+ safe.removeEventListener.apply(document, args);
+ };
+ const safe = safeSelf();
+ const args = [ 'readystatechange', onStateChange, { capture: true } ];
+ safe.addEventListener.apply(document, args);
}
-function preventXhrFn(
+function setConstantFn(
trusted = false,
- propsToMatch = '',
- directive = ''
+ chain = '',
+ rawValue = '',
+ ...varargs
) {
- if ( typeof propsToMatch !== 'string' ) { return; }
+ if ( chain === '' ) { return; }
const safe = safeSelf();
- const scriptletName = trusted ? 'trusted-prevent-xhr' : 'prevent-xhr';
- const logPrefix = safe.makeLogPrefix(scriptletName, propsToMatch, directive);
- const xhrInstances = new WeakMap();
- const propNeedles = parsePropertiesToMatchFn(propsToMatch, 'url');
- const warOrigin = scriptletGlobals.warOrigin;
- const safeDispatchEvent = (xhr, type) => {
- try {
- xhr.dispatchEvent(new Event(type));
- } catch {
- }
- };
- proxyApplyFn('XMLHttpRequest.prototype.open', function(context) {
- const { thisArg, callArgs } = context;
- xhrInstances.delete(thisArg);
- const [ method, url, ...args ] = callArgs;
- if ( warOrigin !== undefined && url.startsWith(warOrigin) ) {
- return context.reflect();
- }
- const haystack = { method, url };
- if ( propsToMatch === '' && directive === '' ) {
- safe.uboLog(logPrefix, `Called: ${safe.JSON_stringify(haystack, null, 2)}`);
- return context.reflect();
- }
- if ( matchObjectPropertiesFn(propNeedles, haystack) ) {
- const xhrDetails = Object.assign(haystack, {
- xhr: thisArg,
- defer: args.length === 0 || !!args[0],
- directive,
- headers: {
- 'date': '',
- 'content-type': '',
- 'content-length': '',
+ const logPrefix = safe.makeLogPrefix('set-constant', chain, rawValue);
+ const extraArgs = safe.parseVarargs(varargs);
+ function setConstant(chain, rawValue) {
+ const trappedProp = (( ) => {
+ const pos = chain.lastIndexOf('.');
+ if ( pos === -1 ) { return chain; }
+ return chain.slice(pos+1);
+ })();
+ const cloakFunc = fn => {
+ safe.Object_defineProperty(fn, 'name', { value: trappedProp });
+ return new Proxy(fn, {
+ defineProperty(target, prop) {
+ if ( prop !== 'toString' ) {
+ return Reflect.defineProperty(...arguments);
+ }
+ return true;
},
- url: haystack.url,
- props: {
- response: { value: '' },
- responseText: { value: '' },
- responseXML: { value: null },
+ deleteProperty(target, prop) {
+ if ( prop !== 'toString' ) {
+ return Reflect.deleteProperty(...arguments);
+ }
+ return true;
+ },
+ get(target, prop) {
+ if ( prop === 'toString' ) {
+ return function() {
+ return `function ${trappedProp}() { [native code] }`;
+ }.bind(null);
+ }
+ return Reflect.get(...arguments);
},
});
- xhrInstances.set(thisArg, xhrDetails);
- }
- return context.reflect();
- });
- proxyApplyFn('XMLHttpRequest.prototype.send', function(context) {
- const { thisArg } = context;
- const xhrDetails = xhrInstances.get(thisArg);
- if ( xhrDetails === undefined ) {
- return context.reflect();
- }
- xhrDetails.headers['date'] = (new Date()).toUTCString();
- let xhrText = '';
- switch ( thisArg.responseType ) {
- case 'arraybuffer':
- xhrDetails.props.response.value = new ArrayBuffer(0);
- xhrDetails.headers['content-type'] = 'application/octet-stream';
- break;
- case 'blob':
- xhrDetails.props.response.value = new Blob([]);
- xhrDetails.headers['content-type'] = 'application/octet-stream';
- break;
- case 'document': {
- const parser = new DOMParser();
- const doc = parser.parseFromString('', 'text/html');
- xhrDetails.props.response.value = doc;
- xhrDetails.props.responseXML.value = doc;
- xhrDetails.headers['content-type'] = 'text/html';
- break;
+ };
+ if ( trappedProp === '' ) { return; }
+ const thisScript = document.currentScript;
+ let normalValue = validateConstantFn(trusted, rawValue, extraArgs);
+ if ( rawValue === 'noopFunc' || rawValue === 'trueFunc' || rawValue === 'falseFunc' ) {
+ normalValue = cloakFunc(normalValue);
}
- case 'json':
- xhrDetails.props.response.value = {};
- xhrDetails.props.responseText.value = '{}';
- xhrDetails.headers['content-type'] = 'application/json';
- break;
- default: {
- if ( directive === '' ) { break; }
- xhrText = generateContentFn(trusted, xhrDetails.directive);
- if ( xhrText instanceof Promise ) {
- xhrText = xhrText.then(text => {
- xhrDetails.props.response.value = text;
- xhrDetails.props.responseText.value = text;
+ let aborted = false;
+ const mustAbort = function(v) {
+ if ( trusted ) { return false; }
+ if ( aborted ) { return true; }
+ aborted =
+ (v !== undefined && v !== null) &&
+ (normalValue !== undefined && normalValue !== null) &&
+ (typeof v !== typeof normalValue);
+ if ( aborted ) {
+ safe.uboLog(logPrefix, `Aborted because value set to ${v}`);
+ }
+ return aborted;
+ };
+ // https://github.com/uBlockOrigin/uBlock-issues/issues/156
+ // Support multiple trappers for the same property.
+ const trapProp = function(owner, prop, configurable, handler) {
+ if ( handler.init(configurable ? owner[prop] : normalValue) === false ) { return; }
+ const odesc = safe.Object_getOwnPropertyDescriptor(owner, prop);
+ let prevGetter, prevSetter;
+ if ( odesc instanceof safe.Object ) {
+ owner[prop] = normalValue;
+ if ( odesc.get instanceof Function ) {
+ prevGetter = odesc.get;
+ }
+ if ( odesc.set instanceof Function ) {
+ prevSetter = odesc.set;
+ }
+ }
+ try {
+ safe.Object_defineProperty(owner, prop, {
+ configurable,
+ get() {
+ if ( prevGetter !== undefined ) {
+ prevGetter();
+ }
+ return handler.getter();
+ },
+ set(a) {
+ if ( prevSetter !== undefined ) {
+ prevSetter(a);
+ }
+ handler.setter(a);
+ }
});
- } else {
- xhrDetails.props.response.value = xhrText;
- xhrDetails.props.responseText.value = xhrText;
- }
- xhrDetails.headers['content-type'] = 'text/plain';
- break;
- }
- }
- if ( xhrDetails.defer === false ) {
- xhrDetails.headers['content-length'] = `${xhrDetails.props.response.value}`.length;
- Object.defineProperties(xhrDetails.xhr, {
- readyState: { value: 4 },
- responseURL: { value: xhrDetails.url },
- status: { value: 200 },
- statusText: { value: 'OK' },
- });
- Object.defineProperties(xhrDetails.xhr, xhrDetails.props);
- return;
- }
- Promise.resolve(xhrText).then(( ) => xhrDetails).then(details => {
- Object.defineProperties(details.xhr, {
- readyState: { value: 1, configurable: true },
- responseURL: { value: xhrDetails.url },
- });
- safeDispatchEvent(details.xhr, 'readystatechange');
- return details;
- }).then(details => {
- xhrDetails.headers['content-length'] = `${details.props.response.value}`.length;
- Object.defineProperties(details.xhr, {
- readyState: { value: 2, configurable: true },
- status: { value: 200 },
- statusText: { value: 'OK' },
- });
- safeDispatchEvent(details.xhr, 'readystatechange');
- return details;
- }).then(details => {
- Object.defineProperties(details.xhr, {
- readyState: { value: 3, configurable: true },
- });
- Object.defineProperties(details.xhr, details.props);
- safeDispatchEvent(details.xhr, 'readystatechange');
- return details;
- }).then(details => {
- Object.defineProperties(details.xhr, {
- readyState: { value: 4 },
- });
- safeDispatchEvent(details.xhr, 'readystatechange');
- safeDispatchEvent(details.xhr, 'load');
- safeDispatchEvent(details.xhr, 'loadend');
- safe.uboLog(logPrefix, `Prevented with response:\n${details.xhr.response}`);
- });
- });
- proxyApplyFn('XMLHttpRequest.prototype.getResponseHeader', function(context) {
- const { thisArg } = context;
- const xhrDetails = xhrInstances.get(thisArg);
- if ( xhrDetails === undefined || thisArg.readyState < thisArg.HEADERS_RECEIVED ) {
- return context.reflect();
- }
- const headerName = `${context.callArgs[0]}`;
- const value = xhrDetails.headers[headerName.toLowerCase()];
- if ( value !== undefined && value !== '' ) { return value; }
- return null;
- });
- proxyApplyFn('XMLHttpRequest.prototype.getAllResponseHeaders', function(context) {
- const { thisArg } = context;
- const xhrDetails = xhrInstances.get(thisArg);
- if ( xhrDetails === undefined || thisArg.readyState < thisArg.HEADERS_RECEIVED ) {
- return context.reflect();
- }
- const out = [];
- for ( const [ name, value ] of Object.entries(xhrDetails.headers) ) {
- if ( !value ) { continue; }
- out.push(`${name}: ${value}`);
- }
- if ( out.length !== 0 ) { out.push(''); }
- return out.join('\r\n');
- });
-}
-function trustedPreventXhr(...args) {
- preventXhrFn(true, ...args);
-};
-trustedPreventXhr(...args);
-},
-};
-
-
-scriptlets['set-constant.js'] = {
-aliases: ["set.js"],
-
-requiresTrust: false,
-func: function (scriptletGlobals = {}, ...args) {
-function validateConstantFn(trusted, raw, extraArgs = {}) {
- const safe = safeSelf();
- let value;
- if ( raw === 'undefined' ) {
- value = undefined;
- } else if ( raw === 'false' ) {
- value = false;
- } else if ( raw === 'true' ) {
- value = true;
- } else if ( raw === 'null' ) {
- value = null;
- } else if ( raw === "''" || raw === '' ) {
- value = '';
- } else if ( raw === '[]' || raw === 'emptyArr' ) {
- value = [];
- } else if ( raw === '{}' || raw === 'emptyObj' ) {
- value = {};
- } else if ( raw === 'noopFunc' ) {
- value = function(){};
- } else if ( raw === 'trueFunc' ) {
- value = function(){ return true; };
- } else if ( raw === 'falseFunc' ) {
- value = function(){ return false; };
- } else if ( raw === 'throwFunc' ) {
- value = function(){ throw ''; };
- } else if ( /^-?\d+$/.test(raw) ) {
- value = parseInt(raw);
- if ( isNaN(raw) ) { return; }
- if ( Math.abs(raw) > 0x7FFF ) { return; }
- } else if ( trusted ) {
- if ( raw.startsWith('json:') ) {
- try { value = safe.JSON_parse(raw.slice(5)); } catch { return; }
- } else if ( raw.startsWith('{') && raw.endsWith('}') ) {
- try { value = safe.JSON_parse(raw).value; } catch { return; }
- }
- } else {
- return;
- }
- if ( extraArgs.as !== undefined ) {
- if ( extraArgs.as === 'function' ) {
- return ( ) => value;
- } else if ( extraArgs.as === 'callback' ) {
- return ( ) => (( ) => value);
- } else if ( extraArgs.as === 'resolved' ) {
- return Promise.resolve(value);
- } else if ( extraArgs.as === 'rejected' ) {
- return Promise.reject(value);
- }
- }
- return value;
-}
-function safeSelf() {
- if ( safeSelf.safe ) {
- return safeSelf.safe;
- }
- const self = globalThis;
- const safe = {
- 'Array_from': Array.from,
- 'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
- 'Math_floor': Math.floor,
- 'Math_max': Math.max,
- 'Math_min': Math.min,
- 'Math_random': Math.random,
- 'Object': Object,
- 'Object_defineProperty': Object.defineProperty.bind(Object),
- 'Object_defineProperties': Object.defineProperties.bind(Object),
- 'Object_fromEntries': Object.fromEntries.bind(Object),
- 'Object_getOwnPropertyDescriptor': Object.getOwnPropertyDescriptor.bind(Object),
- 'Object_hasOwn': Object.hasOwn.bind(Object),
- 'Object_toString': Object.prototype.toString,
- 'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
- 'RegExp_exec': self.RegExp.prototype.exec,
- 'Request_clone': self.Request.prototype.clone,
- 'String': self.String,
- 'String_fromCharCode': String.fromCharCode,
- 'String_split': String.prototype.split,
- 'XMLHttpRequest': self.XMLHttpRequest,
- 'addEventListener': self.EventTarget.prototype.addEventListener,
- 'removeEventListener': self.EventTarget.prototype.removeEventListener,
- 'fetch': self.fetch,
- 'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
- 'log': console.log.bind(console),
- // Properties
- logLevel: 0,
- // Methods
- makeLogPrefix(...args) {
- return this.sendToLogger && `[${args.join(' \u205D ')}]` || '';
- },
- uboLog(...args) {
- if ( this.sendToLogger === undefined ) { return; }
- if ( args === undefined || args[0] === '' ) { return; }
- return this.sendToLogger('info', ...args);
-
- },
- uboErr(...args) {
- if ( this.sendToLogger === undefined ) { return; }
- if ( args === undefined || args[0] === '' ) { return; }
- return this.sendToLogger('error', ...args);
- },
- escapeRegexChars(s) {
- return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
- },
- initPattern(pattern, options = {}) {
- if ( pattern === '' ) {
- return { matchAll: true, expect: true };
- }
- const expect = (options.canNegate !== true || pattern.startsWith('!') === false);
- if ( expect === false ) {
- pattern = pattern.slice(1);
- }
- const match = /^\/(.+)\/([gimsu]*)$/.exec(pattern);
- if ( match !== null ) {
- return {
- re: new this.RegExp(
- match[1],
- match[2] || options.flags
- ),
- expect,
- };
- }
- if ( options.flags !== undefined ) {
- return {
- re: new this.RegExp(this.escapeRegexChars(pattern),
- options.flags
- ),
- expect,
- };
- }
- return { pattern, expect };
- },
- testPattern(details, haystack) {
- if ( details.matchAll ) { return true; }
- if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
- }
- return haystack.includes(details.pattern) === details.expect;
- },
- patternToRegex(pattern, flags = undefined, verbatim = false) {
- if ( pattern === '' ) { return /^/; }
- const match = /^\/(.+)\/([gimsu]*)$/.exec(pattern);
- if ( match === null ) {
- const reStr = this.escapeRegexChars(pattern);
- return new RegExp(verbatim ? `^${reStr}$` : reStr, flags);
- }
- try {
- return new RegExp(match[1], match[2] || undefined);
- }
- catch {
- }
- return /^/;
- },
- parseVarargs(varargs) {
- const entries = varargs.reduce((out, v, i, a) => {
- if ( i & 1 ) { return out; }
- const rawValue = a[i+1];
- const value = /^\d+$/.test(rawValue)
- ? parseInt(rawValue, 10)
- : rawValue;
- out.push([ a[i], value ]);
- return out;
- }, []);
- return this.Object_fromEntries(entries);
- },
- };
- safeSelf.safe = safe;
- if ( scriptletGlobals.bcSecret === undefined ) { return safe; }
- // This is executed only when the logger is opened
- safe.logLevel = scriptletGlobals.logLevel || 1;
- let lastLogType = '';
- let lastLogText = '';
- let lastLogTime = 0;
- safe.toLogText = (type, ...args) => {
- if ( args.length === 0 ) { return; }
- const text = `[${document.location.hostname || document.location.href}]${args.join(' ')}`;
- if ( text === lastLogText && type === lastLogType ) {
- if ( (Date.now() - lastLogTime) < 5000 ) { return; }
- }
- lastLogType = type;
- lastLogText = text;
- lastLogTime = Date.now();
- return text;
- };
- try {
- const bc = new self.BroadcastChannel(scriptletGlobals.bcSecret);
- let bcBuffer = [];
- safe.sendToLogger = (type, ...args) => {
- const text = safe.toLogText(type, ...args);
- if ( text === undefined ) { return; }
- if ( bcBuffer === undefined ) {
- return bc.postMessage({ what: 'messageToLogger', type, text });
- }
- bcBuffer.push({ type, text });
- };
- bc.onmessage = ev => {
- const msg = ev.data;
- switch ( msg ) {
- case 'iamready!':
- if ( bcBuffer === undefined ) { break; }
- bcBuffer.forEach(({ type, text }) =>
- bc.postMessage({ what: 'messageToLogger', type, text })
- );
- bcBuffer = undefined;
- break;
- case 'setScriptletLogLevelToOne':
- safe.logLevel = 1;
- break;
- case 'setScriptletLogLevelToTwo':
- safe.logLevel = 2;
- break;
- }
- };
- bc.postMessage('areyouready?');
- } catch {
- safe.sendToLogger = (type, ...args) => {
- const text = safe.toLogText(type, ...args);
- if ( text === undefined ) { return; }
- safe.log(`uBO ${text}`);
- };
- }
- return safe;
-}
-function runAt(fn, when) {
- const intFromReadyState = state => {
- const targets = {
- 'loading': 1, 'asap': 1,
- 'interactive': 2, 'end': 2, '2': 2,
- 'complete': 3, 'idle': 3, '3': 3,
- };
- const tokens = Array.isArray(state) ? state : [ state ];
- for ( const token of tokens ) {
- const prop = `${token}`;
- if ( Object.hasOwn(targets, prop) === false ) { continue; }
- return targets[prop];
- }
- return 0;
- };
- const runAt = intFromReadyState(when);
- if ( intFromReadyState(document.readyState) >= runAt ) {
- fn(); return;
- }
- const onStateChange = ( ) => {
- if ( intFromReadyState(document.readyState) < runAt ) { return; }
- fn();
- safe.removeEventListener.apply(document, args);
- };
- const safe = safeSelf();
- const args = [ 'readystatechange', onStateChange, { capture: true } ];
- safe.addEventListener.apply(document, args);
-}
-function setConstantFn(
- trusted = false,
- chain = '',
- rawValue = '',
- ...varargs
-) {
- if ( chain === '' ) { return; }
- const safe = safeSelf();
- const logPrefix = safe.makeLogPrefix('set-constant', chain, rawValue);
- const extraArgs = safe.parseVarargs(varargs);
- function setConstant(chain, rawValue) {
- const trappedProp = (( ) => {
- const pos = chain.lastIndexOf('.');
- if ( pos === -1 ) { return chain; }
- return chain.slice(pos+1);
- })();
- const cloakFunc = fn => {
- safe.Object_defineProperty(fn, 'name', { value: trappedProp });
- return new Proxy(fn, {
- defineProperty(target, prop) {
- if ( prop !== 'toString' ) {
- return Reflect.defineProperty(...arguments);
- }
- return true;
- },
- deleteProperty(target, prop) {
- if ( prop !== 'toString' ) {
- return Reflect.deleteProperty(...arguments);
- }
- return true;
- },
- get(target, prop) {
- if ( prop === 'toString' ) {
- return function() {
- return `function ${trappedProp}() { [native code] }`;
- }.bind(null);
- }
- return Reflect.get(...arguments);
- },
- });
- };
- if ( trappedProp === '' ) { return; }
- const thisScript = document.currentScript;
- let normalValue = validateConstantFn(trusted, rawValue, extraArgs);
- if ( rawValue === 'noopFunc' || rawValue === 'trueFunc' || rawValue === 'falseFunc' ) {
- normalValue = cloakFunc(normalValue);
- }
- let aborted = false;
- const mustAbort = function(v) {
- if ( trusted ) { return false; }
- if ( aborted ) { return true; }
- aborted =
- (v !== undefined && v !== null) &&
- (normalValue !== undefined && normalValue !== null) &&
- (typeof v !== typeof normalValue);
- if ( aborted ) {
- safe.uboLog(logPrefix, `Aborted because value set to ${v}`);
- }
- return aborted;
- };
- // https://github.com/uBlockOrigin/uBlock-issues/issues/156
- // Support multiple trappers for the same property.
- const trapProp = function(owner, prop, configurable, handler) {
- if ( handler.init(configurable ? owner[prop] : normalValue) === false ) { return; }
- const odesc = safe.Object_getOwnPropertyDescriptor(owner, prop);
- let prevGetter, prevSetter;
- if ( odesc instanceof safe.Object ) {
- owner[prop] = normalValue;
- if ( odesc.get instanceof Function ) {
- prevGetter = odesc.get;
- }
- if ( odesc.set instanceof Function ) {
- prevSetter = odesc.set;
- }
- }
- try {
- safe.Object_defineProperty(owner, prop, {
- configurable,
- get() {
- if ( prevGetter !== undefined ) {
- prevGetter();
- }
- return handler.getter();
- },
- set(a) {
- if ( prevSetter !== undefined ) {
- prevSetter(a);
- }
- handler.setter(a);
- }
- });
- safe.uboLog(logPrefix, 'Trap installed');
- } catch(ex) {
- safe.uboErr(logPrefix, ex);
+ safe.uboLog(logPrefix, 'Trap installed');
+ } catch(ex) {
+ safe.uboErr(logPrefix, ex);
}
};
const trapChain = function(owner, chain) {
@@ -33960,18 +33112,18 @@ function setConstantFn(
setConstant(chain, rawValue);
}, extraArgs.runAt);
}
-function setConstant(
+function trustedSetConstant(
...args
) {
- setConstantFn(false, ...args);
+ setConstantFn(true, ...args);
};
-setConstant(...args);
+trustedSetConstant(...args);
},
};
-scriptlets['trusted-set-constant.js'] = {
-aliases: ["trusted-set.js"],
+scriptlets['trusted-replace-argument.js'] = {
+aliases: [],
requiresTrust: true,
func: function (scriptletGlobals = {}, ...args) {
@@ -34034,8 +33186,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -34048,7 +33199,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -34059,10 +33210,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -34115,7 +33264,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -34203,249 +33352,1285 @@ function safeSelf() {
}
return safe;
}
-function runAt(fn, when) {
- const intFromReadyState = state => {
- const targets = {
- 'loading': 1, 'asap': 1,
- 'interactive': 2, 'end': 2, '2': 2,
- 'complete': 3, 'idle': 3, '3': 3,
+function proxyApplyFn(
+ target = '',
+ handler = '',
+ options = {}
+) {
+ let context = globalThis;
+ let prop = target;
+ for (;;) {
+ const pos = prop.indexOf('.');
+ if ( pos === -1 ) { break; }
+ context = context[prop.slice(0, pos)];
+ if ( context instanceof Object === false ) { return; }
+ prop = prop.slice(pos+1);
+ }
+ const fn = context[prop];
+ if ( typeof fn !== 'function' ) { return; }
+ if ( proxyApplyFn.CtorContext === undefined ) {
+ proxyApplyFn.ctorContexts = [];
+ proxyApplyFn.CtorContext = class {
+ constructor(...args) {
+ this.init(...args);
+ }
+ init(callFn, callArgs) {
+ this.callFn = callFn;
+ this.callArgs = callArgs;
+ return this;
+ }
+ reflect() {
+ const r = Reflect.construct(this.callFn, this.callArgs);
+ this.callFn = this.callArgs = this.private = undefined;
+ proxyApplyFn.ctorContexts.push(this);
+ return r;
+ }
+ static factory(...args) {
+ return proxyApplyFn.ctorContexts.length !== 0
+ ? proxyApplyFn.ctorContexts.pop().init(...args)
+ : new proxyApplyFn.CtorContext(...args);
+ }
};
- const tokens = Array.isArray(state) ? state : [ state ];
- for ( const token of tokens ) {
- const prop = `${token}`;
- if ( Object.hasOwn(targets, prop) === false ) { continue; }
- return targets[prop];
+ proxyApplyFn.applyContexts = [];
+ proxyApplyFn.ApplyContext = class {
+ constructor(...args) {
+ this.init(...args);
+ }
+ init(callFn, thisArg, callArgs) {
+ this.callFn = callFn;
+ this.thisArg = thisArg;
+ this.callArgs = callArgs;
+ return this;
+ }
+ reflect() {
+ const r = Reflect.apply(this.callFn, this.thisArg, this.callArgs);
+ this.callFn = this.thisArg = this.callArgs = this.private = undefined;
+ proxyApplyFn.applyContexts.push(this);
+ return r;
+ }
+ static factory(...args) {
+ return proxyApplyFn.applyContexts.length !== 0
+ ? proxyApplyFn.applyContexts.pop().init(...args)
+ : new proxyApplyFn.ApplyContext(...args);
+ }
+ };
+ proxyApplyFn.isCtor = new Map();
+ proxyApplyFn.proxies = new WeakMap();
+ if ( (options.skipToString || proxyApplyFn.skipToString) !== true ) {
+ proxyApplyFn.nativeToString = Function.prototype.toString;
+ const proxiedToString = new Proxy(Function.prototype.toString, {
+ apply(target, thisArg) {
+ let proxied = thisArg;
+ for(;;) {
+ const fn = proxyApplyFn.proxies.get(proxied);
+ if ( fn === undefined ) { break; }
+ proxied = fn;
+ }
+ return proxyApplyFn.nativeToString.call(proxied);
+ }
+ });
+ proxyApplyFn.proxies.set(proxiedToString, proxyApplyFn.nativeToString);
+ Function.prototype.toString = proxiedToString;
+ }
+ }
+ if ( proxyApplyFn.isCtor.has(target) === false ) {
+ proxyApplyFn.isCtor.set(target, fn.prototype?.constructor === fn);
+ }
+ const proxyDetails = {
+ apply(target, thisArg, args) {
+ return handler(proxyApplyFn.ApplyContext.factory(target, thisArg, args));
}
- return 0;
};
- const runAt = intFromReadyState(when);
- if ( intFromReadyState(document.readyState) >= runAt ) {
- fn(); return;
+ if ( proxyApplyFn.isCtor.get(target) ) {
+ proxyDetails.construct = function(target, args) {
+ return handler(proxyApplyFn.CtorContext.factory(target, args));
+ };
+ }
+ const proxiedTarget = new Proxy(fn, proxyDetails);
+ proxyApplyFn.proxies.set(proxiedTarget, fn);
+ context[prop] = proxiedTarget;
+}
+class ArglistParser {
+ constructor(separatorChar = ',', mustQuote = false) {
+ this.separatorChar = this.actualSeparatorChar = separatorChar;
+ this.separatorCode = this.actualSeparatorCode = separatorChar.charCodeAt(0);
+ this.mustQuote = mustQuote;
+ this.quoteBeg = 0; this.quoteEnd = 0;
+ this.argBeg = 0; this.argEnd = 0;
+ this.separatorBeg = 0; this.separatorEnd = 0;
+ this.transform = false;
+ this.failed = false;
+ this.reWhitespaceStart = /^\s+/;
+ this.reWhitespaceEnd = /(?:^|\S)(\s+)$/;
+ this.reOddTrailingEscape = /(?:^|[^\\])(?:\\\\)*\\$/;
+ this.reTrailingEscapeChars = /\\+$/;
+ }
+ nextArg(pattern, beg = 0) {
+ const len = pattern.length;
+ this.quoteBeg = beg + this.leftWhitespaceCount(pattern.slice(beg));
+ this.failed = false;
+ const qc = pattern.charCodeAt(this.quoteBeg);
+ if ( qc === 0x22 /* " */ || qc === 0x27 /* ' */ || qc === 0x60 /* ` */ ) {
+ this.indexOfNextArgSeparator(pattern, qc);
+ if ( this.argEnd !== len ) {
+ this.quoteEnd = this.argEnd + 1;
+ this.separatorBeg = this.separatorEnd = this.quoteEnd;
+ this.separatorEnd += this.leftWhitespaceCount(pattern.slice(this.quoteEnd));
+ if ( this.separatorEnd === len ) { return this; }
+ if ( pattern.charCodeAt(this.separatorEnd) === this.separatorCode ) {
+ this.separatorEnd += 1;
+ return this;
+ }
+ }
+ }
+ this.indexOfNextArgSeparator(pattern, this.separatorCode);
+ this.separatorBeg = this.separatorEnd = this.argEnd;
+ if ( this.separatorBeg < len ) {
+ this.separatorEnd += 1;
+ }
+ this.argEnd -= this.rightWhitespaceCount(pattern.slice(0, this.separatorBeg));
+ this.quoteEnd = this.argEnd;
+ if ( this.mustQuote ) {
+ this.failed = true;
+ }
+ return this;
+ }
+ normalizeArg(s, char = '') {
+ if ( char === '' ) { char = this.actualSeparatorChar; }
+ let out = '';
+ let pos = 0;
+ while ( (pos = s.lastIndexOf(char)) !== -1 ) {
+ out = s.slice(pos) + out;
+ s = s.slice(0, pos);
+ const match = this.reTrailingEscapeChars.exec(s);
+ if ( match === null ) { continue; }
+ const tail = (match[0].length & 1) !== 0
+ ? match[0].slice(0, -1)
+ : match[0];
+ out = tail + out;
+ s = s.slice(0, -match[0].length);
+ }
+ if ( out === '' ) { return s; }
+ return s + out;
+ }
+ leftWhitespaceCount(s) {
+ const match = this.reWhitespaceStart.exec(s);
+ return match === null ? 0 : match[0].length;
+ }
+ rightWhitespaceCount(s) {
+ const match = this.reWhitespaceEnd.exec(s);
+ return match === null ? 0 : match[1].length;
+ }
+ indexOfNextArgSeparator(pattern, separatorCode) {
+ this.argBeg = this.argEnd = separatorCode !== this.separatorCode
+ ? this.quoteBeg + 1
+ : this.quoteBeg;
+ this.transform = false;
+ if ( separatorCode !== this.actualSeparatorCode ) {
+ this.actualSeparatorCode = separatorCode;
+ this.actualSeparatorChar = String.fromCharCode(separatorCode);
+ }
+ while ( this.argEnd < pattern.length ) {
+ const pos = pattern.indexOf(this.actualSeparatorChar, this.argEnd);
+ if ( pos === -1 ) {
+ return (this.argEnd = pattern.length);
+ }
+ if ( this.reOddTrailingEscape.test(pattern.slice(0, pos)) === false ) {
+ return (this.argEnd = pos);
+ }
+ this.transform = true;
+ this.argEnd = pos + 1;
+ }
+ }
+}
+function parseReplaceFn(s) {
+ if ( s.charCodeAt(0) !== 0x2F /* / */ ) { return; }
+ const parser = new ArglistParser('/');
+ parser.nextArg(s, 1);
+ let pattern = s.slice(parser.argBeg, parser.argEnd);
+ if ( parser.transform ) {
+ pattern = parser.normalizeArg(pattern);
+ }
+ if ( pattern === '' ) { return; }
+ parser.nextArg(s, parser.separatorEnd);
+ let replacement = s.slice(parser.argBeg, parser.argEnd);
+ if ( parser.separatorEnd === parser.separatorBeg ) { return; }
+ if ( parser.transform ) {
+ replacement = parser.normalizeArg(replacement);
+ }
+ const flags = s.slice(parser.separatorEnd);
+ try {
+ return { re: new RegExp(pattern, flags), replacement };
+ } catch {
+ }
+}
+function trustedReplaceArgument(
+ propChain = '',
+ argposRaw = '',
+ argraw = '',
+ ...varargs
+) {
+ if ( propChain === '' ) { return; }
+ const safe = safeSelf();
+ const logPrefix = safe.makeLogPrefix('trusted-replace-argument', propChain, argposRaw, argraw);
+ const argoffset = parseInt(argposRaw, 10) || 0;
+ const extraArgs = safe.parseVarargs(varargs);
+ let replacer;
+ if ( argraw.startsWith('repl:/') ) {
+ const parsed = parseReplaceFn(argraw.slice(5));
+ if ( parsed === undefined ) { return; }
+ replacer = arg => `${arg}`.replace(replacer.re, replacer.replacement);
+ Object.assign(replacer, parsed);
+ } else if ( argraw.startsWith('add:') ) {
+ const delta = parseFloat(argraw.slice(4));
+ if ( isNaN(delta) ) { return; }
+ replacer = arg => Number(arg) + delta;
+ } else {
+ const value = validateConstantFn(true, argraw, extraArgs);
+ replacer = ( ) => value;
+ }
+ const reCondition = extraArgs.condition
+ ? safe.patternToRegex(`${extraArgs.condition}`)
+ : /^/;
+ const getArg = context => {
+ if ( argposRaw === 'this' ) { return context.thisArg; }
+ const { callArgs } = context;
+ const argpos = argoffset >= 0 ? argoffset : callArgs.length - argoffset;
+ if ( argpos < 0 || argpos >= callArgs.length ) { return; }
+ context.private = { argpos };
+ return callArgs[argpos];
+ };
+ const setArg = (context, value) => {
+ if ( argposRaw === 'this' ) {
+ if ( value !== context.thisArg ) {
+ context.thisArg = value;
+ }
+ } else if ( context.private ) {
+ context.callArgs[context.private.argpos] = value;
+ }
+ };
+ proxyApplyFn(propChain, function(context) {
+ if ( argposRaw === '' ) {
+ safe.uboLog(logPrefix, `Arguments:\n${context.callArgs.join('\n')}`);
+ return context.reflect();
+ }
+ const argBefore = getArg(context);
+ if ( extraArgs.condition !== undefined ) {
+ if ( safe.RegExp_test(reCondition, argBefore) === false ) {
+ return context.reflect();
+ }
+ }
+ const argAfter = replacer(argBefore);
+ if ( argAfter !== argBefore ) {
+ setArg(context, argAfter);
+ safe.uboLog(logPrefix, `Replaced argument:\nBefore: ${JSON.stringify(argBefore)}\nAfter: ${argAfter}`);
+ }
+ return context.reflect();
+ });
+};
+trustedReplaceArgument(...args);
+},
+};
+
+
+scriptlets['spoof-css.js'] = {
+aliases: [],
+
+requiresTrust: false,
+func: function (scriptletGlobals = {}, ...args) {
+function safeSelf() {
+ if ( safeSelf.safe ) {
+ return safeSelf.safe;
+ }
+ const self = globalThis;
+ const safe = {
+ 'Array_from': Array.from,
+ 'Error': self.Error,
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
+ 'Math_floor': Math.floor,
+ 'Math_max': Math.max,
+ 'Math_min': Math.min,
+ 'Math_random': Math.random,
+ 'Object': Object,
+ 'Object_defineProperty': Object.defineProperty.bind(Object),
+ 'Object_defineProperties': Object.defineProperties.bind(Object),
+ 'Object_fromEntries': Object.fromEntries.bind(Object),
+ 'Object_getOwnPropertyDescriptor': Object.getOwnPropertyDescriptor.bind(Object),
+ 'Object_hasOwn': Object.hasOwn.bind(Object),
+ 'Object_toString': Object.prototype.toString,
+ 'RegExp': self.RegExp,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
+ 'RegExp_exec': self.RegExp.prototype.exec,
+ 'Request_clone': self.Request.prototype.clone,
+ 'String': self.String,
+ 'String_fromCharCode': String.fromCharCode,
+ 'String_split': String.prototype.split,
+ 'XMLHttpRequest': self.XMLHttpRequest,
+ 'addEventListener': self.EventTarget.prototype.addEventListener,
+ 'removeEventListener': self.EventTarget.prototype.removeEventListener,
+ 'fetch': self.fetch,
+ 'JSON': self.JSON,
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
+ 'log': console.log.bind(console),
+ // Properties
+ logLevel: 0,
+ // Methods
+ makeLogPrefix(...args) {
+ return this.sendToLogger && `[${args.join(' \u205D ')}]` || '';
+ },
+ uboLog(...args) {
+ if ( this.sendToLogger === undefined ) { return; }
+ if ( args === undefined || args[0] === '' ) { return; }
+ return this.sendToLogger('info', ...args);
+
+ },
+ uboErr(...args) {
+ if ( this.sendToLogger === undefined ) { return; }
+ if ( args === undefined || args[0] === '' ) { return; }
+ return this.sendToLogger('error', ...args);
+ },
+ escapeRegexChars(s) {
+ return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+ },
+ initPattern(pattern, options = {}) {
+ if ( pattern === '' ) {
+ return { matchAll: true, expect: true };
+ }
+ const expect = (options.canNegate !== true || pattern.startsWith('!') === false);
+ if ( expect === false ) {
+ pattern = pattern.slice(1);
+ }
+ const match = /^\/(.+)\/([gimsu]*)$/.exec(pattern);
+ if ( match !== null ) {
+ return {
+ re: new this.RegExp(
+ match[1],
+ match[2] || options.flags
+ ),
+ expect,
+ };
+ }
+ if ( options.flags !== undefined ) {
+ return {
+ re: new this.RegExp(this.escapeRegexChars(pattern),
+ options.flags
+ ),
+ expect,
+ };
+ }
+ return { pattern, expect };
+ },
+ testPattern(details, haystack) {
+ if ( details.matchAll ) { return true; }
+ if ( details.re ) {
+ return this.RegExp_test(details.re, haystack) === details.expect;
+ }
+ return haystack.includes(details.pattern) === details.expect;
+ },
+ patternToRegex(pattern, flags = undefined, verbatim = false) {
+ if ( pattern === '' ) { return /^/; }
+ const match = /^\/(.+)\/([gimsu]*)$/.exec(pattern);
+ if ( match === null ) {
+ const reStr = this.escapeRegexChars(pattern);
+ return new RegExp(verbatim ? `^${reStr}$` : reStr, flags);
+ }
+ try {
+ return new RegExp(match[1], match[2] || undefined);
+ }
+ catch {
+ }
+ return /^/;
+ },
+ parseVarargs(varargs) {
+ const entries = varargs.reduce((out, v, i, a) => {
+ if ( i & 1 ) { return out; }
+ const rawValue = a[i+1];
+ const value = /^\d+$/.test(rawValue)
+ ? parseInt(rawValue, 10)
+ : rawValue;
+ out.push([ a[i], value ]);
+ return out;
+ }, []);
+ return this.Object_fromEntries(entries);
+ },
+ };
+ safeSelf.safe = safe;
+ if ( scriptletGlobals.bcSecret === undefined ) { return safe; }
+ // This is executed only when the logger is opened
+ safe.logLevel = scriptletGlobals.logLevel || 1;
+ let lastLogType = '';
+ let lastLogText = '';
+ let lastLogTime = 0;
+ safe.toLogText = (type, ...args) => {
+ if ( args.length === 0 ) { return; }
+ const text = `[${document.location.hostname || document.location.href}]${args.join(' ')}`;
+ if ( text === lastLogText && type === lastLogType ) {
+ if ( (Date.now() - lastLogTime) < 5000 ) { return; }
+ }
+ lastLogType = type;
+ lastLogText = text;
+ lastLogTime = Date.now();
+ return text;
+ };
+ try {
+ const bc = new self.BroadcastChannel(scriptletGlobals.bcSecret);
+ let bcBuffer = [];
+ safe.sendToLogger = (type, ...args) => {
+ const text = safe.toLogText(type, ...args);
+ if ( text === undefined ) { return; }
+ if ( bcBuffer === undefined ) {
+ return bc.postMessage({ what: 'messageToLogger', type, text });
+ }
+ bcBuffer.push({ type, text });
+ };
+ bc.onmessage = ev => {
+ const msg = ev.data;
+ switch ( msg ) {
+ case 'iamready!':
+ if ( bcBuffer === undefined ) { break; }
+ bcBuffer.forEach(({ type, text }) =>
+ bc.postMessage({ what: 'messageToLogger', type, text })
+ );
+ bcBuffer = undefined;
+ break;
+ case 'setScriptletLogLevelToOne':
+ safe.logLevel = 1;
+ break;
+ case 'setScriptletLogLevelToTwo':
+ safe.logLevel = 2;
+ break;
+ }
+ };
+ bc.postMessage('areyouready?');
+ } catch {
+ safe.sendToLogger = (type, ...args) => {
+ const text = safe.toLogText(type, ...args);
+ if ( text === undefined ) { return; }
+ safe.log(`uBO ${text}`);
+ };
+ }
+ return safe;
+}
+function spoofCSS(
+ selector,
+ ...args
+) {
+ if ( typeof selector !== 'string' ) { return; }
+ if ( selector === '' ) { return; }
+ const toCamelCase = s => s.replace(/-[a-z]/g, s => s.charAt(1).toUpperCase());
+ const propToValueMap = new Map();
+ const privatePropToValueMap = new Map();
+ for ( let i = 0; i < args.length; i += 2 ) {
+ const prop = toCamelCase(args[i+0]);
+ if ( prop === '' ) { break; }
+ const value = args[i+1];
+ if ( typeof value !== 'string' ) { break; }
+ if ( prop.charCodeAt(0) === 0x5F /* _ */ ) {
+ privatePropToValueMap.set(prop, value);
+ } else {
+ propToValueMap.set(prop, value);
+ }
+ }
+ const safe = safeSelf();
+ const logPrefix = safe.makeLogPrefix('spoof-css', selector, ...args);
+ const instanceProperties = [ 'cssText', 'length', 'parentRule' ];
+ const spoofStyle = (prop, real) => {
+ const normalProp = toCamelCase(prop);
+ const shouldSpoof = propToValueMap.has(normalProp);
+ const value = shouldSpoof ? propToValueMap.get(normalProp) : real;
+ if ( shouldSpoof ) {
+ safe.uboLog(logPrefix, `Spoofing ${prop} to ${value}`);
+ }
+ return value;
+ };
+ const cloackFunc = (fn, thisArg, name) => {
+ const trap = fn.bind(thisArg);
+ Object.defineProperty(trap, 'name', { value: name });
+ Object.defineProperty(trap, 'toString', {
+ value: ( ) => `function ${name}() { [native code] }`
+ });
+ return trap;
+ };
+ self.getComputedStyle = new Proxy(self.getComputedStyle, {
+ apply: function(target, thisArg, args) {
+ // eslint-disable-next-line no-debugger
+ if ( privatePropToValueMap.has('_debug') ) { debugger; }
+ const style = Reflect.apply(target, thisArg, args);
+ const targetElements = new WeakSet(document.querySelectorAll(selector));
+ if ( targetElements.has(args[0]) === false ) { return style; }
+ const proxiedStyle = new Proxy(style, {
+ get(target, prop) {
+ if ( typeof target[prop] === 'function' ) {
+ if ( prop === 'getPropertyValue' ) {
+ return cloackFunc(function getPropertyValue(prop) {
+ return spoofStyle(prop, target[prop]);
+ }, target, 'getPropertyValue');
+ }
+ return cloackFunc(target[prop], target, prop);
+ }
+ if ( instanceProperties.includes(prop) ) {
+ return Reflect.get(target, prop);
+ }
+ return spoofStyle(prop, Reflect.get(target, prop));
+ },
+ getOwnPropertyDescriptor(target, prop) {
+ if ( propToValueMap.has(prop) ) {
+ return {
+ configurable: true,
+ enumerable: true,
+ value: propToValueMap.get(prop),
+ writable: true,
+ };
+ }
+ return Reflect.getOwnPropertyDescriptor(target, prop);
+ },
+ });
+ return proxiedStyle;
+ },
+ get(target, prop) {
+ if ( prop === 'toString' ) {
+ return target.toString.bind(target);
+ }
+ return Reflect.get(target, prop);
+ },
+ });
+ Element.prototype.getBoundingClientRect = new Proxy(Element.prototype.getBoundingClientRect, {
+ apply: function(target, thisArg, args) {
+ // eslint-disable-next-line no-debugger
+ if ( privatePropToValueMap.has('_debug') ) { debugger; }
+ const rect = Reflect.apply(target, thisArg, args);
+ const targetElements = new WeakSet(document.querySelectorAll(selector));
+ if ( targetElements.has(thisArg) === false ) { return rect; }
+ let { x, y, height, width } = rect;
+ if ( privatePropToValueMap.has('_rectx') ) {
+ x = parseFloat(privatePropToValueMap.get('_rectx'));
+ }
+ if ( privatePropToValueMap.has('_recty') ) {
+ y = parseFloat(privatePropToValueMap.get('_recty'));
+ }
+ if ( privatePropToValueMap.has('_rectw') ) {
+ width = parseFloat(privatePropToValueMap.get('_rectw'));
+ } else if ( propToValueMap.has('width') ) {
+ width = parseFloat(propToValueMap.get('width'));
+ }
+ if ( privatePropToValueMap.has('_recth') ) {
+ height = parseFloat(privatePropToValueMap.get('_recth'));
+ } else if ( propToValueMap.has('height') ) {
+ height = parseFloat(propToValueMap.get('height'));
+ }
+ return new self.DOMRect(x, y, width, height);
+ },
+ get(target, prop) {
+ if ( prop === 'toString' ) {
+ return target.toString.bind(target);
+ }
+ return Reflect.get(target, prop);
+ },
+ });
+};
+spoofCSS(...args);
+},
+};
+
+
+scriptlets['prevent-xhr.js'] = {
+aliases: ["no-xhr-if.js"],
+
+requiresTrust: false,
+func: function (scriptletGlobals = {}, ...args) {
+function proxyApplyFn(
+ target = '',
+ handler = '',
+ options = {}
+) {
+ let context = globalThis;
+ let prop = target;
+ for (;;) {
+ const pos = prop.indexOf('.');
+ if ( pos === -1 ) { break; }
+ context = context[prop.slice(0, pos)];
+ if ( context instanceof Object === false ) { return; }
+ prop = prop.slice(pos+1);
+ }
+ const fn = context[prop];
+ if ( typeof fn !== 'function' ) { return; }
+ if ( proxyApplyFn.CtorContext === undefined ) {
+ proxyApplyFn.ctorContexts = [];
+ proxyApplyFn.CtorContext = class {
+ constructor(...args) {
+ this.init(...args);
+ }
+ init(callFn, callArgs) {
+ this.callFn = callFn;
+ this.callArgs = callArgs;
+ return this;
+ }
+ reflect() {
+ const r = Reflect.construct(this.callFn, this.callArgs);
+ this.callFn = this.callArgs = this.private = undefined;
+ proxyApplyFn.ctorContexts.push(this);
+ return r;
+ }
+ static factory(...args) {
+ return proxyApplyFn.ctorContexts.length !== 0
+ ? proxyApplyFn.ctorContexts.pop().init(...args)
+ : new proxyApplyFn.CtorContext(...args);
+ }
+ };
+ proxyApplyFn.applyContexts = [];
+ proxyApplyFn.ApplyContext = class {
+ constructor(...args) {
+ this.init(...args);
+ }
+ init(callFn, thisArg, callArgs) {
+ this.callFn = callFn;
+ this.thisArg = thisArg;
+ this.callArgs = callArgs;
+ return this;
+ }
+ reflect() {
+ const r = Reflect.apply(this.callFn, this.thisArg, this.callArgs);
+ this.callFn = this.thisArg = this.callArgs = this.private = undefined;
+ proxyApplyFn.applyContexts.push(this);
+ return r;
+ }
+ static factory(...args) {
+ return proxyApplyFn.applyContexts.length !== 0
+ ? proxyApplyFn.applyContexts.pop().init(...args)
+ : new proxyApplyFn.ApplyContext(...args);
+ }
+ };
+ proxyApplyFn.isCtor = new Map();
+ proxyApplyFn.proxies = new WeakMap();
+ if ( (options.skipToString || proxyApplyFn.skipToString) !== true ) {
+ proxyApplyFn.nativeToString = Function.prototype.toString;
+ const proxiedToString = new Proxy(Function.prototype.toString, {
+ apply(target, thisArg) {
+ let proxied = thisArg;
+ for(;;) {
+ const fn = proxyApplyFn.proxies.get(proxied);
+ if ( fn === undefined ) { break; }
+ proxied = fn;
+ }
+ return proxyApplyFn.nativeToString.call(proxied);
+ }
+ });
+ proxyApplyFn.proxies.set(proxiedToString, proxyApplyFn.nativeToString);
+ Function.prototype.toString = proxiedToString;
+ }
+ }
+ if ( proxyApplyFn.isCtor.has(target) === false ) {
+ proxyApplyFn.isCtor.set(target, fn.prototype?.constructor === fn);
+ }
+ const proxyDetails = {
+ apply(target, thisArg, args) {
+ return handler(proxyApplyFn.ApplyContext.factory(target, thisArg, args));
+ }
+ };
+ if ( proxyApplyFn.isCtor.get(target) ) {
+ proxyDetails.construct = function(target, args) {
+ return handler(proxyApplyFn.CtorContext.factory(target, args));
+ };
+ }
+ const proxiedTarget = new Proxy(fn, proxyDetails);
+ proxyApplyFn.proxies.set(proxiedTarget, fn);
+ context[prop] = proxiedTarget;
+}
+function parsePropertiesToMatchFn(propsToMatch, implicit = '') {
+ const safe = safeSelf();
+ const needles = new Map();
+ if ( propsToMatch === undefined || propsToMatch === '' ) { return needles; }
+ const options = { canNegate: true };
+ for ( const needle of safe.String_split.call(propsToMatch, /\s+/) ) {
+ let [ prop, pattern ] = safe.String_split.call(needle, ':');
+ if ( prop === '' ) { continue; }
+ if ( pattern !== undefined && /[^$\w -]/.test(prop) ) {
+ prop = `${prop}:${pattern}`;
+ pattern = undefined;
+ }
+ if ( pattern !== undefined ) {
+ needles.set(prop, safe.initPattern(pattern, options));
+ } else if ( implicit !== '' ) {
+ needles.set(implicit, safe.initPattern(prop, options));
+ }
+ }
+ return needles;
+}
+function matchObjectPropertiesFn(propNeedles, ...objs) {
+ const safe = safeSelf();
+ const matched = [];
+ for ( const obj of objs ) {
+ if ( obj instanceof Object === false ) { continue; }
+ for ( const [ prop, details ] of propNeedles ) {
+ let value = obj[prop];
+ if ( value === undefined ) { continue; }
+ if ( typeof value !== 'string' ) {
+ try { value = safe.JSON_stringify(value); }
+ catch { }
+ if ( typeof value !== 'string' ) { continue; }
+ }
+ if ( safe.testPattern(details, value) === false ) { return; }
+ matched.push(`${prop}: ${value}`);
+ }
+ }
+ return matched;
+}
+function safeSelf() {
+ if ( safeSelf.safe ) {
+ return safeSelf.safe;
+ }
+ const self = globalThis;
+ const safe = {
+ 'Array_from': Array.from,
+ 'Error': self.Error,
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
+ 'Math_floor': Math.floor,
+ 'Math_max': Math.max,
+ 'Math_min': Math.min,
+ 'Math_random': Math.random,
+ 'Object': Object,
+ 'Object_defineProperty': Object.defineProperty.bind(Object),
+ 'Object_defineProperties': Object.defineProperties.bind(Object),
+ 'Object_fromEntries': Object.fromEntries.bind(Object),
+ 'Object_getOwnPropertyDescriptor': Object.getOwnPropertyDescriptor.bind(Object),
+ 'Object_hasOwn': Object.hasOwn.bind(Object),
+ 'Object_toString': Object.prototype.toString,
+ 'RegExp': self.RegExp,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
+ 'RegExp_exec': self.RegExp.prototype.exec,
+ 'Request_clone': self.Request.prototype.clone,
+ 'String': self.String,
+ 'String_fromCharCode': String.fromCharCode,
+ 'String_split': String.prototype.split,
+ 'XMLHttpRequest': self.XMLHttpRequest,
+ 'addEventListener': self.EventTarget.prototype.addEventListener,
+ 'removeEventListener': self.EventTarget.prototype.removeEventListener,
+ 'fetch': self.fetch,
+ 'JSON': self.JSON,
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
+ 'log': console.log.bind(console),
+ // Properties
+ logLevel: 0,
+ // Methods
+ makeLogPrefix(...args) {
+ return this.sendToLogger && `[${args.join(' \u205D ')}]` || '';
+ },
+ uboLog(...args) {
+ if ( this.sendToLogger === undefined ) { return; }
+ if ( args === undefined || args[0] === '' ) { return; }
+ return this.sendToLogger('info', ...args);
+
+ },
+ uboErr(...args) {
+ if ( this.sendToLogger === undefined ) { return; }
+ if ( args === undefined || args[0] === '' ) { return; }
+ return this.sendToLogger('error', ...args);
+ },
+ escapeRegexChars(s) {
+ return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+ },
+ initPattern(pattern, options = {}) {
+ if ( pattern === '' ) {
+ return { matchAll: true, expect: true };
+ }
+ const expect = (options.canNegate !== true || pattern.startsWith('!') === false);
+ if ( expect === false ) {
+ pattern = pattern.slice(1);
+ }
+ const match = /^\/(.+)\/([gimsu]*)$/.exec(pattern);
+ if ( match !== null ) {
+ return {
+ re: new this.RegExp(
+ match[1],
+ match[2] || options.flags
+ ),
+ expect,
+ };
+ }
+ if ( options.flags !== undefined ) {
+ return {
+ re: new this.RegExp(this.escapeRegexChars(pattern),
+ options.flags
+ ),
+ expect,
+ };
+ }
+ return { pattern, expect };
+ },
+ testPattern(details, haystack) {
+ if ( details.matchAll ) { return true; }
+ if ( details.re ) {
+ return this.RegExp_test(details.re, haystack) === details.expect;
+ }
+ return haystack.includes(details.pattern) === details.expect;
+ },
+ patternToRegex(pattern, flags = undefined, verbatim = false) {
+ if ( pattern === '' ) { return /^/; }
+ const match = /^\/(.+)\/([gimsu]*)$/.exec(pattern);
+ if ( match === null ) {
+ const reStr = this.escapeRegexChars(pattern);
+ return new RegExp(verbatim ? `^${reStr}$` : reStr, flags);
+ }
+ try {
+ return new RegExp(match[1], match[2] || undefined);
+ }
+ catch {
+ }
+ return /^/;
+ },
+ parseVarargs(varargs) {
+ const entries = varargs.reduce((out, v, i, a) => {
+ if ( i & 1 ) { return out; }
+ const rawValue = a[i+1];
+ const value = /^\d+$/.test(rawValue)
+ ? parseInt(rawValue, 10)
+ : rawValue;
+ out.push([ a[i], value ]);
+ return out;
+ }, []);
+ return this.Object_fromEntries(entries);
+ },
+ };
+ safeSelf.safe = safe;
+ if ( scriptletGlobals.bcSecret === undefined ) { return safe; }
+ // This is executed only when the logger is opened
+ safe.logLevel = scriptletGlobals.logLevel || 1;
+ let lastLogType = '';
+ let lastLogText = '';
+ let lastLogTime = 0;
+ safe.toLogText = (type, ...args) => {
+ if ( args.length === 0 ) { return; }
+ const text = `[${document.location.hostname || document.location.href}]${args.join(' ')}`;
+ if ( text === lastLogText && type === lastLogType ) {
+ if ( (Date.now() - lastLogTime) < 5000 ) { return; }
+ }
+ lastLogType = type;
+ lastLogText = text;
+ lastLogTime = Date.now();
+ return text;
+ };
+ try {
+ const bc = new self.BroadcastChannel(scriptletGlobals.bcSecret);
+ let bcBuffer = [];
+ safe.sendToLogger = (type, ...args) => {
+ const text = safe.toLogText(type, ...args);
+ if ( text === undefined ) { return; }
+ if ( bcBuffer === undefined ) {
+ return bc.postMessage({ what: 'messageToLogger', type, text });
+ }
+ bcBuffer.push({ type, text });
+ };
+ bc.onmessage = ev => {
+ const msg = ev.data;
+ switch ( msg ) {
+ case 'iamready!':
+ if ( bcBuffer === undefined ) { break; }
+ bcBuffer.forEach(({ type, text }) =>
+ bc.postMessage({ what: 'messageToLogger', type, text })
+ );
+ bcBuffer = undefined;
+ break;
+ case 'setScriptletLogLevelToOne':
+ safe.logLevel = 1;
+ break;
+ case 'setScriptletLogLevelToTwo':
+ safe.logLevel = 2;
+ break;
+ }
+ };
+ bc.postMessage('areyouready?');
+ } catch {
+ safe.sendToLogger = (type, ...args) => {
+ const text = safe.toLogText(type, ...args);
+ if ( text === undefined ) { return; }
+ safe.log(`uBO ${text}`);
+ };
+ }
+ return safe;
+}
+function generateContentFn(trusted, directive) {
+ const safe = safeSelf();
+ const randomize = len => {
+ const chunks = [];
+ let textSize = 0;
+ do {
+ const s = safe.Math_random().toString(36).slice(2);
+ chunks.push(s);
+ textSize += s.length;
+ }
+ while ( textSize < len );
+ return chunks.join(' ').slice(0, len);
+ };
+ if ( directive === 'true' ) {
+ return randomize(10);
+ }
+ if ( directive === 'emptyObj' ) {
+ return '{}';
+ }
+ if ( directive === 'emptyArr' ) {
+ return '[]';
+ }
+ if ( directive === 'emptyStr' ) {
+ return '';
}
- const onStateChange = ( ) => {
- if ( intFromReadyState(document.readyState) < runAt ) { return; }
- fn();
- safe.removeEventListener.apply(document, args);
- };
- const safe = safeSelf();
- const args = [ 'readystatechange', onStateChange, { capture: true } ];
- safe.addEventListener.apply(document, args);
+ if ( directive.startsWith('length:') ) {
+ const match = /^length:(\d+)(?:-(\d+))?$/.exec(directive);
+ if ( match === null ) { return ''; }
+ const min = parseInt(match[1], 10);
+ const extent = safe.Math_max(parseInt(match[2], 10) || 0, min) - min;
+ const len = safe.Math_min(min + extent * safe.Math_random(), 500000);
+ return randomize(len | 0);
+ }
+ if ( directive.startsWith('war:') ) {
+ if ( scriptletGlobals.warOrigin === undefined ) { return ''; }
+ return new Promise(resolve => {
+ const warOrigin = scriptletGlobals.warOrigin;
+ const warName = directive.slice(4);
+ const fullpath = [ warOrigin, '/', warName ];
+ const warSecret = scriptletGlobals.warSecret;
+ if ( warSecret !== undefined ) {
+ fullpath.push('?secret=', warSecret);
+ }
+ const warXHR = new safe.XMLHttpRequest();
+ warXHR.responseType = 'text';
+ warXHR.onloadend = ev => {
+ resolve(ev.target.responseText || '');
+ };
+ warXHR.open('GET', fullpath.join(''));
+ warXHR.send();
+ }).catch(( ) => '');
+ }
+ if ( directive.startsWith('join:') ) {
+ const parts = directive.slice(7)
+ .split(directive.slice(5, 7))
+ .map(a => generateContentFn(trusted, a));
+ return parts.some(a => a instanceof Promise)
+ ? Promise.all(parts).then(parts => parts.join(''))
+ : parts.join('');
+ }
+ if ( trusted ) {
+ return directive;
+ }
+ return '';
}
-function setConstantFn(
+function preventXhrFn(
trusted = false,
- chain = '',
- rawValue = '',
- ...varargs
+ propsToMatch = '',
+ directive = ''
) {
- if ( chain === '' ) { return; }
+ if ( typeof propsToMatch !== 'string' ) { return; }
const safe = safeSelf();
- const logPrefix = safe.makeLogPrefix('set-constant', chain, rawValue);
- const extraArgs = safe.parseVarargs(varargs);
- function setConstant(chain, rawValue) {
- const trappedProp = (( ) => {
- const pos = chain.lastIndexOf('.');
- if ( pos === -1 ) { return chain; }
- return chain.slice(pos+1);
- })();
- const cloakFunc = fn => {
- safe.Object_defineProperty(fn, 'name', { value: trappedProp });
- return new Proxy(fn, {
- defineProperty(target, prop) {
- if ( prop !== 'toString' ) {
- return Reflect.defineProperty(...arguments);
- }
- return true;
- },
- deleteProperty(target, prop) {
- if ( prop !== 'toString' ) {
- return Reflect.deleteProperty(...arguments);
- }
- return true;
+ const scriptletName = trusted ? 'trusted-prevent-xhr' : 'prevent-xhr';
+ const logPrefix = safe.makeLogPrefix(scriptletName, propsToMatch, directive);
+ const xhrInstances = new WeakMap();
+ const propNeedles = parsePropertiesToMatchFn(propsToMatch, 'url');
+ const warOrigin = scriptletGlobals.warOrigin;
+ const safeDispatchEvent = (xhr, type) => {
+ try {
+ xhr.dispatchEvent(new Event(type));
+ } catch {
+ }
+ };
+ proxyApplyFn('XMLHttpRequest.prototype.open', function(context) {
+ const { thisArg, callArgs } = context;
+ xhrInstances.delete(thisArg);
+ const [ method, url, ...args ] = callArgs;
+ if ( warOrigin !== undefined && url.startsWith(warOrigin) ) {
+ return context.reflect();
+ }
+ const haystack = { method, url };
+ if ( propsToMatch === '' && directive === '' ) {
+ safe.uboLog(logPrefix, `Called: ${safe.JSON_stringify(haystack, null, 2)}`);
+ return context.reflect();
+ }
+ if ( matchObjectPropertiesFn(propNeedles, haystack) ) {
+ const xhrDetails = Object.assign(haystack, {
+ xhr: thisArg,
+ defer: args.length === 0 || !!args[0],
+ directive,
+ headers: {
+ 'date': '',
+ 'content-type': '',
+ 'content-length': '',
},
- get(target, prop) {
- if ( prop === 'toString' ) {
- return function() {
- return `function ${trappedProp}() { [native code] }`;
- }.bind(null);
- }
- return Reflect.get(...arguments);
+ url: haystack.url,
+ props: {
+ response: { value: '' },
+ responseText: { value: '' },
+ responseXML: { value: null },
},
});
- };
- if ( trappedProp === '' ) { return; }
- const thisScript = document.currentScript;
- let normalValue = validateConstantFn(trusted, rawValue, extraArgs);
- if ( rawValue === 'noopFunc' || rawValue === 'trueFunc' || rawValue === 'falseFunc' ) {
- normalValue = cloakFunc(normalValue);
+ xhrInstances.set(thisArg, xhrDetails);
}
- let aborted = false;
- const mustAbort = function(v) {
- if ( trusted ) { return false; }
- if ( aborted ) { return true; }
- aborted =
- (v !== undefined && v !== null) &&
- (normalValue !== undefined && normalValue !== null) &&
- (typeof v !== typeof normalValue);
- if ( aborted ) {
- safe.uboLog(logPrefix, `Aborted because value set to ${v}`);
- }
- return aborted;
- };
- // https://github.com/uBlockOrigin/uBlock-issues/issues/156
- // Support multiple trappers for the same property.
- const trapProp = function(owner, prop, configurable, handler) {
- if ( handler.init(configurable ? owner[prop] : normalValue) === false ) { return; }
- const odesc = safe.Object_getOwnPropertyDescriptor(owner, prop);
- let prevGetter, prevSetter;
- if ( odesc instanceof safe.Object ) {
- owner[prop] = normalValue;
- if ( odesc.get instanceof Function ) {
- prevGetter = odesc.get;
- }
- if ( odesc.set instanceof Function ) {
- prevSetter = odesc.set;
- }
- }
- try {
- safe.Object_defineProperty(owner, prop, {
- configurable,
- get() {
- if ( prevGetter !== undefined ) {
- prevGetter();
- }
- return handler.getter();
- },
- set(a) {
- if ( prevSetter !== undefined ) {
- prevSetter(a);
- }
- handler.setter(a);
- }
- });
- safe.uboLog(logPrefix, 'Trap installed');
- } catch(ex) {
- safe.uboErr(logPrefix, ex);
- }
- };
- const trapChain = function(owner, chain) {
- const pos = chain.indexOf('.');
- if ( pos === -1 ) {
- trapProp(owner, chain, false, {
- v: undefined,
- init: function(v) {
- if ( mustAbort(v) ) { return false; }
- this.v = v;
- return true;
- },
- getter: function() {
- if ( document.currentScript === thisScript ) {
- return this.v;
- }
- safe.uboLog(logPrefix, 'Property read');
- return normalValue;
- },
- setter: function(a) {
- if ( mustAbort(a) === false ) { return; }
- normalValue = a;
- }
+ return context.reflect();
+ });
+ proxyApplyFn('XMLHttpRequest.prototype.send', function(context) {
+ const { thisArg } = context;
+ const xhrDetails = xhrInstances.get(thisArg);
+ if ( xhrDetails === undefined ) {
+ return context.reflect();
+ }
+ xhrDetails.headers['date'] = (new Date()).toUTCString();
+ let xhrText = '';
+ switch ( thisArg.responseType ) {
+ case 'arraybuffer':
+ xhrDetails.props.response.value = new ArrayBuffer(0);
+ xhrDetails.headers['content-type'] = 'application/octet-stream';
+ break;
+ case 'blob':
+ xhrDetails.props.response.value = new Blob([]);
+ xhrDetails.headers['content-type'] = 'application/octet-stream';
+ break;
+ case 'document': {
+ const parser = new DOMParser();
+ const doc = parser.parseFromString('', 'text/html');
+ xhrDetails.props.response.value = doc;
+ xhrDetails.props.responseXML.value = doc;
+ xhrDetails.headers['content-type'] = 'text/html';
+ break;
+ }
+ case 'json':
+ xhrDetails.props.response.value = {};
+ xhrDetails.props.responseText.value = '{}';
+ xhrDetails.headers['content-type'] = 'application/json';
+ break;
+ default: {
+ if ( directive === '' ) { break; }
+ xhrText = generateContentFn(trusted, xhrDetails.directive);
+ if ( xhrText instanceof Promise ) {
+ xhrText = xhrText.then(text => {
+ xhrDetails.props.response.value = text;
+ xhrDetails.props.responseText.value = text;
});
- return;
- }
- const prop = chain.slice(0, pos);
- const v = owner[prop];
- chain = chain.slice(pos + 1);
- if ( v instanceof safe.Object || typeof v === 'object' && v !== null ) {
- trapChain(v, chain);
- return;
+ } else {
+ xhrDetails.props.response.value = xhrText;
+ xhrDetails.props.responseText.value = xhrText;
}
- trapProp(owner, prop, true, {
- v: undefined,
- init: function(v) {
- this.v = v;
- return true;
- },
- getter: function() {
- return this.v;
- },
- setter: function(a) {
- this.v = a;
- if ( a instanceof safe.Object ) {
- trapChain(a, chain);
- }
- }
+ xhrDetails.headers['content-type'] = 'text/plain';
+ break;
+ }
+ }
+ if ( xhrDetails.defer === false ) {
+ xhrDetails.headers['content-length'] = `${xhrDetails.props.response.value}`.length;
+ Object.defineProperties(xhrDetails.xhr, {
+ readyState: { value: 4 },
+ responseURL: { value: xhrDetails.url },
+ status: { value: 200 },
+ statusText: { value: 'OK' },
});
- };
- trapChain(window, chain);
- }
- runAt(( ) => {
- setConstant(chain, rawValue);
- }, extraArgs.runAt);
+ Object.defineProperties(xhrDetails.xhr, xhrDetails.props);
+ return;
+ }
+ Promise.resolve(xhrText).then(( ) => xhrDetails).then(details => {
+ Object.defineProperties(details.xhr, {
+ readyState: { value: 1, configurable: true },
+ responseURL: { value: xhrDetails.url },
+ });
+ safeDispatchEvent(details.xhr, 'readystatechange');
+ return details;
+ }).then(details => {
+ xhrDetails.headers['content-length'] = `${details.props.response.value}`.length;
+ Object.defineProperties(details.xhr, {
+ readyState: { value: 2, configurable: true },
+ status: { value: 200 },
+ statusText: { value: 'OK' },
+ });
+ safeDispatchEvent(details.xhr, 'readystatechange');
+ return details;
+ }).then(details => {
+ Object.defineProperties(details.xhr, {
+ readyState: { value: 3, configurable: true },
+ });
+ Object.defineProperties(details.xhr, details.props);
+ safeDispatchEvent(details.xhr, 'readystatechange');
+ return details;
+ }).then(details => {
+ Object.defineProperties(details.xhr, {
+ readyState: { value: 4 },
+ });
+ safeDispatchEvent(details.xhr, 'readystatechange');
+ safeDispatchEvent(details.xhr, 'load');
+ safeDispatchEvent(details.xhr, 'loadend');
+ safe.uboLog(logPrefix, `Prevented with response:\n${details.xhr.response}`);
+ });
+ });
+ proxyApplyFn('XMLHttpRequest.prototype.getResponseHeader', function(context) {
+ const { thisArg } = context;
+ const xhrDetails = xhrInstances.get(thisArg);
+ if ( xhrDetails === undefined || thisArg.readyState < thisArg.HEADERS_RECEIVED ) {
+ return context.reflect();
+ }
+ const headerName = `${context.callArgs[0]}`;
+ const value = xhrDetails.headers[headerName.toLowerCase()];
+ if ( value !== undefined && value !== '' ) { return value; }
+ return null;
+ });
+ proxyApplyFn('XMLHttpRequest.prototype.getAllResponseHeaders', function(context) {
+ const { thisArg } = context;
+ const xhrDetails = xhrInstances.get(thisArg);
+ if ( xhrDetails === undefined || thisArg.readyState < thisArg.HEADERS_RECEIVED ) {
+ return context.reflect();
+ }
+ const out = [];
+ for ( const [ name, value ] of Object.entries(xhrDetails.headers) ) {
+ if ( !value ) { continue; }
+ out.push(`${name}: ${value}`);
+ }
+ if ( out.length !== 0 ) { out.push(''); }
+ return out.join('\r\n');
+ });
}
-function trustedSetConstant(
- ...args
-) {
- setConstantFn(true, ...args);
+function preventXhr(...args) {
+ preventXhrFn(false, ...args);
};
-trustedSetConstant(...args);
+preventXhr(...args);
},
};
-scriptlets['trusted-replace-argument.js'] = {
+scriptlets['trusted-prevent-xhr.js'] = {
aliases: [],
-requiresTrust: true,
+requiresTrust: false,
func: function (scriptletGlobals = {}, ...args) {
-function validateConstantFn(trusted, raw, extraArgs = {}) {
- const safe = safeSelf();
- let value;
- if ( raw === 'undefined' ) {
- value = undefined;
- } else if ( raw === 'false' ) {
- value = false;
- } else if ( raw === 'true' ) {
- value = true;
- } else if ( raw === 'null' ) {
- value = null;
- } else if ( raw === "''" || raw === '' ) {
- value = '';
- } else if ( raw === '[]' || raw === 'emptyArr' ) {
- value = [];
- } else if ( raw === '{}' || raw === 'emptyObj' ) {
- value = {};
- } else if ( raw === 'noopFunc' ) {
- value = function(){};
- } else if ( raw === 'trueFunc' ) {
- value = function(){ return true; };
- } else if ( raw === 'falseFunc' ) {
- value = function(){ return false; };
- } else if ( raw === 'throwFunc' ) {
- value = function(){ throw ''; };
- } else if ( /^-?\d+$/.test(raw) ) {
- value = parseInt(raw);
- if ( isNaN(raw) ) { return; }
- if ( Math.abs(raw) > 0x7FFF ) { return; }
- } else if ( trusted ) {
- if ( raw.startsWith('json:') ) {
- try { value = safe.JSON_parse(raw.slice(5)); } catch { return; }
- } else if ( raw.startsWith('{') && raw.endsWith('}') ) {
- try { value = safe.JSON_parse(raw).value; } catch { return; }
+function proxyApplyFn(
+ target = '',
+ handler = '',
+ options = {}
+) {
+ let context = globalThis;
+ let prop = target;
+ for (;;) {
+ const pos = prop.indexOf('.');
+ if ( pos === -1 ) { break; }
+ context = context[prop.slice(0, pos)];
+ if ( context instanceof Object === false ) { return; }
+ prop = prop.slice(pos+1);
+ }
+ const fn = context[prop];
+ if ( typeof fn !== 'function' ) { return; }
+ if ( proxyApplyFn.CtorContext === undefined ) {
+ proxyApplyFn.ctorContexts = [];
+ proxyApplyFn.CtorContext = class {
+ constructor(...args) {
+ this.init(...args);
+ }
+ init(callFn, callArgs) {
+ this.callFn = callFn;
+ this.callArgs = callArgs;
+ return this;
+ }
+ reflect() {
+ const r = Reflect.construct(this.callFn, this.callArgs);
+ this.callFn = this.callArgs = this.private = undefined;
+ proxyApplyFn.ctorContexts.push(this);
+ return r;
+ }
+ static factory(...args) {
+ return proxyApplyFn.ctorContexts.length !== 0
+ ? proxyApplyFn.ctorContexts.pop().init(...args)
+ : new proxyApplyFn.CtorContext(...args);
+ }
+ };
+ proxyApplyFn.applyContexts = [];
+ proxyApplyFn.ApplyContext = class {
+ constructor(...args) {
+ this.init(...args);
+ }
+ init(callFn, thisArg, callArgs) {
+ this.callFn = callFn;
+ this.thisArg = thisArg;
+ this.callArgs = callArgs;
+ return this;
+ }
+ reflect() {
+ const r = Reflect.apply(this.callFn, this.thisArg, this.callArgs);
+ this.callFn = this.thisArg = this.callArgs = this.private = undefined;
+ proxyApplyFn.applyContexts.push(this);
+ return r;
+ }
+ static factory(...args) {
+ return proxyApplyFn.applyContexts.length !== 0
+ ? proxyApplyFn.applyContexts.pop().init(...args)
+ : new proxyApplyFn.ApplyContext(...args);
+ }
+ };
+ proxyApplyFn.isCtor = new Map();
+ proxyApplyFn.proxies = new WeakMap();
+ if ( (options.skipToString || proxyApplyFn.skipToString) !== true ) {
+ proxyApplyFn.nativeToString = Function.prototype.toString;
+ const proxiedToString = new Proxy(Function.prototype.toString, {
+ apply(target, thisArg) {
+ let proxied = thisArg;
+ for(;;) {
+ const fn = proxyApplyFn.proxies.get(proxied);
+ if ( fn === undefined ) { break; }
+ proxied = fn;
+ }
+ return proxyApplyFn.nativeToString.call(proxied);
+ }
+ });
+ proxyApplyFn.proxies.set(proxiedToString, proxyApplyFn.nativeToString);
+ Function.prototype.toString = proxiedToString;
}
- } else {
- return;
}
- if ( extraArgs.as !== undefined ) {
- if ( extraArgs.as === 'function' ) {
- return ( ) => value;
- } else if ( extraArgs.as === 'callback' ) {
- return ( ) => (( ) => value);
- } else if ( extraArgs.as === 'resolved' ) {
- return Promise.resolve(value);
- } else if ( extraArgs.as === 'rejected' ) {
- return Promise.reject(value);
+ if ( proxyApplyFn.isCtor.has(target) === false ) {
+ proxyApplyFn.isCtor.set(target, fn.prototype?.constructor === fn);
+ }
+ const proxyDetails = {
+ apply(target, thisArg, args) {
+ return handler(proxyApplyFn.ApplyContext.factory(target, thisArg, args));
+ }
+ };
+ if ( proxyApplyFn.isCtor.get(target) ) {
+ proxyDetails.construct = function(target, args) {
+ return handler(proxyApplyFn.CtorContext.factory(target, args));
+ };
+ }
+ const proxiedTarget = new Proxy(fn, proxyDetails);
+ proxyApplyFn.proxies.set(proxiedTarget, fn);
+ context[prop] = proxiedTarget;
+}
+function parsePropertiesToMatchFn(propsToMatch, implicit = '') {
+ const safe = safeSelf();
+ const needles = new Map();
+ if ( propsToMatch === undefined || propsToMatch === '' ) { return needles; }
+ const options = { canNegate: true };
+ for ( const needle of safe.String_split.call(propsToMatch, /\s+/) ) {
+ let [ prop, pattern ] = safe.String_split.call(needle, ':');
+ if ( prop === '' ) { continue; }
+ if ( pattern !== undefined && /[^$\w -]/.test(prop) ) {
+ prop = `${prop}:${pattern}`;
+ pattern = undefined;
+ }
+ if ( pattern !== undefined ) {
+ needles.set(prop, safe.initPattern(pattern, options));
+ } else if ( implicit !== '' ) {
+ needles.set(implicit, safe.initPattern(prop, options));
}
}
- return value;
+ return needles;
+}
+function matchObjectPropertiesFn(propNeedles, ...objs) {
+ const safe = safeSelf();
+ const matched = [];
+ for ( const obj of objs ) {
+ if ( obj instanceof Object === false ) { continue; }
+ for ( const [ prop, details ] of propNeedles ) {
+ let value = obj[prop];
+ if ( value === undefined ) { continue; }
+ if ( typeof value !== 'string' ) {
+ try { value = safe.JSON_stringify(value); }
+ catch { }
+ if ( typeof value !== 'string' ) { continue; }
+ }
+ if ( safe.testPattern(details, value) === false ) { return; }
+ matched.push(`${prop}: ${value}`);
+ }
+ }
+ return matched;
}
function safeSelf() {
if ( safeSelf.safe ) {
@@ -34455,8 +34640,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -34469,7 +34653,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -34480,10 +34664,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -34536,7 +34718,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -34624,292 +34806,291 @@ function safeSelf() {
}
return safe;
}
-function proxyApplyFn(
- target = '',
- handler = '',
- options = {}
-) {
- let context = globalThis;
- let prop = target;
- for (;;) {
- const pos = prop.indexOf('.');
- if ( pos === -1 ) { break; }
- context = context[prop.slice(0, pos)];
- if ( context instanceof Object === false ) { return; }
- prop = prop.slice(pos+1);
- }
- const fn = context[prop];
- if ( typeof fn !== 'function' ) { return; }
- if ( proxyApplyFn.CtorContext === undefined ) {
- proxyApplyFn.ctorContexts = [];
- proxyApplyFn.CtorContext = class {
- constructor(...args) {
- this.init(...args);
- }
- init(callFn, callArgs) {
- this.callFn = callFn;
- this.callArgs = callArgs;
- return this;
- }
- reflect() {
- const r = Reflect.construct(this.callFn, this.callArgs);
- this.callFn = this.callArgs = this.private = undefined;
- proxyApplyFn.ctorContexts.push(this);
- return r;
- }
- static factory(...args) {
- return proxyApplyFn.ctorContexts.length !== 0
- ? proxyApplyFn.ctorContexts.pop().init(...args)
- : new proxyApplyFn.CtorContext(...args);
- }
- };
- proxyApplyFn.applyContexts = [];
- proxyApplyFn.ApplyContext = class {
- constructor(...args) {
- this.init(...args);
- }
- init(callFn, thisArg, callArgs) {
- this.callFn = callFn;
- this.thisArg = thisArg;
- this.callArgs = callArgs;
- return this;
- }
- reflect() {
- const r = Reflect.apply(this.callFn, this.thisArg, this.callArgs);
- this.callFn = this.thisArg = this.callArgs = this.private = undefined;
- proxyApplyFn.applyContexts.push(this);
- return r;
- }
- static factory(...args) {
- return proxyApplyFn.applyContexts.length !== 0
- ? proxyApplyFn.applyContexts.pop().init(...args)
- : new proxyApplyFn.ApplyContext(...args);
- }
- };
- proxyApplyFn.isCtor = new Map();
- proxyApplyFn.proxies = new WeakMap();
- if ( (options.skipToString || proxyApplyFn.skipToString) !== true ) {
- proxyApplyFn.nativeToString = Function.prototype.toString;
- const proxiedToString = new Proxy(Function.prototype.toString, {
- apply(target, thisArg) {
- let proxied = thisArg;
- for(;;) {
- const fn = proxyApplyFn.proxies.get(proxied);
- if ( fn === undefined ) { break; }
- proxied = fn;
- }
- return proxyApplyFn.nativeToString.call(proxied);
- }
- });
- proxyApplyFn.proxies.set(proxiedToString, proxyApplyFn.nativeToString);
- Function.prototype.toString = proxiedToString;
- }
- }
- if ( proxyApplyFn.isCtor.has(target) === false ) {
- proxyApplyFn.isCtor.set(target, fn.prototype?.constructor === fn);
- }
- const proxyDetails = {
- apply(target, thisArg, args) {
- return handler(proxyApplyFn.ApplyContext.factory(target, thisArg, args));
+function generateContentFn(trusted, directive) {
+ const safe = safeSelf();
+ const randomize = len => {
+ const chunks = [];
+ let textSize = 0;
+ do {
+ const s = safe.Math_random().toString(36).slice(2);
+ chunks.push(s);
+ textSize += s.length;
}
+ while ( textSize < len );
+ return chunks.join(' ').slice(0, len);
};
- if ( proxyApplyFn.isCtor.get(target) ) {
- proxyDetails.construct = function(target, args) {
- return handler(proxyApplyFn.CtorContext.factory(target, args));
- };
- }
- const proxiedTarget = new Proxy(fn, proxyDetails);
- proxyApplyFn.proxies.set(proxiedTarget, fn);
- context[prop] = proxiedTarget;
-}
-class ArglistParser {
- constructor(separatorChar = ',', mustQuote = false) {
- this.separatorChar = this.actualSeparatorChar = separatorChar;
- this.separatorCode = this.actualSeparatorCode = separatorChar.charCodeAt(0);
- this.mustQuote = mustQuote;
- this.quoteBeg = 0; this.quoteEnd = 0;
- this.argBeg = 0; this.argEnd = 0;
- this.separatorBeg = 0; this.separatorEnd = 0;
- this.transform = false;
- this.failed = false;
- this.reWhitespaceStart = /^\s+/;
- this.reWhitespaceEnd = /(?:^|\S)(\s+)$/;
- this.reOddTrailingEscape = /(?:^|[^\\])(?:\\\\)*\\$/;
- this.reTrailingEscapeChars = /\\+$/;
+ if ( directive === 'true' ) {
+ return randomize(10);
}
- nextArg(pattern, beg = 0) {
- const len = pattern.length;
- this.quoteBeg = beg + this.leftWhitespaceCount(pattern.slice(beg));
- this.failed = false;
- const qc = pattern.charCodeAt(this.quoteBeg);
- if ( qc === 0x22 /* " */ || qc === 0x27 /* ' */ || qc === 0x60 /* ` */ ) {
- this.indexOfNextArgSeparator(pattern, qc);
- if ( this.argEnd !== len ) {
- this.quoteEnd = this.argEnd + 1;
- this.separatorBeg = this.separatorEnd = this.quoteEnd;
- this.separatorEnd += this.leftWhitespaceCount(pattern.slice(this.quoteEnd));
- if ( this.separatorEnd === len ) { return this; }
- if ( pattern.charCodeAt(this.separatorEnd) === this.separatorCode ) {
- this.separatorEnd += 1;
- return this;
- }
- }
- }
- this.indexOfNextArgSeparator(pattern, this.separatorCode);
- this.separatorBeg = this.separatorEnd = this.argEnd;
- if ( this.separatorBeg < len ) {
- this.separatorEnd += 1;
- }
- this.argEnd -= this.rightWhitespaceCount(pattern.slice(0, this.separatorBeg));
- this.quoteEnd = this.argEnd;
- if ( this.mustQuote ) {
- this.failed = true;
- }
- return this;
+ if ( directive === 'emptyObj' ) {
+ return '{}';
}
- normalizeArg(s, char = '') {
- if ( char === '' ) { char = this.actualSeparatorChar; }
- let out = '';
- let pos = 0;
- while ( (pos = s.lastIndexOf(char)) !== -1 ) {
- out = s.slice(pos) + out;
- s = s.slice(0, pos);
- const match = this.reTrailingEscapeChars.exec(s);
- if ( match === null ) { continue; }
- const tail = (match[0].length & 1) !== 0
- ? match[0].slice(0, -1)
- : match[0];
- out = tail + out;
- s = s.slice(0, -match[0].length);
- }
- if ( out === '' ) { return s; }
- return s + out;
+ if ( directive === 'emptyArr' ) {
+ return '[]';
}
- leftWhitespaceCount(s) {
- const match = this.reWhitespaceStart.exec(s);
- return match === null ? 0 : match[0].length;
+ if ( directive === 'emptyStr' ) {
+ return '';
}
- rightWhitespaceCount(s) {
- const match = this.reWhitespaceEnd.exec(s);
- return match === null ? 0 : match[1].length;
+ if ( directive.startsWith('length:') ) {
+ const match = /^length:(\d+)(?:-(\d+))?$/.exec(directive);
+ if ( match === null ) { return ''; }
+ const min = parseInt(match[1], 10);
+ const extent = safe.Math_max(parseInt(match[2], 10) || 0, min) - min;
+ const len = safe.Math_min(min + extent * safe.Math_random(), 500000);
+ return randomize(len | 0);
}
- indexOfNextArgSeparator(pattern, separatorCode) {
- this.argBeg = this.argEnd = separatorCode !== this.separatorCode
- ? this.quoteBeg + 1
- : this.quoteBeg;
- this.transform = false;
- if ( separatorCode !== this.actualSeparatorCode ) {
- this.actualSeparatorCode = separatorCode;
- this.actualSeparatorChar = String.fromCharCode(separatorCode);
- }
- while ( this.argEnd < pattern.length ) {
- const pos = pattern.indexOf(this.actualSeparatorChar, this.argEnd);
- if ( pos === -1 ) {
- return (this.argEnd = pattern.length);
- }
- if ( this.reOddTrailingEscape.test(pattern.slice(0, pos)) === false ) {
- return (this.argEnd = pos);
+ if ( directive.startsWith('war:') ) {
+ if ( scriptletGlobals.warOrigin === undefined ) { return ''; }
+ return new Promise(resolve => {
+ const warOrigin = scriptletGlobals.warOrigin;
+ const warName = directive.slice(4);
+ const fullpath = [ warOrigin, '/', warName ];
+ const warSecret = scriptletGlobals.warSecret;
+ if ( warSecret !== undefined ) {
+ fullpath.push('?secret=', warSecret);
}
- this.transform = true;
- this.argEnd = pos + 1;
- }
- }
-}
-function parseReplaceFn(s) {
- if ( s.charCodeAt(0) !== 0x2F /* / */ ) { return; }
- const parser = new ArglistParser('/');
- parser.nextArg(s, 1);
- let pattern = s.slice(parser.argBeg, parser.argEnd);
- if ( parser.transform ) {
- pattern = parser.normalizeArg(pattern);
+ const warXHR = new safe.XMLHttpRequest();
+ warXHR.responseType = 'text';
+ warXHR.onloadend = ev => {
+ resolve(ev.target.responseText || '');
+ };
+ warXHR.open('GET', fullpath.join(''));
+ warXHR.send();
+ }).catch(( ) => '');
}
- if ( pattern === '' ) { return; }
- parser.nextArg(s, parser.separatorEnd);
- let replacement = s.slice(parser.argBeg, parser.argEnd);
- if ( parser.separatorEnd === parser.separatorBeg ) { return; }
- if ( parser.transform ) {
- replacement = parser.normalizeArg(replacement);
+ if ( directive.startsWith('join:') ) {
+ const parts = directive.slice(7)
+ .split(directive.slice(5, 7))
+ .map(a => generateContentFn(trusted, a));
+ return parts.some(a => a instanceof Promise)
+ ? Promise.all(parts).then(parts => parts.join(''))
+ : parts.join('');
}
- const flags = s.slice(parser.separatorEnd);
- try {
- return { re: new RegExp(pattern, flags), replacement };
- } catch {
+ if ( trusted ) {
+ return directive;
}
+ return '';
}
-function trustedReplaceArgument(
- propChain = '',
- argposRaw = '',
- argraw = '',
- ...varargs
+function preventXhrFn(
+ trusted = false,
+ propsToMatch = '',
+ directive = ''
) {
- if ( propChain === '' ) { return; }
+ if ( typeof propsToMatch !== 'string' ) { return; }
const safe = safeSelf();
- const logPrefix = safe.makeLogPrefix('trusted-replace-argument', propChain, argposRaw, argraw);
- const argoffset = parseInt(argposRaw, 10) || 0;
- const extraArgs = safe.parseVarargs(varargs);
- let replacer;
- if ( argraw.startsWith('repl:/') ) {
- const parsed = parseReplaceFn(argraw.slice(5));
- if ( parsed === undefined ) { return; }
- replacer = arg => `${arg}`.replace(replacer.re, replacer.replacement);
- Object.assign(replacer, parsed);
- } else if ( argraw.startsWith('add:') ) {
- const delta = parseFloat(argraw.slice(4));
- if ( isNaN(delta) ) { return; }
- replacer = arg => Number(arg) + delta;
- } else {
- const value = validateConstantFn(true, argraw, extraArgs);
- replacer = ( ) => value;
- }
- const reCondition = extraArgs.condition
- ? safe.patternToRegex(`${extraArgs.condition}`)
- : /^/;
- const getArg = context => {
- if ( argposRaw === 'this' ) { return context.thisArg; }
- const { callArgs } = context;
- const argpos = argoffset >= 0 ? argoffset : callArgs.length - argoffset;
- if ( argpos < 0 || argpos >= callArgs.length ) { return; }
- context.private = { argpos };
- return callArgs[argpos];
- };
- const setArg = (context, value) => {
- if ( argposRaw === 'this' ) {
- if ( value !== context.thisArg ) {
- context.thisArg = value;
- }
- } else if ( context.private ) {
- context.callArgs[context.private.argpos] = value;
+ const scriptletName = trusted ? 'trusted-prevent-xhr' : 'prevent-xhr';
+ const logPrefix = safe.makeLogPrefix(scriptletName, propsToMatch, directive);
+ const xhrInstances = new WeakMap();
+ const propNeedles = parsePropertiesToMatchFn(propsToMatch, 'url');
+ const warOrigin = scriptletGlobals.warOrigin;
+ const safeDispatchEvent = (xhr, type) => {
+ try {
+ xhr.dispatchEvent(new Event(type));
+ } catch {
}
};
- proxyApplyFn(propChain, function(context) {
- if ( argposRaw === '' ) {
- safe.uboLog(logPrefix, `Arguments:\n${context.callArgs.join('\n')}`);
+ proxyApplyFn('XMLHttpRequest.prototype.open', function(context) {
+ const { thisArg, callArgs } = context;
+ xhrInstances.delete(thisArg);
+ const [ method, url, ...args ] = callArgs;
+ if ( warOrigin !== undefined && url.startsWith(warOrigin) ) {
return context.reflect();
}
- const argBefore = getArg(context);
- if ( extraArgs.condition !== undefined ) {
- if ( safe.RegExp_test.call(reCondition, argBefore) === false ) {
- return context.reflect();
- }
+ const haystack = { method, url };
+ if ( propsToMatch === '' && directive === '' ) {
+ safe.uboLog(logPrefix, `Called: ${safe.JSON_stringify(haystack, null, 2)}`);
+ return context.reflect();
}
- const argAfter = replacer(argBefore);
- if ( argAfter !== argBefore ) {
- setArg(context, argAfter);
- safe.uboLog(logPrefix, `Replaced argument:\nBefore: ${JSON.stringify(argBefore)}\nAfter: ${argAfter}`);
+ if ( matchObjectPropertiesFn(propNeedles, haystack) ) {
+ const xhrDetails = Object.assign(haystack, {
+ xhr: thisArg,
+ defer: args.length === 0 || !!args[0],
+ directive,
+ headers: {
+ 'date': '',
+ 'content-type': '',
+ 'content-length': '',
+ },
+ url: haystack.url,
+ props: {
+ response: { value: '' },
+ responseText: { value: '' },
+ responseXML: { value: null },
+ },
+ });
+ xhrInstances.set(thisArg, xhrDetails);
}
return context.reflect();
});
+ proxyApplyFn('XMLHttpRequest.prototype.send', function(context) {
+ const { thisArg } = context;
+ const xhrDetails = xhrInstances.get(thisArg);
+ if ( xhrDetails === undefined ) {
+ return context.reflect();
+ }
+ xhrDetails.headers['date'] = (new Date()).toUTCString();
+ let xhrText = '';
+ switch ( thisArg.responseType ) {
+ case 'arraybuffer':
+ xhrDetails.props.response.value = new ArrayBuffer(0);
+ xhrDetails.headers['content-type'] = 'application/octet-stream';
+ break;
+ case 'blob':
+ xhrDetails.props.response.value = new Blob([]);
+ xhrDetails.headers['content-type'] = 'application/octet-stream';
+ break;
+ case 'document': {
+ const parser = new DOMParser();
+ const doc = parser.parseFromString('', 'text/html');
+ xhrDetails.props.response.value = doc;
+ xhrDetails.props.responseXML.value = doc;
+ xhrDetails.headers['content-type'] = 'text/html';
+ break;
+ }
+ case 'json':
+ xhrDetails.props.response.value = {};
+ xhrDetails.props.responseText.value = '{}';
+ xhrDetails.headers['content-type'] = 'application/json';
+ break;
+ default: {
+ if ( directive === '' ) { break; }
+ xhrText = generateContentFn(trusted, xhrDetails.directive);
+ if ( xhrText instanceof Promise ) {
+ xhrText = xhrText.then(text => {
+ xhrDetails.props.response.value = text;
+ xhrDetails.props.responseText.value = text;
+ });
+ } else {
+ xhrDetails.props.response.value = xhrText;
+ xhrDetails.props.responseText.value = xhrText;
+ }
+ xhrDetails.headers['content-type'] = 'text/plain';
+ break;
+ }
+ }
+ if ( xhrDetails.defer === false ) {
+ xhrDetails.headers['content-length'] = `${xhrDetails.props.response.value}`.length;
+ Object.defineProperties(xhrDetails.xhr, {
+ readyState: { value: 4 },
+ responseURL: { value: xhrDetails.url },
+ status: { value: 200 },
+ statusText: { value: 'OK' },
+ });
+ Object.defineProperties(xhrDetails.xhr, xhrDetails.props);
+ return;
+ }
+ Promise.resolve(xhrText).then(( ) => xhrDetails).then(details => {
+ Object.defineProperties(details.xhr, {
+ readyState: { value: 1, configurable: true },
+ responseURL: { value: xhrDetails.url },
+ });
+ safeDispatchEvent(details.xhr, 'readystatechange');
+ return details;
+ }).then(details => {
+ xhrDetails.headers['content-length'] = `${details.props.response.value}`.length;
+ Object.defineProperties(details.xhr, {
+ readyState: { value: 2, configurable: true },
+ status: { value: 200 },
+ statusText: { value: 'OK' },
+ });
+ safeDispatchEvent(details.xhr, 'readystatechange');
+ return details;
+ }).then(details => {
+ Object.defineProperties(details.xhr, {
+ readyState: { value: 3, configurable: true },
+ });
+ Object.defineProperties(details.xhr, details.props);
+ safeDispatchEvent(details.xhr, 'readystatechange');
+ return details;
+ }).then(details => {
+ Object.defineProperties(details.xhr, {
+ readyState: { value: 4 },
+ });
+ safeDispatchEvent(details.xhr, 'readystatechange');
+ safeDispatchEvent(details.xhr, 'load');
+ safeDispatchEvent(details.xhr, 'loadend');
+ safe.uboLog(logPrefix, `Prevented with response:\n${details.xhr.response}`);
+ });
+ });
+ proxyApplyFn('XMLHttpRequest.prototype.getResponseHeader', function(context) {
+ const { thisArg } = context;
+ const xhrDetails = xhrInstances.get(thisArg);
+ if ( xhrDetails === undefined || thisArg.readyState < thisArg.HEADERS_RECEIVED ) {
+ return context.reflect();
+ }
+ const headerName = `${context.callArgs[0]}`;
+ const value = xhrDetails.headers[headerName.toLowerCase()];
+ if ( value !== undefined && value !== '' ) { return value; }
+ return null;
+ });
+ proxyApplyFn('XMLHttpRequest.prototype.getAllResponseHeaders', function(context) {
+ const { thisArg } = context;
+ const xhrDetails = xhrInstances.get(thisArg);
+ if ( xhrDetails === undefined || thisArg.readyState < thisArg.HEADERS_RECEIVED ) {
+ return context.reflect();
+ }
+ const out = [];
+ for ( const [ name, value ] of Object.entries(xhrDetails.headers) ) {
+ if ( !value ) { continue; }
+ out.push(`${name}: ${value}`);
+ }
+ if ( out.length !== 0 ) { out.push(''); }
+ return out.join('\r\n');
+ });
+}
+function trustedPreventXhr(...args) {
+ preventXhrFn(true, ...args);
};
-trustedReplaceArgument(...args);
+trustedPreventXhr(...args);
},
};
-scriptlets['spoof-css.js'] = {
+scriptlets['mpegdash-prune.js'] = {
aliases: [],
requiresTrust: false,
func: function (scriptletGlobals = {}, ...args) {
+function proxyToStringFn(proxiedFn, nativeFn) {
+ if ( proxyToStringFn.proxies === undefined ) {
+ proxyToStringFn.proxies = new WeakMap();
+ proxyToStringFn.nativeToString = Function.prototype.toString;
+ const proxiedToString = new Proxy(Function.prototype.toString, {
+ apply(target, thisArg) {
+ let proxied = thisArg;
+ for(;;) {
+ const fn = proxyToStringFn.proxies.get(proxied);
+ if ( fn === undefined ) { break; }
+ proxied = fn;
+ }
+ return proxyToStringFn.nativeToString.call(proxied);
+ }
+ });
+ proxyToStringFn.proxies.set(proxiedToString, proxyToStringFn.nativeToString);
+ Function.prototype.toString = proxiedToString;
+ }
+ proxyToStringFn.proxies.set(proxiedFn, nativeFn);
+}
+function parsePropertiesToMatchFn(propsToMatch, implicit = '') {
+ const safe = safeSelf();
+ const needles = new Map();
+ if ( propsToMatch === undefined || propsToMatch === '' ) { return needles; }
+ const options = { canNegate: true };
+ for ( const needle of safe.String_split.call(propsToMatch, /\s+/) ) {
+ let [ prop, pattern ] = safe.String_split.call(needle, ':');
+ if ( prop === '' ) { continue; }
+ if ( pattern !== undefined && /[^$\w -]/.test(prop) ) {
+ prop = `${prop}:${pattern}`;
+ pattern = undefined;
+ }
+ if ( pattern !== undefined ) {
+ needles.set(prop, safe.initPattern(pattern, options));
+ } else if ( implicit !== '' ) {
+ needles.set(implicit, safe.initPattern(prop, options));
+ }
+ }
+ return needles;
+}
function safeSelf() {
if ( safeSelf.safe ) {
return safeSelf.safe;
@@ -34918,8 +35099,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -34932,7 +35112,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -34943,10 +35123,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -34999,7 +35177,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -35087,124 +35265,212 @@ function safeSelf() {
}
return safe;
}
-function spoofCSS(
- selector,
- ...args
+function matchObjectPropertiesFn(propNeedles, ...objs) {
+ const safe = safeSelf();
+ const matched = [];
+ for ( const obj of objs ) {
+ if ( obj instanceof Object === false ) { continue; }
+ for ( const [ prop, details ] of propNeedles ) {
+ let value = obj[prop];
+ if ( value === undefined ) { continue; }
+ if ( typeof value !== 'string' ) {
+ try { value = safe.JSON_stringify(value); }
+ catch { }
+ if ( typeof value !== 'string' ) { continue; }
+ }
+ if ( safe.testPattern(details, value) === false ) { return; }
+ matched.push(`${prop}: ${value}`);
+ }
+ }
+ return matched;
+}
+function modifyXhrResponseFn(
+ propsToMatch = '',
+ modifierFn = ''
+) {
+ if ( typeof propsToMatch !== 'string' ) { return; }
+ const safe = safeSelf();
+ if ( modifyXhrResponseFn.xhrInstances === undefined ) {
+ modifyXhrResponseFn.xhrInstances = new WeakMap();
+ }
+ const propNeedles = parsePropertiesToMatchFn(propsToMatch, 'url');
+ const NativeXMLHttpRequest = self.XMLHttpRequest;
+ const TrappedXMLHttpRequest = class XMLHttpRequest extends NativeXMLHttpRequest {
+ open(method, url, ...args) {
+ const haystack = { method, url };
+ if ( propsToMatch === '' ) {
+ safe.uboLog(`modifyXhrResponseFn() / Called: ${safe.JSON_stringify(haystack, null, 2)}`);
+ } else if ( matchObjectPropertiesFn(propNeedles, haystack) ) {
+ modifyXhrResponseFn.xhrInstances.set(this, modifierFn);
+ }
+ return super.open(method, url, ...args);
+ }
+ get response() {
+ const modifierFn = modifyXhrResponseFn.xhrInstances.get(this);
+ return modifierFn
+ ? modifierFn(this, super.response)
+ : super.response;
+ }
+ get responseText() {
+ const modifierFn = modifyXhrResponseFn.xhrInstances.get(this);
+ return modifierFn
+ ? modifierFn(this, super.responseText)
+ : super.responseText;
+ }
+ get responseXML() {
+ const modifierFn = modifyXhrResponseFn.xhrInstances.get(this);
+ return modifierFn
+ ? modifierFn(this, super.responseXML)
+ : super.responseXML;
+ }
+ };
+ proxyToStringFn(TrappedXMLHttpRequest.prototype.open, NativeXMLHttpRequest.prototype.open);
+ proxyToStringFn(TrappedXMLHttpRequest, NativeXMLHttpRequest);
+ self.XMLHttpRequest = TrappedXMLHttpRequest;
+}
+function mpegdashPrune(
+ selector = '',
+ propsToMatch = ''
) {
if ( typeof selector !== 'string' ) { return; }
if ( selector === '' ) { return; }
- const toCamelCase = s => s.replace(/-[a-z]/g, s => s.charAt(1).toUpperCase());
- const propToValueMap = new Map();
- const privatePropToValueMap = new Map();
- for ( let i = 0; i < args.length; i += 2 ) {
- const prop = toCamelCase(args[i+0]);
- if ( prop === '' ) { break; }
- const value = args[i+1];
- if ( typeof value !== 'string' ) { break; }
- if ( prop.charCodeAt(0) === 0x5F /* _ */ ) {
- privatePropToValueMap.set(prop, value);
- } else {
- propToValueMap.set(prop, value);
- }
- }
const safe = safeSelf();
- const logPrefix = safe.makeLogPrefix('spoof-css', selector, ...args);
- const instanceProperties = [ 'cssText', 'length', 'parentRule' ];
- const spoofStyle = (prop, real) => {
- const normalProp = toCamelCase(prop);
- const shouldSpoof = propToValueMap.has(normalProp);
- const value = shouldSpoof ? propToValueMap.get(normalProp) : real;
- if ( shouldSpoof ) {
- safe.uboLog(logPrefix, `Spoofing ${prop} to ${value}`);
+ const logPrefix = safe.makeLogPrefix('mpegdash-prune', selector, propsToMatch);
+ const queryAll = (xmlDoc, selector) => {
+ if ( selector.startsWith('xpath:') === false ) {
+ return Array.from(xmlDoc.querySelectorAll(selector));
}
- return value;
+ const xpr = xmlDoc.evaluate(
+ selector.slice(6),
+ xmlDoc,
+ null,
+ XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
+ null
+ );
+ const out = [];
+ for ( let i = 0; i < xpr.snapshotLength; i++ ) {
+ const node = xpr.snapshotItem(i);
+ out.push(node);
+ }
+ return out;
};
- const cloackFunc = (fn, thisArg, name) => {
- const trap = fn.bind(thisArg);
- Object.defineProperty(trap, 'name', { value: name });
- Object.defineProperty(trap, 'toString', {
- value: ( ) => `function ${name}() { [native code] }`
- });
- return trap;
+ const rePTparse = /^PT(\d+D)?(\d+H)?(\d+M)?([\d.]+S)?$/;
+ const secondsPerDay = 24 * 60 * 60;
+ const secondsPerHour = 60 * 60;
+ const secondsPerMinute = 60;
+ const secondsFromPT = pt => {
+ const match = rePTparse.exec(pt);
+ if ( match === null ) { return; }
+ let seconds = 0;
+ if ( match[1] ) {
+ const d = parseFloat(match[1].slice(0, -1));
+ if ( isNaN(d) ) { return; }
+ seconds += d * secondsPerDay;
+ }
+ if ( match[2] ) {
+ const h = parseFloat(match[2].slice(0, -1));
+ if ( isNaN(h) ) { return; }
+ seconds += h * secondsPerHour;
+ }
+ if ( match[3] ) {
+ const m = parseFloat(match[3].slice(0, -1));
+ if ( isNaN(m) ) { return; }
+ seconds += m * secondsPerMinute;
+ }
+ if ( match[4] ) {
+ const s = parseFloat(match[4].slice(0, -1));
+ if ( isNaN(s) ) { return; }
+ seconds += s;
+ }
+ return seconds;
+ };
+ const ptFromSeconds = seconds => {
+ const parts = [ 'PT' ];
+ const d = Math.floor(seconds / secondsPerDay);
+ if ( d ) {
+ parts.push(`${d}D`);
+ seconds -= d * secondsPerDay;
+ }
+ const h = Math.floor(seconds / secondsPerHour);
+ if ( h ) {
+ parts.push(`${h}H`);
+ seconds -= h * secondsPerHour;
+ }
+ const m = Math.floor(seconds / secondsPerMinute);
+ if ( m ) {
+ parts.push(`${m}M`);
+ seconds -= m * secondsPerMinute;
+ }
+ parts.push(`${seconds}S`);
+ return parts.join('');
};
- self.getComputedStyle = new Proxy(self.getComputedStyle, {
- apply: function(target, thisArg, args) {
- // eslint-disable-next-line no-debugger
- if ( privatePropToValueMap.has('_debug') ) { debugger; }
- const style = Reflect.apply(target, thisArg, args);
- const targetElements = new WeakSet(document.querySelectorAll(selector));
- if ( targetElements.has(args[0]) === false ) { return style; }
- const proxiedStyle = new Proxy(style, {
- get(target, prop) {
- if ( typeof target[prop] === 'function' ) {
- if ( prop === 'getPropertyValue' ) {
- return cloackFunc(function getPropertyValue(prop) {
- return spoofStyle(prop, target[prop]);
- }, target, 'getPropertyValue');
- }
- return cloackFunc(target[prop], target, prop);
- }
- if ( instanceProperties.includes(prop) ) {
- return Reflect.get(target, prop);
- }
- return spoofStyle(prop, Reflect.get(target, prop));
- },
- getOwnPropertyDescriptor(target, prop) {
- if ( propToValueMap.has(prop) ) {
- return {
- configurable: true,
- enumerable: true,
- value: propToValueMap.get(prop),
- writable: true,
- };
- }
- return Reflect.getOwnPropertyDescriptor(target, prop);
- },
- });
- return proxiedStyle;
- },
- get(target, prop) {
- if ( prop === 'toString' ) {
- return target.toString.bind(target);
- }
- return Reflect.get(target, prop);
- },
- });
- Element.prototype.getBoundingClientRect = new Proxy(Element.prototype.getBoundingClientRect, {
- apply: function(target, thisArg, args) {
- // eslint-disable-next-line no-debugger
- if ( privatePropToValueMap.has('_debug') ) { debugger; }
- const rect = Reflect.apply(target, thisArg, args);
- const targetElements = new WeakSet(document.querySelectorAll(selector));
- if ( targetElements.has(thisArg) === false ) { return rect; }
- let { x, y, height, width } = rect;
- if ( privatePropToValueMap.has('_rectx') ) {
- x = parseFloat(privatePropToValueMap.get('_rectx'));
- }
- if ( privatePropToValueMap.has('_recty') ) {
- y = parseFloat(privatePropToValueMap.get('_recty'));
- }
- if ( privatePropToValueMap.has('_rectw') ) {
- width = parseFloat(privatePropToValueMap.get('_rectw'));
- } else if ( propToValueMap.has('width') ) {
- width = parseFloat(propToValueMap.get('width'));
- }
- if ( privatePropToValueMap.has('_recth') ) {
- height = parseFloat(privatePropToValueMap.get('_recth'));
- } else if ( propToValueMap.has('height') ) {
- height = parseFloat(propToValueMap.get('height'));
+ const fixTimeAttributes = xmlDoc => {
+ try {
+ const periods = queryAll(xmlDoc, 'MPD > Period');
+ if ( periods.length === 0 ) { return; }
+ let seconds = 0;
+ for ( const period of periods ) {
+ const startAttrBefore = period.getAttribute('start');
+ const durAttr = period.getAttribute('duration');
+ if ( startAttrBefore === null || durAttr === null ) { continue; }
+ const startAttrAfter = ptFromSeconds(seconds);
+ period.setAttribute('start', startAttrAfter);
+ if ( period.hasAttribute('id') ) {
+ const idAttr = period.getAttribute('id');
+ period.setAttribute('id', idAttr.replace(startAttrBefore, startAttrAfter));
+ }
+ seconds += secondsFromPT(durAttr);
+ }
+ const mpds = queryAll(xmlDoc, 'MPD[mediaPresentationDuration]');
+ if ( mpds.length !== 1 ) { return; }
+ mpds[0].setAttribute('mediaPresentationDuration', ptFromSeconds(seconds));
+ } catch {
+ }
+ };
+ const pruneFromDoc = xmlDoc => {
+ try {
+ if ( selector === '' ) {
+ const serializer = new XMLSerializer();
+ safe.uboLog(logPrefix, `Document is\n\t${serializer.serializeToString(xmlDoc)}`);
}
- return new self.DOMRect(x, y, width, height);
- },
- get(target, prop) {
- if ( prop === 'toString' ) {
- return target.toString.bind(target);
+ const items = queryAll(xmlDoc, selector);
+ if ( items.length === 0 ) { return xmlDoc; }
+ safe.uboLog(logPrefix, `Patching ${items.length} items`);
+ for ( const item of items ) {
+ if ( item.nodeType !== 1 ) { continue; }
+ item.setAttribute('duration', 'PT0S');
}
- return Reflect.get(target, prop);
- },
+ fixTimeAttributes(xmlDoc);
+ } catch(ex) {
+ safe.uboErr(logPrefix, `Error: ${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 {
+ }
+ return text;
+ };
+ modifyXhrResponseFn(propsToMatch, (xhr, before) => {
+ if ( before instanceof XMLDocument ) {
+ return pruneFromDoc(before);
+ }
+ if ( typeof before === 'string' ) {
+ return pruneFromText(before);
+ }
+ return before;
});
};
-spoofCSS(...args);
+mpegdashPrune(...args);
},
};
@@ -35299,8 +35565,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -35313,7 +35578,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -35324,10 +35589,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -35380,7 +35643,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -35492,6 +35755,8 @@ function getSafeCookieValuesFn() {
'decline', 'declined',
'closed', 'next', 'mandatory',
'disagree', 'agree',
+ 'set', 'unset',
+ 'given',
];
}
function setCookie(
@@ -35621,8 +35886,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -35635,7 +35899,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -35646,10 +35910,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -35702,7 +35964,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -35814,6 +36076,8 @@ function getSafeCookieValuesFn() {
'decline', 'declined',
'closed', 'next', 'mandatory',
'disagree', 'agree',
+ 'set', 'unset',
+ 'given',
];
}
function setCookie(
@@ -35946,8 +36210,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -35960,7 +36223,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -35971,10 +36234,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -36027,7 +36288,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -36259,8 +36520,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -36273,7 +36533,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -36284,10 +36544,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -36340,7 +36598,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -36498,8 +36756,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -36512,7 +36769,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -36523,10 +36780,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -36579,7 +36834,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -36773,6 +37028,8 @@ function getSafeCookieValuesFn() {
'decline', 'declined',
'closed', 'next', 'mandatory',
'disagree', 'agree',
+ 'set', 'unset',
+ 'given',
];
}
function setLocalStorageItemFn(
@@ -36860,8 +37117,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -36874,7 +37130,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -36885,10 +37141,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -36941,7 +37195,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -37068,6 +37322,8 @@ function getSafeCookieValuesFn() {
'decline', 'declined',
'closed', 'next', 'mandatory',
'disagree', 'agree',
+ 'set', 'unset',
+ 'given',
];
}
function setLocalStorageItemFn(
@@ -37155,8 +37411,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -37169,7 +37424,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -37180,10 +37435,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -37236,7 +37489,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -37363,6 +37616,8 @@ function getSafeCookieValuesFn() {
'decline', 'declined',
'closed', 'next', 'mandatory',
'disagree', 'agree',
+ 'set', 'unset',
+ 'given',
];
}
function setLocalStorageItemFn(
@@ -37450,8 +37705,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -37464,7 +37718,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -37475,10 +37729,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -37531,7 +37783,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -37658,6 +37910,8 @@ function getSafeCookieValuesFn() {
'decline', 'declined',
'closed', 'next', 'mandatory',
'disagree', 'agree',
+ 'set', 'unset',
+ 'given',
];
}
function setLocalStorageItemFn(
@@ -37745,8 +37999,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -37759,7 +38012,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -37770,10 +38023,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -37826,7 +38077,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -37937,8 +38188,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -37951,7 +38201,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -37962,10 +38212,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -38018,7 +38266,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -38186,8 +38434,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -38200,7 +38447,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -38211,10 +38458,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -38267,7 +38512,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -38413,8 +38658,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -38427,7 +38671,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -38438,10 +38682,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -38494,7 +38736,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -38627,8 +38869,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -38641,7 +38882,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -38652,10 +38893,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -38708,7 +38947,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -38841,8 +39080,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -38855,7 +39093,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -38866,10 +39104,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -38922,7 +39158,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -39053,8 +39289,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -39067,7 +39302,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -39078,10 +39313,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -39134,7 +39367,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -39336,8 +39569,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -39350,7 +39582,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -39361,10 +39593,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -39417,7 +39647,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -39581,8 +39811,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -39595,7 +39824,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -39606,10 +39835,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -39662,7 +39889,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -39951,8 +40178,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -39965,7 +40191,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -39976,10 +40202,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -40032,7 +40256,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -40317,6 +40541,46 @@ aliases: [],
requiresTrust: false,
func: function (scriptletGlobals = {}, ...args) {
+function proxyToStringFn(proxiedFn, nativeFn) {
+ if ( proxyToStringFn.proxies === undefined ) {
+ proxyToStringFn.proxies = new WeakMap();
+ proxyToStringFn.nativeToString = Function.prototype.toString;
+ const proxiedToString = new Proxy(Function.prototype.toString, {
+ apply(target, thisArg) {
+ let proxied = thisArg;
+ for(;;) {
+ const fn = proxyToStringFn.proxies.get(proxied);
+ if ( fn === undefined ) { break; }
+ proxied = fn;
+ }
+ return proxyToStringFn.nativeToString.call(proxied);
+ }
+ });
+ proxyToStringFn.proxies.set(proxiedToString, proxyToStringFn.nativeToString);
+ Function.prototype.toString = proxiedToString;
+ }
+ proxyToStringFn.proxies.set(proxiedFn, nativeFn);
+}
+function parsePropertiesToMatchFn(propsToMatch, implicit = '') {
+ const safe = safeSelf();
+ const needles = new Map();
+ if ( propsToMatch === undefined || propsToMatch === '' ) { return needles; }
+ const options = { canNegate: true };
+ for ( const needle of safe.String_split.call(propsToMatch, /\s+/) ) {
+ let [ prop, pattern ] = safe.String_split.call(needle, ':');
+ if ( prop === '' ) { continue; }
+ if ( pattern !== undefined && /[^$\w -]/.test(prop) ) {
+ prop = `${prop}:${pattern}`;
+ pattern = undefined;
+ }
+ if ( pattern !== undefined ) {
+ needles.set(prop, safe.initPattern(pattern, options));
+ } else if ( implicit !== '' ) {
+ needles.set(implicit, safe.initPattern(prop, options));
+ }
+ }
+ return needles;
+}
function safeSelf() {
if ( safeSelf.safe ) {
return safeSelf.safe;
@@ -40325,8 +40589,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -40339,7 +40602,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -40350,10 +40613,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -40406,7 +40667,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -40494,6 +40755,69 @@ function safeSelf() {
}
return safe;
}
+function matchObjectPropertiesFn(propNeedles, ...objs) {
+ const safe = safeSelf();
+ const matched = [];
+ for ( const obj of objs ) {
+ if ( obj instanceof Object === false ) { continue; }
+ for ( const [ prop, details ] of propNeedles ) {
+ let value = obj[prop];
+ if ( value === undefined ) { continue; }
+ if ( typeof value !== 'string' ) {
+ try { value = safe.JSON_stringify(value); }
+ catch { }
+ if ( typeof value !== 'string' ) { continue; }
+ }
+ if ( safe.testPattern(details, value) === false ) { return; }
+ matched.push(`${prop}: ${value}`);
+ }
+ }
+ return matched;
+}
+function modifyXhrResponseFn(
+ propsToMatch = '',
+ modifierFn = ''
+) {
+ if ( typeof propsToMatch !== 'string' ) { return; }
+ const safe = safeSelf();
+ if ( modifyXhrResponseFn.xhrInstances === undefined ) {
+ modifyXhrResponseFn.xhrInstances = new WeakMap();
+ }
+ const propNeedles = parsePropertiesToMatchFn(propsToMatch, 'url');
+ const NativeXMLHttpRequest = self.XMLHttpRequest;
+ const TrappedXMLHttpRequest = class XMLHttpRequest extends NativeXMLHttpRequest {
+ open(method, url, ...args) {
+ const haystack = { method, url };
+ if ( propsToMatch === '' ) {
+ safe.uboLog(`modifyXhrResponseFn() / Called: ${safe.JSON_stringify(haystack, null, 2)}`);
+ } else if ( matchObjectPropertiesFn(propNeedles, haystack) ) {
+ modifyXhrResponseFn.xhrInstances.set(this, modifierFn);
+ }
+ return super.open(method, url, ...args);
+ }
+ get response() {
+ const modifierFn = modifyXhrResponseFn.xhrInstances.get(this);
+ return modifierFn
+ ? modifierFn(this, super.response)
+ : super.response;
+ }
+ get responseText() {
+ const modifierFn = modifyXhrResponseFn.xhrInstances.get(this);
+ return modifierFn
+ ? modifierFn(this, super.responseText)
+ : super.responseText;
+ }
+ get responseXML() {
+ const modifierFn = modifyXhrResponseFn.xhrInstances.get(this);
+ return modifierFn
+ ? modifierFn(this, super.responseXML)
+ : super.responseXML;
+ }
+ };
+ proxyToStringFn(TrappedXMLHttpRequest.prototype.open, NativeXMLHttpRequest.prototype.open);
+ proxyToStringFn(TrappedXMLHttpRequest, NativeXMLHttpRequest);
+ self.XMLHttpRequest = TrappedXMLHttpRequest;
+}
function xmlPrune(
selector = '',
selectorCheck = '',
@@ -40596,41 +40920,14 @@ 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 === 'document' ||
- type === '' && thisArg.responseXML instanceof XMLDocument
- ) {
- pruneFromDoc(thisArg.responseXML);
- const serializer = new XMLSerializer();
- const textout = serializer.serializeToString(thisArg.responseXML);
- Object.defineProperty(thisArg, 'responseText', { value: textout });
- if ( typeof thisArg.response === 'string' ) {
- Object.defineProperty(thisArg, 'response', { value: textout });
- }
- return;
- }
- if (
- type === 'text' ||
- type === '' && typeof thisArg.responseText === 'string'
- ) {
- 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;
- }
- });
- return Reflect.apply(target, thisArg, args);
+ modifyXhrResponseFn(urlPattern, (xhr, before) => {
+ if ( before instanceof XMLDocument ) {
+ return pruneFromDoc(before);
+ }
+ if ( typeof before === 'string' ) {
+ return pruneFromText(before);
}
+ return before;
});
};
xmlPrune(...args);
@@ -40651,8 +40948,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -40665,7 +40961,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -40676,10 +40972,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -40732,7 +41026,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -41094,8 +41388,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -41108,7 +41401,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -41119,10 +41412,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -41175,7 +41466,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -41337,8 +41628,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -41351,7 +41641,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -41362,10 +41652,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -41418,7 +41706,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -41528,15 +41816,6 @@ function replaceNodeTextFn(
const reExcludes = extraArgs.excludes
? safe.patternToRegex(extraArgs.excludes, 'ms')
: null;
- const stop = (takeRecord = true) => {
- if ( takeRecord ) {
- handleMutations(observer.takeRecords());
- }
- observer.disconnect();
- if ( safe.logLevel > 1 ) {
- safe.uboLog(logPrefix, 'Quitting');
- }
- };
const textContentFactory = (( ) => {
const out = { createScript: s => s };
const { trustedTypes: tt } = self;
@@ -41549,19 +41828,19 @@ function replaceNodeTextFn(
}
return out;
})();
- let sedCount = extraArgs.sedCount || 0;
+ let sedCount = extraArgs.sedCount ?? Number.MAX_SAFE_INTEGER;
const handleNode = node => {
const before = node.textContent;
if ( reIncludes ) {
reIncludes.lastIndex = 0;
- if ( safe.RegExp_test.call(reIncludes, before) === false ) { return true; }
+ if ( safe.RegExp_test(reIncludes, before) === false ) { return; }
}
if ( reExcludes ) {
reExcludes.lastIndex = 0;
- if ( safe.RegExp_test.call(reExcludes, before) ) { return true; }
+ if ( safe.RegExp_test(reExcludes, before) ) { return; }
}
rePattern.lastIndex = 0;
- if ( safe.RegExp_test.call(rePattern, before) === false ) { return true; }
+ if ( safe.RegExp_test(rePattern, before) === false ) { return; }
rePattern.lastIndex = 0;
const after = pattern !== ''
? before.replace(rePattern, replacement)
@@ -41573,44 +41852,65 @@ function replaceNodeTextFn(
safe.uboLog(logPrefix, `Text before:\n${before.trim()}`);
}
safe.uboLog(logPrefix, `Text after:\n${after.trim()}`);
- return sedCount === 0 || (sedCount -= 1) !== 0;
+ sedCount -= 1;
};
- const handleMutations = mutations => {
- for ( const mutation of mutations ) {
- for ( const node of mutation.addedNodes ) {
- if ( reNodeName.test(node.nodeName) === false ) { continue; }
- if ( handleNode(node) ) { continue; }
- stop(false); return;
- }
- }
- };
- const observer = new MutationObserver(handleMutations);
- observer.observe(document, { childList: true, subtree: true });
- if ( document.documentElement ) {
- const treeWalker = document.createTreeWalker(
- document.documentElement,
+ const handleTree = root => {
+ const treeWalker = document.createTreeWalker(root,
NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT
);
+ const { currentScript } = document;
let count = 0;
for (;;) {
const node = treeWalker.nextNode();
- count += 1;
if ( node === null ) { break; }
- if ( reNodeName.test(node.nodeName) === false ) { continue; }
- if ( node === document.currentScript ) { continue; }
- if ( handleNode(node) ) { continue; }
- stop(); break;
+ count += 1;
+ if ( node === currentScript ) { continue; }
+ if ( reNodeName.test(node.nodeName) ) {
+ handleNode(node);
+ } else if ( node.nodeName === 'TEMPLATE' ) {
+ count += handleTree(node.content);
+ } else {
+ continue;
+ }
+ if ( sedCount === 0 ) { break; }
}
+ return count;
+ };
+ if ( document.documentElement ) {
+ const count = handleTree(document.documentElement);
safe.uboLog(logPrefix, `${count} nodes present before installing mutation observer`);
}
- if ( extraArgs.stay ) { return; }
- runAt(( ) => {
- const quitAfter = extraArgs.quitAfter || 0;
- if ( quitAfter !== 0 ) {
- setTimeout(( ) => { stop(); }, quitAfter);
- } else {
- stop();
+ const stay = Boolean(extraArgs.stay);
+ if ( sedCount === 0 && stay === false ) { return; }
+ const stop = (takeRecord = true) => {
+ const mutations = takeRecord ? observer.takeRecords() : [];
+ observer.disconnect();
+ handleMutations(mutations);
+ if ( safe.logLevel > 1 ) {
+ safe.uboLog(logPrefix, 'Quitting');
}
+ };
+ const handleMutations = mutations => {
+ for ( const mutation of mutations ) {
+ for ( const node of mutation.addedNodes ) {
+ if ( reNodeName.test(node.nodeName) ) {
+ handleNode(node);
+ } else if ( node.nodeName === 'TEMPLATE' ) {
+ handleTree(node.content);
+ } else {
+ continue;
+ }
+ if ( sedCount === 0 ) { return stop(false); }
+ }
+ }
+ };
+ const observer = new MutationObserver(handleMutations);
+ observer.observe(document, { childList: true, subtree: true });
+ if ( stay ) { return; }
+ runAt(( ) => {
+ const quitAfter = extraArgs.quitAfter ?? 0;
+ if ( quitAfter === 0 ) { return stop(); }
+ setTimeout(( ) => { stop(); }, quitAfter);
}, 'interactive');
}
function removeNodeText(
@@ -41638,8 +41938,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -41652,7 +41951,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -41663,10 +41962,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -41719,7 +42016,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -42006,8 +42303,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -42020,7 +42316,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -42031,10 +42327,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -42087,7 +42381,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -42197,15 +42491,6 @@ function replaceNodeTextFn(
const reExcludes = extraArgs.excludes
? safe.patternToRegex(extraArgs.excludes, 'ms')
: null;
- const stop = (takeRecord = true) => {
- if ( takeRecord ) {
- handleMutations(observer.takeRecords());
- }
- observer.disconnect();
- if ( safe.logLevel > 1 ) {
- safe.uboLog(logPrefix, 'Quitting');
- }
- };
const textContentFactory = (( ) => {
const out = { createScript: s => s };
const { trustedTypes: tt } = self;
@@ -42218,19 +42503,19 @@ function replaceNodeTextFn(
}
return out;
})();
- let sedCount = extraArgs.sedCount || 0;
+ let sedCount = extraArgs.sedCount ?? Number.MAX_SAFE_INTEGER;
const handleNode = node => {
const before = node.textContent;
if ( reIncludes ) {
reIncludes.lastIndex = 0;
- if ( safe.RegExp_test.call(reIncludes, before) === false ) { return true; }
+ if ( safe.RegExp_test(reIncludes, before) === false ) { return; }
}
if ( reExcludes ) {
reExcludes.lastIndex = 0;
- if ( safe.RegExp_test.call(reExcludes, before) ) { return true; }
+ if ( safe.RegExp_test(reExcludes, before) ) { return; }
}
rePattern.lastIndex = 0;
- if ( safe.RegExp_test.call(rePattern, before) === false ) { return true; }
+ if ( safe.RegExp_test(rePattern, before) === false ) { return; }
rePattern.lastIndex = 0;
const after = pattern !== ''
? before.replace(rePattern, replacement)
@@ -42242,44 +42527,65 @@ function replaceNodeTextFn(
safe.uboLog(logPrefix, `Text before:\n${before.trim()}`);
}
safe.uboLog(logPrefix, `Text after:\n${after.trim()}`);
- return sedCount === 0 || (sedCount -= 1) !== 0;
- };
- const handleMutations = mutations => {
- for ( const mutation of mutations ) {
- for ( const node of mutation.addedNodes ) {
- if ( reNodeName.test(node.nodeName) === false ) { continue; }
- if ( handleNode(node) ) { continue; }
- stop(false); return;
- }
- }
+ sedCount -= 1;
};
- const observer = new MutationObserver(handleMutations);
- observer.observe(document, { childList: true, subtree: true });
- if ( document.documentElement ) {
- const treeWalker = document.createTreeWalker(
- document.documentElement,
+ const handleTree = root => {
+ const treeWalker = document.createTreeWalker(root,
NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT
);
+ const { currentScript } = document;
let count = 0;
for (;;) {
const node = treeWalker.nextNode();
- count += 1;
if ( node === null ) { break; }
- if ( reNodeName.test(node.nodeName) === false ) { continue; }
- if ( node === document.currentScript ) { continue; }
- if ( handleNode(node) ) { continue; }
- stop(); break;
+ count += 1;
+ if ( node === currentScript ) { continue; }
+ if ( reNodeName.test(node.nodeName) ) {
+ handleNode(node);
+ } else if ( node.nodeName === 'TEMPLATE' ) {
+ count += handleTree(node.content);
+ } else {
+ continue;
+ }
+ if ( sedCount === 0 ) { break; }
}
+ return count;
+ };
+ if ( document.documentElement ) {
+ const count = handleTree(document.documentElement);
safe.uboLog(logPrefix, `${count} nodes present before installing mutation observer`);
}
- if ( extraArgs.stay ) { return; }
- runAt(( ) => {
- const quitAfter = extraArgs.quitAfter || 0;
- if ( quitAfter !== 0 ) {
- setTimeout(( ) => { stop(); }, quitAfter);
- } else {
- stop();
+ const stay = Boolean(extraArgs.stay);
+ if ( sedCount === 0 && stay === false ) { return; }
+ const stop = (takeRecord = true) => {
+ const mutations = takeRecord ? observer.takeRecords() : [];
+ observer.disconnect();
+ handleMutations(mutations);
+ if ( safe.logLevel > 1 ) {
+ safe.uboLog(logPrefix, 'Quitting');
+ }
+ };
+ const handleMutations = mutations => {
+ for ( const mutation of mutations ) {
+ for ( const node of mutation.addedNodes ) {
+ if ( reNodeName.test(node.nodeName) ) {
+ handleNode(node);
+ } else if ( node.nodeName === 'TEMPLATE' ) {
+ handleTree(node.content);
+ } else {
+ continue;
+ }
+ if ( sedCount === 0 ) { return stop(false); }
+ }
}
+ };
+ const observer = new MutationObserver(handleMutations);
+ observer.observe(document, { childList: true, subtree: true });
+ if ( stay ) { return; }
+ runAt(( ) => {
+ const quitAfter = extraArgs.quitAfter ?? 0;
+ if ( quitAfter === 0 ) { return stop(); }
+ setTimeout(( ) => { stop(); }, quitAfter);
}, 'interactive');
}
function replaceNodeText(
@@ -42347,8 +42653,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -42361,7 +42666,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -42372,10 +42677,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -42428,7 +42731,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -42650,8 +42953,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -42664,7 +42966,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -42675,10 +42977,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -42731,7 +43031,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -43047,8 +43347,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -43061,7 +43360,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -43072,10 +43371,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -43128,7 +43425,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -43362,8 +43659,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -43376,7 +43672,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -43387,10 +43683,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -43443,7 +43737,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -43637,7 +43931,7 @@ function trustedReplaceOutboundText(
) {
if ( propChain === '' ) { return; }
const safe = safeSelf();
- const logPrefix = safe.makeLogPrefix('trusted-replace-outbound-text', propChain, rawPattern, rawReplacement, ...args);
+ const logPrefix = safe.makeLogPrefix('trusted-replace-outbound-text', propChain, rawPattern, rawReplacement, ...varargs);
const rePattern = safe.patternToRegex(rawPattern);
const replacement = rawReplacement.startsWith('json:')
? safe.JSON_parse(rawReplacement.slice(5))
@@ -43786,8 +44080,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -43800,7 +44093,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -43811,10 +44104,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -43867,7 +44158,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -44061,7 +44352,7 @@ function trustedSuppressNativeMethod(
}
}
if ( signatureArg.type === 'pattern' ) {
- if ( safe.RegExp_test.call(signatureArg.re, targetArg) === false ) {
+ if ( safe.RegExp_test(signatureArg.re, targetArg) === false ) {
return context.reflect();
}
}
@@ -44100,8 +44391,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -44114,7 +44404,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -44125,10 +44415,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -44181,7 +44469,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},
@@ -44476,8 +44764,7 @@ function safeSelf() {
const safe = {
'Array_from': Array.from,
'Error': self.Error,
- 'Function_toStringFn': self.Function.prototype.toString,
- 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
+ 'Function_toString': Function.prototype.call.bind(self.Function.prototype.toString),
'Math_floor': Math.floor,
'Math_max': Math.max,
'Math_min': Math.min,
@@ -44490,7 +44777,7 @@ function safeSelf() {
'Object_hasOwn': Object.hasOwn.bind(Object),
'Object_toString': Object.prototype.toString,
'RegExp': self.RegExp,
- 'RegExp_test': self.RegExp.prototype.test,
+ 'RegExp_test': Function.prototype.call.bind(self.RegExp.prototype.test),
'RegExp_exec': self.RegExp.prototype.exec,
'Request_clone': self.Request.prototype.clone,
'String': self.String,
@@ -44501,10 +44788,8 @@ function safeSelf() {
'removeEventListener': self.EventTarget.prototype.removeEventListener,
'fetch': self.fetch,
'JSON': self.JSON,
- 'JSON_parseFn': self.JSON.parse,
- 'JSON_stringifyFn': self.JSON.stringify,
- 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
- 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
+ 'JSON_parse': Function.prototype.call.bind(self.JSON.parse, self.JSON),
+ 'JSON_stringify': Function.prototype.call.bind(self.JSON.stringify, self.JSON),
'log': console.log.bind(console),
// Properties
logLevel: 0,
@@ -44557,7 +44842,7 @@ function safeSelf() {
testPattern(details, haystack) {
if ( details.matchAll ) { return true; }
if ( details.re ) {
- return this.RegExp_test.call(details.re, haystack) === details.expect;
+ return this.RegExp_test(details.re, haystack) === details.expect;
}
return haystack.includes(details.pattern) === details.expect;
},