Skip to content

Conversation

@Chiaki-xps
Copy link
Contributor

@Chiaki-xps Chiaki-xps commented Dec 15, 2025

🤔 这个变动的性质是?

  • 🆕 新特性提交
  • 🐞 Bug 修复
  • 📝 站点、文档改进
  • 📽️ 演示代码改进
  • 💄 组件样式/交互改进
  • 🤖 TypeScript 定义更新
  • 📦 包体积优化
  • ⚡️ 性能优化
  • ⭐️ 功能增强
  • 🌐 国际化改进
  • 🛠 重构
  • 🎨 代码风格优化
  • ✅ 测试用例
  • 🔀 分支合并
  • ⏩ 工作流程
  • ⌨️ 无障碍改进
  • ❓ 其他改动(是关于什么的改动?)

🔗 相关 Issue

  1. 描述相关需求的来源,如相关的 issue 讨论链接。
  2. 例如 close #xxxx、 fix #xxxx

💡 需求背景和解决方案

  1. 要解决的具体问题。
  2. 列出最终的 API 实现和用法。
  3. 涉及UI/交互变动建议提供截图或 GIF。

Bug 复现步骤:

  1. 在 Sender 输入框中已有一段文本(例如:"写作助手请帮我写一篇关于...")。
  2. 选中并剪切(Ctrl+X)这段文本。此时浏览器的撤销栈顶是“剪切”操作。
  3. 在输入框中粘贴(Ctrl+V)刚才剪切的文本。
  4. 此时按下撤销(Ctrl+Z)。会发现,并不是回退到上一步,而是直接把原来的文案拼接到后面去。
image

问题表现:
并未撤销刚才的“粘贴”操作,而是执行了更早的“撤销剪切”。
结果:粘贴的内容还在,而被剪切的内容又被恢复了,导致文本重复出现在输入框中(即粘贴内容 + 恢复的剪切内容)。

原因分析:
原有的粘贴逻辑拦截了 onPaste 事件后,通过手动 DOM 操作插入文本。这种方式不会被浏览器记录到 Undo Stack(撤销栈)中。因此,当用户按 Ctrl+Z 时,浏览器跳过了“粘贴”这一步(因为它不知道),直接撤销了上一步已知的操作(即“剪切”)。

解决方案:
onPaste 事件处理中,优先尝试使用 document.execCommand('insertText', false, text) 来插入文本。这是一个浏览器原生支持的命令,会自动将操作记录到 Undo/Redo 历史栈中,从而确保 Ctrl+Z 能正确撤销粘贴操作。

📝 更新日志

语言 更新描述
🇺🇸 英文 Fix Sender component paste behavior to support native undo/redo properly.
🇨🇳 中文 修复 Sender 组件在粘贴文本后无法正确撤销(Undo)的问题。

Summary by CodeRabbit

  • Bug 修复
    • 改进了粘贴文本的插入流程:优先尝试浏览器原生插入以提升兼容性与稳定性,若不可用或失败则回退到原有方案,确保撤销栈与用户体验不受影响。包含非生产环境的日志以便诊断。
    • 对外行为与导出签名未发生变化。

✏️ Tip: You can customize this high-level summary in your review settings.

@github-actions
Copy link
Contributor

github-actions bot commented Dec 15, 2025

Preview failed

@dosubot dosubot bot added the bug Something isn't working label Dec 15, 2025
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @Chiaki-xps, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

此拉取请求旨在解决 Sender 组件中一个关键的可用性问题,即用户在粘贴文本后无法通过 Ctrl+Z 正确撤销该操作。通过将粘贴逻辑从手动DOM操作切换为优先使用浏览器原生的 document.execCommand('insertText') 命令,确保了粘贴行为能够被浏览器的撤销历史正确记录,从而恢复了预期的撤销功能。这一改进提升了用户在文本输入区域操作时的体验一致性。

Highlights

  • Bug修复: 修复了 Sender 组件中粘贴操作后无法正确撤销(Undo)的问题。
  • 撤销栈行为: 解决了由于手动DOM操作导致粘贴内容未被浏览器撤销栈记录的问题,从而导致撤销操作异常。
  • 解决方案: 引入 document.execCommand('insertText') 来处理粘贴操作,确保其被浏览器原生撤销栈记录,并增加了兼容性回退机制。
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

这个 PR 旨在修复 Sender 组件中粘贴操作无法被正确撤销的问题,通过使用 document.execCommand('insertText') 来将粘贴操作加入浏览器的撤销栈。这是一个聪明的解决方案,直接解决了 bug。我的审查主要关注所使用 API 的长期维护性。document.execCommand 是一个已被废弃的 API,未来可能会在浏览器中被移除。我提供了一些建议来降低这种风险,例如添加注释说明情况,以及在开发环境中记录潜在的错误,以提高代码的可维护性和健壮性。

