diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html index 923529074..4335beaee 100644 --- a/cypress/platform/knsv2.html +++ b/cypress/platform/knsv2.html @@ -66,21 +66,24 @@ h --3i -->a b --> d(The dog in the hog) c --> d -
+mindmap - id1["`Start`"] + id1["`**Start2** + second line 😎 with long text that is wrapping to the next line`"] id2["`Child **with bold** text`"] id3["`Children of which some is using *italic type of* text`"] id4[Child] + id5["`Child + Row + and another + `"]-+mindmap - id1["`Start -second line 😎`"] - id2[Child] - id3[Child] - id4[Child] + id1["`**Start** with + + a second line 😎`"]%%{init: {"flowchart": {"defaultRenderer": "elk"}} }%% diff --git a/packages/mermaid/src/diagrams/mindmap/styles.js b/packages/mermaid/src/diagrams/mindmap/styles.js index 986a04514..863522fdf 100644 --- a/packages/mermaid/src/diagrams/mindmap/styles.js +++ b/packages/mermaid/src/diagrams/mindmap/styles.js @@ -70,5 +70,12 @@ const getStyles = (options) => .edge { fill: none; } + .mindmap-node-label { + dy: 1em; + alignment-baseline: middle; + text-anchor: middle; + dominant-baseline: middle; + text-align: center; + } `; export default getStyles; diff --git a/packages/mermaid/src/diagrams/mindmap/svgDraw.js b/packages/mermaid/src/diagrams/mindmap/svgDraw.js index 5394e004e..8b58c11a3 100644 --- a/packages/mermaid/src/diagrams/mindmap/svgDraw.js +++ b/packages/mermaid/src/diagrams/mindmap/svgDraw.js @@ -204,7 +204,7 @@ const roundedRectBkg = function (elem, node) { * @returns {number} The height nodes dom element */ export const drawNode = function (elem, node, fullSection, conf) { - const htmlLabels = false; + const htmlLabels = conf.htmlLabels; const section = fullSection % (MAX_SECTIONS - 1); const nodeElem = elem.append('g'); node.section = section; @@ -217,19 +217,12 @@ export const drawNode = function (elem, node, fullSection, conf) { // Create the wrapped text element const textElem = nodeElem.append('g'); - const newEl = createText(textElem, node.descr, { useHtmlLabels: htmlLabels, width: node.width }); - // const txt = textElem.node().appendChild(newEl); - // const txt = textElem.append(newEl); - // const txt = textElem - // .append('text') - // .text(node.descr) - // .attr('dy', '1em') - // .attr('alignment-baseline', 'middle') - // .attr('dominant-baseline', 'middle') - // .attr('text-anchor', 'middle') - // .call(wrap, node.width); - // const newerEl = textElem.node().appendChild(newEl); - // setSize(textElem); + const newEl = createText(textElem, node.descr, { + useHtmlLabels: htmlLabels, + width: node.width, + classes: 'mindmap-node-label', + }); + if (!htmlLabels) { textElem .attr('dy', '1em') diff --git a/packages/mermaid/src/rendering-util/createText.js b/packages/mermaid/src/rendering-util/createText.js index 47e0776e4..5eea6f4c8 100644 --- a/packages/mermaid/src/rendering-util/createText.js +++ b/packages/mermaid/src/rendering-util/createText.js @@ -17,19 +17,22 @@ function applyStyle(dom, styleFn) { /** * @param element * @param {any} node + * @param width + * @param classes * @returns {SVGForeignObjectElement} Node */ -function addHtmlSpan(element, node) { +function addHtmlSpan(element, node, width, classes) { const fo = element.append('foreignObject'); - const newEl = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject'); + // const newEl = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject'); + // const newEl = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject'); const div = fo.append('xhtml:div'); + // const div = body.append('div'); + // const div = fo.append('div'); const label = node.label; const labelClass = node.isNode ? 'nodeLabel' : 'edgeLabel'; div.html( - '' + label + @@ -37,16 +40,22 @@ function addHtmlSpan(element, node) { ); applyStyle(div, node.labelStyle); - div.style('display', 'inline-block'); - const bbox = div.node().getBoundingClientRect(); + div.style('display', 'table-cell'); + div.style('white-space', 'nowrap'); + div.style('max-width', width + 'px'); + div.attr('xmlns', 'http://www.w3.org/1999/xhtml'); + + let bbox = div.node().getBoundingClientRect(); + if (bbox.width === width) { + div.style('display', 'table'); + div.style('white-space', 'break-spaces'); + div.style('width', '200px'); + bbox = div.node().getBoundingClientRect(); + } + fo.style('width', bbox.width); fo.style('height', bbox.height); - const divNode = div.node(); - window.divNode = divNode; - // Fix for firefox - div.style('white-space', 'nowrap'); - div.attr('xmlns', 'http://www.w3.org/1999/xhtml'); return fo.node(); } @@ -158,7 +167,7 @@ export const createText = ( ), labelStyle: style.replace('fill:', 'color:'), }; - let vertexNode = addHtmlSpan(el, node); + let vertexNode = addHtmlSpan(el, node, width, classes); return vertexNode; } else { const structuredText = markdownToLines(text); diff --git a/packages/mermaid/src/rendering-util/handle-markdown-text.js b/packages/mermaid/src/rendering-util/handle-markdown-text.js index c4d10d9dc..cd79623fe 100644 --- a/packages/mermaid/src/rendering-util/handle-markdown-text.js +++ b/packages/mermaid/src/rendering-util/handle-markdown-text.js @@ -1,12 +1,25 @@ import SimpleMarkdown from '@khanacademy/simple-markdown'; +/** + * + * @param markdown + */ +function preprocessMarkdown(markdown) { + // Replace multiple newlines with a single newline + const withoutMultipleNewlines = markdown.replace(/\n{2,}/g, '\n'); + // Remove extra spaces at the beginning of each line + const withoutExtraSpaces = withoutMultipleNewlines.replace(/^\s+/gm, ''); + return withoutExtraSpaces; +} + /** * * @param markdown */ export function markdownToLines(markdown) { + const preprocessedMarkdown = preprocessMarkdown(markdown); const mdParse = SimpleMarkdown.defaultBlockParse; - const syntaxTree = mdParse(markdown); + const syntaxTree = mdParse(preprocessedMarkdown); let lines = [[]]; let currentLine = 0; @@ -19,6 +32,7 @@ export function markdownToLines(markdown) { function processNode(node, parentType) { if (node.type === 'text') { const textLines = node.content.split('\n'); + textLines.forEach((textLine, index) => { if (index !== 0) { currentLine++; @@ -62,7 +76,7 @@ export function markdownToHTML(markdown) { */ function output(node) { if (node.type === 'text') { - return node.content.replace(/\n/g, '
'); + return node.content.replace(/\n/g, '
'); } else if (node.type === 'strong') { return `${node.content.map(output).join('')}`; } else if (node.type === 'em') { diff --git a/packages/mermaid/src/rendering-util/handle-markdown-text.spec.js b/packages/mermaid/src/rendering-util/handle-markdown-text.spec.js index db542543a..005dd42f6 100644 --- a/packages/mermaid/src/rendering-util/handle-markdown-text.spec.js +++ b/packages/mermaid/src/rendering-util/handle-markdown-text.spec.js @@ -95,6 +95,47 @@ test('markdownToLines - Only bold formatting', () => { expect(output).toEqual(expectedOutput); }); +test('markdownToLines - paragraph 1', () => { + const input = `**Start** with + a second line`; + + const expectedOutput = [ + [ + { content: 'Start', type: 'strong' }, + { content: 'with', type: 'normal' }, + ], + [ + { content: 'a', type: 'normal' }, + { content: 'second', type: 'normal' }, + { content: 'line', type: 'normal' }, + ], + ]; + + const output = markdownToLines(input); + expect(output).toEqual(expectedOutput); +}); + +test('markdownToLines - paragraph', () => { + const input = `**Start** with + + a second line`; + + const expectedOutput = [ + [ + { content: 'Start', type: 'strong' }, + { content: 'with', type: 'normal' }, + ], + [ + { content: 'a', type: 'normal' }, + { content: 'second', type: 'normal' }, + { content: 'line', type: 'normal' }, + ], + ]; + + const output = markdownToLines(input); + expect(output).toEqual(expectedOutput); +}); + test('markdownToLines - Only italic formatting', () => { const input = `This is an *italic* test`; @@ -134,7 +175,7 @@ Here is a new line There is some words **with a bold** section Here is a line *with an italic* section`; - const expectedOutput = `This is regular text
`; + const expectedOutput = `
Here is a new line
There is some words with a bold section
Here is a line with an italic sectionThis is regular text
`; const output = markdownToHTML(input); expect(output).toEqual(expectedOutput); @@ -151,7 +192,7 @@ test('markdownToHTML - No formatting', () => { const input = `This is a simple test with no formatting`; - const expectedOutput = `
Here is a new line
There is some words with a bold section
Here is a line with an italic sectionThis is a simple test
`; + const expectedOutput = `
with no formattingThis is a simple test
`; const output = markdownToHTML(input); expect(output).toEqual(expectedOutput); });
with no formatting