diff --git a/app/assets/javascripts/admin/addon/controllers/modals/admin-watched-word-test.js b/app/assets/javascripts/admin/addon/controllers/modals/admin-watched-word-test.js index 3ce120419c0..3ea2618acb2 100644 --- a/app/assets/javascripts/admin/addon/controllers/modals/admin-watched-word-test.js +++ b/app/assets/javascripts/admin/addon/controllers/modals/admin-watched-word-test.js @@ -18,33 +18,45 @@ export default Controller.extend(ModalFunctionality, { ) matches(value, regexpString, words, isReplace, isTag, isLink) { if (!value || !regexpString) { - return; + return []; } - const regexp = new RegExp(regexpString, "ig"); - const matches = value.match(regexp) || []; - if (isReplace || isLink) { - return matches.map((match) => ({ - match, - replacement: words.find((word) => - new RegExp(word.regexp, "ig").test(match) - ).replacement, - })); - } else if (isTag) { - return matches.map((match) => { - const tags = new Set(); - - words.forEach((word) => { - if (new RegExp(word.regexp, "ig").test(match)) { - word.replacement.split(",").forEach((tag) => tags.add(tag)); - } - }); - - return { match, tags: Array.from(tags) }; + const matches = []; + words.forEach((word) => { + const regexp = new RegExp(word.regexp, "gi"); + let match; + while ((match = regexp.exec(value)) !== null) { + matches.push({ + match: match[1], + replacement: word.replacement, + }); + } }); - } + return matches; + } else if (isTag) { + const matches = {}; + words.forEach((word) => { + const regexp = new RegExp(word.regexp, "gi"); + let match; + while ((match = regexp.exec(value)) !== null) { + if (!matches[match[1]]) { + matches[match[1]] = new Set(); + } - return matches; + let tags = matches[match[1]]; + word.replacement.split(",").forEach((tag) => { + tags.add(tag); + }); + } + }); + + return Object.entries(matches).map((entry) => ({ + match: entry[0], + tags: Array.from(entry[1]), + })); + } else { + return value.match(new RegExp(regexpString, "ig")) || []; + } }, }); diff --git a/app/assets/javascripts/admin/addon/templates/watched-words-action.hbs b/app/assets/javascripts/admin/addon/templates/watched-words-action.hbs index 005e4b759b0..6860ac16d3d 100644 --- a/app/assets/javascripts/admin/addon/templates/watched-words-action.hbs +++ b/app/assets/javascripts/admin/addon/templates/watched-words-action.hbs @@ -26,6 +26,10 @@

{{actionDescription}}

+{{#if siteSettings.watched_words_regular_expressions}} +

{{html-safe (i18n "admin.watched_words.regex_warning" basePath=(base-path))}}

+{{/if}} + {{watched-word-form actionKey=actionNameKey action=(action "recordAdded") diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index c4a18377be1..ca725af3940 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -4752,6 +4752,7 @@ en: clear_all: Clear All clear_all_confirm: "Are you sure you want to clear all watched words for the %{action} action?" invalid_regex: 'The watched word "%{word}" is an invalid regular expression.' + regex_warning: 'Watched words are regular expressions and they do not automatically include word boundaries. If you want the regular expression to match whole words, include \b at the start and end of your regular expression.' actions: block: "Block" censor: "Censor"