try {
success = document.execCommand('insertText', false, cleanText);
} catch (err) {
// ignore
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

静默地忽略错误(empty catch block)会使调试变得困难。一个好的实践是至少在开发环境中打印捕获到的错误。

例如:

if (process.env.NODE_ENV !== 'production') {
  console.error('`insertText` command failed:', err);
}

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 15, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

尝试在粘贴处理路径中优先使用浏览器的 document.execCommand('insertText') 插入已清理(去除换行)的文本;对 execCommand 包含 try/catch 并基于环境记录错误,若失败或返回 false 则回退到原有插入机制以保留撤销栈行为,并留下 TODO 提示将来使用 beforeinput 重构。

Changes

内聚组 / 文件 变更摘要
文本粘贴处理逻辑优化
packages/x/components/sender/SlotTextArea.tsx
粘贴事件处理改为先尝试通过 execCommand('insertText') 插入清理后的文本(去除换行符),对 execCommand 添加 try/catch 与基于环境的错误日志,若失败或返回 false 则回退到原有插入机制(保持撤销栈兼容);保留 TODO 注释以指向未来使用 beforeinput 的重构。

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 分钟

  • 关注 execCommand 的错误捕获和回退路径是否完整覆盖边界情况
  • 验证去换行/文本清理逻辑在各种粘贴内容(含富文本、剪贴板格式)下的行为
  • 检查日志输出条件以确保生产环境不会泄露敏感信息
  • 确认回退路径确实保留原有撤销/重做栈行为

🐰 粘贴来字句轻轻飘,
新法先试旧路保,
捕获异常不慌张,
TODO 留待日后改,
兔子点点头笑好。

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 拉取请求标题清晰、简洁,直接反映了主要变更:在 Sender 组件中使用 document.execCommand 来处理粘贴操作,以支持原生撤销/重做功能。
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@Chiaki-xps Chiaki-xps force-pushed the fix-sender-paste-undo-behavior branch from bc10156 to 9f64490 Compare December 15, 2025 13:48
Copy link
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.

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/x/components/sender/SlotTextArea.tsx (1)

714-732: 粘贴逻辑对 submitType 的处理需要与输入处理保持一致

这里的整体设计合理——优先用 document.execCommand('insertText', false, cleanText) 让粘贴进入浏览器原生撤销栈,失败时回退到 insert 路径——但换行清理逻辑存在一个细节不一致:

  • const cleanText = text.replace(/\n/g, ''); 无条件移除所有换行符
  • removeSpecificBRs 只在 submitType === 'enter' 时清理 BR 标签,在 submitType === 'shiftEnter' 模式下会保留 BR(允许多行)

这导致:

  • submitType === 'enter' 模式:手敲和粘贴都是单行 ✓
  • submitType === 'shiftEnter' 模式:手敲换行被保留,但粘贴换行被移除 ✗

如果产品期望两种模式中的换行处理一致,建议按 submitType 条件化 cleanText,例如:

const cleanText =
  submitType === 'enter' ? text.replace(/\n/g, '') : text;

后续逻辑保持不变,统一使用 cleanTextexecCommand + fallback 即可。建议在 shiftEnter 模式下手动测试"粘贴多行文本 + Ctrl+Z 撤销"场景,确认当前行为是否符合交互预期。

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bc10156 and 9f64490.

📒 Files selected for processing (1)
  • packages/x/components/sender/SlotTextArea.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: afc163
Repo: ant-design/x PR: 0
File: :0-0
Timestamp: 2025-04-11T14:47:09.527Z
Learning: 当评审 ant-design/x 仓库中的 PR 时,需要用中文回复中文评论。该项目的文档支持中英双语。
Learnt from: afc163
Repo: ant-design/x PR: 0
File: :0-0
Timestamp: 2025-04-11T14:47:09.527Z
Learning: 当评审 ant-design/x 仓库中的 PR 时,需要用中文回复中文评论。该项目的文档支持中英双语。
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: build preview
  • GitHub Check: size
  • GitHub Check: test

@codecov
Copy link

codecov bot commented Dec 15, 2025

Bundle Report

Changes will decrease total bundle size by 1.19MB (-38.98%) ⬇️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
antdx-array-push 1.75MB -1.19MB (-40.4%) ⬇️

Affected Assets, Files, and Routes:

view changes for bundle: antdx-array-push

Assets Changed:

Asset Name Size Change Total Size Change (%)
antdx.min.js (New) 1.75MB 1.75MB 100.0% 🚀
antdx.js (Deleted) -2.94MB 0 bytes -100.0% 🗑️

@codecov
Copy link

codecov bot commented Dec 16, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.70%. Comparing base (25d73f5) to head (f9fb18a).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1527   +/-   ##
=======================================
  Coverage   94.69%   94.70%           
=======================================
  Files         137      137           
  Lines        3960     3967    +7     
  Branches     1123     1126    +3     
=======================================
+ Hits         3750     3757    +7     
  Misses        207      207           
  Partials        3        3           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant