豆瓣短评界面优化

毛玻璃风格弹窗/输入框、增高输入框、底部取消/保存按钮、移除分享到微博。

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         豆瓣短评界面优化
// @namespace    http://tampermonkey.net/
// @version      2.0
// @description  毛玻璃风格弹窗/输入框、增高输入框、底部取消/保存按钮、移除分享到微博。
// @author       Gemini
// @match        https://movie.douban.com/subject/*
// @grant        GM_addStyle
// @run-at       document-end
// @icon         https://img1.doubanio.com/favicon.ico
// ==/UserScript==

(function() {
    'use strict';

    // === 1. CSS 样式注入 (核心稳定功能 + 绿色高亮样式) ===
    GM_addStyle(`
        /* A. 主弹窗 (毛玻璃) */
        #dialog {
            background-color: rgba(255, 255, 255, 0.7) !important;
            backdrop-filter: blur(8px) saturate(180%) !important;
            -webkit-backdrop-filter: blur(8px) saturate(180%) !important;
            border-radius: 10px;
            box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
            border: none !important;
        }

        /* B. 保存按钮绿色高亮样式 */
        #dialog #submits span.bn-flat input[type="submit"] {
            color: #fff !important; 
        }

        #dialog #submits span.bn-flat input[type="submit"].bn-ok {
            background-color: #38a55e !important; 
            border-color: #38a55e !important;
            background-image: none !important; 
        }
        
        /* C. 标签/短评输入框样式 (增高和毛玻璃) */
        #dialog input[type="text"] {
            min-height: 28px !important;
            padding: 4px 6px !important;
            background-color: rgba(255, 255, 255, 0.2) !important; 
            backdrop-filter: blur(4px) !important;
            -webkit-backdrop-filter: blur(4px) !important; 
            border: 1px solid rgba(0, 0, 0, 0.1) !important;
            border-radius: 6px !important; 
        }

        textarea.comment {
            height: 200px !important; 
            resize: vertical; 
            padding: 8px !important;
            background-color: rgba(255, 255, 255, 0.2) !important; 
            backdrop-filter: blur(6px) !important;
            -webkit-backdrop-filter: blur(6px) !important; 
            border: 1px solid rgba(0, 0, 0, 0.15) !important;
            border-radius: 6px !important; 
        }
        
        /* D. 移除分享到微博的功能 */
        #dialog .sync-setting.pl {
             display: none !important;
        }

        /* E. 内部元素透明化 */
        #dialog > div, #dialog .interest-form-hd, #dialog .topbar-wrapper, #dialog .advtags, 
        #dialog .mytags, #dialog .populartags, #dialog .comment-label, 
        #dialog .comment-label+li, #dialog .interest-form-ft {
            background-color: transparent !important;
        }
    `);


    // --- 2. JavaScript 行为控制 (锁定/恢复外部滚动 + 按钮替换/样式) ---

    // **核心功能函数**:用于隐藏 'x'、添加 '取消' 按钮,并设置 '保存' 按钮样式
    const modifyDialogButtons = (dialogElement) => {
        const xButtonContainer = dialogElement.querySelector('.gact.rr');
        const submitSpan = dialogElement.querySelector('#submits span.bn-flat');
        const submitInput = dialogElement.querySelector('#submits span.bn-flat input[type="submit"]');

        // 1. 隐藏原始的 'x' 按钮 (右上角)
        if (xButtonContainer) {
            xButtonContainer.style.display = 'none';
        }
        
        // 2. 添加 '取消' 按钮 (仅当未添加时执行)
        let added = false;
        if (submitSpan && !dialogElement.querySelector('.cancel-button-added')) {
            const submitsDiv = submitSpan.parentNode; 
            
            const cancelButtonSpan = submitSpan.cloneNode(true);
            cancelButtonSpan.classList.add('cancel-button-added'); 
            
            const cancelButtonInput = cancelButtonSpan.querySelector('input');
            
            cancelButtonInput.setAttribute('type', 'button'); 
            cancelButtonInput.setAttribute('value', '取消');
            cancelButtonInput.setAttribute('onclick', 'close_dialog()'); 
            cancelButtonInput.removeAttribute('name'); 
            
            cancelButtonInput.classList.remove('bn-ok');

            submitsDiv.insertBefore(cancelButtonSpan, submitSpan);
            
            cancelButtonSpan.style.marginRight = '10px'; 
            added = true;
        }
        
        // 3. 为 '保存' 按钮添加绿色高亮样式 (仅当未添加时执行)
        let styled = false;
        if (submitInput && !submitInput.classList.contains('bn-ok')) {
             submitInput.classList.add('bn-ok');
             styled = true;
        }
        
        // 如果两个关键操作(添加按钮或应用样式)至少一个执行了,则返回 true
        return added || styled;
    };
    
    let dialogObserver = null; 

    // MutationObserver 回调函数 (观察 body 的子元素,只为检测 #dialog 出现或消失)
    const handleBodyMutation = (mutationsList, observer) => {
        const dialogElement = document.getElementById('dialog');
        
        if (dialogElement) {
            // #dialog 出现时:
            document.body.style.overflow = 'hidden';
            
            // 移除分享功能
            const shareSettingDiv = dialogElement.querySelector('.sync-setting.pl');
            if (shareSettingDiv) {
                shareSettingDiv.style.display = 'none';
            }

            // 重点:如果内部观察器未启动,则启动它
            if (!dialogObserver) {
                dialogObserver = new MutationObserver((mutations, obs) => {
                    // 尝试执行按钮替换、隐藏和样式应用操作
                    if (modifyDialogButtons(dialogElement)) {
                        // **优化点**: 成功后立即停止观察,避免持续的性能消耗
                        obs.disconnect(); 
                    }
                });
                dialogObserver.observe(dialogElement, { childList: true, subtree: true });
            }
            
            // 立即尝试一次操作 (以防加载速度很快,跳过观察器等待)
            modifyDialogButtons(dialogElement);


        } else {
            // #dialog 消失时:
            document.body.style.overflow = '';
            // 停止观察 #dialog
            if (dialogObserver) {
                dialogObserver.disconnect();
                dialogObserver = null;
            }
        }
    };

    // 创建观察器实例并开始观察 body 元素
    const bodyObserver = new MutationObserver(handleBodyMutation);
    const bodyObserverConfig = { childList: true };
    bodyObserver.observe(document.body, bodyObserverConfig);
    
    // 初始化检查
    if (document.getElementById('dialog')) {
        handleBodyMutation(); 
    }
    
})();