mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-11-08 14:54:08 +01:00
Using diagram api to add gitGraph
This commit is contained in:
@@ -64,7 +64,7 @@ journey
|
|||||||
commit
|
commit
|
||||||
commit
|
commit
|
||||||
</div>
|
</div>
|
||||||
<div class="mermaid2" style="width: 50%;">
|
<div class="mermaid" style="width: 50%;">
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
title: My Sequence Diagram Title
|
title: My Sequence Diagram Title
|
||||||
accTitle: My Acc Sequence Diagram
|
accTitle: My Acc Sequence Diagram
|
||||||
@@ -283,6 +283,9 @@ class Class10 {
|
|||||||
class: {
|
class: {
|
||||||
// defaultRenderer: 'dagre-d3',
|
// defaultRenderer: 'dagre-d3',
|
||||||
htmlLabels: true,
|
htmlLabels: true,
|
||||||
|
},
|
||||||
|
sequence: {
|
||||||
|
mirrorActors: false,
|
||||||
},
|
},
|
||||||
// gantt: { axisFormat: '%m/%d/%Y' },
|
// gantt: { axisFormat: '%m/%d/%Y' },
|
||||||
// sequence: {
|
// sequence: {
|
||||||
|
|||||||
@@ -1401,6 +1401,15 @@ This sets the auto-wrap padding for the diagram (sides only)
|
|||||||
|
|
||||||
**Notes:** Default value: 0.
|
**Notes:** Default value: 0.
|
||||||
|
|
||||||
|
## parse
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
|
||||||
|
- `text`
|
||||||
|
- `dia`
|
||||||
|
|
||||||
|
Returns **any**
|
||||||
|
|
||||||
## setSiteConfig
|
## setSiteConfig
|
||||||
|
|
||||||
## setSiteConfig
|
## setSiteConfig
|
||||||
@@ -1420,14 +1429,6 @@ function _Default value: At default, will mirror Global Config_
|
|||||||
|
|
||||||
Returns **[object][5]** The siteConfig
|
Returns **[object][5]** The siteConfig
|
||||||
|
|
||||||
## parse
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
|
|
||||||
- `text`
|
|
||||||
|
|
||||||
Returns **any**
|
|
||||||
|
|
||||||
## getSiteConfig
|
## getSiteConfig
|
||||||
|
|
||||||
## getSiteConfig
|
## getSiteConfig
|
||||||
@@ -1485,30 +1486,6 @@ options in-place
|
|||||||
|
|
||||||
- `options` **any** The potential setConfig parameter
|
- `options` **any** The potential setConfig parameter
|
||||||
|
|
||||||
## addDirective
|
|
||||||
|
|
||||||
Pushes in a directive to the configuration
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
|
|
||||||
- `directive` **[object][5]** The directive to push in
|
|
||||||
|
|
||||||
## reset
|
|
||||||
|
|
||||||
## reset
|
|
||||||
|
|
||||||
| Function | Description | Type | Required | Values |
|
|
||||||
| -------- | ---------------------------- | ----------- | -------- | ------ |
|
|
||||||
| reset | Resets currentConfig to conf | Put Request | Required | None |
|
|
||||||
|
|
||||||
## conf
|
|
||||||
|
|
||||||
| Parameter | Description | Type | Required | Values |
|
|
||||||
| --------- | -------------------------------------------------------------- | ---------- | -------- | -------------------------------------------- |
|
|
||||||
| conf | base set of values, which currentConfig could be **reset** to. | Dictionary | Required | Any Values, with respect to the secure Array |
|
|
||||||
|
|
||||||
**Notes**: (default: current siteConfig ) (optional, default `getSiteConfig()`)
|
|
||||||
|
|
||||||
## render
|
## render
|
||||||
|
|
||||||
Function that renders an svg with a graph from a chart definition. Usage example below.
|
Function that renders an svg with a graph from a chart definition. Usage example below.
|
||||||
@@ -1537,16 +1514,36 @@ $(function () {
|
|||||||
|
|
||||||
Returns **any**
|
Returns **any**
|
||||||
|
|
||||||
|
## addDirective
|
||||||
|
|
||||||
|
Pushes in a directive to the configuration
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
|
||||||
|
- `directive` **[object][5]** The directive to push in
|
||||||
|
|
||||||
|
## reset
|
||||||
|
|
||||||
|
## reset
|
||||||
|
|
||||||
|
| Function | Description | Type | Required | Values |
|
||||||
|
| -------- | ---------------------------- | ----------- | -------- | ------ |
|
||||||
|
| reset | Resets currentConfig to conf | Put Request | Required | None |
|
||||||
|
|
||||||
|
## conf
|
||||||
|
|
||||||
|
| Parameter | Description | Type | Required | Values |
|
||||||
|
| --------- | -------------------------------------------------------------- | ---------- | -------- | -------------------------------------------- |
|
||||||
|
| conf | base set of values, which currentConfig could be **reset** to. | Dictionary | Required | Any Values, with respect to the secure Array |
|
||||||
|
|
||||||
|
**Notes**: (default: current siteConfig ) (optional, default `getSiteConfig()`)
|
||||||
|
|
||||||
## updateRendererConfigs
|
## updateRendererConfigs
|
||||||
|
|
||||||
### Parameters
|
### Parameters
|
||||||
|
|
||||||
- `conf` **any**
|
- `conf` **any**
|
||||||
|
|
||||||
## reinitialize
|
|
||||||
|
|
||||||
To be removed
|
|
||||||
|
|
||||||
## initialize
|
## initialize
|
||||||
|
|
||||||
### Parameters
|
### Parameters
|
||||||
|
|||||||
218
src/Diagram.js
218
src/Diagram.js
@@ -1,191 +1,32 @@
|
|||||||
import c4Db from './diagrams/c4/c4Db';
|
|
||||||
import c4Renderer from './diagrams/c4/c4Renderer';
|
|
||||||
import c4Parser from './diagrams/c4/parser/c4Diagram';
|
|
||||||
import classDb from './diagrams/class/classDb';
|
|
||||||
import classRenderer from './diagrams/class/classRenderer';
|
|
||||||
import classRendererV2 from './diagrams/class/classRenderer-v2';
|
|
||||||
import classParser from './diagrams/class/parser/classDiagram';
|
|
||||||
import erDb from './diagrams/er/erDb';
|
|
||||||
import erRenderer from './diagrams/er/erRenderer';
|
|
||||||
import erParser from './diagrams/er/parser/erDiagram';
|
|
||||||
import flowDb from './diagrams/flowchart/flowDb';
|
|
||||||
import flowRenderer from './diagrams/flowchart/flowRenderer';
|
|
||||||
import flowRendererV2 from './diagrams/flowchart/flowRenderer-v2';
|
|
||||||
import flowParser from './diagrams/flowchart/parser/flow';
|
|
||||||
import ganttDb from './diagrams/gantt/ganttDb';
|
|
||||||
import ganttRenderer from './diagrams/gantt/ganttRenderer';
|
|
||||||
import ganttParser from './diagrams/gantt/parser/gantt';
|
|
||||||
import gitGraphAst from './diagrams/git/gitGraphAst';
|
|
||||||
import gitGraphRenderer from './diagrams/git/gitGraphRenderer';
|
|
||||||
import gitGraphParser from './diagrams/git/parser/gitGraph';
|
|
||||||
import infoDb from './diagrams/info/infoDb';
|
|
||||||
import infoRenderer from './diagrams/info/infoRenderer';
|
|
||||||
import infoParser from './diagrams/info/parser/info';
|
|
||||||
import pieParser from './diagrams/pie/parser/pie';
|
|
||||||
import pieDb from './diagrams/pie/pieDb';
|
|
||||||
import pieRenderer from './diagrams/pie/pieRenderer';
|
|
||||||
import requirementParser from './diagrams/requirement/parser/requirementDiagram';
|
|
||||||
import requirementDb from './diagrams/requirement/requirementDb';
|
|
||||||
import requirementRenderer from './diagrams/requirement/requirementRenderer';
|
|
||||||
import sequenceParser from './diagrams/sequence/parser/sequenceDiagram';
|
|
||||||
import sequenceDb from './diagrams/sequence/sequenceDb';
|
|
||||||
import sequenceRenderer from './diagrams/sequence/sequenceRenderer';
|
|
||||||
import stateParser from './diagrams/state/parser/stateDiagram';
|
|
||||||
import stateDb from './diagrams/state/stateDb';
|
|
||||||
import stateRenderer from './diagrams/state/stateRenderer';
|
|
||||||
import stateRendererV2 from './diagrams/state/stateRenderer-v2';
|
|
||||||
import journeyDb from './diagrams/user-journey/journeyDb';
|
|
||||||
import journeyRenderer from './diagrams/user-journey/journeyRenderer';
|
|
||||||
import journeyParser from './diagrams/user-journey/parser/journey';
|
|
||||||
import utils from './utils';
|
import utils from './utils';
|
||||||
import * as configApi from './config';
|
import * as configApi from './config';
|
||||||
import { log } from './logger';
|
import { log } from './logger';
|
||||||
|
import { getDiagrams } from './diagram-api/diagramAPI';
|
||||||
|
import detectType from './diagram-api/detectType';
|
||||||
class Diagram {
|
class Diagram {
|
||||||
type = 'graph';
|
type = 'graph';
|
||||||
parser;
|
parser;
|
||||||
renderer;
|
renderer;
|
||||||
db;
|
db;
|
||||||
constructor(txt) {
|
constructor(txt) {
|
||||||
|
const diagrams = getDiagrams();
|
||||||
const cnf = configApi.getConfig();
|
const cnf = configApi.getConfig();
|
||||||
this.txt = txt;
|
this.txt = txt;
|
||||||
this.type = utils.detectType(txt, cnf);
|
this.type = detectType(txt, cnf);
|
||||||
log.debug('Type ' + this.type);
|
log.debug('Type ' + this.type);
|
||||||
switch (this.type) {
|
|
||||||
case 'c4':
|
// console.log('this.type', this.type, diagrams[this.type]);
|
||||||
this.parser = c4Parser;
|
// Setup diagram
|
||||||
this.parser.parser.yy = c4Db;
|
this.db = diagrams[this.type].db;
|
||||||
this.db = c4Db;
|
this.renderer = diagrams[this.type].renderer;
|
||||||
this.renderer = c4Renderer;
|
this.parser = diagrams[this.type].parser;
|
||||||
this.renderer.setConf(cnf.c4);
|
this.parser.parser.yy = this.db;
|
||||||
break;
|
if (typeof diagrams[this.type].init === 'function') {
|
||||||
case 'gitGraph':
|
diagrams[this.type].init(cnf);
|
||||||
this.parser = gitGraphParser;
|
log.debug('Initialized diagram ' + this.type, cnf);
|
||||||
this.parser.parser.yy = gitGraphAst;
|
|
||||||
this.db = gitGraphAst;
|
|
||||||
this.renderer = gitGraphRenderer;
|
|
||||||
this.txt = this.txt + '\n';
|
|
||||||
break;
|
|
||||||
case 'flowchart':
|
|
||||||
flowRenderer.setConf(cnf.flowchart);
|
|
||||||
cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
|
||||||
flowDb.clear();
|
|
||||||
flowDb.setGen('gen-1');
|
|
||||||
this.parser = flowParser;
|
|
||||||
this.parser.parser.yy = flowDb;
|
|
||||||
this.db = flowDb;
|
|
||||||
this.renderer = flowRenderer;
|
|
||||||
break;
|
|
||||||
case 'flowchart-v2':
|
|
||||||
flowRendererV2.setConf(cnf.flowchart);
|
|
||||||
cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
|
||||||
flowDb.clear();
|
|
||||||
flowDb.setGen('gen-2');
|
|
||||||
this.parser = flowParser;
|
|
||||||
this.parser.parser.yy = flowDb;
|
|
||||||
this.db = flowDb;
|
|
||||||
this.renderer = flowRendererV2;
|
|
||||||
break;
|
|
||||||
case 'sequenceDiagram':
|
|
||||||
case 'sequence':
|
|
||||||
cnf.sequence.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
|
||||||
if (cnf.sequenceDiagram) {
|
|
||||||
// backwards compatibility
|
|
||||||
sequenceRenderer.setConf(Object.assign(cnf.sequence, cnf.sequenceDiagram));
|
|
||||||
console.error(
|
|
||||||
'`mermaid config.sequenceDiagram` has been renamed to `config.sequence`. Please update your mermaid config.'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
this.parser = sequenceParser;
|
|
||||||
this.parser.parser.yy = sequenceDb;
|
|
||||||
this.db = sequenceDb;
|
|
||||||
this.db.setWrap(cnf.wrap);
|
|
||||||
this.renderer = sequenceRenderer;
|
|
||||||
this.renderer.setConf(cnf.sequence);
|
|
||||||
this.txt = this.txt + '\n';
|
|
||||||
break;
|
|
||||||
case 'gantt':
|
|
||||||
cnf.gantt.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
|
||||||
this.parser = ganttParser;
|
|
||||||
this.parser.parser.yy = ganttDb;
|
|
||||||
this.db = ganttDb;
|
|
||||||
this.renderer = ganttRenderer;
|
|
||||||
ganttRenderer.setConf(cnf.gantt);
|
|
||||||
break;
|
|
||||||
case 'class':
|
|
||||||
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
|
||||||
this.parser = classParser;
|
|
||||||
this.parser.parser.yy = classDb;
|
|
||||||
this.db = classDb;
|
|
||||||
this.db.clear();
|
|
||||||
this.renderer = classRenderer;
|
|
||||||
break;
|
|
||||||
case 'classDiagram':
|
|
||||||
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
|
||||||
this.parser = classParser;
|
|
||||||
this.parser.parser.yy = classDb;
|
|
||||||
this.db = classDb;
|
|
||||||
this.db.clear();
|
|
||||||
this.renderer = classRendererV2;
|
|
||||||
break;
|
|
||||||
case 'state':
|
|
||||||
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
|
||||||
this.parser = stateParser;
|
|
||||||
this.parser.parser.yy = stateDb;
|
|
||||||
this.db = stateDb;
|
|
||||||
this.db.clear();
|
|
||||||
this.renderer = stateRenderer;
|
|
||||||
break;
|
|
||||||
case 'stateDiagram':
|
|
||||||
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
|
||||||
this.parser = stateParser;
|
|
||||||
this.parser.parser.yy = stateDb;
|
|
||||||
this.db = stateDb;
|
|
||||||
this.db.clear();
|
|
||||||
this.renderer = stateRendererV2;
|
|
||||||
break;
|
|
||||||
case 'info':
|
|
||||||
log.debug('info info info');
|
|
||||||
this.parser = infoParser;
|
|
||||||
this.parser.parser.yy = infoDb;
|
|
||||||
this.db = infoDb;
|
|
||||||
this.renderer = infoRenderer;
|
|
||||||
break;
|
|
||||||
case 'pie':
|
|
||||||
log.debug('pie');
|
|
||||||
this.parser = pieParser;
|
|
||||||
this.parser.parser.yy = pieDb;
|
|
||||||
this.db = pieDb;
|
|
||||||
this.renderer = pieRenderer;
|
|
||||||
break;
|
|
||||||
case 'er':
|
|
||||||
log.debug('er');
|
|
||||||
this.parser = erParser;
|
|
||||||
this.parser.parser.yy = erDb;
|
|
||||||
this.db = erDb;
|
|
||||||
this.renderer = erRenderer;
|
|
||||||
break;
|
|
||||||
case 'journey':
|
|
||||||
log.debug('Journey');
|
|
||||||
journeyRenderer.setConf(cnf.journey);
|
|
||||||
this.parser = journeyParser;
|
|
||||||
this.parser.parser.yy = journeyDb;
|
|
||||||
this.db = journeyDb;
|
|
||||||
this.db.clear();
|
|
||||||
this.renderer = journeyRenderer;
|
|
||||||
break;
|
|
||||||
case 'requirement':
|
|
||||||
case 'requirementDiagram':
|
|
||||||
log.debug('RequirementDiagram');
|
|
||||||
this.parser = requirementParser;
|
|
||||||
this.parser.parser.yy = requirementDb;
|
|
||||||
this.db = requirementDb;
|
|
||||||
this.renderer = requirementRenderer;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
log.error('Unkown graphtype');
|
|
||||||
throw new Error('Unkown graphtype');
|
|
||||||
}
|
}
|
||||||
|
this.txt = this.txt + '\n';
|
||||||
|
|
||||||
this.parser.parser.yy.graphType = this.type;
|
this.parser.parser.yy.graphType = this.type;
|
||||||
this.parser.parser.yy.parseError = (str, hash) => {
|
this.parser.parser.yy.parseError = (str, hash) => {
|
||||||
const error = { str, hash };
|
const error = { str, hash };
|
||||||
@@ -193,6 +34,33 @@ class Diagram {
|
|||||||
};
|
};
|
||||||
this.parser.parse(this.txt);
|
this.parser.parse(this.txt);
|
||||||
}
|
}
|
||||||
|
parse(text) {
|
||||||
|
var parseEncounteredException = false;
|
||||||
|
try {
|
||||||
|
text = text + '\n';
|
||||||
|
this.db.clear();
|
||||||
|
|
||||||
|
this.parser.parse(text);
|
||||||
|
} catch (error) {
|
||||||
|
parseEncounteredException = true;
|
||||||
|
// Is this the correct way to access mermiad's parseError()
|
||||||
|
// method ? (or global.mermaid.parseError()) ?
|
||||||
|
if (global.mermaid.parseError) {
|
||||||
|
if (error.str != undefined) {
|
||||||
|
// handle case where error string and hash were
|
||||||
|
// wrapped in object like`const error = { str, hash };`
|
||||||
|
global.mermaid.parseError(error.str, error.hash);
|
||||||
|
} else {
|
||||||
|
// assume it is just error string and pass it on
|
||||||
|
global.mermaid.parseError(error);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// No mermaid.parseError() handler defined, so re-throw it
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return !parseEncounteredException;
|
||||||
|
}
|
||||||
getParser() {
|
getParser() {
|
||||||
return this.parser;
|
return this.parser;
|
||||||
}
|
}
|
||||||
|
|||||||
74
src/assignWithDepth.js
Normal file
74
src/assignWithDepth.js
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
/**
|
||||||
|
* @function assignWithDepth Extends the functionality of {@link ObjectConstructor.assign} with the
|
||||||
|
* ability to merge arbitrary-depth objects For each key in src with path `k` (recursively)
|
||||||
|
* performs an Object.assign(dst[`k`], src[`k`]) with a slight change from the typical handling of
|
||||||
|
* undefined for dst[`k`]: instead of raising an error, dst[`k`] is auto-initialized to {} and
|
||||||
|
* effectively merged with src[`k`]<p> Additionally, dissimilar types will not clobber unless the
|
||||||
|
* config.clobber parameter === true. Example:
|
||||||
|
*
|
||||||
|
* ```js
|
||||||
|
* let config_0 = { foo: { bar: 'bar' }, bar: 'foo' };
|
||||||
|
* let config_1 = { foo: 'foo', bar: 'bar' };
|
||||||
|
* let result = assignWithDepth(config_0, config_1);
|
||||||
|
* console.log(result);
|
||||||
|
* //-> result: { foo: { bar: 'bar' }, bar: 'bar' }
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Traditional Object.assign would have clobbered foo in config_0 with foo in config_1. If src is a
|
||||||
|
* destructured array of objects and dst is not an array, assignWithDepth will apply each element
|
||||||
|
* of src to dst in order.
|
||||||
|
* @param dst
|
||||||
|
* @param src
|
||||||
|
* @param config
|
||||||
|
* @param dst
|
||||||
|
* @param src
|
||||||
|
* @param config
|
||||||
|
* @param dst
|
||||||
|
* @param src
|
||||||
|
* @param config
|
||||||
|
* @param {any} dst - The destination of the merge
|
||||||
|
* @param {any} src - The source object(s) to merge into destination
|
||||||
|
* @param {{ depth: number; clobber: boolean }} [config={ depth: 2, clobber: false }] - Depth: depth
|
||||||
|
* to traverse within src and dst for merging - clobber: should dissimilar types clobber (default:
|
||||||
|
* { depth: 2, clobber: false }). Default is `{ depth: 2, clobber: false }`
|
||||||
|
* @returns {any}
|
||||||
|
*/
|
||||||
|
const assignWithDepth = function (dst, src, config) {
|
||||||
|
const { depth, clobber } = Object.assign({ depth: 2, clobber: false }, config);
|
||||||
|
if (Array.isArray(src) && !Array.isArray(dst)) {
|
||||||
|
src.forEach((s) => assignWithDepth(dst, s, config));
|
||||||
|
return dst;
|
||||||
|
} else if (Array.isArray(src) && Array.isArray(dst)) {
|
||||||
|
src.forEach((s) => {
|
||||||
|
if (dst.indexOf(s) === -1) {
|
||||||
|
dst.push(s);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
if (typeof dst === 'undefined' || depth <= 0) {
|
||||||
|
if (dst !== undefined && dst !== null && typeof dst === 'object' && typeof src === 'object') {
|
||||||
|
return Object.assign(dst, src);
|
||||||
|
} else {
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (typeof src !== 'undefined' && typeof dst === 'object' && typeof src === 'object') {
|
||||||
|
Object.keys(src).forEach((key) => {
|
||||||
|
if (
|
||||||
|
typeof src[key] === 'object' &&
|
||||||
|
(dst[key] === undefined || typeof dst[key] === 'object')
|
||||||
|
) {
|
||||||
|
if (dst[key] === undefined) {
|
||||||
|
dst[key] = Array.isArray(src[key]) ? [] : {};
|
||||||
|
}
|
||||||
|
dst[key] = assignWithDepth(dst[key], src[key], { depth: depth - 1, clobber });
|
||||||
|
} else if (clobber || (typeof dst[key] !== 'object' && typeof src[key] !== 'object')) {
|
||||||
|
dst[key] = src[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return dst;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default assignWithDepth;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { assignWithDepth } from './utils';
|
import assignWithDepth from './assignWithDepth';
|
||||||
import { log } from './logger';
|
import { log } from './logger';
|
||||||
import theme from './themes';
|
import theme from './themes';
|
||||||
import config from './defaultConfig';
|
import config from './defaultConfig';
|
||||||
|
|||||||
100
src/diagram-api/detectType.js
Normal file
100
src/diagram-api/detectType.js
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
const directive =
|
||||||
|
/[%]{2}[{]\s*(?:(?:(\w+)\s*:|(\w+))\s*(?:(?:(\w+))|((?:(?![}][%]{2}).|\r?\n)*))?\s*)(?:[}][%]{2})?/gi;
|
||||||
|
const anyComment = /\s*%%.*\n/gm;
|
||||||
|
const detectors = {};
|
||||||
|
/**
|
||||||
|
* @function detectType Detects the type of the graph text. Takes into consideration the possible
|
||||||
|
* existence of an %%init directive
|
||||||
|
*
|
||||||
|
* ```mermaid
|
||||||
|
* %%{initialize: {"startOnLoad": true, logLevel: "fatal" }}%%
|
||||||
|
* graph LR
|
||||||
|
* a-->b
|
||||||
|
* b-->c
|
||||||
|
* c-->d
|
||||||
|
* d-->e
|
||||||
|
* e-->f
|
||||||
|
* f-->g
|
||||||
|
* g-->h
|
||||||
|
* ```
|
||||||
|
* @param {string} text The text defining the graph
|
||||||
|
* @param {{
|
||||||
|
* class: { defaultRenderer: string } | undefined;
|
||||||
|
* state: { defaultRenderer: string } | undefined;
|
||||||
|
* flowchart: { defaultRenderer: string } | undefined;
|
||||||
|
* }} [cnf]
|
||||||
|
* @returns {string} A graph definition key
|
||||||
|
*/
|
||||||
|
const detectType = function (text, cnf) {
|
||||||
|
text = text.replace(directive, '').replace(anyComment, '\n');
|
||||||
|
if (text.match(/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/)) {
|
||||||
|
return 'c4';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text.match(/^\s*sequenceDiagram/)) {
|
||||||
|
return 'sequence';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text.match(/^\s*gantt/)) {
|
||||||
|
return 'gantt';
|
||||||
|
}
|
||||||
|
if (text.match(/^\s*classDiagram-v2/)) {
|
||||||
|
return 'classDiagram';
|
||||||
|
}
|
||||||
|
if (text.match(/^\s*classDiagram/)) {
|
||||||
|
if (cnf && cnf.class && cnf.class.defaultRenderer === 'dagre-wrapper') return 'classDiagram';
|
||||||
|
return 'class';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text.match(/^\s*stateDiagram-v2/)) {
|
||||||
|
return 'stateDiagram';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text.match(/^\s*stateDiagram/)) {
|
||||||
|
if (cnf && cnf.class && cnf.state.defaultRenderer === 'dagre-wrapper') return 'stateDiagram';
|
||||||
|
return 'state';
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (text.match(/^\s*gitGraph/)) {
|
||||||
|
// return 'gitGraph';
|
||||||
|
// }
|
||||||
|
if (text.match(/^\s*flowchart/)) {
|
||||||
|
return 'flowchart-v2';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text.match(/^\s*info/)) {
|
||||||
|
return 'info';
|
||||||
|
}
|
||||||
|
if (text.match(/^\s*pie/)) {
|
||||||
|
return 'pie';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text.match(/^\s*erDiagram/)) {
|
||||||
|
return 'er';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text.match(/^\s*journey/)) {
|
||||||
|
return 'journey';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text.match(/^\s*requirement/) || text.match(/^\s*requirementDiagram/)) {
|
||||||
|
return 'requirement';
|
||||||
|
}
|
||||||
|
if (cnf && cnf.flowchart && cnf.flowchart.defaultRenderer === 'dagre-wrapper')
|
||||||
|
return 'flowchart-v2';
|
||||||
|
const k = Object.keys(detectors);
|
||||||
|
for (let i = 0; i < k.length; i++) {
|
||||||
|
const key = k[i];
|
||||||
|
const dia = detectors[key];
|
||||||
|
if (dia && dia.detector(text)) {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 'flowchart';
|
||||||
|
};
|
||||||
|
export const addDetector = (key, detector) => {
|
||||||
|
detectors[key] = {
|
||||||
|
detector,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
export default detectType;
|
||||||
31
src/diagram-api/diagram-orchestration.js
Normal file
31
src/diagram-api/diagram-orchestration.js
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { registerDiagram } from './diagramAPI.js';
|
||||||
|
// import mindmapDb from '../diagrams/mindmap/mindmapDb';
|
||||||
|
// import mindmapRenderer from '../diagrams/mindmap/mindmapRenderer';
|
||||||
|
// import mindmapParser from '../diagrams/mindmap/parser/mindmapDiagram';
|
||||||
|
// import mindmapDetector from '../diagrams/mindmap/mindmapDetector';
|
||||||
|
|
||||||
|
import gitGraphDb from '../diagrams/git/gitGraphAst';
|
||||||
|
import gitGraphRenderer from '../diagrams/git/gitGraphRenderer';
|
||||||
|
import gitGraphParser from '../diagrams/git/parser/gitGraph';
|
||||||
|
import gitGraphDetector from '../diagrams/git/gitGraphDetector';
|
||||||
|
|
||||||
|
// Register mindmap and other built-in diagrams
|
||||||
|
// registerDiagram(
|
||||||
|
// 'mindmap',
|
||||||
|
// mindmapParser,
|
||||||
|
// mindmapDb,
|
||||||
|
// mindmapRenderer,
|
||||||
|
// undefined,
|
||||||
|
// mindmapRenderer,
|
||||||
|
// mindmapDetector
|
||||||
|
// );
|
||||||
|
registerDiagram(
|
||||||
|
'gitGraph',
|
||||||
|
gitGraphParser,
|
||||||
|
gitGraphDb,
|
||||||
|
gitGraphRenderer,
|
||||||
|
undefined,
|
||||||
|
gitGraphDetector
|
||||||
|
);
|
||||||
|
const apa = { apa: 1 };
|
||||||
|
export default apa;
|
||||||
@@ -1,9 +1,175 @@
|
|||||||
const diagrams = {};
|
import c4Db from '../diagrams/c4/c4Db';
|
||||||
|
import c4Renderer from '../diagrams/c4/c4Renderer';
|
||||||
|
import c4Parser from '../diagrams/c4/parser/c4Diagram';
|
||||||
|
import classDb from '../diagrams/class/classDb';
|
||||||
|
import classRenderer from '../diagrams/class/classRenderer';
|
||||||
|
import classRendererV2 from '../diagrams/class/classRenderer-v2';
|
||||||
|
import classParser from '../diagrams/class/parser/classDiagram';
|
||||||
|
import erDb from '../diagrams/er/erDb';
|
||||||
|
import erRenderer from '../diagrams/er/erRenderer';
|
||||||
|
import erParser from '../diagrams/er/parser/erDiagram';
|
||||||
|
import flowDb from '../diagrams/flowchart/flowDb';
|
||||||
|
import flowRenderer from '../diagrams/flowchart/flowRenderer';
|
||||||
|
import flowRendererV2 from '../diagrams/flowchart/flowRenderer-v2';
|
||||||
|
import flowParser from '../diagrams/flowchart/parser/flow';
|
||||||
|
import ganttDb from '../diagrams/gantt/ganttDb';
|
||||||
|
import ganttRenderer from '../diagrams/gantt/ganttRenderer';
|
||||||
|
import ganttParser from '../diagrams/gantt/parser/gantt';
|
||||||
|
import infoDb from '../diagrams/info/infoDb';
|
||||||
|
import infoRenderer from '../diagrams/info/infoRenderer';
|
||||||
|
import infoParser from '../diagrams/info/parser/info';
|
||||||
|
import pieParser from '../diagrams/pie/parser/pie';
|
||||||
|
import pieDb from '../diagrams/pie/pieDb';
|
||||||
|
import pieRenderer from '../diagrams/pie/pieRenderer';
|
||||||
|
import requirementParser from '../diagrams/requirement/parser/requirementDiagram';
|
||||||
|
import requirementDb from '../diagrams/requirement/requirementDb';
|
||||||
|
import requirementRenderer from '../diagrams/requirement/requirementRenderer';
|
||||||
|
import sequenceParser from '../diagrams/sequence/parser/sequenceDiagram';
|
||||||
|
import sequenceDb from '../diagrams/sequence/sequenceDb';
|
||||||
|
import sequenceRenderer from '../diagrams/sequence/sequenceRenderer';
|
||||||
|
import stateParser from '../diagrams/state/parser/stateDiagram';
|
||||||
|
import stateDb from '../diagrams/state/stateDb';
|
||||||
|
import stateRenderer from '../diagrams/state/stateRenderer';
|
||||||
|
import stateRendererV2 from '../diagrams/state/stateRenderer-v2';
|
||||||
|
import journeyDb from '../diagrams/user-journey/journeyDb';
|
||||||
|
import journeyRenderer from '../diagrams/user-journey/journeyRenderer';
|
||||||
|
import journeyParser from '../diagrams/user-journey/parser/journey';
|
||||||
|
import { addDetector } from './detectType';
|
||||||
|
|
||||||
export const registerDiagram = (id, parser, identifier, renderer) => {
|
const diagrams = {
|
||||||
diagrams[id] = { parser, identifier, renderer };
|
c4: {
|
||||||
|
db: c4Db,
|
||||||
|
renderer: c4Renderer,
|
||||||
|
parser: c4Parser,
|
||||||
|
init: (cnf) => {
|
||||||
|
c4Renderer.setConf(cnf.c4);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
class: {
|
||||||
|
db: classDb,
|
||||||
|
renderer: classRenderer,
|
||||||
|
parser: classParser,
|
||||||
|
init: (cnf) => {
|
||||||
|
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||||
|
classDb.clear();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
classDiagram: {
|
||||||
|
db: classDb,
|
||||||
|
renderer: classRendererV2,
|
||||||
|
parser: classParser,
|
||||||
|
init: (cnf) => {
|
||||||
|
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||||
|
classDb.clear();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
er: {
|
||||||
|
db: erDb,
|
||||||
|
renderer: erRenderer,
|
||||||
|
parser: erParser,
|
||||||
|
},
|
||||||
|
flowchart: {
|
||||||
|
db: flowDb,
|
||||||
|
renderer: flowRenderer,
|
||||||
|
parser: flowParser,
|
||||||
|
init: (cnf) => {
|
||||||
|
flowRenderer.setConf(cnf.flowchart);
|
||||||
|
cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||||
|
flowDb.clear();
|
||||||
|
flowDb.setGen('gen-1');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
flowchartV2: {
|
||||||
|
db: flowDb,
|
||||||
|
renderer: flowRendererV2,
|
||||||
|
parser: flowParser,
|
||||||
|
init: (cnf) => {
|
||||||
|
flowRendererV2.setConf(cnf.flowchart);
|
||||||
|
cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||||
|
flowDb.clear();
|
||||||
|
flowDb.setGen('gen-2');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
gantt: {
|
||||||
|
db: ganttDb,
|
||||||
|
renderer: ganttRenderer,
|
||||||
|
parser: ganttParser,
|
||||||
|
init: (cnf) => {
|
||||||
|
ganttRenderer.setConf(cnf.gantt);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// git: {
|
||||||
|
// db: gitGraphAst,
|
||||||
|
// renderer: gitGraphRenderer,
|
||||||
|
// parser: gitGraphParser,
|
||||||
|
// },
|
||||||
|
info: {
|
||||||
|
db: infoDb,
|
||||||
|
renderer: infoRenderer,
|
||||||
|
parser: infoParser,
|
||||||
|
},
|
||||||
|
pie: {
|
||||||
|
db: pieDb,
|
||||||
|
renderer: pieRenderer,
|
||||||
|
parser: pieParser,
|
||||||
|
},
|
||||||
|
requirement: {
|
||||||
|
db: requirementDb,
|
||||||
|
renderer: requirementRenderer,
|
||||||
|
parser: requirementParser,
|
||||||
|
},
|
||||||
|
sequence: {
|
||||||
|
db: sequenceDb,
|
||||||
|
renderer: sequenceRenderer,
|
||||||
|
parser: sequenceParser,
|
||||||
|
init: (cnf) => {
|
||||||
|
cnf.sequence.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||||
|
if (cnf.sequenceDiagram) {
|
||||||
|
// backwards compatibility
|
||||||
|
sequenceRenderer.setConf(Object.assign(cnf.sequence, cnf.sequenceDiagram));
|
||||||
|
console.error(
|
||||||
|
'`mermaid config.sequenceDiagram` has been renamed to `config.sequence`. Please update your mermaid config.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
sequenceDb.setWrap(cnf.wrap);
|
||||||
|
sequenceRenderer.setConf(cnf.sequence);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
state: {
|
||||||
|
db: stateDb,
|
||||||
|
renderer: stateRenderer,
|
||||||
|
parser: stateParser,
|
||||||
|
init: (cnf) => {
|
||||||
|
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||||
|
stateDb.clear();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
stateDiagram: {
|
||||||
|
db: stateDb,
|
||||||
|
renderer: stateRendererV2,
|
||||||
|
parser: stateParser,
|
||||||
|
init: (cnf) => {
|
||||||
|
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||||
|
stateDb.clear();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
journey: {
|
||||||
|
db: journeyDb,
|
||||||
|
renderer: journeyRenderer,
|
||||||
|
parser: journeyParser,
|
||||||
|
init: (cnf) => {
|
||||||
|
journeyRenderer.setConf(cnf.journey);
|
||||||
|
journeyDb.clear();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
// console.log(sequenceDb);
|
||||||
|
export const registerDiagram = (id, parser, db, renderer, init, detector) => {
|
||||||
|
diagrams[id] = { parser, db, renderer, init };
|
||||||
|
addDetector(id, detector);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getDiagrams = () => {
|
export const getDiagrams = () => {
|
||||||
|
// console.log('diagrams', diagrams);
|
||||||
return diagrams;
|
return diagrams;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,13 +5,8 @@ import { parser } from './parser/c4Diagram';
|
|||||||
import common from '../common/common';
|
import common from '../common/common';
|
||||||
import c4Db from './c4Db';
|
import c4Db from './c4Db';
|
||||||
import * as configApi from '../../config';
|
import * as configApi from '../../config';
|
||||||
import utils, {
|
import assignWithDepth from '../../assignWithDepth';
|
||||||
wrapLabel,
|
import { wrapLabel, calculateTextWidth, calculateTextHeight, configureSvgSize } from '../../utils';
|
||||||
calculateTextWidth,
|
|
||||||
calculateTextHeight,
|
|
||||||
assignWithDepth,
|
|
||||||
configureSvgSize,
|
|
||||||
} from '../../utils';
|
|
||||||
import addSVGAccessibilityFields from '../../accessibility';
|
import addSVGAccessibilityFields from '../../accessibility';
|
||||||
|
|
||||||
let globalBoundaryMaxX = 0,
|
let globalBoundaryMaxX = 0,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { addVertices, addEdges } from './flowRenderer';
|
import { addVertices, addEdges } from './flowRenderer';
|
||||||
import { setConfig } from '../../config';
|
import { setConfig } from '../../config';
|
||||||
import Diagram from '../../Diagram';
|
|
||||||
|
|
||||||
setConfig({
|
setConfig({
|
||||||
flowchart: {
|
flowchart: {
|
||||||
|
|||||||
8
src/diagrams/git/gitGraphDetector.js
Normal file
8
src/diagrams/git/gitGraphDetector.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
const detector = (txt) => {
|
||||||
|
if (txt.match(/^\s*gitGraph/)) {
|
||||||
|
return 'gitGraph';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default detector;
|
||||||
14
src/diagrams/mindmap/info.spc.js
Normal file
14
src/diagrams/mindmap/info.spc.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
describe('when parsing an info graph it', function () {
|
||||||
|
var ex;
|
||||||
|
beforeEach(function () {
|
||||||
|
ex = require('./parser/info').parser;
|
||||||
|
ex.yy = require('./infoDb');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle an info definition', function () {
|
||||||
|
var str = `info
|
||||||
|
showInfo`;
|
||||||
|
|
||||||
|
ex.parse(str);
|
||||||
|
});
|
||||||
|
});
|
||||||
34
src/diagrams/mindmap/infoDb.js
Normal file
34
src/diagrams/mindmap/infoDb.js
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/** Created by knut on 15-01-14. */
|
||||||
|
import { log } from '../../logger';
|
||||||
|
|
||||||
|
var message = '';
|
||||||
|
var info = false;
|
||||||
|
|
||||||
|
export const setMessage = (txt) => {
|
||||||
|
log.debug('Setting message to: ' + txt);
|
||||||
|
message = txt;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getMessage = () => {
|
||||||
|
return message;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const setInfo = (inf) => {
|
||||||
|
info = inf;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getInfo = () => {
|
||||||
|
return info;
|
||||||
|
};
|
||||||
|
|
||||||
|
// export const parseError = (err, hash) => {
|
||||||
|
// global.mermaidAPI.parseError(err, hash)
|
||||||
|
// }
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setMessage,
|
||||||
|
getMessage,
|
||||||
|
setInfo,
|
||||||
|
getInfo,
|
||||||
|
// parseError
|
||||||
|
};
|
||||||
59
src/diagrams/mindmap/infoRenderer.js
Normal file
59
src/diagrams/mindmap/infoRenderer.js
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/** Created by knut on 14-12-11. */
|
||||||
|
import { select } from 'd3';
|
||||||
|
import { log } from '../../logger';
|
||||||
|
import { getConfig } from '../../config';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws a an info picture in the tag with id: id based on the graph definition in text.
|
||||||
|
*
|
||||||
|
* @param {any} text
|
||||||
|
* @param {any} id
|
||||||
|
* @param {any} version
|
||||||
|
* @param diagObj
|
||||||
|
*/
|
||||||
|
export const draw = (text, id, version, diagObj) => {
|
||||||
|
try {
|
||||||
|
// const parser = infoParser.parser;
|
||||||
|
// parser.yy = db;
|
||||||
|
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');
|
||||||
|
const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0].contentDocument : document;
|
||||||
|
|
||||||
|
// Parse the graph definition
|
||||||
|
// parser.parse(text);
|
||||||
|
// log.debug('Parsed info diagram');
|
||||||
|
// Fetch the default direction, use TD if none was found
|
||||||
|
const svg = root.select('#' + id);
|
||||||
|
|
||||||
|
const g = svg.append('g');
|
||||||
|
|
||||||
|
g.append('text') // text label for the x axis
|
||||||
|
.attr('x', 100)
|
||||||
|
.attr('y', 40)
|
||||||
|
.attr('class', 'version')
|
||||||
|
.attr('font-size', '32px')
|
||||||
|
.style('text-anchor', 'middle')
|
||||||
|
.text('v ' + version);
|
||||||
|
|
||||||
|
svg.attr('height', 100);
|
||||||
|
svg.attr('width', 400);
|
||||||
|
// svg.attr('viewBox', '0 0 300 150');
|
||||||
|
} catch (e) {
|
||||||
|
log.error('Error while rendering info diagram');
|
||||||
|
log.error(e.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
draw,
|
||||||
|
};
|
||||||
8
src/diagrams/mindmap/mindamapDetector.js
Normal file
8
src/diagrams/mindmap/mindamapDetector.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
const detector = (txt) => {
|
||||||
|
if (txt.match(/^\s*mindmap/)) {
|
||||||
|
return 'mindmap';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default detector;
|
||||||
48
src/diagrams/mindmap/parser/mindamap.jison
Normal file
48
src/diagrams/mindmap/parser/mindamap.jison
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/** mermaid
|
||||||
|
* https://knsv.github.io/mermaid
|
||||||
|
* (c) 2015 Knut Sveidqvist
|
||||||
|
* MIT license.
|
||||||
|
*/
|
||||||
|
%lex
|
||||||
|
|
||||||
|
%options case-insensitive
|
||||||
|
|
||||||
|
%{
|
||||||
|
// Pre-lexer code can go here
|
||||||
|
%}
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
"info" return 'info' ;
|
||||||
|
[\s\n\r]+ return 'NL' ;
|
||||||
|
[\s]+ return 'space';
|
||||||
|
"showInfo" return 'showInfo';
|
||||||
|
<<EOF>> return 'EOF' ;
|
||||||
|
. return 'TXT' ;
|
||||||
|
|
||||||
|
/lex
|
||||||
|
|
||||||
|
%start start
|
||||||
|
|
||||||
|
%% /* language grammar */
|
||||||
|
|
||||||
|
start
|
||||||
|
// %{ : info document 'EOF' { return yy; } }
|
||||||
|
: info document 'EOF' { return yy; }
|
||||||
|
;
|
||||||
|
|
||||||
|
document
|
||||||
|
: /* empty */
|
||||||
|
| document line
|
||||||
|
;
|
||||||
|
|
||||||
|
line
|
||||||
|
: statement { }
|
||||||
|
| 'NL'
|
||||||
|
;
|
||||||
|
|
||||||
|
statement
|
||||||
|
: showInfo { yy.setInfo(true); }
|
||||||
|
;
|
||||||
|
|
||||||
|
%%
|
||||||
3
src/diagrams/mindmap/styles.js
Normal file
3
src/diagrams/mindmap/styles.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
const getStyles = () => ``;
|
||||||
|
|
||||||
|
export default getStyles;
|
||||||
@@ -140,7 +140,14 @@ export const setWrap = function (wrapSetting) {
|
|||||||
wrapEnabled = wrapSetting;
|
wrapEnabled = wrapSetting;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const autoWrap = () => wrapEnabled;
|
export const autoWrap = () => {
|
||||||
|
// if setWrap has been called, use that value, otherwise use the value from the config
|
||||||
|
// TODO: refactor, always use the config value let setWrap update the config value
|
||||||
|
if (typeof wrapEnabled !== 'undefined') {
|
||||||
|
return wrapEnabled;
|
||||||
|
}
|
||||||
|
return configApi.getConfig().sequence.wrap;
|
||||||
|
};
|
||||||
|
|
||||||
export const clear = function () {
|
export const clear = function () {
|
||||||
actors = {};
|
actors = {};
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,8 @@ import { log } from '../../logger';
|
|||||||
import common from '../common/common';
|
import common from '../common/common';
|
||||||
// import sequenceDb from './sequenceDb';
|
// import sequenceDb from './sequenceDb';
|
||||||
import * as configApi from '../../config';
|
import * as configApi from '../../config';
|
||||||
import utils, { assignWithDepth, configureSvgSize } from '../../utils';
|
import assignWithDepth from '../../assignWithDepth';
|
||||||
|
import utils, { configureSvgSize } from '../../utils';
|
||||||
import addSVGAccessibilityFields from '../../accessibility';
|
import addSVGAccessibilityFields from '../../accessibility';
|
||||||
|
|
||||||
let conf = {};
|
let conf = {};
|
||||||
|
|||||||
@@ -69,7 +69,6 @@ export const draw = function (text, id, version, diagObj) {
|
|||||||
svgDraw.initGraphics(diagram);
|
svgDraw.initGraphics(diagram);
|
||||||
|
|
||||||
const tasks = diagObj.db.getTasks();
|
const tasks = diagObj.db.getTasks();
|
||||||
console.log('text and tasks', text, tasks);
|
|
||||||
const title = diagObj.db.getDiagramTitle();
|
const title = diagObj.db.getDiagramTitle();
|
||||||
|
|
||||||
const actorNames = diagObj.db.getActors();
|
const actorNames = diagObj.db.getActors();
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ const setParseErrorHandler = function (newParseErrorHandler) {
|
|||||||
const mermaid = {
|
const mermaid = {
|
||||||
startOnLoad: true,
|
startOnLoad: true,
|
||||||
htmlLabels: true,
|
htmlLabels: true,
|
||||||
|
diagrams: {},
|
||||||
mermaidAPI,
|
mermaidAPI,
|
||||||
parse: mermaidAPI != undefined ? mermaidAPI.parse : null,
|
parse: mermaidAPI != undefined ? mermaidAPI.parse : null,
|
||||||
render: mermaidAPI != undefined ? mermaidAPI.render : null,
|
render: mermaidAPI != undefined ? mermaidAPI.render : null,
|
||||||
|
|||||||
@@ -19,56 +19,27 @@ import { select } from 'd3';
|
|||||||
import { compile, serialize, stringify } from 'stylis';
|
import { compile, serialize, stringify } from 'stylis';
|
||||||
import pkg from '../package.json';
|
import pkg from '../package.json';
|
||||||
import * as configApi from './config';
|
import * as configApi from './config';
|
||||||
import c4Db from './diagrams/c4/c4Db';
|
import apa from './diagram-api/diagram-orchestration';
|
||||||
import c4Renderer from './diagrams/c4/c4Renderer';
|
|
||||||
import c4Parser from './diagrams/c4/parser/c4Diagram';
|
|
||||||
import classDb from './diagrams/class/classDb';
|
import classDb from './diagrams/class/classDb';
|
||||||
import classRenderer from './diagrams/class/classRenderer';
|
|
||||||
import classRendererV2 from './diagrams/class/classRenderer-v2';
|
|
||||||
import classParser from './diagrams/class/parser/classDiagram';
|
|
||||||
import erDb from './diagrams/er/erDb';
|
|
||||||
import erRenderer from './diagrams/er/erRenderer';
|
|
||||||
import erParser from './diagrams/er/parser/erDiagram';
|
|
||||||
import flowDb from './diagrams/flowchart/flowDb';
|
import flowDb from './diagrams/flowchart/flowDb';
|
||||||
import flowRenderer from './diagrams/flowchart/flowRenderer';
|
import flowRenderer from './diagrams/flowchart/flowRenderer';
|
||||||
import flowRendererV2 from './diagrams/flowchart/flowRenderer-v2';
|
import flowRendererV2 from './diagrams/flowchart/flowRenderer-v2';
|
||||||
import flowParser from './diagrams/flowchart/parser/flow';
|
|
||||||
import ganttDb from './diagrams/gantt/ganttDb';
|
import ganttDb from './diagrams/gantt/ganttDb';
|
||||||
import ganttRenderer from './diagrams/gantt/ganttRenderer';
|
import ganttRenderer from './diagrams/gantt/ganttRenderer';
|
||||||
import ganttParser from './diagrams/gantt/parser/gantt';
|
|
||||||
import gitGraphAst from './diagrams/git/gitGraphAst';
|
|
||||||
import gitGraphRenderer from './diagrams/git/gitGraphRenderer';
|
|
||||||
import gitGraphParser from './diagrams/git/parser/gitGraph';
|
|
||||||
import infoDb from './diagrams/info/infoDb';
|
|
||||||
import infoRenderer from './diagrams/info/infoRenderer';
|
|
||||||
import infoParser from './diagrams/info/parser/info';
|
|
||||||
import pieParser from './diagrams/pie/parser/pie';
|
|
||||||
import pieDb from './diagrams/pie/pieDb';
|
|
||||||
import pieRenderer from './diagrams/pie/pieRenderer';
|
|
||||||
import addSVGAccessibilityFields from './diagrams/pie/pieRenderer';
|
|
||||||
import requirementParser from './diagrams/requirement/parser/requirementDiagram';
|
|
||||||
import requirementDb from './diagrams/requirement/requirementDb';
|
|
||||||
import requirementRenderer from './diagrams/requirement/requirementRenderer';
|
|
||||||
import sequenceParser from './diagrams/sequence/parser/sequenceDiagram';
|
|
||||||
import sequenceDb from './diagrams/sequence/sequenceDb';
|
|
||||||
import sequenceRenderer from './diagrams/sequence/sequenceRenderer';
|
import sequenceRenderer from './diagrams/sequence/sequenceRenderer';
|
||||||
import stateParser from './diagrams/state/parser/stateDiagram';
|
|
||||||
import stateDb from './diagrams/state/stateDb';
|
|
||||||
import stateRenderer from './diagrams/state/stateRenderer';
|
import stateRenderer from './diagrams/state/stateRenderer';
|
||||||
import stateRendererV2 from './diagrams/state/stateRenderer-v2';
|
import stateRendererV2 from './diagrams/state/stateRenderer-v2';
|
||||||
import journeyDb from './diagrams/user-journey/journeyDb';
|
|
||||||
import journeyRenderer from './diagrams/user-journey/journeyRenderer';
|
import journeyRenderer from './diagrams/user-journey/journeyRenderer';
|
||||||
import journeyParser from './diagrams/user-journey/parser/journey';
|
|
||||||
import Diagram from './Diagram';
|
import Diagram from './Diagram';
|
||||||
import errorRenderer from './errorRenderer';
|
import errorRenderer from './errorRenderer';
|
||||||
import { attachFunctions } from './interactionDb';
|
import { attachFunctions } from './interactionDb';
|
||||||
import { log, setLogLevel } from './logger';
|
import { log, setLogLevel } from './logger';
|
||||||
import getStyles from './styles';
|
import getStyles from './styles';
|
||||||
import theme from './themes';
|
import theme from './themes';
|
||||||
import utils, { directiveSanitizer, assignWithDepth, sanitizeCss } from './utils';
|
import utils, { directiveSanitizer } from './utils';
|
||||||
|
import assignWithDepth from './assignWithDepth';
|
||||||
import DOMPurify from 'dompurify';
|
import DOMPurify from 'dompurify';
|
||||||
import mermaid from './mermaid';
|
import mermaid from './mermaid';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param text
|
* @param text
|
||||||
* @param dia
|
* @param dia
|
||||||
@@ -77,20 +48,9 @@ import mermaid from './mermaid';
|
|||||||
function parse(text, dia) {
|
function parse(text, dia) {
|
||||||
var parseEncounteredException = false;
|
var parseEncounteredException = false;
|
||||||
try {
|
try {
|
||||||
text = text + '\n';
|
|
||||||
const diag = dia ? dia : new Diagram(text);
|
const diag = dia ? dia : new Diagram(text);
|
||||||
diag.db.clear();
|
diag.db.clear();
|
||||||
const cnf = configApi.getConfig();
|
return diag.parse(text);
|
||||||
let parser = diag.parser;
|
|
||||||
|
|
||||||
log.debug('Type ' + diag.type);
|
|
||||||
parser.parser.yy.graphType = diag.type;
|
|
||||||
parser.parser.yy.parseError = (str, hash) => {
|
|
||||||
const error = { str, hash };
|
|
||||||
throw error;
|
|
||||||
};
|
|
||||||
|
|
||||||
parser.parse(text);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
parseEncounteredException = true;
|
parseEncounteredException = true;
|
||||||
// Is this the correct way to access mermiad's parseError()
|
// Is this the correct way to access mermiad's parseError()
|
||||||
@@ -290,6 +250,7 @@ const render = function (id, _txt, cb, container) {
|
|||||||
|
|
||||||
txt = encodeEntities(txt);
|
txt = encodeEntities(txt);
|
||||||
|
|
||||||
|
// Imortant that we do not create the diagram until after the directives have been included
|
||||||
const diag = new Diagram(txt);
|
const diag = new Diagram(txt);
|
||||||
// Get the tmp element containing the the svg
|
// Get the tmp element containing the the svg
|
||||||
const element = root.select('#d' + id).node();
|
const element = root.select('#d' + id).node();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import mermaid from './mermaid';
|
import mermaid from './mermaid';
|
||||||
import mermaidAPI from './mermaidAPI';
|
import mermaidAPI from './mermaidAPI';
|
||||||
import { assignWithDepth } from './utils';
|
import assignWithDepth from './assignWithDepth';
|
||||||
|
|
||||||
describe('when using mermaidAPI and ', function () {
|
describe('when using mermaidAPI and ', function () {
|
||||||
describe('doing initialize ', function () {
|
describe('doing initialize ', function () {
|
||||||
|
|||||||
160
src/utils.js
160
src/utils.js
@@ -16,6 +16,8 @@ import {
|
|||||||
import common from './diagrams/common/common';
|
import common from './diagrams/common/common';
|
||||||
import { configKeys } from './defaultConfig';
|
import { configKeys } from './defaultConfig';
|
||||||
import { log } from './logger';
|
import { log } from './logger';
|
||||||
|
import detectType from './diagram-api/detectType';
|
||||||
|
import assignWithDepth from './assignWithDepth';
|
||||||
|
|
||||||
// Effectively an enum of the supported curve types, accessible by name
|
// Effectively an enum of the supported curve types, accessible by name
|
||||||
const d3CurveTypes = {
|
const d3CurveTypes = {
|
||||||
@@ -160,90 +162,6 @@ export const detectDirective = function (text, type = null) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @function detectType Detects the type of the graph text. Takes into consideration the possible
|
|
||||||
* existence of an %%init directive
|
|
||||||
*
|
|
||||||
* ```mermaid
|
|
||||||
* %%{initialize: {"startOnLoad": true, logLevel: "fatal" }}%%
|
|
||||||
* graph LR
|
|
||||||
* a-->b
|
|
||||||
* b-->c
|
|
||||||
* c-->d
|
|
||||||
* d-->e
|
|
||||||
* e-->f
|
|
||||||
* f-->g
|
|
||||||
* g-->h
|
|
||||||
* ```
|
|
||||||
* @param {string} text The text defining the graph
|
|
||||||
* @param {{
|
|
||||||
* class: { defaultRenderer: string } | undefined;
|
|
||||||
* state: { defaultRenderer: string } | undefined;
|
|
||||||
* flowchart: { defaultRenderer: string } | undefined;
|
|
||||||
* }} [cnf]
|
|
||||||
* @returns {string} A graph definition key
|
|
||||||
*/
|
|
||||||
export const detectType = function (text, cnf) {
|
|
||||||
text = text.replace(directive, '').replace(anyComment, '\n');
|
|
||||||
if (text.match(/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/)) {
|
|
||||||
return 'c4';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (text.match(/^\s*sequenceDiagram/)) {
|
|
||||||
return 'sequence';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (text.match(/^\s*gantt/)) {
|
|
||||||
return 'gantt';
|
|
||||||
}
|
|
||||||
if (text.match(/^\s*classDiagram-v2/)) {
|
|
||||||
return 'classDiagram';
|
|
||||||
}
|
|
||||||
if (text.match(/^\s*classDiagram/)) {
|
|
||||||
if (cnf && cnf.class && cnf.class.defaultRenderer === 'dagre-wrapper') return 'classDiagram';
|
|
||||||
return 'class';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (text.match(/^\s*stateDiagram-v2/)) {
|
|
||||||
return 'stateDiagram';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (text.match(/^\s*stateDiagram/)) {
|
|
||||||
if (cnf && cnf.class && cnf.state.defaultRenderer === 'dagre-wrapper') return 'stateDiagram';
|
|
||||||
return 'state';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (text.match(/^\s*gitGraph/)) {
|
|
||||||
return 'gitGraph';
|
|
||||||
}
|
|
||||||
if (text.match(/^\s*flowchart/)) {
|
|
||||||
return 'flowchart-v2';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (text.match(/^\s*info/)) {
|
|
||||||
return 'info';
|
|
||||||
}
|
|
||||||
if (text.match(/^\s*pie/)) {
|
|
||||||
return 'pie';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (text.match(/^\s*erDiagram/)) {
|
|
||||||
return 'er';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (text.match(/^\s*journey/)) {
|
|
||||||
return 'journey';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (text.match(/^\s*requirement/) || text.match(/^\s*requirementDiagram/)) {
|
|
||||||
return 'requirement';
|
|
||||||
}
|
|
||||||
if (cnf && cnf.flowchart && cnf.flowchart.defaultRenderer === 'dagre-wrapper')
|
|
||||||
return 'flowchart-v2';
|
|
||||||
|
|
||||||
return 'flowchart';
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Caches results of functions based on input
|
* Caches results of functions based on input
|
||||||
*
|
*
|
||||||
@@ -578,79 +496,6 @@ export const random = (options) => {
|
|||||||
return makeid(options.length);
|
return makeid(options.length);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @function assignWithDepth Extends the functionality of {@link ObjectConstructor.assign} with the
|
|
||||||
* ability to merge arbitrary-depth objects For each key in src with path `k` (recursively)
|
|
||||||
* performs an Object.assign(dst[`k`], src[`k`]) with a slight change from the typical handling of
|
|
||||||
* undefined for dst[`k`]: instead of raising an error, dst[`k`] is auto-initialized to {} and
|
|
||||||
* effectively merged with src[`k`]<p> Additionally, dissimilar types will not clobber unless the
|
|
||||||
* config.clobber parameter === true. Example:
|
|
||||||
*
|
|
||||||
* ```js
|
|
||||||
* let config_0 = { foo: { bar: 'bar' }, bar: 'foo' };
|
|
||||||
* let config_1 = { foo: 'foo', bar: 'bar' };
|
|
||||||
* let result = assignWithDepth(config_0, config_1);
|
|
||||||
* console.log(result);
|
|
||||||
* //-> result: { foo: { bar: 'bar' }, bar: 'bar' }
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* Traditional Object.assign would have clobbered foo in config_0 with foo in config_1. If src is a
|
|
||||||
* destructured array of objects and dst is not an array, assignWithDepth will apply each element
|
|
||||||
* of src to dst in order.
|
|
||||||
* @param dst
|
|
||||||
* @param src
|
|
||||||
* @param config
|
|
||||||
* @param dst
|
|
||||||
* @param src
|
|
||||||
* @param config
|
|
||||||
* @param dst
|
|
||||||
* @param src
|
|
||||||
* @param config
|
|
||||||
* @param {any} dst - The destination of the merge
|
|
||||||
* @param {any} src - The source object(s) to merge into destination
|
|
||||||
* @param {{ depth: number; clobber: boolean }} [config={ depth: 2, clobber: false }] - Depth: depth
|
|
||||||
* to traverse within src and dst for merging - clobber: should dissimilar types clobber (default:
|
|
||||||
* { depth: 2, clobber: false }). Default is `{ depth: 2, clobber: false }`
|
|
||||||
* @returns {any}
|
|
||||||
*/
|
|
||||||
export const assignWithDepth = function (dst, src, config) {
|
|
||||||
const { depth, clobber } = Object.assign({ depth: 2, clobber: false }, config);
|
|
||||||
if (Array.isArray(src) && !Array.isArray(dst)) {
|
|
||||||
src.forEach((s) => assignWithDepth(dst, s, config));
|
|
||||||
return dst;
|
|
||||||
} else if (Array.isArray(src) && Array.isArray(dst)) {
|
|
||||||
src.forEach((s) => {
|
|
||||||
if (dst.indexOf(s) === -1) {
|
|
||||||
dst.push(s);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return dst;
|
|
||||||
}
|
|
||||||
if (typeof dst === 'undefined' || depth <= 0) {
|
|
||||||
if (dst !== undefined && dst !== null && typeof dst === 'object' && typeof src === 'object') {
|
|
||||||
return Object.assign(dst, src);
|
|
||||||
} else {
|
|
||||||
return src;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (typeof src !== 'undefined' && typeof dst === 'object' && typeof src === 'object') {
|
|
||||||
Object.keys(src).forEach((key) => {
|
|
||||||
if (
|
|
||||||
typeof src[key] === 'object' &&
|
|
||||||
(dst[key] === undefined || typeof dst[key] === 'object')
|
|
||||||
) {
|
|
||||||
if (dst[key] === undefined) {
|
|
||||||
dst[key] = Array.isArray(src[key]) ? [] : {};
|
|
||||||
}
|
|
||||||
dst[key] = assignWithDepth(dst[key], src[key], { depth: depth - 1, clobber });
|
|
||||||
} else if (clobber || (typeof dst[key] !== 'object' && typeof src[key] !== 'object')) {
|
|
||||||
dst[key] = src[key];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return dst;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getTextObj = function () {
|
export const getTextObj = function () {
|
||||||
return {
|
return {
|
||||||
x: 0,
|
x: 0,
|
||||||
@@ -1096,7 +941,6 @@ export default {
|
|||||||
setupGraphViewbox,
|
setupGraphViewbox,
|
||||||
detectInit,
|
detectInit,
|
||||||
detectDirective,
|
detectDirective,
|
||||||
detectType,
|
|
||||||
isSubstringInArray,
|
isSubstringInArray,
|
||||||
interpolateToCurve,
|
interpolateToCurve,
|
||||||
calcLabelPosition,
|
calcLabelPosition,
|
||||||
|
|||||||
@@ -1,52 +1,55 @@
|
|||||||
import utils from './utils';
|
import utils from './utils';
|
||||||
|
import assignWithDepth from './assignWithDepth';
|
||||||
|
import detectType from './diagram-api/detectType';
|
||||||
|
import './diagram-api/diagram-orchestration';
|
||||||
|
|
||||||
describe('when assignWithDepth: should merge objects within objects', function () {
|
describe('when assignWithDepth: should merge objects within objects', function () {
|
||||||
it('should handle simple, depth:1 types (identity)', function () {
|
it('should handle simple, depth:1 types (identity)', function () {
|
||||||
let config_0 = { foo: 'bar', bar: 0 };
|
let config_0 = { foo: 'bar', bar: 0 };
|
||||||
let config_1 = { foo: 'bar', bar: 0 };
|
let config_1 = { foo: 'bar', bar: 0 };
|
||||||
let result = utils.assignWithDepth(config_0, config_1);
|
let result = assignWithDepth(config_0, config_1);
|
||||||
expect(result).toEqual(config_1);
|
expect(result).toEqual(config_1);
|
||||||
});
|
});
|
||||||
it('should handle simple, depth:1 types (dst: undefined)', function () {
|
it('should handle simple, depth:1 types (dst: undefined)', function () {
|
||||||
let config_0 = undefined;
|
let config_0 = undefined;
|
||||||
let config_1 = { foo: 'bar', bar: 0 };
|
let config_1 = { foo: 'bar', bar: 0 };
|
||||||
let result = utils.assignWithDepth(config_0, config_1);
|
let result = assignWithDepth(config_0, config_1);
|
||||||
expect(result).toEqual(config_1);
|
expect(result).toEqual(config_1);
|
||||||
});
|
});
|
||||||
it('should handle simple, depth:1 types (src: undefined)', function () {
|
it('should handle simple, depth:1 types (src: undefined)', function () {
|
||||||
let config_0 = { foo: 'bar', bar: 0 };
|
let config_0 = { foo: 'bar', bar: 0 };
|
||||||
let config_1 = undefined;
|
let config_1 = undefined;
|
||||||
let result = utils.assignWithDepth(config_0, config_1);
|
let result = assignWithDepth(config_0, config_1);
|
||||||
expect(result).toEqual(config_0);
|
expect(result).toEqual(config_0);
|
||||||
});
|
});
|
||||||
it('should handle simple, depth:1 types (merge)', function () {
|
it('should handle simple, depth:1 types (merge)', function () {
|
||||||
let config_0 = { foo: 'bar', bar: 0 };
|
let config_0 = { foo: 'bar', bar: 0 };
|
||||||
let config_1 = { foo: 'foo' };
|
let config_1 = { foo: 'foo' };
|
||||||
let result = utils.assignWithDepth(config_0, config_1);
|
let result = assignWithDepth(config_0, config_1);
|
||||||
expect(result).toEqual({ foo: 'foo', bar: 0 });
|
expect(result).toEqual({ foo: 'foo', bar: 0 });
|
||||||
});
|
});
|
||||||
it('should handle depth:2 types (dst: orphan)', function () {
|
it('should handle depth:2 types (dst: orphan)', function () {
|
||||||
let config_0 = { foo: 'bar', bar: { foo: 'bar' } };
|
let config_0 = { foo: 'bar', bar: { foo: 'bar' } };
|
||||||
let config_1 = { foo: 'bar' };
|
let config_1 = { foo: 'bar' };
|
||||||
let result = utils.assignWithDepth(config_0, config_1);
|
let result = assignWithDepth(config_0, config_1);
|
||||||
expect(result).toEqual(config_0);
|
expect(result).toEqual(config_0);
|
||||||
});
|
});
|
||||||
it('should handle depth:2 types (dst: object, src: simple type)', function () {
|
it('should handle depth:2 types (dst: object, src: simple type)', function () {
|
||||||
let config_0 = { foo: 'bar', bar: { foo: 'bar' } };
|
let config_0 = { foo: 'bar', bar: { foo: 'bar' } };
|
||||||
let config_1 = { foo: 'foo', bar: 'should NOT clobber' };
|
let config_1 = { foo: 'foo', bar: 'should NOT clobber' };
|
||||||
let result = utils.assignWithDepth(config_0, config_1);
|
let result = assignWithDepth(config_0, config_1);
|
||||||
expect(result).toEqual({ foo: 'foo', bar: { foo: 'bar' } });
|
expect(result).toEqual({ foo: 'foo', bar: { foo: 'bar' } });
|
||||||
});
|
});
|
||||||
it('should handle depth:2 types (src: orphan)', function () {
|
it('should handle depth:2 types (src: orphan)', function () {
|
||||||
let config_0 = { foo: 'bar' };
|
let config_0 = { foo: 'bar' };
|
||||||
let config_1 = { foo: 'bar', bar: { foo: 'bar' } };
|
let config_1 = { foo: 'bar', bar: { foo: 'bar' } };
|
||||||
let result = utils.assignWithDepth(config_0, config_1);
|
let result = assignWithDepth(config_0, config_1);
|
||||||
expect(result).toEqual(config_1);
|
expect(result).toEqual(config_1);
|
||||||
});
|
});
|
||||||
it('should handle depth:2 types (merge)', function () {
|
it('should handle depth:2 types (merge)', function () {
|
||||||
let config_0 = { foo: 'bar', bar: { foo: 'bar' }, boofar: 1 };
|
let config_0 = { foo: 'bar', bar: { foo: 'bar' }, boofar: 1 };
|
||||||
let config_1 = { foo: 'foo', bar: { bar: 0 }, foobar: 'foobar' };
|
let config_1 = { foo: 'foo', bar: { bar: 0 }, foobar: 'foobar' };
|
||||||
let result = utils.assignWithDepth(config_0, config_1);
|
let result = assignWithDepth(config_0, config_1);
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
foo: 'foo',
|
foo: 'foo',
|
||||||
bar: { foo: 'bar', bar: 0 },
|
bar: { foo: 'bar', bar: 0 },
|
||||||
@@ -65,7 +68,7 @@ describe('when assignWithDepth: should merge objects within objects', function (
|
|||||||
bar: { foo: 'foo', bar: { foo: { message: 'clobbered other foo' } } },
|
bar: { foo: 'foo', bar: { foo: { message: 'clobbered other foo' } } },
|
||||||
foobar: 'foobar',
|
foobar: 'foobar',
|
||||||
};
|
};
|
||||||
let result = utils.assignWithDepth(config_0, config_1);
|
let result = assignWithDepth(config_0, config_1);
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
foo: 'foo',
|
foo: 'foo',
|
||||||
bar: { foo: 'foo', bar: { foo: { message: 'clobbered other foo' } } },
|
bar: { foo: 'foo', bar: { foo: { message: 'clobbered other foo' } } },
|
||||||
@@ -87,7 +90,7 @@ describe('when assignWithDepth: should merge objects within objects', function (
|
|||||||
bar: { foo: 'foo', bar: { foo: { message: 'this' } } },
|
bar: { foo: 'foo', bar: { foo: { message: 'this' } } },
|
||||||
foobar: 'foobar',
|
foobar: 'foobar',
|
||||||
};
|
};
|
||||||
let result = utils.assignWithDepth(config_0, config_1, { depth: 1 });
|
let result = assignWithDepth(config_0, config_1, { depth: 1 });
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
foo: 'foo',
|
foo: 'foo',
|
||||||
bar: { foo: 'foo', bar: { foo: { message: 'this' } } },
|
bar: { foo: 'foo', bar: { foo: { message: 'this' } } },
|
||||||
@@ -106,7 +109,7 @@ describe('when assignWithDepth: should merge objects within objects', function (
|
|||||||
bar: { foo: 'foo', bar: { foo: { message: 'this' } } },
|
bar: { foo: 'foo', bar: { foo: { message: 'this' } } },
|
||||||
foobar: 'foobar',
|
foobar: 'foobar',
|
||||||
};
|
};
|
||||||
let result = utils.assignWithDepth(config_0, config_1, { depth: 3 });
|
let result = assignWithDepth(config_0, config_1, { depth: 3 });
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
foo: 'foo',
|
foo: 'foo',
|
||||||
bar: { foo: 'foo', bar: { foo: { message: 'this', willbe: 'present' } } },
|
bar: { foo: 'foo', bar: { foo: { message: 'this', willbe: 'present' } } },
|
||||||
@@ -137,7 +140,7 @@ describe('when memoizing', function () {
|
|||||||
describe('when detecting chart type ', function () {
|
describe('when detecting chart type ', function () {
|
||||||
it('should handle a graph definition', function () {
|
it('should handle a graph definition', function () {
|
||||||
const str = 'graph TB\nbfs1:queue';
|
const str = 'graph TB\nbfs1:queue';
|
||||||
const type = utils.detectType(str);
|
const type = detectType(str);
|
||||||
expect(type).toBe('flowchart');
|
expect(type).toBe('flowchart');
|
||||||
});
|
});
|
||||||
it('should handle an initialize definition', function () {
|
it('should handle an initialize definition', function () {
|
||||||
@@ -145,7 +148,7 @@ describe('when detecting chart type ', function () {
|
|||||||
%%{initialize: { 'logLevel': 0, 'theme': 'dark' }}%%
|
%%{initialize: { 'logLevel': 0, 'theme': 'dark' }}%%
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
Alice->Bob: hi`;
|
Alice->Bob: hi`;
|
||||||
const type = utils.detectType(str);
|
const type = detectType(str);
|
||||||
const init = utils.detectInit(str);
|
const init = utils.detectInit(str);
|
||||||
expect(type).toBe('sequence');
|
expect(type).toBe('sequence');
|
||||||
expect(init).toEqual({ logLevel: 0, theme: 'dark' });
|
expect(init).toEqual({ logLevel: 0, theme: 'dark' });
|
||||||
@@ -155,7 +158,7 @@ Alice->Bob: hi`;
|
|||||||
%%{init: { 'logLevel': 0, 'theme': 'dark' }}%%
|
%%{init: { 'logLevel': 0, 'theme': 'dark' }}%%
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
Alice->Bob: hi`;
|
Alice->Bob: hi`;
|
||||||
const type = utils.detectType(str);
|
const type = detectType(str);
|
||||||
const init = utils.detectInit(str);
|
const init = utils.detectInit(str);
|
||||||
expect(type).toBe('sequence');
|
expect(type).toBe('sequence');
|
||||||
expect(init).toEqual({ logLevel: 0, theme: 'dark' });
|
expect(init).toEqual({ logLevel: 0, theme: 'dark' });
|
||||||
@@ -165,7 +168,7 @@ Alice->Bob: hi`;
|
|||||||
%%{init: { 'logLevel': 0, 'theme': 'dark', 'config': {'wrap': true} } }%%
|
%%{init: { 'logLevel': 0, 'theme': 'dark', 'config': {'wrap': true} } }%%
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
Alice->Bob: hi`;
|
Alice->Bob: hi`;
|
||||||
const type = utils.detectType(str);
|
const type = detectType(str);
|
||||||
const init = utils.detectInit(str);
|
const init = utils.detectInit(str);
|
||||||
expect(type).toBe('sequence');
|
expect(type).toBe('sequence');
|
||||||
expect(init).toEqual({ logLevel: 0, theme: 'dark', sequence: { wrap: true } });
|
expect(init).toEqual({ logLevel: 0, theme: 'dark', sequence: { wrap: true } });
|
||||||
@@ -180,7 +183,7 @@ Alice->Bob: hi`;
|
|||||||
}%%
|
}%%
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
Alice->Bob: hi`;
|
Alice->Bob: hi`;
|
||||||
const type = utils.detectType(str);
|
const type = detectType(str);
|
||||||
const init = utils.detectInit(str);
|
const init = utils.detectInit(str);
|
||||||
expect(type).toBe('sequence');
|
expect(type).toBe('sequence');
|
||||||
expect(init).toEqual({ logLevel: 0, theme: 'dark' });
|
expect(init).toEqual({ logLevel: 0, theme: 'dark' });
|
||||||
@@ -195,25 +198,25 @@ Alice->Bob: hi`;
|
|||||||
}%%
|
}%%
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
Alice->Bob: hi`;
|
Alice->Bob: hi`;
|
||||||
const type = utils.detectType(str);
|
const type = detectType(str);
|
||||||
const init = utils.detectInit(str);
|
const init = utils.detectInit(str);
|
||||||
expect(type).toBe('sequence');
|
expect(type).toBe('sequence');
|
||||||
expect(init).toEqual({ logLevel: 0, theme: 'dark' });
|
expect(init).toEqual({ logLevel: 0, theme: 'dark' });
|
||||||
});
|
});
|
||||||
it('should handle a graph definition with leading spaces', function () {
|
it('should handle a graph definition with leading spaces', function () {
|
||||||
const str = ' graph TB\nbfs1:queue';
|
const str = ' graph TB\nbfs1:queue';
|
||||||
const type = utils.detectType(str);
|
const type = detectType(str);
|
||||||
expect(type).toBe('flowchart');
|
expect(type).toBe('flowchart');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle a graph definition with leading spaces and newline', function () {
|
it('should handle a graph definition with leading spaces and newline', function () {
|
||||||
const str = ' \n graph TB\nbfs1:queue';
|
const str = ' \n graph TB\nbfs1:queue';
|
||||||
const type = utils.detectType(str);
|
const type = detectType(str);
|
||||||
expect(type).toBe('flowchart');
|
expect(type).toBe('flowchart');
|
||||||
});
|
});
|
||||||
it('should handle a graph definition for gitGraph', function () {
|
it('should handle a graph definition for gitGraph', function () {
|
||||||
const str = ' \n gitGraph TB:\nbfs1:queue';
|
const str = ' \n gitGraph TB:\nbfs1:queue';
|
||||||
const type = utils.detectType(str);
|
const type = detectType(str);
|
||||||
expect(type).toBe('gitGraph');
|
expect(type).toBe('gitGraph');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user