Spaces:
Running
Running
import { html, LitElement } from "https://cdn.jsdelivr.net/npm/[email protected]/+esm"; | |
import { unsafeHTML } from "https://cdn.jsdelivr.net/npm/[email protected]/directives/unsafe-html.js/+esm"; | |
import dompurify from "https://cdn.jsdelivr.net/npm/[email protected]/+esm"; | |
import { Marked } from "https://cdn.jsdelivr.net/npm/[email protected]/+esm"; | |
import { markedHighlight } from "https://cdn.jsdelivr.net/npm/[email protected]/+esm"; | |
import highlightJs from "https://cdn.jsdelivr.net/npm/[email protected]/+esm"; | |
import mermaid from "https://cdn.jsdelivr.net/npm/[email protected]/+esm"; | |
/** | |
* Markdown component using MarkedJS | |
* | |
* - HighlightJS used for code highlighting | |
* - Mermaid JS integration for diagrams | |
*/ | |
class MarkedJsComponent extends LitElement { | |
static properties = { | |
markdown: { type: String }, | |
themeBrightness: { type: String }, | |
darkModeTheme: { type: String }, | |
lightModeTheme: { type: String }, | |
}; | |
constructor() { | |
super(); | |
mermaid.initialize({ startOnLoad: true }); | |
this.marked = new Marked( | |
markedHighlight({ | |
langPrefix: "hljs language-", | |
highlight(code, lang, info) { | |
if (lang === "mermaid") { | |
return `<div class="mermaid">${code}</div>`; | |
} | |
const language = highlightJs.getLanguage(lang) ? lang : "plaintext"; | |
return highlightJs.highlight(code, { language }).value; | |
}, | |
}) | |
); | |
} | |
createRenderRoot() { | |
return this; | |
} | |
firstUpdated() { | |
this.darkModeUpdated(); | |
} | |
updated(changedProperties) { | |
this.darkModeUpdated(); | |
} | |
darkModeUpdated() { | |
if (this.themeBrightness === "dark") { | |
document | |
.querySelector(`link[href="${this.darkModeTheme}"]`) | |
.removeAttribute("disabled"); | |
document | |
.querySelector(`link[href="${this.lightModeTheme}"]`) | |
.setAttribute("disabled", "disabled"); | |
} else { | |
document | |
.querySelector(`link[href="${this.darkModeTheme}"]`) | |
.setAttribute("disabled", "disabled"); | |
document | |
.querySelector(`link[href="${this.lightModeTheme}"]`) | |
.removeAttribute("disabled"); | |
} | |
} | |
render() { | |
return html`${unsafeHTML( | |
dompurify.sanitize(this.marked.parse(this.markdown)) | |
)}`; | |
} | |
} | |
customElements.define("markedjs-component", MarkedJsComponent); | |