您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Block popups from window.open/about:blank, target=_blank (links/forms/area), base target, and synthetic clicks
// ==UserScript== // @name Anti Popup (Enhanced 90%+ Block • Patch++) // @namespace ryza-no-popup-strong // @version 2.7 // @description Block popups from window.open/about:blank, target=_blank (links/forms/area), base target, and synthetic clicks // @license Ryza License // @match *://*/* // @run-at document-start // @grant none // ==/UserScript== (() => { 'use strict'; const WHITELIST = ['accounts.google.com','paypal.com']; const isWhite = (url) => { try { return WHITELIST.includes(new URL(url, location.href).hostname); } catch { return false; } }; /* ---------- 1) Kill window.open (incl. iframe) ---------- */ const trapOpen = new Proxy(window.open, { apply(_, __, args) { const url = args?.[0]; if (!url || isWhite(url)) return null; console.warn('[AntiPopup] window.open blocked:', url); return null; } }); try { Object.defineProperty(window, 'open', { configurable:true, writable:true, value:trapOpen }); } catch { window.open = trapOpen; } /* Hook iframe created later */ const origCreateEl = Document.prototype.createElement; Document.prototype.createElement = function(...a){ const el = origCreateEl.apply(this, a); if ((a[0]+'').toLowerCase() === 'iframe') { setTimeout(()=>{ try { el.contentWindow.open = () => null; } catch{} }, 500); } return el; }; /* ---------- 2) Neutralize <base target="_blank"> ---------- */ const neuterBase = (root=document) => { root.querySelectorAll('base[target]').forEach(b => b.removeAttribute('target')); }; /* ---------- 3) Sanitize anchors/forms/areas ---------- */ const sanitizeLink = (a) => { if (!a) return; const href = a.getAttribute('href') || a.href || ''; if (!isWhite(href)) a.removeAttribute('target'); const oc = (a.getAttribute('onclick') || '').toLowerCase(); if (oc.includes('window.open')) a.removeAttribute('onclick'); }; const sanitizeForm = (f) => { try { const act = f.getAttribute('action') || ''; if (!isWhite(act)) f.removeAttribute('target'); } catch {} }; const sanitizeArea = (ar) => { const href = ar.getAttribute('href') || ''; if (!isWhite(href)) ar.removeAttribute('target'); }; const sanitizeAll = (root=document) => { neuterBase(root); root.querySelectorAll('a[target], a[onclick]').forEach(sanitizeLink); root.querySelectorAll('form[target]').forEach(sanitizeForm); root.querySelectorAll('area[target]').forEach(sanitizeArea); }; /* ---------- 4) Stop synthetic click tricks ---------- */ const origAclick = HTMLAnchorElement.prototype.click; HTMLAnchorElement.prototype.click = function(...args){ sanitizeLink(this); return origAclick.apply(this, args); }; const origFormSubmit = HTMLFormElement.prototype.submit; HTMLFormElement.prototype.submit = function(...args){ sanitizeForm(this); return origFormSubmit.apply(this, args); }; /* ---------- 5) Pre-click hardening (captures) ---------- */ const preClick = (e) => { // bersihkan tepat sebelum event utama diproses neuterBase(); const a = e.target && (e.target.closest?.('a,area') || null); const f = e.target && (e.target.closest?.('form') || null); if (a) sanitizeLink(a); if (f) sanitizeForm(f); }; ['pointerdown','mousedown','touchstart','click','auxclick'].forEach(ev=>{ document.addEventListener(ev, preClick, true); }); /* ---------- 6) Observe dynamic injections ---------- */ new MutationObserver(muts=>{ for (const m of muts) { for (const n of m.addedNodes) { if (n.nodeType !== 1) continue; if (n.tagName === 'BASE') neuterBase(document); if (n.matches?.('a')) sanitizeLink(n); if (n.matches?.('form')) sanitizeForm(n); if (n.matches?.('area')) sanitizeArea(n); if (n.querySelectorAll){ sanitizeAll(n); n.querySelectorAll('iframe').forEach(i=>{ try { i.contentWindow.open = () => null; } catch{} }); } } } }).observe(document.documentElement, { childList:true, subtree:true }); /* ---------- 7) Block forced redirects ---------- */ const oa = window.location.assign.bind(window.location); window.location.assign = (url)=>{ if (!isWhite(url)) { console.warn('[AntiPopup] redirect blocked:', url); return; } oa(url); }; const or = window.location.replace.bind(window.location); window.location.replace = (url)=>{ if (!isWhite(url)) { console.warn('[AntiPopup] replace blocked:', url); return; } or(url); }; // Initial sweep sanitizeAll(); console.log('[AntiPopup+] Patch++ active'); })();