// ==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();
})();