mirror of https://github.com/gorhill/uBlock.git
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
This commit is contained in:
parent
75ac182fe1
commit
ba11a70013
|
@ -583,6 +583,65 @@
|
|||
})();
|
||||
|
||||
|
||||
/// no-fetch-if.js
|
||||
(function() {
|
||||
let arg1 = '{{1}}';
|
||||
if ( arg1 === '{{1}}' ) { arg1 = ''; }
|
||||
const needles = [];
|
||||
for ( const condition of arg1.split(/\s+/) ) {
|
||||
const pos = condition.indexOf(':');
|
||||
let key, value;
|
||||
if ( pos !== -1 ) {
|
||||
key = condition.slice(0, pos);
|
||||
value = condition.slice(pos + 1);
|
||||
} else {
|
||||
key = 'url';
|
||||
value = condition;
|
||||
}
|
||||
if ( value === '' ) {
|
||||
value = '^';
|
||||
} else if ( value.startsWith('/') && value.endsWith('/') ) {
|
||||
value = value.slice(1, -1);
|
||||
} else {
|
||||
value = value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
}
|
||||
needles.push({ key, re: new RegExp(value) });
|
||||
}
|
||||
self.fetch = new Proxy(self.fetch, {
|
||||
apply: function(target, thisArg, args) {
|
||||
let proceed = true;
|
||||
try {
|
||||
const url = args[0] instanceof self.Request
|
||||
? args[0].url
|
||||
: args[0];
|
||||
const props = new Map([ [ 'url', url ] ]);
|
||||
const init = args[1];
|
||||
if ( init instanceof Object ) {
|
||||
for ( const prop in init ) {
|
||||
if ( init.hasOwnProperty(prop) === false ) { continue; }
|
||||
props.set( prop, init[prop]);
|
||||
}
|
||||
}
|
||||
proceed = false;
|
||||
for ( const { key, re } of needles ) {
|
||||
if (
|
||||
props.has(key) === false ||
|
||||
re.test(props.get(key)) === false
|
||||
) {
|
||||
proceed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch(ex) {
|
||||
}
|
||||
return proceed
|
||||
? Reflect.apply(target, thisArg, args)
|
||||
: Promise.resolve(new Response());
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
|
||||
/// remove-attr.js
|
||||
/// alias ra.js
|
||||
(function() {
|
||||
|
@ -646,36 +705,6 @@
|
|||
})();
|
||||
|
||||
|
||||
/// requestAnimationFrame-if.js
|
||||
/// alias raf-if.js
|
||||
// Deprecated, use "no-requestAnimationFrame-if.js"
|
||||
(function() {
|
||||
let needle = '{{1}}';
|
||||
const not = needle.charAt(0) === '!';
|
||||
if ( not ) { needle = needle.slice(1); }
|
||||
if ( needle === '' || needle === '{{1}}' ) {
|
||||
needle = '.?';
|
||||
} else if ( needle.startsWith('/') && needle.endsWith('/') ) {
|
||||
needle = needle.slice(1,-1);
|
||||
} else {
|
||||
needle = needle.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
}
|
||||
const log = needle === '.?' && not === false ? console.log : undefined;
|
||||
needle = new RegExp(needle);
|
||||
window.requestAnimationFrame = new Proxy(window.requestAnimationFrame, {
|
||||
apply: function(target, thisArg, args) {
|
||||
const a = String(args[0]);
|
||||
if ( log !== undefined ) {
|
||||
log('uBO: requestAnimationFrame("%s")', a);
|
||||
} else if ( needle.test(a) === not ) {
|
||||
args[0] = function(){};
|
||||
}
|
||||
return target.apply(thisArg, args);
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
|
||||
/// no-requestAnimationFrame-if.js
|
||||
/// alias norafif.js
|
||||
(function() {
|
||||
|
@ -827,32 +856,6 @@
|
|||
})();
|
||||
|
||||
|
||||
/// setInterval-defuser.js
|
||||
/// alias sid.js
|
||||
(function() {
|
||||
let needle = '{{1}}';
|
||||
const delay = parseInt('{{2}}', 10);
|
||||
if ( needle === '' || needle === '{{1}}' ) {
|
||||
needle = '.?';
|
||||
} else if ( needle.startsWith('/') && needle.endsWith('/') ) {
|
||||
needle = needle.slice(1,-1);
|
||||
} else {
|
||||
needle = needle.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
}
|
||||
needle = new RegExp(needle);
|
||||
window.setInterval = new Proxy(window.setInterval, {
|
||||
apply: function(target, thisArg, args) {
|
||||
const a = args[0];
|
||||
const b = args[1];
|
||||
if ( (isNaN(delay) || b === delay) && needle.test(a.toString()) ) {
|
||||
args[0] = function(){};
|
||||
}
|
||||
return target.apply(thisArg, args);
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
|
||||
/// no-setInterval-if.js
|
||||
/// alias nosiif.js
|
||||
(function() {
|
||||
|
@ -902,34 +905,9 @@
|
|||
})();
|
||||
|
||||
|
||||
/// setTimeout-defuser.js
|
||||
/// alias std.js
|
||||
(function() {
|
||||
let needle = '{{1}}';
|
||||
const delay = parseInt('{{2}}', 10);
|
||||
if ( needle === '' || needle === '{{1}}' ) {
|
||||
needle = '.?';
|
||||
} else if ( needle.startsWith('/') && needle.endsWith('/') ) {
|
||||
needle = needle.slice(1,-1);
|
||||
} else {
|
||||
needle = needle.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
}
|
||||
needle = new RegExp(needle);
|
||||
window.setTimeout = new Proxy(window.setTimeout, {
|
||||
apply: function(target, thisArg, args) {
|
||||
const a = args[0];
|
||||
const b = args[1];
|
||||
if ( (isNaN(delay) || b === delay) && needle.test(a.toString()) ) {
|
||||
args[0] = function(){};
|
||||
}
|
||||
return target.apply(thisArg, args);
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
|
||||
/// no-setTimeout-if.js
|
||||
/// alias nostif.js
|
||||
/// alias setTimeout-defuser.js
|
||||
(function() {
|
||||
let needle = '{{1}}';
|
||||
const needleNot = needle.charAt(0) === '!';
|
||||
|
|
Loading…
Reference in New Issue