Revert "FIX: Do not autocomplete categories or emojis in code blocks (#8433)"

Revert “FIX: Do not autocomplete categories or emojis in code blocks (#8433)”

This reverts commit b643526d9a407b8abb826dba78a954cdfe6d6133.

Sadly this introduces a regex runaway CPU condition, we will re-work this so it is safe.

diff --git a/app/assets/javascripts/discourse/components/d-editor.js.es6 b/app/assets/javascripts/discourse/components/d-editor.js.es6
index e0b745a47f..e668828ccb 100644
--- a/app/assets/javascripts/discourse/components/d-editor.js.es6
+++ b/app/assets/javascripts/discourse/components/d-editor.js.es6
@@ -20,9 +20,7 @@ import { siteDir } from "discourse/lib/text-direction";
 import {
   determinePostReplaceSelection,
   clipboardData,
-  safariHacksDisabled,
-  caretPosition,
-  inCodeBlock
+  safariHacksDisabled
 } from "discourse/lib/utilities";
 import toMarkdown from "discourse/lib/to-markdown";
 import deprecated from "discourse-common/lib/deprecated";
@@ -422,10 +420,6 @@ export default Component.extend({
       },
 
       onKeyUp: (text, cp) => {
-        if (inCodeBlock(text, cp)) {
-          return false;
-        }
-
         const matches = /(?:^|[^a-z])(:(?!:).?[\w-]*:?(?!:)(?:t\d?)?:?) ?$/gi.exec(
           text.substring(0, cp)
         );
@@ -517,10 +511,7 @@ export default Component.extend({
             }
             return list;
           });
-      },
-
-      triggerRule: textarea =>
-        !inCodeBlock(textarea.value, caretPosition(textarea))
+      }
     });
   },
 
diff --git a/app/assets/javascripts/discourse/lib/category-hashtags.js.es6 b/app/assets/javascripts/discourse/lib/category-hashtags.js.es6
index 28042fff16..cac265f259 100644
--- a/app/assets/javascripts/discourse/lib/category-hashtags.js.es6
+++ b/app/assets/javascripts/discourse/lib/category-hashtags.js.es6
@@ -1,9 +1,5 @@
 export const SEPARATOR = ":";
