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
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
Here is a new line
There is some words with a bold section
Here is a line with an italic section

`; 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 = `

This is a simple test
with no formatting

`; + const expectedOutput = `

This is a simple test
with no formatting

`; const output = markdownToHTML(input); expect(output).toEqual(expectedOutput); });