File size: 2,327 Bytes
a43df2a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import { html, LitElement } from "https://cdn.jsdelivr.net/npm/lit@3.1.4/+esm";
import { unsafeHTML } from "https://cdn.jsdelivr.net/npm/lit@3.1.4/directives/unsafe-html.js/+esm";
import dompurify from "https://cdn.jsdelivr.net/npm/dompurify@3.1.6/+esm";
import { Marked } from "https://cdn.jsdelivr.net/npm/marked@13.0.2/+esm";
import { markedHighlight } from "https://cdn.jsdelivr.net/npm/marked-highlight@2.1.3/+esm";
import highlightJs from "https://cdn.jsdelivr.net/npm/highlight.js@11.10.0/+esm";
import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@10.9.1/+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);