// ==UserScript==
// @name RU AdList JS Fixes
// @namespace ruadlist_js_fixes
// @version 20170510.1
// @description try to take over the world!
// @author lainverse & dimisa
// @match *://*/*
// @grant unsafeWindow
// @grant window.close
// @grant GM_getValue
// @grant GM_setValue
// @run-at document-start
// ==/UserScript==
(function() {
'use strict';
var win = (unsafeWindow || window),
// http://stackoverflow.com/questions/9847580/how-to-detect-safari-chrome-ie-firefox-and-opera-browser
isOpera = (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0,
isChrome = !!window.chrome && !!window.chrome.webstore,
isSafari = (Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0 ||
(function (p) { return p.toString() === "[object SafariRemoteNotification]"; })(!window.safari || safari.pushNotification)),
isFirefox = typeof InstallTrigger !== 'undefined',
_getAttribute = Element.prototype.getAttribute,
_setAttribute = Element.prototype.setAttribute;
// NodeList iterator polyfill (mostly for Safari)
// https://jakearchibald.com/2014/iterators-gonna-iterate/
if (!NodeList.prototype[Symbol.iterator]) {
NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
}
// Options
var opts = {
'useWSIFunc': useWSI
};
(function(){
function optsCall(callback) {
// Register event listener
var key = "optsCallEvent_" + Math.random().toString(36).substr(2),
cb = callback.func.bind(callback.name);
window.addEventListener(key, cb, false);
// Generate and dispatch synthetic event
var ev = document.createEvent("HTMLEvents");
ev.initEvent(key, true, false);
window.dispatchEvent(ev);
// Remove listener
window.removeEventListener(key, cb, false);
}
function initOptsHandler() {
/*jshint validthis:true */
opts[this] = GM_getValue(this, true);
if(opts[this]) {
opts[this+'Func']();
}
}
optsCall({
func: initOptsHandler,
name: 'useWSI'
});
// show options page
function openOptions() {
var ovl = document.createElement('div'),
inner = document.createElement('div');
ovl.style = (
'position: fixed;'+
'top:0; left:0;'+
'bottom: 0; right: 0;'+
'background: rgba(0,0,0,0.85);'+
'z-index: 2147483647;'+
'padding: 5em'
);
inner.style = (
'background: whitesmoke;'+
'font-size: 10pt;'+
'color: black;'+
'padding: 1em'
);
inner.textContent = 'JS Fixes Options: (reload page to apply)';
inner.appendChild(document.createElement('br'));
inner.appendChild(document.createElement('br'));
ovl.addEventListener('click', function(e){
if (e.target === ovl) {
ovl.parentNode.removeChild(ovl);
e.preventDefault();
}
e.stopPropagation();
}, false);
// append checkbox with label function
function addCheckbox(optName, optLabel) {
var c = document.createElement('input'),
l = document.createElement('label');
c.type = 'checkbox';
c.id = optName;
optsCall({
func:function(){
c.checked = GM_getValue(this);
},
name:optName
});
c.addEventListener('click', function(e) {
optsCall({
func:function(){
GM_setValue(this, e.target.checked);
opts[this] = e.target.checked;
},
name:optName
});
}, true);
l.textContent = optLabel;
l.setAttribute('for', optName);
inner.appendChild(c);
inner.appendChild(l);
inner.appendChild(document.createElement('br'));
}
// append checkboxes
addCheckbox('useWSI', 'Use WebSocket filter. Disable if experience problems with WebSocket connections.');
document.body.appendChild(ovl);
ovl.appendChild(inner);
}
// monitor keys pressed for Ctrl+Alt+Shift+J > s > f code
var opPos = 0, opKey = 'Jsf', isNotKey;
document.addEventListener('keydown', function(e) {
isNotKey = (e.key.length > 1);
if ((e.key === opKey[opPos] || isNotKey) &&
(!!opPos || e.altKey && e.ctrlKey)) {
opPos += (isNotKey ? 0 : 1);
e.stopPropagation();
e.preventDefault();
} else {
opPos = 0;
}
if (opPos === opKey.length) {
opPos = 0;
openOptions();
}
}, false);
})();
// Creates and return protected style (unless protection is manually disabled).
// Protected style will re-add itself on removal and remaind enabled on attempt to disable it.
function createStyle(rules, props, skip_protect) {
var prop = '',
root = document.documentElement;
function _createGetterSetter(obj) {
return {
get: function() {return obj;}, //pretend to be empty
set: function() {},
enumerable: true
};
}
function _protect(style) {
Object.defineProperty(style, 'sheet', {
value: style.sheet,
enumerable: true
});
for (prop of ['rules', 'cssRules']) {
Object.defineProperty(style.sheet, prop, _createGetterSetter([]));
}
Object.defineProperty(style, 'disabled', {
get: function() {return true;}, //pretend to be disabled
set: function() {},
enumerable: true
});
var o = new MutationObserver(function() {
root.removeChild(style);
});
o.observe(style, {childList: true});
}
function _create() {
var style = root.appendChild(document.createElement('style')),
prop, rule;
style.type = 'text/css';
for (prop in props) {
if (style[prop] !== undefined) {
style[prop] = props[prop];
}
}
function insertRule(rule) {
try {
style.sheet.insertRule(rule, 0);
} catch (e) {
console.error(e);
}
}
if (typeof rules === 'string') {
insertRule(rules);
} else {
rules.forEach(insertRule);
}
if (!skip_protect) {
_protect(style);
}
return style;
}
var style = _create();
if (skip_protect) {
return style;
}
var o = new MutationObserver(function(ms){
var m, node, rule;
for (m of ms) {
for (node of m.removedNodes) {
if (node === style) {
(new Promise(function(resolve){
setTimeout(function(resolve){
resolve(_create());
}, 0, resolve);
})).then(function(st){
style = st;
});
}
}
}
});
o.observe(root, {childList:true});
return style;
}
// https://gf.qytechs.cn/scripts/19144-websuckit/
function useWSI() {
// check does browser support Proxy and WebSocket
if (typeof Proxy !== 'function' ||
typeof WebSocket !== 'function') {
return;
}
function getWrappedCode(removeSelf) {
var text = getWrappedCode.toString()+WSI.toString();
text = (
'(function(){"use strict";'+
text.replace(/\/\/[^\r\n]*/g,'').replace(/[\s\r\n]+/g,' ')+
'(new WSI(self||window)).init();'+
'})();\n'+
(removeSelf?'var s = document.currentScript; if (s) {s.parentNode.removeChild(s);}':'')
);
return text;
}
function WSI(win, safeWin) {
safeWin = safeWin || win;
var masks = [], filter;
for (filter of [// blacklist
'||10root25.website^', '||24video.xxx^',
'||adlabs.ru^', '||adspayformymortgage.win^', '||aviabay.ru^',
'||bgrndi.com^', '||brokeloy.com^',
'||cnamerutor.ru^',
'||docfilms.info^', '||dreadfula.ru^',
'||et-code.ru^',
'||film-doma.ru^',
'||free-torrent.org^', '||free-torrent.pw^',
'||free-torrents.org^', '||free-torrents.pw^',
'||game-torrent.info^', '||gocdn.ru^',
'||hdkinoshka.com^', '||hghit.com^', '||hindcine.net^',
'||kiev.ua^', '||kinotochka.net^',
'||kinott.com^', '||kinott.ru^', '||kuveres.com^',
'||lepubs.com^', '||luxadv.com^', '||luxup.ru^', '||luxupcdna.com^',
'||mail.ru^', '||marketgid.com^', '||mixadvert.com^', '||mxtads.com^',
'||nickhel.com^',
'||oconner.biz^', '||oconner.link^',
'||pkpojhc.com^',
'||psma01.com^', '||psma02.com^', '||psma03.com^',
'||recreativ.ru^', '||redtram.com^', '||regpole.com^', '||rootmedia.ws^', '||ruttwind.com^',
'||skidl.ru^',
'||torvind.com^', '||traffic-media.co^', '||trafmag.com^',
'||webadvert-gid.ru^', '||webadvertgid.ru^',
'||xxuhter.ru^',
'||yuiout.online^',
'||zoom-film.ru^'
]) {
masks.push(new RegExp(
filter.replace(/([\\\/\[\].*+?(){}$])/g, '\\$1')
.replace(/\^(?!$)/g,'\\.?[^\\w%._-]')
.replace(/\^$/,'\\.?([^\\w%._-]|$)')
.replace(/^\|\|/,'^(ws|http)s?:\\/+([^\/.]+\\.)*'),
'i'));
}
function isBlocked(url) {
for (var mask of masks) {
if (mask.test(url)) {
return true;
}
}
return false;
}
var realWebSocket = win.WebSocket;
function wsGetter (target, name) {
try {
if (typeof realWebSocket.prototype[name] === 'function') {
if (name === 'close' || name === 'send') { // send also closes connection
target.readyState = realWebSocket.CLOSED;
}
return (
function fake() {
console.log('[WSI] Invoked function "'+name+'"', '| Tracing', (new Error()));
return;
}
);
}
if (typeof realWebSocket.prototype[name] === 'number') {
return realWebSocket[name];
}
} catch(ignore) {}
return target[name];
}
function createWebSocketWrapper(target) {
return new Proxy(realWebSocket, {
construct: function (target, args) {
var url = args[0];
console.log('[WSI] Opening socket on ' + url + ' \u2026');
if (isBlocked(url)) {
console.log("[WSI] Blocked.");
return new Proxy({
url: url,
readyState: realWebSocket.OPEN
}, {
get: wsGetter
});
}
return new target(args[0], args[1]);
}
});
}
function WorkerWrapper() {
var realWorker = win.Worker;
function wrappedWorker(resourceURI) {
var isBlobURL = /^blob:/i,
xhr = null,
_callbacks = new WeakMap(),
_worker = null,
_terminate = false,
_onerror = null,
_onmessage = null,
_messages = [],
_events = [],
/*jshint validthis:true */
_self = this;
function callbackWrapper(func) {
if (typeof func !== 'function') {
return undefined;
}
return (
function callback() {
func.apply(_self, arguments);
}
);
}
_self.terminate = function(){
_terminate = true;
if (_worker) {
_worker.terminate();
}
};
Object.defineProperty(_self, 'onmessage', {
get: function() {
return _onmessage;
},
set: function(val) {
_onmessage = val;
if (_worker) {
_worker.onmessage = callbackWrapper(val);
}
}
});
Object.defineProperty(_self, 'onerror', {
get: function() {
return _onerror;
},
set: function(val) {
_onerror = val;
if (_worker) {
_worker.onerror = callbackWrapper(val);
}
}
});
_self.postMessage = function(message){
if (_worker) {
_worker.postMessage(message);
} else {
_messages.push(message);
}
};
_self.terminate = function() {
_terminate = true;
if (_worker) {
_worker.terminate();
}
};
_self.addEventListener = function(){
if (typeof arguments[1] !== 'function') {
return;
}
if (!_callbacks.has(arguments[1])) {
_callbacks.set(arguments[1], callbackWrapper(arguments[1]));
}
arguments[1] = _callbacks.get(arguments[1]);
if (_worker) {
_worker.addEventListener.apply(_worker, arguments);
} else {
_events.push(['addEventListener', arguments]);
}
};
_self.removeEventListener = function(){
if (typeof arguments[1] !== 'function' || !_callbacks.has(arguments[1])) {
return;
}
arguments[1] = _callbacks.get(arguments[1]);
_callbacks.delete(arguments[1]);
if (_worker) {
_worker.removeEventListener.apply(_worker, arguments);
} else {
_events.push(['removeEventListener', arguments]);
}
};
if (!isBlobURL.test(resourceURI)) {
_worker = new realWorker(resourceURI);
return; // not a blob, no need to wrap
}
xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
try {
xhr.open('GET', resourceURI, true);
} catch(ignore) {
_worker = new realWorker(resourceURI);
return; // failed to open connection, unable to continue wrapping procedure
}
(new Promise(function(resolve, reject){
if (xhr.readyState !== XMLHttpRequest.OPENED) {
// connection wasn't opened, unable to continue wrapping procedure
return reject();
}
xhr.onload = function(){
if (this.status === 200) {
var reader = new FileReader();
reader.addEventListener("loadend", function() {
resolve(new realWorker(URL.createObjectURL(
new Blob([getWrappedCode(false)+this.result])
)));
});
reader.readAsText(this.response);
}
};
xhr.send();
})).then(function(val) {
_worker = val;
_worker.onerror = callbackWrapper(_onerror);
_worker.onmessage = callbackWrapper(_onmessage);
var _e;
while(_events.length) {
_e = _events.shift();
_worker[_e[0]].apply(_worker, _e[1]);
}
while(_messages.length) {
_worker.postMessage(_messages.shift());
}
if (_terminate) {
_worker.terminate();
}
}).catch(function(){});
}
win.Worker = wrappedWorker.bind(safeWin);
}
function CreateElementWrapper() {
var realCreateElement = Document.prototype.createElement,
_addEventListener = Element.prototype.addEventListener,
code = encodeURIComponent('<scr'+'ipt>'+getWrappedCode(true)+'</scr'+'ipt>\n'),
isDataURL = /^data:/i,
isBlobURL = /^blob:/i;
function frameRewrite(e) {
var f = e.target,
w = f.contentWindow;
if (!f.src || (w && isBlobURL.test(f.src))) {
w.WebSocket = createWebSocketWrapper();
}
if (isDataURL.test(f.src) && f.src.indexOf(code) < 0) {
f.src = f.src.replace(',',',' + code);
}
}
var scriptMap = new WeakMap();
scriptMap.isBlocked = isBlocked;
var onErrorWrapper = {
set: function(val) {
if (scriptMap.has(this)) {
this.removeEventListener('error', scriptMap.get(this).wrp, false);
scriptMap.delete(this);
}
if (!val || typeof val !== 'function') {
return val;
}
scriptMap.set(this, {
org: val,
wrp: function() {
if (scriptMap.isBlocked(this.src)) {
console.log('[WSI] Blocked "onerror" callback from', this);
return;
}
scriptMap.get(this).org.apply(this, arguments);
}
});
this.addEventListener('error', scriptMap.get(this).wrp, false);
return val;
},
get: function() {
return scriptMap.has(this) ? scriptMap.get(this).org : null;
},
enumerable: true
};
function wrappedCreateElement(name) {
/*jshint validthis:true */
var el = realCreateElement.apply(this, arguments);
if (el.tagName === 'IFRAME') {
_addEventListener.call(el, 'load', frameRewrite, false);
}
if (el.tagName === 'SCRIPT') {
Object.defineProperty(el, 'onerror', onErrorWrapper);
}
return el;
}
Document.prototype.createElement = wrappedCreateElement;
document.addEventListener('DOMContentLoaded', function(){
for (var ifr of document.querySelectorAll('IFRAME')) {
_addEventListener.call(ifr, 'load', frameRewrite, false);
}
}, false);
}
this.init = function() {
win.WebSocket = createWebSocketWrapper();
if (!(/firefox/i.test(navigator.userAgent))) {
WorkerWrapper(); // skip WorkerWrapper in Firefox
}
if (typeof document !== 'undefined') {
CreateElementWrapper();
}
};
}
if (isFirefox) {
var script = document.createElement('script');
script.appendChild(document.createTextNode(getWrappedCode(true)));
document.head.insertBefore(script, document.head.firstChild);
return; //we don't want to call functions on page from here in Fx, so exit
}
(new WSI((unsafeWindow||self||window),(self||window))).init();
}
if (!isFirefox) { // scripts for non-Firefox browsers
// https://gf.qytechs.cn/scripts/14720-it-s-not-important
(function(){
var imptt = /((display|(margin|padding)(-top|-bottom)?)\s*:[^;!]*)!\s*important/ig;
function unimportanter(el, si) {
if (!imptt.test(si) || el.style.display === 'none') {
return 0; // get out if we have nothing to do here
}
if (el.nodeName === 'IFRAME' && el.src &&
el.src.slice(0,17) === 'chrome-extension:') {
return 0; // Web of Trust uses this method to add their frame
}
var so = si.replace(imptt, function(){return arguments[1];}), ret = 0;
if (si !== so) {
ret = 1;
_setAttribute.call(el, 'style', so);
}
return ret;
}
function logger(c) {
if (c) {
console.log('Some page elements became a bit less important.');
}
}
function checkTarget(node, cnt) {
if (!(node && node.getAttribute)) {
return 0;
}
var si = _getAttribute.call(node, 'style');
if (si && si.indexOf('!') > -1) {
cnt += unimportanter(node, si);
}
return cnt;
}
var observer = new MutationObserver(function(mutations) {
setTimeout(function(ms) {
var cnt = 0, m, node;
for (m of ms) {
cnt = checkTarget(m.target, cnt);
for (node of m.addedNodes) {
cnt += checkTarget(node, cnt);
}
}
logger(cnt);
}, 0, mutations);
});
observer.observe(document, { childList : true, attributes : true, attributeFilter : ['style'], subtree : true });
win.addEventListener ("load", function(){
var c = 0, imp;
for (imp of document.querySelectorAll('[style*="!"]')) {
c+= checkTarget(imp, c);
}
logger(c);
}, false);
})();
}
if (/^https?:\/\/(mail\.yandex\.|music\.yandex\.|news\.yandex\.|(www\.)?yandex\.[^\/]+\/(yand)?search[\/?])/i.test(win.location.href)) {
// https://gf.qytechs.cn/en/scripts/809-no-yandex-ads
(function(){
var adWords = ['Яндекс.Директ','Реклама','Ad'];
function remove(node) {
node.parentNode.removeChild(node);
}
// Generic ads removal and fixes
function removeGenericAds() {
var s, i;
s = document.querySelector('.serp-header');
if (s) {
s.style.marginTop='0';
}
for (s of document.querySelectorAll('.serp-adv__head + .serp-item, #adbanner, .serp-adv, .b-spec-adv, div[class*="serp-adv__"]:not(.serp-adv__found):not(.serp-adv__displayed)')) {
remove(s);
}
}
// Search ads
function removeSearchAds() {
var s, item, l;
for (s of document.querySelectorAll('.t-construct-adapter__legacy')) {
item = s.querySelector('.organic__subtitle');
l = window.getComputedStyle(item, ':after').content;
if (item && adWords.indexOf(l.replace(/"/g,'')) > -1) {
remove(s);
console.log('Ads removed.');
}
}
}
// Search link tracking
function disableLinkTracking() {
function removeTracking() {
for (var a of document.querySelectorAll('A[href^="http"][onmousedown]')) {
a.removeAttribute('onmousedown');
}
}
var o = new MutationObserver(function(ms) {
var m, node;
for (m of ms) {
if (m.addedNodes.length) {
removeTracking();
}
}
});
o.observe(document.body, {childList: true, subtree: true});
}
// News ads
function removeNewsAds() {
for (var s of document.querySelectorAll(
'.page-content__left > *,'+
'.page-content__right > *:not(.page-content__col),'+
'.page-content__right > .page-content__col > *'
)) {
if (s.textContent.indexOf(adWords[0]) > -1 ||
(s.clientHeight < 15 && s.classList.contains('rubric'))) {
remove(s);
console.log('Ads removed.');
}
}
}
// Music ads
function removeMusicAds() {
for (var s of document.querySelectorAll('.ads-block')) {
remove(s);
}
}
// Mail ads
function removeMailAds() {
var slice = Array.prototype.slice,
nodes = slice.call(document.querySelectorAll('.ns-view-folders')),
node, len, classes, cls;
for (node of nodes) {
if (!len || len > node.classList.length) {
len = node.classList.length;
}
}
node = nodes.pop();
while (node) {
if (node.classList.length > len) {
for (cls of slice.call(node.classList)) {
if (cls.indexOf('-') === -1) {
remove(node);
break;
}
}
}
node = nodes.pop();
}
}
// News fixes
function removePageAdsClass() {
if (document.body.classList.contains("b-page_ads_yes")){
document.body.classList.remove("b-page_ads_yes");
console.log('Page ads class removed.');
}
}
// Function to attach an observer to monitor dynamic changes on the page
function pageUpdateObserver(func, obj, params) {
if (obj) {
var o = new MutationObserver(func);
o.observe(obj,(params || {childList:true, subtree:true}));
}
}
// Cleaner
document.addEventListener ('DOMContentLoaded', function() {
removeGenericAds();
if (win.location.hostname.search(/^mail\./i) === 0) {
pageUpdateObserver(function(ms, o){
var aside = document.querySelector('.mail-Layout-Aside');
if (aside) {
o.disconnect();
pageUpdateObserver(removeMailAds, aside);
}
}, document.querySelector('BODY'));
removeMailAds();
} else if (win.location.hostname.search(/^music\./i) === 0) {
pageUpdateObserver(removeMusicAds, document.querySelector('.sidebar'));
removeMusicAds();
} else if (win.location.hostname.search(/^news\./i) === 0) {
pageUpdateObserver(removeNewsAds, document.querySelector('BODY'));
pageUpdateObserver(removePageAdsClass, document.body, {attributes:true, attributesFilter:['class']});
removeNewsAds();
removePageAdsClass();
} else {
pageUpdateObserver(removeSearchAds, document.querySelector('.main__content'));
removeSearchAds();
disableLinkTracking();
}
});
})();
return; //skip fixes for other sites
}
// https://gf.qytechs.cn/en/scripts/21937-moonwalk-hdgo-kodik-fix v0.8 (adapted)
document.addEventListener ('DOMContentLoaded', function() {
var tmp;
function log (e) {
console.log('Moonwalk&HDGo&Kodik FIX: ' + e + ' player in ' + win.location.href);
}
if (win.adv_enabled !== undefined && win.condition_detected !== undefined) { // moonwalk
log('Moonwalk');
if (win.adv_enabled) {
win.adv_enabled = false;
}
win.condition_detected = false;
if (win.MXoverrollCallback) {
document.addEventListener('click', function catcher(e){
e.stopPropagation();
win.MXoverrollCallback.call(window);
document.removeEventListener('click', catcher, true);
}, true);
}
} else if (win.stat_url !== undefined && win.is_html5 !== undefined && win.is_wp8 !== undefined) { // hdgo
log('HDGo');
document.body.onclick = null;
tmp = document.querySelector('#swtf');
if (tmp) {
tmp.style.display = 'none';
}
if (win.banner_second !== undefined) {
win.banner_second = 0;
}
if (win.$banner_ads !== undefined) {
win.$banner_ads = false;
}
if (win.$new_ads !== undefined) {
win.$new_ads = false;
}
if (win.createCookie !== undefined) {
win.createCookie('popup','true','999');
}
if (win.canRunAds !== undefined && win.canRunAds !== true) {
win.canRunAds = true;
}
} else if (win.MXoverrollCallback && win.iframeSearch !== undefined) { // kodik
log('Kodik');
tmp = document.querySelector('.play_button');
if (tmp) {
tmp.onclick = win.MXoverrollCallback.bind(window);
}
win.IsAdBlock = false;
}
}, false);
// Automated protection against specific circumvention method based on unwrapping various functions,
// hiding ads in the Shadow DOM and injecting iFrames with ads. Previously this code were known as
// apiBreaker since it were breaking Shadow DOM and onerror/onload API on specific domains. This
// version should be safe enough to run on majority of sites without actually breaking them.
function shadowBlocker(){
var blacklist = new WeakMap(),
replacer, func;
/* Wrap functions used to attach shadow root to a node */
replacer = function (func) {
return function() {
blacklist.set(this, true);
return func.apply(this, arguments);
};
};
for (func of ['createShadowRoot', 'attachShadow']) {
if (func in Element.prototype) {
Element.prototype[func] = replacer(Element.prototype[func]);
}
}
/* Wrap functions used to insert/append elements to check for IFRAME objects */
replacer = function (func) {
return function(el, par) {
if (el.tagName === 'IFRAME' &&
((typeof par === 'object' && blacklist.get(par))/* ||
el.style.display === 'none'*/)) {
console.log('Blocked suspicious', func.name, arguments);
return null;
}
return func.apply(this, arguments);
};
};
for (func of [/*'appendChild', */'insertBefore']) {
Object.defineProperty(Element.prototype, func, {
value: replacer(Element.prototype[func]), enumerable: true
});
}
}
scriptLander(shadowBlocker);
// === Helper functions ===
// function to search and remove nodes by content
// selector - standard CSS selector to define set of nodes to check
// words - regular expression to check content of the suspicious nodes
// params - object with multiple extra parameters:
// .hide - set display to none instead of removing from the page
// .parent - parent node to remove if content is found in the child node
// .siblings - number of simling nodes to remove (excluding text nodes)
function scRemove(e) {e.parentNode.removeChild(e);}
function scHide(e) {
var s = _getAttribute.call(e, 'style') || '',
h = ';display:none!important;';
if (s.indexOf(h) < 0) {
_setAttribute.call(e, 'style', s+h);
}
}
function scissors (selector, words, scope, params) {
var remFunc = (params.hide ? scHide : scRemove),
iterFunc = (params.siblings > 0 ?
'nextSibling' :
'previousSibling'),
toRemove = [],
siblings,
node;
for (node of scope.querySelectorAll(selector)) {
if (params.parent) {
while(node !== scope && !(node.matches(params.parent))) {
node = node.parentNode;
}
}
if (words.test(node.innerHTML) || !node.childNodes.length) {
// drill up to the specified parent node if required
if (node === scope) {
break;
}
toRemove.push(node);
// add multiple nodes if defined more than one sibling
siblings = Math.abs(params.siblings) || 0;
while (siblings) {
node = node[iterFunc];
toRemove.push(node);
if (node.nodeType === Node.ELEMENT_NODE) {
siblings -= 1; //count only element nodes
}
}
}
}
for (node of toRemove) {
remFunc(node);
}
return toRemove.length;
}
// function to perform multiple checks if ads inserted with a delay
// by default does 30 checks withing a 3 seconds unless nonstop mode specified
// also does 1 extra check when a page completely loads
// selector and words - passed dow to scissors
// params - object with multiple extra parameters:
// .root - selector to narrow down scope to scan;
// .observe - if true then check will be performed continuously;
// Other parameters passed down to scissors.
function gardener(selector, words, params) {
params = params || {};
var scope = document,
nonstop = false;
// narrow down scope to a specific element
if (params.root) {
scope = scope.querySelector(params.root);
if (!scope) {// exit if the root element is not present on the page
return 0;
}
}
// add observe mode if required
if (params.observe) {
if (typeof MutationObserver === 'function') {
var o = new MutationObserver(function(ms){
for (var m of ms) {
if (m.addedNodes.length) {
scissors(selector, words, scope, params);
}
}
});
o.observe(scope, {childList:true, subtree: true});
} else {
nonstop = true;
}
}
// wait for a full page load to do one extra cut
win.addEventListener('load',function(){
scissors(selector, words, scope, params);
});
// do multiple cuts until ads removed
function cut(sci, s, w, sc, p, i) {
if (i > 0) {
i -= 1;
}
if (i && !sci(s, w, sc, p)) {
setTimeout(cut, 100, sci, s, w, sc, p, i);
}
}
cut(scissors, selector, words, scope, params, (nonstop ? -1 : 30));
}
// Helper function to close background tab if site opens itself in a new tab and then
// loads a 3rd-party page in the background one (thus performing background redirect).
function preventBackgroundRedirect() {
// create "cose_me" event to call high-level window.close()
var key = Math.random().toString(36).substr(2);
window.addEventListener('close_me_'+key, function(e) {
window.close();
});
// window.open wrapper
function pbrLander() {
var orgOpen = window.open.bind(window),
idx = String.prototype.indexOf,
event = new CustomEvent("close_me_%key%", {});
function closeWindow(){
// site went to a new tab and attempts to unload
// call for high-level close through event
window.dispatchEvent(event);
}
// window.open wrapper
function open(){
console.log(arguments, window.location.host);
if (arguments[0] &&
(idx.call(arguments[0], window.location.host) > -1 ||
idx.call(arguments[0], '://') === -1)) {
window.addEventListener('unload', closeWindow, true);
}
orgOpen.apply(window, arguments);
}
window.open = open.bind(window);
// Node.createElement wrapper to prevent click-dispatch in Google Chrome and similar browsers
var realCreateElement = Document.prototype.createElement;
function wrappedCreateElement(name) {
/*jshint validthis:true */
var el = realCreateElement.apply(this, arguments);
if (el.tagName === 'A') {
el.addEventListener('click', function(e){
if (!e.target.parentNode || !e.isTrusted) {
window.addEventListener('unload', closeWindow, true);
}
}, false);
}
return el;
}
Document.prototype.createElement = wrappedCreateElement;
}
// land wrapper on the page
var script = document.createElement('script');
script.appendChild(document.createTextNode('('+pbrLander.toString().replace(/%key%/g,key)+')();'));
document.head.insertBefore(script, document.head.firstChild);
script.parentNode.removeChild(script);
console.log("Background redirect prevention enabled.");
}
// Function to catch and block various methods to open a new window with 3rd-party content.
// Some advertisement networks went way past simple window.open call to circumvent default popup protection.
// This funciton blocks window.open, ability to restore original window.open from an IFRAME object,
// ability to perform an untrusted (not initiated by user) click on a link, click on a link without a parent
// node or simply a link with piece of javascript code in the HREF attribute.
function preventPopups() {
function open(){
console.log('Site attempted to open a new window', arguments);
function nil(){}
return {
document: {
write: nil,
writeln: nil
}
};
}
win.open = exportFunction(open, win);
function wrapFunctions() {
var realCreateElement = Document.prototype.createElement,
realAppendChild = Element.prototype.appendChild;
Document.prototype.createElement = function createElement(name) {
/*jshint validthis:true */
var el = realCreateElement.apply(this, arguments);
if (el.tagName === 'A') {
el.addEventListener('click', function(e) {
if (!e.target.parentNode || !e.isTrusted ||
(e.target.href && e.target.href.toLowerCase().indexOf('javascript') > -1)) {
e.preventDefault();
console.log('Blocked suspicious click event', e, 'on', e.target);
}
}, false);
}
if (el.tagName === 'IFRAME') {
el.addEventListener('load', function(){
try {
this.contentWindow.open = open;
} catch(ignore) {}
}, false);
}
return el;
};
Element.prototype.appendChild = function appendChild() {
var child = realAppendChild.apply(this, arguments);
if (child && child.nodeType === Node.ELEMENT_NODE && child.tagName === 'IFRAME') {
try {
child.contentWindow.open = open;
} catch(ignore) {}
}
return child;
};
}
if (!isFirefox) {
wrapFunctions();
} else {
var s = document.createElement('script');
s.textContent = open.toString()+'!'+wrapFunctions.toString()+'();';
document.documentElement.appendChild(s);
document.documentElement.removeChild(s);
}
}
// Currently unused piece of code developed to prevent site from registering serviceWorker
// and uninstall any existing instances of serivceWorker in case there is one already.
/* Commented out since not used
function forbidServiceWorker() {
if (!("serviceWorker" in navigator)) {
return;
}
var svr = navigator.serviceWorker.ready;
Object.defineProperty(navigator, 'serviceWorker', {
value: {
register: function(){
console.log('Registration of serviceWorker ' + arguments[0] + ' blocked.');
return new Promise(function(){});
},
ready: new Promise(function(){}),
addEventListener:function(){}
}
});
document.addEventListener('DOMContentLoaded', function() {
if (!svr) {
return;
}
svr.then(function(sw) {
console.log('Found existing serviceWorker:', sw);
console.log('Attempting to unregister...');
sw.unregister().then(function() {
console.log('Unregistered! :)');
}).catch(function(err) {
console.log('Unregistration failed. :(', err);
console.log('Try to remove it manually:');
console.log(' 1. Open: chrome://serviceworker-internals/ (Google Chrome and alike) or about:serviceworkers (Mozilla Firefox) in a new tab.');
console.log(' 2. Search there for one with "'+document.domain+'" in the name.');
console.log(' 3. Use buttons in the same block with service you found to stop it and uninstall/unregister.');
});
}).catch(function(err) {
console.log("Lol, it failed on it's own. -_-", err);
});
}, false);
}
/**/
// Currently obsolete code developed to prevent error and load calls on objects supposed to load resources
// from the internet like IMG or IFRAME, but missing SRC/HREF attribute. Usually tricks like this are used
// to unwrap wrapped functions to be able to load ads.
/* Commented out since not used
function errorAndLoadEventsFilter() {
var toString = Function.prototype.toString,
addEventListener = Element.prototype.addEventListener,
removeEventListener = Element.prototype.removeEventListener,
hasAttribute = Element.prototype.hasAttribute,
evtMap = new WeakMap();
Element.prototype.addEventListener = function(evt, func, capt) {
if (evt === 'error' || evt === 'load') {
if (!evtMap.get(func)) {
evtMap.set(func, function() {
if (hasAttribute.call(this, 'src') ||
hasAttribute.call(this, 'href')) {
func.apply(this, arguments);
} else {
console.log('Blocked', evt, 'handler', toString.call(func), 'on', this);
}
});
}
}
addEventListener.call(this, evt, (evtMap.get(func) || func), capt);
};
Element.prototype.removeEventListener = function(evt, func, capt) {
removeEventListener.call(this, evt, (evtMap.get(func) || func), capt);
};
Object.defineProperty(HTMLElement.prototype, 'onload', {
set: function(func) {
if(evtMap.has(this)) {
if (evtMap.get(this).onload) {
Element.prototype.removeEventListener.call(this, 'load', evtMap.get(this).onload, false);
}
evtMap.get(this).onload = func;
} else {
evtMap.set(this, { onload: func });
}
if (func) {
Element.prototype.addEventListener.call(this, 'load', func, false);
}
return func;
},
get: function() {
return evtMap.has(this) ? evtMap.get(this).onload : null;
}
});
Object.defineProperty(HTMLElement.prototype, 'onerror', {
set: function(func) {
if (evtMap.has(this)) {
evtMap.get(this).onerror = func;
} else {
evtMap.set(this, { onerror: func });
}
if (func) {
console.log('Blocked error handler', toString.call(func), 'on', this);
}
return func;
},
get: function() {
return evtMap.has(this) ? evtMap.get(this).onerror : null;
}
});
}
/**/
function scriptLander(func, prepend) {
if (!isFirefox) {
func();
return;
}
var s = document.createElement('script');
s.textContent = '(function(){' + (
prepend && prepend.join('') || ''
) + '!' + func + '();})();';
document.documentElement.appendChild(s);
document.documentElement.removeChild(s);
}
// === Scripts for specific domains ===
var scripts = {};
// prevent popups and redirects block
var preventPopupsNow = { 'now': preventPopups },
preventBackgroundRedirectNow = { 'now': preventBackgroundRedirect };
// Popups
scripts['biqle.ru'] = preventPopupsNow;
scripts['chaturbate.com'] = preventPopupsNow;
scripts['dfiles.ru'] = preventPopupsNow;
scripts['hentaiz.org'] = preventPopupsNow;
scripts['mirrorcreator.com'] = preventPopupsNow;
scripts['online-multy.ru'] = preventPopupsNow;
scripts['openload.co'] = preventPopupsNow;
scripts['radikal.ru'] = preventPopupsNow;
scripts['seedoff.cc'] = preventPopupsNow;
scripts['tapochek.net'] = preventPopupsNow;
scripts['thepiratebay.org'] = preventPopupsNow;
scripts['torseed.net'] = preventPopupsNow;
scripts['zippyshare.com'] = preventPopupsNow;
// Background redirects
scripts['mediafire.com'] = preventBackgroundRedirectNow;
scripts['megapeer.org'] = preventBackgroundRedirectNow;
scripts['megapeer.ru'] = preventBackgroundRedirectNow;
scripts['perfectgirls.net'] = preventBackgroundRedirectNow;
scripts['turbobit.net'] = preventBackgroundRedirectNow;
// other
scripts['4pda.ru'] = {
'now': function() {
// https://gf.qytechs.cn/en/scripts/14470-4pda-unbrender
var isForum = document.location.href.search('/forum/') !== -1,
hStyle;
function remove(n) {
if (n) {
n.parentNode.removeChild(n);
}
}
function afterClean() {
hStyle.disabled = true;
remove(hStyle);
}
function beforeClean() {
// attach styles before document displayed
hStyle = createStyle([
'html { overflow-y: scroll }',
'section[id] {'+(
'position: absolute;'+
'width: 100%'
)+'}',
'article + aside * { display: none !important }',
'#header + div:after {'+(
'content: "";'+
'position: fixed;'+
'top: 0;'+
'left: 0;'+
'width: 100%;'+
'height: 100%;'+
'background-color: #E6E7E9'
)+'}',
// http://codepen.io/Beaugust/pen/DByiE
'@keyframes spin { 100% { transform: rotate(360deg) } }',
'article + aside:after {'+(
'content: "";'+
'position: absolute;'+
'width: 150px;'+
'height: 150px;'+
'top: 150px;'+
'left: 50%;'+
'margin-top: -75px;'+
'margin-left: -75px;'+
'box-sizing: border-box;'+
'border-radius: 100%;'+
'border: 10px solid rgba(0, 0, 0, 0.2);'+
'border-top-color: rgba(0, 0, 0, 0.6);'+
'animation: spin 2s infinite linear'
)+'}'
], {id:'ubrHider'}, true);
// display content of a page if time to load a page is more than 2 seconds to avoid
// blocking access to a page if it is loading for too long or stuck in a loading state
setTimeout(2000, afterClean);
}
createStyle([
'#nav .use-ad { display: block !important }',
'article:not(.post) + article:not(#id), a[target="_blank"] img[height="90"] { display: none !important }'
]);
if (!isForum) {
beforeClean();
}
// save links to non-overridden functions to use later
var protectedElems;
// protect/hide changed attributes in case site attempt to restore them
function styleProtector(eventMode) {
var oRAN = Element.prototype.removeAttributeNode,
isStyleText = function(t){ return t === 'style'; },
isStyleAttr = function(a){ return a instanceof Attr && a.nodeName === 'style'; },
returnUndefined = function(){},
protectedElems = new WeakMap();
function protoOverride(element, functionName, isStyleCheck, returnIfProtected) {
var oF = element.prototype[functionName], r;
element.prototype[functionName] = function() {
if (protectedElems.has(this) && isStyleCheck(arguments[0])) {
return returnIfProtected(this, arguments);
}
r = oF.apply(this, arguments);
return r;
};
}
protoOverride(Element, 'removeAttribute', isStyleText, returnUndefined);
protoOverride(Element, 'hasAttribute', isStyleText, function(_this) {
return protectedElems.get(_this) !== null;
});
protoOverride(Element, 'setAttribute', isStyleText, function(_this, args) {
protectedElems.set(_this, args[1]);
});
protoOverride(Element, 'getAttribute', isStyleText, function(_this) {
return protectedElems.get(_this);
});
if (eventMode) {
var e = document.createEvent('Event');
e.initEvent('protoOverride', false, false);
window.protectedElems = protectedElems;
window.dispatchEvent(e);
} else {
return protectedElems;
}
}
if (isFirefox) {
var s = document.createElement('script');
s.textContent = '(' + styleProtector.toString() + ')(true);';
window.addEventListener('protoOverride', function protoOverrideCallback(e){
if (win.protectedElems) {
protectedElems = win.protectedElems;
delete win.protectedElems;
}
document.removeEventListener('protoOverride', protoOverrideCallback, true);
}, true);
document.documentElement.appendChild(s);
document.documentElement.removeChild(s);
} else {
protectedElems = styleProtector(false);
}
// clean a page
window.addEventListener('DOMContentLoaded', function(){
var rem, si, itm;
function width(){ return window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth||0; }
function height(){ return window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight||0; }
if (isForum) {
si = document.querySelector('#logostrip');
if (si) {
remove(si.parentNode.nextSibling);
}
}
if (document.location.href.search('/forum/dl/') !== -1) {
document.body.setAttribute('style', (document.body.getAttribute('style')||'')+
';background-color:black!important');
for (itm of document.querySelectorAll('body>div')) {
if (!itm.querySelector('.dw-fdwlink')) {
remove(itm);
}
}
}
if (isForum) { // Do not continue if it's a forum
return;
}
si = document.querySelector('#header');
if (si) {
rem = si.previousSibling;
while (rem) {
si = rem.previousSibling;
remove(rem);
rem = si;
}
}
for (itm of document.querySelectorAll('#nav li[class]')) {
if (itm && itm.querySelector('a[href^="/tag/"]')) {
remove(itm);
}
}
var style, result;
for (itm of document.querySelectorAll('DIV, A')) {
if (itm.tagName ==='DIV' && itm.offsetWidth > 0.95 * width() && itm.offsetHeight > 0.85 * height()) {
style = window.getComputedStyle(itm, null);
result = [];
if (style.backgroundImage !== 'none') {
result.push('background-image:none!important');
}
if (style.backgroundColor !== 'transparent' &&
style.backgroundColor !== 'rgba(0, 0, 0, 0)') {
result.push('background-color:transparent!important');
}
if (result.length) {
if (itm.getAttribute('style')) {
result.unshift(itm.getAttribute('style'));
}
(function(){
var fakeStyle = {
'backgroundImage': itm.style.backgroundImage,
'backgroundColor': itm.style.backgroundColor
};
try {
Object.defineProperty(itm, 'style', {
value: new Proxy(itm.style, {
get: function(target, prop){
if (fakeStyle.hasOwnProperty(prop)) {
return fakeStyle[prop];
} else {
return target[prop];
}
},
set: function(target, prop, value){
if (fakeStyle.hasOwnProperty(prop)) {
fakeStyle[prop] = value;
} else {
target[prop] = value;
}
return value;
}
}),
enumerable: true
});
} catch (e) {
console.log('Unable to protect style property.', e);
}
})();
if (protectedElems) {
protectedElems.set(itm, _getAttribute.call(itm, 'style'));
}
_setAttribute.call(itm, 'style', result.join(';'));
}
}
if (itm.tagName ==='A' && (itm.offsetWidth > 0.95 * width() || itm.offsetHeight > 0.85 * height())) {
if (protectedElems) {
protectedElems.set(itm, _getAttribute.call(itm, 'style'));
}
_setAttribute.call(itm, 'style', 'display:none!important');
}
}
for (itm of document.querySelectorAll('ASIDE>DIV')) {
if ( ((itm.querySelector('script, iframe, a[href*="/ad/www/"]') ||
itm.querySelector('img[src$=".gif"]:not([height="0"]), img[height="400"]')) &&
!itm.classList.contains('post') ) || !itm.childNodes.length ) {
remove(itm);
}
}
document.body.setAttribute('style', (document.body.getAttribute('style')||'')+';background-color:#E6E7E9!important');
// display content of the page
afterClean();
});
}
};
scripts['allmovie.pro'] = function() {
// pretend to be Android to make site use different played for ads
if (isSafari) {
return;
}
Object.defineProperty(navigator, 'userAgent', {
get: function(){ return 'Mozilla/5.0 (Linux; Android 4.1.1; Nexus 7 Build/JRO03D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19'; },
enumerable: true
});
};
scripts['rufilmtv.org'] = scripts['allmovie.pro'];
scripts['anidub-online.ru'] = function() {
var script = document.createElement('script');
script.type = "text/javascript";
script.innerHTML = "function ogonekstart1() {}";
document.getElementsByTagName('head')[0].appendChild(script);
var style = document.createElement('style');
style.type = 'text/css';
style.appendChild(document.createTextNode('.background {background: none!important;}'));
style.appendChild(document.createTextNode('.background > script + div, .background > script ~ div:not([id]):not([class]) + div[id][class] {display:none!important}'));
document.head.appendChild(style);
};
scripts['online.anidub.com'] = scripts['anidub-online.ru'];
scripts['fs.to'] = function() {
function skipClicker(i) {
if (!i) {
return;
}
var skip = document.querySelector('.b-aplayer-banners__close');
if (skip) {
skip.click();
} else {
setTimeout(skipClicker, 100, i-1);
}
}
setTimeout(skipClicker, 100, 30);
createStyle([
'.l-body-branding *,'+
'.b-styled__item-central,'+
'.b-styled__content-right,'+
'.b-styled__section-central,'+
'div[id^="adsProxy-"]'+
'{display:none!important}',
'body {background-image:url(data:image/png;base64,'+
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACX'+
'BIWXMAAC4jAAAuIwF4pT92AAAADUlEQVR42mOQUdL5DwACMgFq'+
'BC3ttwAAAABJRU5ErkJggg==)!important}'
]);
if (/\/(view_iframe|iframeplayer)\//i.test(document.location.pathname)) {
var p = document.querySelector('#player:not([preload="auto"])'),
m = document.querySelector('.main'),
adStepper = function(p) {
if (p.currentTime < p.duration) {
p.currentTime += 1;
}
},
adSkipper = function(f, p) {
f.click();
p.waitAfterSkip = false;
p.longerSkipper = false;
console.log('Пропустили.');
},
cl = function(p) {
var faster = document.querySelector('.b-aplayer__html5-desktop-skip'),
series = document.querySelector('.b-aplayer__actions-series');
function clickSelected() {
var s = document.querySelector('.b-aplayer__popup-series-episodes .selected a');
if (s) {
s.click();
}
}
if ((!faster || faster.style.display !== 'block') && series && !p.seriesClicked) {
series.click();
p.seriesClicked = true;
p.longerSkipper = true;
setTimeout(clickSelected, 1000);
p.pause();
}
function skipListener() {
if (p.waitAfterSkip) {
console.log('В процессе пропуска…');
return;
}
p.pause();
if (!p.classList.contains('m-hidden')) {
p.classList.add('m-hidden');
}
if (faster && p.currentTime &&
win.getComputedStyle(faster).display === 'block' &&
!faster.querySelector('.b-aplayer__html5-desktop-skip-timer')) {
p.waitAfterSkip = true;
setTimeout(adSkipper, (p.longerSkipper?3:1)*1000, faster, p);
console.log('Доступен быстрый пропуск…');
} else {
setTimeout(adStepper, 1000, p);
}
}
p.addEventListener('timeupdate', skipListener, false);
},
o = new MutationObserver(function (ms) {
var m, node;
for (m of ms) {
for (node of m.addedNodes) {
if (node.id === 'player' &&
node.nodeName === 'VIDEO' &&
_getAttribute.call(node, 'preload') !== 'auto') {
cl(node);
}
}
}
});
if (p.nodeName === 'VIDEO') {
cl(p);
} else {
o.observe(m, {childList: true});
}
}
};
scripts['brb.to'] = scripts['fs.to'];
scripts['cxz.to'] = scripts['fs.to'];
scripts['drive2.ru'] = function() {
gardener('.c-block:not([data-metrika="recomm"]),.o-grid__item', />Реклама<\//i);
};
scripts['fishki.net'] = function() {
gardener('.drag_list > .drag_element, .list-view > .paddingtop15, .post-wrap', /543769|Новости партнеров/);
};
scripts['gidonline.club'] = {
'now': function() {
createStyle('.tray > div[style] {display: none!important}');
}
};
scripts['gidonlinekino.com'] = scripts['gidonline.club'];
scripts['hdgo.cc'] = {
'now': function(){
var o = new MutationObserver(function(ms) {
var m, node;
for (m of ms) {
for (node of m.addedNodes) {
if (node.tagName === 'SCRIPT' && _getAttribute(node, 'onerror') !== null) {
node.removeAttribute('onerror');
}
}
}
});
o.observe(document, {childList:true, subtree: true});
}
};
scripts['couber.be'] = scripts['hdgo.cc'];
scripts['46.30.43.38'] = scripts['hdgo.cc'];
scripts['gismeteo.ru'] = {
'DOMContentLoaded': function() {
gardener('div > a[target^="_"]', /Яндекс\.Директ/i, { root: 'body', observe: true, parent: 'div[class*="frame"]' });
}
};
scripts['hdrezka.me'] = {
'now': function() {
Object.defineProperty(win, 'fuckAdBlock', {
value: {
onDetected: function() {
console.log('Pretending to be an ABP detector.');
}
}
});
Object.defineProperty(win, 'ab', {
value: false,
enumerable: true
});
},
'DOMContentLoaded': function() {
gardener('div[id][onclick][onmouseup][onmousedown]', /onmouseout/i);
}
};
scripts['imageban.ru'] = {
'now': preventBackgroundRedirect,
'DOMContentLoaded': function() {
win.addEventListener('unload', function() {
if (!window.location.hash) {
window.location.replace(window.location+'#');
} else {
window.location.hash = '';
}
}, true);
}
};
scripts['e.mail.ru'] = function() {
gardener('#LEGO :not([data-mnemo])>.js-href[data-id]',
/data:image.*>Реклама<|>Реклама<.*\/\/favicon\./i,
{root:'#LEGO', observe: true, parent:'div[id][class]'});
};
scripts['megogo.net'] = {
'now': function() {
Object.defineProperty(win, "adBlock", {
value : false,
enumerable : true
});
Object.defineProperty(win, "showAdBlockMessage", {
value : function () {},
enumerable : true
});
}
};
scripts['naruto-base.su'] = function() {
gardener('div[id^="entryID"],.block', /href="http.*?target="_blank"/i);
};
scripts['overclockers.ru'] = {
'now': function() {
createStyle('.fixoldhtml {display:block!important}');
if (!isChrome && !isOpera) {
return; // Looks like my code works only in Chrome-like browsers
}
var noContentYet = true;
function jWrap() {
var _$ = win.$, _e = _$.extend;
win.$ = function() {
var _ret = _$.apply(window, arguments);
if (_ret[0] === document.body) {
_ret.html = function() {
console.log('Anti-adblock prevented.');
};
}
return _ret;
};
win.$.extend = function() {
return _e.apply(_$, arguments);
};
win.jQuery = win.$;
}
(function jReady() {
if (!win.$ && noContentYet) {
setTimeout(jReady, 0);
} else {
jWrap();
}
})();
document.addEventListener ('DOMContentLoaded', function(){
noContentYet = false;
}, false);
}
};
scripts['forums.overclockers.ru'] = {
'now': function() {
createStyle('.needblock {position: fixed; left: -10000px}');
Object.defineProperty(win, 'adblck', {
value: 'no',
enumerable: true
});
}
};
scripts['pb.wtf'] = function() {
createStyle('.reques,#result,tbody.row1:not([id]) {display: none !important}');
// image in the slider in the header
gardener('a[href$="=="]', /img/i, {root:'.release-navbar', observe:true, parent:'div'});
// ads in blocks on the page
gardener('a[href^="/"]', /<img\s.*<br>/i, {root:'#main_content', observe:true, parent:'div[class]'});
// line above topic content
gardener('.re_top1', /./, {root:'#main_content', parent:'.hidden-sm'});
};
scripts['piratbit.org'] = scripts['pb.wtf'];
scripts['piratbit.ru'] = scripts['pb.wtf'];
scripts['pikabu.ru'] = function() {
gardener('.story', /story__sponsor|story__gag|profile\/ads"/i, {root: '.inner_wrap', observe: true});
};
scripts['rp5.ru'] = function() {
createStyle('#bannerBottom {display: none!important}');
var co = document.querySelector('#content'), i, nodes;
if (!co) {
return;
}
nodes = co.parentNode.childNodes;
i = nodes.length;
while (i--) {
if (nodes[i] !== co) {
nodes[i].parentNode.removeChild(nodes[i]);
}
}
};
scripts['rp5.by'] = scripts['rp5.ru'];
scripts['rp5.ua'] = scripts['rp5.ru'];
scripts['rustorka.com'] = {
'now': function() {
createStyle('.header > div:not(.head-block) a, #sidebar1 img, #logo img {opacity:0!important}', {
id: 'tempHidingStyles'
}, true);
preventPopups();
},
'DOMContentLoaded': function() {
for (var o of document.querySelectorAll('IMG, A')) {
if ((o.clientWidth === 728 && o.clientHeight === 90) ||
(o.clientWidth === 300 && o.clientHeight === 250)) {
while (o && o.tagName !== 'A') {
o = o.parentNode;
}
if (o) {
_setAttribute.call(o, 'style', 'display: none !important');
}
}
}
var s = document.querySelector('#tempHidingStyles');
s.parentNode.removeChild(s);
}
};
scripts['rumedia.ws'] = scripts['rustorka.com'];
scripts['sport-express.ru'] = function() {
gardener('.js-relap__item',/>Реклама\s+<\//, {root:'.container', observe: true});
};
scripts['sports.ru'] = function() {
gardener('.aside-news-list__item', /aside-news-list__advert/i, {root:'.columns-layout__left', observe: true});
gardener('.material-list__item', /Реклама/i, {root:'.columns-layout', observe: true});
// extra functionality: shows/hides panel at the top depending on scroll direction
createStyle([
'.user-panel__fixed { transition: top 0.2s ease-in-out!important; }',
'.user-panel-up { top: -40px!important }'
], {id: 'userPanelSlide'}, false);
(function lookForPanel() {
var panel = document.querySelector('.user-panel__fixed');
if (!panel) {
setTimeout(lookForPanel, 100);
} else {
window.addEventListener('wheel', function(e){
if (e.deltaY > 0 && !panel.classList.contains('user-panel-up')) {
panel.classList.add('user-panel-up');
} else
if (e.deltaY < 0 && panel.classList.contains('user-panel-up')) {
panel.classList.remove('user-panel-up');
}
}, false);
}
})();
};
scripts['www.ukr.net'] = scripts['sinoptik.com.ru'];
scripts['vk.com'] = function() {
gardener('div[data-post-id]', /wall_marked_as_ads/, {root: '#page_wall_posts', observe: true});
};
scripts['yap.ru'] = function() {
var words = /member1438|Administration|\/go\/?.*yplkl\.php/;
gardener('form > table[id^="p_row_"]:nth-of-type(2)', words);
gardener('tr > .holder.newsbottom', words, {parent:'tr', siblings:-2});
};
scripts['yaplakal.com'] = scripts['yap.ru'];
scripts['rambler.ru'] = {
'now': function() {
function createElementWrapper() {
var _createElement = Document.prototype.createElement,
loadMap = new WeakMap();
function wrappedCreateElement(name) {
/*jshint validthis:true */
var el = _createElement.apply(this, arguments);
if (el.tagName === 'LINK') {
Object.defineProperty(el, 'onload', {
get: function() {
return loadMap.get(loadMap.get(this));
},
set: function(func) {
var wrap = loadMap.get(this);
if (wrap) {
this.removeEventListener('load', wrap, false);
loadMap.remove(wrap);
loadMap.remove(this);
}
wrap = function(e) {
if (e.target && e.target.sheet && e.target.sheet.cssRules &&
e.target.sheet.cssRules[0] && e.target.sheet.cssRules[0].cssText &&
/\{\s*content\s*:\s*"[^"]+"/i.test(e.target.sheet.cssRules[0].cssText)) {
console.log('Blocked "onload" for', e.target.href);
return false;
}
return func.apply(this, arguments);
};
loadMap.set(this, wrap);
loadMap.set(wrap, func);
this.addEventListener('load', wrap, false);
},
enumberable: true
});
}
return el;
}
Document.prototype.createElement = wrappedCreateElement;
}
scriptLander(createElementWrapper);
}
};
scripts['reactor.cc'] = {
'now': function() {
win.open = (function(){ throw new Error('Redirect prevention.'); }).bind(window);
},
'click': function(e) {
var node = e.target;
if (node.nodeType === Node.ELEMENT_NODE &&
node.style.position === 'absolute' &&
node.style.zIndex > 0)
node.parentNode.removeChild(node);
},
'DOMContentLoaded': function() {
var words = new RegExp(
'блокировщика рекламы'
.split('')
.map(function(e){return e+'[\u200b\u200c\u200d]*';})
.join('')
.replace(' ', '\\s*')
.replace(/[аоре]/g, function(e){return ['[аa]','[оo]','[рp]','[еe]']['аоре'.indexOf(e)];}),
'i'),
can;
function deeper(spider) {
var c, l, n;
if (words.test(spider.innerText)) {
if (spider.nodeType === Node.TEXT_NODE) {
return true;
}
c = spider.childNodes;
l = c.length;
n = 0;
while(l--) {
if (deeper(c[l]), can) {
n++;
}
}
if (n > 0 && n === c.length && spider.offsetHeight < 750) {
can.push(spider);
}
return false;
}
return true;
}
function probe(){
if (words.test(document.body.innerText)) {
can = [];
deeper(document.body);
var i = can.length, j, spider;
while(i--) {
spider = can[i];
if (spider.offsetHeight > 10 && spider.offsetHeight < 750) {
_setAttribute.call(spider, 'style', 'background:none!important');
}
}
}
}
var o = new MutationObserver(probe);
o.observe(document,{childList:true, subtree:true});
}
};
scripts['joyreactor.cc'] = scripts['reactor.cc'];
scripts['pornreactor.cc'] = scripts['reactor.cc'];
scripts['auto.ru'] = function() {
var words = /Реклама|Яндекс.Директ|yandex_ad_/;
var userAdsListAds = [
'.listing-list > .listing-item',
'.listing-item_type_fixed.listing-item'
];
var catalogAds = [
'div[class*="layout_catalog-inline"]',
'div[class$="layout_horizontal"]'
];
var otherAds = [
'.advt_auto',
'.sidebar-block',
'.pager-listing + div[class]',
'.card > div[class][style]',
'.sidebar > div[class]',
'.main-page__section + div[class]',
'.listing > tbody'];
gardener(userAdsListAds.join(','), words, {root:'.listing-wrap', observe:true});
gardener(catalogAds.join(','), words, {root:'.catalog__page,.content__wrapper', observe:true});
gardener(otherAds.join(','), words);
};
scripts['rsload.net'] = {
'load': function() {
var dis = document.querySelector('label[class*="cb-disable"]');
if (dis) {
dis.click();
}
},
'click': function(e) {
var t = e.target;
if (t && t.href && (/:\/\/\d+\.\d+\.\d+\.\d+\//.test(t.href))) {
t.href = t.href.replace('://','://rsload.net:rsload.net@');
}
}
};
var domain = document.domain, name;
while (domain.indexOf('.') !== -1) {
if (scripts.hasOwnProperty(domain)) {
if (typeof scripts[domain] === 'function') {
document.addEventListener ('DOMContentLoaded', scripts[domain], false);
}
for (name in scripts[domain]) {
if (name !== 'now') {
(name === 'load' ? window : document)
.addEventListener (name, scripts[domain][name], false);
} else {
scripts[domain][name]();
}
}
}
domain = domain.slice(domain.indexOf('.') + 1);
}
})();