Anti-AdBlocker Fuckoff

Protects & Remove Anti-AdBlockers modal windows from web sites

  1. // ==UserScript==
  2. // @name Anti-AdBlocker Fuckoff
  3. // @name:es Anti-AdBlocker Fuckoff
  4. // @namespace Anti-AdBlocker-Fuckoff
  5. // @version 1.6.2
  6. // @description Protects & Remove Anti-AdBlockers modal windows from web sites
  7. // @description:es Protege y elimina las ventanas modales de Anti-AdBlockers de los sitios web
  8. // @author Elwyn
  9. // @license MIT
  10. // @homepage https://github.com/WakeupNeo33/Anti-AdBlocker-Fuckoff-userscript
  11. // @supportURL https://github.com/WakeupNeo33/Anti-AdBlocker-Fuckoff-userscript/issues
  12. // @iconURL https://github.com/WakeupNeo33/Anti-AdBlocker-Fuckoff-userscript/raw/main/icon.png
  13. // @include *
  14. // @exclude https://*aliexpress.com/*
  15. // @exclude https://*amazon.*/*
  16. // @exclude https://*anaconda.org/*
  17. // @exclude https://*apple.com/*
  18. // @exclude https://*ask.com/*
  19. // @exclude https://*baidu.com/*
  20. // @exclude https://*binance.com/*
  21. // @exclude https://*binance.us/*
  22. // @exclude https://*bing.com/*
  23. // @exclude https://*bitfinex.com/*
  24. // @exclude https://*bitflyer.com/*
  25. // @exclude https://*bitstamp.net/*
  26. // @exclude https://*blockchain.com/*
  27. // @exclude https://*blockchair.com/*
  28. // @exclude https://*blockcypher.com/*
  29. // @exclude https://*bscscan.com/*
  30. // @exclude https://*buffer.com/*
  31. // @exclude https://*bufferapp.com/*
  32. // @exclude https://*calm.com/*
  33. // @exclude https://*chatango.com/*
  34. // @exclude https://*coinbase.com/*
  35. // @exclude https://*coinmarketcap.com/*
  36. // @exclude https://*doctor-groups.com/*
  37. // @exclude https://*duckduckgo.com/*
  38. // @exclude https://*ebay.com/*
  39. // @exclude https://*etherscan.io/*
  40. // @exclude https://*facebook.com/*
  41. // @exclude https://*firefaucet.win/*
  42. // @exclude https://*flattr.com/*
  43. // @exclude https://*flickr.com/*
  44. // @exclude https://*fsf.org/*
  45. // @exclude https://*ftx.com/*
  46. // @exclude https://*ftx.us/*
  47. // @exclude https://*gate.io/*
  48. // @exclude https://*geeksforgeeks.org/*
  49. // @exclude https://*gemini.com/*
  50. // @exclude https://*github.com/*
  51. // @exclude https://*gitlab.com/*
  52. // @exclude https://*google.*
  53. // @exclude https://*greasyfork.org/*
  54. // @exclude https://*huobi.com/*
  55. // @exclude https://*imdb.com/*
  56. // @exclude https://*imgbox.com/*
  57. // @exclude https://*imgur.com/*
  58. // @exclude https://*instagram.com/*
  59. // @exclude https://*jsbin.com/*
  60. // @exclude https://*jsfiddle.net/*
  61. // @exclude https://*kucoin.com/*
  62. // @exclude https://*kraken.com/*
  63. // @exclude https://*linkedin.com/*
  64. // @exclude https://*liquid.com/*
  65. // @exclude https://*live.com/*
  66. // @exclude https://*mail.ru/*
  67. // @exclude https://*mega.nz/*
  68. // @exclude https://*minds.com/*
  69. // @exclude https://*microsoft.com/*
  70. // @exclude https://*msn.com/*
  71. // @exclude https://*netflix.com/*
  72. // @exclude https://*odysee.com/*
  73. // @exclude https://*openuserjs.org/*
  74. // @exclude https://*paypal.com/*
  75. // @exclude https://*pinterest.com/*
  76. // @exclude http*://*plnkr.co/*
  77. // @exclude http*://*poloniex.com/*
  78. // @exclude https://*primevideo.com/*
  79. // @exclude https://*protonmail.com/*
  80. // @exclude https://*qq.com/*
  81. // @exclude https://*reddit.com/*
  82. // @exclude https://*stackoverflow.com/*
  83. // @exclude https://*tampermonkey.net/*
  84. // @exclude https://*trello.com/*
  85. // @exclude https://*twitch.tv/*
  86. // @exclude https://*twitter.com/*
  87. // @exclude https://*userstyles.org/*
  88. // @exclude https://*viawallet.com/*
  89. // @exclude https://*vimeo.com/*
  90. // @exclude https://*whatsapp.com/*
  91. // @exclude https://*wikipedia.org/*
  92. // @exclude https://*w3schools.com/*
  93. // @exclude https://*yahoo.*
  94. // @exclude https://*yandex.ru/*
  95. // @exclude https://*youtube.com/*
  96. // @exclude https://*vod.pl/*
  97. // @noframes
  98. // @run-at document-start
  99. // @grant unsafeWindow
  100. // ==/UserScript==
  101. (function() {
  102.  
  103. var enable_debug = false;
  104.  
  105. // Anti-AdBlocker Pattern to Search
  106. var adblock_pattern = /ad-block|adblock|ad block|bloqueur|bloqueador|Werbeblocker|آدبلوك بلس|блокировщиком/i;
  107. var disable_pattern = /kapat|disabl|désactiv|desactiv|desativ|deaktiv|detect|enabled|turned off|turn off|απενεργοποίηση|запрещать|állítsd le|publicités|рекламе|verhindert|advert|kapatınız/i;
  108.  
  109. var tagNames_pattern = /div|section|iframe/i;
  110.  
  111. var is_core_protected = false;
  112.  
  113. var classes = [];
  114.  
  115. // HELPER Functions
  116. //-----------------
  117. function debug( msg, val ) {
  118. if ( !enable_debug ) return;
  119. console.log( '%c ANTI-ADBLOCKER ','color: white; background-color: red', msg );
  120. if ( val === undefined ) return;
  121. if ( val.nodeType === Node.ELEMENT_NODE )
  122. {
  123. console.log ( 'TagName: ' + val.nodeName + ' | Id: ' + val.id + ' | Class: ' + val.classList );
  124. console.log ( val );
  125. } else {
  126. console.log ( val );
  127. }
  128. }
  129.  
  130. function addStyle(str) {
  131. var style = document.createElement('style');
  132. style.innerHTML = str;
  133. document.body.appendChild( style );
  134. }
  135.  
  136. function randomInt( min, max )
  137. {
  138. // min and max included
  139. if ( max === undefined ) {
  140. max = min;
  141. min = 0;
  142. }
  143. return Math.floor(min + Math.random() * (max - min + 1));
  144. }
  145.  
  146. function getRandomName( size )
  147. {
  148. var chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  149. var i;
  150. var name = '';
  151. for (i = 0; i < (size||randomInt(10,20)); i++)
  152. {
  153. name += chars.charAt( randomInt(0,chars.length) );
  154. }
  155. return name;
  156. }
  157.  
  158. function addRandomClass( el ) {
  159. let name = getRandomName();
  160. el.classList.add( name );
  161. return name;
  162. }
  163.  
  164. /* Thanks to RuiGuilherme */
  165. const enableContextMenu = () => {
  166. window.addEventListener('contextmenu', (event) => {
  167. event.stopPropagation();
  168. event.stopImmediatePropagation();
  169. }, true);
  170. }
  171.  
  172. function protectCore() {
  173. if ( is_core_protected ) return;
  174. is_core_protected = true;
  175. // Protect RemoveChild
  176. // Blocks the possibility of being able to remove the BODY or the HEAD
  177.  
  178. var $_removeChild = unsafeWindow.Node.prototype.removeChild;
  179. unsafeWindow.Node.prototype.removeChild = function( node ) {
  180. if ( node.nodeName == 'HEAD' || node.parentNode.nodeName == 'HEAD'){
  181. return debug( 'An attempt to DELETE the element ' + node.nodeName + ' was blocked', node );
  182. }
  183. else if ( node.nodeName == 'BODY' ){
  184. if ( node.parentNode == document.body.firstElementChild ) {
  185. return debug( 'An attempt to DELETE the element ' + node.nodeName + ' from ' + node.parentNode.nodeName + ' was blocked', node );
  186. }
  187. return debug( 'An attempt to DELETE the element ' + node.nodeName + ' was blocked', node );
  188. }
  189. $_removeChild.apply( this, arguments );
  190. };
  191.  
  192. // Protect innerHTML
  193.  
  194. var $_innerHTML = unsafeWindow.Node.prototype.innerHTML;
  195. unsafeWindow.Node.prototype.innerHTML = function( node ) {
  196. if ( node.nodeName == 'BODY' ) {
  197. return debug( 'An attempt to CHANGE the content of the element ' + node.nodeName + ' was blocked\n"' + node.textContent+'"' );
  198. }
  199. $_innerHTML.apply( this, arguments );
  200. };
  201.  
  202. var $_innerHTML_set = Object.getOwnPropertyDescriptor(Element.prototype, 'innerHTML').set;
  203.  
  204. Object.defineProperty(Element.prototype, 'innerHTML', {
  205. set: function (value) {
  206. if ( this.nodeName == 'BODY' ){
  207. return debug( 'An attempt to CHANGE the content of the element ' + this.nodeName + ' was blocked\n"' + this.textContent+'"\n"' + value + '"' );
  208. }
  209. //Call the original setter
  210. return $_innerHTML_set.call(this, value);
  211. }
  212. });
  213.  
  214. debug( 'Core Protected');
  215. }
  216.  
  217. function isElementBlur( el )
  218. {
  219. var style = window.getComputedStyle( el );
  220. var filter = style.getPropertyValue( 'filter' );
  221. return ( (/blur/i).test( filter ) );
  222. }
  223.  
  224. function isElementFixed( el )
  225. {
  226. var style = window.getComputedStyle( el );
  227. return ( style.getPropertyValue( 'position' ) == 'fixed' );
  228. }
  229.  
  230. function isOverflowHidden( el )
  231. {
  232. var style = window.getComputedStyle( el );
  233. return ( style.getPropertyValue( 'overflow' ) == 'hidden' );
  234. }
  235. function isNotHidden( el )
  236. {
  237. var style = window.getComputedStyle( el );
  238. return ( style.getPropertyValue( 'display' ) != 'none' );
  239. }
  240.  
  241. function isBlackoutModal( el )
  242. {
  243. var style = window.getComputedStyle( el );
  244. var position = style.getPropertyValue( 'position' );
  245. var top = parseInt( style.getPropertyValue( 'top' ) );
  246. var left = parseInt( style.getPropertyValue( 'left' ) );
  247. var right = parseInt( style.getPropertyValue( 'right' ) );
  248. var bottom = parseInt( style.getPropertyValue( 'bottom' ) );
  249. var zindex = style.getPropertyValue( 'z-index' );
  250. if ( isNaN( zindex ) ) zindex = 0;
  251. return parseInt( zindex ) > 1 && position == 'fixed' && ( ( el.offsetHeight > window.innerHeight - 50 && el.offsetWidth > window.innerWidth - 20 ) || (top == 0 && left == 0 && right == 0 && bottom == 0) );
  252. }
  253.  
  254. function isModalWindows( el )
  255. {
  256. return isElementFixed ( el ) && ( (adblock_pattern.test( el.textContent ) && disable_pattern.test( el.textContent )) || el.tagName == 'IFRAME' );
  257. }
  258.  
  259. function unblockScroll()
  260. {
  261. if ( isOverflowHidden( document.body ) )
  262. {
  263. document.body.setAttribute('style', (document.body.getAttribute('style')||'').replace('overflow: visible !important;','') + 'overflow: visible !important;');
  264. document.body.classList.add( 'scroll_on' );
  265. debug( 'Scroll Unblocked from BODY tag');
  266. }
  267. if ( isOverflowHidden( document.htmllTag ) )
  268. {
  269. document.html.setAttribute('style', (document.html.getAttribute('style')||'').replace('overflow: visible !important;','') + 'overflow: visible !important;');
  270. document.html.classList.add( 'scroll_on' );
  271. debug( 'Scroll Unblocked from HTML tag ');
  272. }
  273. }
  274.  
  275. // Main Functions
  276. function removeBackStuff()
  277. {
  278. document.querySelectorAll( 'div,section' ).forEach( ( el ) => {
  279. if ( isBlackoutModal( el ) )
  280. {
  281. debug( 'Blackout Modal Detected & Removed: ', el);
  282. el.setAttribute('style', (el.getAttribute('style')||'') + ';display: none !important;');
  283. el.classList.add( 'hide_modal' );
  284. }
  285. else if ( isElementBlur( el ) )
  286. {
  287. debug( 'Blur Element Detected & Deblurred: ', el);
  288. el.classList.add( 'un_blur' );
  289. }
  290. });
  291. setTimeout( unblockScroll, 500);
  292. }
  293.  
  294. function checkModals()
  295. {
  296. debug( 'Checking Modals' );
  297. var modalFound = false;
  298. // Only check common used html tag names
  299. document.querySelectorAll( 'div,section,iframe' ).forEach( ( el ) => {
  300. if ( isModalWindows( el ) && isNotHidden( el ) )
  301. {
  302. modalFound = true;
  303. removeModal( el );
  304. }
  305. });
  306.  
  307. if ( modalFound )
  308. {
  309. setTimeout( removeBackStuff, 150);
  310. }
  311. }
  312.  
  313. function removeModal( el, isNew )
  314. {
  315. // Skip the already processed elements
  316. if ( (new RegExp(classes.join('|'))).test( el.classList ) ) {
  317. //debug( 'Modal already added : ', el );
  318. return;
  319. }
  320.  
  321. // Definde a random class name to hide the element
  322. // ( so that it is not so easy to detect the class name )
  323. var class_name = '';
  324. class_name = addRandomClass( el );
  325. classes.push( class_name );
  326.  
  327. // Hide the element through a high priority incorporating the sentence in the style parameter
  328. el.setAttribute('style', (el.getAttribute('style')||'') + ';display: none !important;');
  329.  
  330. // Also, add the random class name to the element
  331. // (in case there is a script that eliminates the previous statement)
  332. addStyle( '.' + class_name + '{ display: none !important; }' );
  333.  
  334. debug( 'Modal Detected & Removed: ', el);
  335.  
  336. if ( isNew )
  337. {
  338. setTimeout( removeBackStuff, 150);
  339. }
  340. }
  341.  
  342. window.addEventListener('DOMContentLoaded', (event) => {
  343.  
  344. classes.push( getRandomName() );
  345.  
  346. document.html = document.getElementsByTagName('html')[0];
  347.  
  348. // Mutation Observer
  349. var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
  350.  
  351. // Create an observer instance
  352. var observer = new MutationObserver( (mutations) => {
  353. mutations.forEach( (mutation) => {
  354. if ( mutation.addedNodes.length ) {
  355. Array.prototype.forEach.call( mutation.addedNodes, ( el ) => {
  356. // skip unusual html tag names
  357. if ( !tagNames_pattern.test ( el.tagName ) ) return;
  358.  
  359. // Check if element is an Anti-Adblock Modal Windows
  360. if ( isModalWindows( el ) && isNotHidden( el ) )
  361. {
  362. debug( 'OnMutationObserver: ', el );
  363. removeModal( el, true );
  364. }
  365. });
  366. }
  367. });
  368. });
  369. // Observer
  370. observer.observe(document, {
  371. childList : true,
  372. subtree : true
  373. });
  374.  
  375. // enable context menu again
  376. enableContextMenu();
  377.  
  378. // First check with a little delay
  379. setTimeout( function() {
  380. checkModals();
  381. }, 50 );
  382.  
  383. addStyle( 'body.scroll_on, html.scroll_on { overflow: visible !important; } .hide_modal { display: none !important; } .un_blur { -webkit-filter: blur(0px) !important; filter: blur(0px) !important; }' );
  384.  
  385. });
  386.  
  387. window.addEventListener('load', (event) => {
  388. // Second check, when page is complete loaded ( just in case )
  389. checkModals();
  390. });
  391.  
  392. // Protect Core Functions
  393. protectCore();
  394.  
  395. })();