AV_AD_Block

missav 广告拦截与界面优化

// ==UserScript==
// @name         AV_AD_Block
// @description  missav 广告拦截与界面优化
// @icon         https://static.missav.com/img/favicon.png
// @namespace    loadingi.local
// @version      3.0
// @author       ch
// @match        https://missav.ws/*
// @grant        GM_setValue
// @grant        GM_getValue
// @run-at       document-start
// @compatible   chrome
// @compatible   firefox
// @compatible   edge
// @license      GPL-3.0-only
// ==/UserScript==

(function() {
    'use strict';

    // 统一管理所有选择器
    const SELECTORS = {
        // 样式相关选择器
        STYLES: {
            PROGRESS_BUTTONS: '.isolate.inline-flex.rounded-md.shadow-sm',
            PROGRESS_CONTROL: '.sm\\:hidden',
            LOOP_BUTTON: '.sm\\:ml-6 button',
            LOGO: '.font-serif',
            INFO_TEXT: '.mb-1.text-secondary.break-all.line-clamp-2',
            ASPECT_RATIO: '.aspect-w-16.aspect-h-9',
            PLAYER_CONTAINER: 'div.relative.-mx-4.sm\\:m-0.-mt-6',
            VIDEO_WRAPPER: '.aspect-w-16.aspect-h-9.relative',
            RIGHT_CONTAINER: '.hidden.lg\\:flex.h-full.ml-6.order-last'
        },
        // 广告相关选择器
        ADS: {
            SCRIPTS: [
                "script[src*='app.1aad5686.js']",
                "script[src*='inpage.push.js']",
                "script[src*='hartattenuate.com']",
                "script[src*='ads']",
                "script[src*='pop']",
                "script[src*='banner']"
            ],
            ELEMENTS: [
                'div.under_player',
                'div.space-y-5.mb-5',
                'div[class^="rootContent--"]',
                'div[class^="fixed right-2 bottom-2"]',
                'div[class^="space-y-6 mb-6"]',
                'div.space-y-2.mb-4.ml-4.list-disc.text-nord14',
                'div[id*="ads"]',
                'div[id*="banner"]',
                'div[class*="ads"]',
                'div[class*="banner"]',
                '.ad-container',
                '#ad-container'
            ],
            SCRIPT_PATTERNS: [
                'htmlAds',
                'popAds',
                'bannerAds',
                'adsConfig'
            ]
        }
    };

    // 统一的样式更新函数
    function updateStyles() {
        // 使用更高效的选择器
        const styleUpdates = [
            {
                selector: SELECTORS.STYLES.PROGRESS_BUTTONS,
                styles: { 
                    backgroundColor: '#222',
                    borderWidth: '0px'
                }
            },
            {
                selector: SELECTORS.STYLES.PROGRESS_CONTROL,
                styles: { 
                    display: 'flex',
                    visibility: 'visible',
                    opacity: '1'
                }
            },
            {
                selector: SELECTORS.STYLES.LOOP_BUTTON,
                styles: { borderWidth: '0px' }
            }
        ];

        styleUpdates.forEach(({selector, styles}) => {
            document.querySelectorAll(selector).forEach(el => {
                Object.assign(el.style, styles);
            });
        });

        // 设置背景
        document.body.style.backgroundColor = 'black';
    }

    // 优化的广告拦截函数
    function blockAds() {
        // 移除广告脚本
        SELECTORS.ADS.SCRIPTS.forEach(selector => {
            const elements = document.querySelectorAll(selector);
            elements.forEach(el => el?.remove());
        });
        
        // 移除广告元素
        SELECTORS.ADS.ELEMENTS.forEach(selector => {
            const elements = document.querySelectorAll(selector);
            elements.forEach(el => el?.remove());
        });
        
        // 移除所有 iframe
        document.querySelectorAll('iframe').forEach(iframe => iframe.remove());

        // 移除包含特定内容的脚本
        document.querySelectorAll('script').forEach(script => {
            if (SELECTORS.ADS.SCRIPT_PATTERNS.some(pattern => script.innerText.includes(pattern))) {
                script.remove();
            }
        });
    }

    // 优化的播放器设置函数
    function setupPlayer() {
        // 移除所有带有 @click="pop()" 的元素的点击事件
        document.querySelectorAll('[\\@click="pop()"]').forEach(element => {
            element.removeAttribute('@click');
        });

        // 移除窗口失焦暂停
        const aspectElements = document.getElementsByClassName('aspect-w-16 aspect-h-9');
        if(aspectElements[11]) {
            aspectElements[11].removeAttribute('@click');
            aspectElements[11].removeAttribute('@keyup.space.window');
        }
    }

    // 创建浮动按钮
    function createFloatingButtons() {
        const buttonContainer = document.createElement('div');
        Object.assign(buttonContainer.style, {
            position: 'fixed',
            bottom: '20px',
            right: '20px',
            zIndex: '1000'
        });

        // 右侧容器切换按钮
        const toggleContainerButton = document.createElement('button');
        const baseButtonStyles = {
            padding: '.375rem .625rem',
            backgroundColor: '#222',
            borderRadius: '10px',
            color: 'burlywood',
            borderWidth: '1px',
            cursor: 'pointer',
            transition: 'all 0.3s ease',
            outline: 'none',
            width: '100px'
        };

        Object.assign(toggleContainerButton.style, baseButtonStyles);
        toggleContainerButton.innerText = '隐藏右栏';
        toggleContainerButton.addEventListener('mouseover', () => toggleContainerButton.style.backgroundColor = '#333');
        toggleContainerButton.addEventListener('mouseout', () => toggleContainerButton.style.backgroundColor = '#222');
        toggleContainerButton.addEventListener('click', () => {
            const container = document.querySelector(SELECTORS.STYLES.RIGHT_CONTAINER);
            if (container) {
                const isHidden = container.style.display === 'none';
                container.style.display = isHidden ? 'flex' : 'none';
                toggleContainerButton.innerText = isHidden ? '隐藏右栏' : '显示右栏';
            }
        });

        buttonContainer.appendChild(toggleContainerButton);
        document.body.appendChild(buttonContainer);
    }

    // 初始化观察者
    function initObserver() {
        const observer = new MutationObserver(() => {
            blockAds();
            updateStyles();
            setupPlayer();
        });

        observer.observe(document.body, {
            childList: true,
            subtree: true
        });
    }

    // 主函数
    function init() {
        updateStyles();
        blockAds();
        setupPlayer();
        createFloatingButtons();
        initObserver();
    }

    // 当 DOM 加载完成后执行初始化
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
})();