Skip to content

Commit ba11a70

Browse files
committed
Add new scriptlet: no-fetch-if
The new scriptlet allows to defuse calls to fetch() by returning a promise which always resolve to an empty response. There is only one argument, which is a space-separated list of conditions which must be ALL fulfilled in order for the defusing to take place. Each condition is a pair of property name and property value separated by a column. Valid property names are those documented as valid `init` options: https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch The URL of the fetch() is a special case and does not have to be associated with a property name. Example of usage: ...##+js(no-fetch-if, method:HEAD) Which means: defuse the call to fetch() if there is an explicit option which contains `HEAD`. Another example: ...##+js(no-fetch-if, adsbygoogle.js) Which means: defuse the call to fetch() if the URL contains `adsbygoogle.js`. Multiple conditions can be provided: ...##+js(no-fetch-if, adsbygoogle.js method:HEAD) If at least one condition does not match, the defusing will not take place. The string against which to match can be a literal regular expression: ...##+js(no-fetch-if, /adsbygoogle.js$/ method:/HEAD|POST/) Additonally, the following deprecated scriplets have been removed: - requestAnimationFrame-if.js - setInterval-defuser.js - setTimeout-logger.js
1 parent 75ac182 commit ba11a70

File tree

1 file changed

+60
-82
lines changed

1 file changed

+60
-82
lines changed

assets/resources/scriptlets.js

Lines changed: 60 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,65 @@
583583
})();
584584

585585

586+
/// no-fetch-if.js
587+
(function() {
588+
let arg1 = '{{1}}';
589+
if ( arg1 === '{{1}}' ) { arg1 = ''; }
590+
const needles = [];
591+
for ( const condition of arg1.split(/\s+/) ) {
592+
const pos = condition.indexOf(':');
593+
let key, value;
594+
if ( pos !== -1 ) {
595+
key = condition.slice(0, pos);
596+
value = condition.slice(pos + 1);
597+
} else {
598+
key = 'url';
599+
value = condition;
600+
}
601+
if ( value === '' ) {
602+
value = '^';
603+
} else if ( value.startsWith('/') && value.endsWith('/') ) {
604+
value = value.slice(1, -1);
605+
} else {
606+
value = value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
607+
}
608+
needles.push({ key, re: new RegExp(value) });
609+
}
610+
self.fetch = new Proxy(self.fetch, {
611+
apply: function(target, thisArg, args) {
612+
let proceed = true;
613+
try {
614+
const url = args[0] instanceof self.Request
615+
? args[0].url
616+
: args[0];
617+
const props = new Map([ [ 'url', url ] ]);
618+
const init = args[1];
619+
if ( init instanceof Object ) {
620+
for ( const prop in init ) {
621+
if ( init.hasOwnProperty(prop) === false ) { continue; }
622+
props.set( prop, init[prop]);
623+
}
624+
}
625+
proceed = false;
626+
for ( const { key, re } of needles ) {
627+
if (
628+
props.has(key) === false ||
629+
re.test(props.get(key)) === false
630+
) {
631+
proceed = true;
632+
break;
633+
}
634+
}
635+
} catch(ex) {
636+
}
637+
return proceed
638+
? Reflect.apply(target, thisArg, args)
639+
: Promise.resolve(new Response());
640+
}
641+
});
642+
})();
643+
644+
586645
/// remove-attr.js
587646
/// alias ra.js
588647
(function() {
@@ -646,36 +705,6 @@
646705
})();
647706

648707

649-
/// requestAnimationFrame-if.js
650-
/// alias raf-if.js
651-
// Deprecated, use "no-requestAnimationFrame-if.js"
652-
(function() {
653-
let needle = '{{1}}';
654-
const not = needle.charAt(0) === '!';
655-
if ( not ) { needle = needle.slice(1); }
656-
if ( needle === '' || needle === '{{1}}' ) {
657-
needle = '.?';
658-
} else if ( needle.startsWith('/') && needle.endsWith('/') ) {
659-
needle = needle.slice(1,-1);
660-
} else {
661-
needle = needle.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
662-
}
663-
const log = needle === '.?' && not === false ? console.log : undefined;
664-
needle = new RegExp(needle);
665-
window.requestAnimationFrame = new Proxy(window.requestAnimationFrame, {
666-
apply: function(target, thisArg, args) {
667-
const a = String(args[0]);
668-
if ( log !== undefined ) {
669-
log('uBO: requestAnimationFrame("%s")', a);
670-
} else if ( needle.test(a) === not ) {
671-
args[0] = function(){};
672-
}
673-
return target.apply(thisArg, args);
674-
}
675-
});
676-
})();
677-
678-
679708
/// no-requestAnimationFrame-if.js
680709
/// alias norafif.js
681710
(function() {
@@ -827,32 +856,6 @@
827856
})();
828857

829858

830-
/// setInterval-defuser.js
831-
/// alias sid.js
832-
(function() {
833-
let needle = '{{1}}';
834-
const delay = parseInt('{{2}}', 10);
835-
if ( needle === '' || needle === '{{1}}' ) {
836-
needle = '.?';
837-
} else if ( needle.startsWith('/') && needle.endsWith('/') ) {
838-
needle = needle.slice(1,-1);
839-
} else {
840-
needle = needle.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
841-
}
842-
needle = new RegExp(needle);
843-
window.setInterval = new Proxy(window.setInterval, {
844-
apply: function(target, thisArg, args) {
845-
const a = args[0];
846-
const b = args[1];
847-
if ( (isNaN(delay) || b === delay) && needle.test(a.toString()) ) {
848-
args[0] = function(){};
849-
}
850-
return target.apply(thisArg, args);
851-
}
852-
});
853-
})();
854-
855-
856859
/// no-setInterval-if.js
857860
/// alias nosiif.js
858861
(function() {
@@ -902,34 +905,9 @@
902905
})();
903906

904907

905-
/// setTimeout-defuser.js
906-
/// alias std.js
907-
(function() {
908-
let needle = '{{1}}';
909-
const delay = parseInt('{{2}}', 10);
910-
if ( needle === '' || needle === '{{1}}' ) {
911-
needle = '.?';
912-
} else if ( needle.startsWith('/') && needle.endsWith('/') ) {
913-
needle = needle.slice(1,-1);
914-
} else {
915-
needle = needle.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
916-
}
917-
needle = new RegExp(needle);
918-
window.setTimeout = new Proxy(window.setTimeout, {
919-
apply: function(target, thisArg, args) {
920-
const a = args[0];
921-
const b = args[1];
922-
if ( (isNaN(delay) || b === delay) && needle.test(a.toString()) ) {
923-
args[0] = function(){};
924-
}
925-
return target.apply(thisArg, args);
926-
}
927-
});
928-
})();
929-
930-
931908
/// no-setTimeout-if.js
932909
/// alias nostif.js
910+
/// alias setTimeout-defuser.js
933911
(function() {
934912
let needle = '{{1}}';
935913
const needleNot = needle.charAt(0) === '!';

0 commit comments

Comments
 (0)