mermaid/src/mermaid.js

198 lines
5.1 KiB
JavaScript
Raw Normal View History

/**
* Web page integration module for the mermaid framework. It uses the mermaidAPI for mermaid functionality and to render
* the diagrams to svg code.
*/
// import { decode } from 'he';
import decode from 'entity-decode/browser';
2019-09-12 12:59:13 -07:00
import mermaidAPI from './mermaidAPI';
import { logger } from './logger';
2020-06-17 05:54:24 -04:00
import utils from './utils';
2015-05-26 20:59:23 +02:00
/**
* ## init
2015-05-26 20:59:23 +02:00
* Function that goes through the document to find the chart definitions in there and render them.
*
* The function tags the processed attributes with the attribute data-processed and ignores found elements with the
* attribute already set. This way the init function can be triggered several times.
*
2015-05-26 20:59:23 +02:00
* Optionally, `init` can accept in the second argument one of the following:
* - a DOM Node
* - an array of DOM nodes (as would come from a jQuery selector)
* - a W3C selector, a la `.mermaid`
*
* ```mermaid
2015-05-26 20:59:23 +02:00
* graph LR;
* a(Find elements)-->b{Processed}
* b-->|Yes|c(Leave element)
* b-->|No |d(Transform)
2015-05-26 20:59:23 +02:00
* ```
* Renders the mermaid diagrams
* @param nodes a css selector or an array of nodes
2015-05-26 20:59:23 +02:00
*/
2019-09-12 12:59:13 -07:00
const init = function() {
const conf = mermaidAPI.getConfig();
// console.log('Starting rendering diagrams (init) - mermaid.init');
2019-09-12 12:59:13 -07:00
let nodes;
2017-04-11 22:14:25 +08:00
if (arguments.length >= 2) {
2017-04-16 23:08:37 +08:00
/*! sequence config was passed as #1 */
2017-04-11 22:14:25 +08:00
if (typeof arguments[0] !== 'undefined') {
2019-09-12 12:59:13 -07:00
mermaid.sequenceConfig = arguments[0];
2015-05-26 20:59:23 +02:00
}
2019-09-12 12:59:13 -07:00
nodes = arguments[1];
2017-04-11 22:14:25 +08:00
} else {
2019-09-12 12:59:13 -07:00
nodes = arguments[0];
2017-04-11 22:14:25 +08:00
}
2017-04-16 23:08:37 +08:00
// if last argument is a function this is the callback function
2019-09-12 12:59:13 -07:00
let callback;
2017-04-11 22:14:25 +08:00
if (typeof arguments[arguments.length - 1] === 'function') {
2019-09-12 12:59:13 -07:00
callback = arguments[arguments.length - 1];
logger.debug('Callback function found');
2017-04-11 22:14:25 +08:00
} else {
if (typeof conf.mermaid !== 'undefined') {
if (typeof conf.mermaid.callback === 'function') {
2019-09-12 12:59:13 -07:00
callback = conf.mermaid.callback;
logger.debug('Callback function found');
2017-04-11 22:14:25 +08:00
} else {
2019-09-12 12:59:13 -07:00
logger.debug('No Callback function found');
2017-04-11 22:14:25 +08:00
}
}
2017-04-11 22:14:25 +08:00
}
2019-09-12 12:59:13 -07:00
nodes =
nodes === undefined
? document.querySelectorAll('.mermaid')
: typeof nodes === 'string'
? document.querySelectorAll(nodes)
: nodes instanceof window.Node
? [nodes]
: nodes; // Last case - sequence config was passed pick next
logger.debug('Start On Load before: ' + mermaid.startOnLoad);
2017-09-10 10:24:48 +08:00
if (typeof mermaid.startOnLoad !== 'undefined') {
2019-09-12 12:59:13 -07:00
logger.debug('Start On Load inner: ' + mermaid.startOnLoad);
mermaidAPI.initialize({ startOnLoad: mermaid.startOnLoad });
2017-04-11 22:14:25 +08:00
}
2017-09-10 10:24:48 +08:00
if (typeof mermaid.ganttConfig !== 'undefined') {
mermaidAPI.initialize({ gantt: mermaid.ganttConfig });
2017-04-11 22:14:25 +08:00
}
2019-09-12 12:59:13 -07:00
let txt;
2017-09-14 21:12:35 +08:00
for (let i = 0; i < nodes.length; i++) {
2019-09-12 12:59:13 -07:00
const element = nodes[i];
2015-05-26 20:59:23 +02:00
2017-04-16 23:08:37 +08:00
/*! Check if previously processed */
2017-04-11 22:14:25 +08:00
if (!element.getAttribute('data-processed')) {
2019-09-12 12:59:13 -07:00
element.setAttribute('data-processed', true);
2017-04-11 22:14:25 +08:00
} else {
2019-09-12 12:59:13 -07:00
continue;
2017-04-11 22:14:25 +08:00
}
2015-05-26 20:59:23 +02:00
2019-09-12 12:59:13 -07:00
const id = `mermaid-${Date.now()}`;
2015-05-26 20:59:23 +02:00
2017-04-16 23:08:37 +08:00
// Fetch the graph definition including tags
2019-09-12 12:59:13 -07:00
txt = element.innerHTML;
2015-05-26 20:59:23 +02:00
2017-04-16 23:08:37 +08:00
// transforms the html to pure text
txt = decode(txt)
2019-09-12 12:59:13 -07:00
.trim()
.replace(/<br\s*\/?>/gi, '<br/>');
2019-09-12 12:59:13 -07:00
2020-06-17 05:54:24 -04:00
const init = utils.detectInit(txt);
if (init) {
logger.debug('Detected early reinit: ', init);
}
try {
2020-06-06 12:53:19 +02:00
mermaidAPI.render(
id,
txt,
(svgCode, bindFunctions) => {
element.innerHTML = svgCode;
if (typeof callback !== 'undefined') {
callback(id);
}
if (bindFunctions) bindFunctions(element);
},
element
);
} catch (e) {
logger.warn('Syntax Error rendering');
logger.warn(e);
if (this.parseError) {
this.parseError(e);
}
}
2017-04-11 22:14:25 +08:00
}
2019-09-12 12:59:13 -07:00
};
2019-09-12 12:59:13 -07:00
const initialize = function(config) {
// mermaidAPI.reset();
2017-04-11 22:14:25 +08:00
if (typeof config.mermaid !== 'undefined') {
if (typeof config.mermaid.startOnLoad !== 'undefined') {
2019-09-12 12:59:13 -07:00
mermaid.startOnLoad = config.mermaid.startOnLoad;
}
2017-04-11 22:14:25 +08:00
if (typeof config.mermaid.htmlLabels !== 'undefined') {
2019-09-12 12:59:13 -07:00
mermaid.htmlLabels = config.mermaid.htmlLabels;
2015-05-26 20:59:23 +02:00
}
2017-04-11 22:14:25 +08:00
}
2019-09-12 12:59:13 -07:00
mermaidAPI.initialize(config);
mermaidAPI.reset();
2019-09-12 12:59:13 -07:00
};
2017-04-11 22:14:25 +08:00
/**
* ##contentLoaded
* Callback function that is called when page is loaded. This functions fetches configuration for mermaid rendering and
* calls init for rendering the mermaid diagrams on the page.
*/
2019-09-12 12:59:13 -07:00
const contentLoaded = function() {
let config;
2015-05-26 20:59:23 +02:00
2017-09-10 10:24:48 +08:00
if (mermaid.startOnLoad) {
2018-03-09 15:13:05 +08:00
// No config found, do check API config
2019-09-12 12:59:13 -07:00
config = mermaidAPI.getConfig();
2018-03-09 15:13:05 +08:00
if (config.startOnLoad) {
2019-09-12 12:59:13 -07:00
mermaid.init();
2017-04-11 22:14:25 +08:00
}
} else {
2017-09-10 10:24:48 +08:00
if (typeof mermaid.startOnLoad === 'undefined') {
2019-09-12 12:59:13 -07:00
logger.debug('In start, no config');
config = mermaidAPI.getConfig();
2017-04-11 22:14:25 +08:00
if (config.startOnLoad) {
2019-09-12 12:59:13 -07:00
mermaid.init();
2017-04-11 22:14:25 +08:00
}
2015-05-26 20:59:23 +02:00
}
2017-04-11 22:14:25 +08:00
}
2019-09-12 12:59:13 -07:00
};
2015-05-26 20:59:23 +02:00
2017-04-11 22:14:25 +08:00
if (typeof document !== 'undefined') {
2017-04-16 23:08:37 +08:00
/*!
* Wait for document loaded before starting the execution
*/
2019-09-12 12:59:13 -07:00
window.addEventListener(
'load',
function() {
contentLoaded();
},
false
);
2015-05-26 20:59:23 +02:00
}
2017-09-09 21:47:21 +08:00
const mermaid = {
startOnLoad: true,
htmlLabels: true,
2017-09-10 10:19:15 +08:00
mermaidAPI,
parse: mermaidAPI.parse,
render: mermaidAPI.render,
2017-09-09 21:47:21 +08:00
init,
initialize,
2017-09-10 10:19:15 +08:00
contentLoaded
2019-09-12 12:59:13 -07:00
};
2017-09-09 21:47:21 +08:00
2019-09-12 12:59:13 -07:00
export default mermaid;