mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-10-08 08:39:38 +02:00
merge develop to current branch
This commit is contained in:
@@ -25,9 +25,11 @@ export const setConf = function (cnf) {
|
||||
* @param vert Object containing the vertices.
|
||||
* @param g The graph that is to be drawn.
|
||||
* @param svgId
|
||||
* @param root
|
||||
* @param doc
|
||||
*/
|
||||
export const addVertices = function (vert, g, svgId) {
|
||||
const svg = select(`[id="${svgId}"]`);
|
||||
export const addVertices = function (vert, g, svgId, root, doc) {
|
||||
const svg = root.select(`[id="${svgId}"]`);
|
||||
const keys = Object.keys(vert);
|
||||
|
||||
// Iterate through each item in the vertex object (containing all the vertices found) in the graph definition
|
||||
@@ -62,13 +64,13 @@ export const addVertices = function (vert, g, svgId) {
|
||||
vertexNode = addHtmlLabel(svg, node).node();
|
||||
vertexNode.parentNode.removeChild(vertexNode);
|
||||
} else {
|
||||
const svgLabel = document.createElementNS('http://www.w3.org/2000/svg', 'text');
|
||||
const svgLabel = doc.createElementNS('http://www.w3.org/2000/svg', 'text');
|
||||
svgLabel.setAttribute('style', styles.labelStyle.replace('color:', 'fill:'));
|
||||
|
||||
const rows = vertexText.split(common.lineBreakRegex);
|
||||
|
||||
for (let j = 0; j < rows.length; j++) {
|
||||
const tspan = document.createElementNS('http://www.w3.org/2000/svg', 'tspan');
|
||||
const tspan = doc.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', '1');
|
||||
@@ -131,6 +133,9 @@ export const addVertices = function (vert, g, svgId) {
|
||||
case 'group':
|
||||
_shape = 'rect';
|
||||
break;
|
||||
case 'doublecircle':
|
||||
_shape = 'doublecircle';
|
||||
break;
|
||||
default:
|
||||
_shape = 'rect';
|
||||
}
|
||||
@@ -374,6 +379,18 @@ export const draw = function (text, id) {
|
||||
const nodeSpacing = conf.nodeSpacing || 50;
|
||||
const rankSpacing = conf.rankSpacing || 50;
|
||||
|
||||
const securityLevel = getConfig().securityLevel;
|
||||
// Handle root and ocument for when rendering in sanbox mode
|
||||
let sandboxElement;
|
||||
if (securityLevel === 'sandbox') {
|
||||
sandboxElement = select('#i' + id);
|
||||
}
|
||||
const root =
|
||||
securityLevel === 'sandbox'
|
||||
? select(sandboxElement.nodes()[0].contentDocument.body)
|
||||
: select('body');
|
||||
const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0].contentDocument : document;
|
||||
|
||||
// Create the input mermaid.graph
|
||||
const g = new graphlib.Graph({
|
||||
multigraph: true,
|
||||
@@ -417,18 +434,18 @@ export const draw = function (text, id) {
|
||||
g.setParent(subG.nodes[j], subG.id);
|
||||
}
|
||||
}
|
||||
addVertices(vert, g, id);
|
||||
addVertices(vert, g, id, root, doc);
|
||||
addEdges(edges, g);
|
||||
|
||||
// Add custom shapes
|
||||
// flowChartShapes.addToRenderV2(addShape);
|
||||
|
||||
// Set up an SVG group so that we can translate the final graph.
|
||||
const svg = select(`[id="${id}"]`);
|
||||
const svg = root.select(`[id="${id}"]`);
|
||||
svg.attr('xmlns:xlink', 'http://www.w3.org/1999/xlink');
|
||||
|
||||
// Run the renderer. This is what draws the final graph.
|
||||
const element = select('#' + id + ' g');
|
||||
const element = root.select('#' + id + ' g');
|
||||
render(element, g, ['point', 'circle', 'cross'], 'flowchart', id);
|
||||
|
||||
const padding = conf.diagramPadding;
|
||||
@@ -452,14 +469,14 @@ export const draw = function (text, id) {
|
||||
|
||||
// Add label rects for non html labels
|
||||
if (!conf.htmlLabels) {
|
||||
const labels = document.querySelectorAll('[id="' + id + '"] .edgeLabel .label');
|
||||
const labels = doc.querySelectorAll('[id="' + id + '"] .edgeLabel .label');
|
||||
for (let k = 0; k < labels.length; k++) {
|
||||
const label = labels[k];
|
||||
|
||||
// Get dimensions of label
|
||||
const dim = label.getBBox();
|
||||
|
||||
const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
|
||||
const rect = doc.createElementNS('http://www.w3.org/2000/svg', 'rect');
|
||||
rect.setAttribute('rx', 0);
|
||||
rect.setAttribute('ry', 0);
|
||||
rect.setAttribute('width', dim.width);
|
||||
@@ -478,11 +495,13 @@ export const draw = function (text, id) {
|
||||
if (vertex.link) {
|
||||
const node = select('#' + id + ' [id="' + key + '"]');
|
||||
if (node) {
|
||||
const link = document.createElementNS('http://www.w3.org/2000/svg', 'a');
|
||||
const link = doc.createElementNS('http://www.w3.org/2000/svg', 'a');
|
||||
link.setAttributeNS('http://www.w3.org/2000/svg', 'class', vertex.classes.join(' '));
|
||||
link.setAttributeNS('http://www.w3.org/2000/svg', 'href', vertex.link);
|
||||
link.setAttributeNS('http://www.w3.org/2000/svg', 'rel', 'noopener');
|
||||
if (vertex.linkTarget) {
|
||||
if (securityLevel === 'sandbox') {
|
||||
link.setAttributeNS('http://www.w3.org/2000/svg', 'target', '_top');
|
||||
} else if (vertex.linkTarget) {
|
||||
link.setAttributeNS('http://www.w3.org/2000/svg', 'target', vertex.linkTarget);
|
||||
}
|
||||
|
||||
|
@@ -26,9 +26,15 @@ export const setConf = function (cnf) {
|
||||
* @param vert Object containing the vertices.
|
||||
* @param g The graph that is to be drawn.
|
||||
* @param svgId
|
||||
* @param root
|
||||
* @param doc
|
||||
* @param _doc
|
||||
*/
|
||||
export const addVertices = function (vert, g, svgId) {
|
||||
const svg = select(`[id="${svgId}"]`);
|
||||
export const addVertices = function (vert, g, svgId, root, _doc) {
|
||||
const securityLevel = getConfig().securityLevel;
|
||||
|
||||
const svg = !root ? select(`[id="${svgId}"]`) : root.select(`[id="${svgId}"]`);
|
||||
const doc = !_doc ? document : _doc;
|
||||
const keys = Object.keys(vert);
|
||||
|
||||
// Iterate through each item in the vertex object (containing all the vertices found) in the graph definition
|
||||
@@ -63,13 +69,13 @@ export const addVertices = function (vert, g, svgId) {
|
||||
vertexNode = addHtmlLabel(svg, node).node();
|
||||
vertexNode.parentNode.removeChild(vertexNode);
|
||||
} else {
|
||||
const svgLabel = document.createElementNS('http://www.w3.org/2000/svg', 'text');
|
||||
const svgLabel = doc.createElementNS('http://www.w3.org/2000/svg', 'text');
|
||||
svgLabel.setAttribute('style', styles.labelStyle.replace('color:', 'fill:'));
|
||||
|
||||
const rows = vertexText.split(common.lineBreakRegex);
|
||||
|
||||
for (let j = 0; j < rows.length; j++) {
|
||||
const tspan = document.createElementNS('http://www.w3.org/2000/svg', 'tspan');
|
||||
const tspan = doc.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', '1');
|
||||
@@ -293,6 +299,17 @@ export const draw = function (text, id) {
|
||||
const parser = flow.parser;
|
||||
parser.yy = flowDb;
|
||||
|
||||
const securityLevel = getConfig().securityLevel;
|
||||
let sandboxElement;
|
||||
if (securityLevel === 'sandbox') {
|
||||
sandboxElement = select('#i' + id);
|
||||
}
|
||||
const root =
|
||||
securityLevel === 'sandbox'
|
||||
? select(sandboxElement.nodes()[0].contentDocument.body)
|
||||
: select('body');
|
||||
const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0].contentDocument : document;
|
||||
|
||||
// Parse the graph definition
|
||||
// try {
|
||||
parser.parse(text);
|
||||
@@ -355,7 +372,7 @@ export const draw = function (text, id) {
|
||||
g.setParent(flowDb.lookUpDomId(subG.nodes[j]), flowDb.lookUpDomId(subG.id));
|
||||
}
|
||||
}
|
||||
addVertices(vert, g, id);
|
||||
addVertices(vert, g, id, root, doc);
|
||||
addEdges(edges, g);
|
||||
|
||||
// Create the renderer
|
||||
@@ -404,13 +421,13 @@ export const draw = function (text, id) {
|
||||
};
|
||||
|
||||
// Set up an SVG group so that we can translate the final graph.
|
||||
const svg = select(`[id="${id}"]`);
|
||||
const svg = root.select(`[id="${id}"]`);
|
||||
svg.attr('xmlns:xlink', 'http://www.w3.org/1999/xlink');
|
||||
|
||||
log.warn(g);
|
||||
|
||||
// Run the renderer. This is what draws the final graph.
|
||||
const element = select('#' + id + ' g');
|
||||
const element = root.select('#' + id + ' g');
|
||||
render(element, g);
|
||||
|
||||
element.selectAll('g.node').attr('title', function () {
|
||||
@@ -436,10 +453,10 @@ export const draw = function (text, id) {
|
||||
for (i = 0; i < subGraphs.length; i++) {
|
||||
subG = subGraphs[i];
|
||||
if (subG.title !== 'undefined') {
|
||||
const clusterRects = document.querySelectorAll(
|
||||
const clusterRects = doc.querySelectorAll(
|
||||
'#' + id + ' [id="' + flowDb.lookUpDomId(subG.id) + '"] rect'
|
||||
);
|
||||
const clusterEl = document.querySelectorAll(
|
||||
const clusterEl = doc.querySelectorAll(
|
||||
'#' + id + ' [id="' + flowDb.lookUpDomId(subG.id) + '"]'
|
||||
);
|
||||
|
||||
@@ -459,14 +476,14 @@ export const draw = function (text, id) {
|
||||
|
||||
// Add label rects for non html labels
|
||||
if (!evaluate(conf.htmlLabels) || true) { // eslint-disable-line
|
||||
const labels = document.querySelectorAll('[id="' + id + '"] .edgeLabel .label');
|
||||
const labels = doc.querySelectorAll('[id="' + id + '"] .edgeLabel .label');
|
||||
for (let k = 0; k < labels.length; k++) {
|
||||
const label = labels[k];
|
||||
|
||||
// Get dimensions of label
|
||||
const dim = label.getBBox();
|
||||
|
||||
const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
|
||||
const rect = doc.createElementNS('http://www.w3.org/2000/svg', 'rect');
|
||||
rect.setAttribute('rx', 0);
|
||||
rect.setAttribute('ry', 0);
|
||||
rect.setAttribute('width', dim.width);
|
||||
@@ -483,13 +500,15 @@ export const draw = function (text, id) {
|
||||
const vertex = vert[key];
|
||||
|
||||
if (vertex.link) {
|
||||
const node = select('#' + id + ' [id="' + flowDb.lookUpDomId(key) + '"]');
|
||||
const node = root.select('#' + id + ' [id="' + flowDb.lookUpDomId(key) + '"]');
|
||||
if (node) {
|
||||
const link = document.createElementNS('http://www.w3.org/2000/svg', 'a');
|
||||
const link = doc.createElementNS('http://www.w3.org/2000/svg', 'a');
|
||||
link.setAttributeNS('http://www.w3.org/2000/svg', 'class', vertex.classes.join(' '));
|
||||
link.setAttributeNS('http://www.w3.org/2000/svg', 'href', vertex.link);
|
||||
link.setAttributeNS('http://www.w3.org/2000/svg', 'rel', 'noopener');
|
||||
if (vertex.linkTarget) {
|
||||
if (securityLevel === 'sandbox') {
|
||||
link.setAttributeNS('http://www.w3.org/2000/svg', 'target', '_top');
|
||||
} else if (vertex.linkTarget) {
|
||||
link.setAttributeNS('http://www.w3.org/2000/svg', 'target', vertex.linkTarget);
|
||||
}
|
||||
|
||||
|
@@ -159,6 +159,40 @@ describe('[Singlenodes] when parsing', () => {
|
||||
expect(vert['a'].text).toBe('A <br> end');
|
||||
});
|
||||
|
||||
it('should handle a single double circle node', function () {
|
||||
// Silly but syntactically correct
|
||||
const res = flow.parser.parse('graph TD;a(((A)));');
|
||||
|
||||
const vert = flow.parser.yy.getVertices();
|
||||
const edges = flow.parser.yy.getEdges();
|
||||
|
||||
expect(edges.length).toBe(0);
|
||||
expect(vert['a'].type).toBe('doublecircle');
|
||||
});
|
||||
|
||||
it('should handle a single double circle node with whitespace after it', function () {
|
||||
// Silly but syntactically correct
|
||||
const res = flow.parser.parse('graph TD;a(((A))) ;');
|
||||
|
||||
const vert = flow.parser.yy.getVertices();
|
||||
const edges = flow.parser.yy.getEdges();
|
||||
|
||||
expect(edges.length).toBe(0);
|
||||
expect(vert['a'].type).toBe('doublecircle');
|
||||
});
|
||||
|
||||
it('should handle a single double circle node with html in it (SN3)', function () {
|
||||
// Silly but syntactically correct
|
||||
const res = flow.parser.parse('graph TD;a(((A <br> end)));');
|
||||
|
||||
const vert = flow.parser.yy.getVertices();
|
||||
const edges = flow.parser.yy.getEdges();
|
||||
|
||||
expect(edges.length).toBe(0);
|
||||
expect(vert['a'].type).toBe('doublecircle');
|
||||
expect(vert['a'].text).toBe('A <br> end');
|
||||
});
|
||||
|
||||
it('should handle a single node with alphanumerics starting on a char', function () {
|
||||
// Silly but syntactically correct
|
||||
const res = flow.parser.parse('graph TD;id1;');
|
||||
|
@@ -121,6 +121,8 @@ that id.
|
||||
"[|" return 'VERTEX_WITH_PROPS_START';
|
||||
"[(" return 'CYLINDERSTART';
|
||||
")]" return 'CYLINDEREND';
|
||||
"(((" return 'DOUBLECIRCLESTART';
|
||||
")))" return 'DOUBLECIRCLEEND';
|
||||
\- return 'MINUS';
|
||||
"." return 'DOT';
|
||||
[\_] return 'UNDERSCORE';
|
||||
@@ -373,6 +375,8 @@ node: vertex
|
||||
|
||||
vertex: idString SQS text SQE
|
||||
{$$ = $1;yy.addVertex($1,$3,'square');}
|
||||
| idString DOUBLECIRCLESTART text DOUBLECIRCLEEND
|
||||
{$$ = $1;yy.addVertex($1,$3,'doublecircle');}
|
||||
| idString PS PS text PE PE
|
||||
{$$ = $1;yy.addVertex($1,$4,'circle');}
|
||||
| idString '(-' text '-)'
|
||||
|
Reference in New Issue
Block a user