Android 上引用文本的弹出菜单无响应

AI (GPT 5.6 Sol Ultra) 在 Codex 中的诊断(如有用):

找到了:Discourse Reactions 泄漏了一个全局的“禁止文本选择”状态。

  • plugins/discourse-reactions/assets/javascripts/discourse/components/discourse-reactions-actions.gjs:222 中,Reaction 的 touchstart 事件会向 <html> 添加 discourse-reactions-no-select 类。
  • 该类在 plugins/discourse-reactions/assets/stylesheets/common/discourse-reactions.scss:1 中应用了 user-select: none,并禁用了整个文档中 WebKit 的长按呼出菜单。
  • 如果垂直滚动从 Reaction 按钮上方开始,plugins/discourse-reactions/assets/javascripts/discourse/components/discourse-reactions-actions.gjs:249 会使手势无效,但未移除该类。
  • 随后 plugins/discourse-reactions/assets/javascripts/discourse/components/discourse-reactions-actions.gjs:257 提前返回,导致该类永久残留。
  • 此外,也没有针对 touchcancel 或组件销毁的清理逻辑。

唯一的移除逻辑位于 plugins/discourse-reactions/assets/javascripts/discourse/components/discourse-reactions-actions.gjs:690。这解释了报告中提到的变通方法(https://meta.discourse.org/t/the-popup-menu-for-quoting-text-is-unresponsive-on-android/407332):打开并关闭 Reaction 弹出窗口会调用 collapseAllPanels(),从而恢复选择功能。

引用工具栏本身处于下游——它监听 selectionchange 事件,并在 frontend/discourse/app/components/post-text-selection.gjs:58 中需要真实的浏览器选择。由于全局设置了 user-select: none,Android 浏览器永远不会创建该选择。

历史记录证实了这一类 Bug:2023 年的一项滚动修复(https://github.com/discourse/discourse-reactions/commit/d1970cf750e82a3035e05ddc3d52733a5c76a6ab)引入了无效触摸的提前返回逻辑,而 2024 年的一项部分修复(https://github.com/discourse/discourse-reactions/commit/c6710ef909481fd2fc16c10405f3daa92b6481fc)将清理逻辑移至面板折叠时,但遗漏了滚动和取消路径。

修复方案应在每个已完成、被拒绝、被取消或销毁的触摸生命周期中清除该类,并为 touchstart → touchmove → touchendtouchcancel 添加回归测试。

3 个赞