Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Node and edge labels should only render as markdown if properly delimited #6345

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/gold-ducks-sort.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'mermaid': patch
---

fix: Proper separation between strings and markdown strings
49 changes: 49 additions & 0 deletions cypress/integration/rendering/flowchart.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -917,6 +917,7 @@ graph TD
}
);
});

it('#6369: edge color should affect arrow head', () => {
imgSnapshotTest(
`
Expand All @@ -934,4 +935,52 @@ graph TD
}
);
});

it('#5824: should be able to use string and markdown labels', () => {
imgSnapshotTest(
`
flowchart TB
mermaid{"What is\nyourmermaid version?"} --> v10["<11"] --"\`<**1**1\`"--> fine["No bug"]
mermaid --> v11[">= v11"] -- ">= v11" --> broken["Affected by https://github.com/mermaid-js/mermaid/issues/5824"]
subgraph subgraph1["\`How to fix **fix**\`"]
broken --> B["B"]
end
githost["Github, Gitlab, BitBucket, etc."]
githost2["\`Github, Gitlab, BitBucket, etc.\`"]
a["1."]
b["- x"]
`,
{
flowchart: { htmlLabels: true },
securityLevel: 'loose',
}
);
});

it('#5824: should render subgraphs with adhoc list headings', () => {
imgSnapshotTest(
`
graph TB
subgraph "1. first"
a1-->a2
end
subgraph 2. second
b1-->b2
end
`,
{ fontFamily: 'courier' }
);
});

it('#5824: should render subgraphs with markdown headings', () => {
imgSnapshotTest(
`
graph TB
subgraph "\`**strong**\`"
a1-->a2
end
`,
{ fontFamily: 'courier' }
);
});
});
26 changes: 13 additions & 13 deletions cypress/platform/knsv2.html
Original file line number Diff line number Diff line change
Expand Up @@ -226,21 +226,21 @@ <h2>Mermaid - edge-animation-fast</h2>
n8@{ shape: rect}

</pre>
<pre id="diagram4" class="mermaid2">
<pre id="diagram4" class="mermaid">
---
config:
layout: elk
title: https://github.com/mermaid-js/mermaid/issues/5824
---
flowchart LR
subgraph s1["Untitled subgraph"]
n1["Evaluate"]
n2["Option 1"]
end
n1 -- One --> n2




%% 6048, 5824
flowchart TB
mermaid{"What is\nyourmermaid version?"} --> v10["<11"] --"`<**1**1`"--> fine["No bug"]
mermaid --> v11[">= v11"] -- ">= v11" --> broken["Affected by https://github.com/mermaid-js/mermaid/issues/5824"]
subgraph subgraph1["`How to fix **fix**`"]
broken --> B["B"]
end
githost["Github, Gitlab, BitBucket, etc."]
githost2["`Github, Gitlab, BitBucket, etc.`"]
a["1."]
b["- x"]
</pre>
<pre id="diagram4" class="mermaid2">
---
Expand Down
4 changes: 2 additions & 2 deletions docs/config/setup/mermaid/interfaces/ParseOptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@

# Interface: ParseOptions

Defined in: [packages/mermaid/src/types.ts:59](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L59)
Defined in: [packages/mermaid/src/types.ts:60](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L60)

## Properties

### suppressErrors?

> `optional` **suppressErrors**: `boolean`

Defined in: [packages/mermaid/src/types.ts:64](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L64)
Defined in: [packages/mermaid/src/types.ts:65](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L65)

If `true`, parse will return `false` instead of throwing error when the diagram is invalid.
The `parseError` function will not be called.
6 changes: 3 additions & 3 deletions docs/config/setup/mermaid/interfaces/ParseResult.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@

# Interface: ParseResult

Defined in: [packages/mermaid/src/types.ts:67](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L67)
Defined in: [packages/mermaid/src/types.ts:68](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L68)

## Properties

### config

> **config**: [`MermaidConfig`](MermaidConfig.md)

Defined in: [packages/mermaid/src/types.ts:75](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L75)
Defined in: [packages/mermaid/src/types.ts:76](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L76)

The config passed as YAML frontmatter or directives

Expand All @@ -28,6 +28,6 @@ The config passed as YAML frontmatter or directives

> **diagramType**: `string`

Defined in: [packages/mermaid/src/types.ts:71](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L71)
Defined in: [packages/mermaid/src/types.ts:72](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L72)

The diagram type, e.g. 'flowchart', 'sequence', etc.
8 changes: 4 additions & 4 deletions docs/config/setup/mermaid/interfaces/RenderResult.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@

# Interface: RenderResult

Defined in: [packages/mermaid/src/types.ts:85](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L85)
Defined in: [packages/mermaid/src/types.ts:86](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L86)

## Properties

### bindFunctions()?

> `optional` **bindFunctions**: (`element`) => `void`

Defined in: [packages/mermaid/src/types.ts:103](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L103)
Defined in: [packages/mermaid/src/types.ts:104](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L104)

Bind function to be called after the svg has been inserted into the DOM.
This is necessary for adding event listeners to the elements in the svg.
Expand All @@ -45,7 +45,7 @@ bindFunctions?.(div); // To call bindFunctions only if it's present.

> **diagramType**: `string`

Defined in: [packages/mermaid/src/types.ts:93](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L93)
Defined in: [packages/mermaid/src/types.ts:94](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L94)

The diagram type, e.g. 'flowchart', 'sequence', etc.

Expand All @@ -55,6 +55,6 @@ The diagram type, e.g. 'flowchart', 'sequence', etc.

> **svg**: `string`

Defined in: [packages/mermaid/src/types.ts:89](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L89)
Defined in: [packages/mermaid/src/types.ts:90](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/types.ts#L90)

The svg code for the rendered graph.
15 changes: 15 additions & 0 deletions packages/mermaid/src/diagrams/flowchart/flowDb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,17 @@ export class FlowDB implements DiagramDB {
return common.sanitizeText(txt, this.config);
}

private sanitizeNodeLabelType(labelType: string) {
switch (labelType) {
case 'markdown':
case 'string':
case 'text':
return labelType;
default:
return 'markdown';
}
}

/**
* Function to lookup domId from id in the graph definition.
*
Expand Down Expand Up @@ -205,6 +216,7 @@ export class FlowDB implements DiagramDB {

if (doc?.label) {
vertex.text = doc?.label;
vertex.labelType = this.sanitizeNodeLabelType(doc?.labelType ?? 'markdown');
}
if (doc?.icon) {
vertex.icon = doc?.icon;
Expand Down Expand Up @@ -996,6 +1008,7 @@ You have to call mermaid.initialize.`
const baseNode = {
id: vertex.id,
label: vertex.text,
labelType: vertex.labelType,
labelStyle: '',
parentId,
padding: config.flowchart?.padding || 8,
Expand Down Expand Up @@ -1072,6 +1085,7 @@ You have to call mermaid.initialize.`
id: subGraph.id,
label: subGraph.title,
labelStyle: '',
labelType: subGraph.labelType,
parentId: parentDB.get(subGraph.id),
padding: 8,
cssCompiledStyles: this.getCompiledStyles(subGraph.classes),
Expand Down Expand Up @@ -1103,6 +1117,7 @@ You have to call mermaid.initialize.`
end: rawEdge.end,
type: rawEdge.type ?? 'normal',
label: rawEdge.text,
labelType: rawEdge.labelType,
labelpos: 'c',
thickness: rawEdge.stroke,
minlen: rawEdge.length,
Expand Down
4 changes: 2 additions & 2 deletions packages/mermaid/src/diagrams/flowchart/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export interface FlowVertex {
domId: string;
haveCallback?: boolean;
id: string;
labelType: 'text';
labelType: 'markdown' | 'string' | 'text';
link?: string;
linkTarget?: string;
props?: any;
Expand Down Expand Up @@ -62,7 +62,7 @@ export interface FlowEdge {
style?: string[];
length?: number;
text: string;
labelType: 'text';
labelType: 'markdown' | 'string' | 'text';
classes: string[];
id?: string;
animation?: 'fast' | 'slow';
Expand Down
16 changes: 11 additions & 5 deletions packages/mermaid/src/rendering-util/rendering-elements/clusters.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,17 @@ const rect = async (parent, node) => {
// Create the label and insert it after the rect
const labelEl = shapeSvg.insert('g').attr('class', 'cluster-label ');

const text = await createText(labelEl, node.label, {
style: node.labelStyle,
useHtmlLabels,
isNode: true,
});
let text;
if (node.labelType === 'markdown') {
text = await createText(labelEl, node.label, {
style: node.labelStyle,
useHtmlLabels,
isNode: true,
});
} else {
const labelElement = await createLabel(node.label, node.labelStyle, false, true);
text = labelEl.node()?.appendChild(labelElement);
}

// Get the size of the label
let bbox = text.getBBox();
Expand Down
16 changes: 10 additions & 6 deletions packages/mermaid/src/rendering-util/rendering-elements/edges.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,16 @@ export const getLabelStyles = (styleArray) => {
export const insertEdgeLabel = async (elem, edge) => {
let useHtmlLabels = evaluate(getConfig().flowchart.htmlLabels);

const labelElement = await createText(elem, edge.label, {
style: getLabelStyles(edge.labelStyle),
useHtmlLabels,
addSvgBackground: true,
isNode: false,
});
const labelElement =
edge.labelType === 'markdown'
? await createText(elem, edge.label, {
style: getLabelStyles(edge.labelStyle),
useHtmlLabels,
addSvgBackground: true,
isNode: false,
})
: await createLabel(edge.label, getLabelStyles(edge.labelStyle), undefined, false);

log.info('abc82', edge, edge.labelType);

// Create outer g, edgeLabel, this will be positioned after graph layout
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import createLabel from '../createLabel.js';
import { createText } from '../../createText.js';
import type { Node } from '../../types.js';
import { getConfig } from '../../../diagram-api/diagramAPI.js';
Expand Down Expand Up @@ -40,14 +41,26 @@ export const labelHelper = async <T extends SVGGraphicsElement>(
label = typeof node.label === 'string' ? node.label : node.label[0];
}

const text = await createText(labelEl, sanitizeText(decodeEntities(label), getConfig()), {
useHtmlLabels,
width: node.width || getConfig().flowchart?.wrappingWidth,
// @ts-expect-error -- This is currently not used. Should this be `classes` instead?
cssClasses: 'markdown-node-label',
style: node.labelStyle,
addSvgBackground: !!node.icon || !!node.img,
});
let text;
if (node.labelType === 'markdown') {
text = await createText(labelEl, sanitizeText(decodeEntities(label), getConfig()), {
useHtmlLabels,
width: node.width || getConfig().flowchart?.wrappingWidth,
// @ts-expect-error -- This is currently not used. Should this be `classes` instead?
cssClasses: 'markdown-node-label',
style: node.labelStyle,
addSvgBackground: !!node.icon || !!node.img,
});
} else {
const labelElement = await createLabel(
sanitizeText(decodeEntities(label), getConfig()),
node.labelStyle,
false,
true
);
text = labelEl.node()?.appendChild(labelElement);
}

// Get the size of the label
let bbox = text.getBBox();
const halfPadding = (node?.padding ?? 0) / 2;
Expand Down
1 change: 1 addition & 0 deletions packages/mermaid/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export interface NodeMetaData {
shape?: string;
label?: string;
labelType?: string;
icon?: string;
form?: string;
pos?: 't' | 'b';
Expand Down
Loading