2021-01-30 07:33:04 +08:00
|
|
|
import marked from "marked";
|
|
|
|
import morphdom from "morphdom";
|
2021-02-18 22:11:24 +08:00
|
|
|
import DOMPurify from "dompurify";
|
2021-02-24 22:41:00 +08:00
|
|
|
import monaco from "./live_editor/monaco";
|
|
|
|
|
|
|
|
// Reuse Monaco highlighter for Markdown code blocks
|
|
|
|
marked.setOptions({
|
|
|
|
highlight: (code, lang, callback) => {
|
|
|
|
monaco.editor
|
|
|
|
.colorize(code, lang)
|
|
|
|
.then((result) => {
|
|
|
|
// `colorize` always adds additional newline, so we remove it
|
|
|
|
result = result.replace(/<br\/>$/, "");
|
|
|
|
callback(null, result);
|
|
|
|
})
|
|
|
|
.catch((error) => {
|
|
|
|
callback(error, null);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
});
|
2021-01-30 07:33:04 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Renders markdown content in the given container.
|
|
|
|
*/
|
|
|
|
class Markdown {
|
2021-04-05 00:55:51 +08:00
|
|
|
constructor(container, content, baseUrl = null) {
|
2021-01-30 07:33:04 +08:00
|
|
|
this.container = container;
|
|
|
|
this.content = content;
|
2021-04-05 00:55:51 +08:00
|
|
|
this.baseUrl = baseUrl;
|
2021-01-30 07:33:04 +08:00
|
|
|
|
|
|
|
this.__render();
|
|
|
|
}
|
|
|
|
|
|
|
|
setContent(content) {
|
|
|
|
this.content = content;
|
|
|
|
this.__render();
|
|
|
|
}
|
|
|
|
|
|
|
|
__render() {
|
2021-02-24 22:41:00 +08:00
|
|
|
this.__getHtml().then((html) => {
|
|
|
|
// Wrap the HTML in another element, so that we
|
|
|
|
// can use morphdom's childrenOnly option.
|
|
|
|
const wrappedHtml = `<div>${html}</div>`;
|
2021-01-30 07:33:04 +08:00
|
|
|
|
2021-02-24 22:41:00 +08:00
|
|
|
morphdom(this.container, wrappedHtml, { childrenOnly: true });
|
|
|
|
});
|
2021-01-30 07:33:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
__getHtml() {
|
2021-02-24 22:41:00 +08:00
|
|
|
return new Promise((resolve, reject) => {
|
2021-04-05 00:55:51 +08:00
|
|
|
// Marked requires a trailing slash in the base URL
|
|
|
|
const opts = { baseUrl: this.baseUrl + "/" };
|
|
|
|
|
|
|
|
marked(this.content, opts, (error, html) => {
|
2021-02-24 22:41:00 +08:00
|
|
|
const sanitizedHtml = DOMPurify.sanitize(html);
|
|
|
|
|
|
|
|
if (sanitizedHtml) {
|
|
|
|
resolve(sanitizedHtml);
|
|
|
|
} else {
|
|
|
|
resolve(`
|
|
|
|
<div class="text-gray-300">
|
|
|
|
Empty markdown cell
|
|
|
|
</div>
|
|
|
|
`);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
2021-01-30 07:33:04 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default Markdown;
|