mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 06:38:31 +00:00 
			
		
		
		
	Add loading spinners and mermaid error handling (#12358)
- Add loading spinners on editor and mermaid renderers - Add error handling and inline error box for mermaid - Fix Mermaid rendering by using the .init api
This commit is contained in:
		| @@ -1,5 +1,5 @@ | ||||
| import {renderMermaid} from './mermaid.js'; | ||||
|  | ||||
| export default async function renderMarkdownContent() { | ||||
|   await renderMermaid(document.querySelectorAll('.language-mermaid')); | ||||
|   await renderMermaid(document.querySelectorAll('code.language-mermaid')); | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user