mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-19 07:19:41 +02:00
96 lines
2.9 KiB
JavaScript
96 lines
2.9 KiB
JavaScript
import { select } from 'd3';
|
|
import { getConfig } from '../diagram-api/diagramAPI.js';
|
|
import { evaluate, sanitizeText } from '../diagrams/common/common.js';
|
|
import { log } from '../logger.js';
|
|
import { replaceIconSubstring } from '../rendering-util/createText.js';
|
|
import { decodeEntities } from '../utils.js';
|
|
|
|
/**
|
|
* @param dom
|
|
* @param styleFn
|
|
*/
|
|
function applyStyle(dom, styleFn) {
|
|
if (styleFn) {
|
|
dom.attr('style', styleFn);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {any} node
|
|
* @returns {SVGForeignObjectElement} Node
|
|
*/
|
|
function addHtmlLabel(node, config) {
|
|
const fo = select(document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject'));
|
|
const div = fo.append('xhtml:div');
|
|
|
|
const label = node.label;
|
|
const labelClass = node.isNode ? 'nodeLabel' : 'edgeLabel';
|
|
const span = div.append('span');
|
|
span.html(sanitizeText(label, config));
|
|
applyStyle(span, node.labelStyle);
|
|
span.attr('class', labelClass);
|
|
|
|
applyStyle(div, node.labelStyle);
|
|
div.style('display', 'inline-block');
|
|
// Fix for firefox
|
|
div.style('white-space', 'nowrap');
|
|
div.attr('xmlns', 'http://www.w3.org/1999/xhtml');
|
|
return fo.node();
|
|
}
|
|
/**
|
|
* @param _vertexText
|
|
* @param style
|
|
* @param isTitle
|
|
* @param isNode
|
|
* @deprecated svg-util/createText instead
|
|
*/
|
|
const createLabel = async (_vertexText, style, isTitle, isNode) => {
|
|
let vertexText = _vertexText || '';
|
|
if (typeof vertexText === 'object') {
|
|
vertexText = vertexText[0];
|
|
}
|
|
const config = getConfig();
|
|
if (evaluate(config.flowchart.htmlLabels)) {
|
|
// TODO: addHtmlLabel accepts a labelStyle. Do we possibly have that?
|
|
vertexText = vertexText.replace(/\\n|\n/g, '<br />');
|
|
log.debug('vertexText' + vertexText);
|
|
const label = await replaceIconSubstring(decodeEntities(vertexText));
|
|
const node = {
|
|
isNode,
|
|
label,
|
|
labelStyle: style.replace('fill:', 'color:'),
|
|
};
|
|
let vertexNode = addHtmlLabel(node, config);
|
|
// vertexNode.parentNode.removeChild(vertexNode);
|
|
return vertexNode;
|
|
} else {
|
|
const svgLabel = document.createElementNS('http://www.w3.org/2000/svg', 'text');
|
|
svgLabel.setAttribute('style', style.replace('color:', 'fill:'));
|
|
let rows = [];
|
|
if (typeof vertexText === 'string') {
|
|
rows = vertexText.split(/\\n|\n|<br\s*\/?>/gi);
|
|
} else if (Array.isArray(vertexText)) {
|
|
rows = vertexText;
|
|
} else {
|
|
rows = [];
|
|
}
|
|
|
|
for (const row of rows) {
|
|
const tspan = document.createElementNS('http://www.w3.org/2000/svg', 'tspan');
|
|
tspan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
|
|
tspan.setAttribute('dy', '1em');
|
|
tspan.setAttribute('x', '0');
|
|
if (isTitle) {
|
|
tspan.setAttribute('class', 'title-row');
|
|
} else {
|
|
tspan.setAttribute('class', 'row');
|
|
}
|
|
tspan.textContent = row.trim();
|
|
svgLabel.appendChild(tspan);
|
|
}
|
|
return svgLabel;
|
|
}
|
|
};
|
|
|
|
export default createLabel;
|