Safe AdBlocker (Precise & Non-breaking)

Hides ads from known networks without breaking the interface or being detected as an active AdBlock.

// ==UserScript==
// @name         Safe AdBlocker (Precise & Non-breaking)
// @namespace    https://tampermonkey.net/
// @version      1.7
// @description  Hides ads from known networks without breaking the interface or being detected as an active AdBlock.
// @author       Rubystance
// @license      MIT
// @match        https://donaldco.in/*
// @match        https://freeltc.online/*
// @match        https://zerads.com/*
// @match        https://claimcrypto.in/*
// @match        https://claimcoin.in/*
// @match        https://starlavinia.name.tr/*
// @match        https://rimakoko.com/*
// @match        https://faucetcrypto.com/*
// @match        https://eftacrypto.com/*
// @match        https://keran.co/*
// @match        https://wheelofgold.com/*
// @match        https://bagi.co.in/*
// @grant        none
// @run-at       document-idle
// ==/UserScript==

(function () {
    'use strict';

    const adDomains = [
        "a-ads.com", "bitmedia.io/*", "cryptocoinsad.com", "bank.gov.ua/*", "zerads.com", "cdn.bmcdn6.com", "faucetpay.io", "cdn.conzilla.com", "api.fpadserver.com", "faucetpay.io/ad-network", "coinzilla.com", "propellerads.com", "popads.net",
        "adsterra.com", "doubleclick.net", "googlesyndication.com", "media.net",
        "taboola.com", "outbrain.com", "revcontent.com", "mgid.com"
    ];

    function isAdUrl(url) {
        if (!url) return false;
        return adDomains.some(domain => url.includes(domain));
    }

    function hideEl(el) {
        el.style.display = 'none';
        el.setAttribute('data-hidden-by', 'safe-adblocker');
    }

    function process() {

        const elements = document.querySelectorAll('iframe[src], script[src], img[src]');

        elements.forEach(el => {
            if (el.hasAttribute('data-hidden-by')) return;
            const src = el.getAttribute('src');
            if (isAdUrl(src)) {
                hideEl(el);
            }
        });
    }

    setTimeout(process, 1500);
    setInterval(process, 5000);
    const observer = new MutationObserver(process);
    observer.observe(document.body, { childList: true, subtree: true });
})();