FIX: Make replace watched words work with wildcard (#13084)

Watched words are always regular expressions, despite watched_words_
_regular_expressions being enabled or not. Internally, wildcard
characters are replaced with a regular expression that matches any non
whitespace character.
This commit is contained in:
Bianca Nenciu
2021-05-18 12:09:47 +03:00
committed by GitHub
parent a21700a444
commit c1dfd76658
5 changed files with 35 additions and 48 deletions
@@ -6,50 +6,30 @@ function isLinkClose(str) {
return /^<\/a\s*>/i.test(str);
}
function findAllMatches(text, matchers, useRegExp) {
function findAllMatches(text, matchers) {
const matches = [];
if (useRegExp) {
const maxMatches = 100;
let count = 0;
const maxMatches = 100;
let count = 0;
matchers.forEach((matcher) => {
let match;
while (
(match = matcher.pattern.exec(text)) !== null &&
count++ < maxMatches
) {
matches.push({
index: match.index,
text: match[0],
replacement: matcher.replacement,
});
}
});
} else {
const lowerText = text.toLowerCase();
matchers.forEach((matcher) => {
const lowerPattern = matcher.pattern.toLowerCase();
let index = -1;
while ((index = lowerText.indexOf(lowerPattern, index + 1)) !== -1) {
matches.push({
index,
text: text.substr(index, lowerPattern.length),
replacement: matcher.replacement,
});
}
});
}
matchers.forEach((matcher) => {
let match;
while (
(match = matcher.pattern.exec(text)) !== null &&
count++ < maxMatches
) {
matches.push({
index: match.index,
text: match[0],
replacement: matcher.replacement,
});
}
});
return matches.sort((a, b) => a.index - b.index);
}
export function setup(helper) {
helper.registerOptions((opts, siteSettings) => {
opts.watchedWordsRegularExpressions =
siteSettings.watched_words_regular_expressions;
});
helper.registerPlugin((md) => {
const replacements = md.options.discourse.watchedWordsReplacements;
if (!replacements) {
@@ -57,9 +37,7 @@ export function setup(helper) {
}
const matchers = Object.keys(replacements).map((word) => ({
pattern: md.options.discourse.watchedWordsRegularExpressions
? new RegExp(word, "gi")
: word,
pattern: new RegExp(word, "gi"),
replacement: replacements[word],
}));
@@ -110,12 +88,7 @@ export function setup(helper) {
if (currentToken.type === "text") {
const text = currentToken.content;
const matches = (cache[text] =
cache[text] ||
findAllMatches(
text,
matchers,
md.options.discourse.watchedWordsRegularExpressions
));
cache[text] || findAllMatches(text, matchers));
// Now split string to nodes
const nodes = [];