From ccd55a0bde2782546d49eb62c19478cf305c7bf3 Mon Sep 17 00:00:00 2001 From: "Ashley Engelund (weedySeaDragon @ github)" Date: Mon, 14 Nov 2022 11:24:59 -0800 Subject: [PATCH 01/10] add stateDiagram-v2 to list of graphs with classDefs --- packages/mermaid/src/mermaidAPI.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mermaid/src/mermaidAPI.ts b/packages/mermaid/src/mermaidAPI.ts index b921655ab3..7a67c708ea 100644 --- a/packages/mermaid/src/mermaidAPI.ts +++ b/packages/mermaid/src/mermaidAPI.ts @@ -32,7 +32,7 @@ import { evaluate } from './diagrams/common/common'; import { isEmpty } from 'lodash'; // diagram names that support classDef statements -const CLASSDEF_DIAGRAMS = ['graph', 'flowchart', 'flowchart-v2', 'stateDiagram']; +const CLASSDEF_DIAGRAMS = ['graph', 'flowchart', 'flowchart-v2', 'stateDiagram', 'stateDiagram-v2']; const MAX_TEXTLENGTH_EXCEEDED_MSG = 'graph TB;a[Maximum text size in diagram exceeded];style a fill:#faa'; From 345eaade221fb15b0777ff07f74219d06ce61d41 Mon Sep 17 00:00:00 2001 From: "Ashley Engelund (weedySeaDragon @ github)" Date: Mon, 14 Nov 2022 11:39:58 -0800 Subject: [PATCH 02/10] stateDB classes must be a {} not [] --- packages/mermaid/src/diagrams/state/stateDb.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/mermaid/src/diagrams/state/stateDb.js b/packages/mermaid/src/diagrams/state/stateDb.js index d0877847cf..914ac74109 100644 --- a/packages/mermaid/src/diagrams/state/stateDb.js +++ b/packages/mermaid/src/diagrams/state/stateDb.js @@ -31,9 +31,15 @@ const FILL_KEYWORD = 'fill'; const BG_FILL = 'bgFill'; const STYLECLASS_SEP = ','; +// Returns a new list of classes. +// In the future, this can be replaced with a class common to all diagrams. +function newClassesList() { + return {}; +} + let direction = DEFAULT_DIAGRAM_DIRECTION; let rootDoc = []; -let classes = []; // style classes defined by a classDef +let classes = newClassesList(); // style classes defined by a classDef const newDoc = () => { return { @@ -274,7 +280,7 @@ export const clear = function (saveCommon) { // number of start and end nodes; used to construct ids startEndCount = 0; - classes = []; + classes = newClassesList(); if (!saveCommon) { commonClear(); } From 9996e53e24cced6bbfc0681161345cc0a313a1d8 Mon Sep 17 00:00:00 2001 From: "Ashley Engelund (weedySeaDragon @ github)" Date: Tue, 15 Nov 2022 08:50:20 -0800 Subject: [PATCH 03/10] (minor) add comments, remove duplicated line --- packages/mermaid/src/diagrams/state/stateDb.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/mermaid/src/diagrams/state/stateDb.js b/packages/mermaid/src/diagrams/state/stateDb.js index 914ac74109..cf012fc2cd 100644 --- a/packages/mermaid/src/diagrams/state/stateDb.js +++ b/packages/mermaid/src/diagrams/state/stateDb.js @@ -31,8 +31,13 @@ const FILL_KEYWORD = 'fill'; const BG_FILL = 'bgFill'; const STYLECLASS_SEP = ','; -// Returns a new list of classes. -// In the future, this can be replaced with a class common to all diagrams. +/** + * Returns a new list of classes. + * In the future, this can be replaced with a class common to all diagrams. + * ClassDef information = { id: id, styles: [], textStyles: [] } + * + * @return {{}} + */ function newClassesList() { return {}; } @@ -276,8 +281,6 @@ export const clear = function (saveCommon) { }; currentDocument = documents.root; - currentDocument = documents.root; - // number of start and end nodes; used to construct ids startEndCount = 0; classes = newClassesList(); @@ -453,7 +456,7 @@ const getDividerId = () => { export const addStyleClass = function (id, styleAttributes = '') { // create a new style class object with this id if (typeof classes[id] === 'undefined') { - classes[id] = { id: id, styles: [], textStyles: [] }; + classes[id] = { id: id, styles: [], textStyles: [] }; // This is a classDef } const foundClass = classes[id]; if (typeof styleAttributes !== 'undefined') { From d3f5474f38155d3af63718e90b646d58123ff88c Mon Sep 17 00:00:00 2001 From: "Ashley Engelund (weedySeaDragon @ github)" Date: Tue, 15 Nov 2022 08:59:01 -0800 Subject: [PATCH 04/10] (minor) fix JSdoc types in comments --- packages/mermaid/src/diagrams/state/stateDb.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/mermaid/src/diagrams/state/stateDb.js b/packages/mermaid/src/diagrams/state/stateDb.js index cf012fc2cd..3c7ca6b6a1 100644 --- a/packages/mermaid/src/diagrams/state/stateDb.js +++ b/packages/mermaid/src/diagrams/state/stateDb.js @@ -309,7 +309,7 @@ export const getRelations = function () { * else return the given id * * @param {string} id - * @returns {{id: string, type: string}} - the id and type that should be used + * @returns {string} - the id (original or constructed) */ function startIdIfNeeded(id = '') { let fixedId = id; @@ -338,7 +338,7 @@ function startTypeIfNeeded(id = '', type = DEFAULT_STATE_TYPE) { * else return the given id * * @param {string} id - * @returns {{id: string, type: string}} - the id and type that should be used + * @returns {string} - the id (original or constructed) */ function endIdIfNeeded(id = '') { let fixedId = id; @@ -451,7 +451,7 @@ const getDividerId = () => { * @example classDef my-style fill:#f96; * * @param {string} id - the id of this (style) class - * @param {string} styleAttributes - the string with 1 or more style attributes (each separated by a comma) + * @param {string | null} styleAttributes - the string with 1 or more style attributes (each separated by a comma) */ export const addStyleClass = function (id, styleAttributes = '') { // create a new style class object with this id From c6db0524bd39ba85f390b615959ee7431a053d9b Mon Sep 17 00:00:00 2001 From: "Ashley Engelund (weedySeaDragon @ github)" Date: Tue, 15 Nov 2022 09:01:34 -0800 Subject: [PATCH 05/10] + spec stateRenderer-v2.js getClasses() to verify it returns a {} --- .../diagrams/state/stateDiagram-v2.spec.js | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/packages/mermaid/src/diagrams/state/stateDiagram-v2.spec.js b/packages/mermaid/src/diagrams/state/stateDiagram-v2.spec.js index 39ec0f0d2c..81dae6dbb1 100644 --- a/packages/mermaid/src/diagrams/state/stateDiagram-v2.spec.js +++ b/packages/mermaid/src/diagrams/state/stateDiagram-v2.spec.js @@ -1,8 +1,24 @@ import { parser } from './parser/stateDiagram'; import stateDb from './stateDb'; import stateDiagram from './parser/stateDiagram.jison'; +import stateRendererV2 from './stateRenderer-v2'; + +// Can use this instead of having to register diagrams and load/orchestrate them, etc. +class FauxDiagramObj { + db = stateDb; + parser = parser; + renderer = stateRendererV2; + + constructor(options = { db: stateDb, parser: parser, renderer: stateRendererV2 }) { + this.db = options.db; + this.parser = options.parser; + this.renderer = options.renderer; + this.parser.yy = this.db; + } +} describe('state diagram V2, ', function () { + // TODO - these examples should be put into ./parser/stateDiagram.spec.js describe('when parsing an info graph it', function () { beforeEach(function () { parser.yy = stateDb; @@ -423,4 +439,16 @@ describe('state diagram V2, ', function () { expect(rel_Active_Active.relationTitle).toEqual('LOG'); }); }); + + describe('stateRenderer-v2', () => { + describe('getClasses', () => { + const diagramText = 'statediagram-v2\n'; + const fauxStateDiagram = new FauxDiagramObj(); + + it('returns a {}', () => { + const result = stateRendererV2.getClasses(diagramText, fauxStateDiagram); + expectTypeOf(result).toBeObject(); + }); + }); + }); }); From 1ecd4a551d042ddb652b060b1db318751399e70e Mon Sep 17 00:00:00 2001 From: "Ashley Engelund (weedySeaDragon @ github)" Date: Tue, 15 Nov 2022 09:13:27 -0800 Subject: [PATCH 06/10] (minor) fix JSdoc tag --- packages/mermaid/src/diagrams/state/stateDb.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mermaid/src/diagrams/state/stateDb.js b/packages/mermaid/src/diagrams/state/stateDb.js index 3c7ca6b6a1..5e82eaf78b 100644 --- a/packages/mermaid/src/diagrams/state/stateDb.js +++ b/packages/mermaid/src/diagrams/state/stateDb.js @@ -36,7 +36,7 @@ const STYLECLASS_SEP = ','; * In the future, this can be replaced with a class common to all diagrams. * ClassDef information = { id: id, styles: [], textStyles: [] } * - * @return {{}} + * @returns {{}} */ function newClassesList() { return {}; From 6090a1f65ab0045b11b3818c18ea17af58b41b2b Mon Sep 17 00:00:00 2001 From: "Ashley Engelund (weedySeaDragon @ github)" Date: Tue, 15 Nov 2022 09:14:00 -0800 Subject: [PATCH 07/10] (minor) import expectTypeOf in spec --- packages/mermaid/src/diagrams/state/stateDiagram-v2.spec.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/mermaid/src/diagrams/state/stateDiagram-v2.spec.js b/packages/mermaid/src/diagrams/state/stateDiagram-v2.spec.js index 81dae6dbb1..38bb44727e 100644 --- a/packages/mermaid/src/diagrams/state/stateDiagram-v2.spec.js +++ b/packages/mermaid/src/diagrams/state/stateDiagram-v2.spec.js @@ -1,3 +1,5 @@ +import { expectTypeOf } from 'vitest'; + import { parser } from './parser/stateDiagram'; import stateDb from './stateDb'; import stateDiagram from './parser/stateDiagram.jison'; From 13f3008f8200102e3f442f819c6d39380246973a Mon Sep 17 00:00:00 2001 From: "Ashley Engelund (weedySeaDragon @ github)" Date: Tue, 15 Nov 2022 09:18:10 -0800 Subject: [PATCH 08/10] diagramClasses no longer needs to be cached; mermaidAPI no longer calls it repeatedly --- .../src/diagrams/state/stateRenderer-v2.js | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/packages/mermaid/src/diagrams/state/stateRenderer-v2.js b/packages/mermaid/src/diagrams/state/stateRenderer-v2.js index 1011fb6b13..f9e6d4183a 100644 --- a/packages/mermaid/src/diagrams/state/stateRenderer-v2.js +++ b/packages/mermaid/src/diagrams/state/stateRenderer-v2.js @@ -58,11 +58,7 @@ const G_EDGE_LABELTYPE = 'text'; const G_EDGE_THICKNESS = 'normal'; // -------------------------------------- -// When information is parsed and processed (extracted) by stateDb.extract() -// These are globals so the information can be accessed as needed (e.g. in setUpNode, etc.) let diagramStates = []; -let diagramClasses = []; - // List of nodes created from the parsed diagram statement items let nodeDb = {}; @@ -81,18 +77,14 @@ export const setConf = function (cnf) { }; /** - * Returns the all the styles from classDef statements in the graph definition. + * Returns the all the classdef styles (a.k.a. classes) from classDef statements in the graph definition. * * @param {string} text - the diagram text to be parsed - * @param {Diagram} diagramObj - * @returns {object} ClassDef styles + * @param diagramObj + * @returns {object} ClassDef styles (a Map with keys = strings, values = ) */ export const getClasses = function (text, diagramObj) { log.trace('Extracting classes'); - if (diagramClasses.length > 0) { - return diagramClasses; // we have already extracted the classes - } - diagramObj.db.clear(); try { // Parse the graph definition @@ -407,8 +399,7 @@ export const draw = function (text, id, _version, diag) { diag.db.extract(diag.db.getRootDocV2()); log.info(diag.db.getRootDocV2()); - diagramStates = diag.db.getStates(); - diagramClasses = diag.db.getClasses(); + const diagramStates = diag.db.getStates(); // Create the input mermaid.graph const g = new graphlib.Graph({ From fcec9adbcd734137a0e581adac4299e3bb23f987 Mon Sep 17 00:00:00 2001 From: "Ashley Engelund (weedySeaDragon @ github)" Date: Tue, 15 Nov 2022 09:19:27 -0800 Subject: [PATCH 09/10] diagramStates should not be global; pass it into functions; minor comment fixes --- .../src/diagrams/state/stateRenderer-v2.js | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/mermaid/src/diagrams/state/stateRenderer-v2.js b/packages/mermaid/src/diagrams/state/stateRenderer-v2.js index f9e6d4183a..752b70e445 100644 --- a/packages/mermaid/src/diagrams/state/stateRenderer-v2.js +++ b/packages/mermaid/src/diagrams/state/stateRenderer-v2.js @@ -58,7 +58,6 @@ const G_EDGE_LABELTYPE = 'text'; const G_EDGE_THICKNESS = 'normal'; // -------------------------------------- -let diagramStates = []; // List of nodes created from the parsed diagram statement items let nodeDb = {}; @@ -91,7 +90,6 @@ export const getClasses = function (text, diagramObj) { diagramObj.parser.parse(text); // must run extract() to turn the parsed statements into states, relationships, classes, etc. diagramObj.db.extract(diagramObj.db.getRootDocV2()); - return diagramObj.db.getClasses(); } catch (e) { return e; @@ -99,7 +97,7 @@ export const getClasses = function (text, diagramObj) { }; /** - * Get classes from the db info item. + * Get classes from the db for the info item. * If there aren't any or if dbInfoItem isn't defined, return an empty string. * Else create 1 string from the list of classes found * @@ -124,7 +122,7 @@ function getClassesFromDbInfo(dbInfoItem) { * * @param itemId * @param counter - * @param type + * @param {string | null} type * @param typeSpacer * @returns {string} */ @@ -139,10 +137,11 @@ export function stateDomId(itemId = '', counter = 0, type = '', typeSpacer = DOM * @param g - graph * @param {object} parent * @param {object} parsedItem - parsed statement item + * @param {object[]} diagramStates - the list of all known states for the diagram * @param {object} diagramDb * @param {boolean} altFlag - for clusters, add the "statediagram-cluster-alt" CSS class */ -const setupNode = (g, parent, parsedItem, diagramDb, altFlag) => { +const setupNode = (g, parent, parsedItem, diagramStates, diagramDb, altFlag) => { const itemId = parsedItem.id; const classStr = getClassesFromDbInfo(diagramStates[itemId]); @@ -299,7 +298,7 @@ const setupNode = (g, parent, parsedItem, diagramDb, altFlag) => { } if (parsedItem.doc) { log.trace('Adding nodes children '); - setupDoc(g, parsedItem, parsedItem.doc, diagramDb, !altFlag); + setupDoc(g, parsedItem, parsedItem.doc, diagramStates, diagramDb, !altFlag); } }; @@ -310,25 +309,26 @@ const setupNode = (g, parent, parsedItem, diagramDb, altFlag) => { * @param g * @param parentParsedItem - parsed Item that is the parent of this document (doc) * @param doc - the document to set up + * @param {object} diagramStates - the list of all known states for the diagram * @param diagramDb - * @param altFlag + * @param {boolean} altFlag * @todo This duplicates some of what is done in stateDb.js extract method */ -const setupDoc = (g, parentParsedItem, doc, diagramDb, altFlag) => { +const setupDoc = (g, parentParsedItem, doc, diagramStates, diagramDb, altFlag) => { // graphItemCount = 0; log.trace('items', doc); doc.forEach((item) => { switch (item.stmt) { case STMT_STATE: - setupNode(g, parentParsedItem, item, diagramDb, altFlag); + setupNode(g, parentParsedItem, item, diagramStates, diagramDb, altFlag); break; case DEFAULT_STATE_TYPE: - setupNode(g, parentParsedItem, item, diagramDb, altFlag); + setupNode(g, parentParsedItem, item, diagramStates, diagramDb, altFlag); break; case STMT_RELATION: { - setupNode(g, parentParsedItem, item.state1, diagramDb, altFlag); - setupNode(g, parentParsedItem, item.state2, diagramDb, altFlag); + setupNode(g, parentParsedItem, item.state1, diagramStates, diagramDb, altFlag); + setupNode(g, parentParsedItem, item.state2, diagramStates, diagramDb, altFlag); const edgeData = { id: 'edge' + graphItemCount, arrowhead: 'normal', @@ -417,7 +417,7 @@ export const draw = function (text, id, _version, diag) { return {}; }); - setupNode(g, undefined, diag.db.getRootDocV2(), diag.db, true); + setupNode(g, undefined, diag.db.getRootDocV2(), diagramStates, diag.db, true); // Set up an SVG group so that we can translate the final graph. let sandboxElement; From 2cbf6110a6266fd20ad0f32b98293c8181abe92f Mon Sep 17 00:00:00 2001 From: "Ashley Engelund (weedySeaDragon @ github)" Date: Tue, 15 Nov 2022 12:30:10 -0800 Subject: [PATCH 10/10] create separate spec for stateRenderer-v2 --- .../diagrams/state/stateDiagram-v2.spec.js | 29 ----------------- .../diagrams/state/stateRenderer-v2.spec.js | 31 +++++++++++++++++++ 2 files changed, 31 insertions(+), 29 deletions(-) create mode 100644 packages/mermaid/src/diagrams/state/stateRenderer-v2.spec.js diff --git a/packages/mermaid/src/diagrams/state/stateDiagram-v2.spec.js b/packages/mermaid/src/diagrams/state/stateDiagram-v2.spec.js index 38bb44727e..7ed5555dba 100644 --- a/packages/mermaid/src/diagrams/state/stateDiagram-v2.spec.js +++ b/packages/mermaid/src/diagrams/state/stateDiagram-v2.spec.js @@ -1,23 +1,6 @@ -import { expectTypeOf } from 'vitest'; - import { parser } from './parser/stateDiagram'; import stateDb from './stateDb'; import stateDiagram from './parser/stateDiagram.jison'; -import stateRendererV2 from './stateRenderer-v2'; - -// Can use this instead of having to register diagrams and load/orchestrate them, etc. -class FauxDiagramObj { - db = stateDb; - parser = parser; - renderer = stateRendererV2; - - constructor(options = { db: stateDb, parser: parser, renderer: stateRendererV2 }) { - this.db = options.db; - this.parser = options.parser; - this.renderer = options.renderer; - this.parser.yy = this.db; - } -} describe('state diagram V2, ', function () { // TODO - these examples should be put into ./parser/stateDiagram.spec.js @@ -441,16 +424,4 @@ describe('state diagram V2, ', function () { expect(rel_Active_Active.relationTitle).toEqual('LOG'); }); }); - - describe('stateRenderer-v2', () => { - describe('getClasses', () => { - const diagramText = 'statediagram-v2\n'; - const fauxStateDiagram = new FauxDiagramObj(); - - it('returns a {}', () => { - const result = stateRendererV2.getClasses(diagramText, fauxStateDiagram); - expectTypeOf(result).toBeObject(); - }); - }); - }); }); diff --git a/packages/mermaid/src/diagrams/state/stateRenderer-v2.spec.js b/packages/mermaid/src/diagrams/state/stateRenderer-v2.spec.js new file mode 100644 index 0000000000..3a118e607d --- /dev/null +++ b/packages/mermaid/src/diagrams/state/stateRenderer-v2.spec.js @@ -0,0 +1,31 @@ +import { expectTypeOf } from 'vitest'; + +import { parser } from './parser/stateDiagram'; +import stateDb from './stateDb'; +import stateRendererV2 from './stateRenderer-v2'; + +// Can use this instead of having to register diagrams and load/orchestrate them, etc. +class FauxDiagramObj { + db = stateDb; + parser = parser; + renderer = stateRendererV2; + + constructor(options = { db: stateDb, parser: parser, renderer: stateRendererV2 }) { + this.db = options.db; + this.parser = options.parser; + this.renderer = options.renderer; + this.parser.yy = this.db; + } +} + +describe('stateRenderer-v2', () => { + describe('getClasses', () => { + const diagramText = 'statediagram-v2\n'; + const fauxStateDiagram = new FauxDiagramObj(); + + it('returns a {}', () => { + const result = stateRendererV2.getClasses(diagramText, fauxStateDiagram); + expectTypeOf(result).toBeObject(); + }); + }); +});