summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/notification.go4
-rw-r--r--app/notification_test.go6
-rw-r--r--webapp/tests/utils/post_utils.test.jsx54
-rw-r--r--webapp/utils/post_utils.jsx12
4 files changed, 71 insertions, 5 deletions
diff --git a/app/notification.go b/app/notification.go
index b0a5d83ad..c86e1669f 100644
--- a/app/notification.go
+++ b/app/notification.go
@@ -839,14 +839,14 @@ func GetExplicitMentions(message string, keywords map[string][]string) (map[stri
// Matches a line containing only ``` and a potential language definition, any number of lines not containing ```,
// and then either a line containing only ``` or the end of the text
-var codeBlockPattern = regexp.MustCompile("(?m)^[^\\S\n]*\\`\\`\\`.*$[\\s\\S]+?(^[^\\S\n]*\\`\\`\\`$|\\z)")
+var codeBlockPattern = regexp.MustCompile("(?m)^[^\\S\n]*[\\`~]{3}.*$[\\s\\S]+?(^[^\\S\n]*[`~]{3}$|\\z)")
// Matches a backquote, either some text or any number of non-empty lines, and then a final backquote
var inlineCodePattern = regexp.MustCompile("(?m)\\`+(?:.+?|.*?\n(.*?\\S.*?\n)*.*?)\\`+")
// Strips pre-formatted text and code blocks from a Markdown string by replacing them with whitespace
func removeCodeFromMessage(message string) string {
- if strings.Contains(message, "```") {
+ if strings.Contains(message, "```") || strings.Contains(message, "~~~") {
message = codeBlockPattern.ReplaceAllString(message, "")
}
diff --git a/app/notification_test.go b/app/notification_test.go
index 02b6e1db0..e0c1a54e6 100644
--- a/app/notification_test.go
+++ b/app/notification_test.go
@@ -399,6 +399,12 @@ func TestRemoveCodeFromMessage(t *testing.T) {
if actual := removeCodeFromMessage(input); actual != expected {
t.Fatalf("received incorrect output\n\nGot:\n%v\n\nExpected:\n%v\n", actual, expected)
}
+
+ input = "this is text with\n~~~\na code block\n~~~\nin it"
+ expected = "this is text with\n\nin it"
+ if actual := removeCodeFromMessage(input); actual != expected {
+ t.Fatalf("received incorrect output\n\nGot:\n%v\n\nExpected:\n%v\n", actual, expected)
+ }
}
func TestGetMentionKeywords(t *testing.T) {
diff --git a/webapp/tests/utils/post_utils.test.jsx b/webapp/tests/utils/post_utils.test.jsx
index 0546d5bea..bcb5c039e 100644
--- a/webapp/tests/utils/post_utils.test.jsx
+++ b/webapp/tests/utils/post_utils.test.jsx
@@ -4,8 +4,8 @@ describe('PostUtils.containsAtMention', function() {
test('should return correct @all (same for @channel)', function() {
for (const data of [
{
- text: undefined, //eslint-disable-line no-undefined
- key: undefined, //eslint-disable-line no-undefined
+ text: undefined, // eslint-disable-line no-undefined
+ key: undefined, // eslint-disable-line no-undefined
result: false
},
{
@@ -87,6 +87,56 @@ describe('PostUtils.containsAtMention', function() {
text: 'hey @ALL:+1:',
key: '@all',
result: true
+ },
+ {
+ text: '`@all`',
+ key: '@all',
+ result: false
+ },
+ {
+ text: '@someone `@all`',
+ key: '@all',
+ result: false
+ },
+ {
+ text: '@someone `@all`',
+ key: '@someone',
+ result: true
+ },
+ {
+ text: '``@all``',
+ key: '@all',
+ result: false
+ },
+ {
+ text: '```@all```',
+ key: '@all',
+ result: false
+ },
+ {
+ text: '```\n@all\n```',
+ key: '@all',
+ result: false
+ },
+ {
+ text: '```````\n@all\n```````',
+ key: '@all',
+ result: false
+ },
+ {
+ text: '```code\n@all\n```',
+ key: '@all',
+ result: false
+ },
+ {
+ text: '~~~@all~~~',
+ key: '@all',
+ result: true
+ },
+ {
+ text: '~~~\n@all\n~~~',
+ key: '@all',
+ result: false
}
]) {
const containsAtMention = PostUtils.containsAtMention(data.text, data.key);
diff --git a/webapp/utils/post_utils.jsx b/webapp/utils/post_utils.jsx
index 1ff16a5ab..d37e6c26d 100644
--- a/webapp/utils/post_utils.jsx
+++ b/webapp/utils/post_utils.jsx
@@ -113,5 +113,15 @@ export function containsAtMention(text, key) {
}
// This doesn't work for at mentions containing periods or hyphens
- return new RegExp(`\\B${key}\\b`, 'i').test(text);
+ return new RegExp(`\\B${key}\\b`, 'i').test(removeCode(text));
+}
+
+// Returns a given text string with all Markdown code replaced with whitespace.
+export function removeCode(text) {
+ // These patterns should match the ones in app/notification.go, except JavaScript doesn't
+ // support \z for the end of the text in multiline mode, so we use $(?![\r\n])
+ const codeBlockPattern = /^[^\S\n]*[`~]{3}.*$[\s\S]+?(^[^\S\n]*[`~]{3}$|$(?![\r\n]))/m;
+ const inlineCodePattern = /`+(?:.+?|.*?\n(.*?\S.*?\n)*.*?)`+/m;
+
+ return text.replace(codeBlockPattern, '').replace(inlineCodePattern, ' ');
}