FIX: Do not suggest Emoji when in open code blocks (#14337)

FIX: Do not suggest Emoji when in open code blocks (#14337)

There was a check for closed code blocks (which had both opening and closing markups), but it did not work for the case when the text ends in an open code block.

diff --git a/app/assets/javascripts/discourse/app/lib/utilities.js b/app/assets/javascripts/discourse/app/lib/utilities.js
index d644ffc..e9cdaaf 100644
--- a/app/assets/javascripts/discourse/app/lib/utilities.js
+++ b/app/assets/javascripts/discourse/app/lib/utilities.js
@@ -469,19 +469,22 @@ const CODE_BLOCKS_REGEX = /^(    |\t).*|`[^`]+`|^`‍``[^]*?^`‍``|\[code\][^]*?\[\/c
 //                               |
 //                               +------- paragraphs starting with 4 spaces or tab
 
-export function inCodeBlock(text, pos) {
-  let result = false;
+const OPEN_CODE_BLOCKS_REGEX = /`[^`]+|^`‍``[^]*?|\[code\][^]*?/gm;
 
-  let match;
-  while ((match = CODE_BLOCKS_REGEX.exec(text)) !== null) {
-    const begin = match.index;
-    const end = match.index + match[0].length;
-    if (begin <= pos && pos <= end) {
-      result = true;
+export function inCodeBlock(text, pos) {
+  let end = 0;
+  for (const match of text.matchAll(CODE_BLOCKS_REGEX)) {
+    end = match.index + match[0].length;
+    if (match.index <= pos && pos <= end) {
+      return true;
     }
   }
 
-  return result;
+  // Character at position `pos` can be in a code block that is unfinished.
+  // To check this case, we look for any open code blocks after the last closed
+  // code block.
+  const lastOpenBlock = text.substr(end).search(OPEN_CODE_BLOCKS_REGEX);
+  return lastOpenBlock !== -1 && pos >= end + lastOpenBlock;
 }
 
 // This prevents a mini racer crash
diff --git a/app/assets/javascripts/discourse/tests/unit/lib/utilities-test.js b/app/assets/javascripts/discourse/tests/unit/lib/utilities-test.js
index 6739b72..c863511 100644
--- a/app/assets/javascripts/discourse/tests/unit/lib/utilities-test.js
+++ b/app/assets/javascripts/discourse/tests/unit/lib/utilities-test.js
@@ -251,18 +251,28 @@ discourseModule("Unit | Utilities", function () {
   });
 
   test("inCodeBlock", function (assert) {
-    const text =
-      "000\n\n`‍``\n111\n`‍``\n\n000\n\n`111 111`\n\n000\n\n[code]\n111\n[/code]\n\n    111\n\t111\n\n000`000";
-    for (let i = 0; i < text.length; ++i) {
-      if (text[i] === "0") {
-        assert.notOk(
-          inCodeBlock(text, i),
-          `position ${i} is not in code block`
-        );
-      } else if (text[i] === "1") {
-        assert.ok(inCodeBlock(text, i), `position ${i} is in code block`);
+    const texts = [
+      // closed code blocks
+      "000\n\n    111\n\n000",
+      "000 `111` 000",
+      "000\n`‍``\n111\n`‍``\n000",
+      "000\n[code]111[/code]\n000",
+      // open code blocks
+      "000\n\n    111",
+      "000 `111",
+      "000\n`‍``\n111",
+      "000\n[code]111",
+      // complex test
+      "000\n\n`‍``\n111\n`‍``\n\n000\n\n`111 111`\n\n000\n\n[code]\n111\n[/code]\n\n    111\n\t111\n\n000`111",
+    ];
+
+    texts.forEach((text) => {
+      for (let i = 0; i < text.length; ++i) {
+        if (text[i] === "0" || text[i] === "1") {
+          assert.equal(inCodeBlock(text, i), text[i] === "1");
+        }
       }
-    }
+    });
   });
 
   skip("inCodeBlock - runs fast", function (assert) {

GitHub sha: 856732786fd9ba723303c922c688a7e090ebabd9

This commit appears in #14337 which was approved by eviltrout. It was merged by udan11.