Greasy Fork

来自缓存

Greasy Fork is available in English.

AI对话窗口增强专业版

为主流AI平台优化对话窗口体验:支持ChatGPT、Claude、Kimi、通义千问、智谱GLM、天工、Deepseek、Gemini

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         AI Chat Window Enhancer Pro
// @name:zh-CN   AI对话窗口增强专业版
// @namespace    http://tampermonkey.net/
// @version      0.3.4
// @description  Enhanced chat window for various AI platforms: ChatGPT, Claude, Kimi, Tongyi, ChatGLM, Tiangong, Deepseek, Gemini
// @description:zh-CN  为主流AI平台优化对话窗口体验:支持ChatGPT、Claude、Kimi、通义千问、智谱GLM、天工、Deepseek、Gemini
// @author       Claude
// @match        *://chatgpt.com/*
// @match        *://new.oaifree.com/*
// @match        *://shared.oaifree.com/*
// @match        *://www.aicnn.cn/oaifree/*
// @match        *://chat.aicnn.xyz/*
// @match        *://plus.aivvm.com/*
// @match        *://kimi.moonshot.cn/*
// @match        *://tongyi.aliyun.com/qianwen*
// @match        *://www.tiangong.cn/*
// @match        *://chatglm.cn/*
// @match        *://claude.ai/*
// @match        *://chat.deepseek.com/*
// @include      *://*claude*/*
// @match        *://chat.kelaode.ai/*
// @match        *://gemini.google.com/*
// @icon         data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPHJlY3Qgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiByeD0iNSIgcnk9IjUiIGZpbGw9IiM2YmIiLz4KICA8cGF0aCBkPSJtMTcgMTMuNyA0LTQtNC00bS0xMCA4LTQtNCA0LTRtMTMuOTk5IDMuODI1SDMuMjE1Ii8+CiAgPHBhdGggZD0iTTE5IDE2aC0yLjVhLjk5LjkgMCAwIDAtLjc3NS4zNzVsLTIuOSAzLjY1Yy0uNC41LTEuMTYyLjUtMS41NjMgMGwtMi45MjUtMy42NUEuOTkuOSAwIDAgMCA3LjUgMTZINWMtMS42NjMgMC0zLTEuMzM4LTMtM1Y2YzAtMS42NjIgMS4zNS0zIDMtM2gxNGEzIDMgMCAwIDEgMyAzdjdjMCAxLjY2Mi0xLjM1IDMtMyAzWiIgZmlsbC1vcGFjaXR5PSIuMTYiIHN0cm9rZT0iI0VFRSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8L3N2Zz4K
// @license      AGPL-3.0
// @grant        GM_addStyle
// @noframes
// ==/UserScript==

