discourse/app/assets/javascripts/pretty-text/engines/discourse-markdown/quotes.js.es6

174 lines
4.5 KiB
JavaScript

import { performEmojiUnescape } from "pretty-text/emoji";
const rule = {
tag: "quote",
before(state, tagInfo) {
const attrs = tagInfo.attrs;
let options = state.md.options.discourse;
let quoteInfo = attrs["_default"];
let username,
postNumber,
topicId,
avatarImg,
primaryGroupName,
full,
displayName;
if (quoteInfo) {
let split = quoteInfo.split(/\,\s*/);
username = split[0];
let i;
for (i = 1; i < split.length; i++) {
if (split[i].indexOf("post:") === 0) {
postNumber = parseInt(split[i].substr(5), 10);
continue;
}
if (split[i].indexOf("topic:") === 0) {
topicId = parseInt(split[i].substr(6), 10);
continue;
}
if (/full:\s*true/.test(split[i])) {
full = true;
continue;
}
}
}
if (options.lookupAvatarByPostNumber) {
// client-side, we can retrieve the avatar from the post
avatarImg = options.lookupAvatarByPostNumber(postNumber, topicId);
} else if (options.lookupAvatar) {
// server-side, we need to lookup the avatar from the username
avatarImg = options.lookupAvatar(username);
}
if (options.lookupPrimaryUserGroupByPostNumber) {
// client-side, we can retrieve the primary user group from the post
primaryGroupName = options.lookupPrimaryUserGroupByPostNumber(
postNumber,
topicId
);
} else if (options.lookupPrimaryUserGroup) {
// server-side, we need to lookup the primary user group from the username
primaryGroupName = options.lookupPrimaryUserGroup(username);
}
if (options.formatUsername) {
displayName = options.formatUsername(username);
} else {
displayName = username;
}
let token = state.push("bbcode_open", "aside", 1);
token.attrs = [];
if (primaryGroupName && primaryGroupName.length !== 0) {
token.attrs.push(["class", `quote group-${primaryGroupName}`]);
} else {
token.attrs.push(["class", "quote no-group"]);
}
if (postNumber) {
token.attrs.push(["data-post", postNumber]);
}
if (topicId) {
token.attrs.push(["data-topic", topicId]);
}
if (full) {
token.attrs.push(["data-full", "true"]);
}
if (username) {
let offTopicQuote =
options.topicId &&
postNumber &&
options.getTopicInfo &&
topicId !== options.topicId;
// on topic quote
token = state.push("quote_header_open", "div", 1);
token.attrs = [["class", "title"]];
token = state.push("quote_controls_open", "div", 1);
token.attrs = [["class", "quote-controls"]];
token = state.push("quote_controls_close", "div", -1);
if (avatarImg) {
token = state.push("html_inline", "", 0);
token.content = avatarImg;
}
if (offTopicQuote) {
const topicInfo = options.getTopicInfo(topicId);
if (topicInfo) {
var href = topicInfo.href;
if (postNumber > 0) {
href += "/" + postNumber;
}
let title = topicInfo.title;
if (options.enableEmoji) {
title = performEmojiUnescape(topicInfo.title, {
getURL: options.getURL,
emojiSet: options.emojiSet
});
}
token = state.push("link_open", "a", 1);
token.attrs = [["href", href]];
token.block = false;
token = state.push("html_inline", "", 0);
token.content = title;
token = state.push("link_close", "a", -1);
token.block = false;
}
} else {
token = state.push("text", "", 0);
token.content = ` ${displayName}:`;
}
token = state.push("quote_header_close", "div", -1);
}
token = state.push("bbcode_open", "blockquote", 1);
},
after: function(state) {
state.push("bbcode_close", "blockquote", -1);
state.push("bbcode_close", "aside", -1);
}
};
export function setup(helper) {
helper.registerOptions((opts, siteSettings) => {
opts.enableEmoji = siteSettings.enable_emoji;
opts.emojiSet = siteSettings.emoji_set;
});
helper.registerPlugin(md => {
md.block.bbcode.ruler.push("quotes", rule);
});
helper.whiteList(["img[class=avatar]"]);
helper.whiteList({
custom(tag, name, value) {
if (tag === "aside" && name === "class") {
return (
value === "quote no-group" || !!/^quote group\-(.+)$/.exec(value)
);
}
}
});
}