mirror of
https://github.com/gorhill/uBlock.git
synced 2025-01-31 12:11:36 +01:00
Finalize converting resources.txt into immutable resources
With hindsight, I revised decisions made earlier during this development cycle: Un-redirectable scriptlets have been removed from /web_accessible_resources and instead put in the new /assets/resources/scriptlets.js, which contains all scriptlets used for web page injection purpose. uBO will no longer fetch a remote version of built-in resources. Advanced setting `userResourcesLocation` will still be honoured by uBO, and if set, will be fetched every time at least one asset is updated.
This commit is contained in:
parent
813b390dda
commit
6f5aa947fb
@ -19,10 +19,7 @@
|
|||||||
"ublock-resources": {
|
"ublock-resources": {
|
||||||
"content": "internal",
|
"content": "internal",
|
||||||
"updateAfter": 7,
|
"updateAfter": 7,
|
||||||
"contentURL": [
|
"contentURL": "assets/ublock/resources.txt"
|
||||||
"https://raw.githubusercontent.com/uBlockOrigin/uAssets/master/filters/resources.txt",
|
|
||||||
"assets/ublock/resources.txt"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"ublock-filters": {
|
"ublock-filters": {
|
||||||
"content": "filters",
|
"content": "filters",
|
||||||
|
975
assets/resources/scriptlets.js
Normal file
975
assets/resources/scriptlets.js
Normal file
@ -0,0 +1,975 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
|
||||||
|
uBlock Origin - a browser extension to block requests.
|
||||||
|
Copyright (C) 2019-present Raymond Hill
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||||
|
|
||||||
|
Home: https://github.com/gorhill/uBlock
|
||||||
|
|
||||||
|
The scriptlets below are meant to be injected only into a
|
||||||
|
web page context.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/// abort-current-inline-script.js
|
||||||
|
/// alias acis.js
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
const target = '{{1}}';
|
||||||
|
if ( target === '' || target === '{{1}}' ) { return; }
|
||||||
|
const needle = '{{2}}';
|
||||||
|
let reText = '.?';
|
||||||
|
if ( needle !== '' && needle !== '{{2}}' ) {
|
||||||
|
reText = /^\/.+\/$/.test(needle)
|
||||||
|
? needle.slice(1,-1)
|
||||||
|
: needle.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||||
|
}
|
||||||
|
const thisScript = document.currentScript;
|
||||||
|
const re = new RegExp(reText);
|
||||||
|
const chain = target.split('.');
|
||||||
|
let owner = window;
|
||||||
|
let prop;
|
||||||
|
for (;;) {
|
||||||
|
prop = chain.shift();
|
||||||
|
if ( chain.length === 0 ) { break; }
|
||||||
|
owner = owner[prop];
|
||||||
|
if ( owner instanceof Object === false ) { return; }
|
||||||
|
}
|
||||||
|
const desc = Object.getOwnPropertyDescriptor(owner, prop);
|
||||||
|
if ( desc && desc.get !== undefined ) { return; }
|
||||||
|
const magic = String.fromCharCode(Date.now() % 26 + 97) +
|
||||||
|
Math.floor(Math.random() * 982451653 + 982451653).toString(36);
|
||||||
|
let value = owner[prop];
|
||||||
|
const validate = function() {
|
||||||
|
const e = document.currentScript;
|
||||||
|
if (
|
||||||
|
e instanceof HTMLScriptElement &&
|
||||||
|
e.src === '' &&
|
||||||
|
e !== thisScript &&
|
||||||
|
re.test(e.textContent)
|
||||||
|
) {
|
||||||
|
throw new ReferenceError(magic);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Object.defineProperty(owner, prop, {
|
||||||
|
get: function() {
|
||||||
|
validate();
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
set: function(a) {
|
||||||
|
validate();
|
||||||
|
value = a;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const oe = window.onerror;
|
||||||
|
window.onerror = function(msg) {
|
||||||
|
if ( typeof msg === 'string' && msg.indexOf(magic) !== -1 ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ( oe instanceof Function ) {
|
||||||
|
return oe.apply(this, arguments);
|
||||||
|
}
|
||||||
|
}.bind();
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
/// abort-on-property-read.js
|
||||||
|
/// alias aopr.js
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
const magic = String.fromCharCode(Date.now() % 26 + 97) +
|
||||||
|
Math.floor(Math.random() * 982451653 + 982451653).toString(36);
|
||||||
|
const abort = function() {
|
||||||
|
throw new ReferenceError(magic);
|
||||||
|
};
|
||||||
|
const makeProxy = function(owner, chain) {
|
||||||
|
const pos = chain.indexOf('.');
|
||||||
|
if ( pos === -1 ) {
|
||||||
|
const desc = Object.getOwnPropertyDescriptor(owner, chain);
|
||||||
|
if ( !desc || desc.get !== abort ) {
|
||||||
|
Object.defineProperty(owner, chain, {
|
||||||
|
get: abort,
|
||||||
|
set: function(){}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const prop = chain.slice(0, pos);
|
||||||
|
let v = owner[prop];
|
||||||
|
chain = chain.slice(pos + 1);
|
||||||
|
if ( v ) {
|
||||||
|
makeProxy(v, chain);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const desc = Object.getOwnPropertyDescriptor(owner, prop);
|
||||||
|
if ( desc && desc.set !== undefined ) { return; }
|
||||||
|
Object.defineProperty(owner, prop, {
|
||||||
|
get: function() { return v; },
|
||||||
|
set: function(a) {
|
||||||
|
v = a;
|
||||||
|
if ( a instanceof Object ) {
|
||||||
|
makeProxy(a, chain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const owner = window;
|
||||||
|
let chain = '{{1}}';
|
||||||
|
makeProxy(owner, chain);
|
||||||
|
const oe = window.onerror;
|
||||||
|
window.onerror = function(msg, src, line, col, error) {
|
||||||
|
if ( typeof msg === 'string' && msg.indexOf(magic) !== -1 ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ( oe instanceof Function ) {
|
||||||
|
return oe(msg, src, line, col, error);
|
||||||
|
}
|
||||||
|
}.bind();
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
/// abort-on-property-write.js
|
||||||
|
/// alias aopw.js
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
const magic = String.fromCharCode(Date.now() % 26 + 97) +
|
||||||
|
Math.floor(Math.random() * 982451653 + 982451653).toString(36);
|
||||||
|
let prop = '{{1}}';
|
||||||
|
let owner = window;
|
||||||
|
for (;;) {
|
||||||
|
const pos = prop.indexOf('.');
|
||||||
|
if ( pos === -1 ) { break; }
|
||||||
|
owner = owner[prop.slice(0, pos)];
|
||||||
|
if ( owner instanceof Object === false ) { return; }
|
||||||
|
prop = prop.slice(pos + 1);
|
||||||
|
}
|
||||||
|
delete owner[prop];
|
||||||
|
Object.defineProperty(owner, prop, {
|
||||||
|
set: function() {
|
||||||
|
throw new ReferenceError(magic);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const oe = window.onerror;
|
||||||
|
window.onerror = function(msg, src, line, col, error) {
|
||||||
|
if ( typeof msg === 'string' && msg.indexOf(magic) !== -1 ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ( oe instanceof Function ) {
|
||||||
|
return oe(msg, src, line, col, error);
|
||||||
|
}
|
||||||
|
}.bind();
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
/// addEventListener-defuser.js
|
||||||
|
/// alias aeld.js
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
let needle1 = '{{1}}';
|
||||||
|
if ( needle1 === '' || needle1 === '{{1}}' ) {
|
||||||
|
needle1 = '.?';
|
||||||
|
} else if ( /^\/.+\/$/.test(needle1) ) {
|
||||||
|
needle1 = needle1.slice(1,-1);
|
||||||
|
} else {
|
||||||
|
needle1 = needle1.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||||
|
}
|
||||||
|
needle1 = new RegExp(needle1);
|
||||||
|
let needle2 = '{{2}}';
|
||||||
|
if ( needle2 === '' || needle2 === '{{2}}' ) {
|
||||||
|
needle2 = '.?';
|
||||||
|
} else if ( /^\/.+\/$/.test(needle2) ) {
|
||||||
|
needle2 = needle2.slice(1,-1);
|
||||||
|
} else {
|
||||||
|
needle2 = needle2.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||||
|
}
|
||||||
|
needle2 = new RegExp(needle2);
|
||||||
|
self.EventTarget.prototype.addEventListener = new Proxy(
|
||||||
|
self.EventTarget.prototype.addEventListener,
|
||||||
|
{
|
||||||
|
apply: function(target, thisArg, args) {
|
||||||
|
const type = args[0].toString();
|
||||||
|
const handler = String(args[1]);
|
||||||
|
if (
|
||||||
|
needle1.test(type) === false ||
|
||||||
|
needle2.test(handler) === false
|
||||||
|
) {
|
||||||
|
return target.apply(thisArg, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
/// addEventListener-logger.js
|
||||||
|
/// alias aell.js
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
const log = console.log.bind(console);
|
||||||
|
self.EventTarget.prototype.addEventListener = new Proxy(
|
||||||
|
self.EventTarget.prototype.addEventListener,
|
||||||
|
{
|
||||||
|
apply: function(target, thisArg, args) {
|
||||||
|
const type = args[0].toString();
|
||||||
|
const handler = String(args[1]);
|
||||||
|
log('addEventListener("%s", %s)', type, handler);
|
||||||
|
return target.apply(thisArg, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
/// nano-setInterval-booster.js
|
||||||
|
/// alias nano-sib.js
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
let needle = '{{1}}';
|
||||||
|
let delay = parseInt('{{2}}', 10);
|
||||||
|
let boost = parseFloat('{{3}}');
|
||||||
|
if ( needle === '' || needle === '{{1}}' ) {
|
||||||
|
needle = '.?';
|
||||||
|
} else if ( needle.charAt(0) === '/' && needle.slice(-1) === '/' ) {
|
||||||
|
needle = needle.slice(1, -1);
|
||||||
|
} else {
|
||||||
|
needle = needle.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||||
|
}
|
||||||
|
needle = new RegExp(needle);
|
||||||
|
if ( isNaN(delay) || !isFinite(delay) ) {
|
||||||
|
delay = 1000;
|
||||||
|
}
|
||||||
|
if ( isNaN(boost) || !isFinite(boost) ) {
|
||||||
|
boost = 0.05;
|
||||||
|
}
|
||||||
|
if ( boost < 0.02 ) {
|
||||||
|
boost = 0.02;
|
||||||
|
}
|
||||||
|
if ( boost > 50 ) {
|
||||||
|
boost = 50;
|
||||||
|
}
|
||||||
|
window.setInterval = new Proxy(window.setInterval, {
|
||||||
|
apply: function(target, thisArg, args) {
|
||||||
|
const a = args[0];
|
||||||
|
const b = args[1];
|
||||||
|
if ( b === delay && needle.test(a.toString()) ) {
|
||||||
|
args[1] = b * boost;
|
||||||
|
}
|
||||||
|
return target.apply(thisArg, args);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
/// nano-setTimeout-booster.js
|
||||||
|
/// alias nano-stb.js
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
let needle = '{{1}}';
|
||||||
|
let delay = parseInt('{{2}}', 10);
|
||||||
|
let boost = parseFloat('{{3}}');
|
||||||
|
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);
|
||||||
|
if ( isNaN(delay) || !isFinite(delay) ) {
|
||||||
|
delay = 1000;
|
||||||
|
}
|
||||||
|
if ( isNaN(boost) || !isFinite(boost) ) {
|
||||||
|
boost = 0.05;
|
||||||
|
}
|
||||||
|
if ( boost < 0.02 ) {
|
||||||
|
boost = 0.02;
|
||||||
|
}
|
||||||
|
if ( boost > 50 ) {
|
||||||
|
boost = 50;
|
||||||
|
}
|
||||||
|
window.setTimeout = new Proxy(window.setTimeout, {
|
||||||
|
apply: function(target, thisArg, args) {
|
||||||
|
const a = args[0];
|
||||||
|
const b = args[1];
|
||||||
|
if ( b === delay && needle.test(a.toString()) ) {
|
||||||
|
args[1] = b * boost;
|
||||||
|
}
|
||||||
|
return target.apply(thisArg, args);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
/// noeval-if.js
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
let needle = '{{1}}';
|
||||||
|
if ( needle === '' || needle === '{{1}}' ) {
|
||||||
|
needle = '.?';
|
||||||
|
} else if ( needle.slice(0,1) === '/' && needle.slice(-1) === '/' ) {
|
||||||
|
needle = needle.slice(1,-1);
|
||||||
|
} else {
|
||||||
|
needle = needle.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||||
|
}
|
||||||
|
needle = new RegExp(needle);
|
||||||
|
window.eval = new Proxy(window.eval, { // jshint ignore: line
|
||||||
|
apply: function(target, thisArg, args) {
|
||||||
|
const a = args[0];
|
||||||
|
if ( needle.test(a.toString()) === false ) {
|
||||||
|
return target.apply(thisArg, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
/// remove-attr.js
|
||||||
|
/// alias ra.js
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
const token = '{{1}}';
|
||||||
|
if ( token === '' || token === '{{1}}' ) { return; }
|
||||||
|
const tokens = token.split(/\s*\|\s*/);
|
||||||
|
let selector = '{{2}}';
|
||||||
|
if ( selector === '' || selector === '{{2}}' ) {
|
||||||
|
selector = `[${tokens.join('],[')}]`;
|
||||||
|
}
|
||||||
|
const rmattr = function(ev) {
|
||||||
|
if ( ev ) {
|
||||||
|
window.removeEventListener(ev.type, rmattr, true);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const nodes = document.querySelectorAll(selector);
|
||||||
|
for ( const node of nodes ) {
|
||||||
|
for ( const attr of tokens ) {
|
||||||
|
node.removeAttribute(attr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(ex) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if ( document.readyState === 'loading' ) {
|
||||||
|
window.addEventListener('DOMContentLoaded', rmattr, true);
|
||||||
|
} else {
|
||||||
|
rmattr();
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
/// set-constant.js
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
const thisScript = document.currentScript;
|
||||||
|
let cValue = '{{2}}';
|
||||||
|
if ( cValue === 'undefined' ) {
|
||||||
|
cValue = undefined;
|
||||||
|
} else if ( cValue === 'false' ) {
|
||||||
|
cValue = false;
|
||||||
|
} else if ( cValue === 'true' ) {
|
||||||
|
cValue = true;
|
||||||
|
} else if ( cValue === 'null' ) {
|
||||||
|
cValue = null;
|
||||||
|
} else if ( cValue === 'noopFunc' ) {
|
||||||
|
cValue = function(){};
|
||||||
|
} else if ( cValue === 'trueFunc' ) {
|
||||||
|
cValue = function(){ return true; };
|
||||||
|
} else if ( cValue === 'falseFunc' ) {
|
||||||
|
cValue = function(){ return false; };
|
||||||
|
} else if ( /^\d+$/.test(cValue) ) {
|
||||||
|
cValue = parseFloat(cValue);
|
||||||
|
if ( isNaN(cValue) ) { return; }
|
||||||
|
if ( Math.abs(cValue) > 0x7FFF ) { return; }
|
||||||
|
} else if ( cValue === "''" ) {
|
||||||
|
cValue = '';
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let aborted = false;
|
||||||
|
const mustAbort = function(v) {
|
||||||
|
if ( aborted ) { return true; }
|
||||||
|
aborted = v !== undefined && cValue !== undefined && typeof v !== typeof cValue;
|
||||||
|
return aborted;
|
||||||
|
};
|
||||||
|
const makeProxy = function(owner, chain) {
|
||||||
|
const pos = chain.indexOf('.');
|
||||||
|
if ( pos === -1 ) {
|
||||||
|
const original = owner[chain];
|
||||||
|
if ( mustAbort(original) ) { return; }
|
||||||
|
const desc = Object.getOwnPropertyDescriptor(owner, chain);
|
||||||
|
if ( desc === undefined || desc.get === undefined ) {
|
||||||
|
Object.defineProperty(owner, chain, {
|
||||||
|
get: function() {
|
||||||
|
return document.currentScript === thisScript
|
||||||
|
? original
|
||||||
|
: cValue;
|
||||||
|
},
|
||||||
|
set: function(a) {
|
||||||
|
if ( mustAbort(a) ) {
|
||||||
|
cValue = a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const prop = chain.slice(0, pos);
|
||||||
|
let v = owner[prop];
|
||||||
|
chain = chain.slice(pos + 1);
|
||||||
|
if ( v !== undefined ) {
|
||||||
|
makeProxy(v, chain);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const desc = Object.getOwnPropertyDescriptor(owner, prop);
|
||||||
|
if ( desc && desc.set !== undefined ) { return; }
|
||||||
|
Object.defineProperty(owner, prop, {
|
||||||
|
get: function() {
|
||||||
|
return v;
|
||||||
|
},
|
||||||
|
set: function(a) {
|
||||||
|
v = a;
|
||||||
|
if ( a instanceof Object ) {
|
||||||
|
makeProxy(a, chain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
makeProxy(window, '{{1}}');
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
/// setInterval-defuser.js
|
||||||
|
/// alias sid.js
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
/// setInterval-logger.js
|
||||||
|
/// alias sil.js
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
const log = console.log.bind(console);
|
||||||
|
window.setInterval = new Proxy(window.setInterval, {
|
||||||
|
apply: function(target, thisArg, args) {
|
||||||
|
const a = args[0];
|
||||||
|
const b = args[1];
|
||||||
|
log('uBO: setInterval("%s", %s)', a.toString(), b);
|
||||||
|
return target.apply(thisArg, args);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
/// setTimeout-defuser.js
|
||||||
|
/// alias std.js
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
/// setTimeout-logger.js
|
||||||
|
/// alias stl.js
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
const log = console.log.bind(console);
|
||||||
|
window.setTimeout = new Proxy(window.setTimeout, {
|
||||||
|
apply: function(target, thisArg, args) {
|
||||||
|
const a = args[0];
|
||||||
|
const b = args[1];
|
||||||
|
log('uBO: setTimeout("%s", %s)', a.toString(), b);
|
||||||
|
return target.apply(thisArg, args);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
/// webrtc-if.js
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
let good = '{{1}}';
|
||||||
|
if ( good.startsWith('/') && good.endsWith('/') ) {
|
||||||
|
good = good.slice(1, -1);
|
||||||
|
} else {
|
||||||
|
good = good.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||||
|
}
|
||||||
|
let reGood;
|
||||||
|
try {
|
||||||
|
reGood = new RegExp(good);
|
||||||
|
} catch(ex) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const rtcName = window.RTCPeerConnection
|
||||||
|
? 'RTCPeerConnection'
|
||||||
|
: (window.webkitRTCPeerConnection ? 'webkitRTCPeerConnection' : '');
|
||||||
|
if ( rtcName === '' ) { return; }
|
||||||
|
const log = console.log.bind(console);
|
||||||
|
const neuteredPeerConnections = new WeakSet();
|
||||||
|
const isGoodConfig = function(instance, config) {
|
||||||
|
if ( neuteredPeerConnections.has(instance) ) { return false; }
|
||||||
|
if ( config instanceof Object === false ) { return true; }
|
||||||
|
if ( Array.isArray(config.iceServers) === false ) { return true; }
|
||||||
|
for ( const server of config.iceServers ) {
|
||||||
|
const urls = typeof server.urls === 'string'
|
||||||
|
? [ server.urls ]
|
||||||
|
: server.urls;
|
||||||
|
if ( Array.isArray(urls) ) {
|
||||||
|
for ( const url of urls ) {
|
||||||
|
if ( reGood.test(url) ) { return true; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( typeof server.username === 'string' ) {
|
||||||
|
if ( reGood.test(server.username) ) { return true; }
|
||||||
|
}
|
||||||
|
if ( typeof server.credential === 'string' ) {
|
||||||
|
if ( reGood.test(server.credential) ) { return true; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
neuteredPeerConnections.add(instance);
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
const peerConnectionCtor = window[rtcName];
|
||||||
|
const peerConnectionProto = peerConnectionCtor.prototype;
|
||||||
|
peerConnectionProto.createDataChannel =
|
||||||
|
new Proxy(peerConnectionProto.createDataChannel, {
|
||||||
|
apply: function(target, thisArg, args) {
|
||||||
|
if ( isGoodConfig(target, args[1]) === false ) {
|
||||||
|
log(args[1]);
|
||||||
|
return target.apply(thisArg, args.slice(0, 1));
|
||||||
|
}
|
||||||
|
return target.apply(thisArg, args);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
window[rtcName] =
|
||||||
|
new Proxy(peerConnectionCtor, {
|
||||||
|
construct: function(target, args) {
|
||||||
|
if ( isGoodConfig(target, args[0]) === false ) {
|
||||||
|
log(args[0]);
|
||||||
|
return new target();
|
||||||
|
}
|
||||||
|
return new target(...args);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
// https://github.com/gorhill/uBlock/issues/1228
|
||||||
|
/// window.name-defuser
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
if ( window === window.top ) {
|
||||||
|
window.name = '';
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
// Experimental: Generic nuisance overlay buster.
|
||||||
|
// if this works well and proves to be useful, this may end up
|
||||||
|
// as a stock tool in uBO's popup panel.
|
||||||
|
/// overlay-buster.js
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
if ( window !== window.top ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var tstart;
|
||||||
|
var ttl = 30000;
|
||||||
|
var delay = 0;
|
||||||
|
var delayStep = 50;
|
||||||
|
var buster = function() {
|
||||||
|
var docEl = document.documentElement,
|
||||||
|
bodyEl = document.body,
|
||||||
|
vw = Math.min(docEl.clientWidth, window.innerWidth),
|
||||||
|
vh = Math.min(docEl.clientHeight, window.innerHeight),
|
||||||
|
tol = Math.min(vw, vh) * 0.05,
|
||||||
|
el = document.elementFromPoint(vw/2, vh/2),
|
||||||
|
style, rect;
|
||||||
|
for (;;) {
|
||||||
|
if ( el === null || el.parentNode === null || el === bodyEl ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
style = window.getComputedStyle(el);
|
||||||
|
if ( parseInt(style.zIndex, 10) >= 1000 || style.position === 'fixed' ) {
|
||||||
|
rect = el.getBoundingClientRect();
|
||||||
|
if ( rect.left <= tol && rect.top <= tol && (vw - rect.right) <= tol && (vh - rect.bottom) < tol ) {
|
||||||
|
el.parentNode.removeChild(el);
|
||||||
|
tstart = Date.now();
|
||||||
|
el = document.elementFromPoint(vw/2, vh/2);
|
||||||
|
bodyEl.style.setProperty('overflow', 'auto', 'important');
|
||||||
|
docEl.style.setProperty('overflow', 'auto', 'important');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
el = el.parentNode;
|
||||||
|
}
|
||||||
|
if ( (Date.now() - tstart) < ttl ) {
|
||||||
|
delay = Math.min(delay + delayStep, 1000);
|
||||||
|
setTimeout(buster, delay);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var domReady = function(ev) {
|
||||||
|
if ( ev ) {
|
||||||
|
document.removeEventListener(ev.type, domReady);
|
||||||
|
}
|
||||||
|
tstart = Date.now();
|
||||||
|
setTimeout(buster, delay);
|
||||||
|
};
|
||||||
|
if ( document.readyState === 'loading' ) {
|
||||||
|
document.addEventListener('DOMContentLoaded', domReady);
|
||||||
|
} else {
|
||||||
|
domReady();
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
// https://github.com/uBlockOrigin/uAssets/issues/8
|
||||||
|
/// alert-buster.js
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
window.alert = function(a) {
|
||||||
|
console.info(a);
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
// https://github.com/uBlockOrigin/uAssets/issues/58
|
||||||
|
/// gpt-defuser.js application/javascript
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
const noopfn = function() {
|
||||||
|
};
|
||||||
|
let props = '_resetGPT resetGPT resetAndLoadGPTRecovery _resetAndLoadGPTRecovery setupGPT setupGPTuo';
|
||||||
|
props = props.split(/\s+/);
|
||||||
|
while ( props.length ) {
|
||||||
|
var prop = props.pop();
|
||||||
|
if ( typeof window[prop] === 'function' ) {
|
||||||
|
window[prop] = noopfn;
|
||||||
|
} else {
|
||||||
|
Object.defineProperty(window, prop, {
|
||||||
|
get: function() { return noopfn; },
|
||||||
|
set: noopfn
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
// Prevent web pages from using RTCPeerConnection(), and report attempts in console.
|
||||||
|
/// nowebrtc.js
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
var rtcName = window.RTCPeerConnection ? 'RTCPeerConnection' : (
|
||||||
|
window.webkitRTCPeerConnection ? 'webkitRTCPeerConnection' : ''
|
||||||
|
);
|
||||||
|
if ( rtcName === '' ) { return; }
|
||||||
|
var log = console.log.bind(console);
|
||||||
|
var pc = function(cfg) {
|
||||||
|
log('Document tried to create an RTCPeerConnection: %o', cfg);
|
||||||
|
};
|
||||||
|
const noop = function() {
|
||||||
|
};
|
||||||
|
pc.prototype = {
|
||||||
|
close: noop,
|
||||||
|
createDataChannel: noop,
|
||||||
|
createOffer: noop,
|
||||||
|
setRemoteDescription: noop,
|
||||||
|
toString: function() {
|
||||||
|
return '[object RTCPeerConnection]';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var z = window[rtcName];
|
||||||
|
window[rtcName] = pc.bind(window);
|
||||||
|
if ( z.prototype ) {
|
||||||
|
z.prototype.createDataChannel = function() {
|
||||||
|
return {
|
||||||
|
close: function() {},
|
||||||
|
send: function() {}
|
||||||
|
};
|
||||||
|
}.bind(null);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
// https://github.com/uBlockOrigin/uAssets/issues/88
|
||||||
|
/// golem.de.js
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
const rael = window.addEventListener;
|
||||||
|
window.addEventListener = function(a, b) {
|
||||||
|
rael(...arguments);
|
||||||
|
let haystack;
|
||||||
|
try {
|
||||||
|
haystack = b.toString();
|
||||||
|
} catch(ex) {
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
typeof haystack === 'string' &&
|
||||||
|
/^\s*function\s*\(\)\s*\{\s*window\.clearTimeout\(r\)\s*\}\s*$/.test(haystack)
|
||||||
|
) {
|
||||||
|
b();
|
||||||
|
}
|
||||||
|
}.bind(window);
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
// https://forums.lanik.us/viewtopic.php?f=64&t=32278
|
||||||
|
// https://www.reddit.com/r/chrome/comments/58eix6/ublock_origin_not_working_on_certain_sites/
|
||||||
|
/// upmanager-defuser.js
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
var onerror = window.onerror;
|
||||||
|
window.onerror = function(msg, source, lineno, colno, error) {
|
||||||
|
if ( typeof msg === 'string' && msg.indexOf('upManager') !== -1 ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ( onerror instanceof Function ) {
|
||||||
|
onerror.call(window, msg, source, lineno, colno, error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Object.defineProperty(window, 'upManager', { value: function() {} });
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
// https://github.com/uBlockOrigin/uAssets/issues/110
|
||||||
|
/// smartadserver.com.js
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
Object.defineProperties(window, {
|
||||||
|
SmartAdObject: { value: function(){} },
|
||||||
|
SmartAdServerAjax: { value: function(){} },
|
||||||
|
smartAd: { value: { LoadAds: function() {}, Register: function() {} } }
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
// https://github.com/reek/anti-adblock-killer/issues/3774#issuecomment-348536138
|
||||||
|
// https://github.com/uBlockOrigin/uAssets/issues/883
|
||||||
|
/// adfly-defuser.js
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
// Based on AdsBypasser
|
||||||
|
// License:
|
||||||
|
// https://github.com/adsbypasser/adsbypasser/blob/master/LICENSE
|
||||||
|
var isDigit = /^\d$/;
|
||||||
|
var handler = function(encodedURL) {
|
||||||
|
var var1 = "", var2 = "", i;
|
||||||
|
for (i = 0; i < encodedURL.length; i++) {
|
||||||
|
if (i % 2 === 0) {
|
||||||
|
var1 = var1 + encodedURL.charAt(i);
|
||||||
|
} else {
|
||||||
|
var2 = encodedURL.charAt(i) + var2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var data = (var1 + var2).split("");
|
||||||
|
for (i = 0; i < data.length; i++) {
|
||||||
|
if (isDigit.test(data[i])) {
|
||||||
|
for (var ii = i + 1; ii < data.length; ii++) {
|
||||||
|
if (isDigit.test(data[ii])) {
|
||||||
|
var temp = parseInt(data[i],10) ^ parseInt(data[ii],10);
|
||||||
|
if (temp < 10) {
|
||||||
|
data[i] = temp.toString();
|
||||||
|
}
|
||||||
|
i = ii;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data = data.join("");
|
||||||
|
var decodedURL = window.atob(data).slice(16, -16);
|
||||||
|
window.stop();
|
||||||
|
window.onbeforeunload = null;
|
||||||
|
window.location.href = decodedURL;
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
var val;
|
||||||
|
var flag = true;
|
||||||
|
window.Object.defineProperty(window, "ysmm", {
|
||||||
|
configurable: false,
|
||||||
|
set: function(value) {
|
||||||
|
if (flag) {
|
||||||
|
flag = false;
|
||||||
|
try {
|
||||||
|
if (typeof value === "string") {
|
||||||
|
handler(value);
|
||||||
|
}
|
||||||
|
} catch (err) { }
|
||||||
|
}
|
||||||
|
val = value;
|
||||||
|
},
|
||||||
|
get: function() {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
window.console.error("Failed to set up Adfly bypasser!");
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
// https://github.com/uBlockOrigin/uAssets/issues/913
|
||||||
|
/// disable-newtab-links.js
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
document.addEventListener('click', function(ev) {
|
||||||
|
var target = ev.target;
|
||||||
|
while ( target !== null ) {
|
||||||
|
if ( target.localName === 'a' && target.hasAttribute('target') ) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
ev.preventDefault();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
target = target.parentNode;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
/// damoh-defuser.js
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
var handled = new WeakSet();
|
||||||
|
var asyncTimer;
|
||||||
|
var cleanVideo = function() {
|
||||||
|
asyncTimer = undefined;
|
||||||
|
var v = document.querySelector('video');
|
||||||
|
if ( v === null ) { return; }
|
||||||
|
if ( handled.has(v) ) { return; }
|
||||||
|
handled.add(v);
|
||||||
|
v.pause();
|
||||||
|
v.controls = true;
|
||||||
|
var el = v.querySelector('meta[itemprop="contentURL"][content]');
|
||||||
|
if ( el === null ) { return; }
|
||||||
|
v.src = el.getAttribute('content');
|
||||||
|
el = v.querySelector('meta[itemprop="thumbnailUrl"][content]');
|
||||||
|
if ( el !== null ) { v.poster = el.getAttribute('content'); }
|
||||||
|
};
|
||||||
|
var cleanVideoAsync = function() {
|
||||||
|
if ( asyncTimer !== undefined ) { return; }
|
||||||
|
asyncTimer = window.requestAnimationFrame(cleanVideo);
|
||||||
|
};
|
||||||
|
var observer = new MutationObserver(cleanVideoAsync);
|
||||||
|
observer.observe(document.documentElement, { childList: true, subtree: true });
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
// https://github.com/uBlockOrigin/uAssets/pull/3517
|
||||||
|
/// twitch-videoad.js
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
if ( /(^|\.)twitch\.tv$/.test(document.location.hostname) === false ) { return; }
|
||||||
|
var realFetch = window.fetch;
|
||||||
|
window.fetch = function(input) {
|
||||||
|
if ( arguments.length >= 2 && typeof input === 'string' && input.includes('/access_token') ) {
|
||||||
|
var url = new URL(arguments[0]);
|
||||||
|
url.searchParams.set('platform', '_');
|
||||||
|
arguments[0] = url.href;
|
||||||
|
}
|
||||||
|
return realFetch.apply(this, arguments);
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
// https://github.com/uBlockOrigin/uAssets/issues/2912
|
||||||
|
/// fingerprint2.js
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
let fp2 = function(){};
|
||||||
|
fp2.prototype = {
|
||||||
|
get: function(cb) {
|
||||||
|
setTimeout(function() { cb('', []); }, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
window.Fingerprint2 = fp2;
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
// https://github.com/NanoAdblocker/NanoFilters/issues/149
|
||||||
|
/// cookie-remover.js
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
let needle = '{{1}}',
|
||||||
|
reName = /./;
|
||||||
|
if ( /^\/.+\/$/.test(needle) ) {
|
||||||
|
reName = new RegExp(needle.slice(1,-1));
|
||||||
|
} else if ( needle !== '' && needle !== '{{1}}' ) {
|
||||||
|
reName = new RegExp(needle.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
|
||||||
|
}
|
||||||
|
let removeCookie = function() {
|
||||||
|
document.cookie.split(';').forEach(cookieStr => {
|
||||||
|
let pos = cookieStr.indexOf('=');
|
||||||
|
if ( pos === -1 ) { return; }
|
||||||
|
let cookieName = cookieStr.slice(0, pos).trim();
|
||||||
|
if ( !reName.test(cookieName) ) { return; }
|
||||||
|
let part1 = cookieName + '=';
|
||||||
|
let part2a = '; domain=' + document.location.hostname;
|
||||||
|
let part2b = '; domain=.' + document.location.hostname;
|
||||||
|
let domain = document.domain;
|
||||||
|
let part2c = domain && domain !== document.location.hostname ? '; domain=.' + domain : undefined;
|
||||||
|
let part3 = '; path=/';
|
||||||
|
let part4 = '; Max-Age=-1000; expires=Thu, 01 Jan 1970 00:00:00 GMT';
|
||||||
|
document.cookie = part1 + part4;
|
||||||
|
document.cookie = part1 + part2a + part4;
|
||||||
|
document.cookie = part1 + part2b + part4;
|
||||||
|
document.cookie = part1 + part3 + part4;
|
||||||
|
document.cookie = part1 + part2a + part3 + part4;
|
||||||
|
document.cookie = part1 + part2b + part3 + part4;
|
||||||
|
if ( part2c !== undefined ) {
|
||||||
|
document.cookie = part1 + part2c + part3 + part4;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
removeCookie();
|
||||||
|
window.addEventListener('beforeunload', removeCookie);
|
||||||
|
})();
|
@ -1094,11 +1094,6 @@ const onMessage = function(request, sender, callback) {
|
|||||||
case 'purgeCache':
|
case 'purgeCache':
|
||||||
µb.assets.purge(request.assetKey);
|
µb.assets.purge(request.assetKey);
|
||||||
µb.assets.remove('compiled/' + request.assetKey);
|
µb.assets.remove('compiled/' + request.assetKey);
|
||||||
// https://github.com/gorhill/uBlock/pull/2314#issuecomment-278716960
|
|
||||||
if ( request.assetKey === 'ublock-filters' ) {
|
|
||||||
µb.assets.purge('ublock-resources');
|
|
||||||
µb.redirectEngine.invalidateResourcesSelfie();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'readHiddenSettings':
|
case 'readHiddenSettings':
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
const immutableResources = new Map([
|
const redirectableResources = new Map([
|
||||||
[ '1x1.gif', {
|
[ '1x1.gif', {
|
||||||
alias: '1x1-transparent.gif',
|
alias: '1x1-transparent.gif',
|
||||||
inject: false
|
inject: false
|
||||||
@ -45,26 +45,6 @@ const immutableResources = new Map([
|
|||||||
alias: '32x32-transparent.png',
|
alias: '32x32-transparent.png',
|
||||||
inject: false
|
inject: false
|
||||||
} ],
|
} ],
|
||||||
[ 'abort-current-inline-script.js', {
|
|
||||||
alias: 'acis.js',
|
|
||||||
redirect: false
|
|
||||||
} ],
|
|
||||||
[ 'abort-on-property-read.js', {
|
|
||||||
alias: 'aopr.js',
|
|
||||||
redirect: false
|
|
||||||
} ],
|
|
||||||
[ 'abort-on-property-write.js', {
|
|
||||||
alias: 'aopw.js',
|
|
||||||
redirect: false
|
|
||||||
} ],
|
|
||||||
[ 'addEventListener-defuser.js', {
|
|
||||||
alias: 'aeld.js',
|
|
||||||
redirect: false
|
|
||||||
} ],
|
|
||||||
[ 'addEventListener-logger.js', {
|
|
||||||
alias: 'aell.js',
|
|
||||||
redirect: false
|
|
||||||
} ],
|
|
||||||
[ 'addthis_widget.js', {
|
[ 'addthis_widget.js', {
|
||||||
alias: 'addthis.com/addthis_widget.js',
|
alias: 'addthis.com/addthis_widget.js',
|
||||||
inject: false
|
inject: false
|
||||||
@ -138,19 +118,8 @@ const immutableResources = new Map([
|
|||||||
alias: 'd3pkae9owd2lcf.cloudfront.net/mb105.js',
|
alias: 'd3pkae9owd2lcf.cloudfront.net/mb105.js',
|
||||||
inject: false
|
inject: false
|
||||||
} ],
|
} ],
|
||||||
[ 'nano-setInterval-booster.js', {
|
|
||||||
alias: 'nano-sib.js',
|
|
||||||
redirect: false
|
|
||||||
} ],
|
|
||||||
[ 'nano-setTimeout-booster.js', {
|
|
||||||
alias: 'nano-stb.js',
|
|
||||||
redirect: false
|
|
||||||
} ],
|
|
||||||
[ 'noeval.js', {
|
[ 'noeval.js', {
|
||||||
} ],
|
} ],
|
||||||
[ 'noeval-if.js', {
|
|
||||||
redirect: false
|
|
||||||
} ],
|
|
||||||
[ 'noeval-silent.js', {
|
[ 'noeval-silent.js', {
|
||||||
alias: 'silent-noeval.js',
|
alias: 'silent-noeval.js',
|
||||||
} ],
|
} ],
|
||||||
@ -182,36 +151,10 @@ const immutableResources = new Map([
|
|||||||
[ 'popads-dummy.js', {
|
[ 'popads-dummy.js', {
|
||||||
alias: 'popads-dummy.js',
|
alias: 'popads-dummy.js',
|
||||||
} ],
|
} ],
|
||||||
[ 'remove-attr.js', {
|
|
||||||
alias: 'ra.js',
|
|
||||||
redirect: false
|
|
||||||
} ],
|
|
||||||
[ 'scorecardresearch_beacon.js', {
|
[ 'scorecardresearch_beacon.js', {
|
||||||
alias: 'scorecardresearch.com/beacon.js',
|
alias: 'scorecardresearch.com/beacon.js',
|
||||||
inject: false
|
inject: false
|
||||||
} ],
|
} ],
|
||||||
[ 'set-constant.js', {
|
|
||||||
redirect: false
|
|
||||||
} ],
|
|
||||||
[ 'setInterval-defuser.js', {
|
|
||||||
alias: 'sid.js',
|
|
||||||
redirect: false
|
|
||||||
} ],
|
|
||||||
[ 'setInterval-logger.js', {
|
|
||||||
alias: 'sil.js',
|
|
||||||
redirect: false
|
|
||||||
} ],
|
|
||||||
[ 'setTimeout-defuser.js', {
|
|
||||||
alias: 'std.js',
|
|
||||||
redirect: false
|
|
||||||
} ],
|
|
||||||
[ 'setTimeout-logger.js', {
|
|
||||||
alias: 'stl.js',
|
|
||||||
redirect: false
|
|
||||||
} ],
|
|
||||||
[ 'webrtc-if.js', {
|
|
||||||
redirect: false
|
|
||||||
} ],
|
|
||||||
[ 'window.open-defuser.js', {
|
[ 'window.open-defuser.js', {
|
||||||
} ],
|
} ],
|
||||||
]);
|
]);
|
||||||
@ -226,6 +169,13 @@ const mimeMap = {
|
|||||||
txt: 'text/plain',
|
txt: 'text/plain',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const mimeFromName = function(name) {
|
||||||
|
const match = /\.([^.]+)$/.exec(name);
|
||||||
|
if ( match !== null ) {
|
||||||
|
return mimeMap[match[1]];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// https://github.com/gorhill/uBlock/issues/3639
|
// https://github.com/gorhill/uBlock/issues/3639
|
||||||
// https://github.com/EFForg/https-everywhere/issues/14961
|
// https://github.com/EFForg/https-everywhere/issues/14961
|
||||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=111700
|
// https://bugs.chromium.org/p/chromium/issues/detail?id=111700
|
||||||
@ -278,8 +228,8 @@ RedirectEntry.prototype.toURL = function(fctxt) {
|
|||||||
|
|
||||||
RedirectEntry.prototype.toContent = function() {
|
RedirectEntry.prototype.toContent = function() {
|
||||||
if ( this.data.startsWith('data:') ) {
|
if ( this.data.startsWith('data:') ) {
|
||||||
var pos = this.data.indexOf(',');
|
const pos = this.data.indexOf(',');
|
||||||
var base64 = this.data.endsWith(';base64', pos);
|
const base64 = this.data.endsWith(';base64', pos);
|
||||||
this.data = this.data.slice(pos + 1);
|
this.data = this.data.slice(pos + 1);
|
||||||
if ( base64 ) {
|
if ( base64 ) {
|
||||||
this.data = atob(this.data);
|
this.data = atob(this.data);
|
||||||
@ -290,19 +240,17 @@ RedirectEntry.prototype.toContent = function() {
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
RedirectEntry.fromFields = function(mime, lines) {
|
RedirectEntry.fromContent = function(mime, content) {
|
||||||
const r = new RedirectEntry();
|
const r = new RedirectEntry();
|
||||||
r.mime = mime;
|
r.mime = mime;
|
||||||
r.data = µBlock.orphanizeString(
|
r.data = content;
|
||||||
lines.join(mime.indexOf(';') !== -1 ? '' : '\n')
|
|
||||||
);
|
|
||||||
return r;
|
return r;
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
RedirectEntry.fromSelfie = function(selfie) {
|
RedirectEntry.fromSelfie = function(selfie) {
|
||||||
var r = new RedirectEntry();
|
const r = new RedirectEntry();
|
||||||
r.mime = selfie.mime;
|
r.mime = selfie.mime;
|
||||||
r.data = selfie.data;
|
r.data = selfie.data;
|
||||||
r.warURL = selfie.warURL;
|
r.warURL = selfie.warURL;
|
||||||
@ -313,6 +261,7 @@ RedirectEntry.fromSelfie = function(selfie) {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
const RedirectEngine = function() {
|
const RedirectEngine = function() {
|
||||||
|
this.aliases = new Map();
|
||||||
this.resources = new Map();
|
this.resources = new Map();
|
||||||
this.reset();
|
this.reset();
|
||||||
this.resourceNameRegister = '';
|
this.resourceNameRegister = '';
|
||||||
@ -337,7 +286,7 @@ RedirectEngine.prototype.freeze = function() {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
RedirectEngine.prototype.toBroaderHostname = function(hostname) {
|
RedirectEngine.prototype.toBroaderHostname = function(hostname) {
|
||||||
var pos = hostname.indexOf('.');
|
const pos = hostname.indexOf('.');
|
||||||
if ( pos !== -1 ) {
|
if ( pos !== -1 ) {
|
||||||
return hostname.slice(pos + 1);
|
return hostname.slice(pos + 1);
|
||||||
}
|
}
|
||||||
@ -395,7 +344,7 @@ RedirectEngine.prototype.lookupToken = function(entries, reqURL) {
|
|||||||
RedirectEngine.prototype.toURL = function(fctxt) {
|
RedirectEngine.prototype.toURL = function(fctxt) {
|
||||||
let token = this.lookup(fctxt);
|
let token = this.lookup(fctxt);
|
||||||
if ( token === undefined ) { return; }
|
if ( token === undefined ) { return; }
|
||||||
let entry = this.resources.get(token);
|
const entry = this.resources.get(this.aliases.get(token) || token);
|
||||||
if ( entry !== undefined ) {
|
if ( entry !== undefined ) {
|
||||||
return entry.toURL(fctxt);
|
return entry.toURL(fctxt);
|
||||||
}
|
}
|
||||||
@ -404,8 +353,9 @@ RedirectEngine.prototype.toURL = function(fctxt) {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
RedirectEngine.prototype.matches = function(context) {
|
RedirectEngine.prototype.matches = function(context) {
|
||||||
var token = this.lookup(context);
|
const token = this.lookup(context);
|
||||||
return token !== undefined && this.resources.has(token);
|
return token !== undefined &&
|
||||||
|
this.resources.has(this.aliases.get(token) || token);
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -414,14 +364,14 @@ RedirectEngine.prototype.addRule = function(src, des, type, pattern, redirect) {
|
|||||||
this.ruleSources.add(src);
|
this.ruleSources.add(src);
|
||||||
this.ruleDestinations.add(des);
|
this.ruleDestinations.add(des);
|
||||||
this.ruleTypes.add(type);
|
this.ruleTypes.add(type);
|
||||||
var key = src + ' ' + des + ' ' + type,
|
const key = `${src} ${des} ${type}`,
|
||||||
entries = this.rules.get(key);
|
entries = this.rules.get(key);
|
||||||
if ( entries === undefined ) {
|
if ( entries === undefined ) {
|
||||||
this.rules.set(key, [ { tok: redirect, pat: pattern } ]);
|
this.rules.set(key, [ { tok: redirect, pat: pattern } ]);
|
||||||
this.modifyTime = Date.now();
|
this.modifyTime = Date.now();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var entry;
|
let entry;
|
||||||
for ( var i = 0, n = entries.length; i < n; i++ ) {
|
for ( var i = 0, n = entries.length; i < n; i++ ) {
|
||||||
entry = entries[i];
|
entry = entries[i];
|
||||||
if ( redirect === entry.tok ) { break; }
|
if ( redirect === entry.tok ) { break; }
|
||||||
@ -430,12 +380,12 @@ RedirectEngine.prototype.addRule = function(src, des, type, pattern, redirect) {
|
|||||||
entries.push({ tok: redirect, pat: pattern });
|
entries.push({ tok: redirect, pat: pattern });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var p = entry.pat;
|
let p = entry.pat;
|
||||||
if ( p instanceof RegExp ) {
|
if ( p instanceof RegExp ) {
|
||||||
p = p.source;
|
p = p.source;
|
||||||
}
|
}
|
||||||
// Duplicate?
|
// Duplicate?
|
||||||
var pos = p.indexOf(pattern);
|
let pos = p.indexOf(pattern);
|
||||||
if ( pos !== -1 ) {
|
if ( pos !== -1 ) {
|
||||||
if ( pos === 0 || p.charAt(pos - 1) === '|' ) {
|
if ( pos === 0 || p.charAt(pos - 1) === '|' ) {
|
||||||
pos += pattern.length;
|
pos += pattern.length;
|
||||||
@ -526,7 +476,7 @@ RedirectEngine.prototype.compileRuleFromStaticFilter = function(line) {
|
|||||||
for ( const srchn of srchns ) {
|
for ( const srchn of srchns ) {
|
||||||
if ( srchn === '' ) { continue; }
|
if ( srchn === '' ) { continue; }
|
||||||
if ( srchn.startsWith('~') ) { continue; }
|
if ( srchn.startsWith('~') ) { continue; }
|
||||||
out.push(srchn + '\t' + deshn + '\t' + type + '\t' + pattern + '\t' + redirect);
|
out.push(`${srchn}\t${deshn}\t${type}\t${pattern}\t${redirect}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
@ -603,8 +553,11 @@ RedirectEngine.prototype.fromSelfie = function(path) {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
RedirectEngine.prototype.resourceURIFromName = function(name, mime) {
|
RedirectEngine.prototype.resourceURIFromName = function(name, mime) {
|
||||||
var entry = this.resources.get(name);
|
const entry = this.resources.get(this.aliases.get(name) || name);
|
||||||
if ( entry && (mime === undefined || entry.mime.startsWith(mime)) ) {
|
if (
|
||||||
|
(entry !== undefined) &&
|
||||||
|
(mime === undefined || entry.mime.startsWith(mime))
|
||||||
|
) {
|
||||||
return entry.toURL();
|
return entry.toURL();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -612,15 +565,8 @@ RedirectEngine.prototype.resourceURIFromName = function(name, mime) {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
RedirectEngine.prototype.resourceContentFromName = function(name, mime) {
|
RedirectEngine.prototype.resourceContentFromName = function(name, mime) {
|
||||||
var entry;
|
const entry = this.resources.get(this.aliases.get(name) || name);
|
||||||
for (;;) {
|
|
||||||
entry = this.resources.get(name);
|
|
||||||
if ( entry === undefined ) { return; }
|
if ( entry === undefined ) { return; }
|
||||||
if ( entry.mime.startsWith('alias/') === false ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
name = entry.mime.slice(6);
|
|
||||||
}
|
|
||||||
if ( mime === undefined || entry.mime.startsWith(mime) ) {
|
if ( mime === undefined || entry.mime.startsWith(mime) ) {
|
||||||
return entry.toContent();
|
return entry.toContent();
|
||||||
}
|
}
|
||||||
@ -633,24 +579,38 @@ RedirectEngine.prototype.resourceContentFromName = function(name, mime) {
|
|||||||
// https://github.com/uBlockOrigin/uAssets/commit/deefe875551197d655f79cb540e62dfc17c95f42
|
// https://github.com/uBlockOrigin/uAssets/commit/deefe875551197d655f79cb540e62dfc17c95f42
|
||||||
// Consider 'none' a reserved keyword, to be used to disable redirection.
|
// Consider 'none' a reserved keyword, to be used to disable redirection.
|
||||||
|
|
||||||
RedirectEngine.prototype.resourcesFromString = function(
|
RedirectEngine.prototype.resourcesFromString = function(text) {
|
||||||
text,
|
const lineIter = new µBlock.LineIterator(removeTopCommentBlock(text));
|
||||||
override = true
|
|
||||||
) {
|
|
||||||
const lineIter = new µBlock.LineIterator(text);
|
|
||||||
const reNonEmptyLine = /\S/;
|
const reNonEmptyLine = /\S/;
|
||||||
let fields, encoded;
|
let fields, encoded, details;
|
||||||
|
|
||||||
while ( lineIter.eot() === false ) {
|
while ( lineIter.eot() === false ) {
|
||||||
let line = lineIter.next();
|
let line = lineIter.next();
|
||||||
if ( line.startsWith('#') ) { continue; }
|
if ( line.startsWith('#') ) { continue; }
|
||||||
|
if ( line.startsWith('// ') ) { continue; }
|
||||||
|
|
||||||
if ( fields === undefined ) {
|
if ( fields === undefined ) {
|
||||||
let head = line.trim().split(/\s+/);
|
if ( line.startsWith('/// ') ) {
|
||||||
|
const name = line.slice(4).trim();
|
||||||
|
fields = [ name, mimeFromName(name) ];
|
||||||
|
} else {
|
||||||
|
const head = line.trim().split(/\s+/);
|
||||||
if ( head.length !== 2 ) { continue; }
|
if ( head.length !== 2 ) { continue; }
|
||||||
if ( head[0] === 'none' ) { continue; }
|
if ( head[0] === 'none' ) { continue; }
|
||||||
encoded = head[1].indexOf(';') !== -1;
|
encoded = head[1].indexOf(';') !== -1;
|
||||||
fields = head;
|
fields = head;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( line.startsWith('/// ') ) {
|
||||||
|
if ( details === undefined ) {
|
||||||
|
details = {};
|
||||||
|
}
|
||||||
|
const [ prop, value ] = line.slice(4).trim().split(/\s+/);
|
||||||
|
if ( value !== undefined ) {
|
||||||
|
details[prop] = value;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -659,45 +619,62 @@ RedirectEngine.prototype.resourcesFromString = function(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// No more data, add the resource.
|
const name = fields[0];
|
||||||
if (
|
const mime = fields[1];
|
||||||
this.resources.has(fields[0]) === false ||
|
const content = µBlock.orphanizeString(
|
||||||
override !== false
|
fields.slice(2).join(encoded ? '' : '\n')
|
||||||
) {
|
|
||||||
this.resources.set(
|
|
||||||
fields[0],
|
|
||||||
RedirectEntry.fromFields(fields[1], fields.slice(2))
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// No more data, add the resource.
|
||||||
|
this.resources.set(
|
||||||
|
name,
|
||||||
|
RedirectEntry.fromContent(mime, content)
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( details instanceof Object && details.alias ) {
|
||||||
|
this.aliases.set(details.alias, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
fields = undefined;
|
fields = undefined;
|
||||||
|
details = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process pending resource data.
|
// Process pending resource data.
|
||||||
if ( fields !== undefined ) {
|
if ( fields !== undefined ) {
|
||||||
this.resources.set(
|
const name = fields[0];
|
||||||
fields[0],
|
const mime = fields[1];
|
||||||
RedirectEntry.fromFields(fields[1], fields.slice(2))
|
const content = µBlock.orphanizeString(
|
||||||
|
fields.slice(2).join(encoded ? '' : '\n')
|
||||||
);
|
);
|
||||||
|
this.resources.set(
|
||||||
|
name,
|
||||||
|
RedirectEntry.fromContent(mime, content)
|
||||||
|
);
|
||||||
|
if ( details instanceof Object && details.alias ) {
|
||||||
|
this.aliases.set(details.alias, name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.modifyTime = Date.now();
|
this.modifyTime = Date.now();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const removeTopCommentBlock = function(text) {
|
||||||
|
return text.replace(/^\/\*[\S\s]+?\n\*\/\s*/, '');
|
||||||
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
RedirectEngine.prototype.loadBuiltinResources = function() {
|
RedirectEngine.prototype.loadBuiltinResources = function() {
|
||||||
this.resources = new Map();
|
this.resources = new Map();
|
||||||
const mimeFromName = function(name) {
|
this.aliases = new Map();
|
||||||
const match = /\.([^.]+)$/.exec(name);
|
|
||||||
if ( match !== null ) {
|
|
||||||
return mimeMap[match[1]];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const fetches = [
|
const fetches = [
|
||||||
µBlock.assets.get('ublock-resources'),
|
µBlock.assets.fetchText('/assets/resources/scriptlets.js'),
|
||||||
];
|
];
|
||||||
for ( const [ name, details ] of immutableResources ) {
|
|
||||||
|
// TODO: remove once usage of uBO 1.20.4 is widespread.
|
||||||
|
µBlock.assets.remove('ublock-resources');
|
||||||
|
|
||||||
|
for ( const [ name, details ] of redirectableResources ) {
|
||||||
if ( details.inject !== false ) {
|
if ( details.inject !== false ) {
|
||||||
fetches.push(
|
fetches.push(
|
||||||
µBlock.assets.fetchText(
|
µBlock.assets.fetchText(
|
||||||
@ -712,48 +689,48 @@ RedirectEngine.prototype.loadBuiltinResources = function() {
|
|||||||
});
|
});
|
||||||
this.resources.set(name, entry);
|
this.resources.set(name, entry);
|
||||||
if ( details.alias !== undefined ) {
|
if ( details.alias !== undefined ) {
|
||||||
this.resources.set(details.alias, entry);
|
this.aliases.set(details.alias, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.all(fetches).then(results => {
|
return Promise.all(fetches).then(results => {
|
||||||
// Immutable resources
|
// Built-in redirectable resources
|
||||||
for ( let i = 1; i < results.length; i++ ) {
|
for ( let i = 1; i < results.length; i++ ) {
|
||||||
const result = results[i];
|
const result = results[i];
|
||||||
const match = /^\/web_accessible_resources\/([^?]+)/.exec(result.url);
|
const match = /^\/web_accessible_resources\/([^?]+)/.exec(result.url);
|
||||||
if ( match === null ) { continue; }
|
if ( match === null ) { continue; }
|
||||||
const name = match[1];
|
const name = match[1];
|
||||||
const content = result.content.replace(/^\/\*[\S\s]+?\n\*\/\s*/, '');
|
const content = removeTopCommentBlock(result.content);
|
||||||
const details = immutableResources.get(name);
|
const details = redirectableResources.get(name);
|
||||||
const entry = RedirectEntry.fromSelfie({
|
const entry = RedirectEntry.fromSelfie({
|
||||||
mime: mimeFromName(name),
|
mime: mimeFromName(name),
|
||||||
data: content,
|
data: content,
|
||||||
warURL: details.redirect !== false
|
warURL: vAPI.getURL(`/web_accessible_resources/${name}`),
|
||||||
? vAPI.getURL(`/web_accessible_resources/${name}`)
|
|
||||||
: undefined,
|
|
||||||
});
|
});
|
||||||
this.resources.set(name, entry);
|
this.resources.set(name, entry);
|
||||||
if ( details.alias !== undefined ) {
|
if ( details.alias !== undefined ) {
|
||||||
this.resources.set(details.alias, entry);
|
this.aliases.set(details.alias, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Mutable resources
|
// Additional resources
|
||||||
const content = results[0].content;
|
const content = results[0].content;
|
||||||
if ( typeof content === 'string' && content.length !== 0 ) {
|
if ( typeof content === 'string' && content.length !== 0 ) {
|
||||||
this.resourcesFromString(content, false);
|
this.resourcesFromString(content);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
const resourcesSelfieVersion = 3;
|
const resourcesSelfieVersion = 4;
|
||||||
|
|
||||||
RedirectEngine.prototype.selfieFromResources = function() {
|
RedirectEngine.prototype.selfieFromResources = function() {
|
||||||
µBlock.assets.put(
|
µBlock.assets.put(
|
||||||
'compiled/redirectEngine/resources',
|
'compiled/redirectEngine/resources',
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
version: resourcesSelfieVersion,
|
version: resourcesSelfieVersion,
|
||||||
resources: Array.from(this.resources)
|
aliases: Array.from(this.aliases),
|
||||||
|
resources: Array.from(this.resources),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -774,6 +751,7 @@ RedirectEngine.prototype.resourcesFromSelfie = function() {
|
|||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
this.aliases = new Map(selfie.aliases);
|
||||||
this.resources = new Map();
|
this.resources = new Map();
|
||||||
for ( const [ token, entry ] of selfie.resources ) {
|
for ( const [ token, entry ] of selfie.resources ) {
|
||||||
this.resources.set(token, RedirectEntry.fromSelfie(entry));
|
this.resources.set(token, RedirectEntry.fromSelfie(entry));
|
||||||
|
@ -1327,15 +1327,10 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// https://github.com/gorhill/uBlock/issues/2594
|
// This asset is deprecated.
|
||||||
if ( details.assetKey === 'ublock-resources' ) {
|
if ( details.assetKey === 'ublock-resources' ) {
|
||||||
if (
|
|
||||||
this.hiddenSettings.ignoreRedirectFilters === true &&
|
|
||||||
this.hiddenSettings.ignoreScriptInjectFilters === true
|
|
||||||
) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1367,8 +1362,6 @@
|
|||||||
if ( cached ) {
|
if ( cached ) {
|
||||||
this.compilePublicSuffixList(details.content);
|
this.compilePublicSuffixList(details.content);
|
||||||
}
|
}
|
||||||
} else if ( details.assetKey === 'ublock-resources' ) {
|
|
||||||
this.redirectEngine.invalidateResourcesSelfie();
|
|
||||||
}
|
}
|
||||||
vAPI.messaging.broadcast({
|
vAPI.messaging.broadcast({
|
||||||
what: 'assetUpdated',
|
what: 'assetUpdated',
|
||||||
@ -1395,6 +1388,10 @@
|
|||||||
// Reload all filter lists if needed.
|
// Reload all filter lists if needed.
|
||||||
if ( topic === 'after-assets-updated' ) {
|
if ( topic === 'after-assets-updated' ) {
|
||||||
if ( details.assetKeys.length !== 0 ) {
|
if ( details.assetKeys.length !== 0 ) {
|
||||||
|
// https://github.com/gorhill/uBlock/pull/2314#issuecomment-278716960
|
||||||
|
if ( this.hiddenSettings.userResourcesLocation !== 'unset' ) {
|
||||||
|
this.redirectEngine.invalidateResourcesSelfie();
|
||||||
|
}
|
||||||
this.loadFilterLists();
|
this.loadFilterLists();
|
||||||
}
|
}
|
||||||
if ( this.userSettings.autoUpdate ) {
|
if ( this.userSettings.autoUpdate ) {
|
||||||
|
@ -1,79 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
uBlock Origin - a browser extension to block requests.
|
|
||||||
Copyright (C) 2019-present Raymond Hill
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
|
||||||
|
|
||||||
Home: https://github.com/gorhill/uBlock
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
'use strict';
|
|
||||||
const target = '{{1}}';
|
|
||||||
if ( target === '' || target === '{{1}}' ) { return; }
|
|
||||||
const needle = '{{2}}';
|
|
||||||
let reText = '.?';
|
|
||||||
if ( needle !== '' && needle !== '{{2}}' ) {
|
|
||||||
reText = /^\/.+\/$/.test(needle)
|
|
||||||
? needle.slice(1,-1)
|
|
||||||
: needle.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
||||||
}
|
|
||||||
const thisScript = document.currentScript;
|
|
||||||
const re = new RegExp(reText);
|
|
||||||
const chain = target.split('.');
|
|
||||||
let owner = window;
|
|
||||||
let prop;
|
|
||||||
for (;;) {
|
|
||||||
prop = chain.shift();
|
|
||||||
if ( chain.length === 0 ) { break; }
|
|
||||||
owner = owner[prop];
|
|
||||||
if ( owner instanceof Object === false ) { return; }
|
|
||||||
}
|
|
||||||
const desc = Object.getOwnPropertyDescriptor(owner, prop);
|
|
||||||
if ( desc && desc.get !== undefined ) { return; }
|
|
||||||
const magic = String.fromCharCode(Date.now() % 26 + 97) +
|
|
||||||
Math.floor(Math.random() * 982451653 + 982451653).toString(36);
|
|
||||||
let value = owner[prop];
|
|
||||||
const validate = function() {
|
|
||||||
const e = document.currentScript;
|
|
||||||
if (
|
|
||||||
e instanceof HTMLScriptElement &&
|
|
||||||
e.src === '' &&
|
|
||||||
e !== thisScript &&
|
|
||||||
re.test(e.textContent)
|
|
||||||
) {
|
|
||||||
throw new ReferenceError(magic);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Object.defineProperty(owner, prop, {
|
|
||||||
get: function() {
|
|
||||||
validate();
|
|
||||||
return value;
|
|
||||||
},
|
|
||||||
set: function(a) {
|
|
||||||
validate();
|
|
||||||
value = a;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const oe = window.onerror;
|
|
||||||
window.onerror = function(msg) {
|
|
||||||
if ( typeof msg === 'string' && msg.indexOf(magic) !== -1 ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if ( oe instanceof Function ) {
|
|
||||||
return oe.apply(this, arguments);
|
|
||||||
}
|
|
||||||
}.bind();
|
|
||||||
})();
|
|
@ -1,72 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
uBlock Origin - a browser extension to block requests.
|
|
||||||
Copyright (C) 2019-present Raymond Hill
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
|
||||||
|
|
||||||
Home: https://github.com/gorhill/uBlock
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
'use strict';
|
|
||||||
const magic = String.fromCharCode(Date.now() % 26 + 97) +
|
|
||||||
Math.floor(Math.random() * 982451653 + 982451653).toString(36);
|
|
||||||
const abort = function() {
|
|
||||||
throw new ReferenceError(magic);
|
|
||||||
};
|
|
||||||
const makeProxy = function(owner, chain) {
|
|
||||||
const pos = chain.indexOf('.');
|
|
||||||
if ( pos === -1 ) {
|
|
||||||
const desc = Object.getOwnPropertyDescriptor(owner, chain);
|
|
||||||
if ( !desc || desc.get !== abort ) {
|
|
||||||
Object.defineProperty(owner, chain, {
|
|
||||||
get: abort,
|
|
||||||
set: function(){}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const prop = chain.slice(0, pos);
|
|
||||||
let v = owner[prop];
|
|
||||||
chain = chain.slice(pos + 1);
|
|
||||||
if ( v ) {
|
|
||||||
makeProxy(v, chain);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const desc = Object.getOwnPropertyDescriptor(owner, prop);
|
|
||||||
if ( desc && desc.set !== undefined ) { return; }
|
|
||||||
Object.defineProperty(owner, prop, {
|
|
||||||
get: function() { return v; },
|
|
||||||
set: function(a) {
|
|
||||||
v = a;
|
|
||||||
if ( a instanceof Object ) {
|
|
||||||
makeProxy(a, chain);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const owner = window;
|
|
||||||
let chain = '{{1}}';
|
|
||||||
makeProxy(owner, chain);
|
|
||||||
const oe = window.onerror;
|
|
||||||
window.onerror = function(msg, src, line, col, error) {
|
|
||||||
if ( typeof msg === 'string' && msg.indexOf(magic) !== -1 ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if ( oe instanceof Function ) {
|
|
||||||
return oe(msg, src, line, col, error);
|
|
||||||
}
|
|
||||||
}.bind();
|
|
||||||
})();
|
|
@ -1,50 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
uBlock Origin - a browser extension to block requests.
|
|
||||||
Copyright (C) 2019-present Raymond Hill
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
|
||||||
|
|
||||||
Home: https://github.com/gorhill/uBlock
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
'use strict';
|
|
||||||
const magic = String.fromCharCode(Date.now() % 26 + 97) +
|
|
||||||
Math.floor(Math.random() * 982451653 + 982451653).toString(36);
|
|
||||||
let prop = '{{1}}';
|
|
||||||
let owner = window;
|
|
||||||
for (;;) {
|
|
||||||
const pos = prop.indexOf('.');
|
|
||||||
if ( pos === -1 ) { break; }
|
|
||||||
owner = owner[prop.slice(0, pos)];
|
|
||||||
if ( owner instanceof Object === false ) { return; }
|
|
||||||
prop = prop.slice(pos + 1);
|
|
||||||
}
|
|
||||||
delete owner[prop];
|
|
||||||
Object.defineProperty(owner, prop, {
|
|
||||||
set: function() {
|
|
||||||
throw new ReferenceError(magic);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const oe = window.onerror;
|
|
||||||
window.onerror = function(msg, src, line, col, error) {
|
|
||||||
if ( typeof msg === 'string' && msg.indexOf(magic) !== -1 ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if ( oe instanceof Function ) {
|
|
||||||
return oe(msg, src, line, col, error);
|
|
||||||
}
|
|
||||||
}.bind();
|
|
||||||
})();
|
|
@ -1,57 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
uBlock Origin - a browser extension to block requests.
|
|
||||||
Copyright (C) 2019-present Raymond Hill
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
|
||||||
|
|
||||||
Home: https://github.com/gorhill/uBlock
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
'use strict';
|
|
||||||
let needle1 = '{{1}}';
|
|
||||||
if ( needle1 === '' || needle1 === '{{1}}' ) {
|
|
||||||
needle1 = '.?';
|
|
||||||
} else if ( /^\/.+\/$/.test(needle1) ) {
|
|
||||||
needle1 = needle1.slice(1,-1);
|
|
||||||
} else {
|
|
||||||
needle1 = needle1.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
||||||
}
|
|
||||||
needle1 = new RegExp(needle1);
|
|
||||||
let needle2 = '{{2}}';
|
|
||||||
if ( needle2 === '' || needle2 === '{{2}}' ) {
|
|
||||||
needle2 = '.?';
|
|
||||||
} else if ( /^\/.+\/$/.test(needle2) ) {
|
|
||||||
needle2 = needle2.slice(1,-1);
|
|
||||||
} else {
|
|
||||||
needle2 = needle2.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
||||||
}
|
|
||||||
needle2 = new RegExp(needle2);
|
|
||||||
self.EventTarget.prototype.addEventListener = new Proxy(
|
|
||||||
self.EventTarget.prototype.addEventListener,
|
|
||||||
{
|
|
||||||
apply: function(target, thisArg, args) {
|
|
||||||
const type = args[0].toString();
|
|
||||||
const handler = String(args[1]);
|
|
||||||
if (
|
|
||||||
needle1.test(type) === false ||
|
|
||||||
needle2.test(handler) === false
|
|
||||||
) {
|
|
||||||
return target.apply(thisArg, args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
})();
|
|
@ -1,36 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
uBlock Origin - a browser extension to block requests.
|
|
||||||
Copyright (C) 2019-present Raymond Hill
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
|
||||||
|
|
||||||
Home: https://github.com/gorhill/uBlock
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
'use strict';
|
|
||||||
const log = console.log.bind(console);
|
|
||||||
self.EventTarget.prototype.addEventListener = new Proxy(
|
|
||||||
self.EventTarget.prototype.addEventListener,
|
|
||||||
{
|
|
||||||
apply: function(target, thisArg, args) {
|
|
||||||
const type = args[0].toString();
|
|
||||||
const handler = String(args[1]);
|
|
||||||
log('addEventListener("%s", %s)', type, handler);
|
|
||||||
return target.apply(thisArg, args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
})();
|
|
@ -1,51 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
Imported from:
|
|
||||||
https://github.com/NanoAdblocker/NanoFilters/blob/1f3be7211bb0809c5106996f52564bf10c4525f7/NanoFiltersSource/NanoResources.txt#L126
|
|
||||||
|
|
||||||
Speed up or down setInterval, 3 optional arguments.
|
|
||||||
funcMatcher - The payload matcher, a string literal or a JavaScript RegExp,
|
|
||||||
defaults to match all.
|
|
||||||
delayMatcher - The delay matcher, an integer, defaults to 1000.
|
|
||||||
boostRatio - The delay multiplier when there is a match, 0.5 speeds up by
|
|
||||||
2 times and 2 slows down by 2 times, defaults to 0.05 or speed up 20 times.
|
|
||||||
Speed up and down both cap at 50 times.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
'use strict';
|
|
||||||
let needle = '{{1}}';
|
|
||||||
let delay = parseInt('{{2}}', 10);
|
|
||||||
let boost = parseFloat('{{3}}');
|
|
||||||
if ( needle === '' || needle === '{{1}}' ) {
|
|
||||||
needle = '.?';
|
|
||||||
} else if ( needle.charAt(0) === '/' && needle.slice(-1) === '/' ) {
|
|
||||||
needle = needle.slice(1, -1);
|
|
||||||
} else {
|
|
||||||
needle = needle.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
||||||
}
|
|
||||||
needle = new RegExp(needle);
|
|
||||||
if ( isNaN(delay) || !isFinite(delay) ) {
|
|
||||||
delay = 1000;
|
|
||||||
}
|
|
||||||
if ( isNaN(boost) || !isFinite(boost) ) {
|
|
||||||
boost = 0.05;
|
|
||||||
}
|
|
||||||
if ( boost < 0.02 ) {
|
|
||||||
boost = 0.02;
|
|
||||||
}
|
|
||||||
if ( boost > 50 ) {
|
|
||||||
boost = 50;
|
|
||||||
}
|
|
||||||
window.setInterval = new Proxy(window.setInterval, {
|
|
||||||
apply: function(target, thisArg, args) {
|
|
||||||
const a = args[0];
|
|
||||||
const b = args[1];
|
|
||||||
if ( b === delay && needle.test(a.toString()) ) {
|
|
||||||
args[1] = b * boost;
|
|
||||||
}
|
|
||||||
return target.apply(thisArg, args);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})();
|
|
@ -1,51 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
Originally imported from:
|
|
||||||
https://github.com/NanoAdblocker/NanoFilters/blob/1f3be7211bb0809c5106996f52564bf10c4525f7/NanoFiltersSource/NanoResources.txt#L82
|
|
||||||
|
|
||||||
Speed up or down setTimeout, 3 optional arguments.
|
|
||||||
funcMatcher - The payload matcher, a string literal or a JavaScript RegExp,
|
|
||||||
defaults to match all.
|
|
||||||
delayMatcher - The delay matcher, an integer, defaults to 1000.
|
|
||||||
boostRatio - The delay multiplier when there is a match, 0.5 speeds up by
|
|
||||||
2 times and 2 slows down by 2 times, defaults to 0.05 or speed up 20 times.
|
|
||||||
Speed up and down both cap at 50 times.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
'use strict';
|
|
||||||
let needle = '{{1}}';
|
|
||||||
let delay = parseInt('{{2}}', 10);
|
|
||||||
let boost = parseFloat('{{3}}');
|
|
||||||
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);
|
|
||||||
if ( isNaN(delay) || !isFinite(delay) ) {
|
|
||||||
delay = 1000;
|
|
||||||
}
|
|
||||||
if ( isNaN(boost) || !isFinite(boost) ) {
|
|
||||||
boost = 0.05;
|
|
||||||
}
|
|
||||||
if ( boost < 0.02 ) {
|
|
||||||
boost = 0.02;
|
|
||||||
}
|
|
||||||
if ( boost > 50 ) {
|
|
||||||
boost = 50;
|
|
||||||
}
|
|
||||||
window.setTimeout = new Proxy(window.setTimeout, {
|
|
||||||
apply: function(target, thisArg, args) {
|
|
||||||
const a = args[0];
|
|
||||||
const b = args[1];
|
|
||||||
if ( b === delay && needle.test(a.toString()) ) {
|
|
||||||
args[1] = b * boost;
|
|
||||||
}
|
|
||||||
return target.apply(thisArg, args);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})();
|
|
@ -1,41 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
uBlock Origin - a browser extension to block requests.
|
|
||||||
Copyright (C) 2019-present Raymond Hill
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
|
||||||
|
|
||||||
Home: https://github.com/gorhill/uBlock
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
'use strict';
|
|
||||||
let needle = '{{1}}';
|
|
||||||
if ( needle === '' || needle === '{{1}}' ) {
|
|
||||||
needle = '.?';
|
|
||||||
} else if ( needle.slice(0,1) === '/' && needle.slice(-1) === '/' ) {
|
|
||||||
needle = needle.slice(1,-1);
|
|
||||||
} else {
|
|
||||||
needle = needle.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
||||||
}
|
|
||||||
needle = new RegExp(needle);
|
|
||||||
window.eval = new Proxy(window.eval, { // jshint ignore: line
|
|
||||||
apply: function(target, thisArg, args) {
|
|
||||||
const a = args[0];
|
|
||||||
if ( needle.test(a.toString()) === false ) {
|
|
||||||
return target.apply(thisArg, args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})();
|
|
@ -1,50 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
uBlock Origin - a browser extension to block requests.
|
|
||||||
Copyright (C) 2019-present Raymond Hill
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
|
||||||
|
|
||||||
Home: https://github.com/gorhill/uBlock
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
'use strict';
|
|
||||||
const token = '{{1}}';
|
|
||||||
if ( token === '' || token === '{{1}}' ) { return; }
|
|
||||||
const tokens = token.split(/\s*\|\s*/);
|
|
||||||
let selector = '{{2}}';
|
|
||||||
if ( selector === '' || selector === '{{2}}' ) {
|
|
||||||
selector = `[${tokens.join('],[')}]`;
|
|
||||||
}
|
|
||||||
const rmattr = function(ev) {
|
|
||||||
if ( ev ) {
|
|
||||||
window.removeEventListener(ev.type, rmattr, true);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const nodes = document.querySelectorAll(selector);
|
|
||||||
for ( const node of nodes ) {
|
|
||||||
for ( const attr of tokens ) {
|
|
||||||
node.removeAttribute(attr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch(ex) {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if ( document.readyState === 'loading' ) {
|
|
||||||
window.addEventListener('DOMContentLoaded', rmattr, true);
|
|
||||||
} else {
|
|
||||||
rmattr();
|
|
||||||
}
|
|
||||||
})();
|
|
@ -1,99 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
uBlock Origin - a browser extension to block requests.
|
|
||||||
Copyright (C) 2019-present Raymond Hill
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
|
||||||
|
|
||||||
Home: https://github.com/gorhill/uBlock
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
'use strict';
|
|
||||||
const thisScript = document.currentScript;
|
|
||||||
let cValue = '{{2}}';
|
|
||||||
if ( cValue === 'undefined' ) {
|
|
||||||
cValue = undefined;
|
|
||||||
} else if ( cValue === 'false' ) {
|
|
||||||
cValue = false;
|
|
||||||
} else if ( cValue === 'true' ) {
|
|
||||||
cValue = true;
|
|
||||||
} else if ( cValue === 'null' ) {
|
|
||||||
cValue = null;
|
|
||||||
} else if ( cValue === 'noopFunc' ) {
|
|
||||||
cValue = function(){};
|
|
||||||
} else if ( cValue === 'trueFunc' ) {
|
|
||||||
cValue = function(){ return true; };
|
|
||||||
} else if ( cValue === 'falseFunc' ) {
|
|
||||||
cValue = function(){ return false; };
|
|
||||||
} else if ( /^\d+$/.test(cValue) ) {
|
|
||||||
cValue = parseFloat(cValue);
|
|
||||||
if ( isNaN(cValue) ) { return; }
|
|
||||||
if ( Math.abs(cValue) > 0x7FFF ) { return; }
|
|
||||||
} else if ( cValue === "''" ) {
|
|
||||||
cValue = '';
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let aborted = false;
|
|
||||||
const mustAbort = function(v) {
|
|
||||||
if ( aborted ) { return true; }
|
|
||||||
aborted = v !== undefined && cValue !== undefined && typeof v !== typeof cValue;
|
|
||||||
return aborted;
|
|
||||||
};
|
|
||||||
const makeProxy = function(owner, chain) {
|
|
||||||
const pos = chain.indexOf('.');
|
|
||||||
if ( pos === -1 ) {
|
|
||||||
const original = owner[chain];
|
|
||||||
if ( mustAbort(original) ) { return; }
|
|
||||||
const desc = Object.getOwnPropertyDescriptor(owner, chain);
|
|
||||||
if ( desc === undefined || desc.get === undefined ) {
|
|
||||||
Object.defineProperty(owner, chain, {
|
|
||||||
get: function() {
|
|
||||||
return document.currentScript === thisScript
|
|
||||||
? original
|
|
||||||
: cValue;
|
|
||||||
},
|
|
||||||
set: function(a) {
|
|
||||||
if ( mustAbort(a) ) {
|
|
||||||
cValue = a;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const prop = chain.slice(0, pos);
|
|
||||||
let v = owner[prop];
|
|
||||||
chain = chain.slice(pos + 1);
|
|
||||||
if ( v !== undefined ) {
|
|
||||||
makeProxy(v, chain);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const desc = Object.getOwnPropertyDescriptor(owner, prop);
|
|
||||||
if ( desc && desc.set !== undefined ) { return; }
|
|
||||||
Object.defineProperty(owner, prop, {
|
|
||||||
get: function() {
|
|
||||||
return v;
|
|
||||||
},
|
|
||||||
set: function(a) {
|
|
||||||
v = a;
|
|
||||||
if ( a instanceof Object ) {
|
|
||||||
makeProxy(a, chain);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
makeProxy(window, '{{1}}');
|
|
||||||
})();
|
|
@ -1,44 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
uBlock Origin - a browser extension to block requests.
|
|
||||||
Copyright (C) 2019-present Raymond Hill
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
|
||||||
|
|
||||||
Home: https://github.com/gorhill/uBlock
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
'use strict';
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})();
|
|
@ -1,33 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
uBlock Origin - a browser extension to block requests.
|
|
||||||
Copyright (C) 2019-present Raymond Hill
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
|
||||||
|
|
||||||
Home: https://github.com/gorhill/uBlock
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
'use strict';
|
|
||||||
const log = console.log.bind(console);
|
|
||||||
window.setInterval = new Proxy(window.setInterval, {
|
|
||||||
apply: function(target, thisArg, args) {
|
|
||||||
const a = args[0];
|
|
||||||
const b = args[1];
|
|
||||||
log('uBO: setInterval("%s", %s)', a.toString(), b);
|
|
||||||
return target.apply(thisArg, args);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})();
|
|
@ -1,44 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
uBlock Origin - a browser extension to block requests.
|
|
||||||
Copyright (C) 2019-present Raymond Hill
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
|
||||||
|
|
||||||
Home: https://github.com/gorhill/uBlock
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
'use strict';
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})();
|
|
@ -1,33 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
uBlock Origin - a browser extension to block requests.
|
|
||||||
Copyright (C) 2019-present Raymond Hill
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
|
||||||
|
|
||||||
Home: https://github.com/gorhill/uBlock
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
'use strict';
|
|
||||||
const log = console.log.bind(console);
|
|
||||||
window.setTimeout = new Proxy(window.setTimeout, {
|
|
||||||
apply: function(target, thisArg, args) {
|
|
||||||
const a = args[0];
|
|
||||||
const b = args[1];
|
|
||||||
log('uBO: setTimeout("%s", %s)', a.toString(), b);
|
|
||||||
return target.apply(thisArg, args);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})();
|
|
@ -1,87 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
uBlock Origin - a browser extension to block requests.
|
|
||||||
Copyright (C) 2019-present Raymond Hill
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
|
||||||
|
|
||||||
Home: https://github.com/gorhill/uBlock
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
'use strict';
|
|
||||||
let good = '{{1}}';
|
|
||||||
if ( good.startsWith('/') && good.endsWith('/') ) {
|
|
||||||
good = good.slice(1, -1);
|
|
||||||
} else {
|
|
||||||
good = good.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
||||||
}
|
|
||||||
let reGood;
|
|
||||||
try {
|
|
||||||
reGood = new RegExp(good);
|
|
||||||
} catch(ex) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const rtcName = window.RTCPeerConnection
|
|
||||||
? 'RTCPeerConnection'
|
|
||||||
: (window.webkitRTCPeerConnection ? 'webkitRTCPeerConnection' : '');
|
|
||||||
if ( rtcName === '' ) { return; }
|
|
||||||
const log = console.log.bind(console);
|
|
||||||
const neuteredPeerConnections = new WeakSet();
|
|
||||||
const isGoodConfig = function(instance, config) {
|
|
||||||
if ( neuteredPeerConnections.has(instance) ) { return false; }
|
|
||||||
if ( config instanceof Object === false ) { return true; }
|
|
||||||
if ( Array.isArray(config.iceServers) === false ) { return true; }
|
|
||||||
for ( const server of config.iceServers ) {
|
|
||||||
const urls = typeof server.urls === 'string'
|
|
||||||
? [ server.urls ]
|
|
||||||
: server.urls;
|
|
||||||
if ( Array.isArray(urls) ) {
|
|
||||||
for ( const url of urls ) {
|
|
||||||
if ( reGood.test(url) ) { return true; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( typeof server.username === 'string' ) {
|
|
||||||
if ( reGood.test(server.username) ) { return true; }
|
|
||||||
}
|
|
||||||
if ( typeof server.credential === 'string' ) {
|
|
||||||
if ( reGood.test(server.credential) ) { return true; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
neuteredPeerConnections.add(instance);
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
const peerConnectionCtor = window[rtcName];
|
|
||||||
const peerConnectionProto = peerConnectionCtor.prototype;
|
|
||||||
peerConnectionProto.createDataChannel =
|
|
||||||
new Proxy(peerConnectionProto.createDataChannel, {
|
|
||||||
apply: function(target, thisArg, args) {
|
|
||||||
if ( isGoodConfig(target, args[1]) === false ) {
|
|
||||||
log(args[1]);
|
|
||||||
return target.apply(thisArg, args.slice(0, 1));
|
|
||||||
}
|
|
||||||
return target.apply(thisArg, args);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
window[rtcName] =
|
|
||||||
new Proxy(peerConnectionCtor, {
|
|
||||||
construct: function(target, args) {
|
|
||||||
if ( isGoodConfig(target, args[0]) === false ) {
|
|
||||||
log(args[0]);
|
|
||||||
return new target();
|
|
||||||
}
|
|
||||||
return new target(...args);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})();
|
|
@ -13,8 +13,7 @@ if [ -n "${TRAVIS_TAG}" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
rm -rf $DES
|
rm -rf $DES
|
||||||
mkdir $DES
|
cp -R ./assets $DES/
|
||||||
cp ./assets/assets.json $DES/
|
|
||||||
|
|
||||||
if [ -f ./tmp/requests.json.gz ]; then
|
if [ -f ./tmp/requests.json.gz ]; then
|
||||||
gunzip -c ./tmp/requests.json.gz > $DES/requests.json
|
gunzip -c ./tmp/requests.json.gz > $DES/requests.json
|
||||||
@ -31,5 +30,6 @@ mkdir $DES/ublock
|
|||||||
cp -R ../uAssets/filters/* $DES/ublock/
|
cp -R ../uAssets/filters/* $DES/ublock/
|
||||||
# Optional filter lists: do not include in package
|
# Optional filter lists: do not include in package
|
||||||
rm $DES/ublock/annoyances.txt
|
rm $DES/ublock/annoyances.txt
|
||||||
|
rm $DES/ublock/resources.txt
|
||||||
|
|
||||||
echo "done."
|
echo "done."
|
||||||
|
Loading…
x
Reference in New Issue
Block a user