(function() {
    'use strict';

    // 统一的样式配置
    const STYLE_CONFIG = {
        maxWidth: '95%',
        maxViewportWidth: '90vw',
        scrollbarWidth: 'thin',
        scrollbarThumbColor: '#aaaa',
        scrollbarTrackColor: '#1111',
        codeBlockScrollbarHeight: '8px',
        codeBlockScrollbarThumbColor: '#666',
        codeBlockScrollbarTrackColor: '#f1f1f1',
        // 代码块选中样式
        codeSelectionBgColor: 'rgba(70, 130, 180, 0.5)',     // 深色主题选中背景色
        codeSelectionTextColor: 'white',                     // 深色主题选中文本色
        lightCodeSelectionBgColor: 'rgba(0, 120, 215, 0.3)', // 浅色主题选中背景色
        lightCodeSelectionTextColor: 'black'                 // 浅色主题选中文本色
    };

    // 通用代码块样式
    const CODE_BLOCK_STYLES = `
        /* 代码块样式优化 */
        pre > div.rounded-md,
        .code-block__code {
            min-height: 1.5em;
            height: auto !important;
        }
        /* 保持代码块的水平滚动,移除纵向限制 */
        pre > div.rounded-md > div.overflow-y-auto,
        .code-block__code {
            max-height: none !important;
            height: auto !important;
            overflow-y: visible !important;
            overflow-x: auto !important;
        }
        /* 移除代码块的折叠按钮 */
        button[class*="code-block-collapse-button"],
        div[class*="code-block-collapse"] {
            display: none !important;
        }
        /* 确保代码块始终展开 */
        div[class*="code-block-wrapper"].collapsed {
            max-height: none !important;
            height: auto !important;
        }
        /* 优化代码块滚动条样式 */
        pre > div.rounded-md > div.overflow-y-auto::-webkit-scrollbar,
        .code-block__code::-webkit-scrollbar {
            height: ${STYLE_CONFIG.codeBlockScrollbarHeight};
            width: ${STYLE_CONFIG.codeBlockScrollbarHeight};
        }
        pre > div.rounded-md > div.overflow-y-auto::-webkit-scrollbar-thumb,
        .code-block__code::-webkit-scrollbar-thumb {
            background: ${STYLE_CONFIG.codeBlockScrollbarThumbColor};
            border-radius: 4px;
        }
        pre > div.rounded-md > div.overflow-y-auto::-webkit-scrollbar-track,
        .code-block__code::-webkit-scrollbar-track {
            background: ${STYLE_CONFIG.codeBlockScrollbarTrackColor};
        }

        /* 代码块文本选中样式 - 适用于深色背景 */
        pre code::selection,
        .code-block__code code::selection,
        pre div::selection,
        .code-block__code div::selection,
        pre span::selection,
        .code-block__code span::selection,
        div[class*="codeBlockContainer"] *::selection,
        div[class*="code-block"] *::selection {
            background-color: ${STYLE_CONFIG.codeSelectionBgColor} !important;
            color: ${STYLE_CONFIG.codeSelectionTextColor} !important;
        }

        /* 浅色背景代码块的选中样式 */
        pre.bg-white code::selection,
        pre.bg-gray-50 code::selection,
        pre.bg-slate-50 code::selection,
        .light-theme pre code::selection,
        .light pre code::selection {
            background-color: ${STYLE_CONFIG.lightCodeSelectionBgColor} !important;
            color: ${STYLE_CONFIG.lightCodeSelectionTextColor} !important;
        }

        /* 提升代码块hover时的可识别性 */
        pre:hover,
        .code-block__code:hover,
        div[class*="codeBlockContainer"]:hover,
        div[class*="code-block"]:hover {
            box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.1);
            transition: box-shadow 0.2s ease-in-out;
        }
    `;

    // 平台特定的样式定义
    const PLATFORM_STYLES = {
        kimi: `
            div[data-testid] div[data-index] div.MuiBox-root {
                max-width: 100% !important;
            }
            div[class^=mainContent] div.MuiBox-root > div[class^=chatBottom_] {
                max-width: calc(100% - 100px);
            }
            div[class^=mainContent] div[class^=chatInput_] div[class^=inputInner_] div[class^=editor] {
                max-height: 360px;
            }
            #scroll-list div[class^=chatItemBox_].MuiBox-root {
                max-width: 100%;
            }
            div.MuiBox-root[class^=homepage] div[class^=mainContent] div[class^=chatInput_] div[class^=inputInner_] div[class^=editor] {
                max-height: 600px;
            }
            #root > div > div[class*=mainContent] > div[class*=layoutContent] > div.MuiBox-root > div.MuiBox-root[class*=homepage] > div.MuiContainer-root.MuiContainer-maxWidthMd {
                max-width: calc(100% - 100px);
            }
            ${CODE_BLOCK_STYLES}
        `,
        deepseek: `
            div:has(> #latest-context-divider) {
                width: ${STYLE_CONFIG.maxWidth} !important;
            }
            div:has(> div > #chat-input) {
                width: ${STYLE_CONFIG.maxWidth} !important;
                max-width: ${STYLE_CONFIG.maxViewportWidth};
            }
            ${CODE_BLOCK_STYLES}
        `,
        tongyi: `
            div[class^=mainContent] div[class^=questionItem--],
            div[class^=mainContent] div[class^=answerItem--] {
                width: 90% !important;
                max-width: ${STYLE_CONFIG.maxViewportWidth};
            }
            ${CODE_BLOCK_STYLES}
        `,
        tiangong: `
            #app > div > div > main > div.overflow-y-scroll.w-full > div.search-content.relative.flex.w-full.flex-row.justify-center,
            #app > div > div > main > div.overflow-y-scroll.w-full > div.search-content.relative.flex.w-full.flex-row.justify-center > label.w-full.cursor-default.select-auto,
            label.w-full {
                max-width: calc(100% - 100px);
                --search-max-width: calc(100% - 100px);
            }
            :root {
                --search-max-width: calc(100% - 100px);
            }
            ${CODE_BLOCK_STYLES}
        `,
        chatglm: `
            div.conversation-inner.dialogue > div.conversation-list.detail > div.item.conversation-item,
            .markdown-body.md-body {
                max-width: ${STYLE_CONFIG.maxViewportWidth} !important;
            }
            ${CODE_BLOCK_STYLES}
        `,
        gemini: `
            #chat-history > infinite-scroller > div,
            #app-root > main > side-navigation-v2 > bard-sidenav-container > bard-sidenav-content > div > div > div.content-container > chat-window > div.chat-container.ng-star-inserted > div.bottom-container.response-optimization.ng-star-inserted,
            #app-root > main > side-navigation-v2 > bard-sidenav-container > bard-sidenav-content > div > div > div.content-container > chat-window > div.chat-container.ng-star-inserted > div.bottom-container.response-optimization.ng-star-inserted > div.input-area-container.ng-star-inserted {
                max-width: calc(100% - 20px);
            }
            ${CODE_BLOCK_STYLES}
        `,
        default: `
            .xl\\:max-w-\\[48rem\\] {
                width: ${STYLE_CONFIG.maxWidth} !important;
                max-width: 96% !important;
            }
            div.mx-auto.md\\:max-w-3xl,
            div.mx-auto.flex {
                max-width: calc(100% - 10px);
            }
            ${CODE_BLOCK_STYLES}
            .ProseMirror.break-words.ProseMirror-focused {
                max-width: 100%;
            }
            body > div.flex.min-h-screen.w-full div.flex.flex-col div.flex.gap-2 div.mt-1.max-h-96.w-full.overflow-y-auto.break-words > div.ProseMirror.break-words {
                max-width: 90%;
            }
            main > div.composer-parent article > div.text-base > div.mx-auto,
            main article > div.text-base > div.mx-auto {
                max-width: ${STYLE_CONFIG.maxWidth};
            }
            body > div.flex.min-h-screen.w-full > div > main > div.top-5.z-10.mx-auto.w-full.max-w-2xl.md,
            body > div.flex.min-h-screen.w-full > div > main > div.mx-auto.w-full.max-w-2xl.px-1.md {
                max-width: 100%;
            }
            body > div.flex.min-h-screen.w-full > div > main.max-w-7xl {
                max-width: 90rem;
            }
        `
    };

    // 平台映射配置
    const PLATFORM_MAP = {
        'kimi.moonshot.cn': 'kimi',
        'chat.deepseek.com': 'deepseek',
        'tongyi.aliyun.com': 'tongyi',
        'tiangong.cn': 'tiangong',
        'chatglm.cn': 'chatglm',
        'gemini.google.com': 'gemini'
    };

    // 检测当前平台并应用相应样式
    function applyPlatformStyles() {
        try {
            const host = window.location.hostname;
            let platformKey = 'default';
            
            // 使用平台映射检测当前平台
            for (const [domain, key] of Object.entries(PLATFORM_MAP)) {
                if (host.includes(domain)) {
                    platformKey = key;
                    break;
                }
            }
            
            // 应用对应平台的样式
            const styleToApply = PLATFORM_STYLES[platformKey] || PLATFORM_STYLES.default;
            GM_addStyle(styleToApply);
            
            console.log(`[AI Chat Enhancer] Applied styles for platform: ${platformKey}`);
        } catch (error) {
            console.error('[AI Chat Enhancer] Error applying styles:', error);
        }
    }

    // 优化链接处理
    function enhanceLinks() {
        // 使用防抖避免频繁调用
        if (enhanceLinks.timer) {
            clearTimeout(enhanceLinks.timer);
        }
        
        try {
            const links = document.querySelectorAll('div[data-message-id] a[rel="noreferrer"]');
            
            if (links.length > 0) {
                links.forEach(link => {
                    if (!link.href && link.innerText && link.innerText.trim()) {
                        const linkText = link.innerText.trim();
                        // 仅处理有效链接文本
                        if (linkText.startsWith('http') || linkText.includes('www.')) {
                            link.href = linkText;
                            link.target = "_blank";
                            link.rel = "noopener noreferrer";
                        }
                    }
                });
            }
        } catch (error) {
            console.error('[AI Chat Enhancer] Error enhancing links:', error);
        }
        
        // 使用MutationObserver替代递归调用,降低性能消耗
        enhanceLinks.timer = setTimeout(() => {
            if (!enhanceLinks.observer) {
                // 创建观察器,监听DOM变化
                enhanceLinks.observer = new MutationObserver((mutations) => {
                    const shouldProcess = mutations.some(mutation => 
                        mutation.addedNodes.length > 0 || 
                        (mutation.type === 'attributes' && mutation.attributeName === 'href')
                    );
                    
                    if (shouldProcess) {
                        enhanceLinks();
                    }
                });
                
                // 开始观察文档变化
                enhanceLinks.observer.observe(document.body, {
                    childList: true,
                    subtree: true,
                    attributes: true,
                    attributeFilter: ['href']
                });
            }
        }, 2000);
    }

    // 初始化
    function init() {
        // 在DOMContentLoaded后执行
        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', () => {
                applyPlatformStyles();
                enhanceLinks();
            });
        } else {
            // 文档已经加载完成
            applyPlatformStyles();
            enhanceLinks();
        }
        
        // 监听页面变化,适应单页应用
        window.addEventListener('popstate', applyPlatformStyles);
        window.addEventListener('pushstate', applyPlatformStyles);
        window.addEventListener('replacestate', applyPlatformStyles);
    }

    // 启动脚本
    init();
})();