UNPKG

mermaid-isomorphic

Version:

Transform mermaid diagrams in the browser or Node.js

87 lines (72 loc) 2.15 kB
import type { MermaidRenderer, createMermaidRenderer as nodeImplementation, RenderResult } from './mermaid-isomorphic.js' import mermaid from 'mermaid' const parser = new DOMParser() const serializer = new XMLSerializer() /** * Get an aria value form a referencing attribute. * * @param element * The SVG element the get the value from. * @param attribute * The attribute whose value to get. * @returns * The aria value. */ function getAriaValue(element: SVGSVGElement, attribute: string): string | undefined { const value = element.getAttribute(attribute) if (!value) { return } let result = '' for (const id of value.split(/\s+/)) { const node = element.getElementById(id) if (node) { result += node.textContent } } return result } let count = 0 const renderer: MermaidRenderer = async (diagrams, options) => { const container = document.createElement('div') container.ariaHidden = 'true' container.style.maxHeight = '0' container.style.opacity = '0' container.style.overflow = 'hidden' if (options?.containerStyle) { Object.assign(container.style, options.containerStyle) } document.body.append(container) const results = await Promise.allSettled( diagrams.map(async (diagram) => { const id = `${options?.prefix ?? 'mermaid'}-${count}` count += 1 const { svg } = await mermaid.render(id, diagram, container) const root = parser.parseFromString(svg, 'text/html') const [element] = root.getElementsByTagName('svg') const { height, width } = element.viewBox.baseVal const description = getAriaValue(element, 'aria-describedby') const title = getAriaValue(element, 'aria-labelledby') const result: RenderResult = { height, id, svg: serializer.serializeToString(element), width } if (description) { result.description = description } if (title) { result.title = title } return result }) ) container.remove() return results } export const createMermaidRenderer: typeof nodeImplementation = () => renderer