Merge pull request #4486 from Yokozuna59/standardized-diagrams-definitions

standardize info diagram definitions
This commit is contained in:
Sidharth Vinod 2023-06-16 17:44:31 +05:30 committed by GitHub
commit 15dbf22a40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
53 changed files with 2728 additions and 2551 deletions

View File

@ -1,8 +1,6 @@
// @ts-ignore No typings for jison
import jison from 'jison';
export const transformJison = (src: string): string => {
// @ts-ignore No typings for jison
const parser = new jison.Generator(src, {
moduleType: 'js',
'token-stack': true,

View File

@ -1,4 +1,3 @@
// @ts-nocheck TODO: Fix TS
import { MockedD3 } from '../packages/mermaid/src/tests/MockedD3.js';
export const select = function () {

View File

@ -1,13 +0,0 @@
import { imgSnapshotTest } from '../../helpers/util.js';
describe('Sequencediagram', () => {
it('should render a simple info diagrams', () => {
imgSnapshotTest(
`
info
showInfo
`,
{}
);
});
});

View File

@ -0,0 +1,11 @@
import { imgSnapshotTest } from '../../helpers/util.js';
describe('info diagram', () => {
it('should handle an info definition', () => {
imgSnapshotTest(`info`);
});
it('should handle an info definition with showInfo', () => {
imgSnapshotTest(`info showInfo`);
});
});

View File

@ -1,23 +0,0 @@
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet" />
</head>
<body>
<h1>info below</h1>
<pre class="mermaid">
info
</pre>
<script type="module">
import mermaid from './mermaid.esm.mjs';
mermaid.initialize({
theme: 'forest',
// themeCSS: '.node rect { fill: red; }',
logLevel: 3,
flowchart: { curve: 'linear' },
gantt: { axisFormat: '%m/%d/%Y' },
sequence: { actorMargin: 50 },
// sequenceDiagram: { actorMargin: 300 } // deprecated
});
</script>
</body>
</html>

View File

@ -45,6 +45,9 @@
<li>
<h2><a href="./git.html">Git</a></h2>
</li>
<li>
<h2><a href="./info.html">Info</a></h2>
</li>
<li>
<h2><a href="./journey.html">Journey</a></h2>
</li>
@ -66,6 +69,9 @@
<li>
<h2><a href="./state.html">State</a></h2>
</li>
<li>
<h2><a href="./timeline.html">Timeline</a></h2>
</li>
<li>
<h2><a href="./zenuml.html">ZenUML</a></h2>
</li>

35
demos/info.html Normal file
View File

@ -0,0 +1,35 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Mermaid Quick Test Page</title>
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=" />
<style>
div.mermaid {
font-family: 'Courier New', Courier, monospace !important;
}
</style>
</head>
<body>
<h1>Info diagram demos</h1>
<pre class="mermaid">
info
</pre>
<hr />
<pre class="mermaid">
info showInfo
</pre>
<script type="module">
import mermaid from './mermaid.esm.mjs';
mermaid.initialize({
theme: 'forest',
logLevel: 3,
securityLevel: 'loose',
});
</script>
</body>
</html>

View File

@ -39,7 +39,7 @@ bindFunctions?.(div); // To call bindFunctions only if it's present.
#### Defined in
[mermaidAPI.ts:98](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L98)
[mermaidAPI.ts:97](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L97)
---
@ -51,4 +51,4 @@ The svg code for the rendered graph.
#### Defined in
[mermaidAPI.ts:88](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L88)
[mermaidAPI.ts:87](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L87)

View File

@ -25,7 +25,7 @@ Renames and re-exports [mermaidAPI](mermaidAPI.md#mermaidapi)
#### Defined in
[mermaidAPI.ts:82](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L82)
[mermaidAPI.ts:81](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L81)
## Variables
@ -96,7 +96,7 @@ mermaid.initialize(config);
#### Defined in
[mermaidAPI.ts:670](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L670)
[mermaidAPI.ts:663](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L663)
## Functions
@ -127,7 +127,7 @@ Return the last node appended
#### Defined in
[mermaidAPI.ts:309](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L309)
[mermaidAPI.ts:308](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L308)
---
@ -153,7 +153,7 @@ the cleaned up svgCode
#### Defined in
[mermaidAPI.ts:257](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L257)
[mermaidAPI.ts:256](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L256)
---
@ -179,7 +179,7 @@ the string with all the user styles
#### Defined in
[mermaidAPI.ts:186](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L186)
[mermaidAPI.ts:185](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L185)
---
@ -202,7 +202,7 @@ the string with all the user styles
#### Defined in
[mermaidAPI.ts:234](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L234)
[mermaidAPI.ts:233](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L233)
---
@ -229,7 +229,7 @@ with an enclosing block that has each of the cssClasses followed by !important;
#### Defined in
[mermaidAPI.ts:170](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L170)
[mermaidAPI.ts:169](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L169)
---
@ -249,7 +249,7 @@ with an enclosing block that has each of the cssClasses followed by !important;
#### Defined in
[mermaidAPI.ts:156](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L156)
[mermaidAPI.ts:155](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L155)
---
@ -269,7 +269,7 @@ with an enclosing block that has each of the cssClasses followed by !important;
#### Defined in
[mermaidAPI.ts:127](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L127)
[mermaidAPI.ts:126](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L126)
---
@ -295,7 +295,7 @@ Put the svgCode into an iFrame. Return the iFrame code
#### Defined in
[mermaidAPI.ts:288](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L288)
[mermaidAPI.ts:287](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L287)
---
@ -320,4 +320,4 @@ Remove any existing elements from the given document
#### Defined in
[mermaidAPI.ts:359](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L359)
[mermaidAPI.ts:358](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L358)

View File

@ -3,7 +3,7 @@ import type { ExternalDiagramDefinition } from 'mermaid';
const id = 'example-diagram';
const detector = (txt: string) => {
return txt.match(/^\s*example-diagram/) !== null;
return /^\s*example-diagram/.test(txt);
};
const loader = async () => {

View File

@ -1,10 +1,9 @@
import type { ExternalDiagramDefinition } from 'mermaid';
const id = 'zenuml';
const regexp = /^\s*zenuml/;
const detector = (txt: string) => {
return txt.match(regexp) !== null;
return /^\s*zenuml/.test(txt);
};
const loader = async () => {

View File

@ -73,6 +73,7 @@
"devDependencies": {
"@types/cytoscape": "^3.19.9",
"@types/d3": "^7.4.0",
"@types/d3-selection": "^3.0.5",
"@types/dompurify": "^3.0.2",
"@types/jsdom": "^21.1.1",
"@types/lodash-es": "^4.17.7",

View File

@ -51,7 +51,6 @@ describe('accessibility', () => {
desc: string | null | undefined,
givenId: string
) {
// @ts-ignore Required to easily handle the d3 select types
const svgAttrSpy = vi.spyOn(svgD3Node, 'attr').mockReturnValue(svgD3Node);
addSVGa11yTitleDescription(svgD3Node, title, desc, givenId);
expect(svgAttrSpy).toHaveBeenCalledWith('aria-labelledby', `chart-title-${givenId}`);
@ -63,7 +62,6 @@ describe('accessibility', () => {
desc: string | null | undefined,
givenId: string
) {
// @ts-ignore Required to easily handle the d3 select types
const svgAttrSpy = vi.spyOn(svgD3Node, 'attr').mockReturnValue(svgD3Node);
addSVGa11yTitleDescription(svgD3Node, title, desc, givenId);
expect(svgAttrSpy).toHaveBeenCalledWith('aria-describedby', `chart-desc-${givenId}`);

View File

@ -4,7 +4,7 @@ import flowchartV2 from '../diagrams/flowchart/flowDetector-v2.js';
import er from '../diagrams/er/erDetector.js';
import git from '../diagrams/git/gitGraphDetector.js';
import gantt from '../diagrams/gantt/ganttDetector.js';
import info from '../diagrams/info/infoDetector.js';
import { info } from '../diagrams/info/infoDetector.js';
import pie from '../diagrams/pie/pieDetector.js';
import quadrantChart from '../diagrams/quadrant-chart/quadrantDetector.js';
import requirement from '../diagrams/requirement/requirementDetector.js';

View File

@ -7,6 +7,7 @@ import { addStylesForDiagram } from '../styles.js';
import { DiagramDefinition, DiagramDetector } from './types.js';
import * as _commonDb from '../commonDb.js';
import { parseDirective as _parseDirective } from '../directiveUtils.js';
import isEmpty from 'lodash-es/isEmpty.js';
/*
Packaging and exposing resources for external diagrams so that they can import
@ -50,7 +51,9 @@ export const registerDiagram = (
if (detector) {
addDetector(id, detector);
}
addStylesForDiagram(id, diagram.styles);
if (!isEmpty(diagram.styles)) {
addStylesForDiagram(id, diagram.styles);
}
if (diagram.injectUtils) {
diagram.injectUtils(

View File

@ -1,4 +1,4 @@
import { DiagramDb } from './types.js';
import { DiagramDB } from './types.js';
// The "* as yaml" part is necessary for tree-shaking
import * as yaml from 'js-yaml';
@ -22,7 +22,7 @@ type FrontMatterMetadata = {
* @param db - Diagram database, could be of any diagram.
* @returns text with frontmatter stripped out
*/
export function extractFrontMatter(text: string, db: DiagramDb): string {
export function extractFrontMatter(text: string, db: DiagramDB): string {
const matches = text.match(frontMatterRegex);
if (matches) {
const parsed: FrontMatterMetadata = yaml.load(matches[1], {

View File

@ -1,4 +1,6 @@
import { Diagram } from '../Diagram.js';
import { MermaidConfig } from '../config.type.js';
import type * as d3 from 'd3';
export interface InjectUtils {
_log: any;
@ -13,7 +15,7 @@ export interface InjectUtils {
/**
* Generic Diagram DB that may apply to any diagram type.
*/
export interface DiagramDb {
export interface DiagramDB {
clear?: () => void;
setDiagramTitle?: (title: string) => void;
setDisplayMode?: (title: string) => void;
@ -23,10 +25,10 @@ export interface DiagramDb {
}
export interface DiagramDefinition {
db: DiagramDb;
db: DiagramDB;
renderer: any;
parser: any;
styles: any;
styles?: any;
init?: (config: MermaidConfig) => void;
injectUtils?: (
_log: InjectUtils['_log'],
@ -52,3 +54,31 @@ export interface ExternalDiagramDefinition {
export type DiagramDetector = (text: string, config?: MermaidConfig) => boolean;
export type DiagramLoader = () => Promise<{ id: string; diagram: DiagramDefinition }>;
/**
* Type for function draws diagram in the tag with id: id based on the graph definition in text.
*
* @param text - The text of the diagram.
* @param id - The id of the diagram which will be used as a DOM element id.
* @param version - MermaidJS version from package.json.
* @param diagramObject - A standard diagram containing the DB and the text and type etc of the diagram.
*/
export type DrawDefinition = (
text: string,
id: string,
version: string,
diagramObject: Diagram
) => void;
/**
* Type for function parse directive from diagram code.
*
* @param statement -
* @param context -
* @param type -
*/
export type ParseDirectiveDefinition = (statement: string, context: string, type: string) => void;
export type HTML = d3.Selection<HTMLIFrameElement, unknown, Element, unknown>;
export type SVG = d3.Selection<SVGSVGElement, unknown, Element, unknown>;

View File

@ -1,12 +1,16 @@
import type { ExternalDiagramDefinition } from '../../diagram-api/types.js';
import type {
DiagramDetector,
DiagramLoader,
ExternalDiagramDefinition,
} from '../../diagram-api/types.js';
const id = 'c4';
const detector = (txt: string) => {
return txt.match(/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/) !== null;
const detector: DiagramDetector = (txt) => {
return /^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/.test(txt);
};
const loader = async () => {
const loader: DiagramLoader = async () => {
const { diagram } = await import('./c4Diagram.js');
return { id, diagram };
};

View File

@ -1,4 +1,4 @@
// @ts-expect-error - d3 types issue
// @ts-nocheck - don't check until handle it
import { select, Selection } from 'd3';
import { log } from '../../logger.js';
import * as configApi from '../../config.js';
@ -367,7 +367,6 @@ export const relationType = {
const setupToolTips = function (element: Element) {
let tooltipElem: Selection<HTMLDivElement, unknown, HTMLElement, unknown> =
select('.mermaidTooltip');
// @ts-ignore - _groups is a dynamic property
if ((tooltipElem._groups || tooltipElem)[0][0] === null) {
tooltipElem = select('body').append('div').attr('class', 'mermaidTooltip').style('opacity', 0);
}

View File

@ -1,20 +1,21 @@
import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types.js';
import type {
DiagramDetector,
DiagramLoader,
ExternalDiagramDefinition,
} from '../../diagram-api/types.js';
const id = 'classDiagram';
const detector: DiagramDetector = (txt, config) => {
// If we have configured to use dagre-wrapper then we should return true in this function for classDiagram code thus making it use the new class diagram
if (
txt.match(/^\s*classDiagram/) !== null &&
config?.class?.defaultRenderer === 'dagre-wrapper'
) {
if (/^\s*classDiagram/.test(txt) && config?.class?.defaultRenderer === 'dagre-wrapper') {
return true;
}
// We have not opted to use the new renderer so we should return true if we detect a class diagram
return txt.match(/^\s*classDiagram-v2/) !== null;
return /^\s*classDiagram-v2/.test(txt);
};
const loader = async () => {
const loader: DiagramLoader = async () => {
const { diagram } = await import('./classDiagram-v2.js');
return { id, diagram };
};

View File

@ -1,4 +1,8 @@
import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types.js';
import type {
DiagramDetector,
DiagramLoader,
ExternalDiagramDefinition,
} from '../../diagram-api/types.js';
const id = 'class';
@ -8,10 +12,10 @@ const detector: DiagramDetector = (txt, config) => {
return false;
}
// We have not opted to use the new renderer so we should return true if we detect a class diagram
return txt.match(/^\s*classDiagram/) !== null;
return /^\s*classDiagram/.test(txt);
};
const loader = async () => {
const loader: DiagramLoader = async () => {
const { diagram } = await import('./classDiagram.js');
return { id, diagram };
};

View File

@ -1,4 +1,4 @@
// @ts-ignore d3 types are not available
// @ts-nocheck - don't check until handle it
import { select, curveLinear } from 'd3';
import * as graphlib from 'dagre-d3-es/src/graphlib/index.js';
import { log } from '../../logger.js';
@ -353,15 +353,11 @@ export const draw = async function (text: string, id: string, _version: string,
}
const root =
securityLevel === 'sandbox'
? // @ts-ignore Ignore type error for now
select(sandboxElement.nodes()[0].contentDocument.body)
? select(sandboxElement.nodes()[0].contentDocument.body)
: select('body');
// @ts-ignore Ignore type error for now
const svg = root.select(`[id="${id}"]`);
// Run the renderer. This is what draws the final graph.
// @ts-ignore Ignore type error for now
const element = root.select('#' + id + ' g');
await render(
element,
@ -377,7 +373,6 @@ export const draw = async function (text: string, id: string, _version: string,
// Add label rects for non html labels
if (!conf?.htmlLabels) {
// @ts-ignore Ignore type error for now
const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0].contentDocument : document;
const labels = doc.querySelectorAll('[id="' + id + '"] .edgeLabel .label');
for (const label of labels) {

View File

@ -1,12 +1,16 @@
import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types.js';
import type {
DiagramDetector,
DiagramLoader,
ExternalDiagramDefinition,
} from '../../diagram-api/types.js';
const id = 'er';
const detector: DiagramDetector = (txt) => {
return txt.match(/^\s*erDiagram/) !== null;
return /^\s*erDiagram/.test(txt);
};
const loader = async () => {
const loader: DiagramLoader = async () => {
const { diagram } = await import('./erDiagram.js');
return { id, diagram };
};

View File

@ -1,4 +1,4 @@
// @ts-ignore: TODO Fix ts errors
// @ts-ignore: TODO: Fix ts errors
import erParser from './parser/erDiagram.jison';
import erDb from './erDb.js';
import erRenderer from './erRenderer.js';

View File

@ -1,21 +1,24 @@
import type { MermaidConfig } from '../../../config.type.js';
import type { ExternalDiagramDefinition, DiagramDetector } from '../../../diagram-api/types.js';
import type {
ExternalDiagramDefinition,
DiagramDetector,
DiagramLoader,
} from '../../../diagram-api/types.js';
const id = 'flowchart-elk';
const detector: DiagramDetector = (txt: string, config?: MermaidConfig): boolean => {
const detector: DiagramDetector = (txt, config): boolean => {
if (
// If diagram explicitly states flowchart-elk
txt.match(/^\s*flowchart-elk/) ||
/^\s*flowchart-elk/.test(txt) ||
// If a flowchart/graph diagram has their default renderer set to elk
(txt.match(/^\s*flowchart|graph/) && config?.flowchart?.defaultRenderer === 'elk')
(/^\s*flowchart|graph/.test(txt) && config?.flowchart?.defaultRenderer === 'elk')
) {
return true;
}
return false;
};
const loader = async () => {
const loader: DiagramLoader = async () => {
const { diagram } = await import('./flowchart-elk-definition.js');
return { id, diagram };
};

View File

@ -1,4 +1,4 @@
import type { DiagramDetector } from '../../diagram-api/types.js';
import type { DiagramDetector, DiagramLoader } from '../../diagram-api/types.js';
import type { ExternalDiagramDefinition } from '../../diagram-api/types.js';
const id = 'flowchart-v2';
@ -12,13 +12,13 @@ const detector: DiagramDetector = (txt, config) => {
}
// If we have configured to use dagre-wrapper then we should return true in this function for graph code thus making it use the new flowchart diagram
if (txt.match(/^\s*graph/) !== null && config?.flowchart?.defaultRenderer === 'dagre-wrapper') {
if (/^\s*graph/.test(txt) && config?.flowchart?.defaultRenderer === 'dagre-wrapper') {
return true;
}
return txt.match(/^\s*flowchart/) !== null;
return /^\s*flowchart/.test(txt);
};
const loader = async () => {
const loader: DiagramLoader = async () => {
const { diagram } = await import('./flowDiagram-v2.js');
return { id, diagram };
};

View File

@ -1,4 +1,8 @@
import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types.js';
import type {
DiagramDetector,
DiagramLoader,
ExternalDiagramDefinition,
} from '../../diagram-api/types.js';
const id = 'flowchart';
@ -11,10 +15,10 @@ const detector: DiagramDetector = (txt, config) => {
) {
return false;
}
return txt.match(/^\s*graph/) !== null;
return /^\s*graph/.test(txt);
};
const loader = async () => {
const loader: DiagramLoader = async () => {
const { diagram } = await import('./flowDiagram.js');
return { id, diagram };
};

View File

@ -1,12 +1,16 @@
import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types.js';
import type {
DiagramDetector,
DiagramLoader,
ExternalDiagramDefinition,
} from '../../diagram-api/types.js';
const id = 'gantt';
const detector: DiagramDetector = (txt) => {
return txt.match(/^\s*gantt/) !== null;
return /^\s*gantt/.test(txt);
};
const loader = async () => {
const loader: DiagramLoader = async () => {
const { diagram } = await import('./ganttDiagram.js');
return { id, diagram };
};

View File

@ -1,13 +1,13 @@
import type { DiagramDetector } from '../../diagram-api/types.js';
import type { DiagramDetector, DiagramLoader } from '../../diagram-api/types.js';
import type { ExternalDiagramDefinition } from '../../diagram-api/types.js';
const id = 'gitGraph';
const detector: DiagramDetector = (txt) => {
return txt.match(/^\s*gitGraph/) !== null;
return /^\s*gitGraph/.test(txt);
};
const loader = async () => {
const loader: DiagramLoader = async () => {
const { diagram } = await import('./gitGraphDiagram.js');
return { id, diagram };
};

View File

@ -1,16 +0,0 @@
import { parser } from './parser/info.jison';
import infoDb from './infoDb.js';
describe('when parsing an info graph it', function () {
let ex;
beforeEach(function () {
ex = parser;
ex.yy = infoDb;
});
it('should handle an info definition', function () {
let str = `info
showInfo`;
ex.parse(str);
});
});

View File

@ -0,0 +1,24 @@
// @ts-ignore - jison doesn't export types
import { parser } from './parser/info.jison';
import { db } from './infoDb.js';
describe('info diagram', () => {
beforeEach(() => {
parser.yy = db;
parser.yy.clear();
});
it('should handle an info definition', () => {
const str = `info`;
parser.parse(str);
expect(db.getInfo()).toBeFalsy();
});
it('should handle an info definition with showInfo', () => {
const str = `info showInfo`;
parser.parse(str);
expect(db.getInfo()).toBeTruthy();
});
});

View File

@ -1,36 +0,0 @@
/** Created by knut on 15-01-14. */
import { log } from '../../logger.js';
import { clear } from '../../commonDb.js';
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,
clear,
// parseError
};

View File

@ -0,0 +1,23 @@
import type { InfoFields, InfoDB } from './infoTypes.js';
export const DEFAULT_INFO_DB: InfoFields = {
info: false,
} as const;
let info: boolean = DEFAULT_INFO_DB.info;
export const setInfo = (toggle: boolean): void => {
info = toggle;
};
export const getInfo = (): boolean => info;
const clear = (): void => {
info = DEFAULT_INFO_DB.info;
};
export const db: InfoDB = {
clear,
setInfo,
getInfo,
};

View File

@ -1,20 +1,22 @@
import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types.js';
import type {
DiagramDetector,
DiagramLoader,
ExternalDiagramDefinition,
} from '../../diagram-api/types.js';
const id = 'info';
const detector: DiagramDetector = (txt) => {
return txt.match(/^\s*info/) !== null;
return /^\s*info/.test(txt);
};
const loader = async () => {
const loader: DiagramLoader = async () => {
const { diagram } = await import('./infoDiagram.js');
return { id, diagram };
};
const plugin: ExternalDiagramDefinition = {
export const info: ExternalDiagramDefinition = {
id,
detector,
loader,
};
export default plugin;

View File

@ -1,13 +1,11 @@
import { DiagramDefinition } from '../../diagram-api/types.js';
// @ts-ignore: TODO Fix ts errors
import type { DiagramDefinition } from '../../diagram-api/types.js';
// @ts-ignore - jison doesn't export types
import parser from './parser/info.jison';
import db from './infoDb.js';
import styles from './styles.js';
import renderer from './infoRenderer.js';
import { db } from './infoDb.js';
import { renderer } from './infoRenderer.js';
export const diagram: DiagramDefinition = {
parser,
db,
renderer,
styles,
};

View File

@ -1,57 +0,0 @@
/** Created by knut on 14-12-11. */
import { select } from 'd3';
import { log } from '../../logger.js';
import { getConfig } from '../../config.js';
/**
* 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
*/
export const draw = (text, id, version) => {
try {
// const parser = infoParser.parser;
// parser.yy = db;
log.debug('Rendering info diagram\n' + text);
const securityLevel = getConfig().securityLevel;
// Handle root and Document for when rendering in sandbox 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
// 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,
};

View File

@ -0,0 +1,50 @@
import { select } from 'd3';
import { log } from '../../logger.js';
import { getConfig } from '../../config.js';
import type { DrawDefinition, HTML, SVG } from '../../diagram-api/types.js';
/**
* Draws a an info picture in the tag with id: id based on the graph definition in text.
*
* @param text - The text of the diagram.
* @param id - The id of the diagram which will be used as a DOM element id.
* @param version - MermaidJS version.
*/
const draw: DrawDefinition = (text, id, version) => {
try {
log.debug('rendering info diagram\n' + text);
const { securityLevel } = getConfig();
// handle root and document for when rendering in sandbox mode
let sandboxElement: HTML | undefined;
let document: Document | null | undefined;
if (securityLevel === 'sandbox') {
sandboxElement = select('#i' + id);
document = sandboxElement.nodes()[0].contentDocument;
}
// @ts-ignore - figure out how to assign HTML to document type
const root: HTML =
sandboxElement !== undefined && document !== undefined && document !== null
? select(document)
: select('body');
const svg: SVG = root.select('#' + id);
svg.attr('height', 100);
svg.attr('width', 400);
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);
} catch (e) {
log.error('error while rendering info diagram', e);
}
};
export const renderer = { draw };

View File

@ -0,0 +1,11 @@
import type { DiagramDB } from '../../diagram-api/types.js';
export interface InfoFields {
info: boolean;
}
export interface InfoDB extends DiagramDB {
clear: () => void;
setInfo: (info: boolean) => void;
getInfo: () => boolean;
}

View File

@ -1,3 +0,0 @@
const getStyles = () => ``;
export default getStyles;

View File

@ -1,11 +1,15 @@
import type { ExternalDiagramDefinition } from '../../diagram-api/types.js';
import type {
DiagramDetector,
DiagramLoader,
ExternalDiagramDefinition,
} from '../../diagram-api/types.js';
const id = 'mindmap';
const detector = (txt: string) => {
return txt.match(/^\s*mindmap/) !== null;
const detector: DiagramDetector = (txt) => {
return /^\s*mindmap/.test(txt);
};
const loader = async () => {
const loader: DiagramLoader = async () => {
const { diagram } = await import('./mindmap-definition.js');
return { id, diagram };
};

View File

@ -1,12 +1,16 @@
import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types.js';
import type {
DiagramDetector,
DiagramLoader,
ExternalDiagramDefinition,
} from '../../diagram-api/types.js';
const id = 'pie';
const detector: DiagramDetector = (txt) => {
return txt.match(/^\s*pie/) !== null;
return /^\s*pie/.test(txt);
};
const loader = async () => {
const loader: DiagramLoader = async () => {
const { diagram } = await import('./pieDiagram.js');
return { id, diagram };
};

View File

@ -1,12 +1,16 @@
import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types.js';
import type {
DiagramDetector,
DiagramLoader,
ExternalDiagramDefinition,
} from '../../diagram-api/types.js';
const id = 'quadrantChart';
const detector: DiagramDetector = (txt) => {
return txt.match(/^\s*quadrantChart/) !== null;
return /^\s*quadrantChart/.test(txt);
};
const loader = async () => {
const loader: DiagramLoader = async () => {
const { diagram } = await import('./quadrantDiagram.js');
return { id, diagram };
};

View File

@ -1,4 +1,4 @@
// @ts-ignore: TODO Fix ts errors
// @ts-nocheck - don't check until handle it
import { select } from 'd3';
import * as configApi from '../../config.js';
import { log } from '../../logger.js';

View File

@ -1,12 +1,16 @@
import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types.js';
import type {
DiagramDetector,
DiagramLoader,
ExternalDiagramDefinition,
} from '../../diagram-api/types.js';
const id = 'requirement';
const detector: DiagramDetector = (txt) => {
return txt.match(/^\s*requirement(Diagram)?/) !== null;
return /^\s*requirement(Diagram)?/.test(txt);
};
const loader = async () => {
const loader: DiagramLoader = async () => {
const { diagram } = await import('./requirementDiagram.js');
return { id, diagram };
};

View File

@ -1,12 +1,16 @@
import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types.js';
import type {
DiagramDetector,
DiagramLoader,
ExternalDiagramDefinition,
} from '../../diagram-api/types.js';
const id = 'sequence';
const detector: DiagramDetector = (txt) => {
return txt.match(/^\s*sequenceDiagram/) !== null;
return /^\s*sequenceDiagram/.test(txt);
};
const loader = async () => {
const loader: DiagramLoader = async () => {
const { diagram } = await import('./sequenceDiagram.js');
return { id, diagram };
};

View File

@ -1,21 +1,22 @@
import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types.js';
import type {
DiagramDetector,
DiagramLoader,
ExternalDiagramDefinition,
} from '../../diagram-api/types.js';
const id = 'stateDiagram';
const detector: DiagramDetector = (text, config) => {
if (text.match(/^\s*stateDiagram-v2/) !== null) {
const detector: DiagramDetector = (txt, config) => {
if (/^\s*stateDiagram-v2/.test(txt)) {
return true;
}
if (text.match(/^\s*stateDiagram/) && config?.state?.defaultRenderer === 'dagre-wrapper') {
return true;
}
if (text.match(/^\s*stateDiagram/) && config?.state?.defaultRenderer === 'dagre-wrapper') {
if (/^\s*stateDiagram/.test(txt) && config?.state?.defaultRenderer === 'dagre-wrapper') {
return true;
}
return false;
};
const loader = async () => {
const loader: DiagramLoader = async () => {
const { diagram } = await import('./stateDiagram-v2.js');
return { id, diagram };
};

View File

@ -1,4 +1,8 @@
import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types.js';
import type {
DiagramDetector,
DiagramLoader,
ExternalDiagramDefinition,
} from '../../diagram-api/types.js';
const id = 'state';
@ -8,10 +12,10 @@ const detector: DiagramDetector = (txt, config) => {
if (config?.state?.defaultRenderer === 'dagre-wrapper') {
return false;
}
return txt.match(/^\s*stateDiagram/) !== null;
return /^\s*stateDiagram/.test(txt);
};
const loader = async () => {
const loader: DiagramLoader = async () => {
const { diagram } = await import('./stateDiagram.js');
return { id, diagram };
};

View File

@ -1,12 +1,16 @@
import type { ExternalDiagramDefinition } from '../../diagram-api/types.js';
import type {
DiagramDetector,
DiagramLoader,
ExternalDiagramDefinition,
} from '../../diagram-api/types.js';
const id = 'timeline';
const detector = (txt: string) => {
return txt.match(/^\s*timeline/) !== null;
const detector: DiagramDetector = (txt) => {
return /^\s*timeline/.test(txt);
};
const loader = async () => {
const loader: DiagramLoader = async () => {
const { diagram } = await import('./timeline-definition.js');
return { id, diagram };
};

View File

@ -1,4 +1,4 @@
// @ts-ignore - db not typed yet
// @ts-nocheck - don't check until handle it
import { select, Selection } from 'd3';
import svgDraw from './svgDraw.js';
import { log } from '../../logger.js';
@ -46,11 +46,9 @@ export const draw = function (text: string, id: string, version: string, diagObj
}
const root =
securityLevel === 'sandbox'
? // @ts-ignore d3 types are wrong
select(sandboxElement.nodes()[0].contentDocument.body)
? select(sandboxElement.nodes()[0].contentDocument.body)
: select('body');
// @ts-ignore d3 types are wrong
const svg = root.select('#' + id);
svg.append('g');

View File

@ -1,12 +1,16 @@
import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types.js';
import type {
DiagramDetector,
DiagramLoader,
ExternalDiagramDefinition,
} from '../../diagram-api/types.js';
const id = 'journey';
const detector: DiagramDetector = (txt) => {
return txt.match(/^\s*journey/) !== null;
return /^\s*journey/.test(txt);
};
const loader = async () => {
const loader: DiagramLoader = async () => {
const { diagram } = await import('./journeyDiagram.js');
return { id, diagram };
};

View File

@ -78,7 +78,6 @@ export interface ParseOptions {
}
// This makes it clear that we're working with a d3 selected element of some kind, even though it's hard to specify the exact type.
// @ts-ignore Could replicate the type definition in d3. This also makes it possible to use the untyped info from the js diagram files.
export type D3Element = any;
export interface RenderResult {
@ -491,13 +490,7 @@ const render = async function (
? diag.renderer.getClasses(text, diag)
: {};
const rules = createUserStyles(
config,
graphType,
// @ts-ignore convert renderer to TS.
diagramClassDefs,
idSelector
);
const rules = createUserStyles(config, graphType, diagramClassDefs, idSelector);
const style1 = document.createElement('style');
style1.innerHTML = rules;

View File

@ -22,7 +22,6 @@ import er from './diagrams/er/styles.js';
import error from './diagrams/error/styles.js';
import git from './diagrams/git/styles.js';
import gantt from './diagrams/gantt/styles.js';
import info from './diagrams/info/styles.js';
import pie from './diagrams/pie/styles.js';
import requirement from './diagrams/requirement/styles.js';
import sequence from './diagrams/sequence/styles.js';
@ -92,7 +91,6 @@ describe('styles', () => {
flowchartElk,
gantt,
git,
info,
journey,
mindmap,
pie,

File diff suppressed because it is too large Load Diff