No Ad IFrame

No Ad IFrame created by Stay

Versione datata 16/12/2024. Vedi la nuova versione l'ultima versione.

Dovrai installare un'estensione come Tampermonkey, Greasemonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Userscripts per installare questo script.

Dovrai installare un'estensione come ad esempio Tampermonkey per installare questo script.

Dovrai installare un gestore di script utente per installare questo script.

(Ho già un gestore di script utente, lasciamelo installare!)

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

(Ho già un gestore di stile utente, lasciamelo installare!)

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

// @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) => {

        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;

            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();
                    caching.set(nv, bv);
                    caching.set(bv, bv);
                    return bv;
                }
            }
            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...
})();