No Ad IFrame

No Ad IFrame created by Stay

Tendrás que instalar una extensión para tu navegador como Tampermonkey, Greasemonkey o Violentmonkey si quieres utilizar este script.

Necesitarás instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Userscripts para instalar este script.

Necesitará instalar una extensión como Tampermonkey para instalar este script.

Necesitarás instalar una extensión para administrar scripts de usuario si quieres instalar este script.

(Ya tengo un administrador de scripts de usuario, déjame instalarlo)

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

(Ya tengo un administrador de estilos de usuario, déjame instalarlo)

// ==UserScript==
// @name         No Ad IFrame
// @namespace    https://staybrowser.com/
// @version      0.1.1

// @description         No Ad IFrame created by Stay
// @description:en      No Ad IFrame created by Stay
// @description:ja      No Ad IFrame created by Stay
// @description:zh-TW   No Ad IFrame created by Stay
// @description:zh-CN   No Ad IFrame created by Stay

// @author       You
// @match        *://*/*
// @grant        none
// @inject-into page
// @unwrap
// @run-at              document-start
// @license             MIT
// @compatible          chrome
// @compatible          firefox
// @compatible          opera
// @compatible          edge
// @compatible          safari
// @allFrames           true
// ==/UserScript==
(function () {
    'use strict';

    const TURN_ON_BLOCK_REMOVAL = true;

    if (Object.getOwnPropertyDescriptor(HTMLIFrameElement.prototype, "__src437__")) return;

    Object.defineProperty(HTMLIFrameElement.prototype, "__src437__", {
        value: undefined,
        writable: true,
        configurable: false,
        enumerable: false
    });

    if (!Object.getOwnPropertyDescriptor(HTMLIFrameElement.prototype, "__src437__")) return;

    const pd1 = Object.getOwnPropertyDescriptor(HTMLIFrameElement.prototype, "src");
    const pd2 = Object.assign({}, pd1, {
        configurable: true,
        enumerable: true
    });

    const wSnb = Symbol();

    const adFilter = {

        'iframe[src*="doubleclick.net"]': 1,
        'iframe[src*="googlesyndication.com"]': 1,
        'iframe[src*="googleadservices.com"]': 1,
        'iframe[src*="googletagservices.com"]': 1,
        'iframe[src*="adservice.google.com"]': 1,
        'iframe[src*="adservice.yahoo.com"]': 1,
        'iframe[src*="amazon-adsystem.com"]': 1,
        'iframe[src*="adroll.com"]': 1,
        'iframe[src*="ads-twitter.com"]': 1,
        'iframe[src*="criteo.com"]': 1,
        'iframe[src*="taboola.com"]': 1,
        'iframe[src*="outbrain.com"]': 1,
        'iframe[src*="smartadserver.com"]': 1,
        'iframe[src*="openx.net"]': 1,
        'iframe[src*="rubiconproject.com"]': 1,

        'iframe[id^="aswift_"][src*="ads"][3]': 1,
        'iframe[id^="google_ads_iframe_"]': 1,
        'iframe[name^="google_ads_iframe_"]': 1,
        // 'iframe[src*="doubleclick.net"]': 1,
        // 'iframe[src*="googlesyndication.com"]': 1,
        'iframe[src*="adservice"]': 1,
        'iframe[src*="adserver"]': 1,
        // 'iframe[src*="/ads/"]': 1,
        // 'iframe[class*="ad-"]': 1,
        'iframe[data-ad-slot]': 1,

        // Additional patterns
        'iframe[id*="adframe"]': 1,         // Common variation like "adframe"
        'iframe[id*="ad_iframe"]': 1,       // "ad_iframe" naming pattern
        'iframe[id*="ad_container"]': 1,    // Container-like naming often used for ads
        'iframe[id*="ad_wrapper"]': 1,      // Another container naming pattern

        'iframe[class*="adslot"]': 1,       // "adslot" is a known pattern (e.g., GPT ad slots)
        'iframe[class*="adsense"]': 1,      // "adsense" typically indicates Google AdSense
        'iframe[class*="ad_frame"]': 1,     // Variation with underscore
        // 'iframe[class*="advert"]': 1,       // "advert" is another clue

        // Attribute patterns
        'iframe[data-ad-client]': 1,         // Data attribute used by some ad scripts
        'iframe[data-ad-region]': 1,         // Another ad-related data attribute

    };

    function createBase64DataURL(title) {
        // Construct a minimal HTML5 page with the given title
        const html = `<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"/><title>${title}</title></head><body></body></html>`;

        // Encode the HTML string into Base64
        const base64String = btoa(html);

        // Return as a Data URL
        return `data:text/html;base64,${base64String}`;
    }


    const dynamicGeneration = () => {
        const key = Math.floor(Math.random() * 314159265359 + 314159265359).toString(36);
        return createBase64DataURL(key);
    }

    const caching = new Map();

    const hKey = `e-${Math.floor(Math.random() * 314159265359 + 314159265359).toString(36)}`;

    const checkOnly = (elm) => {

        let noP = true;
        let noQ = true;
        let t = elm || 0;
        while (t = t.previousSibling) {

            if (t instanceof Text) {
                if (t.textContent.trim().length > 0) {
                    noP = false;
                    break;
                }
            } else if (t instanceof Element) {
                const nd = t.nodeName;
                if (nd === 'NOSCRIPT' || nd === 'SCRIPT' || nd === 'STYLE') continue;
                noP = false;
                break;
            } else if (t instanceof Comment) {

            } else {
                noP = false;
                break;
            }
        }
        if (noP === false) return false;

        t = elm || 0;
        while (t = t.nextSibling) {

            if (t instanceof Text) {
                if (t.textContent.trim().length > 0) {
                    noQ = false;
                    break;
                }
            } else if (t instanceof Element) {
                const nd = t.nodeName;
                if (nd === 'NOSCRIPT' || nd === 'SCRIPT' || nd === 'STYLE') continue;
                noQ = false;
                break;
            } else if (t instanceof Comment) {

            } else {
                noQ = false;
                break;
            }
        }

        if (noQ === false) return false;

        return true;


    };
    const hideIframe = (iframe) => {
        let noscriptWrapOK = false;
        try {
            if (iframe instanceof HTMLIFrameElement && iframe.isConnected === true && (iframe.parentNode || 0).nodeName !== 'NOSCRIPT') {
                const noscript = document.createElement('noscript');
                iframe.replaceWith(noscript);
                noscript.appendChild(iframe);
                noscriptWrapOK = true;
            }
        } catch (e) {
            console.warn(e);
        }

        if (TURN_ON_BLOCK_REMOVAL && noscriptWrapOK) {
            let layerNMax = 8;
            let parent = iframe;
            let lastSuccess = iframe;
            while (parent instanceof HTMLElement && checkOnly(parent)) {
                lastSuccess = parent;
                parent = parent.parentNode;
                layerNMax--;
                if (!layerNMax) break;
            }

            const effectNode = parent instanceof HTMLElement ? parent : lastSuccess;

            if ((effectNode instanceof HTMLElement) && effectNode.nodeName !== "NOSCRIPT") {
                effectNode.setAttribute(hKey, '');
                let noscriptWrapOK = false;
                try {
                    const noscript = document.createElement('noscript');
                    effectNode.replaceWith(noscript);
                    noscript.appendChild(effectNode);
                    noscriptWrapOK = true;
                } catch (e) { }
                if (!noscriptWrapOK) {
                    effectNode.style.setProperty('position', 'fixed', 'important');
                    effectNode.style.setProperty('left', '-130vw', 'important');
                    effectNode.style.setProperty('top', '-140vh', 'important');
                }
            }

        }

    };


    const convertionUrl = (nv, iframe) => {

        let btt = 0;

        if (typeof nv == 'string' && nv.length > 15 && iframe instanceof HTMLIFrameElement) {
            if ((iframe.parentNode || 0).nodeName === 'NOSCRIPT') return null;
            if (nv.length >= 22 && nv.startsWith('data:text/html;base64,')) return null;
            btt = 1;
        } else if ((nv || '') === '' && iframe instanceof HTMLIFrameElement) {
            btt = 2;
        }


        if (btt > 0) {
            if (btt === 1) {
                const cv = caching.get(nv);
                if (cv !== undefined) return cv;
            }
            for (const adf of Object.keys(adFilter)) {
                const adk = adf.replace(/\[\d+\w*\]/g, '');
                if (iframe.matches(adk)) {
                    const w = adFilter[adf];
                    const bv = typeof w === 'string' ? w : dynamicGeneration();
                    if (btt === 1) {
                        caching.set(nv, bv);
                        caching.set(bv, bv);
                    }
                    return bv;
                }
            }
            if (btt === 1) {
                caching.set(nv, null);
            }
        }
        return null;
    };
    const pd3 = {
        set(nv) {
            if (typeof nv === 'string') {
                if (this[wSnb] === nv) return true;
                if (nv.length >= 22 && nv.startsWith('data:text/html;base64,')) {
                } else if (nv.length > 15) {
                    const bv = convertionUrl(nv, this);
                    if (bv) {
                        hideIframe(this);
                        if ((this.parentNode || 0).nodeName !== 'NOSCRIPT') nv = bv;
                    }
                }
            }
            this[wSnb] = nv;
            return true;
        },
        get() {
            return this[wSnb];
        },
        configurable: true,
        enumerable: true
    };

    Object.defineProperty(HTMLIFrameElement.prototype, wSnb, pd2);


    Object.defineProperty(HTMLIFrameElement.prototype, "src", pd3);


    document.addEventListener('load', function (evt) {
        const evtTarget = evt.target;
        if (evtTarget instanceof HTMLIFrameElement) {
            const bv = convertionUrl(evtTarget.src, evtTarget);
            if (bv) {
                hideIframe(evtTarget);
                if ((evtTarget.parentNode || 0).nodeName !== 'NOSCRIPT') evtTarget.src = bv;
                evt.stopPropagation();
                evt.stopImmediatePropagation();
                evt.preventDefault();
            }
        }
    }, true);

    const um = new WeakSet();

    const iframeAll = document.getElementsByTagName('iframe');
    let iframeLC = 0;
    new MutationObserver(() => {
        const iframeTC = iframeAll.length;
        if (iframeTC !== iframeLC) {
            iframeLC = iframeTC;
            for (const iframe of iframeAll) {
                if (um.has(iframe)) continue;
                um.add(iframe);
                const bv = convertionUrl(iframe.src, iframe);
                if (bv) {
                    hideIframe(iframe);
                    if ((iframe.parentNode || 0).nodeName !== 'NOSCRIPT') iframe.src = bv;
                }
            }
        }
    }).observe(document, { subtree: true, childList: true });

    // Your code here...
})();