该问题已存在数月,我可以在 Meta 使用 Android/Chrome 设备(均为最新版本)复现此问题——实际上,该问题自 1 月左右以来已发生数月。
消息编辑器在选择建议的表情符号时似乎会不时“崩溃”。
复现步骤:
- 回复某个主题,添加一些文本
- 输入“:+1”开始添加大拇指表情,然后点击建议的表情符号

发生的情况:
编辑器似乎会崩溃或重新绘制。通常会导致部分已输入的文本丢失。
该问题并非 100% 可复现,但我可以在随意操作的一分钟内轻松触发此问题。
该问题已存在数月,我可以在 Meta 使用 Android/Chrome 设备(均为最新版本)复现此问题——实际上,该问题自 1 月左右以来已发生数月。
消息编辑器在选择建议的表情符号时似乎会不时“崩溃”。
编辑器似乎会崩溃或重新绘制。通常会导致部分已输入的文本丢失。
该问题并非 100% 可复现,但我可以在随意操作的一分钟内轻松触发此问题。
您具体使用的是哪个版本的 Android 或 Chrome?
我可以复现。以下是堆栈跟踪:
_application-bfbda341c2eb6dd7d61c681e17bdccec057c30e045ddc332927a7363150e9b1b.js:16386 Uncaught TypeError: Cannot read property '0' of null
at HTMLLIElement.<anonymous> (application-bfbda341c2eb6dd7d61c681e17bdccec057c30e045ddc332927a7363150e9b1b.br.js:1)
at HTMLLIElement.dispatch (ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.br.js:1)
at HTMLLIElement.d.handle (ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.br.js:1)
(anonymous) @ application-bfbda341c2eb6dd7d61c681e17bdccec057c30e045ddc332927a7363150e9b1b.br.js:1
dispatch @ ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.br.js:1
d.handle @ ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.br.js:1
问题出在这一行:
错误发生的原因是 selectedOption 为 0(即单个建议,也就是第一个),而 autocompleteOptions 不知为何为 null。
我正在调查原因……
目前我还不确定具体原因。起初我怀疑是 @Osama 的这个 PR:
但我添加了不少断点,却仍然无法找到究竟是谁在修改 autocompleteOptions 并将其设为 null。
autocompleteOptions 来自上方两层父级闭包的作用域,这一点也非常奇怪,使得代码更难追踪和调试。
Android 11 / Chrome 89,为当前最新版本。
是的,对我来说在 Chrome Android 上仍然会崩溃。你必须 100% 遵循说明才能复现,因为条件非常具体。
刚刚尝试了一下,但无法轻易复现此问题。不过我相当确定,今年夏天我曾偶然在撰写真实帖子时遇到过几次。
编辑:我会询问我们的社区,看他们能否提供更全面的测试覆盖。
编辑 2:哦对了,我现在自己复现了。我们的社区正在进行测试,看起来普通用户也复现了更多情况。
不小心又复现了,所以这个 issue 仍然处于打开状态。
我们仍然将此问题列入我们的清单,只是发现它极难复现和调试。
我实在无法为此添加 pr-welcome 标签,因为难度实在太大。我们稍后会重新审视此问题,并为其设定一个 6 个月的期限。
此问题是否仍然存在?
是的,仍然存在。就我个人而言,我经过 15 分钟的激烈测试仍无法复现该问题,因此我请求社区提供支持。几位用户成功复现了该问题,其中一人甚至通过 截图 进行了证明。症状未变:一旦在选择器中点击“竖起大拇指”表情符号,键盘就会收起,编辑器中已输入的部分内容会丢失。
我过去很容易复现此问题,但现在似乎无法准确重现。因此,该问题确实存在,但复现率并非 100%。我们将继续测试,试图找出是否有某个 UI 操作步骤会触发此问题。
能否请能够复现该问题的人,看看他们是否能在 try.discourse.org 上复现?
我刚刚在不刻意尝试的情况下就重现了它。
Firefox 94.1.1 (Build #2015842491)
以及 Chrome 95.0.4638.74
我觉得非原生平台的表情符号选择器才是真正的问题所在。
最简单的解决方法是,使用您选择的操作系统中的原生表情符号选择器?
当然,通常有一个变通办法。不一定总是如此,例如,Discourse 上可能正在使用自定义表情符号。
无论如何,重新加载页面并丢失已写内容是一种糟糕的行为,我们应该修复它。
好的,我今天又看了一下,在将手机上的虚拟键盘切换到 Gboard 后,我成功重现了这个问题。Gboard 有时会对单个按键操作触发两次 keydown 和 keyup 事件,如果这发生在您在从自动补全中选择表情符号之前按下的最后一个键,就会导致崩溃。
我不确定是什么原因导致 Gboard 触发这些事件两次,但这似乎取决于您输入的内容和您的 Gboard 设置。
这两个事件导致崩溃的原因在于我们的自动补全库的设计方式。该库会监听 keydown 和 keyup 事件,在 keydown 时清除自动补全建议,在 keyup 时根据新的自动补全词条提供新建议。
但是,有一个小的保护/优化措施可以防止库在词条自上次建议以来未更改时执行重复工作,而问题就出在这里。第一对 keydown 和 keyup 事件会按预期清除旧建议并提供新建议,但第二对错误的事件会在 keydown 时再次清除建议,但在 keyup 时不会提供新建议,因为自动补全词条没有改变。
我能想到的唯一最不“hacky”的“修复”方法是移除保护/优化措施,让库在 keyup 时始终提供新建议,但我不知道这是否是期望的,或者是否值得这样做。
我知道我们最终想要重写我们的自动补全库(它是代码库中最古老的部分之一,急需重写),所以也许这个 bug 可以等到我们重写的时候再处理?
这次崩溃是某种“无限循环”吗?我们能否简单地跟踪我们刚刚进入的反馈循环并清理事物?
不,崩溃是访问了一个空变量。当建议被清除时,autocompleteOptions 变量被设置为 null,然后当我们点击渲染的建议之一时,我们期望 autocompleteOptions 是一个数组,但它是 null。
这给了我另一个想法:也许我们可以在选择建议时检查 autocompleteOptions 是否为 null,如果变量为 null,那么我们为给定的术语重新获取建议?
是的,这听起来是一个不错的解决方法。
啊,我真笨,竟然没注意到这个细节。我的上一部手机是纯净版安卓一号,所以它默认就安装了 Gboard,而且它一直跟着我到了下一部设备(三星 A42 5G)。但如今市面上销售的大多数安卓设备默认都使用第三方键盘应用。
很高兴看到这项进展。
我已经合并了此错误的修复程序:
修复程序已部署到 Meta 和您的站点 @ljpp,请告知我您的用户是否仍然可以重现此问题。