mirror of
https://github.com/discourse/discourse.git
synced 2025-05-23 07:11:17 +08:00
FIX: support for watched_words_regular_expressions when censoring words
This commit is contained in:
@ -2,14 +2,17 @@ function escapeRegexp(text) {
|
|||||||
return text.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&').replace(/\*/g, "\S*");
|
return text.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&').replace(/\*/g, "\S*");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function censorFn(censoredWords, censoredPattern, replacementLetter) {
|
export function censorFn(censoredWords, censoredPattern, replacementLetter, watchedWordsRegularExpressions) {
|
||||||
|
|
||||||
let patterns = [];
|
let patterns = [];
|
||||||
|
|
||||||
replacementLetter = replacementLetter || "■";
|
replacementLetter = replacementLetter || "■";
|
||||||
|
|
||||||
if (censoredWords && censoredWords.length) {
|
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) {
|
if (censoredPattern && censoredPattern.length > 0) {
|
||||||
@ -20,7 +23,11 @@ export function censorFn(censoredWords, censoredPattern, replacementLetter) {
|
|||||||
let censorRegexp;
|
let censorRegexp;
|
||||||
|
|
||||||
try {
|
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) {
|
if (censorRegexp) {
|
||||||
|
|
||||||
@ -33,7 +40,11 @@ export function censorFn(censoredWords, censoredPattern, replacementLetter) {
|
|||||||
while (m && m[0]) {
|
while (m && m[0]) {
|
||||||
if (m[0].length > original.length) { return original; } // regex is dangerous
|
if (m[0].length > original.length) { return original; } // regex is dangerous
|
||||||
const replacement = new Array(m[0].length+1).join(replacementLetter);
|
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);
|
m = censorRegexp.exec(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ function censorTree(state, censor) {
|
|||||||
export function setup(helper) {
|
export function setup(helper) {
|
||||||
helper.registerOptions((opts, siteSettings) => {
|
helper.registerOptions((opts, siteSettings) => {
|
||||||
opts.censoredPattern = siteSettings.censored_pattern;
|
opts.censoredPattern = siteSettings.censored_pattern;
|
||||||
|
opts.watchedWordsRegularExpressions = siteSettings.watched_words_regular_expressions;
|
||||||
});
|
});
|
||||||
|
|
||||||
helper.registerPlugin(md => {
|
helper.registerPlugin(md => {
|
||||||
@ -33,7 +34,7 @@ export function setup(helper) {
|
|||||||
|
|
||||||
if ((words && words.length > 0) || (patterns && patterns.length > 0)) {
|
if ((words && words.length > 0) || (patterns && patterns.length > 0)) {
|
||||||
const replacement = String.fromCharCode(9632);
|
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));
|
md.core.ruler.push('censored', state => censorTree(state, censor));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -633,6 +633,7 @@ posting:
|
|||||||
default: 30
|
default: 30
|
||||||
min: 1
|
min: 1
|
||||||
watched_words_regular_expressions:
|
watched_words_regular_expressions:
|
||||||
|
client: true
|
||||||
default: false
|
default: false
|
||||||
enable_advanced_editor_preview_sync:
|
enable_advanced_editor_preview_sync:
|
||||||
hidden: true
|
hidden: true
|
||||||
|
@ -607,6 +607,17 @@ QUnit.test("censoring", assert => {
|
|||||||
assert.cooked("No badword or apple here plz.",
|
assert.cooked("No badword or apple here plz.",
|
||||||
"<p>No ■■■■■■■ or ■■■■■ here plz.</p>",
|
"<p>No ■■■■■■■ or ■■■■■ here plz.</p>",
|
||||||
"it handles * as wildcard");
|
"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 => {
|
QUnit.test("code blocks/spans hoisting", assert => {
|
||||||
|
Reference in New Issue
Block a user