mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-01-28 07:03:17 +08:00
Merge pull request #1202 from GDFaber/bug/1200_unify_regex_for_br_tags
Unify regex for finding <br> tags throughout mermaid
This commit is contained in:
commit
c564a843fa
@ -121,6 +121,18 @@ describe('State diagram', () => {
|
|||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
it('should handle multiline notes with different line breaks', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`
|
||||||
|
stateDiagram
|
||||||
|
State1
|
||||||
|
note right of State1
|
||||||
|
Line1<br>Line2<br/>Line3<br />Line4<br />Line5
|
||||||
|
end note
|
||||||
|
`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('should render a states with descriptions including multi-line descriptions', () => {
|
it('should render a states with descriptions including multi-line descriptions', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
|
77
dist/index.html
vendored
77
dist/index.html
vendored
@ -519,45 +519,46 @@ class Class10 {
|
|||||||
int id
|
int id
|
||||||
size()
|
size()
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mermaid">
|
<div class="mermaid">
|
||||||
classDiagram
|
classDiagram
|
||||||
Class01~T~ <|-- AveryLongClass : Cool
|
Class01~T~ <|-- AveryLongClass : Cool
|
||||||
<<interface>> Class01
|
<<interface>> Class01
|
||||||
Class03~T~ "0" *-- "0..n" Class04
|
Class03~T~ "0" *-- "0..n" Class04
|
||||||
Class05 "1" o-- "many" Class06
|
Class05 "1" o-- "many" Class06
|
||||||
Class07~T~ .. Class08
|
Class07~T~ .. Class08
|
||||||
Class09 "many" --> "1" C2 : Where am i?
|
Class09 "many" --> "1" C2 : Where am i?
|
||||||
Class09 "0" --* "1..n" C3
|
Class09 "0" --* "1..n" C3
|
||||||
Class09 --|> Class07
|
Class09 --|> Class07
|
||||||
Class07 : equals()
|
Class07 : equals()
|
||||||
Class07 : Object[] elementData
|
Class07 : Object[] elementData
|
||||||
Class01 : #size()
|
Class01 : #size()
|
||||||
Class01 : -int chimp
|
Class01 : -int chimp
|
||||||
Class01 : +int gorilla
|
Class01 : +int gorilla
|
||||||
Class08 <--> C2: Cool label
|
Class08 <--> C2: Cool label
|
||||||
class Class10 {
|
class Class10 {
|
||||||
<<service>>
|
<<service>>
|
||||||
int id
|
int id
|
||||||
size()
|
size()
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mermaid">
|
<div class="mermaid">
|
||||||
stateDiagram
|
stateDiagram
|
||||||
State1
|
State1
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
<div class="mermaid">
|
|
||||||
stateDiagram
|
<div class="mermaid">
|
||||||
[*] --> First
|
stateDiagram
|
||||||
state First {
|
[*] --> First
|
||||||
[*] --> second
|
state First {
|
||||||
second --> [*]
|
[*] --> second
|
||||||
}
|
second --> [*]
|
||||||
</div>
|
}
|
||||||
|
</div>
|
||||||
<div class="mermaid">
|
<div class="mermaid">
|
||||||
stateDiagram
|
stateDiagram
|
||||||
State1: The state with a note
|
State1: The state with a note
|
||||||
@ -567,8 +568,14 @@ class Class10 {
|
|||||||
end note
|
end note
|
||||||
State1 --> State2
|
State1 --> State2
|
||||||
note left of State2 : This is the note to the left.
|
note left of State2 : This is the note to the left.
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mermaid">
|
||||||
|
stateDiagram
|
||||||
|
State1
|
||||||
|
note right of State1
|
||||||
|
Line1<br>Line2<br/>Line3<br />Line4<br />Line5
|
||||||
|
end note
|
||||||
|
</div>
|
||||||
|
|
||||||
<script src="./mermaid.js"></script>
|
<script src="./mermaid.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
@ -88,7 +88,7 @@ export const addVertices = function(vert, g, svgId) {
|
|||||||
} else {
|
} else {
|
||||||
const svgLabel = document.createElementNS('http://www.w3.org/2000/svg', 'text');
|
const svgLabel = document.createElementNS('http://www.w3.org/2000/svg', 'text');
|
||||||
|
|
||||||
const rows = vertexText.split(/<br[/]{0,1}>/);
|
const rows = vertexText.split(/<br\s*\/?>/gi);
|
||||||
|
|
||||||
for (let j = 0; j < rows.length; j++) {
|
for (let j = 0; j < rows.length; j++) {
|
||||||
const tspan = document.createElementNS('http://www.w3.org/2000/svg', 'tspan');
|
const tspan = document.createElementNS('http://www.w3.org/2000/svg', 'tspan');
|
||||||
@ -237,7 +237,7 @@ export const addEdges = function(edges, g) {
|
|||||||
edgeData.label = '<span class="edgeLabel">' + edge.text + '</span>';
|
edgeData.label = '<span class="edgeLabel">' + edge.text + '</span>';
|
||||||
} else {
|
} else {
|
||||||
edgeData.labelType = 'text';
|
edgeData.labelType = 'text';
|
||||||
edgeData.label = edge.text.replace(/<br\s*\/?>/g, '\n');
|
edgeData.label = edge.text.replace(/<br\s*\/?>/gi, '\n');
|
||||||
|
|
||||||
if (typeof edge.style === 'undefined') {
|
if (typeof edge.style === 'undefined') {
|
||||||
edgeData.style = edgeData.style || 'stroke: #333; stroke-width: 1.5px;fill:none';
|
edgeData.style = edgeData.style || 'stroke: #333; stroke-width: 1.5px;fill:none';
|
||||||
|
@ -55,6 +55,43 @@ describe('the flowchart renderer', function() {
|
|||||||
expect(addedNodes[0][1]).toHaveProperty('ry', expectedRadios);
|
expect(addedNodes[0][1]).toHaveProperty('ry', expectedRadios);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
[
|
||||||
|
'Multi<br>Line',
|
||||||
|
'Multi<br/>Line',
|
||||||
|
'Multi<br />Line',
|
||||||
|
'Multi<br\t/>Line'
|
||||||
|
].forEach(function(labelText) {
|
||||||
|
it('should handle multiline texts with different line breaks', function() {
|
||||||
|
const addedNodes = [];
|
||||||
|
const mockG = {
|
||||||
|
setNode: function(id, object) {
|
||||||
|
addedNodes.push([id, object]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
addVertices(
|
||||||
|
{
|
||||||
|
v1: {
|
||||||
|
type: 'rect',
|
||||||
|
id: 'my-node-id',
|
||||||
|
classes: [],
|
||||||
|
styles: [],
|
||||||
|
text: 'Multi<br>Line'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mockG,
|
||||||
|
'svg-id'
|
||||||
|
);
|
||||||
|
expect(addedNodes).toHaveLength(1);
|
||||||
|
expect(addedNodes[0][0]).toEqual('my-node-id');
|
||||||
|
expect(addedNodes[0][1]).toHaveProperty('id', 'my-node-id');
|
||||||
|
expect(addedNodes[0][1]).toHaveProperty('labelType', 'svg');
|
||||||
|
expect(addedNodes[0][1].label).toBeDefined();
|
||||||
|
expect(addedNodes[0][1].label).toBeDefined(); // <text> node
|
||||||
|
expect(addedNodes[0][1].label.firstChild.innerHTML).toEqual('Multi'); // <tspan> node, line 1
|
||||||
|
expect(addedNodes[0][1].label.lastChild.innerHTML).toEqual('Line'); // <tspan> node, line 2
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
[
|
[
|
||||||
@ -109,9 +146,11 @@ describe('the flowchart renderer', function() {
|
|||||||
{ text: 'Multi<br>Line' },
|
{ text: 'Multi<br>Line' },
|
||||||
{ text: 'Multi<br/>Line' },
|
{ text: 'Multi<br/>Line' },
|
||||||
{ text: 'Multi<br />Line' },
|
{ text: 'Multi<br />Line' },
|
||||||
|
{ text: 'Multi<br\t/>Line' },
|
||||||
{ style: ['stroke:DarkGray', 'stroke-width:2px'], text: 'Multi<br>Line' },
|
{ style: ['stroke:DarkGray', 'stroke-width:2px'], text: 'Multi<br>Line' },
|
||||||
{ style: ['stroke:DarkGray', 'stroke-width:2px'], text: 'Multi<br/>Line' },
|
{ style: ['stroke:DarkGray', 'stroke-width:2px'], text: 'Multi<br/>Line' },
|
||||||
{ style: ['stroke:DarkGray', 'stroke-width:2px'], text: 'Multi<br />Line' }
|
{ style: ['stroke:DarkGray', 'stroke-width:2px'], text: 'Multi<br />Line' },
|
||||||
|
{ style: ['stroke:DarkGray', 'stroke-width:2px'], text: 'Multi<br\t/>Line' }
|
||||||
],
|
],
|
||||||
mockG,
|
mockG,
|
||||||
'svg-id'
|
'svg-id'
|
||||||
|
@ -280,7 +280,7 @@ const drawForkJoinState = (g, stateDef) => {
|
|||||||
|
|
||||||
export const drawText = function(elem, textData) {
|
export const drawText = function(elem, textData) {
|
||||||
// Remove and ignore br:s
|
// Remove and ignore br:s
|
||||||
const nText = textData.text.replace(/<br\/?>/gi, ' ');
|
const nText = textData.text.replace(/<br\s*\/?>/gi, ' ');
|
||||||
|
|
||||||
const textElem = elem.append('text');
|
const textElem = elem.append('text');
|
||||||
textElem.attr('x', textData.x);
|
textElem.attr('x', textData.x);
|
||||||
@ -308,7 +308,7 @@ const _drawLongText = (_text, x, y, g) => {
|
|||||||
|
|
||||||
let text = _text.replace(/\r\n/g, '<br/>');
|
let text = _text.replace(/\r\n/g, '<br/>');
|
||||||
text = text.replace(/\n/g, '<br/>');
|
text = text.replace(/\n/g, '<br/>');
|
||||||
const lines = text.split(/<br\/?>/gi);
|
const lines = text.split(/<br\s*\/?>/gi);
|
||||||
|
|
||||||
let tHeight = 1.25 * getConfig().state.noteMargin;
|
let tHeight = 1.25 * getConfig().state.noteMargin;
|
||||||
for (const line of lines) {
|
for (const line of lines) {
|
||||||
@ -392,7 +392,7 @@ export const drawState = function(elem, stateDef) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getRows = s => {
|
const getRows = s => {
|
||||||
let str = s.replace(/<br\/?>/gi, '#br#');
|
let str = s.replace(/<br\s*\/?>/gi, '#br#');
|
||||||
str = str.replace(/\\n/g, '#br#');
|
str = str.replace(/\\n/g, '#br#');
|
||||||
return str.split('#br#');
|
return str.split('#br#');
|
||||||
};
|
};
|
||||||
|
@ -261,6 +261,16 @@ describe('state diagram, ', function() {
|
|||||||
|
|
||||||
parser.parse(str);
|
parser.parse(str);
|
||||||
});
|
});
|
||||||
|
it('should handle multiline notes with different line breaks', function() {
|
||||||
|
const str = `stateDiagram
|
||||||
|
State1
|
||||||
|
note right of State1
|
||||||
|
Line1<br>Line2<br/>Line3<br />Line4<br />Line5
|
||||||
|
end note
|
||||||
|
`;
|
||||||
|
|
||||||
|
parser.parse(str);
|
||||||
|
});
|
||||||
it('should handle floating notes', function() {
|
it('should handle floating notes', function() {
|
||||||
const str = `stateDiagram
|
const str = `stateDiagram
|
||||||
foo: bar
|
foo: bar
|
||||||
|
@ -102,7 +102,7 @@ const getLabelWidth = text => {
|
|||||||
/* TODO: REMOVE DUPLICATION, SEE SHAPES */
|
/* TODO: REMOVE DUPLICATION, SEE SHAPES */
|
||||||
const getRows = s => {
|
const getRows = s => {
|
||||||
if (!s) return 1;
|
if (!s) return 1;
|
||||||
let str = s.replace(/<br\/?>/gi, '#br#');
|
let str = s.replace(/<br\s*\/?>/gi, '#br#');
|
||||||
str = str.replace(/\\n/g, '#br#');
|
str = str.replace(/\\n/g, '#br#');
|
||||||
return str.split('#br#');
|
return str.split('#br#');
|
||||||
};
|
};
|
||||||
|
@ -98,7 +98,7 @@ const init = function() {
|
|||||||
txt = he
|
txt = he
|
||||||
.decode(txt)
|
.decode(txt)
|
||||||
.trim()
|
.trim()
|
||||||
.replace(/<br>/gi, '<br/>');
|
.replace(/<br\s*\/?>/gi, '<br/>');
|
||||||
|
|
||||||
mermaidAPI.render(
|
mermaidAPI.render(
|
||||||
id,
|
id,
|
||||||
|
@ -84,8 +84,7 @@ export const sanitize = (text, config) => {
|
|||||||
htmlLabels = false;
|
htmlLabels = false;
|
||||||
|
|
||||||
if (config.securityLevel !== 'loose' && htmlLabels) { // eslint-disable-line
|
if (config.securityLevel !== 'loose' && htmlLabels) { // eslint-disable-line
|
||||||
txt = txt.replace(/<br>/g, '#br#');
|
txt = txt.replace(/<br\s*\/?>/gi, '#br#');
|
||||||
txt = txt.replace(/<br\S*?\/>/g, '#br#');
|
|
||||||
txt = txt.replace(/</g, '<').replace(/>/g, '>');
|
txt = txt.replace(/</g, '<').replace(/>/g, '>');
|
||||||
txt = txt.replace(/=/g, '=');
|
txt = txt.replace(/=/g, '=');
|
||||||
txt = txt.replace(/#br#/g, '<br/>');
|
txt = txt.replace(/#br#/g, '<br/>');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user