mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-01-14 06:43:25 +08:00
merged with master
This commit is contained in:
commit
aad53f9e61
@ -61,24 +61,25 @@
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": "./**/*.html",
|
||||
"rules": {
|
||||
"no-undef": "off",
|
||||
"jsdoc/require-jsdoc": "off"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["./cypress/**", "./demos/**"],
|
||||
"files": ["cypress/**", "demos/**"],
|
||||
"rules": {
|
||||
"no-console": "off"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["./**/*.spec.{ts,js}", "./cypress/**", "./demos/**", "./**/docs/**"],
|
||||
"files": ["*.spec.{ts,js}", "cypress/**", "demos/**", "**/docs/**"],
|
||||
"rules": {
|
||||
"jsdoc/require-jsdoc": "off",
|
||||
"@typescript-eslint/no-unused-vars": "off"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["*.html", "*.md", "**/*.md/*"],
|
||||
"rules": {
|
||||
"no-var": "error",
|
||||
"no-undef": "off",
|
||||
"@typescript-eslint/no-unused-vars": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@ -16,7 +16,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [16.x]
|
||||
node-version: [18.x]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
|
4
.github/workflows/docs.yml
vendored
4
.github/workflows/docs.yml
vendored
@ -16,9 +16,9 @@ jobs:
|
||||
name: 'Docs: Spellcheck'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
name: Check out the code
|
||||
- uses: actions/setup-node@v1
|
||||
- uses: actions/setup-node@v3
|
||||
name: Setup node
|
||||
with:
|
||||
node-version: '16'
|
||||
|
2
.github/workflows/e2e-applitools.yml
vendored
2
.github/workflows/e2e-applitools.yml
vendored
@ -23,7 +23,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [16.x]
|
||||
node-version: [18.x]
|
||||
steps:
|
||||
- if: ${{ ! env.USE_APPLI }}
|
||||
name: Warn if not using Applitools
|
||||
|
2
.github/workflows/e2e.yml
vendored
2
.github/workflows/e2e.yml
vendored
@ -11,7 +11,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node-version: [16.x]
|
||||
node-version: [18.x]
|
||||
containers: [1, 2, 3, 4]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
2
.github/workflows/lint.yml
vendored
2
.github/workflows/lint.yml
vendored
@ -16,7 +16,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [16.x]
|
||||
node-version: [18.x]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
|
@ -13,7 +13,7 @@ jobs:
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
node-version: 18.x
|
||||
- name: Install Yarn
|
||||
run: npm i yarn --global
|
||||
|
||||
|
2
.github/workflows/release-publish.yml
vendored
2
.github/workflows/release-publish.yml
vendored
@ -14,7 +14,7 @@ jobs:
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
node-version: 18.x
|
||||
- name: Install Yarn
|
||||
run: npm i yarn --global
|
||||
|
||||
|
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@ -10,7 +10,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [16.x]
|
||||
node-version: [18.x]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
|
@ -6,12 +6,23 @@ So you want to help? That's great!
|
||||
|
||||
Here are a few things to know to get you started on the right path.
|
||||
|
||||
Below link will help you making a copy of the repository in your local system.
|
||||
|
||||
https://docs.github.com/en/get-started/quickstart/fork-a-repo
|
||||
|
||||
## Requirements
|
||||
|
||||
- [volta](https://volta.sh/) to manage node versions.
|
||||
- [Node.js](https://nodejs.org/en/). `volta install node`
|
||||
- [pnpm](https://pnpm.io/) package manager. `volta install pnpm`
|
||||
|
||||
## Development Installation
|
||||
|
||||
```bash
|
||||
git clone git@github.com:mermaid-js/mermaid.git
|
||||
cd mermaid
|
||||
pnpm install
|
||||
# npx is required for first install as volta support for pnpm is not added yet.
|
||||
npx pnpm install
|
||||
pnpm test
|
||||
```
|
||||
|
||||
@ -39,16 +50,16 @@ Less strict here, it is OK to commit directly in the `develop` branch if you are
|
||||
|
||||
The documentation is written in **Markdown**. For more information about Markdown [see the GitHub Markdown help page](https://help.github.com/en/github/writing-on-github/basic-writing-and-formatting-syntax).
|
||||
|
||||
### Documentation source files are in /src/docs
|
||||
### Documentation source files are in [`/packages/mermaid/src/docs`](packages/mermaid/src/docs)
|
||||
|
||||
The source files for the project documentation are located in the `/src/docs` directory. This is where you should make changes.
|
||||
The files under `/src/docs` are processed to generate the published documentation, and the resulting files are put into the `/docs` directory.
|
||||
The source files for the project documentation are located in the [`/packages/mermaid/src/docs`](packages/mermaid/src/docs) directory. This is where you should make changes.
|
||||
The files under `/packages/mermaid/src/docs` are processed to generate the published documentation, and the resulting files are put into the `/docs` directory.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
classDef default fill:#fff,color:black,stroke:black
|
||||
|
||||
source["files in /src/docs\n(changes should be done here)"] -- automatic processing\nto generate the final documentation--> published["files in /docs\ndisplayed on the official documentation site"]
|
||||
source["files in /packages/mermaid/src/docs\n(changes should be done here)"] -- automatic processing\nto generate the final documentation--> published["files in /docs\ndisplayed on the official documentation site"]
|
||||
|
||||
```
|
||||
|
||||
@ -137,7 +148,7 @@ it('should render forks and joins', () => {
|
||||
|
||||
Finally, if it is not in the documentation, no one will know about it and then **no one will use it**. Wouldn't that be sad? With all the effort that was put into the feature?
|
||||
|
||||
The source files for documentation are in `/src/docs` and are written in markdown. Just pick the right section and start typing. See the [Committing Documentation](#committing-documentation) section for more about how the documentation is generated.
|
||||
The source files for documentation are in `/packages/mermaid/src/docs` and are written in markdown. Just pick the right section and start typing. See the [Committing Documentation](#committing-documentation) section for more about how the documentation is generated.
|
||||
|
||||
#### Adding to or changing the documentation organization
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
# mermaid [![Build Status](https://travis-ci.org/mermaid-js/mermaid.svg?branch=master)](https://travis-ci.org/mermaid-js/mermaid) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE)
|
||||
# mermaid
|
||||
|
||||
# Whoa, whats going on here?
|
||||
[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
|
||||
|
||||
# Whoa, what's going on here?
|
||||
|
||||
We are transforming the Mermaid repository to a so called mono-repo. This is a part of the effort to decouple the diagrams from the core of mermaid. This will:
|
||||
|
||||
|
@ -1,4 +1,6 @@
|
||||
# mermaid [![Build Status](https://travis-ci.org/mermaid-js/mermaid.svg?branch=master)](https://travis-ci.org/mermaid-js/mermaid) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE)
|
||||
# mermaid
|
||||
|
||||
[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
|
||||
|
||||
[English](./README.md) | 简体中文
|
||||
|
||||
|
@ -1,3 +1 @@
|
||||
import { vi } from 'vitest';
|
||||
|
||||
// export const render = vi.fn();
|
||||
// DO NOT delete this file. It is used by vitest to mock the dagre-d3 module.
|
||||
|
@ -52,7 +52,8 @@
|
||||
"Ashish",
|
||||
"bbox",
|
||||
"techn",
|
||||
"cytoscape"
|
||||
"cytoscape",
|
||||
"ts-nocheck"
|
||||
],
|
||||
"patterns": [
|
||||
{
|
||||
|
14
cypress/platform/sidv.html
Normal file
14
cypress/platform/sidv.html
Normal file
@ -0,0 +1,14 @@
|
||||
<html>
|
||||
<body>
|
||||
<pre class="mermaid">
|
||||
none
|
||||
hello world
|
||||
</pre>
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
mermaid.initialize({
|
||||
logLevel: 1,
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -93,7 +93,7 @@
|
||||
throw new Error('XSS Succeeded');
|
||||
}
|
||||
|
||||
var diagram = 'classDiagram\n';
|
||||
let diagram = 'classDiagram\n';
|
||||
diagram += 'class Square~<img/src';
|
||||
diagram += "='1'/onerror=xssAttack()>~{\n";
|
||||
diagram += 'id A\n';
|
||||
|
@ -93,7 +93,7 @@
|
||||
throw new Error('XSS Succeeded');
|
||||
}
|
||||
|
||||
var diagram = 'stateDiagram-v2\n';
|
||||
let diagram = 'stateDiagram-v2\n';
|
||||
diagram += 's2 : This is a state description<img/src';
|
||||
diagram += "='1'/onerror=xssAttack()>";
|
||||
|
||||
|
@ -93,7 +93,7 @@
|
||||
throw new Error('XSS Succeeded');
|
||||
}
|
||||
|
||||
var diagram = 'stateDiagram-v2\n';
|
||||
let diagram = 'stateDiagram-v2\n';
|
||||
diagram += 's2 : A<img/src';
|
||||
diagram += "='1'/onerror=xssAttack()>";
|
||||
|
||||
|
@ -93,7 +93,7 @@
|
||||
throw new Error('XSS Succeeded');
|
||||
}
|
||||
|
||||
var diagram = 'stateDiagram-v2\n';
|
||||
let diagram = 'stateDiagram-v2\n';
|
||||
diagram += 'if_state --> False: if n < 0<img/src';
|
||||
diagram += "='1'/onerror=xssAttack()>";
|
||||
|
||||
|
@ -93,7 +93,7 @@
|
||||
throw new Error('XSS Succeeded');
|
||||
}
|
||||
|
||||
var diagram = 'classDiagram\n';
|
||||
let diagram = 'classDiagram\n';
|
||||
diagram += 'classA <-- classB : <ifr';
|
||||
diagram += "ame/srcdoc='<scr";
|
||||
diagram += 'ipt>parent.xssAttack(`XSS`)</';
|
||||
|
@ -93,7 +93,7 @@
|
||||
throw new Error('XSS Succeeded');
|
||||
}
|
||||
|
||||
var diagram = `sequenceDiagram
|
||||
let diagram = `sequenceDiagram
|
||||
participant John
|
||||
links John: {"XSS": "javas`;
|
||||
diagram += `cript:alert('AudioParam')"}`;
|
||||
|
@ -93,7 +93,7 @@
|
||||
throw new Error('XSS Succeeded');
|
||||
}
|
||||
|
||||
var diagram = `sequenceDiagram
|
||||
let diagram = `sequenceDiagram
|
||||
participant Alice
|
||||
links Alice: { "Click me!" : "javasjavascript:cript:alert('goose')" }`;
|
||||
|
||||
|
@ -93,7 +93,7 @@
|
||||
throw new Error('XSS Succeeded');
|
||||
}
|
||||
|
||||
var diagram = `sequenceDiagram
|
||||
let diagram = `sequenceDiagram
|
||||
participant Alice
|
||||
link Alice: Click Me!@javasjavascript:cript:alert("goose")`;
|
||||
|
||||
|
@ -93,7 +93,7 @@
|
||||
throw new Error('XSS Succeeded');
|
||||
}
|
||||
|
||||
var diagram = `classDiagram
|
||||
let diagram = `classDiagram
|
||||
Class "<img/src='x'/onerror=xssAttack(1)>" <--> "<img/src='x'/onerror=xssAttack(2)>" C2: Cool label`;
|
||||
|
||||
// // var diagram = "stateDiagram-v2\n";
|
||||
|
@ -93,7 +93,7 @@
|
||||
throw new Error('XSS Succeeded');
|
||||
}
|
||||
|
||||
var diagram = `classDiagram
|
||||
let diagram = `classDiagram
|
||||
class Shape{
|
||||
<<<img/src='1'/`;
|
||||
|
||||
|
@ -54,9 +54,9 @@
|
||||
startOnLoad: true,
|
||||
useMaxWidth: true,
|
||||
});
|
||||
var cnt = 0;
|
||||
var a;
|
||||
var handler = setInterval(() => {
|
||||
let cnt = 0;
|
||||
let a;
|
||||
const handler = setInterval(() => {
|
||||
cnt++;
|
||||
a = {};
|
||||
if (typeof a.polluted !== 'undefined') {
|
||||
|
@ -96,7 +96,7 @@
|
||||
// var diagram = ` graph TD
|
||||
// A --> B["<a href='javasc`;
|
||||
// diagram += `ript#colon;xssAttack()'>AAA</a>"]`;
|
||||
var diagram = ` graph TD
|
||||
let diagram = ` graph TD
|
||||
A --> B["<a href='javasc`;
|
||||
diagram += `ript#colon;xssAttack()'>AAA</a>"]`;
|
||||
// diagram += '//via.placeholder.com/64\' width=64 />"]';
|
||||
|
@ -96,7 +96,7 @@
|
||||
// var diagram = ` graph TD
|
||||
// A --> B["<a href='javascript`;
|
||||
// diagram += `ript#colon;xssAttack()'>AAA</a>"]`;
|
||||
var diagram = ` graph TD
|
||||
let diagram = ` graph TD
|
||||
A --> B["<a href='javasc`;
|
||||
diagram += `ript#9;t#colon;xssAttack()'>AAA</a>"]`;
|
||||
// diagram += '//via.placeholder.com/64\' width=64 />"]';
|
||||
|
@ -42,9 +42,9 @@
|
||||
startOnLoad: true,
|
||||
useMaxWidth: true,
|
||||
});
|
||||
var cnt = 0;
|
||||
var a;
|
||||
var handler = setInterval(() => {
|
||||
let cnt = 0;
|
||||
let a;
|
||||
const handler = setInterval(() => {
|
||||
cnt++;
|
||||
a = {};
|
||||
if (typeof a.polluted !== 'undefined') {
|
||||
|
@ -85,7 +85,7 @@
|
||||
alert('It worked');
|
||||
}
|
||||
|
||||
var diagram = '%%{init: {"flowchart": {"htmlLabels": "true"}} }%%\n';
|
||||
let diagram = '%%{init: {"flowchart": {"htmlLabels": "true"}} }%%\n';
|
||||
diagram += 'flowchart\n';
|
||||
diagram += 'A["<ifra';
|
||||
diagram += "me srcdoc='<scrip";
|
||||
|
@ -92,7 +92,7 @@
|
||||
document.getElementsByTagName('body')[0].appendChild(div);
|
||||
throw new Error('XSS Succeeded');
|
||||
}
|
||||
var diagram = 'graph LR\n';
|
||||
let diagram = 'graph LR\n';
|
||||
diagram += 'B-->D("<img onerror=location=`java';
|
||||
// diagram += "script\u003aalert\u0028document.domain\u0029\` src=x>\"\);\n";
|
||||
diagram += 'script\x3a;xssAttack\u0028\u0029` src=x>");\n';
|
||||
|
@ -92,7 +92,7 @@
|
||||
document.getElementsByTagName('body')[0].appendChild(div);
|
||||
throw new Error('XSS Succeeded');
|
||||
}
|
||||
var diagram = 'graph LR\n';
|
||||
let diagram = 'graph LR\n';
|
||||
diagram += 'A(<img/src/onerror=xssAttack`1`>)';
|
||||
// diagram += "script\u003aalert\u0028document.domain\u0029\` src=x>\"\);\n";
|
||||
console.log(diagram);
|
||||
|
@ -92,7 +92,7 @@
|
||||
document.getElementsByTagName('body')[0].appendChild(div);
|
||||
throw new Error('XSS Succeeded');
|
||||
}
|
||||
var diagram = 'graph LR\n';
|
||||
let diagram = 'graph LR\n';
|
||||
diagram += " B(<a href='<";
|
||||
diagram += 'script></';
|
||||
diagram += "script>Javascript:xssAttack`1`'>Click)";
|
||||
|
@ -93,7 +93,7 @@
|
||||
throw new Error('XSS Succeeded');
|
||||
}
|
||||
|
||||
var diagram = 'stateDiagram-v2\n';
|
||||
let diagram = 'stateDiagram-v2\n';
|
||||
diagram += "<img/src='1'/onerror=xssAttack()> --> B";
|
||||
// diagram += "script\u003aalert\u0028document.domain\u0029\` src=x>\"\);\n";
|
||||
console.log(diagram);
|
||||
|
@ -93,7 +93,7 @@
|
||||
throw new Error('XSS Succeeded');
|
||||
}
|
||||
|
||||
var diagram = 'stateDiagram-v2\n';
|
||||
let diagram = 'stateDiagram-v2\n';
|
||||
diagram += "<img/src='1'/onerror=xssAttack()> --> B";
|
||||
// diagram += "script\u003aalert\u0028document.domain\u0029\` src=x>\"\);\n";
|
||||
console.log(diagram);
|
||||
|
@ -277,7 +277,7 @@
|
||||
<script>
|
||||
function testClick(nodeId) {
|
||||
console.log('clicked', nodeId);
|
||||
var originalBgColor = document.querySelector('body').style.backgroundColor;
|
||||
let originalBgColor = document.querySelector('body').style.backgroundColor;
|
||||
document.querySelector('body').style.backgroundColor = 'yellow';
|
||||
setTimeout(function () {
|
||||
document.querySelector('body').style.backgroundColor = originalBgColor;
|
||||
|
@ -46,7 +46,7 @@
|
||||
<script>
|
||||
function testClick(nodeId) {
|
||||
console.log('clicked', nodeId);
|
||||
var originalBgColor = document.querySelector('body').style.backgroundColor;
|
||||
let originalBgColor = document.querySelector('body').style.backgroundColor;
|
||||
document.querySelector('body').style.backgroundColor = 'yellow';
|
||||
setTimeout(function () {
|
||||
document.querySelector('body').style.backgroundColor = originalBgColor;
|
||||
|
@ -1513,7 +1513,7 @@
|
||||
<script>
|
||||
function testClick(nodeId) {
|
||||
console.log('clicked', nodeId);
|
||||
var originalBgColor = document.querySelector('body').style.backgroundColor;
|
||||
let originalBgColor = document.querySelector('body').style.backgroundColor;
|
||||
document.querySelector('body').style.backgroundColor = 'yellow';
|
||||
setTimeout(function () {
|
||||
document.querySelector('body').style.backgroundColor = originalBgColor;
|
||||
|
@ -174,7 +174,7 @@
|
||||
}
|
||||
function testClick(nodeId) {
|
||||
console.log('clicked', nodeId);
|
||||
var originalBgColor = document.querySelector('body').style.backgroundColor;
|
||||
let originalBgColor = document.querySelector('body').style.backgroundColor;
|
||||
document.querySelector('body').style.backgroundColor = 'yellow';
|
||||
setTimeout(function () {
|
||||
document.querySelector('body').style.backgroundColor = originalBgColor;
|
||||
|
@ -10,7 +10,7 @@ It is a JavaScript based diagramming and charting tool that renders Markdown-ins
|
||||
|
||||
<img src="img/header.png" alt="" />
|
||||
|
||||
[![Build Status](https://travis-ci.org/mermaid-js/mermaid.svg?branch=master)](https://travis-ci.org/mermaid-js/mermaid) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE)
|
||||
[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
|
||||
|
||||
<!-- Mermaid book banner -->
|
||||
|
||||
@ -271,16 +271,16 @@ To Deploy Mermaid:
|
||||
|
||||
### [Mermaid API](./Setup.md):
|
||||
|
||||
**To deploy mermaid without a bundler, one can insert a `script` tag with an absolute address and a `mermaidAPI` call into the HTML like so:**
|
||||
**To deploy mermaid without a bundler, one can insert a `script` tag with an absolute address and a `mermaid.initialize` call into the HTML like so:**
|
||||
|
||||
```html
|
||||
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
|
||||
<script>
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@9/dist/mermaid.esm.min.mjs';
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
```
|
||||
|
||||
**Doing so will command the mermaid parser to look for the `<div>` tags with `class="mermaid"`. From these tags mermaid will try to read the diagram/chart definitions and render them into SVG charts.**
|
||||
**Doing so will command the mermaid parser to look for the `<div>` or `<pre>` tags with `class="mermaid"`. From these tags mermaid will try to read the diagram/chart definitions and render them into SVG charts.**
|
||||
|
||||
**Examples can be found at** [Other examples](/examples)
|
||||
|
||||
|
@ -1561,7 +1561,7 @@ Returns **void**
|
||||
|
||||
```html
|
||||
<script>
|
||||
var config = {
|
||||
const config = {
|
||||
theme: 'default',
|
||||
logLevel: 'fatal',
|
||||
securityLevel: 'strict',
|
||||
|
@ -589,7 +589,7 @@ click Shape2 call callbackFunction() "This is a tooltip for a callback"
|
||||
|
||||
```html
|
||||
<script>
|
||||
var callbackFunction = function () {
|
||||
const callbackFunction = function () {
|
||||
alert('A callback was triggered');
|
||||
};
|
||||
</script>
|
||||
@ -653,10 +653,10 @@ Beginner's tip—a full example using interactive links in an HTML page:
|
||||
</pre>
|
||||
|
||||
<script>
|
||||
var callback = function () {
|
||||
const callback = function () {
|
||||
alert('A callback was triggered');
|
||||
};
|
||||
var config = {
|
||||
const config = {
|
||||
startOnLoad: true,
|
||||
securityLevel: 'loose',
|
||||
};
|
||||
|
@ -649,7 +649,7 @@ A node can have click events bound that lead to either a JavaScript callback or
|
||||
|
||||
```html
|
||||
<script>
|
||||
var callback = function (nodeId) {
|
||||
const callback = function (nodeId) {
|
||||
alert('A callback was triggered on ' + nodeId);
|
||||
};
|
||||
</script>
|
||||
@ -727,10 +727,10 @@ Beginner's tip—here's a full example of using interactive links in HTML:
|
||||
</pre>
|
||||
|
||||
<script>
|
||||
var callback = function () {
|
||||
const callback = function () {
|
||||
alert('A callback was triggered');
|
||||
};
|
||||
var config = {
|
||||
const config = {
|
||||
startOnLoad: true,
|
||||
flowchart: {
|
||||
useMaxWidth: true,
|
||||
|
@ -315,13 +315,13 @@ flowchart LR
|
||||
### Dotted link
|
||||
|
||||
```mermaid-example
|
||||
flowchart LR;
|
||||
A-.->B;
|
||||
flowchart LR
|
||||
A-.->B
|
||||
```
|
||||
|
||||
```mermaid
|
||||
flowchart LR;
|
||||
A-.->B;
|
||||
flowchart LR
|
||||
A-.->B
|
||||
```
|
||||
|
||||
### Dotted link with text
|
||||
@ -695,7 +695,7 @@ Examples of tooltip usage below:
|
||||
|
||||
```html
|
||||
<script>
|
||||
var callback = function () {
|
||||
const callback = function () {
|
||||
alert('A callback was triggered');
|
||||
};
|
||||
</script>
|
||||
@ -771,10 +771,10 @@ Beginner's tip—a full example using interactive links in a html context:
|
||||
</pre>
|
||||
|
||||
<script>
|
||||
var callback = function () {
|
||||
const callback = function () {
|
||||
alert('A callback was triggered');
|
||||
};
|
||||
var config = {
|
||||
const config = {
|
||||
startOnLoad: true,
|
||||
flowchart: { useMaxWidth: true, htmlLabels: true, curve: 'cardinal' },
|
||||
securityLevel: 'loose',
|
||||
@ -866,13 +866,13 @@ A shorter form of adding a class is to attach the classname to the node using th
|
||||
```mermaid-example
|
||||
flowchart LR
|
||||
A:::someclass --> B
|
||||
classDef someclass fill:#f96;
|
||||
classDef someclass fill:#f96
|
||||
```
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A:::someclass --> B
|
||||
classDef someclass fill:#f96;
|
||||
classDef someclass fill:#f96
|
||||
```
|
||||
|
||||
### Css classes
|
||||
@ -895,14 +895,14 @@ below:
|
||||
**Example definition**
|
||||
|
||||
```mermaid-example
|
||||
flowchart LR;
|
||||
flowchart LR
|
||||
A-->B[AAA<span>BBB</span>]
|
||||
B-->D
|
||||
class A cssClass
|
||||
```
|
||||
|
||||
```mermaid
|
||||
flowchart LR;
|
||||
flowchart LR
|
||||
A-->B[AAA<span>BBB</span>]
|
||||
B-->D
|
||||
class A cssClass
|
||||
@ -924,7 +924,7 @@ The icons are accessed via the syntax fa:#icon class name#.
|
||||
flowchart TD
|
||||
B["fab:fa-twitter for peace"]
|
||||
B-->C[fa:fa-ban forbidden]
|
||||
B-->D(fa:fa-spinner);
|
||||
B-->D(fa:fa-spinner)
|
||||
B-->E(A fa:fa-camera-retro perhaps?)
|
||||
```
|
||||
|
||||
@ -932,7 +932,7 @@ flowchart TD
|
||||
flowchart TD
|
||||
B["fab:fa-twitter for peace"]
|
||||
B-->C[fa:fa-ban forbidden]
|
||||
B-->D(fa:fa-spinner);
|
||||
B-->D(fa:fa-spinner)
|
||||
B-->E(A fa:fa-camera-retro perhaps?)
|
||||
```
|
||||
|
||||
|
@ -391,13 +391,13 @@ Beginner's tip—a full example using interactive links in an html context:
|
||||
</pre>
|
||||
|
||||
<script>
|
||||
var printArguments = function (arg1, arg2, arg3) {
|
||||
const printArguments = function (arg1, arg2, arg3) {
|
||||
alert('printArguments called with arguments: ' + arg1 + ', ' + arg2 + ', ' + arg3);
|
||||
};
|
||||
var printTask = function (taskId) {
|
||||
const printTask = function (taskId) {
|
||||
alert('taskId: ' + taskId);
|
||||
};
|
||||
var config = {
|
||||
const config = {
|
||||
startOnLoad: true,
|
||||
securityLevel: 'loose',
|
||||
};
|
||||
|
@ -21,21 +21,34 @@
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css"
|
||||
/>
|
||||
<script src="//cdn.jsdelivr.net/npm/mermaid@9.1.7/dist/mermaid.min.js"></script>
|
||||
<!-- <script src="http://localhost:9000/mermaid.js"></script> -->
|
||||
<script
|
||||
defer=""
|
||||
data-domain="mermaid-js.github.io"
|
||||
src="https://plausible.io/js/plausible.js"
|
||||
></script>
|
||||
<script>
|
||||
var require = {
|
||||
paths: { vs: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.29.1/min/vs' },
|
||||
const require = {
|
||||
paths: { vs: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.0/min/vs' },
|
||||
};
|
||||
</script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.29.1/min/vs/loader.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.29.1/min/vs/editor/editor.main.nls.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.29.1/min/vs/editor/editor.main.js"></script>
|
||||
<script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.0/min/vs/loader.min.js"
|
||||
integrity="sha512-6bIYsGqvLpAiEBXPdRQeFf5cueeBECtAKJjIHer3BhBZNTV3WLcLA8Tm3pDfxUwTMIS+kAZwTUvJ1IrMdX8C5w=="
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
></script>
|
||||
<script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.0/min/vs/editor/editor.main.nls.min.js"
|
||||
integrity="sha512-CCv+DKWw+yZhxf4Z+ExT6HC5G+3S45TeMTYcJyYbdrv4BpK2vyALJ4FoVR/KGWDIPu7w4tNCOC9MJQIkYPR5FA=="
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
></script>
|
||||
<script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.0/min/vs/editor/editor.main.min.js"
|
||||
integrity="sha512-iVHvVf6TQEoF5oQrocjP88wstImQHQZCxGsa5nKYOs6gXWzsV7QZHyk80HrXhrEWRJ1ADoIV6Uji3UUXtCmBMg=="
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
></script>
|
||||
<script>
|
||||
exports = {};
|
||||
</script>
|
||||
@ -50,17 +63,22 @@
|
||||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@9/dist/mermaid.esm.min.mjs';
|
||||
window.mermaid = mermaid;
|
||||
</script>
|
||||
<script>
|
||||
var initEditor = exports.default;
|
||||
var parser = new DOMParser();
|
||||
var currentCodeExample = 0;
|
||||
var colorize = [];
|
||||
let initEditor = exports.default;
|
||||
let parser = new DOMParser();
|
||||
let currentCodeExample = 0;
|
||||
let colorize = [];
|
||||
let num = 0;
|
||||
|
||||
function colorizeEverything(html) {
|
||||
initEditor(monaco);
|
||||
return new Promise((resolve, reject) => {
|
||||
monaco.editor.setTheme('mermaid');
|
||||
var parsed = parser.parseFromString(html, 'text/html').body;
|
||||
const parsed = parser.parseFromString(html, 'text/html').body;
|
||||
Promise.all(
|
||||
[...parsed.querySelectorAll('pre[id*="code"]')].map((codeBlock) =>
|
||||
monaco.editor.colorize(codeBlock.innerText, 'mermaid')
|
||||
@ -99,6 +117,7 @@
|
||||
colorize.push(currentCodeExample);
|
||||
return '<pre id="code' + currentCodeExample + '">' + escapeHTML(code) + '</pre>';
|
||||
} else if (lang === 'mermaid') {
|
||||
// TODO: This will need to be updated when render is async.
|
||||
return (
|
||||
'<pre class="mermaid">' + mermaid.render('mermaid-svg-' + num++, code) + '</pre>'
|
||||
);
|
||||
@ -117,7 +136,7 @@
|
||||
function (hook, vm) {
|
||||
hook.beforeEach(function (html) {
|
||||
url = 'https://github.com/mermaid-js/mermaid/blob/develop/src/docs/' + vm.route.file;
|
||||
var editHtml = '[:memo: Edit this Page](' + url + ')\n';
|
||||
const editHtml = '[:memo: Edit this Page](' + url + ')\n';
|
||||
return editHtml + html;
|
||||
});
|
||||
|
||||
@ -136,7 +155,6 @@
|
||||
],
|
||||
};
|
||||
|
||||
var num = 0;
|
||||
const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
|
||||
const conf = {
|
||||
|
@ -75,23 +75,13 @@ The API works by pulling rendering instructions from the source `mermaid.js` in
|
||||
|
||||
### Requirements for the Mermaid API.
|
||||
|
||||
When writing the .html file, we give three instructions inside the html code to the web browser:
|
||||
When writing the .html file, we give two instructions inside the html code to the web browser:
|
||||
|
||||
a. A reference for fetching the online mermaid renderer, through the `mermaid.js` or `mermaid.min.js`.
|
||||
a. The mermaid code for the diagram we want to create.
|
||||
|
||||
b. The mermaid code for the diagram we want to create.
|
||||
b. The importing of mermaid library through the `mermaid.esm.js` or `mermaid.esm.min.mjs` and the `mermaid.initialize()` call, which dictates the appearance of diagrams and also starts the rendering process .
|
||||
|
||||
c. The `mermaid.initialize()` call, which dictates the appearance of diagrams and also starts the rendering process .
|
||||
|
||||
**a. A reference to the external CDN in a `<script src>` tag, or a reference to mermaid.js as a separate file.:**
|
||||
|
||||
```html
|
||||
<body>
|
||||
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
|
||||
</body>
|
||||
```
|
||||
|
||||
**b. The embedded mermaid diagram definition inside a `<pre class="mermaid">`:**
|
||||
**a. The embedded mermaid diagram definition inside a `<pre class="mermaid">`:**
|
||||
|
||||
```html
|
||||
<body>
|
||||
@ -107,13 +97,14 @@ c. The `mermaid.initialize()` call, which dictates the appearance of diagrams an
|
||||
|
||||
**Notes**: Every Mermaid chart/graph/diagram definition, should have separate `<pre>` tags.
|
||||
|
||||
**c. The `mermaid.initialize()` call.**
|
||||
**b. The import of mermaid and the `mermaid.initialize()` call.**
|
||||
|
||||
`mermaid.initialize()` call takes all the definitions contained in all the `<pre class="mermaid">` tags that it finds in the html body and renders them into diagrams. Example:
|
||||
|
||||
```html
|
||||
<body>
|
||||
<script>
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@9/dist/mermaid.esm.min.mjs';
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
</body>
|
||||
@ -135,11 +126,6 @@ Rendering in Mermaid is initialized by `mermaid.initialize()` call. You can plac
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
|
||||
<script>
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
|
||||
Here is one mermaid diagram:
|
||||
<pre class="mermaid">
|
||||
graph TD
|
||||
@ -156,6 +142,11 @@ Rendering in Mermaid is initialized by `mermaid.initialize()` call. You can plac
|
||||
B -->|tcp_456| C[Server1]
|
||||
B -->|tcp_456| D[Server2]
|
||||
</pre>
|
||||
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@9/dist/mermaid.esm.min.mjs';
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@ -181,8 +172,8 @@ In this example mermaid.js is referenced in `src` as a separate JavaScript file,
|
||||
B --> C[Server1]
|
||||
B --> D[Server2]
|
||||
</pre>
|
||||
<script src="The\Path\In\Your\Package\mermaid.js"></script>
|
||||
<script>
|
||||
<script type="module">
|
||||
import mermaid from 'The/Path/In/Your/Package/mermaid.esm.mjs';
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
</body>
|
||||
@ -206,4 +197,4 @@ In this example mermaid.js is referenced in `src` as a separate JavaScript file,
|
||||
|
||||
**Comments from Knut Sveidqvist, creator of mermaid:**
|
||||
|
||||
- In early versions of mermaid, the `<script src>` tag was invoked in the `<head>` part of the web page. Nowadays we can place it in the `<body>` as seen above. Older parts of the documentation frequently reflects the previous way which still works.
|
||||
- In early versions of mermaid, the `<script>` tag was invoked in the `<head>` part of the web page. Nowadays we can place it in the `<body>` as seen above. Older parts of the documentation frequently reflects the previous way which still works.
|
||||
|
@ -39,23 +39,9 @@ We have compiled some Video [Tutorials](./Tutorials.md) on how to use the mermai
|
||||
|
||||
> Note:This topic explored in greater depth in the [User Guide for Beginners](./n00b-gettingStarted.md)
|
||||
|
||||
The easiest way to integrate mermaid on a web page requires three elements:
|
||||
The easiest way to integrate mermaid on a web page requires two elements:
|
||||
|
||||
1. Inclusion of the mermaid address in the html page using a `script` tag, in the `src` section.Example:
|
||||
|
||||
```html
|
||||
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
|
||||
```
|
||||
|
||||
2. The `mermaidAPI` call, in a separate `script` tag. Example:
|
||||
|
||||
```html
|
||||
<script>
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
```
|
||||
|
||||
3. A graph definition, inside `<div>` tags labeled `class=mermaid`. Example:
|
||||
- A graph definition, inside `<pre>` tags labeled `class=mermaid`. Example:
|
||||
|
||||
```html
|
||||
<pre class="mermaid">
|
||||
@ -66,8 +52,18 @@ The easiest way to integrate mermaid on a web page requires three elements:
|
||||
</pre>
|
||||
```
|
||||
|
||||
**Following these directions, mermaid starts at page load and (when the page has loaded) it will
|
||||
locate the graph definitions inside the `div` tags with `class="mermaid"` and return diagrams in SVG form, following given definitions.**
|
||||
- Inclusion of the mermaid address in the html page body using a `script` tag as an ESM import, and the `mermaidAPI` call.
|
||||
|
||||
Example:
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@9/dist/mermaid.esm.min.mjs';
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
```
|
||||
|
||||
**Following these directions, mermaid starts at page load and (when the page has loaded) it will locate the graph definitions inside the `pre` tags with `class="mermaid"` and return diagrams in SVG form, following given definitions.**
|
||||
|
||||
## Simple full example:
|
||||
|
||||
@ -84,8 +80,8 @@ locate the graph definitions inside the `div` tags with `class="mermaid"` and re
|
||||
B-->C[fa:fa-ban forbidden]
|
||||
B-->D(fa:fa-spinner);
|
||||
</pre>
|
||||
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
|
||||
<script>
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@9/dist/mermaid.esm.min.mjs';
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
</body>
|
||||
@ -204,18 +200,17 @@ fetch the graph definition from the site (perhaps from a textarea), render it an
|
||||
The example below show an outline of how this could be used. The example just logs the resulting SVG to the JavaScript console.
|
||||
|
||||
```html
|
||||
<script src="mermaid.js"></script>
|
||||
|
||||
<script>
|
||||
<script type="module">
|
||||
import mermaid from './mermaid.mjs';
|
||||
mermaid.mermaidAPI.initialize({ startOnLoad: false });
|
||||
$(function () {
|
||||
$(async function () {
|
||||
// Example of using the API var
|
||||
element = document.querySelector('#graphDiv');
|
||||
var insertSvg = function (svgCode, bindFunctions) {
|
||||
const insertSvg = function (svgCode, bindFunctions) {
|
||||
element.innerHTML = svgCode;
|
||||
};
|
||||
var graphDefinition = 'graph TB\na-->b';
|
||||
var graph = mermaid.mermaidAPI.render('graphDiv', graphDefinition, insertSvg);
|
||||
const graphDefinition = 'graph TB\na-->b';
|
||||
const graph = await mermaid.mermaidAPI.render('graphDiv', graphDefinition, insertSvg);
|
||||
});
|
||||
</script>
|
||||
```
|
||||
@ -339,7 +334,7 @@ on what kind of integration you use.
|
||||
```html
|
||||
<script src="../dist/mermaid.js"></script>
|
||||
<script>
|
||||
var config = { startOnLoad: true, flowchart: { useMaxWidth: false, htmlLabels: true } };
|
||||
let config = { startOnLoad: true, flowchart: { useMaxWidth: false, htmlLabels: true } };
|
||||
mermaid.initialize(config);
|
||||
</script>
|
||||
```
|
||||
|
151
package.json
151
package.json
@ -7,7 +7,7 @@
|
||||
"module": "dist/mermaid.core.mjs",
|
||||
"types": "dist/mermaid.d.ts",
|
||||
"type": "module",
|
||||
"packageManager": "pnpm@7.13.2",
|
||||
"packageManager": "pnpm@7.13.5",
|
||||
"exports": {
|
||||
".": {
|
||||
"require": "./dist/mermaid.min.js",
|
||||
@ -30,7 +30,7 @@
|
||||
"build:types": "concurrently \"tsc -p ./packages/mermaid/tsconfig.json --emitDeclarationOnly\" \"tsc -p ./packages/mermaid-mindmap/tsconfig.json --emitDeclarationOnly\"",
|
||||
"build:watch": "pnpm build:vite --watch",
|
||||
"build": "pnpm run -r clean && concurrently \"pnpm build:vite\" \"pnpm build:types\"",
|
||||
"dev": "concurrently \"pnpm build:vite --watch\" \"ts-node-esm .vite/server\"",
|
||||
"dev": "concurrently \"pnpm build:vite --watch\" \"ts-node-esm .vite/server.ts\"",
|
||||
"docs:build": "ts-node-esm --transpileOnly packages/mermaid/src/docs.mts",
|
||||
"docs:verify": "pnpm docs:build --verify",
|
||||
"todo-postbuild": "documentation build src/mermaidAPI.ts src/config.ts src/defaultConfig.ts --shallow -f md --markdown-toc false > src/docs/Setup.md && prettier --write src/docs/Setup.md",
|
||||
@ -47,7 +47,8 @@
|
||||
"e2e": "start-server-and-test dev http://localhost:9000/ cypress",
|
||||
"ci": "vitest run",
|
||||
"test": "pnpm lint && vitest run",
|
||||
"test:watch": "vitest --coverage --watch",
|
||||
"test:watch": "vitest --watch",
|
||||
"test:coverage": "vitest --coverage",
|
||||
"prepublishOnly": "pnpm build && pnpm test",
|
||||
"prepare": "concurrently \"husky install\" \"pnpm build\"",
|
||||
"pre-commit": "lint-staged"
|
||||
@ -69,81 +70,82 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@braintree/sanitize-url": "^6.0.0",
|
||||
"@types/node": "^18.8.1",
|
||||
"@types/uuid": "^8.3.4",
|
||||
"d3": "^7.0.0",
|
||||
"dagre": "^0.8.5",
|
||||
"dagre-d3": "^0.6.4",
|
||||
"@braintree/sanitize-url": "6.0.0",
|
||||
"@types/node": "18.11.0",
|
||||
"@types/uuid": "8.3.4",
|
||||
"d3": "7.6.1",
|
||||
"dagre": "0.8.5",
|
||||
"dagre-d3": "0.6.4",
|
||||
"dompurify": "2.4.0",
|
||||
"fast-clone": "^1.5.13",
|
||||
"graphlib": "^2.1.8",
|
||||
"khroma": "^2.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
"moment-mini": "^2.24.0",
|
||||
"non-layered-tidy-tree-layout": "^2.0.2",
|
||||
"rollup": "^2.79.1",
|
||||
"stylis": "^4.1.2",
|
||||
"uuid": "^9.0.0"
|
||||
"fast-clone": "1.5.13",
|
||||
"graphlib": "2.1.8",
|
||||
"khroma": "2.0.0",
|
||||
"lodash": "4.17.21",
|
||||
"moment-mini": "2.29.4",
|
||||
"non-layered-tidy-tree-layout": "2.0.2",
|
||||
"rollup": "2.79.1",
|
||||
"stylis": "4.1.2",
|
||||
"uuid": "9.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@applitools/eyes-cypress": "^3.27.1",
|
||||
"@commitlint/cli": "^17.1.2",
|
||||
"@commitlint/config-conventional": "^17.1.0",
|
||||
"@applitools/eyes-cypress": "3.27.2",
|
||||
"@commitlint/cli": "17.1.2",
|
||||
"@commitlint/config-conventional": "17.1.0",
|
||||
"@cspell/eslint-plugin": "^6.12.0",
|
||||
"@types/d3": "^7.4.0",
|
||||
"@types/dompurify": "^2.3.4",
|
||||
"@types/eslint": "^8.4.6",
|
||||
"@types/express": "^4.17.14",
|
||||
"@types/jsdom": "^20.0.0",
|
||||
"@types/lodash": "^4.14.186",
|
||||
"@types/prettier": "^2.7.1",
|
||||
"@types/stylis": "^4.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^5.39.0",
|
||||
"@typescript-eslint/parser": "^5.39.0",
|
||||
"@vitest/coverage-c8": "^0.23.4",
|
||||
"@vitest/ui": "^0.23.4",
|
||||
"concurrently": "^7.4.0",
|
||||
"coveralls": "^3.1.1",
|
||||
"cypress": "^10.0.0",
|
||||
"cypress-image-snapshot": "^4.0.1",
|
||||
"documentation": "13.2.0",
|
||||
"esbuild": "^0.15.10",
|
||||
"eslint": "^8.24.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-cypress": "^2.12.1",
|
||||
"eslint-plugin-html": "^7.1.0",
|
||||
"eslint-plugin-jest": "^27.1.0",
|
||||
"eslint-plugin-jsdoc": "^39.3.6",
|
||||
"eslint-plugin-json": "^3.1.0",
|
||||
"eslint-plugin-markdown": "^3.0.0",
|
||||
"express": "^4.18.1",
|
||||
"globby": "^13.1.2",
|
||||
"husky": "^8.0.1",
|
||||
"identity-obj-proxy": "^3.0.0",
|
||||
"jest": "29.x",
|
||||
"jison": "^0.4.18",
|
||||
"jsdom": "^20.0.1",
|
||||
"lint-staged": "^13.0.3",
|
||||
"markdown-it": "^13.0.1",
|
||||
"path-browserify": "^1.0.1",
|
||||
"pnpm": "^7.13.2",
|
||||
"prettier": "^2.7.1",
|
||||
"prettier-plugin-jsdoc": "^0.4.2",
|
||||
"remark": "^14.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"start-server-and-test": "^1.14.0",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^4.8.4",
|
||||
"unist-util-flatmap": "^1.0.0",
|
||||
"vite": "^3.1.4",
|
||||
"vitepress": "^1.0.0-alpha.19",
|
||||
"vitepress-plugin-mermaid": "^2.0.8",
|
||||
"vitepress-plugin-search": "^1.0.4-alpha.11",
|
||||
"vitest": "^0.23.4"
|
||||
"@types/d3": "7.4.0",
|
||||
"@types/dompurify": "2.3.4",
|
||||
"@types/eslint": "8.4.6",
|
||||
"@types/express": "4.17.14",
|
||||
"@types/jsdom": "20.0.0",
|
||||
"@types/lodash": "4.14.186",
|
||||
"@types/mdast": "3.0.10",
|
||||
"@types/prettier": "2.7.1",
|
||||
"@types/stylis": "4.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "5.40.0",
|
||||
"@typescript-eslint/parser": "5.40.0",
|
||||
"@vitest/coverage-c8": "0.24.3",
|
||||
"@vitest/ui": "0.24.3",
|
||||
"concurrently": "7.4.0",
|
||||
"coveralls": "3.1.1",
|
||||
"cypress": "10.10.0",
|
||||
"cypress-image-snapshot": "4.0.1",
|
||||
"documentation": "13.2.5",
|
||||
"esbuild": "0.15.11",
|
||||
"eslint": "8.25.0",
|
||||
"eslint-config-prettier": "8.5.0",
|
||||
"eslint-plugin-cypress": "2.12.1",
|
||||
"eslint-plugin-html": "7.1.0",
|
||||
"eslint-plugin-jest": "27.1.2",
|
||||
"eslint-plugin-jsdoc": "39.3.6",
|
||||
"eslint-plugin-json": "3.1.0",
|
||||
"eslint-plugin-markdown": "3.0.0",
|
||||
"express": "4.18.2",
|
||||
"globby": "13.1.2",
|
||||
"husky": "8.0.1",
|
||||
"identity-obj-proxy": "3.0.0",
|
||||
"jest": "29.2.0",
|
||||
"jison": "0.4.18",
|
||||
"jsdom": "20.0.1",
|
||||
"lint-staged": "13.0.3",
|
||||
"markdown-it": "13.0.1",
|
||||
"path-browserify": "1.0.1",
|
||||
"pnpm": "7.13.5",
|
||||
"prettier": "2.7.1",
|
||||
"prettier-plugin-jsdoc": "0.4.2",
|
||||
"remark": "14.0.2",
|
||||
"rimraf": "3.0.2",
|
||||
"start-server-and-test": "1.14.0",
|
||||
"ts-node": "10.9.1",
|
||||
"typescript": "4.8.4",
|
||||
"unist-util-flatmap": "1.0.0",
|
||||
"vite": "3.1.8",
|
||||
"vitepress": "1.0.0-alpha.21",
|
||||
"vitepress-plugin-mermaid": "2.0.8",
|
||||
"vitepress-plugin-search": "1.0.4-alpha.11",
|
||||
"vitest": "0.24.3"
|
||||
},
|
||||
"resolutions": {
|
||||
"d3": "^7.0.0"
|
||||
"d3": "7.6.1"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
@ -151,5 +153,8 @@
|
||||
"sideEffects": [
|
||||
"**/*.css",
|
||||
"**/*.scss"
|
||||
]
|
||||
],
|
||||
"volta": {
|
||||
"node": "18.5.0"
|
||||
}
|
||||
}
|
||||
|
@ -50,8 +50,8 @@
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"concurrently": "^7.4.0",
|
||||
"rimraf": "^3.0.2"
|
||||
"concurrently": "7.4.0",
|
||||
"rimraf": "3.0.2"
|
||||
},
|
||||
"resolutions": {
|
||||
"d3": "^7.0.0"
|
||||
|
@ -57,8 +57,8 @@
|
||||
"non-layered-tidy-tree-layout": "^2.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"concurrently": "^7.4.0",
|
||||
"rimraf": "^3.0.2"
|
||||
"concurrently": "7.4.0",
|
||||
"rimraf": "3.0.2"
|
||||
},
|
||||
"resolutions": {
|
||||
"d3": "^7.0.0"
|
||||
|
@ -75,51 +75,51 @@
|
||||
"stylis": "^4.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@applitools/eyes-cypress": "^3.25.7",
|
||||
"@commitlint/cli": "^17.1.2",
|
||||
"@commitlint/config-conventional": "^17.0.0",
|
||||
"@types/d3": "^7.4.0",
|
||||
"@types/dompurify": "^2.3.4",
|
||||
"@types/eslint": "^8.4.6",
|
||||
"@types/express": "^4.17.13",
|
||||
"@types/jsdom": "^20.0.0",
|
||||
"@types/lodash": "^4.14.185",
|
||||
"@types/prettier": "^2.7.0",
|
||||
"@types/stylis": "^4.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^5.37.0",
|
||||
"@typescript-eslint/parser": "^5.37.0",
|
||||
"concurrently": "^7.4.0",
|
||||
"coveralls": "^3.1.1",
|
||||
"cypress": "^10.0.0",
|
||||
"cypress-image-snapshot": "^4.0.1",
|
||||
"documentation": "13.2.0",
|
||||
"esbuild": "^0.15.8",
|
||||
"eslint": "^8.23.1",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-cypress": "^2.12.1",
|
||||
"eslint-plugin-html": "^7.1.0",
|
||||
"eslint-plugin-jest": "^27.0.4",
|
||||
"eslint-plugin-jsdoc": "^39.3.6",
|
||||
"eslint-plugin-json": "^3.1.0",
|
||||
"eslint-plugin-markdown": "^3.0.0",
|
||||
"express": "^4.18.1",
|
||||
"globby": "^13.1.2",
|
||||
"husky": "^8.0.0",
|
||||
"identity-obj-proxy": "^3.0.0",
|
||||
"jison": "^0.4.18",
|
||||
"@applitools/eyes-cypress": "3.27.2",
|
||||
"@commitlint/cli": "17.1.2",
|
||||
"@commitlint/config-conventional": "17.1.0",
|
||||
"@types/d3": "7.4.0",
|
||||
"@types/dompurify": "2.3.4",
|
||||
"@types/eslint": "8.4.6",
|
||||
"@types/express": "4.17.14",
|
||||
"@types/jsdom": "20.0.0",
|
||||
"@types/lodash": "4.14.186",
|
||||
"@types/prettier": "2.7.1",
|
||||
"@types/stylis": "4.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "5.40.0",
|
||||
"@typescript-eslint/parser": "5.40.0",
|
||||
"concurrently": "7.4.0",
|
||||
"coveralls": "3.1.1",
|
||||
"cypress": "10.10.0",
|
||||
"cypress-image-snapshot": "4.0.1",
|
||||
"documentation": "13.2.5",
|
||||
"esbuild": "0.15.11",
|
||||
"eslint": "8.25.0",
|
||||
"eslint-config-prettier": "8.5.0",
|
||||
"eslint-plugin-cypress": "2.12.1",
|
||||
"eslint-plugin-html": "7.1.0",
|
||||
"eslint-plugin-jest": "27.1.2",
|
||||
"eslint-plugin-jsdoc": "39.3.6",
|
||||
"eslint-plugin-json": "3.1.0",
|
||||
"eslint-plugin-markdown": "3.0.0",
|
||||
"express": "4.18.2",
|
||||
"globby": "13.1.2",
|
||||
"husky": "8.0.1",
|
||||
"identity-obj-proxy": "3.0.0",
|
||||
"jison": "0.4.18",
|
||||
"js-base64": "3.7.2",
|
||||
"jsdom": "^20.0.0",
|
||||
"lint-staged": "^13.0.0",
|
||||
"moment": "^2.23.0",
|
||||
"path-browserify": "^1.0.1",
|
||||
"prettier": "^2.7.1",
|
||||
"prettier-plugin-jsdoc": "^0.4.2",
|
||||
"remark": "^14.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"start-server-and-test": "^1.12.6",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^4.8.3",
|
||||
"unist-util-flatmap": "^1.0.0"
|
||||
"jsdom": "20.0.1",
|
||||
"lint-staged": "13.0.3",
|
||||
"moment": "2.29.4",
|
||||
"path-browserify": "1.0.1",
|
||||
"prettier": "2.7.1",
|
||||
"prettier-plugin-jsdoc": "0.4.2",
|
||||
"remark": "14.0.2",
|
||||
"rimraf": "3.0.2",
|
||||
"start-server-and-test": "1.14.0",
|
||||
"ts-node": "10.9.1",
|
||||
"typescript": "4.8.4",
|
||||
"unist-util-flatmap": "1.0.0"
|
||||
},
|
||||
"resolutions": {
|
||||
"d3": "^7.0.0"
|
||||
|
@ -2,17 +2,26 @@ import * as configApi from './config';
|
||||
import { log } from './logger';
|
||||
import { getDiagram, registerDiagram } from './diagram-api/diagramAPI';
|
||||
import { detectType, getDiagramLoader } from './diagram-api/detectType';
|
||||
import { isDetailedError } from './utils';
|
||||
import { isDetailedError, type DetailedError } from './utils';
|
||||
|
||||
export type ParseErrorFunction = (err: string | DetailedError, hash?: any) => void;
|
||||
|
||||
export class Diagram {
|
||||
type = 'graph';
|
||||
parser;
|
||||
renderer;
|
||||
db;
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
constructor(public txt: string, parseError?: Function) {
|
||||
private detectTypeFailed = false;
|
||||
constructor(public txt: string, parseError?: ParseErrorFunction) {
|
||||
const cnf = configApi.getConfig();
|
||||
this.txt = txt;
|
||||
try {
|
||||
this.type = detectType(txt, cnf);
|
||||
} catch (e) {
|
||||
this.handleError(e, parseError);
|
||||
this.type = 'error';
|
||||
this.detectTypeFailed = true;
|
||||
}
|
||||
const diagram = getDiagram(this.type);
|
||||
log.debug('Type ' + this.type);
|
||||
// Setup diagram
|
||||
@ -30,31 +39,39 @@ export class Diagram {
|
||||
this.parse(this.txt, parseError);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
parse(text: string, parseError?: Function): boolean {
|
||||
parse(text: string, parseError?: ParseErrorFunction): boolean {
|
||||
if (this.detectTypeFailed) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
text = text + '\n';
|
||||
this.db.clear();
|
||||
this.parser.parse(text);
|
||||
return true;
|
||||
} catch (error) {
|
||||
this.handleError(error, parseError);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
handleError(error: unknown, parseError?: ParseErrorFunction) {
|
||||
// Is this the correct way to access mermiad's parseError()
|
||||
// method ? (or global.mermaid.parseError()) ?
|
||||
if (parseError) {
|
||||
if (isDetailedError(error)) {
|
||||
// handle case where error string and hash were
|
||||
// wrapped in object like`const error = { str, hash };`
|
||||
parseError(error.str, error.hash);
|
||||
} else {
|
||||
// assume it is just error string and pass it on
|
||||
parseError(error);
|
||||
}
|
||||
} else {
|
||||
|
||||
if (parseError === undefined) {
|
||||
// No mermaid.parseError() handler defined, so re-throw it
|
||||
throw error;
|
||||
}
|
||||
|
||||
if (isDetailedError(error)) {
|
||||
// Handle case where error string and hash were
|
||||
// wrapped in object like`const error = { str, hash };`
|
||||
parseError(error.str, error.hash);
|
||||
return;
|
||||
}
|
||||
return false;
|
||||
|
||||
// Otherwise, assume it is just an error string and pass it on
|
||||
parseError(error as string);
|
||||
}
|
||||
|
||||
getParser() {
|
||||
@ -66,10 +83,10 @@ export class Diagram {
|
||||
}
|
||||
}
|
||||
|
||||
export default Diagram;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
export const getDiagramFromText = async (txt: string, parseError?: Function) => {
|
||||
export const getDiagramFromText = async (
|
||||
txt: string,
|
||||
parseError?: ParseErrorFunction
|
||||
): Promise<Diagram> => {
|
||||
const type = detectType(txt, configApi.getConfig());
|
||||
try {
|
||||
// Trying to find the diagram
|
||||
@ -80,23 +97,13 @@ export const getDiagramFromText = async (txt: string, parseError?: Function) =>
|
||||
throw new Error(`Diagram ${type} not found.`);
|
||||
}
|
||||
// Diagram not available, loading it
|
||||
// const path = getPathForDiagram(type);
|
||||
const { diagram } = await loader(); // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
registerDiagram(
|
||||
type,
|
||||
{
|
||||
db: diagram.db,
|
||||
renderer: diagram.renderer,
|
||||
parser: diagram.parser,
|
||||
styles: diagram.styles,
|
||||
},
|
||||
diagram.injectUtils
|
||||
);
|
||||
// await loadDiagram('./packages/mermaid-mindmap/dist/mermaid-mindmap.js');
|
||||
// await loadDiagram(path + 'mermaid-' + type + '.js');
|
||||
const { diagram } = await loader();
|
||||
registerDiagram(type, diagram, undefined, diagram.injectUtils);
|
||||
// new diagram will try getDiagram again and if fails then it is a valid throw
|
||||
}
|
||||
// If either of the above worked, we have the diagram
|
||||
// logic and can continue
|
||||
return new Diagram(txt, parseError);
|
||||
};
|
||||
|
||||
export default Diagram;
|
||||
|
@ -6,22 +6,17 @@
|
||||
import * as configApi from '../config';
|
||||
import { vi } from 'vitest';
|
||||
import { addDiagrams } from '../diagram-api/diagram-orchestration';
|
||||
import Diagram from '../Diagram';
|
||||
import Diagram, { type ParseErrorFunction } from '../Diagram';
|
||||
|
||||
// Normally, we could just do the following to get the original `parse()`
|
||||
// implementation, however, requireActual returns a promise and it's not documented how to use withing mock file.
|
||||
|
||||
let hasLoadedDiagrams = false;
|
||||
/**
|
||||
* @param text
|
||||
* @param parseError
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
function parse(text: string, parseError?: Function): boolean {
|
||||
if (!hasLoadedDiagrams) {
|
||||
function parse(text: string, parseError?: ParseErrorFunction): boolean {
|
||||
addDiagrams();
|
||||
hasLoadedDiagrams = true;
|
||||
}
|
||||
const diagram = new Diagram(text, parseError);
|
||||
return diagram.parse(text, parseError);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
import DOMPurify from 'dompurify';
|
||||
|
||||
export interface MermaidConfig {
|
||||
lazyLoadedDiagrams?: any;
|
||||
lazyLoadedDiagrams?: string[];
|
||||
theme?: string;
|
||||
themeVariables?: any;
|
||||
themeCSS?: string;
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { MermaidConfig } from '../config.type';
|
||||
import { log } from '../logger';
|
||||
import { DetectorRecord, DiagramDetector, DiagramLoader } from './types';
|
||||
|
||||
export type DiagramDetector = (text: string, config?: MermaidConfig) => boolean;
|
||||
export type DiagramLoader = (() => any) | null;
|
||||
export type DetectorRecord = { detector: DiagramDetector; loader: DiagramLoader };
|
||||
const directive =
|
||||
/[%]{2}[{]\s*(?:(?:(\w+)\s*:|(\w+))\s*(?:(?:(\w+))|((?:(?![}][%]{2}).|\r?\n)*))?\s*)(?:[}][%]{2})?/gi;
|
||||
const anyComment = /\s*%%.*\n/gm;
|
||||
@ -34,26 +33,22 @@ const detectors: Record<string, DetectorRecord> = {};
|
||||
*/
|
||||
export const detectType = function (text: string, config?: MermaidConfig): string {
|
||||
text = text.replace(directive, '').replace(anyComment, '\n');
|
||||
|
||||
// console.log(detectors);
|
||||
|
||||
for (const [key, { detector }] of Object.entries(detectors)) {
|
||||
const diagram = detector(text, config);
|
||||
if (diagram) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
// TODO: #3391
|
||||
// throw new Error(`No diagram type detected for text: ${text}`);
|
||||
return 'flowchart';
|
||||
|
||||
throw new Error(`No diagram type detected for text: ${text}`);
|
||||
};
|
||||
|
||||
export const addDetector = (
|
||||
key: string,
|
||||
detector: DiagramDetector,
|
||||
loader: DiagramLoader | null
|
||||
) => {
|
||||
export const addDetector = (key: string, detector: DiagramDetector, loader?: DiagramLoader) => {
|
||||
if (detectors[key]) {
|
||||
throw new Error(`Detector with key ${key} already exists`);
|
||||
}
|
||||
detectors[key] = { detector, loader };
|
||||
log.debug(`Detector with key ${key} added${loader ? ' with loader' : ''}`);
|
||||
};
|
||||
|
||||
export const getDiagramLoader = (key: string) => detectors[key].loader;
|
||||
|
@ -1,16 +1,4 @@
|
||||
import {
|
||||
registerDiagram,
|
||||
registerDetector,
|
||||
DiagramDefinition,
|
||||
DiagramDetector,
|
||||
} from './diagramAPI';
|
||||
|
||||
// // @ts-ignore: TODO Fix ts errors
|
||||
// import mindmapParser from '../diagrams/mindmap/parser/mindmap';
|
||||
// import * as mindmapDb from '../diagrams/mindmap/mindmapDb';
|
||||
// import { mindmapDetector } from '../diagrams/mindmap/mindmapDetector';
|
||||
// import mindmapRenderer from '../diagrams/mindmap/mindmapRenderer';
|
||||
// import mindmapStyles from '../diagrams/mindmap/styles';
|
||||
import { registerDiagram } from './diagramAPI';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import gitGraphParser from '../diagrams/git/parser/gitGraph';
|
||||
@ -106,17 +94,15 @@ import { setConfig } from '../config';
|
||||
import errorRenderer from '../diagrams/error/errorRenderer';
|
||||
import errorStyles from '../diagrams/error/styles';
|
||||
|
||||
const registerDiagramAndDetector = (
|
||||
id: string,
|
||||
diagram: DiagramDefinition,
|
||||
detector: DiagramDetector
|
||||
) => {
|
||||
registerDiagram(id, diagram);
|
||||
registerDetector(id, detector);
|
||||
};
|
||||
|
||||
let hasLoadedDiagrams = false;
|
||||
export const addDiagrams = () => {
|
||||
registerDiagramAndDetector(
|
||||
if (hasLoadedDiagrams) {
|
||||
return;
|
||||
}
|
||||
// This is added here to avoid race-conditions.
|
||||
// We could optimize the loading logic somehow.
|
||||
hasLoadedDiagrams = true;
|
||||
registerDiagram(
|
||||
'error',
|
||||
// Special diagram with error messages but setup as a regular diagram
|
||||
{
|
||||
@ -140,7 +126,7 @@ export const addDiagrams = () => {
|
||||
(text) => text.toLowerCase().trim() === 'error'
|
||||
);
|
||||
|
||||
registerDiagramAndDetector(
|
||||
registerDiagram(
|
||||
'c4',
|
||||
{
|
||||
parser: c4Parser,
|
||||
@ -153,7 +139,7 @@ export const addDiagrams = () => {
|
||||
},
|
||||
c4Detector
|
||||
);
|
||||
registerDiagramAndDetector(
|
||||
registerDiagram(
|
||||
'class',
|
||||
{
|
||||
parser: classParser,
|
||||
@ -170,7 +156,7 @@ export const addDiagrams = () => {
|
||||
},
|
||||
classDetector
|
||||
);
|
||||
registerDiagramAndDetector(
|
||||
registerDiagram(
|
||||
'classDiagram',
|
||||
{
|
||||
parser: classParser,
|
||||
@ -187,7 +173,7 @@ export const addDiagrams = () => {
|
||||
},
|
||||
classDetectorV2
|
||||
);
|
||||
registerDiagramAndDetector(
|
||||
registerDiagram(
|
||||
'er',
|
||||
{
|
||||
parser: erParser,
|
||||
@ -197,7 +183,7 @@ export const addDiagrams = () => {
|
||||
},
|
||||
erDetector
|
||||
);
|
||||
registerDiagramAndDetector(
|
||||
registerDiagram(
|
||||
'gantt',
|
||||
{
|
||||
parser: ganttParser,
|
||||
@ -207,7 +193,7 @@ export const addDiagrams = () => {
|
||||
},
|
||||
ganttDetector
|
||||
);
|
||||
registerDiagramAndDetector(
|
||||
registerDiagram(
|
||||
'info',
|
||||
{
|
||||
parser: infoParser,
|
||||
@ -217,7 +203,7 @@ export const addDiagrams = () => {
|
||||
},
|
||||
infoDetector
|
||||
);
|
||||
registerDiagramAndDetector(
|
||||
registerDiagram(
|
||||
'pie',
|
||||
{
|
||||
parser: pieParser,
|
||||
@ -227,7 +213,7 @@ export const addDiagrams = () => {
|
||||
},
|
||||
pieDetector
|
||||
);
|
||||
registerDiagramAndDetector(
|
||||
registerDiagram(
|
||||
'requirement',
|
||||
{
|
||||
parser: requirementParser,
|
||||
@ -237,7 +223,7 @@ export const addDiagrams = () => {
|
||||
},
|
||||
requirementDetector
|
||||
);
|
||||
registerDiagramAndDetector(
|
||||
registerDiagram(
|
||||
'sequence',
|
||||
{
|
||||
parser: sequenceParser,
|
||||
@ -260,7 +246,7 @@ export const addDiagrams = () => {
|
||||
},
|
||||
sequenceDetector
|
||||
);
|
||||
registerDiagramAndDetector(
|
||||
registerDiagram(
|
||||
'state',
|
||||
{
|
||||
parser: stateParser,
|
||||
@ -277,7 +263,7 @@ export const addDiagrams = () => {
|
||||
},
|
||||
stateDetector
|
||||
);
|
||||
registerDiagramAndDetector(
|
||||
registerDiagram(
|
||||
'stateDiagram',
|
||||
{
|
||||
parser: stateParser,
|
||||
@ -294,7 +280,7 @@ export const addDiagrams = () => {
|
||||
},
|
||||
stateDetectorV2
|
||||
);
|
||||
registerDiagramAndDetector(
|
||||
registerDiagram(
|
||||
'journey',
|
||||
{
|
||||
parser: journeyParser,
|
||||
@ -309,7 +295,7 @@ export const addDiagrams = () => {
|
||||
journeyDetector
|
||||
);
|
||||
|
||||
registerDiagramAndDetector(
|
||||
registerDiagram(
|
||||
'flowchart',
|
||||
{
|
||||
parser: flowParser,
|
||||
@ -329,7 +315,7 @@ export const addDiagrams = () => {
|
||||
},
|
||||
flowDetector
|
||||
);
|
||||
registerDiagramAndDetector(
|
||||
registerDiagram(
|
||||
'flowchart-v2',
|
||||
{
|
||||
parser: flowParser,
|
||||
@ -350,14 +336,9 @@ export const addDiagrams = () => {
|
||||
},
|
||||
flowDetectorV2
|
||||
);
|
||||
registerDiagramAndDetector(
|
||||
registerDiagram(
|
||||
'gitGraph',
|
||||
{ parser: gitGraphParser, db: gitGraphDb, renderer: gitGraphRenderer, styles: gitGraphStyles },
|
||||
gitGraphDetector
|
||||
);
|
||||
// registerDiagram(
|
||||
// 'mindmap',
|
||||
// { parser: mindmapParser, db: mindmapDb, renderer: mindmapRenderer, styles: mindmapStyles },
|
||||
// mindmapDetector
|
||||
// );
|
||||
};
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { detectType, DiagramDetector } from './detectType';
|
||||
import { getDiagram, registerDiagram, registerDetector } from './diagramAPI';
|
||||
import { detectType } from './detectType';
|
||||
import { getDiagram, registerDiagram } from './diagramAPI';
|
||||
import { addDiagrams } from './diagram-orchestration';
|
||||
import { DiagramDetector } from './types';
|
||||
|
||||
addDiagrams();
|
||||
|
||||
@ -15,17 +16,22 @@ describe('DiagramAPI', () => {
|
||||
|
||||
it('should handle diagram registrations', () => {
|
||||
expect(() => getDiagram('loki')).toThrow();
|
||||
expect(() => detectType('loki diagram')).not.toThrow(); // TODO: #3391
|
||||
expect(() => detectType('loki diagram')).toThrow(
|
||||
'No diagram type detected for text: loki diagram'
|
||||
);
|
||||
const detector: DiagramDetector = (str: string) => {
|
||||
return str.match('loki') !== null;
|
||||
};
|
||||
registerDetector('loki', detector);
|
||||
registerDiagram('loki', {
|
||||
registerDiagram(
|
||||
'loki',
|
||||
{
|
||||
db: {},
|
||||
parser: {},
|
||||
renderer: {},
|
||||
styles: {},
|
||||
});
|
||||
},
|
||||
detector
|
||||
);
|
||||
expect(getDiagram('loki')).not.toBeNull();
|
||||
expect(detectType('loki diagram')).toBe('loki');
|
||||
});
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { addDetector, DiagramDetector as _DiagramDetector } from './detectType';
|
||||
import { addDetector } from './detectType';
|
||||
import { log as _log, setLogLevel as _setLogLevel } from '../logger';
|
||||
import { getConfig as _getConfig } from '../config';
|
||||
import { sanitizeText as _sanitizeText } from '../diagrams/common/common';
|
||||
import { MermaidConfig } from '../config.type';
|
||||
import { setupGraphViewbox as _setupGraphViewbox } from '../setupGraphViewbox';
|
||||
import { addStylesForDiagram } from '../styles';
|
||||
import { DiagramDefinition, DiagramDetector } from './types';
|
||||
|
||||
/*
|
||||
Packaging and exposing resources for external diagrams so that they can import
|
||||
@ -13,41 +13,19 @@ import { addStylesForDiagram } from '../styles';
|
||||
*/
|
||||
export const log = _log;
|
||||
export const setLogLevel = _setLogLevel;
|
||||
export type DiagramDetector = _DiagramDetector;
|
||||
export const getConfig = _getConfig;
|
||||
export const sanitizeText = (text: string) => _sanitizeText(text, getConfig());
|
||||
export const setupGraphViewbox = _setupGraphViewbox;
|
||||
|
||||
export interface InjectUtils {
|
||||
_log: any;
|
||||
_setLogLevel: any;
|
||||
_getConfig: any;
|
||||
_sanitizeText: any;
|
||||
_setupGraphViewbox: any;
|
||||
}
|
||||
|
||||
export interface DiagramDefinition {
|
||||
db: any;
|
||||
renderer: any;
|
||||
parser: any;
|
||||
styles: any;
|
||||
init?: (config: MermaidConfig) => void;
|
||||
injectUtils?: (utils: InjectUtils) => void;
|
||||
}
|
||||
|
||||
const diagrams: Record<string, DiagramDefinition> = {};
|
||||
const connectCallbacks: Record<string, any> = {}; // TODO fix, eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
export interface Detectors {
|
||||
[key: string]: DiagramDetector;
|
||||
}
|
||||
|
||||
export const registerDetector = (id: string, detector: DiagramDetector) => {
|
||||
addDetector(id, detector, null);
|
||||
};
|
||||
|
||||
export const registerDiagram = (
|
||||
id: string,
|
||||
diagram: DiagramDefinition,
|
||||
detector?: DiagramDetector,
|
||||
callback?: (
|
||||
_log: any,
|
||||
_setLogLevel: any,
|
||||
@ -57,9 +35,12 @@ export const registerDiagram = (
|
||||
) => void
|
||||
) => {
|
||||
if (diagrams[id]) {
|
||||
log.warn(`Diagram ${id} already registered.`);
|
||||
throw new Error(`Diagram ${id} already registered.`);
|
||||
}
|
||||
diagrams[id] = diagram;
|
||||
if (detector) {
|
||||
addDetector(id, detector);
|
||||
}
|
||||
addStylesForDiagram(id, diagram.styles);
|
||||
if (typeof callback !== 'undefined') {
|
||||
callback(log, setLogLevel, getConfig, sanitizeText, setupGraphViewbox);
|
||||
@ -72,19 +53,3 @@ export const getDiagram = (name: string): DiagramDefinition => {
|
||||
}
|
||||
throw new Error(`Diagram ${name} not found.`);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param sScriptSrc
|
||||
*/
|
||||
export const loadDiagram = (sScriptSrc: string) =>
|
||||
new Promise((resolve) => {
|
||||
const oHead = document.getElementsByTagName('HEAD')[0];
|
||||
const oScript = document.createElement('script');
|
||||
oScript.type = 'text/javascript';
|
||||
oScript.src = sScriptSrc;
|
||||
oHead.appendChild(oScript);
|
||||
oScript.onload = () => {
|
||||
resolve(true);
|
||||
};
|
||||
});
|
||||
|
@ -1,227 +0,0 @@
|
||||
export const lineBreakRegex = /<br\s*\/?>/gi;
|
||||
|
||||
/**
|
||||
* Caches results of functions based on input
|
||||
*
|
||||
* @param {Function} fn Function to run
|
||||
* @param {Function} resolver Function that resolves to an ID given arguments the `fn` takes
|
||||
* @returns {Function} An optimized caching function
|
||||
*/
|
||||
const memoize = (fn, resolver) => {
|
||||
let cache = {};
|
||||
return (...args) => {
|
||||
let n = resolver ? resolver.apply(this, args) : args[0];
|
||||
if (n in cache) {
|
||||
return cache[n];
|
||||
} else {
|
||||
let result = fn(...args);
|
||||
cache[n] = result;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
};
|
||||
/**
|
||||
* This calculates the width of the given text, font size and family.
|
||||
*
|
||||
* @param {any} text - The text to calculate the width of
|
||||
* @param {any} config - The config for fontSize, fontFamily, and fontWeight all impacting the resulting size
|
||||
* @returns {any} - The width for the given text
|
||||
*/
|
||||
export const calculateTextWidth = function (text, config) {
|
||||
config = Object.assign({ fontSize: 12, fontWeight: 400, fontFamily: 'Arial' }, config);
|
||||
return calculateTextDimensions(text, config).width;
|
||||
};
|
||||
|
||||
export const getTextObj = function () {
|
||||
return {
|
||||
x: 0,
|
||||
y: 0,
|
||||
fill: undefined,
|
||||
anchor: 'start',
|
||||
style: '#666',
|
||||
width: 100,
|
||||
height: 100,
|
||||
textMargin: 0,
|
||||
rx: 0,
|
||||
ry: 0,
|
||||
valign: undefined,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds text to an element
|
||||
*
|
||||
* @param {SVGElement} elem Element to add text to
|
||||
* @param {{
|
||||
* text: string;
|
||||
* x: number;
|
||||
* y: number;
|
||||
* anchor: 'start' | 'middle' | 'end';
|
||||
* fontFamily: string;
|
||||
* fontSize: string | number;
|
||||
* fontWeight: string | number;
|
||||
* fill: string;
|
||||
* class: string | undefined;
|
||||
* textMargin: number;
|
||||
* }} textData
|
||||
* @returns {SVGTextElement} Text element with given styling and content
|
||||
*/
|
||||
export const drawSimpleText = function (elem, textData) {
|
||||
// Remove and ignore br:s
|
||||
const nText = textData.text.replace(lineBreakRegex, ' ');
|
||||
|
||||
const textElem = elem.append('text');
|
||||
textElem.attr('x', textData.x);
|
||||
textElem.attr('y', textData.y);
|
||||
textElem.style('text-anchor', textData.anchor);
|
||||
textElem.style('font-family', textData.fontFamily);
|
||||
textElem.style('font-size', textData.fontSize);
|
||||
textElem.style('font-weight', textData.fontWeight);
|
||||
textElem.attr('fill', textData.fill);
|
||||
if (typeof textData.class !== 'undefined') {
|
||||
textElem.attr('class', textData.class);
|
||||
}
|
||||
|
||||
const span = textElem.append('tspan');
|
||||
span.attr('x', textData.x + textData.textMargin * 2);
|
||||
span.attr('fill', textData.fill);
|
||||
span.text(nText);
|
||||
|
||||
return textElem;
|
||||
};
|
||||
|
||||
/**
|
||||
* This calculates the dimensions of the given text, font size, font family, font weight, and margins.
|
||||
*
|
||||
* @param {any} text - The text to calculate the width of
|
||||
* @param {any} config - The config for fontSize, fontFamily, fontWeight, and margin all impacting
|
||||
* the resulting size
|
||||
* @returns - The width for the given text
|
||||
*/
|
||||
export const calculateTextDimensions = memoize(
|
||||
function (text, config) {
|
||||
config = Object.assign({ fontSize: 12, fontWeight: 400, fontFamily: 'Arial' }, config);
|
||||
const { fontSize, fontFamily, fontWeight } = config;
|
||||
if (!text) {
|
||||
return { width: 0, height: 0 };
|
||||
}
|
||||
|
||||
// We can't really know if the user supplied font family will render on the user agent;
|
||||
// thus, we'll take the max width between the user supplied font family, and a default
|
||||
// of sans-serif.
|
||||
const fontFamilies = ['sans-serif', fontFamily];
|
||||
const lines = text.split(common.lineBreakRegex);
|
||||
let dims = [];
|
||||
|
||||
const body = select('body');
|
||||
// We don't want to leak DOM elements - if a removal operation isn't available
|
||||
// for any reason, do not continue.
|
||||
if (!body.remove) {
|
||||
return { width: 0, height: 0, lineHeight: 0 };
|
||||
}
|
||||
|
||||
const g = body.append('svg');
|
||||
|
||||
for (let fontFamily of fontFamilies) {
|
||||
let cheight = 0;
|
||||
let dim = { width: 0, height: 0, lineHeight: 0 };
|
||||
for (let line of lines) {
|
||||
const textObj = getTextObj();
|
||||
textObj.text = line;
|
||||
const textElem = drawSimpleText(g, textObj)
|
||||
.style('font-size', fontSize)
|
||||
.style('font-weight', fontWeight)
|
||||
.style('font-family', fontFamily);
|
||||
|
||||
let bBox = (textElem._groups || textElem)[0][0].getBBox();
|
||||
dim.width = Math.round(Math.max(dim.width, bBox.width));
|
||||
cheight = Math.round(bBox.height);
|
||||
dim.height += cheight;
|
||||
dim.lineHeight = Math.round(Math.max(dim.lineHeight, cheight));
|
||||
}
|
||||
dims.push(dim);
|
||||
}
|
||||
|
||||
g.remove();
|
||||
|
||||
let index =
|
||||
isNaN(dims[1].height) ||
|
||||
isNaN(dims[1].width) ||
|
||||
isNaN(dims[1].lineHeight) ||
|
||||
(dims[0].height > dims[1].height &&
|
||||
dims[0].width > dims[1].width &&
|
||||
dims[0].lineHeight > dims[1].lineHeight)
|
||||
? 0
|
||||
: 1;
|
||||
return dims[index];
|
||||
},
|
||||
(text, config) => `${text}-${config.fontSize}-${config.fontWeight}-${config.fontFamily}`
|
||||
);
|
||||
|
||||
const breakString = memoize(
|
||||
(word, maxWidth, hyphenCharacter = '-', config) => {
|
||||
config = Object.assign(
|
||||
{ fontSize: 12, fontWeight: 400, fontFamily: 'Arial', margin: 0 },
|
||||
config
|
||||
);
|
||||
const characters = word.split('');
|
||||
const lines = [];
|
||||
let currentLine = '';
|
||||
characters.forEach((character, index) => {
|
||||
const nextLine = `${currentLine}${character}`;
|
||||
const lineWidth = calculateTextWidth(nextLine, config);
|
||||
if (lineWidth >= maxWidth) {
|
||||
const currentCharacter = index + 1;
|
||||
const isLastLine = characters.length === currentCharacter;
|
||||
const hyphenatedNextLine = `${nextLine}${hyphenCharacter}`;
|
||||
lines.push(isLastLine ? nextLine : hyphenatedNextLine);
|
||||
currentLine = '';
|
||||
} else {
|
||||
currentLine = nextLine;
|
||||
}
|
||||
});
|
||||
return { hyphenatedStrings: lines, remainingWord: currentLine };
|
||||
},
|
||||
(word, maxWidth, hyphenCharacter = '-', config) =>
|
||||
`${word}-${maxWidth}-${hyphenCharacter}-${config.fontSize}-${config.fontWeight}-${config.fontFamily}`
|
||||
);
|
||||
|
||||
export const wrapLabel = memoize(
|
||||
(label, maxWidth, config) => {
|
||||
if (!label) {
|
||||
return label;
|
||||
}
|
||||
config = Object.assign(
|
||||
{ fontSize: 12, fontWeight: 400, fontFamily: 'Arial', joinWith: '<br/>' },
|
||||
config
|
||||
);
|
||||
if (lineBreakRegex.test(label)) {
|
||||
return label;
|
||||
}
|
||||
const words = label.split(' ');
|
||||
const completedLines = [];
|
||||
let nextLine = '';
|
||||
words.forEach((word, index) => {
|
||||
const wordLength = calculateTextWidth(`${word} `, config);
|
||||
const nextLineLength = calculateTextWidth(nextLine, config);
|
||||
if (wordLength > maxWidth) {
|
||||
const { hyphenatedStrings, remainingWord } = breakString(word, maxWidth, '-', config);
|
||||
completedLines.push(nextLine, ...hyphenatedStrings);
|
||||
nextLine = remainingWord;
|
||||
} else if (nextLineLength + wordLength >= maxWidth) {
|
||||
completedLines.push(nextLine);
|
||||
nextLine = word;
|
||||
} else {
|
||||
nextLine = [nextLine, word].filter(Boolean).join(' ');
|
||||
}
|
||||
const currentWord = index + 1;
|
||||
const isLastWord = currentWord === words.length;
|
||||
if (isLastWord) {
|
||||
completedLines.push(nextLine);
|
||||
}
|
||||
});
|
||||
return completedLines.filter((line) => line !== '').join(config.joinWith);
|
||||
},
|
||||
(label, maxWidth, config) =>
|
||||
`${label}-${maxWidth}-${config.fontSize}-${config.fontWeight}-${config.fontFamily}-${config.joinWith}`
|
||||
);
|
26
packages/mermaid/src/diagram-api/types.ts
Normal file
26
packages/mermaid/src/diagram-api/types.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { MermaidConfig } from '../config.type';
|
||||
|
||||
export interface InjectUtils {
|
||||
_log: any;
|
||||
_setLogLevel: any;
|
||||
_getConfig: any;
|
||||
_sanitizeText: any;
|
||||
_setupGraphViewbox: any;
|
||||
}
|
||||
|
||||
export interface DiagramDefinition {
|
||||
db: any;
|
||||
renderer: any;
|
||||
parser: any;
|
||||
styles: any;
|
||||
init?: (config: MermaidConfig) => void;
|
||||
injectUtils?: (utils: InjectUtils) => void;
|
||||
}
|
||||
|
||||
export interface DetectorRecord {
|
||||
detector: DiagramDetector;
|
||||
loader?: DiagramLoader;
|
||||
}
|
||||
|
||||
export type DiagramDetector = (text: string, config?: MermaidConfig) => boolean;
|
||||
export type DiagramLoader = (() => Promise<{ id: string; diagram: DiagramDefinition }>) | null;
|
@ -1,4 +1,4 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
import type { DiagramDetector } from '../../diagram-api/types';
|
||||
|
||||
export const c4Detector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/) !== null;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
import type { DiagramDetector } from '../../diagram-api/types';
|
||||
|
||||
export const classDetectorV2: 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
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
import type { DiagramDetector } from '../../diagram-api/types';
|
||||
|
||||
export const classDetector: DiagramDetector = (txt, config) => {
|
||||
// If we have configured to use dagre-wrapper then we should never return true in this function
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
import type { DiagramDetector } from '../../diagram-api/types';
|
||||
|
||||
export const erDetector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*erDiagram/) !== null;
|
||||
|
@ -429,8 +429,7 @@ export const clear = function (ver = 'gen-1') {
|
||||
vertices = {};
|
||||
classes = {};
|
||||
edges = [];
|
||||
funs = [];
|
||||
funs.push(setupToolTips);
|
||||
funs = [setupToolTips];
|
||||
subGraphs = [];
|
||||
subGraphLookup = {};
|
||||
subCount = 0;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
import type { DiagramDetector } from '../../diagram-api/types';
|
||||
|
||||
export const flowDetectorV2: 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
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
import type { DiagramDetector } from '../../diagram-api/types';
|
||||
|
||||
export const flowDetector: DiagramDetector = (txt, config) => {
|
||||
// If we have conferred to only use new flow charts this function should always return false
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
import type { DiagramDetector } from '../../diagram-api/types';
|
||||
|
||||
export const ganttDetector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*gantt/) !== null;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
import type { DiagramDetector } from '../../diagram-api/types';
|
||||
|
||||
export const gitGraphDetector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*gitGraph/) !== null;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
import type { DiagramDetector } from '../../diagram-api/types';
|
||||
|
||||
export const infoDetector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*info/) !== null;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
import type { DiagramDetector } from '../../diagram-api/types';
|
||||
|
||||
export const pieDetector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*pie/) !== null;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
import type { DiagramDetector } from '../../diagram-api/types';
|
||||
|
||||
export const requirementDetector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*requirement(Diagram)?/) !== null;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
import type { DiagramDetector } from '../../diagram-api/types';
|
||||
|
||||
export const sequenceDetector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*sequenceDiagram/) !== null;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
import type { DiagramDetector } from '../../diagram-api/types';
|
||||
|
||||
export const stateDetectorV2: DiagramDetector = (text, config) => {
|
||||
if (text.match(/^\s*stateDiagram-v2/) !== null) return true;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
import type { DiagramDetector } from '../../diagram-api/types';
|
||||
|
||||
export const stateDetector: DiagramDetector = (txt, config) => {
|
||||
// If we have confirmed to only use new state diagrams this function should always return false
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
import type { DiagramDetector } from '../../diagram-api/types';
|
||||
|
||||
export const journeyDetector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*journey/) !== null;
|
||||
|
@ -35,13 +35,17 @@ import { exec } from 'child_process';
|
||||
import { globby } from 'globby';
|
||||
import { JSDOM } from 'jsdom';
|
||||
import type { Code, Root } from 'mdast';
|
||||
import { join, dirname } from 'path';
|
||||
import { posix, dirname } from 'path';
|
||||
import prettier from 'prettier';
|
||||
import { remark } from 'remark';
|
||||
// @ts-ignore No typescript declaration file
|
||||
// eslint-disable-next-line @cspell/spellchecker
|
||||
import flatmap from 'unist-util-flatmap';
|
||||
|
||||
const MERMAID_MAJOR_VERSION = (
|
||||
JSON.parse(readFileSync('packages/mermaid/package.json', 'utf8')).version as string
|
||||
).split('.')[0];
|
||||
|
||||
// These paths are from the root of the mono-repo, not from the
|
||||
// mermaid sub-directory
|
||||
const SOURCE_DOCS_DIR = 'packages/mermaid/src/docs';
|
||||
@ -145,7 +149,7 @@ const readSyncedUTF8file = (filename: string): string => {
|
||||
* @param file {string} name of the file that will be verified
|
||||
*/
|
||||
const transformMarkdown = (file: string) => {
|
||||
const doc = readSyncedUTF8file(file);
|
||||
const doc = readSyncedUTF8file(file).replace(/<MERMAID_VERSION>/g, MERMAID_MAJOR_VERSION);
|
||||
const ast: Root = remark.parse(doc);
|
||||
const out = flatmap(ast, (c: Code) => {
|
||||
if (c.type !== 'code') {
|
||||
@ -186,7 +190,10 @@ const transformHtml = (filename: string) => {
|
||||
* @returns {string} The contents of the file with the comment inserted
|
||||
*/
|
||||
const insertAutoGeneratedComment = (fileName: string): string => {
|
||||
const fileContents = readSyncedUTF8file(fileName);
|
||||
const fileContents = readSyncedUTF8file(fileName).replace(
|
||||
/<MERMAID_VERSION>/g,
|
||||
MERMAID_MAJOR_VERSION
|
||||
);
|
||||
const jsdom = new JSDOM(fileContents);
|
||||
const htmlDoc = jsdom.window.document;
|
||||
const autoGeneratedComment = jsdom.window.document.createComment(AUTOGENERATED_TEXT);
|
||||
@ -204,30 +211,28 @@ const transformHtml = (filename: string) => {
|
||||
copyTransformedContents(filename, !verifyOnly, formattedHTML);
|
||||
};
|
||||
|
||||
const getFilesFromGlobs = async (globs: string[]): Promise<string[]> => {
|
||||
return await globby(globs, { dot: true });
|
||||
};
|
||||
|
||||
/** Main method (entry point) */
|
||||
(async () => {
|
||||
if (verifyOnly) {
|
||||
console.log('Verifying that all files are in sync with the source files');
|
||||
}
|
||||
const sourceDirGlob = join('.', SOURCE_DOCS_DIR, '**');
|
||||
const includeFilesStartingWithDot = true;
|
||||
const sourceDirGlob = posix.join('.', SOURCE_DOCS_DIR, '**');
|
||||
const action = verifyOnly ? 'Verifying' : 'Transforming';
|
||||
|
||||
console.log('Transforming markdown files...');
|
||||
const mdFiles = await globby([join(sourceDirGlob, '*.md')], {
|
||||
dot: includeFilesStartingWithDot,
|
||||
});
|
||||
const mdFiles = await getFilesFromGlobs([posix.join(sourceDirGlob, '*.md')]);
|
||||
console.log(`${action} ${mdFiles.length} markdown files...`);
|
||||
mdFiles.forEach(transformMarkdown);
|
||||
|
||||
console.log('Transforming html files...');
|
||||
const htmlFiles = await globby([join(sourceDirGlob, '*.html')], {
|
||||
dot: includeFilesStartingWithDot,
|
||||
});
|
||||
const htmlFiles = await getFilesFromGlobs([posix.join(sourceDirGlob, '*.html')]);
|
||||
console.log(`${action} ${htmlFiles.length} html files...`);
|
||||
htmlFiles.forEach(transformHtml);
|
||||
|
||||
console.log('Transforming all other files...');
|
||||
const otherFiles = await globby([sourceDirGlob, '!**/*.md', '!**/*.html'], {
|
||||
dot: includeFilesStartingWithDot,
|
||||
});
|
||||
const otherFiles = await getFilesFromGlobs([sourceDirGlob, '!**/*.md', '!**/*.html']);
|
||||
console.log(`${action} ${otherFiles.length} other files...`);
|
||||
otherFiles.forEach((file: string) => {
|
||||
copyTransformedContents(file, !verifyOnly); // no transformation
|
||||
});
|
||||
@ -238,7 +243,7 @@ const transformHtml = (filename: string) => {
|
||||
process.exit(1);
|
||||
}
|
||||
if (git) {
|
||||
console.log('Adding changes in ${FINAL_DOCS_DIR} folder to git');
|
||||
console.log(`Adding changes in ${FINAL_DOCS_DIR} folder to git`);
|
||||
exec('git add docs');
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ It is a JavaScript based diagramming and charting tool that renders Markdown-ins
|
||||
|
||||
<img src="img/header.png" alt="" />
|
||||
|
||||
[![Build Status](https://travis-ci.org/mermaid-js/mermaid.svg?branch=master)](https://travis-ci.org/mermaid-js/mermaid) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE)
|
||||
[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
|
||||
|
||||
<!-- Mermaid book banner -->
|
||||
|
||||
@ -187,16 +187,16 @@ To Deploy Mermaid:
|
||||
|
||||
### [Mermaid API](./Setup.md):
|
||||
|
||||
**To deploy mermaid without a bundler, one can insert a `script` tag with an absolute address and a `mermaidAPI` call into the HTML like so:**
|
||||
**To deploy mermaid without a bundler, one can insert a `script` tag with an absolute address and a `mermaid.initialize` call into the HTML like so:**
|
||||
|
||||
```html
|
||||
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
|
||||
<script>
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@<MERMAID_VERSION>/dist/mermaid.esm.min.mjs';
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
```
|
||||
|
||||
**Doing so will command the mermaid parser to look for the `<div>` tags with `class="mermaid"`. From these tags mermaid will try to read the diagram/chart definitions and render them into SVG charts.**
|
||||
**Doing so will command the mermaid parser to look for the `<div>` or `<pre>` tags with `class="mermaid"`. From these tags mermaid will try to read the diagram/chart definitions and render them into SVG charts.**
|
||||
|
||||
**Examples can be found at** [Other examples](/examples)
|
||||
|
||||
|
@ -1559,7 +1559,7 @@ Returns **void**
|
||||
|
||||
```html
|
||||
<script>
|
||||
var config = {
|
||||
const config = {
|
||||
theme: 'default',
|
||||
logLevel: 'fatal',
|
||||
securityLevel: 'strict',
|
||||
|
@ -399,7 +399,7 @@ click Shape2 call callbackFunction() "This is a tooltip for a callback"
|
||||
|
||||
```html
|
||||
<script>
|
||||
var callbackFunction = function () {
|
||||
const callbackFunction = function () {
|
||||
alert('A callback was triggered');
|
||||
};
|
||||
</script>
|
||||
@ -451,10 +451,10 @@ Beginner's tip—a full example using interactive links in an HTML page:
|
||||
</pre>
|
||||
|
||||
<script>
|
||||
var callback = function () {
|
||||
const callback = function () {
|
||||
alert('A callback was triggered');
|
||||
};
|
||||
var config = {
|
||||
const config = {
|
||||
startOnLoad: true,
|
||||
securityLevel: 'loose',
|
||||
};
|
||||
|
@ -416,7 +416,7 @@ click nodeId call callback()
|
||||
|
||||
```html
|
||||
<script>
|
||||
var callback = function (nodeId) {
|
||||
const callback = function (nodeId) {
|
||||
alert('A callback was triggered on ' + nodeId);
|
||||
};
|
||||
</script>
|
||||
@ -471,10 +471,10 @@ Beginner's tip—here's a full example of using interactive links in HTML:
|
||||
</pre>
|
||||
|
||||
<script>
|
||||
var callback = function () {
|
||||
const callback = function () {
|
||||
alert('A callback was triggered');
|
||||
};
|
||||
var config = {
|
||||
const config = {
|
||||
startOnLoad: true,
|
||||
flowchart: {
|
||||
useMaxWidth: true,
|
||||
|
@ -198,8 +198,8 @@ flowchart LR
|
||||
### Dotted link
|
||||
|
||||
```mermaid-example
|
||||
flowchart LR;
|
||||
A-.->B;
|
||||
flowchart LR
|
||||
A-.->B
|
||||
```
|
||||
|
||||
### Dotted link with text
|
||||
@ -442,7 +442,7 @@ Examples of tooltip usage below:
|
||||
|
||||
```html
|
||||
<script>
|
||||
var callback = function () {
|
||||
const callback = function () {
|
||||
alert('A callback was triggered');
|
||||
};
|
||||
</script>
|
||||
@ -495,10 +495,10 @@ Beginner's tip—a full example using interactive links in a html context:
|
||||
</pre>
|
||||
|
||||
<script>
|
||||
var callback = function () {
|
||||
const callback = function () {
|
||||
alert('A callback was triggered');
|
||||
};
|
||||
var config = {
|
||||
const config = {
|
||||
startOnLoad: true,
|
||||
flowchart: { useMaxWidth: true, htmlLabels: true, curve: 'cardinal' },
|
||||
securityLevel: 'loose',
|
||||
@ -587,7 +587,7 @@ A shorter form of adding a class is to attach the classname to the node using th
|
||||
```mermaid-example
|
||||
flowchart LR
|
||||
A:::someclass --> B
|
||||
classDef someclass fill:#f96;
|
||||
classDef someclass fill:#f96
|
||||
```
|
||||
|
||||
### Css classes
|
||||
@ -610,7 +610,7 @@ below:
|
||||
**Example definition**
|
||||
|
||||
```mermaid-example
|
||||
flowchart LR;
|
||||
flowchart LR
|
||||
A-->B[AAA<span>BBB</span>]
|
||||
B-->D
|
||||
class A cssClass
|
||||
@ -634,7 +634,7 @@ The icons are accessed via the syntax fa:#icon class name#.
|
||||
flowchart TD
|
||||
B["fab:fa-twitter for peace"]
|
||||
B-->C[fa:fa-ban forbidden]
|
||||
B-->D(fa:fa-spinner);
|
||||
B-->D(fa:fa-spinner)
|
||||
B-->E(A fa:fa-camera-retro perhaps?)
|
||||
```
|
||||
|
||||
|
@ -327,13 +327,13 @@ Beginner's tip—a full example using interactive links in an html context:
|
||||
</pre>
|
||||
|
||||
<script>
|
||||
var printArguments = function (arg1, arg2, arg3) {
|
||||
const printArguments = function (arg1, arg2, arg3) {
|
||||
alert('printArguments called with arguments: ' + arg1 + ', ' + arg2 + ', ' + arg3);
|
||||
};
|
||||
var printTask = function (taskId) {
|
||||
const printTask = function (taskId) {
|
||||
alert('taskId: ' + taskId);
|
||||
};
|
||||
var config = {
|
||||
const config = {
|
||||
startOnLoad: true,
|
||||
securityLevel: 'loose',
|
||||
};
|
||||
|
@ -21,21 +21,34 @@
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css"
|
||||
/>
|
||||
<script src="//cdn.jsdelivr.net/npm/mermaid@9.1.7/dist/mermaid.min.js"></script>
|
||||
<!-- <script src="http://localhost:9000/mermaid.js"></script> -->
|
||||
<script
|
||||
defer
|
||||
data-domain="mermaid-js.github.io"
|
||||
src="https://plausible.io/js/plausible.js"
|
||||
></script>
|
||||
<script>
|
||||
var require = {
|
||||
paths: { vs: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.29.1/min/vs' },
|
||||
const require = {
|
||||
paths: { vs: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.0/min/vs' },
|
||||
};
|
||||
</script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.29.1/min/vs/loader.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.29.1/min/vs/editor/editor.main.nls.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.29.1/min/vs/editor/editor.main.js"></script>
|
||||
<script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.0/min/vs/loader.min.js"
|
||||
integrity="sha512-6bIYsGqvLpAiEBXPdRQeFf5cueeBECtAKJjIHer3BhBZNTV3WLcLA8Tm3pDfxUwTMIS+kAZwTUvJ1IrMdX8C5w=="
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
></script>
|
||||
<script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.0/min/vs/editor/editor.main.nls.min.js"
|
||||
integrity="sha512-CCv+DKWw+yZhxf4Z+ExT6HC5G+3S45TeMTYcJyYbdrv4BpK2vyALJ4FoVR/KGWDIPu7w4tNCOC9MJQIkYPR5FA=="
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
></script>
|
||||
<script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.0/min/vs/editor/editor.main.min.js"
|
||||
integrity="sha512-iVHvVf6TQEoF5oQrocjP88wstImQHQZCxGsa5nKYOs6gXWzsV7QZHyk80HrXhrEWRJ1ADoIV6Uji3UUXtCmBMg=="
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
></script>
|
||||
<script>
|
||||
exports = {};
|
||||
</script>
|
||||
@ -50,17 +63,22 @@
|
||||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@<MERMAID_VERSION>/dist/mermaid.esm.min.mjs';
|
||||
window.mermaid = mermaid;
|
||||
</script>
|
||||
<script>
|
||||
var initEditor = exports.default;
|
||||
var parser = new DOMParser();
|
||||
var currentCodeExample = 0;
|
||||
var colorize = [];
|
||||
let initEditor = exports.default;
|
||||
let parser = new DOMParser();
|
||||
let currentCodeExample = 0;
|
||||
let colorize = [];
|
||||
let num = 0;
|
||||
|
||||
function colorizeEverything(html) {
|
||||
initEditor(monaco);
|
||||
return new Promise((resolve, reject) => {
|
||||
monaco.editor.setTheme('mermaid');
|
||||
var parsed = parser.parseFromString(html, 'text/html').body;
|
||||
const parsed = parser.parseFromString(html, 'text/html').body;
|
||||
Promise.all(
|
||||
[...parsed.querySelectorAll('pre[id*="code"]')].map((codeBlock) =>
|
||||
monaco.editor.colorize(codeBlock.innerText, 'mermaid')
|
||||
@ -99,6 +117,7 @@
|
||||
colorize.push(currentCodeExample);
|
||||
return '<pre id="code' + currentCodeExample + '">' + escapeHTML(code) + '</pre>';
|
||||
} else if (lang === 'mermaid') {
|
||||
// TODO: This will need to be updated when render is async.
|
||||
return (
|
||||
'<pre class="mermaid">' + mermaid.render('mermaid-svg-' + num++, code) + '</pre>'
|
||||
);
|
||||
@ -117,7 +136,7 @@
|
||||
function (hook, vm) {
|
||||
hook.beforeEach(function (html) {
|
||||
url = 'https://github.com/mermaid-js/mermaid/blob/develop/src/docs/' + vm.route.file;
|
||||
var editHtml = '[:memo: Edit this Page](' + url + ')\n';
|
||||
const editHtml = '[:memo: Edit this Page](' + url + ')\n';
|
||||
return editHtml + html;
|
||||
});
|
||||
|
||||
@ -136,7 +155,6 @@
|
||||
],
|
||||
};
|
||||
|
||||
var num = 0;
|
||||
const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
|
||||
const conf = {
|
||||
|
@ -73,23 +73,13 @@ The API works by pulling rendering instructions from the source `mermaid.js` in
|
||||
|
||||
### Requirements for the Mermaid API.
|
||||
|
||||
When writing the .html file, we give three instructions inside the html code to the web browser:
|
||||
When writing the .html file, we give two instructions inside the html code to the web browser:
|
||||
|
||||
a. A reference for fetching the online mermaid renderer, through the `mermaid.js` or `mermaid.min.js`.
|
||||
a. The mermaid code for the diagram we want to create.
|
||||
|
||||
b. The mermaid code for the diagram we want to create.
|
||||
b. The importing of mermaid library through the `mermaid.esm.js` or `mermaid.esm.min.mjs` and the `mermaid.initialize()` call, which dictates the appearance of diagrams and also starts the rendering process .
|
||||
|
||||
c. The `mermaid.initialize()` call, which dictates the appearance of diagrams and also starts the rendering process .
|
||||
|
||||
**a. A reference to the external CDN in a `<script src>` tag, or a reference to mermaid.js as a separate file.:**
|
||||
|
||||
```html
|
||||
<body>
|
||||
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
|
||||
</body>
|
||||
```
|
||||
|
||||
**b. The embedded mermaid diagram definition inside a `<pre class="mermaid">`:**
|
||||
**a. The embedded mermaid diagram definition inside a `<pre class="mermaid">`:**
|
||||
|
||||
```html
|
||||
<body>
|
||||
@ -105,13 +95,14 @@ c. The `mermaid.initialize()` call, which dictates the appearance of diagrams an
|
||||
|
||||
**Notes**: Every Mermaid chart/graph/diagram definition, should have separate `<pre>` tags.
|
||||
|
||||
**c. The `mermaid.initialize()` call.**
|
||||
**b. The import of mermaid and the `mermaid.initialize()` call.**
|
||||
|
||||
`mermaid.initialize()` call takes all the definitions contained in all the `<pre class="mermaid">` tags that it finds in the html body and renders them into diagrams. Example:
|
||||
|
||||
```html
|
||||
<body>
|
||||
<script>
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@<MERMAID_VERSION>/dist/mermaid.esm.min.mjs';
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
</body>
|
||||
@ -133,11 +124,6 @@ Rendering in Mermaid is initialized by `mermaid.initialize()` call. You can plac
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
|
||||
<script>
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
|
||||
Here is one mermaid diagram:
|
||||
<pre class="mermaid">
|
||||
graph TD
|
||||
@ -154,6 +140,11 @@ Rendering in Mermaid is initialized by `mermaid.initialize()` call. You can plac
|
||||
B -->|tcp_456| C[Server1]
|
||||
B -->|tcp_456| D[Server2]
|
||||
</pre>
|
||||
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@<MERMAID_VERSION>/dist/mermaid.esm.min.mjs';
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@ -179,8 +170,8 @@ In this example mermaid.js is referenced in `src` as a separate JavaScript file,
|
||||
B --> C[Server1]
|
||||
B --> D[Server2]
|
||||
</pre>
|
||||
<script src="The\Path\In\Your\Package\mermaid.js"></script>
|
||||
<script>
|
||||
<script type="module">
|
||||
import mermaid from 'The/Path/In/Your/Package/mermaid.esm.mjs';
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
</body>
|
||||
@ -204,4 +195,4 @@ In this example mermaid.js is referenced in `src` as a separate JavaScript file,
|
||||
|
||||
**Comments from Knut Sveidqvist, creator of mermaid:**
|
||||
|
||||
- In early versions of mermaid, the `<script src>` tag was invoked in the `<head>` part of the web page. Nowadays we can place it in the `<body>` as seen above. Older parts of the documentation frequently reflects the previous way which still works.
|
||||
- In early versions of mermaid, the `<script>` tag was invoked in the `<head>` part of the web page. Nowadays we can place it in the `<body>` as seen above. Older parts of the documentation frequently reflects the previous way which still works.
|
||||
|
@ -39,23 +39,9 @@ We have compiled some Video [Tutorials](./Tutorials.md) on how to use the mermai
|
||||
|
||||
> Note:This topic explored in greater depth in the [User Guide for Beginners](./n00b-gettingStarted.md)
|
||||
|
||||
The easiest way to integrate mermaid on a web page requires three elements:
|
||||
The easiest way to integrate mermaid on a web page requires two elements:
|
||||
|
||||
1. Inclusion of the mermaid address in the html page using a `script` tag, in the `src` section.Example:
|
||||
|
||||
```html
|
||||
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
|
||||
```
|
||||
|
||||
2. The `mermaidAPI` call, in a separate `script` tag. Example:
|
||||
|
||||
```html
|
||||
<script>
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
```
|
||||
|
||||
3. A graph definition, inside `<div>` tags labeled `class=mermaid`. Example:
|
||||
- A graph definition, inside `<pre>` tags labeled `class=mermaid`. Example:
|
||||
|
||||
```html
|
||||
<pre class="mermaid">
|
||||
@ -66,8 +52,18 @@ The easiest way to integrate mermaid on a web page requires three elements:
|
||||
</pre>
|
||||
```
|
||||
|
||||
**Following these directions, mermaid starts at page load and (when the page has loaded) it will
|
||||
locate the graph definitions inside the `div` tags with `class="mermaid"` and return diagrams in SVG form, following given definitions.**
|
||||
- Inclusion of the mermaid address in the html page body using a `script` tag as an ESM import, and the `mermaidAPI` call.
|
||||
|
||||
Example:
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@<MERMAID_VERSION>/dist/mermaid.esm.min.mjs';
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
```
|
||||
|
||||
**Following these directions, mermaid starts at page load and (when the page has loaded) it will locate the graph definitions inside the `pre` tags with `class="mermaid"` and return diagrams in SVG form, following given definitions.**
|
||||
|
||||
## Simple full example:
|
||||
|
||||
@ -84,8 +80,8 @@ locate the graph definitions inside the `div` tags with `class="mermaid"` and re
|
||||
B-->C[fa:fa-ban forbidden]
|
||||
B-->D(fa:fa-spinner);
|
||||
</pre>
|
||||
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
|
||||
<script>
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@<MERMAID_VERSION>/dist/mermaid.esm.min.mjs';
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
</body>
|
||||
@ -204,18 +200,17 @@ fetch the graph definition from the site (perhaps from a textarea), render it an
|
||||
The example below show an outline of how this could be used. The example just logs the resulting SVG to the JavaScript console.
|
||||
|
||||
```html
|
||||
<script src="mermaid.js"></script>
|
||||
|
||||
<script>
|
||||
<script type="module">
|
||||
import mermaid from './mermaid.mjs';
|
||||
mermaid.mermaidAPI.initialize({ startOnLoad: false });
|
||||
$(function () {
|
||||
$(async function () {
|
||||
// Example of using the API var
|
||||
element = document.querySelector('#graphDiv');
|
||||
var insertSvg = function (svgCode, bindFunctions) {
|
||||
const insertSvg = function (svgCode, bindFunctions) {
|
||||
element.innerHTML = svgCode;
|
||||
};
|
||||
var graphDefinition = 'graph TB\na-->b';
|
||||
var graph = mermaid.mermaidAPI.render('graphDiv', graphDefinition, insertSvg);
|
||||
const graphDefinition = 'graph TB\na-->b';
|
||||
const graph = await mermaid.mermaidAPI.render('graphDiv', graphDefinition, insertSvg);
|
||||
});
|
||||
</script>
|
||||
```
|
||||
@ -339,7 +334,7 @@ on what kind of integration you use.
|
||||
```html
|
||||
<script src="../dist/mermaid.js"></script>
|
||||
<script>
|
||||
var config = { startOnLoad: true, flowchart: { useMaxWidth: false, htmlLabels: true } };
|
||||
let config = { startOnLoad: true, flowchart: { useMaxWidth: false, htmlLabels: true } };
|
||||
mermaid.initialize(config);
|
||||
</script>
|
||||
```
|
||||
|
@ -7,15 +7,8 @@ import { log } from './logger';
|
||||
import utils from './utils';
|
||||
import { mermaidAPI } from './mermaidAPI';
|
||||
import { addDetector } from './diagram-api/detectType';
|
||||
import {
|
||||
registerDiagram,
|
||||
DiagramDefinition,
|
||||
setLogLevel,
|
||||
getConfig,
|
||||
setupGraphViewbox,
|
||||
sanitizeText,
|
||||
} from './diagram-api/diagramAPI';
|
||||
import { isDetailedError } from './utils';
|
||||
import type { ParseErrorFunction } from './Diagram';
|
||||
|
||||
/**
|
||||
* ## init
|
||||
@ -53,17 +46,16 @@ const init = async function (
|
||||
callback?: Function
|
||||
) {
|
||||
try {
|
||||
log.info('Detectors in init', mermaid.detectors); // eslint-disable-line
|
||||
const conf = mermaidAPI.getConfig();
|
||||
if (typeof conf.lazyLoadedDiagrams !== 'undefined' && conf.lazyLoadedDiagrams.length > 0) {
|
||||
for (let i = 0; i < conf.lazyLoadedDiagrams.length; i++) {
|
||||
const { id, detector, loadDiagram } = await import(conf.lazyLoadedDiagrams[i]);
|
||||
if (conf?.lazyLoadedDiagrams && conf.lazyLoadedDiagrams.length > 0) {
|
||||
// Load all lazy loaded diagrams in parallel
|
||||
await Promise.allSettled(
|
||||
conf.lazyLoadedDiagrams.map(async (diagram: string) => {
|
||||
const { id, detector, loadDiagram } = await import(diagram);
|
||||
addDetector(id, detector, loadDiagram);
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
mermaid.detectors.forEach(({ id, detector, path }) => {
|
||||
addDetector(id, detector, path);
|
||||
});
|
||||
await initThrowsErrors(config, nodes, callback);
|
||||
} catch (e) {
|
||||
log.warn('Syntax Error rendering');
|
||||
@ -71,7 +63,7 @@ const init = async function (
|
||||
log.warn(e.str);
|
||||
}
|
||||
if (mermaid.parseError) {
|
||||
mermaid.parseError(e);
|
||||
mermaid.parseError(e as string);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -218,27 +210,10 @@ const parse = (txt: string) => {
|
||||
return mermaidAPI.parse(txt, mermaid.parseError);
|
||||
};
|
||||
|
||||
const connectDiagram = (
|
||||
id: string,
|
||||
diagram: DiagramDefinition,
|
||||
callback: (
|
||||
_log: any,
|
||||
_setLogLevel: any,
|
||||
_getConfig: any,
|
||||
_sanitizeText: any,
|
||||
_setupGraphViewbox: any
|
||||
) => void
|
||||
) => {
|
||||
registerDiagram(id, diagram, callback);
|
||||
// Todo move this connect call to after the diagram is actually loaded.
|
||||
callback(log, setLogLevel, getConfig, sanitizeText, setupGraphViewbox);
|
||||
};
|
||||
|
||||
const mermaid: {
|
||||
startOnLoad: boolean;
|
||||
diagrams: any;
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
parseError?: Function;
|
||||
parseError?: ParseErrorFunction;
|
||||
mermaidAPI: typeof mermaidAPI;
|
||||
parse: typeof parse;
|
||||
render: typeof mermaidAPI.render;
|
||||
@ -247,9 +222,6 @@ const mermaid: {
|
||||
initialize: typeof initialize;
|
||||
contentLoaded: typeof contentLoaded;
|
||||
setParseErrorHandler: typeof setParseErrorHandler;
|
||||
// Array of functions to use for detecting diagram types
|
||||
detectors: Array<any>; // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
connectDiagram: (id: string, diagram: DiagramDefinition, callback: (id: string) => void) => void;
|
||||
} = {
|
||||
startOnLoad: true,
|
||||
diagrams: {},
|
||||
@ -262,8 +234,6 @@ const mermaid: {
|
||||
parseError: undefined,
|
||||
contentLoaded,
|
||||
setParseErrorHandler,
|
||||
detectors: [],
|
||||
connectDiagram: connectDiagram,
|
||||
};
|
||||
|
||||
export default mermaid;
|
||||
|
@ -18,12 +18,11 @@ import { compile, serialize, stringify } from 'stylis';
|
||||
import pkg from '../package.json';
|
||||
import * as configApi from './config';
|
||||
import { addDiagrams } from './diagram-api/diagram-orchestration';
|
||||
import { addDetector } from './diagram-api/detectType';
|
||||
import classDb from './diagrams/class/classDb';
|
||||
import flowDb from './diagrams/flowchart/flowDb';
|
||||
import flowRenderer from './diagrams/flowchart/flowRenderer';
|
||||
import ganttDb from './diagrams/gantt/ganttDb';
|
||||
import Diagram, { getDiagramFromText } from './Diagram';
|
||||
import Diagram, { getDiagramFromText, type ParseErrorFunction } from './Diagram';
|
||||
import errorRenderer from './diagrams/error/errorRenderer';
|
||||
import { attachFunctions } from './interactionDb';
|
||||
import { log, setLogLevel } from './logger';
|
||||
@ -34,18 +33,12 @@ import DOMPurify from 'dompurify';
|
||||
import { MermaidConfig } from './config.type';
|
||||
import { evaluate } from './diagrams/common/common';
|
||||
|
||||
let hasLoadedDiagrams = false;
|
||||
|
||||
/**
|
||||
* @param text
|
||||
* @param parseError
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
function parse(text: string, parseError?: Function): boolean {
|
||||
if (!hasLoadedDiagrams) {
|
||||
function parse(text: string, parseError?: ParseErrorFunction): boolean {
|
||||
addDiagrams();
|
||||
hasLoadedDiagrams = true;
|
||||
}
|
||||
const diagram = new Diagram(text, parseError);
|
||||
return diagram.parse(text, parseError);
|
||||
}
|
||||
@ -122,10 +115,7 @@ const render = async function (
|
||||
cb: (svgCode: string, bindFunctions?: (element: Element) => void) => void,
|
||||
container?: Element
|
||||
): Promise<void> {
|
||||
if (!hasLoadedDiagrams) {
|
||||
addDiagrams();
|
||||
hasLoadedDiagrams = true;
|
||||
}
|
||||
configApi.reset();
|
||||
text = text.replace(/\r\n?/g, '\n'); // parser problems on CRLF ignore all CR and leave LF;;
|
||||
const graphInit = utils.detectInit(text);
|
||||
@ -486,11 +476,7 @@ async function initialize(options: MermaidConfig) {
|
||||
typeof options === 'object' ? configApi.setSiteConfig(options) : configApi.getSiteConfig();
|
||||
|
||||
setLogLevel(config.logLevel);
|
||||
|
||||
if (!hasLoadedDiagrams) {
|
||||
addDiagrams();
|
||||
hasLoadedDiagrams = true;
|
||||
}
|
||||
}
|
||||
|
||||
export const mermaidAPI = Object.freeze({
|
||||
|
5331
pnpm-lock.yaml
generated
5331
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
24
renovate.json
Normal file
24
renovate.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"extends": [
|
||||
"config:base",
|
||||
":rebaseStalePrs",
|
||||
"group:allNonMajor",
|
||||
"schedule:earlyMondays",
|
||||
":automergeMinor",
|
||||
":automergeTesters",
|
||||
":automergeLinters",
|
||||
":automergeTypes",
|
||||
":automergePatch"
|
||||
],
|
||||
"packageRules": [
|
||||
{
|
||||
"matchUpdateTypes": ["minor", "patch", "pin", "digest"],
|
||||
"automerge": true
|
||||
}
|
||||
],
|
||||
"dependencyDashboard": true,
|
||||
"major": {
|
||||
"dependencyDashboardApproval": true
|
||||
},
|
||||
"dependencyDashboardAutoclose": true
|
||||
}
|
@ -1,108 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
/* Visit https://aka.ms/tsconfig.json to read more about this file */
|
||||
|
||||
/* Projects */
|
||||
// "incremental": true /* Enable incremental compilation */,
|
||||
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
|
||||
// "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */
|
||||
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */
|
||||
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
|
||||
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
||||
|
||||
/* Language and Environment */
|
||||
"target": "ES6" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
|
||||
"lib": [
|
||||
"DOM",
|
||||
"ES2021"
|
||||
] /* Specify a set of bundled library declaration files that describe the target runtime environment. */,
|
||||
// "jsx": "preserve", /* Specify what JSX code is generated. */
|
||||
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
|
||||
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */
|
||||
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
|
||||
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */
|
||||
// "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */
|
||||
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
|
||||
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
|
||||
|
||||
/* Modules */
|
||||
"module": "ES6" /* Specify what module code is generated. */,
|
||||
"rootDir": "./src" /* Specify the root folder within your source files. */,
|
||||
"moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */,
|
||||
// "baseUrl": "./src" /* Specify the base directory to resolve non-relative module names. */,
|
||||
// "paths": {} /* Specify a set of entries that re-map imports to additional lookup locations. */,
|
||||
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
||||
// "typeRoots": [] /* Specify multiple folders that act like `./node_modules/@types`. */,
|
||||
"types": [
|
||||
"vitest/globals"
|
||||
] /* Specify type package names to be included without being referenced in a source file. */,
|
||||
|
||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||
"resolveJsonModule": true /* Enable importing .json files */,
|
||||
// "noResolve": true, /* Disallow `import`s, `require`s or `<reference>`s from expanding the number of files TypeScript should add to a project. */
|
||||
|
||||
/* JavaScript Support */
|
||||
"allowJs": true /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */,
|
||||
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
|
||||
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */
|
||||
|
||||
/* Emit */
|
||||
"declaration": true /* Generate .d.ts files from TypeScript and JavaScript files in your project. */,
|
||||
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
||||
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
||||
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
|
||||
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */
|
||||
"outDir": "./dist" /* Specify an output folder for all emitted files. */,
|
||||
// "removeComments": true, /* Disable emitting comments. */
|
||||
// "noEmit": true, /* Disable emitting files from a compilation. */
|
||||
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
|
||||
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */
|
||||
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
|
||||
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
|
||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
|
||||
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
|
||||
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
|
||||
// "newLine": "crlf", /* Set the newline character for emitting files. */
|
||||
// "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */
|
||||
// "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */
|
||||
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
|
||||
// "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
|
||||
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
|
||||
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
|
||||
|
||||
/* Interop Constraints */
|
||||
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
|
||||
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */,
|
||||
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
|
||||
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
|
||||
|
||||
/* Type Checking */
|
||||
"strict": true /* Enable all strict type-checking options. */,
|
||||
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */
|
||||
// "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */
|
||||
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
|
||||
// "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */
|
||||
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
|
||||
// "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */
|
||||
// "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
|
||||
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
|
||||
// "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */
|
||||
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */
|
||||
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
|
||||
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
|
||||
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
|
||||
// "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
|
||||
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
|
||||
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */
|
||||
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
|
||||
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
|
||||
|
||||
/* Completeness */
|
||||
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
||||
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
||||
},
|
||||
"include": ["./src/**/*.ts", "./package.json"]
|
||||
}
|
@ -29,7 +29,7 @@ mermaid.initialize({ flowchart: { htmlLabels: false } });
|
||||
**Example 2:**
|
||||
|
||||
```js
|
||||
var config = {
|
||||
const config = {
|
||||
startOnLoad: true,
|
||||
flowchart: { useMaxWidth: true, htmlLabels: true, curve: 'cardinal' },
|
||||
|
||||
@ -1560,7 +1560,7 @@ Returns **void**
|
||||
|
||||
```html
|
||||
<script>
|
||||
var config = {
|
||||
const config = {
|
||||
theme: 'default',
|
||||
logLevel: 'fatal',
|
||||
securityLevel: 'strict',
|
||||
|
@ -39,23 +39,9 @@ We have compiled some Video [Tutorials](./Tutorials.md) on how to use the mermai
|
||||
|
||||
> Note:This topic explored in greater depth in the [User Guide for Beginners](../intro/n00b-gettingStarted.md)
|
||||
|
||||
The easiest way to integrate mermaid on a web page requires three elements:
|
||||
The easiest way to integrate mermaid on a web page requires two elements:
|
||||
|
||||
1. Inclusion of the mermaid address in the html page using a `script` tag, in the `src` section.Example:
|
||||
|
||||
```html
|
||||
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
|
||||
```
|
||||
|
||||
2. The `mermaidAPI` call, in a separate `script` tag. Example:
|
||||
|
||||
```html
|
||||
<script>
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
```
|
||||
|
||||
3. A graph definition, inside `<div>` tags labeled `class=mermaid`. Example:
|
||||
- A graph definition, inside `<pre>` tags labeled `class=mermaid`. Example:
|
||||
|
||||
```html
|
||||
<pre class="mermaid">
|
||||
@ -66,8 +52,18 @@ The easiest way to integrate mermaid on a web page requires three elements:
|
||||
</pre>
|
||||
```
|
||||
|
||||
**Following these directions, mermaid starts at page load and (when the page has loaded) it will
|
||||
locate the graph definitions inside the `div` tags with `class="mermaid"` and return diagrams in SVG form, following given definitions.**
|
||||
- Inclusion of the mermaid address in the html page body using a `script` tag as an ESM import, and the `mermaidAPI` call.
|
||||
|
||||
Example:
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@<MERMAID_VERSION>/dist/mermaid.esm.min.mjs';
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
```
|
||||
|
||||
**Following these directions, mermaid starts at page load and (when the page has loaded) it will locate the graph definitions inside the `pre` tags with `class="mermaid"` and return diagrams in SVG form, following given definitions.**
|
||||
|
||||
## Simple full example:
|
||||
|
||||
@ -84,8 +80,8 @@ locate the graph definitions inside the `div` tags with `class="mermaid"` and re
|
||||
B-->C[fa:fa-ban forbidden]
|
||||
B-->D(fa:fa-spinner);
|
||||
</pre>
|
||||
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
|
||||
<script>
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@<MERMAID_VERSION>/dist/mermaid.esm.min.mjs';
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
</body>
|
||||
@ -211,11 +207,11 @@ The example below show an outline of how this could be used. The example just lo
|
||||
$(function () {
|
||||
// Example of using the API var
|
||||
element = document.querySelector('#graphDiv');
|
||||
var insertSvg = function (svgCode, bindFunctions) {
|
||||
const insertSvg = function (svgCode, bindFunctions) {
|
||||
element.innerHTML = svgCode;
|
||||
};
|
||||
var graphDefinition = 'graph TB\na-->b';
|
||||
var graph = mermaid.mermaidAPI.render('graphDiv', graphDefinition, insertSvg);
|
||||
const graphDefinition = 'graph TB\na-->b';
|
||||
const graph = mermaid.mermaidAPI.render('graphDiv', graphDefinition, insertSvg);
|
||||
});
|
||||
</script>
|
||||
```
|
||||
@ -339,7 +335,7 @@ on what kind of integration you use.
|
||||
```html
|
||||
<script src="../dist/mermaid.js"></script>
|
||||
<script>
|
||||
var config = { startOnLoad: true, flowchart: { useMaxWidth: false, htmlLabels: true } };
|
||||
let config = { startOnLoad: true, flowchart: { useMaxWidth: false, htmlLabels: true } };
|
||||
mermaid.initialize(config);
|
||||
</script>
|
||||
```
|
||||
|
@ -8,7 +8,7 @@ It is a JavaScript based diagramming and charting tool that renders Markdown-ins
|
||||
|
||||
<img src="/header.png" alt="" />
|
||||
|
||||
[![Build Status](https://travis-ci.org/mermaid-js/mermaid.svg?branch=master)](https://travis-ci.org/mermaid-js/mermaid) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE)
|
||||
[![Build CI Status](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml/badge.svg)](https://github.com/mermaid-js/mermaid/actions/workflows/build.yml) [![NPM](https://img.shields.io/npm/v/mermaid)](https://www.npmjs.com/package/mermaid) [![Coverage Status](https://coveralls.io/repos/github/mermaid-js/mermaid/badge.svg?branch=master)](https://coveralls.io/github/mermaid-js/mermaid?branch=master) [![CDN Status](https://img.shields.io/jsdelivr/npm/hm/mermaid)](https://www.jsdelivr.com/package/npm/mermaid) [![NPM](https://img.shields.io/npm/dm/mermaid)](https://www.npmjs.com/package/mermaid) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Twitter Follow](https://img.shields.io/twitter/follow/mermaidjs_?style=social)](https://twitter.com/mermaidjs_)
|
||||
|
||||
<!-- Mermaid book banner -->
|
||||
|
||||
@ -262,16 +262,16 @@ To Deploy Mermaid:
|
||||
|
||||
### [Mermaid API](../config/Setup.md):
|
||||
|
||||
**To deploy mermaid without a bundler, one can insert a `script` tag with an absolute address and a `mermaidAPI` call into the HTML like so:**
|
||||
**To deploy mermaid without a bundler, one can insert a `script` tag with an absolute address and a `mermaid.initialize` call into the HTML like so:**
|
||||
|
||||
```html
|
||||
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
|
||||
<script>
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@<MERMAID_VERSION>/dist/mermaid.esm.min.mjs';
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
```
|
||||
|
||||
**Doing so will command the mermaid parser to look for the `<div>` tags with `class="mermaid"`. From these tags mermaid will try to read the diagram/chart definitions and render them into SVG charts.**
|
||||
**Doing so will command the mermaid parser to look for the `<div>` or `<pre>` tags with `class="mermaid"`. From these tags mermaid will try to read the diagram/chart definitions and render them into SVG charts.**
|
||||
|
||||
**Examples can be found at** [Other examples](../syntax/examples)
|
||||
|
||||
|
@ -82,23 +82,13 @@ The API works by pulling rendering instructions from the source `mermaid.js` in
|
||||
|
||||
### Requirements for the Mermaid API.
|
||||
|
||||
When writing the .html file, we give three instructions inside the html code to the web browser:
|
||||
When writing the .html file, we give two instructions inside the html code to the web browser:
|
||||
|
||||
a. A reference for fetching the online mermaid renderer, through the `mermaid.js` or `mermaid.min.js`.
|
||||
a. The mermaid code for the diagram we want to create.
|
||||
|
||||
b. The mermaid code for the diagram we want to create.
|
||||
b. The importing of mermaid library through the `mermaid.esm.js` or `mermaid.esm.min.mjs` and the `mermaid.initialize()` call, which dictates the appearance of diagrams and also starts the rendering process .
|
||||
|
||||
c. The `mermaid.initialize()` call, which dictates the appearance of diagrams and also starts the rendering process .
|
||||
|
||||
**a. A reference to the external CDN in a `<script src>` tag, or a reference to mermaid.js as a separate file.:**
|
||||
|
||||
```html
|
||||
<body>
|
||||
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
|
||||
</body>
|
||||
```
|
||||
|
||||
**b. The embedded mermaid diagram definition inside a `<pre class="mermaid">`:**
|
||||
**a. The embedded mermaid diagram definition inside a `<pre class="mermaid">`:**
|
||||
|
||||
```html
|
||||
<body>
|
||||
@ -114,13 +104,14 @@ c. The `mermaid.initialize()` call, which dictates the appearance of diagrams an
|
||||
|
||||
**Notes**: Every Mermaid chart/graph/diagram definition, should have separate `<pre>` tags.
|
||||
|
||||
**c. The `mermaid.initialize()` call.**
|
||||
**b. The import of mermaid and the `mermaid.initialize()` call.**
|
||||
|
||||
`mermaid.initialize()` call takes all the definitions contained in all the `<pre class="mermaid">` tags that it finds in the html body and renders them into diagrams. Example:
|
||||
|
||||
```html
|
||||
<body>
|
||||
<script>
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@<MERMAID_VERSION>/dist/mermaid.esm.min.mjs';
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
</body>
|
||||
@ -142,11 +133,6 @@ Rendering in Mermaid is initialized by `mermaid.initialize()` call. You can plac
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
|
||||
<script>
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
|
||||
Here is one mermaid diagram:
|
||||
<pre class="mermaid">
|
||||
graph TD
|
||||
@ -163,6 +149,11 @@ Rendering in Mermaid is initialized by `mermaid.initialize()` call. You can plac
|
||||
B -->|tcp_456| C[Server1]
|
||||
B -->|tcp_456| D[Server2]
|
||||
</pre>
|
||||
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@<MERMAID_VERSION>/dist/mermaid.esm.min.mjs';
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@ -188,8 +179,8 @@ In this example mermaid.js is referenced in `src` as a separate JavaScript file,
|
||||
B --> C[Server1]
|
||||
B --> D[Server2]
|
||||
</pre>
|
||||
<script src="The\Path\In\Your\Package\mermaid.js"></script>
|
||||
<script>
|
||||
<script type="module">
|
||||
import mermaid from 'The/Path/In/Your/Package/mermaid.ems.mjs';
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
</script>
|
||||
</body>
|
||||
@ -213,4 +204,4 @@ In this example mermaid.js is referenced in `src` as a separate JavaScript file,
|
||||
|
||||
**Comments from Knut Sveidqvist, creator of mermaid:**
|
||||
|
||||
- In early versions of mermaid, the `<script src>` tag was invoked in the `<head>` part of the web page. Nowadays we can place it in the `<body>` as seen above. Older parts of the documentation frequently reflects the previous way which still works.
|
||||
- In early versions of mermaid, the `<script>` tag was invoked in the `<head>` part of the web page. Nowadays we can place it in the `<body>` as seen above. Older parts of the documentation frequently reflects the previous way which still works.
|
||||
|
@ -399,7 +399,7 @@ click Shape2 call callbackFunction() "This is a tooltip for a callback"
|
||||
|
||||
```html
|
||||
<script>
|
||||
var callbackFunction = function () {
|
||||
const callbackFunction = function () {
|
||||
alert('A callback was triggered');
|
||||
};
|
||||
</script>
|
||||
@ -451,10 +451,10 @@ Beginner's tip—a full example using interactive links in an HTML page:
|
||||
</pre>
|
||||
|
||||
<script>
|
||||
var callback = function () {
|
||||
const callback = function () {
|
||||
alert('A callback was triggered');
|
||||
};
|
||||
var config = {
|
||||
const config = {
|
||||
startOnLoad: true,
|
||||
securityLevel: 'loose',
|
||||
};
|
||||
|
@ -449,7 +449,7 @@ Examples of tooltip usage below:
|
||||
|
||||
```html
|
||||
<script>
|
||||
var callback = function () {
|
||||
const callback = function () {
|
||||
alert('A callback was triggered');
|
||||
};
|
||||
</script>
|
||||
@ -502,10 +502,10 @@ Beginner's tip—a full example using interactive links in a html context:
|
||||
</pre>
|
||||
|
||||
<script>
|
||||
var callback = function () {
|
||||
const callback = function () {
|
||||
alert('A callback was triggered');
|
||||
};
|
||||
var config = {
|
||||
const config = {
|
||||
startOnLoad: true,
|
||||
flowchart: { useMaxWidth: true, htmlLabels: true, curve: 'cardinal' },
|
||||
securityLevel: 'loose',
|
||||
|
@ -327,13 +327,13 @@ Beginner's tip—a full example using interactive links in an html context:
|
||||
</pre>
|
||||
|
||||
<script>
|
||||
var printArguments = function (arg1, arg2, arg3) {
|
||||
const printArguments = function (arg1, arg2, arg3) {
|
||||
alert('printArguments called with arguments: ' + arg1 + ', ' + arg2 + ', ' + arg3);
|
||||
};
|
||||
var printTask = function (taskId) {
|
||||
const printTask = function (taskId) {
|
||||
alert('taskId: ' + taskId);
|
||||
};
|
||||
var config = {
|
||||
const config = {
|
||||
startOnLoad: true,
|
||||
securityLevel: 'loose',
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user