-import {
-  caretRowCol,
-  caretPosition,
-  inCodeBlock
-} from "discourse/lib/utilities";
+import { caretRowCol } from "discourse/lib/utilities";
 
 export function replaceSpan($elem, categorySlug, categoryLink) {
   $elem.replaceWith(
@@ -25,14 +21,10 @@ export function categoryHashtagTriggerRule(textarea, opts) {
     if (/^#{1}\w+/.test(line)) return false;
   }
 
-  // Don't trigger autocomplete when ATX-style headers are used
-  if (col < 6 && line.slice(0, col) === "#".repeat(col)) {
-    return false;
+  if (col < 6) {
+    // Don't trigger autocomplete when ATX-style headers are used
+    return line.slice(0, col) !== "#".repeat(col);
+  } else {
+    return true;
   }
-
-  if (inCodeBlock(textarea.value, caretPosition(textarea))) {
-    return false;
-  }
-
-  return true;
 }
diff --git a/app/assets/javascripts/discourse/lib/utilities.js.es6 b/app/assets/javascripts/discourse/lib/utilities.js.es6
index 4ab8eb7ccb..145674f3a5 100644
--- a/app/assets/javascripts/discourse/lib/utilities.js.es6
+++ b/app/assets/javascripts/discourse/lib/utilities.js.es6
@@ -410,44 +410,5 @@ export function rescueThemeError(name, error, api) {
   document.body.prepend(alertDiv);
 }
 
-const CODE_BLOCKS_RULES = [
-  { rule: /`(?:[^`\n]+?\n?)+?`/gm, end: "`" },
-  { rule: /^`‍``[^]*?^`‍``/gm, end: "\n`‍``" },
-  { rule: /\[code\][^]*?\[\/code\]/gm, end: "\n[/code]" }
-];
-
-export function getCodeBlocks(value) {
-  const blocks = [];
-
-  CODE_BLOCKS_RULES.forEach(entry => {
-    const { rule, end } = entry;
-
-    let match;
-    while ((match = rule.exec(value)) != null) {
-      blocks.push([match.index, match.index + match[0].length]);
-    }
-
-    // Try to end block and see if other code blocks are found
-    if (end) {
-      while ((match = rule.exec(value + end)) != null) {
-        // Save only positions that were not found before (which end past the
-        // end of the original value).
-        if (
-          match.index < value.length &&
-          match.index + match[0].length > value.length
-        ) {
-          blocks.push([match.index, value.length]);
-        }
-      }
-    }
-  });
-
-  return blocks;
-}
-
-export function inCodeBlock(value, pos) {
-  return getCodeBlocks(value).any(([start, end]) => start <= pos && pos <= end);
-}
-
 // This prevents a mini racer crash
 export default {};
diff --git a/test/javascripts/lib/utilities-test.js.es6 b/test/javascripts/lib/utilities-test.js.es6
index 46c00735bf..39c9b0635a 100644
--- a/test/javascripts/lib/utilities-test.js.es6
+++ b/test/javascripts/lib/utilities-test.js.es6
@@ -9,9 +9,7 @@ import {
   setDefaultHomepage,
   caretRowCol,
   setCaretPosition,
-  fillMissingDates,
-  getCodeBlocks,
-  inCodeBlock
+  fillMissingDates
 } from "discourse/lib/utilities";
 
 QUnit.module("lib:utilities");
@@ -188,50 +186,3 @@ QUnit.test("fillMissingDates", assert => {
     "it returns a JSON array with 31 dates"
   );
 });
-
-QUnit.test("getCodeBlocks - works with [code]", assert => {
-  assert.deepEqual(
-    getCodeBlocks("[code]\nfoo\n[/code]\n\nbar\n\n[code]\nbaz"),
-    [
-      [0, 18],
-      [25, 35]
-    ]
-  );
-});
-
-QUnit.test("getCodeBlocks - works with backticks", assert => {
-  assert.deepEqual(getCodeBlocks("foo `bar\nbar`! `baz"), [
-    [4, 13],
-    [15, 19]
-  ]);
-});
-
-QUnit.test("getCodeBlocks - works with triple backticks", assert => {
-  assert.deepEqual(getCodeBlocks("`‍``\nfoo\n`‍``\n\nbar\n\n`‍``\nbaz"), [
-    [0, 11],
-    [18, 25]
-  ]);
-});
-
-QUnit.test("inCodeBlock", assert => {
-  const raw =
-    "bar\n\n`‍``\nfoo\n`‍``\n\nbar\n\n`foo\nfoo`\n\nbar\n\n[code]\nfoo\n[/code]\n\nbar`foo";
-
-  assert.notOk(inCodeBlock(raw, 4));
-  assert.ok(inCodeBlock(raw, 5));
-  assert.ok(inCodeBlock(raw, 16));
-  assert.notOk(inCodeBlock(raw, 17));
-
-  assert.notOk(inCodeBlock(raw, 22));
-  assert.ok(inCodeBlock(raw, 23));
-  assert.ok(inCodeBlock(raw, 32));
-  assert.notOk(inCodeBlock(raw, 33));
-
-  assert.notOk(inCodeBlock(raw, 38));
-  assert.ok(inCodeBlock(raw, 39));
-  assert.ok(inCodeBlock(raw, 57));
-  assert.notOk(inCodeBlock(raw, 58));
-
-  assert.notOk(inCodeBlock(raw, 61));
-  assert.ok(inCodeBlock(raw, 62));
-});

GitHub sha: f65c4535

1 Like

For the record, the reason this commit was reverted is the first regular expression, which is super expensive.

2 Likes