// ==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 // @downloadURL https://update.greasyfork.icu/scripts/520952/No%20Ad%20IFrame.user.js // @updateURL https://update.greasyfork.icu/scripts/520952/No%20Ad%20IFrame.meta.js // ==/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 = `${title}`; // 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... })();