Greasy Fork

Greasy Fork is available in English.

Claude.ai 汉化

自动翻译claude.ai网页内的内容,并且支持自动翻译title

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Claude.ai 汉化
// @namespace    http://tampermonkey.net/
// @version      1.7.1
// @description  自动翻译claude.ai网页内的内容,并且支持自动翻译title
// @match        https://claude.ai/*
// @grant        none
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    // 翻译映射
    const translations = {
        "Start new chat": "开始新对话",
        "Start New Chat": "开始新对话",
        "New chat": "新对话",
        "Star chat": "星标对话",
        "Projects": "项目",
        "Starred": "已加星标",
        "Unpin sidebar": "取消固定侧边栏",
        "Pin sidebar": "固定侧边栏",
        "Star projects and chats you use often": "为您经常使用的项目和对话加星标",
        "Your recent chats": "您最近的对话",
        "View all": "查看全部",
        "How can Claude help you today?": "今天Claude能为您做些什么?",
        "Use a project": "使用项目",
        "Add content": "添加内容",
        "Upload docs or images": "上传文档或者图片",
        "Max 5, 30mb each": "最多5个,每个30MB",
        "Summarize meeting notes": "总结会议记录",
        "Extract insights from report": "从报告中提取见解",
        "Generate interview questions": "生成面试问题",
        "Professional Plan": "专业版计划",
        "Good morning": "早上好",
        "Help & support": "帮助与支持",
        "Claude currently cannot access the internet or reference links": "Claude目前无法访问互联网或参考链接",
        "Use shift + return for new line": "用 Shift + 回车键换行",
        "Send message": "发送消息",
        "Rename": "重命名",
        "Delete": "删除",
        "Copy": "复制",
        "Claude can make mistakes. Please double-check responses.": "Claude可能会犯错。请仔细检查回复。",
        "Edit": "编辑",
        "Retry": "重试",
        "Share positive feedback": "分享正面反馈",
        "Report issue": "报告问题",
        "Recents": "最近",
        "Select": "选择",
        "You have {n} previous chats with Claude": "您与Claude有{n}个以前的对话",
        "Last message": "最后消息",
        "Capture screenshot":"截图",
        "Your chat history":"您的对话历史",
        "selected chats":"已选对话",
        "Select all":"全选",
        "Cancel":"取消",
        "Delete selected":"删除已选",
        "Clear Cache": "清除缓存",
        "Are you sure you want to clear the translation cache?": "您确定要清除翻译缓存吗?",
        "Yes": "是",
        "No": "否",
        "Settings": "设置",
        "Appearance": "外观",
        "Feature Preview": "功能预览",
        "Learn more": "了解更多",
        "API Console": "API 控制台",
        "Help & Support": "帮助与支持",
        "Log Out": "退出登录",
        // 图片中的新选项
        "System": "系统",
        "Light": "浅色",
        "Dark": "深色",
        // 新增的翻译项
        "Profile": "个人资料",
        "Billing": "账单",
        "Account": "账户",
        "Full name": "全名",
        "What should we call you?": "我们应该如何称呼您?",
        "Update Name": "更新名称",
        "What best describes your work?": "什么最能描述您的工作?",
        "Select your work function": "选择您的工作职能",
        "Show prompt suggestions": "显示提示建议",
        "We’ll show examples of starter prompts you can use based on your role": "我们将根据您的角色显示您可以使用的起始提示示例",
        "Enable artifacts": "启用智能工件",
        "Ask Claude to generate content like code snippets, text documents, or website designs, and Claude will create an Artifact that appears in a dedicated window alongside your conversation.": "要求 Claude 生成代码片段、文本文档或网站设计等内容,Claude 将创建一个人工制品,显示在您对话旁边的专用窗口中。",
        // 新增的翻译项
        "Subscribed to Pro": "已订阅专业版",
        "Thanks for being a Pro, BaiYa": "感谢您成为专业版用户,BaiYa",
        "Level up your Claude usage with 5x more usage versus Free plan": "相比免费计划,您的 Claude 使用量提升了 5 倍",
        "Access to Claude 3 Haiku, our fastest model, and Claude 3 Opus": "可以使用 Claude 3 Haiku(我们最快的模型)和 Claude 3 Opus",
        "Create Projects to work with Claude around a set of docs, code, or files": "创建项目,使用 Claude 处理一组文档、代码或文件",
        "Priority access during high-traffic periods": "在高流量期间享有优先访问权",
        "Early access to new features": "抢先体验新功能",
        "Payment": "支付",
        "Link by Stripe": "Stripe 链接",
        "Update": "更新",
        "Invoices": "发票",
        "Date": "日期",
        "Total": "总计",
        "Status": "状态",
        "Actions": "操作",
        "Paid": "已支付",
        "View": "查看",
        "Cancellation": "取消订阅",
        "Cancel plan": "取消计划",
        // 新增的翻译项
        "Export data": "导出数据",
        "Export Data": "导出数据",
        "Delete account": "删除账户",
        "Contact Support": "联系支持",
        // 新增的翻译项
        "About Anthropic": "关于 Anthropic",
        "Consumer Terms": "用户条款",
        "Usage Policy": "使用政策",
        "Privacy Policy": "隐私政策",
        "Your Privacy Choices": "您的隐私选择",
        // 新增的翻译项
        "Provide stakeholder perspective": "提供利益相关者视角",
        "Generate excel formulas": "生成 Excel 公式",
        "Try this prompt": "试试这个提示",
        "Polish your prose": "润色您的文笔",
        "Write a memo": "写一份备忘录",
        "Use projects to organize chats and give Claude knowledge context": "使用项目组织对话并给Claude知识上下文",
        "Reload suggestions": "重新加载提示",
        "Hide suggestions": "隐藏提示",
        "Good afternoon": "下午好",
        // 新增的翻译项
        "Chat controls": "对话控制",
        "Claude 3.5 Sonnet": "Claude 3.5 Sonnet",
        "Most intelligent model": "最智能的模型",
        "Content": "内容",
        "Add images, PDFs, docs, spreadsheets, and more to summarize, analyze, and query content with Claude.": "添加图片、PDF、文档、电子表格等,以便使用 Claude 总结、分析和查询内容。",
        "Chat styles": "对话样式",
        "Font": "字体",
        "Default": "默认",
        "Match system": "匹配系统",
        "Dyslexic friendly": "适合阅读障碍者",
        "Click to open document": "点击打开文档",
        "Refresh": "刷新",
        "Download to file": "下载到文件"
    };

    // 翻译缓存
    let translationCache = {};

    // 修改翻译函数
    function translateText(node) {
        if (node.nodeType === Node.TEXT_NODE) {
            const trimmedText = node.textContent.trim();
            if (translations[trimmedText]) {
                node.textContent = node.textContent.replace(trimmedText, translations[trimmedText]);
            } else if (node.parentElement && 
                       (node.parentElement.classList.contains('truncate') || 
                        node.parentElement.classList.contains('font-tiempos') ||
                        node.parentElement.classList.contains('text-sm') ||
                        (node.parentElement.closest('.group') && node.parentElement.classList.contains('break-words')))) {
                // 检查缓存
                if (translationCache[trimmedText]) {
                    node.textContent = translationCache[trimmedText];
                } else {
                    // 如果缓存中没有,则使用Google Translate API进行翻译
                    translateWithGoogleAPI(trimmedText).then(translatedText => {
                        node.textContent = translatedText;
                        // 将翻译结果存入缓存
                        translationCache[trimmedText] = translatedText;
                    });
                }
            }
        } else if (node.nodeType === Node.ELEMENT_NODE) {
            ['placeholder', 'aria-label', 'title'].forEach(attr => {
                if (node.hasAttribute(attr)) {
                    let original = node.getAttribute(attr);
                    if (translations[original]) {
                        node.setAttribute(attr, translations[original]);
                    }
                }
            });
            // 特殊处理链接文本
            if (node.tagName === 'A' && node.textContent.trim() in translations) {
                node.textContent = translations[node.textContent.trim()];
            }

            // 添加新的逻辑来处理特定的 artifact 预览内容
            if (node.classList.contains('font-styrene') && node.querySelector('.break-words.text-sm.font-medium.leading-tight')) {
                const previewTextElement = node.querySelector('.break-words.text-sm.font-medium.leading-tight');
                const originalText = previewTextElement.textContent.trim();
                
                // 检查缓存
                if (translationCache[originalText]) {
                    previewTextElement.textContent = translationCache[originalText];
                } else {
                    // 使用 Google Translate API 进行翻译
                    translateWithGoogleAPI(originalText).then(translatedText => {
                        previewTextElement.textContent = translatedText;
                        // 将翻译结果存入缓存
                        translationCache[originalText] = translatedText;
                    });
                }
            }

            // 添加对特定元素的处理
            if (node.classList.contains('font-tiempos') && node.classList.contains('truncate')) {
                translateElementContent(node);
            }
        }
    }

    // 使用Google Translate API进行翻译
    async function translateWithGoogleAPI(text) {
        // 首先检查缓存
        if (translationCache[text]) {
            return translationCache[text];
        }

        const apiUrl = `https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl=zh-CN&dt=t&q=${encodeURIComponent(text)}`;
        try {
            const response = await fetch(apiUrl);
            const data = await response.json();
            const translatedText = data[0][0][0];
            // 将翻译结果存入缓存
            translationCache[text] = translatedText;
            return translatedText;
        } catch (error) {
            console.error('Translation error:', error);
            return text; // 如果翻译失败,返回原文
        }
    }

    // 修改翻译页面函数
    function translatePage() {
        const walker = document.createTreeWalker(
            document.body,
            NodeFilter.SHOW_TEXT | NodeFilter.SHOW_ELEMENT,
            {
                acceptNode: function(node) {
                    // 排除用户输入框、消息框和对话内容,但包括对话历史条目和特殊的group内元素
                    if (node.nodeType === Node.ELEMENT_NODE && 
                        (node.getAttribute('contenteditable') === 'true' ||
                         node.tagName === 'TEXTAREA' ||
                         node.tagName === 'INPUT' ||
                         (node.closest('.font-claude-message') && 
                          !node.classList.contains('truncate') && 
                          !node.classList.contains('font-tiempos') &&
                          !node.classList.contains('break-words')))) {
                        return NodeFilter.FILTER_REJECT;
                    }
                    return NodeFilter.FILTER_ACCEPT;
                }
            },
            false
        );

        let node;
        while(node = walker.nextNode()) {
            translateText(node);
        }

        // 添加对特定元素的翻译
        translateSpecificElements();

        // 在翻译完成后添加清除缓存按钮
        addClearCacheButton();
    }

    // 添加新函数来处理特定元素
    function translateSpecificElements() {
        // 翻译 artifact 预览内容
        document.querySelectorAll('.font-styrene .break-words.text-sm.font-medium.leading-tight').forEach(element => {
            translateElementContent(element);
        });

        // 翻译 sticky 头部的标题
        document.querySelectorAll('.sticky .font-tiempos.truncate').forEach(element => {
            translateElementContent(element);
        });

        // 可以在这里添加其他特定元素的翻译逻辑
    }

    function translateElementContent(element) {
        const originalText = element.textContent.trim();
        if (originalText && !translationCache[originalText]) {
            translateWithGoogleAPI(originalText).then(translatedText => {
                element.textContent = translatedText;
                translationCache[originalText] = translatedText;
            });
        } else if (translationCache[originalText]) {
            element.textContent = translationCache[originalText];
        }
    }

    // 修改添加清除缓存按钮的函数
    function addClearCacheButton() {
        const sidebarNav = document.querySelector('ul.flex.flex-col.gap-px');
        if (sidebarNav && !document.getElementById('clearCacheButton')) {
            const clearCacheButton = document.createElement('li');
            clearCacheButton.innerHTML = `
                <button id="clearCacheButton" class="hover:bg-bg-400 group -mx-1.5 flex items-center gap-1 rounded-md px-1.5 py-1 transition-colors duration-200 text-text-100">
                    ${translations["Clear Cache"]}
                </button>
            `;
            clearCacheButton.querySelector('button').onclick = showClearCacheConfirmation;
            sidebarNav.appendChild(clearCacheButton);
        }
    }

    // 显示清除缓存确认弹窗
    function showClearCacheConfirmation() {
        const confirmMessage = translations["Are you sure you want to clear the translation cache?"];
        if (confirm(confirmMessage)) {
            translationCache = {};
            alert(translations["Cache cleared successfully!"]);
            translatePage(); // 重新翻译页面
        }
    }

    // 监听DOM变化
    const observer = new MutationObserver((mutations) => {
        mutations.forEach((mutation) => {
            if (mutation.type === 'childList') {
                mutation.addedNodes.forEach((node) => {
                    if (node.nodeType === Node.ELEMENT_NODE) {
                        const walker = document.createTreeWalker(
                            node,
                            NodeFilter.SHOW_TEXT | NodeFilter.SHOW_ELEMENT,
                            {
                                acceptNode: function(node) {
                                    // 排除用户输入框、消息框和对话内容,但包括对话历史条目
                                    if (node.nodeType === Node.ELEMENT_NODE && 
                                        (node.getAttribute('contenteditable') === 'true' ||
                                         node.tagName === 'TEXTAREA' ||
                                         node.tagName === 'INPUT' ||
                                         (node.closest('.font-claude-message') && !node.classList.contains('truncate') && !node.classList.contains('font-tiempos')))) {
                                        return NodeFilter.FILTER_REJECT;
                                    }
                                    return NodeFilter.FILTER_ACCEPT;
                                }
                            },
                            false
                        );

                        let childNode;
                        while(childNode = walker.nextNode()) {
                            translateText(childNode);
                        }

                        // 对新添加的节点也执行特定元素翻译
                        translateSpecificElements();
                    }
                });
            }
        });
    });

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

    // 修改定时器逻辑
    let translationInterval = setInterval(() => {
        translatePage();
        // 如果页面加载完成后仍有未翻译的内容,可以增加检查次数或延长间隔时间
        if (document.readyState === 'complete') {
            clearInterval(translationInterval);
            // 设置一个较长的间隔来检查可能的动态内容
            setInterval(translateSpecificElements, 5000);
        }
    }, 1000);

    // 初始翻译
    translatePage();
})();