discourse/app/assets/javascripts/pretty-text/addon/pretty-text.js
Andrei Prigorshnev 73781c8a96
FIX: Do not consider code-blocks when parsing mentions (#23280)
We have the max_mentions_per_chat_message site settings; when a user tries 
to mention more users than allowed, no one gets mentioned.

Chat messages may contain code-blocks with strings that look like mentions:

  def foo
    @bar + @baz
  end

The problem is that the parsing code considers these as real mentions and counts 
them when checking the limit. This commit fixes the problem.
2023-09-07 16:13:13 +04:00

136 lines
3.0 KiB
JavaScript

import {
cook as cookIt,
setup as setupIt,
} from "pretty-text/engines/discourse-markdown-it";
import { deepMerge } from "discourse-common/lib/object";
import deprecated from "discourse-common/lib/deprecated";
export function registerOption() {
deprecated(
"`registerOption() from `pretty-text` is deprecated. Use `helper.registerOptions()` instead.",
{
since: "2.8.0.beta9",
dropFrom: "2.9.0.beta1",
id: "discourse.pretty-text.registerOption",
}
);
}
// see also: __optInput in PrettyText#cook and PrettyText#markdown,
// the options are passed here and must be explicitly allowed with
// the const options & state below
export function buildOptions(state) {
const {
siteSettings,
getURL,
lookupAvatar,
lookupPrimaryUserGroup,
getTopicInfo,
topicId,
forceQuoteLink,
userId,
getCurrentUser,
currentUser,
lookupAvatarByPostNumber,
lookupPrimaryUserGroupByPostNumber,
formatUsername,
emojiUnicodeReplacer,
lookupUploadUrls,
previewing,
censoredRegexp,
disableEmojis,
customEmojiTranslation,
watchedWordsReplace,
watchedWordsLink,
emojiDenyList,
featuresOverride,
markdownItRules,
additionalOptions,
hashtagTypesInPriorityOrder,
hashtagIcons,
hashtagLookup,
} = state;
let features = {};
if (state.features) {
features = deepMerge(features, state.features);
}
const options = {
sanitize: true,
getURL,
features,
lookupAvatar,
lookupPrimaryUserGroup,
getTopicInfo,
topicId,
forceQuoteLink,
userId,
getCurrentUser,
currentUser,
lookupAvatarByPostNumber,
lookupPrimaryUserGroupByPostNumber,
formatUsername,
emojiUnicodeReplacer,
lookupUploadUrls,
censoredRegexp,
customEmojiTranslation,
allowedHrefSchemes: siteSettings.allowed_href_schemes
? siteSettings.allowed_href_schemes.split("|")
: null,
allowedIframes: siteSettings.allowed_iframes
? siteSettings.allowed_iframes.split("|")
: [],
markdownIt: true,
previewing,
disableEmojis,
watchedWordsReplace,
watchedWordsLink,
emojiDenyList,
featuresOverride,
markdownItRules,
additionalOptions,
hashtagTypesInPriorityOrder,
hashtagIcons,
hashtagLookup,
};
// note, this will mutate options due to the way the API is designed
// may need a refactor
setupIt(options, siteSettings, state);
return options;
}
export default class {
constructor(opts) {
if (!opts) {
opts = buildOptions({ siteSettings: {} });
}
this.opts = opts;
}
disableSanitizer() {
this.opts.sanitizer = this.opts.discourse.sanitizer = (ident) => ident;
}
cook(raw) {
if (!raw || raw.length === 0) {
return "";
}
let result;
result = cookIt(raw, this.opts);
return result ? result : "";
}
parse(markdown, env = {}) {
return this.opts.engine.parse(markdown, env);
}
sanitize(html) {
return this.opts.sanitizer(html).trim();
}
}