collab/mermaid/packages/mermaid-zenuml/src/zenumlRenderer.tsblame
View source
6dd74de1import { getConfig, log } from './mermaidUtils.js';
6dd74de2import ZenUml from '@zenuml/core';
6dd74de3
6dd74de4const regexp = /^\s*zenuml/;
6dd74de5
6dd74de6// Create a Zen UML container outside the svg first for rendering, otherwise the Zen UML diagram cannot be rendered properly
6dd74de7function createTemporaryZenumlContainer(id: string) {
6dd74de8 const container = document.createElement('div');
6dd74de9 container.id = `container-${id}`;
6dd74de10 container.style.display = 'flex';
6dd74de11 container.innerHTML = `<div id="zenUMLApp-${id}"></div>`;
6dd74de12 const app = container.querySelector(`#zenUMLApp-${id}`)!;
6dd74de13 return { container, app };
6dd74de14}
6dd74de15
6dd74de16// Create a foreignObject to wrap the Zen UML container in the svg
6dd74de17function createForeignObject(id: string) {
6dd74de18 const foreignObject = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject');
6dd74de19 foreignObject.setAttribute('x', '0');
6dd74de20 foreignObject.setAttribute('y', '0');
6dd74de21 foreignObject.setAttribute('width', '100%');
6dd74de22 foreignObject.setAttribute('height', '100%');
6dd74de23 const { container, app } = createTemporaryZenumlContainer(id);
6dd74de24 foreignObject.appendChild(container);
6dd74de25 return { foreignObject, container, app };
6dd74de26}
6dd74de27
6dd74de28/**
6dd74de29 * Draws a Zen UML in the tag with id: id based on the graph definition in text.
6dd74de30 *
6dd74de31 * @param text - The text of the diagram
6dd74de32 * @param id - The id of the diagram which will be used as a DOM element id¨
6dd74de33 */
6dd74de34export const draw = async function (text: string, id: string) {
6dd74de35 log.info('draw with Zen UML renderer', ZenUml);
6dd74de36
6dd74de37 text = text.replace(regexp, '');
6dd74de38 const { securityLevel } = getConfig();
6dd74de39 // Handle root and Document for when rendering in sandbox mode
6dd74de40 let sandboxElement: HTMLIFrameElement | null = null;
6dd74de41 if (securityLevel === 'sandbox') {
6dd74de42 sandboxElement = document.getElementById('i' + id) as HTMLIFrameElement;
6dd74de43 }
6dd74de44
6dd74de45 const root = securityLevel === 'sandbox' ? sandboxElement?.contentWindow?.document : document;
6dd74de46
6dd74de47 const svgContainer = root?.querySelector(`svg#${id}`);
6dd74de48
6dd74de49 if (!root || !svgContainer) {
6dd74de50 log.error('Cannot find root or svgContainer');
6dd74de51 return;
6dd74de52 }
6dd74de53
6dd74de54 const { foreignObject, container, app } = createForeignObject(id);
6dd74de55 svgContainer.appendChild(foreignObject);
6dd74de56 const zenuml = new ZenUml(app);
6dd74de57 // default is a theme name. More themes to be added and will be configurable in the future
6dd74de58 await zenuml.render(text, { theme: 'default', mode: 'static' });
6dd74de59
6dd74de60 const { width, height } = window.getComputedStyle(container);
6dd74de61 log.debug('zenuml diagram size', width, height);
6dd74de62 svgContainer.setAttribute('style', `width: ${width}; height: ${height};`);
6dd74de63};
6dd74de64
6dd74de65export default {
6dd74de66 draw,
6dd74de67};