Skip to content

feat(翻译): 添加data-translate属性支持以跳过翻译#134

Merged
AmintaCCCP merged 26 commits intoAmintaCCCP:mainfrom
SummerRay160:Dev
May 6, 2026
Merged

feat(翻译): 添加data-translate属性支持以跳过翻译#134
AmintaCCCP merged 26 commits intoAmintaCCCP:mainfrom
SummerRay160:Dev

Conversation

@SummerRay160
Copy link
Copy Markdown
Contributor

@SummerRay160 SummerRay160 commented May 6, 2026

Summary by CodeRabbit

  • New Features

    • Added interactive image viewer with zoom, pan (mouse/touch/scroll), full-screen modal display, keyboard shortcuts (Esc to close), and download functionality
  • Improvements

    • Enhanced translation handling to respect granular content exclusions

SummerRay160 and others added 26 commits April 30, 2026 04:11
refactor(RepositoryCard): 增强工具提示在浅色模式下的可读性
feat(ReadmeModal): 添加字体大小类型支持
style(index.css): 改进文本区域和输入框的浅色模式样式
refactor(MarkdownRenderer): 移除行号显示并支持字体大小调整
refactor(RepositoryEditModal): 优化浅色模式下的表单样式和交互
Adjust Tailwind typography classes in MarkdownRenderer: use 'prose prose-sm' for the 'small' fontSize instead of 'prose-xs', and remove the explicit 'prose-sm' for the medium/default case to fall back to the base 'prose' class. This normalizes sizing across fontSize options.
Fix stacking and improve the AI search tooltip UI and copy. Lowered SortByDropdown menu z-index to z-40 and added explicit z-indexes for the search input (z-40) and sort controls (z-30) to resolve overlay issues. Reworked the info tooltip: wider, responsive sizing, unified light/dark backgrounds and borders, improved text color/spacing, enabled word-wrapping, and adjusted the tooltip arrow styling/position. Also replaced the previous conditional AI copy with a single bilingual description explaining the multi-dimensional weighted search/ranking algorithm.
添加 hasHydrated 状态用于检测 store 是否完成水合
在 App 组件中添加加载状态以确保主题正确应用
更新搜索算法权重描述文案
根据activeAIConfig状态动态显示不同的搜索模式说明,当启用AI配置时显示语义搜索模式说明,否则显示本地智能排序说明
将加载状态的渲染逻辑移动到useEffect之后,使组件初始化逻辑更清晰
将加载状态的渲染逻辑移到认证检查之前,确保主题正确应用后再进行认证检查
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
实现文档翻译核心功能,包括:
1. 添加query-string依赖处理URL参数
2. 创建翻译服务模块调用微软翻译API
3. 实现Markdown分割与重组工具
4. 在ReadmeModal中添加翻译UI控件
5. 创建useMarkdownTranslation自定义hook管理翻译状态
将TOC提取逻辑从README内容加载中分离,改为在翻译内容或原始内容更新时触发
优化翻译服务,支持请求中止并改进参数处理
增强markdown分割器,支持更多代码块格式并改进链接和图片处理
重构 markdown 解析器,新增对 HTML 标签和带链接图片的支持
优化语言检测和翻译方向判断逻辑
调整 tailwind 配置中的颜色结构
重构翻译服务,添加FALLBACK_TOKEN_TTL_MS常量用于令牌过期处理
新增BilingualMarkdownRenderer组件实现双语对照显示
重构useMarkdownTranslation钩子和markdownSplitter工具函数
优化翻译分段处理逻辑和占位符替换机制
修复令牌验证时未检查缓存令牌是否存在的问题
优化markdown分割器中的代码块正则匹配,支持~~~语法
移除不必要的AbortError类型检查
简化双语渲染组件中的翻译状态显示逻辑
优化 translateService 中的 isTokenValid 类型守卫,使其更准确地判断 token 有效性
移除 BilingualMarkdownRenderer 中未使用的 language 属性及相关依赖
支持内联代码和details标签的占位处理,保留原始分隔符
添加原文/译文/双语三种显示模式切换功能
优化翻译按钮样式和占位符恢复逻辑
重构翻译功能,使用DOM文本扫描器替代Markdown分割器,实现更精准的文本块识别和翻译
新增BilingualMarkdownRenderer组件,支持原文、译文和双语三种显示模式
优化翻译服务,添加重试机制和HTML内容类型支持
改进目录功能,支持翻译后的标题同步显示
添加appendSafeHTMLNodes函数来安全处理翻译文本中的内联代码节点,防止潜在的HTML注入风险。当文本包含内联代码时,不再直接设置innerHTML,而是递归复制安全节点。
修复翻译服务中的重试逻辑,仅对瞬态错误进行重试
优化双语渲染器中的代码块处理逻辑
更新DOM文本扫描器以包含summary标签
在ReadmeModal中重置翻译标题映射
修复翻译服务中的认证过期处理,添加AuthExpiredError类标记认证过期错误
优化token获取逻辑,避免竞态条件和重复请求
添加对abort signal的支持,确保请求可被正确取消
- 在ReadmeModal中添加对可见元素的检查,防止滚动到隐藏元素
- 改进翻译服务,支持大文本分块处理和取消操作
- 优化双语Markdown渲染器,区分处理纯文本和HTML内容
- 导出TranslateResult接口供外部使用
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
在domTextScanner和MarkdownRenderer中添加对data-translate="false"属性的检查,当元素标记为不翻译时跳过处理。这用于避免翻译图片下方的操作提示文本等特定内容。
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 6, 2026

📝 Walkthrough

Walkthrough

