1<script>
2  import { codeStore } from '../code-store.js';
3  import { codeErrorStore, configErrorStore } from '../error-store.js';
4  import { onMount } from 'svelte';
5  import mermaid from '@mermaid';
6
7  const detectType = (text) => {
8    text = text.replace(/^\s*%%.*\n/g, '\n');
9    console.debug('Detecting diagram type based on the text ' + text);
10    if (text.match(/^\s*sequenceDiagram/)) {
11      return 'sequence';
12    }
13
14    if (text.match(/^\s*gantt/)) {
15      return 'gantt';
16    }
17
18    if (text.match(/^\s*classDiagram/)) {
19      return 'class';
20    }
21
22    if (text.match(/^\s*stateDiagram/)) {
23      return 'state';
24    }
25
26    if (text.match(/^\s*gitGraph/)) {
27      return 'git';
28    }
29    if (text.match(/^\s*flowchart/)) {
30      return 'flowchart';
31    }
32
33    if (text.match(/^\s*info/)) {
34      return 'info';
35    }
36    if (text.match(/^\s*pie/)) {
37      return 'pie';
38    }
39
40    return 'flowchart';
41  };
42
43  // manual debounce
44  let timeout;
45  const saveStatistcs = (graphType) => {
46    clearTimeout(timeout);
47    // Only save statistcs after a 5 sec delay
48    timeout = setTimeout(function () {
49      console.log('ga:', 'send', 'event', 'render', graphType, graphType);
50      ga('send', 'event', graphType, 'render', 'render');
51    }, 5000);
52  };
53
54  let container;
55
56  export let code = '';
57  export let configClasses = '';
58  export let codeClasses = '';
59
60  onMount(async () => {
61    const unsubscribe = codeStore.subscribe((state) => {
62      try {
63        if (container && state) {
64
65          // Replacing special characters '<' and '>' with encoded '&lt;' and '&gt;'
66          code = state.code.replace(/</g, '&lt;').replace(/>/g, '&gt;');
67
68          container.innerHTML = code;
69          saveStatistcs(detectType(code));
70          delete container.dataset.processed;
71          mermaid.initialize(Object.assign({}, state.mermaid));
72          mermaid.init(undefined, container);
73          if (code) mermaid.render('graph-div', code, insertSvg);
74        }
75      } catch (e) {
76        console.log('view fail', e);
77      }
78    });
79    const unsubscribeError = codeErrorStore.subscribe((_error) => {
80      if (typeof _error === 'undefined') {
81        codeClasses = '';
82      } else {
83        codeClasses = 'error';
84        console.log('code error: ', _error);
85      }
86    });
87    const unsubscribeConfigError = configErrorStore.subscribe((_error) => {
88      if (typeof _error === 'undefined') {
89        configClasses = '';
90      } else {
91        configClasses = 'error';
92        console.log('conf error: ', _error);
93      }
94    });
95  });
96
97  let insertSvg = function (svgCode, bindFunctions) {};
98
99</script>
100
101<style>
102  #view {
103    border: 1px solor darkred;
104    flex: 1;
105  }
106  #container {
107    overflow-x: auto;
108  }
109  .error {
110    opacity: 0.5;
111  }
112</style>
113
114<div id="view" class="{codeClasses} {configClasses}">
115  <div id="container" bind:this={container} />
116</div>
117