diff options
Diffstat (limited to 'web_src/js/markdown/mermaid.js')
-rw-r--r-- | web_src/js/markdown/mermaid.js | 55 |
1 files changed, 44 insertions, 11 deletions
diff --git a/web_src/js/markdown/mermaid.js b/web_src/js/markdown/mermaid.js index 1fda101dc0..a518bc7345 100644 --- a/web_src/js/markdown/mermaid.js +++ b/web_src/js/markdown/mermaid.js @@ -1,23 +1,56 @@ -import {random} from '../utils.js'; +const MAX_SOURCE_CHARACTERS = 5000; + +function displayError(el, err) { + el.closest('pre').classList.remove('is-loading'); + const errorNode = document.createElement('div'); + errorNode.setAttribute('class', 'ui message error markdown-block-error mono'); + errorNode.textContent = err.str || err.message || String(err); + el.closest('pre').before(errorNode); +} export async function renderMermaid(els) { if (!els || !els.length) return; - const {mermaidAPI} = await import(/* webpackChunkName: "mermaid" */'mermaid'); + const mermaid = await import(/* webpackChunkName: "mermaid" */'mermaid'); - mermaidAPI.initialize({ - startOnLoad: false, + mermaid.initialize({ + mermaid: { + startOnLoad: false, + }, + flowchart: { + useMaxWidth: true, + htmlLabels: false, + }, theme: 'neutral', securityLevel: 'strict', }); for (const el of els) { - mermaidAPI.render(`mermaid-${random(12)}`, el.textContent, (svg, bindFunctions) => { - const div = document.createElement('div'); - div.classList.add('mermaid-chart'); - div.innerHTML = svg; - if (typeof bindFunctions === 'function') bindFunctions(div); - el.closest('pre').replaceWith(div); - }); + if (el.textContent.length > MAX_SOURCE_CHARACTERS) { + displayError(el, new Error(`Mermaid source of ${el.textContent.length} characters exceeds the maximum allowed length of ${MAX_SOURCE_CHARACTERS}.`)); + continue; + } + + let valid; + try { + valid = mermaid.parse(el.textContent); + } catch (err) { + displayError(el, err); + } + + if (!valid) { + el.closest('pre').classList.remove('is-loading'); + continue; + } + + try { + mermaid.init(undefined, el, (id) => { + const svg = document.getElementById(id); + svg.classList.add('mermaid-chart'); + svg.closest('pre').replaceWith(svg); + }); + } catch (err) { + displayError(el, err); + } } } |