@@ -19129,6 +19129,231 @@ noEvalIf(...args);
1912919129};
1913019130
1913119131
19132+ scriptlets['prevent-dialog.js'] = {
19133+ aliases: [],
19134+
19135+ requiresTrust: false,
19136+ func: function (scriptletGlobals = {}, ...args) {
19137+ function safeSelf() {
19138+ if ( scriptletGlobals.safeSelf ) {
19139+ return scriptletGlobals.safeSelf;
19140+ }
19141+ const self = globalThis;
19142+ const safe = {
19143+ 'Array_from': Array.from,
19144+ 'Error': self.Error,
19145+ 'Function_toStringFn': self.Function.prototype.toString,
19146+ 'Function_toString': thisArg => safe.Function_toStringFn.call(thisArg),
19147+ 'Math_floor': Math.floor,
19148+ 'Math_max': Math.max,
19149+ 'Math_min': Math.min,
19150+ 'Math_random': Math.random,
19151+ 'Object': Object,
19152+ 'Object_defineProperty': Object.defineProperty.bind(Object),
19153+ 'Object_defineProperties': Object.defineProperties.bind(Object),
19154+ 'Object_fromEntries': Object.fromEntries.bind(Object),
19155+ 'Object_getOwnPropertyDescriptor': Object.getOwnPropertyDescriptor.bind(Object),
19156+ 'Object_hasOwn': Object.hasOwn.bind(Object),
19157+ 'RegExp': self.RegExp,
19158+ 'RegExp_test': self.RegExp.prototype.test,
19159+ 'RegExp_exec': self.RegExp.prototype.exec,
19160+ 'Request_clone': self.Request.prototype.clone,
19161+ 'String': self.String,
19162+ 'String_fromCharCode': String.fromCharCode,
19163+ 'String_split': String.prototype.split,
19164+ 'XMLHttpRequest': self.XMLHttpRequest,
19165+ 'addEventListener': self.EventTarget.prototype.addEventListener,
19166+ 'removeEventListener': self.EventTarget.prototype.removeEventListener,
19167+ 'fetch': self.fetch,
19168+ 'JSON': self.JSON,
19169+ 'JSON_parseFn': self.JSON.parse,
19170+ 'JSON_stringifyFn': self.JSON.stringify,
19171+ 'JSON_parse': (...args) => safe.JSON_parseFn.call(safe.JSON, ...args),
19172+ 'JSON_stringify': (...args) => safe.JSON_stringifyFn.call(safe.JSON, ...args),
19173+ 'log': console.log.bind(console),
19174+ // Properties
19175+ logLevel: 0,
19176+ // Methods
19177+ makeLogPrefix(...args) {
19178+ return this.sendToLogger && `[${args.join(' \u205D ')}]` || '';
19179+ },
19180+ uboLog(...args) {
19181+ if ( this.sendToLogger === undefined ) { return; }
19182+ if ( args === undefined || args[0] === '' ) { return; }
19183+ return this.sendToLogger('info', ...args);
19184+
19185+ },
19186+ uboErr(...args) {
19187+ if ( this.sendToLogger === undefined ) { return; }
19188+ if ( args === undefined || args[0] === '' ) { return; }
19189+ return this.sendToLogger('error', ...args);
19190+ },
19191+ escapeRegexChars(s) {
19192+ return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
19193+ },
19194+ initPattern(pattern, options = {}) {
19195+ if ( pattern === '' ) {
19196+ return { matchAll: true, expect: true };
19197+ }
19198+ const expect = (options.canNegate !== true || pattern.startsWith('!') === false);
19199+ if ( expect === false ) {
19200+ pattern = pattern.slice(1);
19201+ }
19202+ const match = /^\/(.+)\/([gimsu]*)$/.exec(pattern);
19203+ if ( match !== null ) {
19204+ return {
19205+ re: new this.RegExp(
19206+ match[1],
19207+ match[2] || options.flags
19208+ ),
19209+ expect,
19210+ };
19211+ }
19212+ if ( options.flags !== undefined ) {
19213+ return {
19214+ re: new this.RegExp(this.escapeRegexChars(pattern),
19215+ options.flags
19216+ ),
19217+ expect,
19218+ };
19219+ }
19220+ return { pattern, expect };
19221+ },
19222+ testPattern(details, haystack) {
19223+ if ( details.matchAll ) { return true; }
19224+ if ( details.re ) {
19225+ return this.RegExp_test.call(details.re, haystack) === details.expect;
19226+ }
19227+ return haystack.includes(details.pattern) === details.expect;
19228+ },
19229+ patternToRegex(pattern, flags = undefined, verbatim = false) {
19230+ if ( pattern === '' ) { return /^/; }
19231+ const match = /^\/(.+)\/([gimsu]*)$/.exec(pattern);
19232+ if ( match === null ) {
19233+ const reStr = this.escapeRegexChars(pattern);
19234+ return new RegExp(verbatim ? `^${reStr}$` : reStr, flags);
19235+ }
19236+ try {
19237+ return new RegExp(match[1], match[2] || undefined);
19238+ }
19239+ catch {
19240+ }
19241+ return /^/;
19242+ },
19243+ getExtraArgs(args, offset = 0) {
19244+ const entries = args.slice(offset).reduce((out, v, i, a) => {
19245+ if ( (i & 1) === 0 ) {
19246+ const rawValue = a[i+1];
19247+ const value = /^\d+$/.test(rawValue)
19248+ ? parseInt(rawValue, 10)
19249+ : rawValue;
19250+ out.push([ a[i], value ]);
19251+ }
19252+ return out;
19253+ }, []);
19254+ return this.Object_fromEntries(entries);
19255+ },
19256+ onIdle(fn, options) {
19257+ if ( self.requestIdleCallback ) {
19258+ return self.requestIdleCallback(fn, options);
19259+ }
19260+ return self.requestAnimationFrame(fn);
19261+ },
19262+ offIdle(id) {
19263+ if ( self.requestIdleCallback ) {
19264+ return self.cancelIdleCallback(id);
19265+ }
19266+ return self.cancelAnimationFrame(id);
19267+ }
19268+ };
19269+ scriptletGlobals.safeSelf = safe;
19270+ if ( scriptletGlobals.bcSecret === undefined ) { return safe; }
19271+ // This is executed only when the logger is opened
19272+ safe.logLevel = scriptletGlobals.logLevel || 1;
19273+ let lastLogType = '';
19274+ let lastLogText = '';
19275+ let lastLogTime = 0;
19276+ safe.toLogText = (type, ...args) => {
19277+ if ( args.length === 0 ) { return; }
19278+ const text = `[${document.location.hostname || document.location.href}]${args.join(' ')}`;
19279+ if ( text === lastLogText && type === lastLogType ) {
19280+ if ( (Date.now() - lastLogTime) < 5000 ) { return; }
19281+ }
19282+ lastLogType = type;
19283+ lastLogText = text;
19284+ lastLogTime = Date.now();
19285+ return text;
19286+ };
19287+ try {
19288+ const bc = new self.BroadcastChannel(scriptletGlobals.bcSecret);
19289+ let bcBuffer = [];
19290+ safe.sendToLogger = (type, ...args) => {
19291+ const text = safe.toLogText(type, ...args);
19292+ if ( text === undefined ) { return; }
19293+ if ( bcBuffer === undefined ) {
19294+ return bc.postMessage({ what: 'messageToLogger', type, text });
19295+ }
19296+ bcBuffer.push({ type, text });
19297+ };
19298+ bc.onmessage = ev => {
19299+ const msg = ev.data;
19300+ switch ( msg ) {
19301+ case 'iamready!':
19302+ if ( bcBuffer === undefined ) { break; }
19303+ bcBuffer.forEach(({ type, text }) =>
19304+ bc.postMessage({ what: 'messageToLogger', type, text })
19305+ );
19306+ bcBuffer = undefined;
19307+ break;
19308+ case 'setScriptletLogLevelToOne':
19309+ safe.logLevel = 1;
19310+ break;
19311+ case 'setScriptletLogLevelToTwo':
19312+ safe.logLevel = 2;
19313+ break;
19314+ }
19315+ };
19316+ bc.postMessage('areyouready?');
19317+ } catch {
19318+ safe.sendToLogger = (type, ...args) => {
19319+ const text = safe.toLogText(type, ...args);
19320+ if ( text === undefined ) { return; }
19321+ safe.log(`uBO ${text}`);
19322+ };
19323+ }
19324+ return safe;
19325+ }
19326+ function preventDialog(
19327+ selector = '',
19328+ ) {
19329+ const safe = safeSelf();
19330+ const logPrefix = safe.makeLogPrefix('prevent-dialog', selector);
19331+ const prevent = ( ) => {
19332+ debouncer = undefined;
19333+ const elems = document.querySelectorAll(`dialog${selector}`);
19334+ for ( const elem of elems ) {
19335+ if ( typeof elem.close !== 'function' ) { continue; }
19336+ if ( elem.open === false ) { continue; }
19337+ elem.close();
19338+ safe.uboLog(logPrefix, 'Closed');
19339+ }
19340+ };
19341+ let debouncer;
19342+ const observer = new MutationObserver(( ) => {
19343+ if ( debouncer !== undefined ) { return; }
19344+ debouncer = requestAnimationFrame(prevent);
19345+ });
19346+ observer.observe(document, {
19347+ attributes: true,
19348+ childList: true,
19349+ subtree: true,
19350+ });
19351+ };
19352+ preventDialog(...args);
19353+ },
19354+ };
19355+
19356+
1913219357scriptlets['prevent-fetch.js'] = {
1913319358aliases: ["no-fetch-if.js"],
1913419359
@@ -19547,40 +19772,41 @@ function preventFetchFn(
1954719772 responseProps.type = { value: responseType };
1954819773 }
1954919774 }
19775+ const fetchProps = (src, out) => {
19776+ if ( typeof src !== 'object' || src === null ) { return; }
19777+ const props = [
19778+ 'body', 'cache', 'credentials', 'duplex', 'headers',
19779+ 'integrity', 'keepalive', 'method', 'mode', 'priority',
19780+ 'redirect', 'referrer', 'referrerPolicy', 'signal',
19781+ ];
19782+ for ( const prop of props ) {
19783+ if ( src[prop] === undefined ) { continue; }
19784+ out[prop] = src[prop];
19785+ }
19786+ };
19787+ const fetchDetails = args => {
19788+ const out = {};
19789+ if ( args[0] instanceof self.Request ) {
19790+ out.url = `${args[0].url}`;
19791+ fetchProps(args[0], out);
19792+ } else {
19793+ out.url = `${args[0]}`;
19794+ }
19795+ fetchProps(args[1], out);
19796+ return out;
19797+ };
1955019798 proxyApplyFn('fetch', function fetch(context) {
1955119799 const { callArgs } = context;
19552- const details = (( ) => {
19553- const fetchProps = (src, out) => {
19554- if ( typeof src !== 'object' || src === null ) { return; }
19555- const props = [
19556- 'body', 'cache', 'credentials', 'duplex', 'headers',
19557- 'integrity', 'keepalive', 'method', 'mode', 'priority',
19558- 'redirect', 'referrer', 'referrerPolicy', 'signal',
19559- ];
19560- for ( const prop of props ) {
19561- if ( src[prop] === undefined ) { continue; }
19562- out[prop] = src[prop];
19563- }
19564- };
19565- const out = {};
19566- if ( callArgs[0] instanceof self.Request ) {
19567- out.url = `${callArgs[0].url}`;
19568- fetchProps(callArgs[0], out);
19569- } else {
19570- out.url = `${callArgs[0]}`;
19571- }
19572- fetchProps(callArgs[1], out);
19573- return out;
19574- })();
19800+ const details = fetchDetails(callArgs);
1957519801 if ( safe.logLevel > 1 || propsToMatch === '' && responseBody === '' ) {
19576- const out = Array.from(details).map(a => `${a[0]}:${a[1]}`);
19802+ const out = Array.from(Object.entries( details) ).map(a => `${a[0]}:${a[1]}`);
1957719803 safe.uboLog(logPrefix, `Called: ${out.join('\n')}`);
1957819804 }
1957919805 if ( propsToMatch === '' && responseBody === '' ) {
1958019806 return context.reflect();
1958119807 }
1958219808 const matched = matchObjectPropertiesFn(propNeedles, details);
19583- if ( matched === undefined ) {
19809+ if ( matched === undefined || matched.length === 0 ) {
1958419810 return context.reflect();
1958519811 }
1958619812 return Promise.resolve(generateContentFn(trusted, responseBody)).then(text => {
@@ -20030,40 +20256,41 @@ function preventFetchFn(
2003020256 responseProps.type = { value: responseType };
2003120257 }
2003220258 }
20259+ const fetchProps = (src, out) => {
20260+ if ( typeof src !== 'object' || src === null ) { return; }
20261+ const props = [
20262+ 'body', 'cache', 'credentials', 'duplex', 'headers',
20263+ 'integrity', 'keepalive', 'method', 'mode', 'priority',
20264+ 'redirect', 'referrer', 'referrerPolicy', 'signal',
20265+ ];
20266+ for ( const prop of props ) {
20267+ if ( src[prop] === undefined ) { continue; }
20268+ out[prop] = src[prop];
20269+ }
20270+ };
20271+ const fetchDetails = args => {
20272+ const out = {};
20273+ if ( args[0] instanceof self.Request ) {
20274+ out.url = `${args[0].url}`;
20275+ fetchProps(args[0], out);
20276+ } else {
20277+ out.url = `${args[0]}`;
20278+ }
20279+ fetchProps(args[1], out);
20280+ return out;
20281+ };
2003320282 proxyApplyFn('fetch', function fetch(context) {
2003420283 const { callArgs } = context;
20035- const details = (( ) => {
20036- const fetchProps = (src, out) => {
20037- if ( typeof src !== 'object' || src === null ) { return; }
20038- const props = [
20039- 'body', 'cache', 'credentials', 'duplex', 'headers',
20040- 'integrity', 'keepalive', 'method', 'mode', 'priority',
20041- 'redirect', 'referrer', 'referrerPolicy', 'signal',
20042- ];
20043- for ( const prop of props ) {
20044- if ( src[prop] === undefined ) { continue; }
20045- out[prop] = src[prop];
20046- }
20047- };
20048- const out = {};
20049- if ( callArgs[0] instanceof self.Request ) {
20050- out.url = `${callArgs[0].url}`;
20051- fetchProps(callArgs[0], out);
20052- } else {
20053- out.url = `${callArgs[0]}`;
20054- }
20055- fetchProps(callArgs[1], out);
20056- return out;
20057- })();
20284+ const details = fetchDetails(callArgs);
2005820285 if ( safe.logLevel > 1 || propsToMatch === '' && responseBody === '' ) {
20059- const out = Array.from(details).map(a => `${a[0]}:${a[1]}`);
20286+ const out = Array.from(Object.entries( details) ).map(a => `${a[0]}:${a[1]}`);
2006020287 safe.uboLog(logPrefix, `Called: ${out.join('\n')}`);
2006120288 }
2006220289 if ( propsToMatch === '' && responseBody === '' ) {
2006320290 return context.reflect();
2006420291 }
2006520292 const matched = matchObjectPropertiesFn(propNeedles, details);
20066- if ( matched === undefined ) {
20293+ if ( matched === undefined || matched.length === 0 ) {
2006720294 return context.reflect();
2006820295 }
2006920296 return Promise.resolve(generateContentFn(trusted, responseBody)).then(text => {
0 commit comments