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.
This commit is contained in:
Dan Ungureanu 2021-09-14 17:37:14 +03:00 committed by GitHub
parent 5cce1b38e4
commit 856732786f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 20 deletions

View File

@ -469,19 +469,22 @@ const CODE_BLOCKS_REGEX = /^( |\t).*|`[^`]+`|^```[^]*?^```|\[code\][^]*?\[\/c
// | // |
// +------- paragraphs starting with 4 spaces or tab // +------- paragraphs starting with 4 spaces or tab
const OPEN_CODE_BLOCKS_REGEX = /`[^`]+|^```[^]*?|\[code\][^]*?/gm;
export function inCodeBlock(text, pos) { export function inCodeBlock(text, pos) {
let result = false; let end = 0;
for (const match of text.matchAll(CODE_BLOCKS_REGEX)) {
let match; end = match.index + match[0].length;
while ((match = CODE_BLOCKS_REGEX.exec(text)) !== null) { if (match.index <= pos && pos <= end) {
const begin = match.index; return true;
const end = match.index + match[0].length;
if (begin <= pos && pos <= end) {
result = 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 // This prevents a mini racer crash

View File

@ -251,19 +251,29 @@ discourseModule("Unit | Utilities", function () {
}); });
test("inCodeBlock", function (assert) { test("inCodeBlock", function (assert) {
const text = const texts = [
"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"; // 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) { for (let i = 0; i < text.length; ++i) {
if (text[i] === "0") { if (text[i] === "0" || text[i] === "1") {
assert.notOk( assert.equal(inCodeBlock(text, i), text[i] === "1");
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`);
} }
} }
}); });
});
skip("inCodeBlock - runs fast", function (assert) { skip("inCodeBlock - runs fast", function (assert) {
const phrase = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."; const phrase = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";