chore: Use markdown-it instead of marked (#6123)

* chore: Use markdown-it instead of marked

* Adds styling for markdown rendered content

* fixes codeclimate issue

* Fixes blockquote styles for widget in darkmode

* fix: issue block quote color issue in light mode

* fix: issue block quote color issue in light mode

* Fixes blockquote color in dark mode

* Remove usage of dark mode mixin in user bubble

* chore: code clean up

---------

Co-authored-by: Nithin David Thomas <1277421+nithindavid@users.noreply.github.com>
Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
Co-authored-by: iamsivin <iamsivin@gmail.com>
This commit is contained in:
Pranav Raj S
2023-03-02 23:56:54 -08:00
committed by GitHub
parent ec04ddc725
commit 2a385f377c
13 changed files with 332 additions and 106 deletions

View File

@@ -1,57 +1,49 @@
import { marked } from 'marked';
import DOMPurify from 'dompurify';
import { escapeHtml, afterSanitizeAttributes } from './HTMLSanitizer';
import mila from 'markdown-it-link-attributes';
import mentionPlugin from './markdownIt/link';
const md = require('markdown-it')({
html: false,
xhtmlOut: true,
breaks: true,
langPrefix: 'language-',
linkify: true,
typographer: true,
quotes: '\u201c\u201d\u2018\u2019',
maxNesting: 20,
})
.use(mentionPlugin)
.use(mila, {
attrs: {
class: 'link',
rel: 'noreferrer noopener nofollow',
target: '_blank',
},
});
const TWITTER_USERNAME_REGEX = /(^|[^@\w])@(\w{1,15})\b/g;
const TWITTER_USERNAME_REPLACEMENT =
'$1<a href="http://twitter.com/$2" target="_blank" rel="noreferrer nofollow noopener">@$2</a>';
const TWITTER_USERNAME_REPLACEMENT = '$1[@$2](http://twitter.com/$2)';
const TWITTER_HASH_REGEX = /(^|\s)#(\w+)/g;
const TWITTER_HASH_REPLACEMENT =
'$1<a href="https://twitter.com/hashtag/$2" target="_blank" rel="noreferrer nofollow noopener">#$2</a>';
const USER_MENTIONS_REGEX = /mention:\/\/(user|team)\/(\d+)\/(.+)/gm;
const TWITTER_HASH_REPLACEMENT = '$1[#$2](https://twitter.com/hashtag/$2)';
class MessageFormatter {
constructor(message, isATweet = false, isAPrivateNote = false) {
this.message = DOMPurify.sanitize(escapeHtml(message || ''));
this.message = message || '';
this.isAPrivateNote = isAPrivateNote;
this.isATweet = isATweet;
this.marked = marked;
const renderer = {
heading(text) {
return `<strong>${text}</strong>`;
},
link(url, title, text) {
const mentionRegex = new RegExp(USER_MENTIONS_REGEX);
if (url.match(mentionRegex)) {
return `<span class="prosemirror-mention-node">${text}</span>`;
}
return `<a rel="noreferrer noopener nofollow" href="${url}" class="link" title="${title ||
''}" target="_blank">${text}</a>`;
},
};
this.marked.use({ renderer });
}
formatMessage() {
let updatedMessage = this.message;
if (this.isATweet && !this.isAPrivateNote) {
const withUserName = this.message.replace(
updatedMessage = updatedMessage.replace(
TWITTER_USERNAME_REGEX,
TWITTER_USERNAME_REPLACEMENT
);
const withHash = withUserName.replace(
updatedMessage = updatedMessage.replace(
TWITTER_HASH_REGEX,
TWITTER_HASH_REPLACEMENT
);
const markedDownOutput = marked(withHash);
return markedDownOutput;
}
DOMPurify.addHook('afterSanitizeAttributes', afterSanitizeAttributes);
return DOMPurify.sanitize(
marked(this.message, { breaks: true, gfm: true })
);
return md.render(updatedMessage);
}
get formattedMessage() {