FIX: Don't crash the browser when tapping autocomplete suggestions on Android/Gboard (#15076)

FIX: Don’t crash the browser when tapping autocomplete suggestions on Android/Gboard (#15076)

This is a workaround for an annoying bug that crashes the browser when an autocomplete suggestion is selected on Android if the virtual keyboard is Gboard. It’s specific to Gboard because it sometimes sends keydown and keyup events twice for a single key press, more details can be found here: Emoji selector crashes the message editor in Android / Chrome - #24 by Osama - bug - Discourse Meta.

diff --git a/app/assets/javascripts/discourse/app/lib/autocomplete.js b/app/assets/javascripts/discourse/app/lib/autocomplete.js
index 5645050..38ab560 100644
--- a/app/assets/javascripts/discourse/app/lib/autocomplete.js
+++ b/app/assets/javascripts/discourse/app/lib/autocomplete.js
@@ -309,9 +309,22 @@ export default function (options) {
     }
     ul.find("li").click(function () {
       selectedOption = ul.find("li").index(this);
-      completeTerm(autocompleteOptions[selectedOption]);
-      if (!options.single) {
-        me.focus();
+      // hack for Gboard, see meta.discourse.org/t/-/187009/24
+      if (autocompleteOptions == null) {
+        const opts = { ...options, _gboard_hack_force_lookup: true };
+        const forcedAutocompleteOptions = dataSource(prevTerm, opts);
+        forcedAutocompleteOptions?.then((data) => {
+          updateAutoComplete(data);
+          completeTerm(autocompleteOptions[selectedOption]);
+          if (!options.single) {
+            me.focus();
+          }
+        });
+      } else {
+        completeTerm(autocompleteOptions[selectedOption]);
+        if (!options.single) {
+          me.focus();
+        }
       }
       return false;
     });
@@ -398,7 +411,11 @@ export default function (options) {
   }
 
   function dataSource(term, opts) {
-    if (prevTerm === term) {
+    const force = opts._gboard_hack_force_lookup;
+    if (force) {
+      delete opts._gboard_hack_force_lookup;
+    }
+    if (prevTerm === term && !force) {
       return SKIP;
     }
 

GitHub sha: 8fd10e6414cf4eabdb28d2c5bde8a5b25ea4a4df

This commit has been mentioned on Discourse Meta. There might be relevant details there: