import { RuleOptions } from '../../MdToHtml'; export default { assets: function(theme: any) { return [ { name: 'mermaid.min.js' }, { name: 'mermaid_render.js' }, { inline: true, // Note: Mermaid is buggy when rendering below a certain width (500px?) // so set an arbitrarily high width here for the container. Once the // diagram is rendered it will be reset to 100% in mermaid_render.js text: '.mermaid { width: 640px; }', mime: 'text/css', }, { inline: true, // Export button in mermaid graph should be shown only on hovering the mermaid graph // ref: https://github.com/laurent22/joplin/issues/6101 text: ` .mermaid-export-graph { visibility: hidden; } .joplin-editable:hover .mermaid-export-graph { visibility: visible; } .mermaid-export-graph:hover { background-color: ${theme.backgroundColorHover3} !important; } `.trim(), mime: 'text/css', }, ]; }, plugin: function(markdownIt: any, ruleOptions: RuleOptions) { // eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied const defaultRender: Function = markdownIt.renderer.rules.fence || function(tokens: any[], idx: number, options: any, env: any, self: any) { return self.renderToken(tokens, idx, options, env, self); }; const exportButtonMarkup = isDesktop(ruleOptions.platformName) ? exportGraphButton(ruleOptions) : ''; markdownIt.renderer.rules.fence = function(tokens: any[], idx: number, options: any, env: any, self: any) { const token = tokens[idx]; if (token.info !== 'mermaid') return defaultRender(tokens, idx, options, env, self); const contentHtml = markdownIt.utils.escapeHtml(token.content); const cssClasses = ['mermaid']; if (ruleOptions.theme.appearance === 'dark') { // This class applies globally -- if any elements have this class, all mermaid // elements will be rendered in dark mode. // (See mermaid_render.js for details). cssClasses.push('joplin--mermaid-use-dark-theme'); } // Note: The mermaid script (`contentHtml`) needs to be wrapped // in a `pre` tag, otherwise in WYSIWYG mode TinyMCE removes // all the white space from it, which causes mermaid to fail. // See PR #4670 https://github.com/laurent22/joplin/pull/4670 return `
${contentHtml}
${exportButtonMarkup}
${contentHtml}
`; }; }, }; const exportGraphButton = (ruleOptions: RuleOptions) => { const theme = ruleOptions.theme; // Clicking on export button manually triggers a right click context menu event const onClickHandler = ` const target = arguments[0].target; const button = target.closest("button.mermaid-export-graph"); if (!button) return false; const $mermaid_elem = button.nextElementSibling; const rightClickEvent = new PointerEvent("contextmenu", {bubbles: true}); rightClickEvent.target = $mermaid_elem; $mermaid_elem.dispatchEvent(rightClickEvent); return false; `.trim(); const style = ` display: block; margin-left: auto; border-radius: ${theme.buttonStyle.borderRadius}px; font-size: ${theme.fontSize}px; color: ${theme.color}; background: ${theme.buttonStyle.backgroundColor}; border: ${theme.buttonStyle.border}; `.trim(); return ``; }; const downloadIcon = () => { // https://www.svgrepo.com/svg/505363/download return ' '; }; const isDesktop = (platformName?: string) => { if (!platformName) { return false; } return ['darwin', 'linux', 'freebsd', 'win32'].includes(platformName); };