FIX: support for watched_words_regular_expressions when censoring words

This commit is contained in:
Neil Lalonde 2018-01-10 14:11:14 -05:00
parent 213cc2fe51
commit edb3a7f646
4 changed files with 29 additions and 5 deletions

View File

@ -2,14 +2,17 @@ function escapeRegexp(text) {
return text.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&').replace(/\*/g, "\S*");
}
export function censorFn(censoredWords, censoredPattern, replacementLetter) {
export function censorFn(censoredWords, censoredPattern, replacementLetter, watchedWordsRegularExpressions) {
let patterns = [];
replacementLetter = replacementLetter || "■";
if (censoredWords && censoredWords.length) {
patterns = censoredWords.split("|").map(t => `(${escapeRegexp(t)})`);
patterns = censoredWords.split("|");
if (!watchedWordsRegularExpressions) {
patterns = patterns.map(t => `(${escapeRegexp(t)})`);
}
}
if (censoredPattern && censoredPattern.length > 0) {
@ -20,7 +23,11 @@ export function censorFn(censoredWords, censoredPattern, replacementLetter) {
let censorRegexp;
try {
censorRegexp = new RegExp("(\\b(?:" + patterns.join("|") + ")\\b)(?![^\\(]*\\))", "ig");
if (watchedWordsRegularExpressions) {
censorRegexp = new RegExp("((?:" + patterns.join("|") + "))(?![^\\(]*\\))", "ig");
} else {
censorRegexp = new RegExp("(\\b(?:" + patterns.join("|") + ")\\b)(?![^\\(]*\\))", "ig");
}
if (censorRegexp) {
@ -33,7 +40,11 @@ export function censorFn(censoredWords, censoredPattern, replacementLetter) {
while (m && m[0]) {
if (m[0].length > original.length) { return original; } // regex is dangerous
const replacement = new Array(m[0].length+1).join(replacementLetter);
text = text.replace(new RegExp(`(\\b${escapeRegexp(m[0])}\\b)(?![^\\(]*\\))`, "ig"), replacement);
if (watchedWordsRegularExpressions) {
text = text.replace(new RegExp(`(${escapeRegexp(m[0])})(?![^\\(]*\\))`, "ig"), replacement);
} else {
text = text.replace(new RegExp(`(\\b${escapeRegexp(m[0])}\\b)(?![^\\(]*\\))`, "ig"), replacement);
}
m = censorRegexp.exec(text);
}

View File

@ -25,6 +25,7 @@ function censorTree(state, censor) {
export function setup(helper) {
helper.registerOptions((opts, siteSettings) => {
opts.censoredPattern = siteSettings.censored_pattern;
opts.watchedWordsRegularExpressions = siteSettings.watched_words_regular_expressions;
});
helper.registerPlugin(md => {
@ -33,7 +34,7 @@ export function setup(helper) {
if ((words && words.length > 0) || (patterns && patterns.length > 0)) {
const replacement = String.fromCharCode(9632);
const censor = censorFn(words, patterns, replacement);
const censor = censorFn(words, patterns, replacement, md.options.discourse.watchedWordsRegularExpressions);
md.core.ruler.push('censored', state => censorTree(state, censor));
}
});

View File

@ -633,6 +633,7 @@ posting:
default: 30
min: 1
watched_words_regular_expressions:
client: true
default: false
enable_advanced_editor_preview_sync:
hidden: true

View File

@ -607,6 +607,17 @@ QUnit.test("censoring", assert => {
assert.cooked("No badword or apple here plz.",
"<p>No ■■■■■■■ or ■■■■■ here plz.</p>",
"it handles * as wildcard");
assert.cookedOptions(
"Pleased to meet you, but pleeeease call me later, xyz123",
{ siteSettings: {
watched_words_regular_expressions: true,
censored_pattern: null
},
censoredWords: 'xyz*|plee+ase'
},
"<p>Pleased to meet you, but ■■■■■■■■■ call me later, ■■■123</p>",
"supports words as regular expressions");
});
QUnit.test("code blocks/spans hoisting", assert => {