summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/behaviors/markdown/render_mermaid.js
blob: 35380ca49fb6b4313b64dab6e5072e02190f7e23 (plain)
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
import flash from '~/flash';

// Renders diagrams and flowcharts from text using Mermaid in any element with the
// `js-render-mermaid` class.
//
// Example markup:
//
// <pre class="js-render-mermaid">
//  graph TD;
//    A-- > B;
//    A-- > C;
//    B-- > D;
//    C-- > D;
// </pre>
//

export default function renderMermaid($els) {
  if (!$els.length) return;

  import(/* webpackChunkName: 'mermaid' */ 'mermaid')
    .then(mermaid => {
      mermaid.initialize({
        // mermaid core options
        mermaid: {
          startOnLoad: false,
        },
        // mermaidAPI options
        theme: 'neutral',
        flowchart: {
          htmlLabels: false,
        },
      });

      $els.each((i, el) => {
        const source = el.textContent;

        // Remove any extra spans added by the backend syntax highlighting.
        Object.assign(el, { textContent: source });

        mermaid.init(undefined, el, id => {
          const svg = document.getElementById(id);

          svg.classList.add('mermaid');

          // pre > code > svg
          svg.closest('pre').replaceWith(svg);

          // We need to add the original source into the DOM to allow Copy-as-GFM
          // to access it.
          const sourceEl = document.createElement('text');
          sourceEl.classList.add('source');
          sourceEl.setAttribute('display', 'none');
          sourceEl.textContent = source;

          svg.appendChild(sourceEl);
        });
      });
    })
    .catch(err => {
      flash(`Can't load mermaid module: ${err}`);
    });
}