From a928120bec3df9ad45670b0e34fc7610ef70544c Mon Sep 17 00:00:00 2001 From: Knut Sveidqvist Date: Mon, 26 Sep 2022 10:44:18 +0200 Subject: [PATCH] #3061 Log handing and other fixes, error handling in diagram creation --- .vite/build.ts | 2 +- cypress/platform/knsv2.html | 14 ++-- package.json | 2 +- packages/mermaid-mindmap/src/mermaidUtils.ts | 4 + packages/mermaid-mindmap/src/mindmapDb.js | 16 +++- .../mermaid-mindmap/src/mindmapRenderer.js | 80 ++++++++++--------- .../mermaid-mindmap/src/parser/mindmap.jison | 54 ++++++------- packages/mermaid-mindmap/src/registry.ts | 4 +- packages/mermaid/src/Diagram.ts | 18 +---- packages/mermaid/src/mermaid.ts | 2 +- 10 files changed, 101 insertions(+), 95 deletions(-) diff --git a/.vite/build.ts b/.vite/build.ts index dec58854c..c263f78ea 100644 --- a/.vite/build.ts +++ b/.vite/build.ts @@ -97,7 +97,7 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions) if (watch && config.build) { config.build.watch = { - include: 'src/**', + include: ['packages/mermaid-mindmap/src/**', 'packages/mermaid/src/**'], }; } diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html index cc4e8f135..0c887f246 100644 --- a/cypress/platform/knsv2.html +++ b/cypress/platform/knsv2.html @@ -45,12 +45,12 @@
Security check
-
-flowchart LR
-      A --> B
-    
-        mindmap
+flowchart LR
+      A -> B
+    
+
+        mindmap((
           root
             ch1
             ch2
@@ -71,6 +71,10 @@ flowchart LR
       function callback() {
         alert('It worked');
       }
+      mermaid.parseError = function (err, hash) {
+        console.error('In parse error:');
+        console.error(err);
+      };
     
   
 
diff --git a/package.json b/package.json
index 4f07b6986..653723bf4 100644
--- a/package.json
+++ b/package.json
@@ -29,7 +29,7 @@
     "clean": "rimraf dist",
     "build:vite": "ts-node-esm --transpileOnly --project=.vite/tsconfig.json .vite/build.ts",
     "build:types": "concurrently \"tsc -p ./packages/mermaid/tsconfig.json --emitDeclarationOnly\" \"tsc -p ./packages/mermaid-mindmap/tsconfig.json --emitDeclarationOnly\"",
-    "build:watch": "pnpm build:code --watch",
+    "build:watch": "pnpm build:vite --watch",
     "build": "pnpm clean; concurrently \"pnpm build:vite\" \"pnpm build:types\"",
     "dev": "concurrently \"pnpm build:vite --watch\" \"ts-node-esm .vite/server\"",
     "docs:build": "ts-node-esm --transpileOnly packages/mermaid/src/docs.mts",
diff --git a/packages/mermaid-mindmap/src/mermaidUtils.ts b/packages/mermaid-mindmap/src/mermaidUtils.ts
index 82bf3653b..a65523f0c 100644
--- a/packages/mermaid-mindmap/src/mermaidUtils.ts
+++ b/packages/mermaid-mindmap/src/mermaidUtils.ts
@@ -41,10 +41,13 @@ export const injectUtils = (
   _sanitizeText: any,
   _setupGraphViewbox: any
 ) => {
+  _log.info('Mermaid utils injected');
+  log.trace = _log.trace;
   log.debug = _log.debug;
   log.info = _log.info;
   log.warn = _log.warn;
   log.error = _log.error;
+  log.fatal = _log.fatal;
   setLogLevel = _setLogLevel;
   getConfig = _getConfig;
   sanitizeText = _sanitizeText;
@@ -55,6 +58,7 @@ export const injectUtils = (
 const warning = (..._args: any[]) => {
   console.error('Log function was called before initialization');
 };
+
 export let log = {
   trace: warning,
   debug: warning,
diff --git a/packages/mermaid-mindmap/src/mindmapDb.js b/packages/mermaid-mindmap/src/mindmapDb.js
index 3b322b2b4..cbe4d0286 100644
--- a/packages/mermaid-mindmap/src/mindmapDb.js
+++ b/packages/mermaid-mindmap/src/mindmapDb.js
@@ -1,5 +1,5 @@
 /** Created by knut on 15-01-14. */
-import { sanitizeText, getConfig, log as _log } from './mermaidUtils';
+import { sanitizeText, getConfig, log } from './mermaidUtils';
 
 let nodes = [];
 let cnt = 0;
@@ -131,9 +131,19 @@ export const type2Str = (type) => {
       return 'no-border';
   }
 };
+
+export let parseError; // = (str, hash)
+//  => {
+//   const error = { str, hash };
+//   throw error;
+// };
+export const setErrorHandler = (handler) => {
+  parseError = handler;
+};
+
 // Expose logger to grammar
-export const log = _log;
-export let graphType = 'mindmap';
+export const getLogger = () => log;
+
 export const getNodeById = (id) => nodes[id];
 export const getElementById = (id) => elements[id];
 // export default {
diff --git a/packages/mermaid-mindmap/src/mindmapRenderer.js b/packages/mermaid-mindmap/src/mindmapRenderer.js
index 9ad81df9d..aab12a157 100644
--- a/packages/mermaid-mindmap/src/mindmapRenderer.js
+++ b/packages/mermaid-mindmap/src/mindmapRenderer.js
@@ -215,51 +215,53 @@ function positionNodes(node, conf) {
  * @param {any} version
  * @param diagObj
  */
+
 export const draw = (text, id, version, diagObj) => {
   const conf = getConfig();
-  try {
-    log.debug('Renering info diagram\n' + text);
 
-    const securityLevel = getConfig().securityLevel;
-    // Handle root and Document 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');
-    // Parse the graph definition
+  // This is done only for throwing the error if the text is not valid.
+  diagObj.db.clear();
+  // Parse the graph definition
+  diagObj.parser.parse(text);
 
-    const svg = root.select('#' + id);
+  log.debug('Renering info diagram\n' + text);
 
-    svg.append('g');
-    const mm = diagObj.db.getMindmap();
-
-    // Draw the graph and start with drawing the nodes without proper position
-    // this gives us the size of the nodes and we can set the positions later
-
-    const edgesElem = svg.append('g');
-    edgesElem.attr('class', 'mindmap-edges');
-    const nodesElem = svg.append('g');
-    nodesElem.attr('class', 'mindmap-nodes');
-    drawNodes(nodesElem, mm, -1, conf);
-
-    // Next step is to layout the mindmap, giving each node a position
-
-    const positionedMindmap = layoutMindmap(mm, conf);
-
-    // After this we can draw, first the edges and the then nodes with the correct position
-    drawEdges(edgesElem, positionedMindmap, null, 0, -1, conf);
-    positionNodes(positionedMindmap, conf);
-
-    // Setup the view box and size of the svg element
-    setupGraphViewbox(undefined, svg, conf.mindmap.padding, conf.mindmap.useMaxWidth);
-  } catch (e) {
-    log.error('Error while rendering info diagram');
-    log.error(e.message);
+  const securityLevel = getConfig().securityLevel;
+  // Handle root and Document 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');
+  // Parse the graph definition
+
+  const svg = root.select('#' + id);
+
+  svg.append('g');
+  const mm = diagObj.db.getMindmap();
+
+  // Draw the graph and start with drawing the nodes without proper position
+  // this gives us the size of the nodes and we can set the positions later
+
+  const edgesElem = svg.append('g');
+  edgesElem.attr('class', 'mindmap-edges');
+  const nodesElem = svg.append('g');
+  nodesElem.attr('class', 'mindmap-nodes');
+  drawNodes(nodesElem, mm, -1, conf);
+
+  // Next step is to layout the mindmap, giving each node a position
+
+  const positionedMindmap = layoutMindmap(mm, conf);
+
+  // After this we can draw, first the edges and the then nodes with the correct position
+  drawEdges(edgesElem, positionedMindmap, null, 0, -1, conf);
+  positionNodes(positionedMindmap, conf);
+
+  // Setup the view box and size of the svg element
+  setupGraphViewbox(undefined, svg, conf.mindmap.padding, conf.mindmap.useMaxWidth);
 };
 
 export default {
diff --git a/packages/mermaid-mindmap/src/parser/mindmap.jison b/packages/mermaid-mindmap/src/parser/mindmap.jison
index f8c72787c..bd008db7f 100644
--- a/packages/mermaid-mindmap/src/parser/mindmap.jison
+++ b/packages/mermaid-mindmap/src/parser/mindmap.jison
@@ -17,21 +17,21 @@
 
 %%
 
-\s*\%\%.*          {yy.log.trace('Found comment',yytext);}
+\s*\%\%.*          {yy.getLogger().trace('Found comment',yytext);}
 // \%\%[^\n]*\n                             /* skip comments */
 "mindmap"		       return 'MINDMAP';
 ":::"              { this.begin('CLASS'); }
 .+			     { this.popState();return 'CLASS'; }
 \n				   { this.popState();}
 // [\s]*"::icon("   { this.begin('ICON'); }
-"::icon("   { yy.log.trace('Begin icon');this.begin('ICON'); }
+"::icon("   { yy.getLogger().trace('Begin icon');this.begin('ICON'); }
 [\n]+               return 'NL';
 [^\)]+			 { return 'ICON'; }
-\)				   {yy.log.trace('end icon');this.popState();}
-"-)"               { yy.log.trace('Exploding node'); this.begin('NODE');return 'NODE_DSTART'; }
-"(-"               { yy.log.trace('Cloud'); this.begin('NODE');return 'NODE_DSTART'; }
-"))"               { yy.log.trace('Explosion Bang'); this.begin('NODE');return 'NODE_DSTART'; }
-")"               { yy.log.trace('Cloud Bang'); this.begin('NODE');return 'NODE_DSTART'; }
+\)				   {yy.getLogger().trace('end icon');this.popState();}
+"-)"               { yy.getLogger().trace('Exploding node'); this.begin('NODE');return 'NODE_DSTART'; }
+"(-"               { yy.getLogger().trace('Cloud'); this.begin('NODE');return 'NODE_DSTART'; }
+"))"               { yy.getLogger().trace('Explosion Bang'); this.begin('NODE');return 'NODE_DSTART'; }
+")"               { yy.getLogger().trace('Cloud Bang'); this.begin('NODE');return 'NODE_DSTART'; }
 "(("               { this.begin('NODE');return 'NODE_DSTART'; }
 "("                { this.begin('NODE');return 'NODE_DSTART'; }
 "["                { this.begin('NODE');return 'NODE_DSTART'; }
@@ -39,18 +39,18 @@
 // !(-\()            return 'NODE_ID';
 [^\(\[\n\-\)]+         return 'NODE_ID';
 <>            return 'EOF';
-["]          { yy.log.trace('Starting NSTR');this.begin("NSTR");}
-[^"]+        { yy.log.trace('description:', yytext); return "NODE_DESCR";}
+["]          { yy.getLogger().trace('Starting NSTR');this.begin("NSTR");}
+[^"]+        { yy.getLogger().trace('description:', yytext); return "NODE_DESCR";}
 ["]          {this.popState();}
-[\)]\)         {this.popState();yy.log.trace('node end ))');return "NODE_DEND";}
-[\)]         {this.popState();yy.log.trace('node end )');return "NODE_DEND";}
-[\]]         {this.popState();yy.log.trace('node end ...',yytext);return "NODE_DEND";}
-"(-"         {this.popState();yy.log.trace('node end (-');return "NODE_DEND";}
-"-)"         {this.popState();yy.log.trace('node end (-');return "NODE_DEND";}
-"(("         {this.popState();yy.log.trace('node end ((');return "NODE_DEND";}
-"("         {this.popState();yy.log.trace('node end ((');return "NODE_DEND";}
-[^\)\]\(]+     { yy.log.trace('Long description:', yytext);   return 'NODE_DESCR';}
-.+(?!\(\()     { yy.log.trace('Long description:', yytext);   return 'NODE_DESCR';}
+[\)]\)         {this.popState();yy.getLogger().trace('node end ))');return "NODE_DEND";}
+[\)]         {this.popState();yy.getLogger().trace('node end )');return "NODE_DEND";}
+[\]]         {this.popState();yy.getLogger().trace('node end ...',yytext);return "NODE_DEND";}
+"(-"         {this.popState();yy.getLogger().trace('node end (-');return "NODE_DEND";}
+"-)"         {this.popState();yy.getLogger().trace('node end (-');return "NODE_DEND";}
+"(("         {this.popState();yy.getLogger().trace('node end ((');return "NODE_DEND";}
+"("         {this.popState();yy.getLogger().trace('node end ((');return "NODE_DEND";}
+[^\)\]\(]+     { yy.getLogger().trace('Long description:', yytext);   return 'NODE_DESCR';}
+.+(?!\(\()     { yy.getLogger().trace('Long description:', yytext);   return 'NODE_DESCR';}
 // [\[]               return 'NODE_START';
 // .+                 return 'TXT' ;
 
@@ -68,10 +68,10 @@ start
 	;
 
 stop
-  : NL {yy.log.trace('Stop NL ');}
-  | EOF {yy.log.trace('Stop EOF ');}
-  | stop NL {yy.log.trace('Stop NL2 ');}
-  | stop EOF {yy.log.trace('Stop EOF2 ');}
+  : NL {yy.getLogger().trace('Stop NL ');}
+  | EOF {yy.getLogger().trace('Stop EOF ');}
+  | stop NL {yy.getLogger().trace('Stop NL2 ');}
+  | stop EOF {yy.getLogger().trace('Stop EOF2 ');}
   ;
 document
 	: document statement stop
@@ -79,10 +79,10 @@ document
 	;
 
 statement
-	: SPACELIST node       { yy.log.trace('Node: ',$2.id);yy.addNode($1.length, $2.id, $2.descr, $2.type);  }
-	| SPACELIST ICON       { yy.log.trace('Icon: ',$2);yy.decorateNode({icon: $2}); }
+	: SPACELIST node       { yy.getLogger().trace('Node: ',$2.id);yy.addNode($1.length, $2.id, $2.descr, $2.type);  }
+	| SPACELIST ICON       { yy.getLogger().trace('Icon: ',$2);yy.decorateNode({icon: $2}); }
 	| SPACELIST CLASS      { yy.decorateNode({class: $2}); }
-	| node					       { yy.log.trace('Node: ',$1.id);yy.addNode(0, $1.id, $1.descr, $1.type);  }
+	| node					       { yy.getLogger().trace('Node: ',$1.id);yy.addNode(0, $1.id, $1.descr, $1.type);  }
 	| ICON                 { yy.decorateNode({icon: $1}); }
 	| CLASS                { yy.decorateNode({class: $1}); }
   | SPACELIST
@@ -97,12 +97,12 @@ node
 
 nodeWithoutId
   :   NODE_DSTART NODE_DESCR NODE_DEND
-	      { yy.log.trace("node found ..", $1); $$ = { id: $2, descr: $2, type: yy.getType($1, $3) }; }
+	      { yy.getLogger().trace("node found ..", $1); $$ = { id: $2, descr: $2, type: yy.getType($1, $3) }; }
   ;
 
 nodeWithId
 	:  NODE_ID             { $$ = { id: $1, descr: $1, type: yy.nodeType.DEFAULT }; }
 	|  NODE_ID NODE_DSTART NODE_DESCR NODE_DEND
-	                       { yy.log.trace("node found ..", $1); $$ = { id: $1, descr: $3, type: yy.getType($2, $4) }; }
+	                       { yy.getLogger().trace("node found ..", $1); $$ = { id: $1, descr: $3, type: yy.getType($2, $4) }; }
 	;
 %%
diff --git a/packages/mermaid-mindmap/src/registry.ts b/packages/mermaid-mindmap/src/registry.ts
index 837929f33..141b6e25e 100644
--- a/packages/mermaid-mindmap/src/registry.ts
+++ b/packages/mermaid-mindmap/src/registry.ts
@@ -5,10 +5,10 @@ if (typeof document !== 'undefined') {
   if (window.mermaid && typeof window.mermaid.detectors === 'object') {
     window.mermaid.detectors.push({ id: 'mindmap', detector: mindmapDetector });
   } else {
-    console.error('window.mermaid.detectors not found'); // eslint-disable-line no-console
+    // console.error('window.mermaid.detectors was not found!'); // eslint-disable-line no-console
     window.mermaid = {};
     window.mermaid.detectors = [{ id: 'mindmap', detector: mindmapDetector }];
-    console.error('Detectors now:', window.mermaid.detectors); // eslint-disable-line no-console
+    // console.error('Detectors now:', window.mermaid.detectors); // eslint-disable-line no-console
   }
 
   /*!
diff --git a/packages/mermaid/src/Diagram.ts b/packages/mermaid/src/Diagram.ts
index a695db6f6..a56338955 100644
--- a/packages/mermaid/src/Diagram.ts
+++ b/packages/mermaid/src/Diagram.ts
@@ -15,33 +15,19 @@ export class Diagram {
     this.type = detectType(txt, cnf);
     const diagram = getDiagram(this.type);
     log.debug('Type ' + this.type);
-    // console.log('Type ' + this.type);
     // Setup diagram
     this.db = diagram.db;
     this.db.clear?.();
     this.renderer = diagram.renderer;
     this.parser = diagram.parser;
-    // console.log('Setting db to !', this.db);
     this.parser.parser.yy = this.db;
     if (diagram.init) {
       diagram.init(cnf);
       log.debug('Initialized diagram ' + this.type, cnf);
     }
     this.txt += '\n';
-    try {
-      this.parser.parser.yy.graphType = this.type;
-      this.parser.parser.yy.parseError = (str: string, hash: string) => {
-        const error = { str, hash };
-        throw error;
-      };
-    } catch (error) {
-      log.error('error', error);
-    }
-    try {
-      this.parse(this.txt, parseError);
-    } catch (error) {
-      log.error('error', error);
-    }
+
+    this.parse(this.txt, parseError);
   }
 
   // eslint-disable-next-line @typescript-eslint/ban-types
diff --git a/packages/mermaid/src/mermaid.ts b/packages/mermaid/src/mermaid.ts
index 1d63ba6c9..597109618 100644
--- a/packages/mermaid/src/mermaid.ts
+++ b/packages/mermaid/src/mermaid.ts
@@ -53,7 +53,7 @@ const init = function (
   callback?: Function
 ) {
   try {
-    console.error('Detectors in init', mermaid.detectors); // eslint-disable-line
+    log.info('Detectors in init', mermaid.detectors); // eslint-disable-line
     mermaid.detectors.forEach(({ id, detector }) => {
       addDetector(id, detector);
     });