From f65c4535556eeff24944369d6f262ef6be147eec Mon Sep 17 00:00:00 2001 From: Sam Saffron Date: Tue, 3 Dec 2019 09:27:26 +1100 Subject: [PATCH] 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. --- .../discourse/components/d-editor.js.es6 | 13 +---- .../discourse/lib/category-hashtags.js.es6 | 20 +++----- .../discourse/lib/utilities.js.es6 | 39 -------------- test/javascripts/lib/utilities-test.js.es6 | 51 +------------------ 4 files changed, 9 insertions(+), 114 deletions(-) diff --git a/app/assets/javascripts/discourse/components/d-editor.js.es6 b/app/assets/javascripts/discourse/components/d-editor.js.es6 index e0b745a47f8..e668828ccbf 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 28042fff160..cac265f259e 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 4ab8eb7ccb2..145674f3a57 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 46c00735bf3..39c9b0635a5 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)); -});