From 0532a5a43e85cbd2834c19cd749d6db1223ba20e Mon Sep 17 00:00:00 2001 From: Bianca Nenciu <nbianca@users.noreply.github.com> Date: Thu, 9 Sep 2021 12:03:59 +0300 Subject: [PATCH] FIX: Do not replace in mentions and hashtags (#14260) Watched words of type 'replace' or 'link' replaced the text inside mentions or hashtags too, which broke these. These types of watched words must skip any match that has an @ or # before it. --- .../engines/discourse-markdown/watched-words.js | 8 ++++++++ spec/components/pretty_text_spec.rb | 14 ++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/app/assets/javascripts/pretty-text/engines/discourse-markdown/watched-words.js b/app/assets/javascripts/pretty-text/engines/discourse-markdown/watched-words.js index cce39254b90..ec7f26fa147 100644 --- a/app/assets/javascripts/pretty-text/engines/discourse-markdown/watched-words.js +++ b/app/assets/javascripts/pretty-text/engines/discourse-markdown/watched-words.js @@ -119,6 +119,14 @@ export function setup(helper) { continue; } + if ( + matches[ln].index > 0 && + (text[matches[ln].index - 1] === "@" || + text[matches[ln].index - 1] === "#") + ) { + continue; + } + if (matches[ln].index > lastPos) { token = new state.Token("text", "", 0); token.content = text.slice(lastPos, matches[ln].index); diff --git a/spec/components/pretty_text_spec.rb b/spec/components/pretty_text_spec.rb index cf9a2145c01..7acb5e0f3b5 100644 --- a/spec/components/pretty_text_spec.rb +++ b/spec/components/pretty_text_spec.rb @@ -1465,6 +1465,20 @@ HTML expect(PrettyText.cook("f.o")).to match_html("<p>test</p>") end + it "does not replace hashtags and mentions" do + Fabricate(:user, username: "test") + category = Fabricate(:category, slug: "test") + Fabricate(:watched_word, action: WatchedWord.actions[:replace], word: "test", replacement: "discourse") + + expect(PrettyText.cook("@test #test test")).to match_html(<<~HTML) + <p> + <a class="mention" href="/u/test">@test</a> + <a class="hashtag" href="/c/test/#{category.id}">#<span>test</span></a> + discourse + </p> + HTML + end + it "supports overlapping words" do Fabricate(:watched_word, action: WatchedWord.actions[:link], word: "meta", replacement: "https://meta.discourse.org") Fabricate(:watched_word, action: WatchedWord.actions[:replace], word: "iz", replacement: "is")