Enhanced the MarkdownImage component with an interactive zoom viewer featuring a full-screen modal, pan/zoom controls (mouse, touch, wheel), keyboard support, and download capability. Updated domTextScanner to skip translation processing for elements marked with data-translate="false" to suppress translation of UI captions.

Changes

Image Interaction & Translation Suppression

Layer / File(s) Summary
Translation Suppression Mechanism
src/utils/domTextScanner.ts
Added guards to skip elements with data-translate="false" in extractTextPreservingInlineCode and to skip text nodes with translation-suppressed ancestors in wrapTextNodesWithAttr.
Image Viewer Enhancement
src/components/MarkdownRenderer.tsx
Implemented zoomable image viewer with React Portal modal supporting pan (mouse drag, touch), zoom (wheel), keyboard (Esc to close), download, and optional link-bar UI. Captions marked with data-translate="false" to prevent translation.
UI Integration
src/components/MarkdownRenderer.tsx
Added "Click to zoom" caption prompt, dimension display, link-bar for images inside links (showing truncated URL and open action), and modal controls (zoom in/out, reset to 1:1, download, close).

Sequence Diagram

sequenceDiagram
    actor User
    participant MarkdownRenderer
    participant MarkdownImage
    participant Modal as Modal<br/>(React Portal)
    participant domTextScanner

    User->>MarkdownRenderer: Render markdown with images
    MarkdownRenderer->>MarkdownImage: Pass image data
    MarkdownImage->>domTextScanner: Skip caption text<br/>(data-translate="false")
    MarkdownImage->>MarkdownImage: Render small/large image<br/>+ caption
    
    User->>MarkdownImage: Click image
    MarkdownImage->>Modal: Open full-screen zoom modal
    Modal->>Modal: Display image + controls<br/>(zoom, pan, download, close)
    
    User->>Modal: Mouse drag / touch / wheel
    Modal->>Modal: Pan or zoom image
    
    User->>Modal: Click download / open link
    Modal->>Modal: Trigger download or navigate
    
    User->>Modal: Press Esc / click background
    Modal->>MarkdownImage: Close modal
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • AmintaCCCP/GithubStarsManager#130: Directly related; introduced wrapTextNodesWithAttr and scanDomForTranslation functions in domTextScanner.ts that this PR extends with translation-suppression guards.

Poem

🐇 Behold, dear images now zoom and dance,
With modal portals they take their chance,
Pan and wheel, keyboard's gentle call,
Download glory, captions suppress them all!
The scanner learns to skip what's marked "false"—
Translation tamed, no more translation waltz! 🎨✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main changes: adding data-translate attribute support to skip translation processing in the codebase, which is reflected in both modified files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/utils/domTextScanner.ts (1)

59-61: 💤 Low value

Inconsistent ancestor handling between extractTextPreservingInlineCode and wrapTextNodesWithAttr.

wrapTextNodesWithAttr (line 142) uses parent.closest('[data-translate="false"]'), which checks the element and all ancestors. The new guard here only inspects the current element. As a result, if data-translate="false" is placed on an ancestor of a block element matched by BLOCK_SELECTOR (e.g. <div data-translate="false"><p>…</p></div>), scanDomForTranslation will still pick up the inner <p> via querySelectorAll, extract its text, and return a segment — while wrapTextNodesWithAttr will correctly skip all of its text nodes. The two functions then disagree about whether the segment is translatable.

This isn't triggered by the current MarkdownRenderer usage (the marked <div>s only contain <span>s, no block elements), so it's not a live bug, but it's worth aligning to avoid surprises if the attribute is later applied to wrapper elements.

♻️ Proposed alignment in `scanDomForTranslation`
   for (const element of elements) {
     if (isInsideSkippedElement(element, container)) continue;
+    if (element.closest('[data-translate="false"]')) continue;

     const extracted = extractTextPreservingInlineCode(element);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/utils/domTextScanner.ts` around lines 59 - 61, The guard that skips
elements only checks the current element (el.hasAttribute/data-translate) which
differs from wrapTextNodesWithAttr's ancestor-aware check; update the guard in
scanDomForTranslation/extractTextPreservingInlineCode to use
el.closest('[data-translate="false"]') (same selector logic as
wrapTextNodesWithAttr) and return when that returns non-null so ancestors with
data-translate="false" are respected consistently across
extractTextPreservingInlineCode, scanDomForTranslation, and
wrapTextNodesWithAttr.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/utils/domTextScanner.ts`:
- Around line 59-61: The guard that skips elements only checks the current
element (el.hasAttribute/data-translate) which differs from
wrapTextNodesWithAttr's ancestor-aware check; update the guard in
scanDomForTranslation/extractTextPreservingInlineCode to use
el.closest('[data-translate="false"]') (same selector logic as
wrapTextNodesWithAttr) and return when that returns non-null so ancestors with
data-translate="false" are respected consistently across
extractTextPreservingInlineCode, scanDomForTranslation, and
wrapTextNodesWithAttr.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f072110e-de6f-44ac-a931-85d77d8bf6e3

📥 Commits

Reviewing files that changed from the base of the PR and between 7592dce and 8d9f5ad.

📒 Files selected for processing (2)
  • src/components/MarkdownRenderer.tsx
  • src/utils/domTextScanner.ts

@AmintaCCCP
Copy link
Copy Markdown
Owner

能合了吗

@SummerRay160
Copy link
Copy Markdown
Contributor Author

SummerRay160 commented May 6, 2026 via email

@AmintaCCCP AmintaCCCP merged commit daae883 into AmintaCCCP:main May 6, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants