Compare commits

..

174 Commits

Author SHA1 Message Date
Sidharth Vinod
361dd6a96e Add Security Policy 2022-11-03 10:59:57 +05:30
Sidharth Vinod
17adec38af chore: lint 2022-11-03 10:59:56 +05:30
Andre_601
638b9d9aae Discussions are now available 2022-11-03 10:59:56 +05:30
Andre_601
c8f6994895 Make colors required 2022-11-03 10:59:55 +05:30
Andre_601
1117a80500 make setup not required 2022-11-03 10:59:55 +05:30
Andre_601
5d83ec6fa2 Update theme_proposal.yml 2022-11-03 10:59:54 +05:30
Andre_601
bab5937426 Update syntaxt_proposal.yml 2022-11-03 10:59:54 +05:30
Andre_601
099a26977a Update diagram_proposal.yml 2022-11-03 10:59:53 +05:30
Andre_601
0b834485a8 Update bug_report.yml 2022-11-03 10:59:52 +05:30
Andre_601
41f21d4f72 Delete question.md 2022-11-03 10:59:50 +05:30
Andre_601
312e5f3d96 Create syntaxt_proposal.yml 2022-11-03 10:59:35 +05:30
Andre_601
6ef3e7f536 Create theme_proposal.yml 2022-11-03 10:59:34 +05:30
Andre_601
4f5228aec4 Create diagram_proposal.yml 2022-11-03 10:59:32 +05:30
Andre_601
b9daa35558 Switch to bug_report.yml 2022-11-03 10:59:10 +05:30
Andre_601
21304a9677 Create config.yml 2022-11-03 10:57:57 +05:30
Knut Sveidqvist
3f6613ea9f Updated mermaid version for the docs 2022-11-01 15:52:35 +01:00
Knut Sveidqvist
c8635c0b9b Merge branch 'release/9.2.0'
Conflicts:
	.github/ISSUE_TEMPLATE/bug_report.md
2022-11-01 15:37:00 +01:00
Knut Sveidqvist
e78ac9b92a Updated version 2022-11-01 15:27:20 +01:00
Sidharth Vinod
7a47fcfcbc Merge pull request #3727 from gibson042/2022-10-issue-template
chore: Update bug report template
2022-10-29 23:44:02 +05:30
Knut Sveidqvist
d4c19ffa59 Merge branch 'release/9.2.0' of github.com:mermaid-js/mermaid into release/9.2.0 2022-10-28 09:34:36 +02:00
Knut Sveidqvist
120940f9f4 Merge pull request #3731 from aloisklink/fix/load-lazy-loaded-diagrams-in-initThrowsErrors
[9.2.0] Support `lazyLoadedDiagrams` when calling `initThrowsErrorsAsync`
2022-10-28 09:33:58 +02:00
Alois Klink
48b1f489fc fix(mermaid): error if lazyLoadedDiagrams fails
Throws and logs a warning if lazyLoadedDiagrams fails to load properly.

Rendering is still performed, even on a lazyLoadedDiagrams failure.
2022-10-27 17:48:21 +01:00
Alois Klink
e62dd255bc feat: expose initThrowsErrorsAsync publicly
Expose the function `initThrowsErrorsAsync()` publicly
as `mermaid.initThrowsErrorsAsync()`.

It has the TSDoc `@alpha` and `@deprecated` tags, so people should
be warned that it might be modified in Mermaid v10 or earlier.

Needed for `mermaid-cli` to handle `lazyLoadedDiagrams`.
2022-10-27 17:48:12 +01:00
Alois Klink
13110c4ed9 docs(mermaid): document initThrowsErrorsAsync
Add some basic tsdoc for initThrowsErrorsAsync.
2022-10-27 17:02:50 +01:00
Alois Klink
327fcbf902 fix: lazy load diagrams in initThrowsErrorsAsync
Previously, calling initThrowsErrorsAsync would not
load any of the lazyLoadedDiagrams entries.

Adaptated from reverted commit 4601c90904
2022-10-27 16:50:57 +01:00
Alois Klink
81924f72c8 Revert "Merge branch 'release_9.2.0_buggfixes'"
This reverts commit 1a0309fb87, reversing
changes made to 56a8068a7f.

This is because the PR https://github.com/mermaid-js/mermaid/pull/3702
worked fine on the `develop` and `release_9.2.0_buggfixes` branches,
but had a bunch of git merge conflicts on the `release/9.2.0` branch.
2022-10-27 16:43:09 +01:00
Richard Gibson
5d048ce21e chore: Update bug report template
Add common pattern for reproduction with https://mermaid.live/
2022-10-26 23:17:15 -04:00
Knut Sveidqvist
1a0309fb87 Merge branch 'release_9.2.0_buggfixes'
Conflicts:
	packages/mermaid/src/mermaid.ts
2022-10-24 10:28:27 +02:00
Knut Sveidqvist
e793aae0ec Merge pull request #3702 from aloisklink/fix/initThrowErrors-support-lazyLoadedDiagrams
Support `lazyLoadedDiagrams` when calling `initThrowsErrors`
2022-10-24 08:28:50 +02:00
Alois Klink
3a2669e634 fix(mermaid): error if lazyLoadedDiagrams fails
Throw an error if lazyLoadedDiagrams fails to load properly.

Rendering is still performed, even on a lazyLoadedDiagrams failure.
2022-10-23 13:19:40 +01:00
Alois Klink
895a5eb78a docs(mermaid): document initThrowsErrors
Add some basic tsdoc for initThrowsErrors
2022-10-23 13:19:33 +01:00
Alois Klink
4601c90904 fix: load lazyLoadedDiagrams in initThrowsErrors
Previously, calling initThrowsErrors would not
load any of the lazyLoadedDiagrams entries.
2022-10-23 13:19:26 +01:00
Knut Sveidqvist
8ad8d39fe4 Versions for latest rcs 2022-10-20 12:57:29 +02:00
Sidharth Vinod
56a8068a7f fix: Error handling 2022-10-19 20:30:07 +05:30
Sidharth Vinod
d17aa6ecdd Merge branch 'release_9.2.0_buggfixes' into release/9.2.0
* release_9.2.0_buggfixes:
  fix: Add default arg to options
  fix: Build types
  chore: Update creation date
  fix: getElementById type issue.
2022-10-19 19:21:19 +05:30
Knut Sveidqvist
6f27363862 Merge pull request #3683 from mermaid-js/sidv/TSMindmap
fix: Converts mindmapDB to TS
2022-10-19 15:47:08 +02:00
Sidharth Vinod
5192608f7c Merge branch 'release_9.2.0_buggfixes' into sidv/TSMindmap
* release_9.2.0_buggfixes:
  fix: Add default arg to options
2022-10-19 19:13:46 +05:30
Sidharth Vinod
77f5e0d5f3 fix: Add default arg to options 2022-10-19 19:13:05 +05:30
Sidharth Vinod
4c311ea4b1 fix: TS errors 2022-10-19 19:03:29 +05:30
Sidharth Vinod
bbb3712284 Merge branch 'release_9.2.0_buggfixes' into sidv/TSMindmap
* release_9.2.0_buggfixes:
  Color fix for default nodes in mindmap, line uses inv color
2022-10-19 18:42:13 +05:30
Knut Sveidqvist
1388e201e5 Adding queue for async calls in mermaidts and fixing icon color 2022-10-19 14:30:36 +02:00
Sidharth Vinod
125312c114 chore: Add CORS to vite dev 2022-10-19 12:48:09 +02:00
Knut Sveidqvist
ea314cd24a Setting version to rc7 2022-10-19 08:01:21 +02:00
Knut Sveidqvist
8230c8f8b4 Merge remote-tracking branch 'origin/release/9.2.0' into release/9.2.0 2022-10-19 07:52:14 +02:00
Knut Sveidqvist
d115fbc6da Merge branch 'release_9.2.0_buggfixes' into release/9.2.0 2022-10-19 07:52:05 +02:00
Knut Sveidqvist
2ae8bf2987 Color fix for default nodes in mindmap, line uses inv color 2022-10-18 16:04:14 +02:00
Knut Sveidqvist
e86d7894f5 #3680 Add font familiy in a way that does remove other configuration 2022-10-17 10:51:41 +02:00
Knut Sveidqvist
752a6b2cb0 #3687 Separating the render specific data from the data related to parsing 2022-10-17 10:46:46 +02:00
Sidharth Vinod
97a842e651 fix: Build types 2022-10-17 11:45:19 +05:30
Sidharth Vinod
c83e29c6e3 chore: Update creation date 2022-10-16 10:11:19 +05:30
Sidharth Vinod
a4af3704ba fix: getElementById type issue.
Converts mindmapDB to TS
2022-10-16 10:06:44 +05:30
Sidharth Vinod
775fb80c43 Merge branch 'release_9.2.0_buggfixes' into release/9.2.0
* release_9.2.0_buggfixes:
  fix: Remove hardcoded numericLevel
  fix: Diagram load issue
2022-10-15 21:38:34 +05:30
Sidharth Vinod
aec1d80966 fix: Remove hardcoded numericLevel 2022-10-15 21:33:09 +05:30
Sidharth Vinod
58a53c0fa8 fix: Diagram load issue 2022-10-15 00:30:02 +05:30
Sidharth Vinod
b486177ca7 fix: Diagram load issue 2022-10-15 00:28:21 +05:30
Knut Sveidqvist
957e64fe8a Docs with lazy loading using rc bundles 2022-10-14 16:10:57 +02:00
Knut Sveidqvist
7881d1e457 Merge branch 'release_9.2.0_buggfixes' into release/9.2.0 2022-10-14 15:12:56 +02:00
Knut Sveidqvist
16be835c9b Removing error thrown disrupting rendering 2022-10-14 15:12:22 +02:00
Knut Sveidqvist
59cf085af5 #448 Fix for root nodes without children 2022-10-14 15:11:29 +02:00
Knut Sveidqvist
fc8db95597 Release 9.20 fixes of docsify 2022-10-14 15:05:00 +02:00
Knut Sveidqvist
cc10e62ebd Merge branch 'release_9.2.0_buggfixes' into release/9.2.0 2022-10-14 10:03:02 +02:00
Knut Sveidqvist
bed95c77a9 Some changes in the docs for mindmap 2022-10-14 10:01:32 +02:00
Knut Sveidqvist
d348f2847c Merge branch 'release_9.2.0_buggfixes' into release/9.2.0 2022-10-12 11:54:22 +02:00
Knut Sveidqvist
4d46ea9801 #3192 Adding link type of the std docs 2022-10-12 11:53:02 +02:00
Knut Sveidqvist
eec97d10af #3192 Adding the ability to create invisible links in flowcharts(v2) 2022-10-12 11:48:51 +02:00
Sidharth Vinod
ebef4a1416 chore: add auto-install-peers to .npmrc 2022-10-12 12:02:08 +05:30
Sidharth Vinod
24605784f2 chore: Update lockfile 2022-10-12 12:01:54 +05:30
Sidharth Vinod
3240f8ae56 feat: loadExternalDiagramsAtStartup 2022-10-12 11:56:39 +05:30
Sidharth Vinod
50f44c5cb0 Merge branch 'release/9.2.0' of https://github.com/mermaid-js/mermaid into release/9.2.0
* 'release/9.2.0' of https://github.com/mermaid-js/mermaid:
  #3252 Handling for trailing whitespaces in subgraph titles
2022-10-11 16:17:00 +05:30
Sidharth Vinod
cc2f4f779a feat: Add initializeAsync 2022-10-11 16:16:54 +05:30
Knut Sveidqvist
00ce0fc034 Merge branch 'release_9.2.0_buggfixes' into release/9.2.0 2022-10-11 12:30:38 +02:00
Knut Sveidqvist
551b37f969 #3252 Handling for trailing whitespaces in subgraph titles 2022-10-11 12:29:39 +02:00
Knut Sveidqvist
bc5ef5fb7d Fix for async issue in parse, adding parseAsync 2022-10-11 11:20:34 +02:00
Knut Sveidqvist
c20b8a0664 Merge pull request #3633 from mermaid-js/sidv/dirtyFixSync
fix: Dirty fix for sync render.
2022-10-11 09:04:43 +02:00
Sidharth Vinod
9660b0e9fb docs: Fix initial install step 2022-10-11 11:48:52 +05:30
Sidharth Vinod
23e590e09b Revert "fix(test): Rerender"
This reverts commit a017ffc3c9.
2022-10-10 22:04:33 +08:00
Sidharth Vinod
60e4585e20 Revert "fix: use async in render-after-error"
This reverts commit d59f878020.
2022-10-10 22:04:05 +08:00
Sidharth Vinod
ba436cc37a fix: Tests 2022-10-10 21:57:22 +08:00
Sidharth Vinod
960ea450e9 fix: Dirty fix for sync render.
Should be reverted for v10
2022-10-10 21:50:59 +08:00
Sidharth Vinod
8ffa7e6334 docs: Update twitter link 2022-10-10 20:47:34 +08:00
Sidharth Vinod
2fb1876023 Merge pull request #3627 from mermaid-js/renovate/configure
Configure Renovate
2022-10-10 20:43:26 +08:00
Sidharth Vinod
f5692e742b chore: renovate lint 2022-10-10 20:39:25 +08:00
Knut Sveidqvist
d7e7498fea Merge pull request #3630 from mermaid-js/sidv/node18
chore: Node 18
2022-10-10 14:25:58 +02:00
Matthieu MOREL
8ea1a1a077 Update renovate.json 2022-10-10 14:22:04 +02:00
Knut Sveidqvist
7cd281eea8 Merge pull request #3628 from mermaid-js/sidv/volta
chore: Add volta
2022-10-10 14:18:53 +02:00
Sidharth Vinod
1570eb7b73 chore: Bump node to v18 2022-10-10 20:13:50 +08:00
Knut Sveidqvist
5060c9f390 Merge pull request #3596 from mermaid-js/sidv/fixImportDoc
docs: Add mermaid version to script URL
2022-10-10 14:11:34 +02:00
Sidharth Vinod
1fea43e125 chore: Set node v16 2022-10-10 20:10:23 +08:00
Sidharth Vinod
ef47cc5b6f chore: Add volta 2022-10-10 20:07:59 +08:00
Knut Sveidqvist
e876c35ef9 Merge pull request #3591 from mermaid-js/sidv/fixDetectDiagram
fix Detect diagram fallback
2022-10-10 13:43:41 +02:00
renovate[bot]
800cb65706 chore(deps): add renovate.json 2022-10-10 11:27:41 +00:00
Sidharth Vinod
25ff005dd7 Merge pull request #3614 from Aniket1026/Aniket
Contribution.md updates
2022-10-10 14:15:15 +08:00
Aniket
72c266b242 Contrbution steps updated 2022-10-10 01:25:59 +05:30
Aniket
828f69f011 Link added for local setup 2022-10-09 20:54:51 +05:30
Aniket
ad4b079d63 contribution.md updated 2022-10-09 20:54:51 +05:30
Sidharth Vinod
5d4d7c5fbf Merge pull request #3579 from aryandeelwal/docs_keywords_branch
docs:Improved keywords in index.html
2022-10-09 22:28:47 +08:00
Sidharth Vinod
238b15df9d Merge branch 'sidv/noVar' into pr/aryandeelwal/3579
* sidv/noVar: (77 commits)
  fix: Fix eslint warnings
  docs: Fix docs path in Contributing.md
  Fix file name during "dev" script
  docs: Sync
  capitalization fix
  format Setup.md
  format cSpell.json
  format docs YAML
  format cSpell.json
  separate words & ignoreWords
  fix: "skin param"
  ignore the changelog
  Revert "fix: "skin param""
  fix: "skin param"
  fix: "corresponding"
  known terms
  known terms
  fix: "JetBrains"
  known terms
  known terms
  ...
2022-10-09 22:13:36 +08:00
Sidharth Vinod
6e2deb1fa7 fix: Fix eslint warnings 2022-10-09 22:08:32 +08:00
Sidharth Vinod
1255c0064b docs: Fix docs path in Contributing.md 2022-10-09 21:12:14 +08:00
Sidharth Vinod
d2300d375b Merge pull request #3608 from vallsv/patch-1
Fix file name during "pnpm run dev" script
2022-10-09 20:25:21 +08:00
Valentin Valls
235797a97c Fix file name during "dev" script 2022-10-08 19:22:55 +02:00
Sidharth Vinod
508fbccdb4 docs: Add twitter 2022-10-08 19:20:06 +08:00
Sidharth Vinod
ad0cb7ff3c Merge branch 'sidv/fixImportDoc' of https://github.com/mermaid-js/mermaid into sidv/fixImportDoc
* 'sidv/fixImportDoc' of https://github.com/mermaid-js/mermaid:
  Update packages/mermaid/src/docs/n00b-gettingStarted.md
2022-10-08 19:15:08 +08:00
Sidharth Vinod
bc258793ac docs: Add version to doc index.html 2022-10-08 19:15:01 +08:00
Sidharth Vinod
10d2e0a62f Update packages/mermaid/src/docs/n00b-gettingStarted.md
Co-authored-by: Alois Klink <alois@aloisklink.com>
2022-10-08 19:13:53 +08:00
Sidharth Vinod
738abc8946 chore: Cleanup 2022-10-08 13:41:04 +08:00
Sidharth Vinod
de5ad8644e fix: Optional detector 2022-10-08 13:38:40 +08:00
Sidharth Vinod
97b39bca95 fix: Remove connectDiagram 2022-10-08 13:22:06 +08:00
Sidharth Vinod
3698b30809 fix: Optimize diagram loading 2022-10-08 13:14:16 +08:00
Sidharth Vinod
069437842b Merge branch 'develop' into sidv/fixDetectDiagram
* develop: (50 commits)
  docs: Sync
  capitalization fix
  format Setup.md
  format cSpell.json
  format docs YAML
  format cSpell.json
  separate words & ignoreWords
  fix: "skin param"
  ignore the changelog
  Revert "fix: "skin param""
  fix: "skin param"
  fix: "corresponding"
  known terms
  known terms
  fix: "JetBrains"
  known terms
  known terms
  fix: "stable"
  known term
  add known term
  ...
2022-10-08 12:35:40 +08:00
Sidharth Vinod
ee13c7666d Merge pull request #3600 from SeanKilleen/docs-spellcheck
Automated docs spell-checking via GitHub Actions (and address all reported issues)
2022-10-08 12:29:48 +08:00
Sidharth Vinod
a23a7edd26 docs: Sync 2022-10-08 12:17:26 +08:00
Sean Killeen
e21da2ec7f capitalization fix 2022-10-07 21:58:52 -04:00
Sean Killeen
2b40bc0a48 format Setup.md 2022-10-07 21:56:28 -04:00
Sean Killeen
7e1006db26 format cSpell.json 2022-10-07 21:54:40 -04:00
Sean Killeen
44f463c4f4 format docs YAML 2022-10-07 21:42:39 -04:00
Sidharth Vinod
6029bdeee9 Merge branch 'develop' into sidv/fixImportDoc
* develop:
  Fix for broken test
  fix: build npm-script
  Fix for issue in classdiagram-v2 from the typescript updates
  fix: build npm-script
  chore: Cleanup
  chore: cleanup
  fix: dynamic import
  fix: module import in pie chart demo
  fix: use async in render-after-error
2022-10-08 09:41:11 +08:00
Sidharth Vinod
0261e7464a docs: ESM import 2022-10-08 09:40:54 +08:00
Sean Killeen
a22158b2e2 format cSpell.json 2022-10-07 21:37:40 -04:00
Sean Killeen
8a3bd5bcb8 separate words & ignoreWords 2022-10-07 21:34:40 -04:00
Sean Killeen
514d12d48c fix: "skin param" 2022-10-07 21:31:18 -04:00
Sean Killeen
01fac85cde ignore the changelog 2022-10-07 21:31:00 -04:00
Sean Killeen
18283bc48f Revert "fix: "skin param""
This reverts commit f31db315b8.
2022-10-07 21:30:36 -04:00
Sean Killeen
f31db315b8 fix: "skin param" 2022-10-07 21:30:10 -04:00
Sidharth Vinod
8a2aea219e docs: ESM import 2022-10-08 09:27:19 +08:00
Sean Killeen
034fe80411 fix: "corresponding" 2022-10-07 21:26:16 -04:00
Sean Killeen
6d9b695ada known terms 2022-10-07 21:25:50 -04:00
Sean Killeen
9c1da3bca1 known terms 2022-10-07 21:25:20 -04:00
Sean Killeen
0e61395aa9 fix: "JetBrains" 2022-10-07 21:24:32 -04:00
Sean Killeen
8215c7d98e known terms 2022-10-07 21:24:00 -04:00
Sean Killeen
ee45ab2e6c known terms 2022-10-07 21:23:22 -04:00
Sean Killeen
b1f3e21d28 fix: "stable" 2022-10-07 21:21:32 -04:00
Sean Killeen
a4b0e6b87b known term 2022-10-07 21:21:14 -04:00
Sean Killeen
9fe7152d98 add known term 2022-10-07 21:20:54 -04:00
Sean Killeen
0859f28a14 fix: "different" 2022-10-07 21:20:37 -04:00
Sean Killeen
56b9aab5ce fix: "previous" 2022-10-07 21:20:28 -04:00
Sean Killeen
aacc40e525 add known term 2022-10-07 21:20:14 -04:00
Sean Killeen
b0ed5e9be2 turn npmjs.org into link 2022-10-07 21:19:33 -04:00
Sean Killeen
3777ccb305 more known terms 2022-10-07 21:19:26 -04:00
Sean Killeen
6b736f0bb0 add known term 2022-10-07 21:18:34 -04:00
Sean Killeen
2e72c0bf6e add known term 2022-10-07 21:17:56 -04:00
Sean Killeen
a1757ba217 standardization: "sanitize" 2022-10-07 21:17:30 -04:00
Sean Killeen
5390c409d0 back-ticks for non-word terms 2022-10-07 21:17:11 -04:00
Sean Killeen
4f91c9a8de add known terms 2022-10-07 21:16:59 -04:00
Sean Killeen
8cf4efc190 fix: "source control" 2022-10-07 21:15:50 -04:00
Sean Killeen
405df09e43 standardization: "behavior" 2022-10-07 21:15:32 -04:00
Sean Killeen
86adf96021 fix: boundaries 2022-10-07 21:13:37 -04:00
Sean Killeen
a0c3de568b back-ticks for non-word terms 2022-10-07 21:13:07 -04:00
Sean Killeen
c10eb5af79 back-ticks for non-word terms 2022-10-07 21:12:25 -04:00
Sean Killeen
3c4acd2184 back-ticks for non-word terms 2022-10-07 21:11:39 -04:00
Sean Killeen
ab1573053e add terms 2022-10-07 21:10:50 -04:00
Sean Killeen
c404f6fe34 add terms 2022-10-07 21:09:28 -04:00
Sean Killeen
d24256e1c2 add knsv to dictionary 2022-10-07 21:06:29 -04:00
Sean Killeen
e494e2dc56 Revert "Back-ticks around non-word term"
This reverts commit ab2e727db9.
2022-10-07 21:06:11 -04:00
Sean Killeen
ab2e727db9 Back-ticks around non-word term 2022-10-07 21:06:02 -04:00
Sean Killeen
b9fcb66d28 Add known words 2022-10-07 21:05:50 -04:00
Sean Killeen
12e4819c49 Add cSpell config 2022-10-07 20:50:23 -04:00
Sean Killeen
0b54366705 Add GH Action 2022-10-07 20:50:20 -04:00
Knut Sveidqvist
c99fd2baa9 Merge pull request #3598 from mermaid-js/lazy-load-import
Lazy load import
2022-10-07 16:06:48 +02:00
Sidharth Vinod
868cb529aa Merge pull request #3595 from arpansaha13/develop
fix: pnpm clean in windows
2022-10-07 19:12:09 +08:00
lemontreejs
2d01548d02 fix: build npm-script 2022-10-07 16:03:32 +05:30
Sidharth Vinod
6fb92f6f3c fix: Restore conf. 2022-10-07 17:14:33 +08:00
Sidharth Vinod
f4a5b80eff fix: Load all extraDiagrams 2022-10-07 16:57:28 +08:00
lemontreejs
74c7a8585d fix: build npm-script 2022-10-07 14:14:28 +05:30
Arpan Saha
8c1046169f Merge branch 'mermaid-js:develop' into develop 2022-10-07 14:05:45 +05:30
Sidharth Vinod
2389f4a285 cleanup 2022-10-07 16:33:59 +08:00
Sidharth Vinod
24fb2337d7 cleanup 2022-10-07 16:30:44 +08:00
Sidharth Vinod
cc55a82b64 Merge branch 'develop' into sidv/fixDetectDiagram
* develop:
  chore: cleanup
  fix: dynamic import
  fix: Filename in viewer.js
  fix: pnpm not found
  fix: Import diagram
  Updated logic for diagram loading
  WIP
2022-10-07 16:30:34 +08:00
Sidharth Vinod
1f8fb56409 docs: Add badges 2022-10-07 16:01:33 +08:00
Sidharth Vinod
5865c890b5 docs: Add mermaid version to script URL 2022-10-07 15:52:32 +08:00
lemontreejs
00053b8e97 fix: module import in pie chart demo 2022-10-07 11:56:01 +05:30
Sidharth Vinod
1615c6d9f9 fix #3391: Remove flowchart as fallback for diagram detection. 2022-10-06 19:14:25 +08:00
aryandeelwal
43f3784c83 docs:Improved keywords in index.html 2022-10-05 17:10:24 +05:30
Knut Sveidqvist
c5d859e52e Merge branch 'release/9.1.7' 2022-09-13 20:12:08 +02:00
134 changed files with 3123 additions and 1204 deletions

View File

@@ -52,24 +52,25 @@
}, },
"overrides": [ "overrides": [
{ {
"files": "./**/*.html", "files": ["cypress/**", "demos/**"],
"rules": {
"no-undef": "off",
"jsdoc/require-jsdoc": "off"
}
},
{
"files": ["./cypress/**", "./demos/**"],
"rules": { "rules": {
"no-console": "off" "no-console": "off"
} }
}, },
{ {
"files": ["./**/*.spec.{ts,js}", "./cypress/**", "./demos/**", "./**/docs/**"], "files": ["*.spec.{ts,js}", "cypress/**", "demos/**", "**/docs/**"],
"rules": { "rules": {
"jsdoc/require-jsdoc": "off", "jsdoc/require-jsdoc": "off",
"@typescript-eslint/no-unused-vars": "off" "@typescript-eslint/no-unused-vars": "off"
} }
},
{
"files": ["*.html", "*.md", "**/*.md/*"],
"rules": {
"no-var": "error",
"no-undef": "off",
"@typescript-eslint/no-unused-vars": "off"
}
} }
] ]
} }

View File

@@ -1,43 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: 'Status: Triage, Type: Bug / Error'
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Code Sample**
If applicable, add the code sample or a link to the [live editor](https://mermaid.live).
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

69
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@@ -0,0 +1,69 @@
name: Bug Report
description: Create a report to help us improve
labels:
- 'Status: Triage'
- 'Type: Bug / Error'
body:
- type: markdown
attributes:
value: |-
## Security vulnerabilities
Please refer our [Security Policy](https://github.com/mermaid-js/.github/blob/main/SECURITY.md) and report to keep vulnerabilities confidential so we can release fixes first.
## Before you submit...
We like to help you, but in order to do that should you make a few things first:
- Use a clear and concise title
- Fill out the text fields with as much detail as possible.
- Never be shy to give us screenshots and/or code samples. It will help!
- type: textarea
attributes:
label: Description
description: Give a clear and concise description of what the bug is.
placeholder: When I do ... does ... happen.
validations:
required: true
- type: textarea
attributes:
label: Steps to reproduce
description: Give a step-by-step example on how to reproduce the bug.
placeholder: |-
1. Do this
2. Do that
3. ...
4. Bug!
validations:
required: true
- type: textarea
attributes:
label: Screenshots
description: If applicable, add screenshots to help explain your issue.
- type: textarea
attributes:
label: Code Sample
description: |-
If applicable, add the code sample or a link to the [Live Editor](https://mermaid.live).
Any text pasted here will be rendered as a Code block.
render: text
- type: textarea
attributes:
label: Setup
description: |-
Please fill out the below info.
Note that you only need to fill out one and not both sections.
value: |-
**Desktop**
- OS and Version: [Windows, Linux, Mac, ...]
- Browser and Version: [Chrome, Edge, Firefox]
**Smartphone**
- Device: [Samsung, iPhone, ...]
- OS and Version: [Android, iOS, ...]
- Browser and Version: [Chrome, Safari, ...]
- type: textarea
attributes:
label: Additional Context
description: Anything else to add?

17
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,17 @@
blank_issues_enabled: false
contact_links:
- name: GitHub Discussions
url: https://github.com/mermaid-js/mermaid/discussions
about: Ask the Community questions or share your own graphs in our discussions.
- name: Security Vulnerability
url: https://github.com/mermaid-js/.github/blob/main/SECURITY.md
about: Report security issues
- name: Slack
url: https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE
about: Join our Community on Slack for Help and a casual chat.
- name: Documentation
url: https://mermaid-js.github.io
about: Read our documentation for all that Mermaid.js can offer.
- name: Live Editor
url: https://mermaid.live
about: Try the live editor to preview graphs in no time.

View File

@@ -0,0 +1,42 @@
name: Diagram Proposal
description: Suggest a new Diagram Type to add to Mermaid.
labels:
- 'Status: Triage'
- 'Type: Enhancement'
body:
- type: markdown
attributes:
value: |-
## Before you submit...
First of all, thank you for proposing a new Diagram to us.
We are always happy about new ideas to improve Mermaid.js wherever possible.
To get the fastest and best response possible, make sure you do the following:
- Use a clear and concise title
- Fill out the text fields with as much detail as possible.
- Never be shy to give us screenshots and/or code samples. It will help!
- type: textarea
attributes:
label: Proposal
description: A clear and concise description of what should be added to Mermaid.js.
placeholder: Mermaid.js should add ... because ...
validations:
required: true
- type: textarea
attributes:
label: Use Cases
description: If applicable, give some use cases for where this diagram would be useful.
placeholder: The Diagram could be used for ...
- type: textarea
attributes:
label: Screenshots
description: If applicable, add screenshots to show possible examples of how the diagram may look like.
- type: textarea
attributes:
label: Code Sample
description: |-
If applicable, add a code sample for how to implement this new diagram.
The text will automatically be rendered as JavaScript code.
render: javascript

View File

@@ -1,19 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: 'Status: Triage, Type: Enhancement'
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@@ -1,16 +0,0 @@
---
name: Question
about: Get some help from the community.
title: ''
labels: 'Help wanted!, Type: Other'
assignees: ''
---
## Help us help you!
You want an answer. Here are some ways to get it quicker:
- Use a clear and concise title.
- Try to pose a clear and concise question.
- Include as much, or as little, code as necessary.
- Don't be shy to give us some screenshots, if it helps!

View File

@@ -0,0 +1,34 @@
name: Syntax Proposal
description: Suggest a new Syntax to add to Mermaid.js.
labels:
- 'Status: Triage'
- 'Type: Enhancement'
body:
- type: markdown
attributes:
value: |-
## Before you submit...
First of all, thank you for proposing a new Syntax to us.
We are always happy about new ideas to improve Mermaid.js wherever possible.
To get the fastest and best response possible, make sure you do the following:
- Use a clear and concise title
- Fill out the text fields with as much detail as possible. Examples are always welcome.
- Never be shy to give us screenshots and/or code samples. It will help!
- type: textarea
attributes:
label: Proposal
description: A clear and concise description of what Syntax should be added to Mermaid.js.
placeholder: Mermaid.js should add ... because ...
validations:
required: true
- type: textarea
attributes:
label: Example
description: If applicable, provide an example of the new Syntax.
- type: textarea
attributes:
label: Screenshots
description: If applicable, add screenshots to show possible examples of how the theme may look like.

View File

@@ -0,0 +1,42 @@
name: Theme Proposal
description: Suggest a new theme to add to Mermaid.js.
labels:
- 'Status: Triage'
- 'Type: Enhancement'
body:
- type: markdown
attributes:
value: |-
## Before you submit...
First of all, thank you for proposing a new Theme to us.
We are always happy about new ideas to improve Mermaid.js wherever possible.
To get the fastest and best response possible, make sure you do the following:
- Use a clear and concise title
- Fill out the text fields with as much detail as possible. Examples are always welcome!
- Never be shy to give us screenshots and/or code samples. It will help!
- type: textarea
attributes:
label: Proposal
description: A clear and concise description of what theme should be added to Mermaid.js.
placeholder: Mermaid.js should add ... because ...
validations:
required: true
- type: textarea
attributes:
label: Colors
description: |-
A detailed list of the different colour values to use.
A list of currently used variable names can be found [here](https://mermaid-js.github.io/mermaid/#/theming?id=theme-variables-reference-table)
placeholder: |-
- background: #f4f4f4
- primaryColor: #fff4dd
- ...
validations:
required: true
- type: textarea
attributes:
label: Screenshots
description: If applicable, add screenshots to show possible examples of how the theme may look like.

View File

@@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
node-version: [16.x] node-version: [18.x]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3

28
.github/workflows/docs.yml vendored Normal file
View File

@@ -0,0 +1,28 @@
name: Documentation Checks
on:
push:
branches:
- develop
paths:
- 'packages/mermaid/src/docs/**/*'
pull_request:
branches:
- develop
paths:
- 'packages/mermaid/src/docs/**/*'
jobs:
spellcheck:
name: 'Docs: Spellcheck'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
name: Check out the code
- uses: actions/setup-node@v1
name: Setup node
with:
node-version: '16'
- run: npm install -g cspell
name: Install cSpell
- run: cspell --config ./cSpell.json "packages/mermaid/src/docs/**/*.md" --no-progress
name: Run cSpell

View File

@@ -23,7 +23,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
node-version: [16.x] node-version: [18.x]
steps: steps:
- if: ${{ ! env.USE_APPLI }} - if: ${{ ! env.USE_APPLI }}
name: Warn if not using Applitools name: Warn if not using Applitools

View File

@@ -11,7 +11,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
node-version: [16.x] node-version: [18.x]
containers: [1, 2, 3, 4] containers: [1, 2, 3, 4]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3

View File

@@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
node-version: [16.x] node-version: [18.x]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3

View File

@@ -13,7 +13,7 @@ jobs:
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@v3 uses: actions/setup-node@v3
with: with:
node-version: 16.x node-version: 18.x
- name: Install Yarn - name: Install Yarn
run: npm i yarn --global run: npm i yarn --global

View File

@@ -14,7 +14,7 @@ jobs:
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@v3 uses: actions/setup-node@v3
with: with:
node-version: 16.x node-version: 18.x
- name: Install Yarn - name: Install Yarn
run: npm i yarn --global run: npm i yarn --global

View File

@@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
node-version: [16.x] node-version: [18.x]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3

3
.gitignore vendored
View File

@@ -32,3 +32,6 @@ cypress/snapshots/
.eslintcache .eslintcache
.tsbuildinfo .tsbuildinfo
tsconfig.tsbuildinfo tsconfig.tsbuildinfo
knsv*.html
local*.html

1
.npmrc Normal file
View File

@@ -0,0 +1 @@
auto-install-peers=true

View File

@@ -6,6 +6,7 @@ import pkg from '../package.json' assert { type: 'json' };
const { dependencies } = pkg; const { dependencies } = pkg;
const watch = process.argv.includes('--watch'); const watch = process.argv.includes('--watch');
const mermaidOnly = process.argv.includes('--mermaid');
const __dirname = fileURLToPath(new URL('.', import.meta.url)); const __dirname = fileURLToPath(new URL('.', import.meta.url));
type OutputOptions = Exclude< type OutputOptions = Exclude<
@@ -129,14 +130,19 @@ const buildPackage = async (entryName: keyof typeof packageOptions) => {
const main = async () => { const main = async () => {
const packageNames = Object.keys(packageOptions) as (keyof typeof packageOptions)[]; const packageNames = Object.keys(packageOptions) as (keyof typeof packageOptions)[];
for (const pkg of packageNames) { for (const pkg of packageNames) {
if (mermaidOnly && pkg !== 'mermaid') {
continue;
}
await buildPackage(pkg); await buildPackage(pkg);
} }
}; };
if (watch) { if (watch) {
build(getBuildConfig({ minify: false, watch, entryName: 'mermaid' })); build(getBuildConfig({ minify: false, watch, core: true, entryName: 'mermaid' }));
if (!mermaidOnly) {
build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-mindmap' })); build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-mindmap' }));
build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-example-diagram' })); build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-example-diagram' }));
}
} else { } else {
void main(); void main();
} }

View File

@@ -1,7 +1,15 @@
import express from 'express'; import express, { NextFunction, Request, Response } from 'express';
import { createServer as createViteServer } from 'vite'; import { createServer as createViteServer } from 'vite';
// import { getBuildConfig } from './build'; // import { getBuildConfig } from './build';
const cors = (req: Request, res: Response, next: NextFunction) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
};
async function createServer() { async function createServer() {
const app = express(); const app = express();
@@ -12,6 +20,7 @@ async function createServer() {
appType: 'custom', // don't include Vite's default HTML handling middlewares appType: 'custom', // don't include Vite's default HTML handling middlewares
}); });
app.use(cors);
app.use(express.static('./packages/mermaid/dist')); app.use(express.static('./packages/mermaid/dist'));
app.use(express.static('./packages/mermaid-example-diagram/dist')); app.use(express.static('./packages/mermaid-example-diagram/dist'));
app.use(express.static('./packages/mermaid-mindmap/dist')); app.use(express.static('./packages/mermaid-mindmap/dist'));

View File

@@ -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. 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 ## Development Installation
```bash ```bash
git clone git@github.com:mermaid-js/mermaid.git git clone git@github.com:mermaid-js/mermaid.git
cd mermaid cd mermaid
pnpm install # npx is required for first install as volta support for pnpm is not added yet.
npx pnpm install
pnpm test 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). 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 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 `/src/docs` are processed to generate the published documentation, and the resulting files are put into the `/docs` directory. 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 ```mermaid
flowchart LR flowchart LR
classDef default fill:#fff,color:black,stroke:black 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? 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 #### Adding to or changing the documentation organization

View File

@@ -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: 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:

View File

@@ -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) | 简体中文 [English](./README.md) | 简体中文

View File

@@ -1,3 +1 @@
import { vi } from 'vitest'; // DO NOT delete this file. It is used by vitest to mock the dagre-d3 module.
// export const render = vi.fn();

95
cSpell.json Normal file
View File

@@ -0,0 +1,95 @@
{
"version": "0.2",
"language": "en",
"words": [
"customizability",
"Gantt",
"jison",
"knsv",
"Knut",
"mindmap",
"Mindmaps",
"mitigations",
"sandboxed",
"Sveidqvist",
"verdana",
"Visio"
],
"ignoreWords": [
"Adamiecki",
"applitools",
"Asciidoctor",
"Astah",
"Bisheng",
"codedoc",
"Docsy",
"Doku",
"Gitea",
"Gitgraph",
"Grav",
"Inkdrop",
"Jaoude",
"mdbook",
"mermerd",
"mkdocs",
"phpbb",
"Plantuml",
"Playfair's",
"Podlite",
"redmine",
"sphinxcontrib",
"Tuleap"
],
"patterns": [
{
"name": "Markdown links",
"pattern": "\\((.*)\\)",
"description": ""
},
{
"name": "Markdown code blocks",
"pattern": "/^(\\s*`{3,}).*[\\s\\S]*?^\\1/gmx",
"description": "Taken from the cSpell example at https://cspell.org/configuration/patterns/#verbose-regular-expressions"
},
{
"name": "Inline code blocks",
"pattern": "\\`([^\\`\\r\\n]+?)\\`",
"description": "https://stackoverflow.com/questions/41274241/how-to-capture-inline-markdown-code-but-not-a-markdown-code-fence-with-regex"
},
{
"name": "Link contents",
"pattern": "\\<a(.*)\\>",
"description": ""
},
{
"name": "Snippet references",
"pattern": "-- snippet:(.*)",
"description": ""
},
{
"name": "Snippet references 2",
"pattern": "\\<\\[sample:(.*)",
"description": "another kind of snippet reference"
},
{
"name": "Multi-line code blocks",
"pattern": "/^\\s*```[\\s\\S]*?^\\s*```/gm"
},
{
"name": "HTML Tags",
"pattern": "<[^>]*>",
"description": "Reference: https://stackoverflow.com/questions/11229831/regular-expression-to-remove-html-tags-from-a-string"
}
],
"ignoreRegExpList": [
"Markdown links",
"Markdown code blocks",
"Inline code blocks",
"Link contents",
"Snippet references",
"Snippet references 2",
"Multi-line code blocks",
"HTML Tags"
],
"ignorePaths": ["packages/mermaid/src/docs/CHANGELOG.md"]
}

View File

@@ -75,16 +75,6 @@ classDiagram
<pre id="diagram" class="mermaid2"> <pre id="diagram" class="mermaid2">
mindmap mindmap
root root
A
B
C
D
E
A2
B2
C2
D2
E2
child1((Circle)) child1((Circle))
grandchild 1 grandchild 1
grandchild 2 grandchild 2

View File

@@ -14,16 +14,14 @@
mermaid.init({ startOnLoad: false }); mermaid.init({ startOnLoad: false });
mermaid.mermaidAPI.initialize({ securityLevel: 'strict' }); mermaid.mermaidAPI.initialize({ securityLevel: 'strict' });
(async () => {
try { try {
console.log('rendering'); console.log('rendering');
await mermaid.mermaidAPI.render('graphDiv', `>`); mermaid.mermaidAPI.render('graphDiv', `>`);
} catch (e) {} } catch (e) {}
await mermaid.mermaidAPI.render('graphDiv', `graph LR\n a --> b`, (html) => { mermaid.mermaidAPI.render('graphDiv', `graph LR\n a --> b`, (html) => {
document.getElementById('graph').innerHTML = html; document.getElementById('graph').innerHTML = html;
}); });
})();
</script> </script>
</body> </body>
</html> </html>

View File

@@ -19,10 +19,9 @@
function rerender(text) { function rerender(text) {
const graphText = `graph TD const graphText = `graph TD
A[${text}] -->|Get money| B(Go shopping)`; A[${text}] -->|Get money| B(Go shopping)`;
mermaid.mermaidAPI.render('id', graphText).then((svg) => { const graph = mermaid.mermaidAPI.render('id', graphText);
console.log('\x1b[35m%s\x1b[0m', '>> graph', svg); console.log('\x1b[35m%s\x1b[0m', '>> graph', graph);
document.getElementById('graph').innerHTML = svg; document.getElementById('graph').innerHTML = graph;
});
} }
</script> </script>
<button id="rerender" onclick="rerender('Saturday')">Rerender</button> <button id="rerender" onclick="rerender('Saturday')">Rerender</button>

View 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>

View File

@@ -93,7 +93,7 @@
throw new Error('XSS Succeeded'); throw new Error('XSS Succeeded');
} }
var diagram = 'classDiagram\n'; let diagram = 'classDiagram\n';
diagram += 'class Square~<img/src'; diagram += 'class Square~<img/src';
diagram += "='1'/onerror=xssAttack()>~{\n"; diagram += "='1'/onerror=xssAttack()>~{\n";
diagram += 'id A\n'; diagram += 'id A\n';

View File

@@ -93,7 +93,7 @@
throw new Error('XSS Succeeded'); 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 += 's2 : This is a state description<img/src';
diagram += "='1'/onerror=xssAttack()>"; diagram += "='1'/onerror=xssAttack()>";

View File

@@ -93,7 +93,7 @@
throw new Error('XSS Succeeded'); throw new Error('XSS Succeeded');
} }
var diagram = 'stateDiagram-v2\n'; let diagram = 'stateDiagram-v2\n';
diagram += 's2 : A<img/src'; diagram += 's2 : A<img/src';
diagram += "='1'/onerror=xssAttack()>"; diagram += "='1'/onerror=xssAttack()>";

View File

@@ -93,7 +93,7 @@
throw new Error('XSS Succeeded'); 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 += 'if_state --> False: if n < 0<img/src';
diagram += "='1'/onerror=xssAttack()>"; diagram += "='1'/onerror=xssAttack()>";

View File

@@ -93,7 +93,7 @@
throw new Error('XSS Succeeded'); throw new Error('XSS Succeeded');
} }
var diagram = 'classDiagram\n'; let diagram = 'classDiagram\n';
diagram += 'classA <-- classB : <ifr'; diagram += 'classA <-- classB : <ifr';
diagram += "ame/srcdoc='<scr"; diagram += "ame/srcdoc='<scr";
diagram += 'ipt>parent.xssAttack(`XSS`)</'; diagram += 'ipt>parent.xssAttack(`XSS`)</';

View File

@@ -93,7 +93,7 @@
throw new Error('XSS Succeeded'); throw new Error('XSS Succeeded');
} }
var diagram = `sequenceDiagram let diagram = `sequenceDiagram
participant John participant John
links John: {"XSS": "javas`; links John: {"XSS": "javas`;
diagram += `cript:alert('AudioParam')"}`; diagram += `cript:alert('AudioParam')"}`;

View File

@@ -93,7 +93,7 @@
throw new Error('XSS Succeeded'); throw new Error('XSS Succeeded');
} }
var diagram = `sequenceDiagram let diagram = `sequenceDiagram
participant Alice participant Alice
links Alice: { "Click me!" : "javasjavascript:cript:alert('goose')" }`; links Alice: { "Click me!" : "javasjavascript:cript:alert('goose')" }`;

View File

@@ -93,7 +93,7 @@
throw new Error('XSS Succeeded'); throw new Error('XSS Succeeded');
} }
var diagram = `sequenceDiagram let diagram = `sequenceDiagram
participant Alice participant Alice
link Alice: Click Me!@javasjavascript:cript:alert("goose")`; link Alice: Click Me!@javasjavascript:cript:alert("goose")`;

View File

@@ -93,7 +93,7 @@
throw new Error('XSS Succeeded'); 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`; Class "<img/src='x'/onerror=xssAttack(1)>" <--> "<img/src='x'/onerror=xssAttack(2)>" C2: Cool label`;
// // var diagram = "stateDiagram-v2\n"; // // var diagram = "stateDiagram-v2\n";

View File

@@ -93,7 +93,7 @@
throw new Error('XSS Succeeded'); throw new Error('XSS Succeeded');
} }
var diagram = `classDiagram let diagram = `classDiagram
class Shape{ class Shape{
<<<img/src='1'/`; <<<img/src='1'/`;

View File

@@ -54,9 +54,9 @@
startOnLoad: true, startOnLoad: true,
useMaxWidth: true, useMaxWidth: true,
}); });
var cnt = 0; let cnt = 0;
var a; let a;
var handler = setInterval(() => { const handler = setInterval(() => {
cnt++; cnt++;
a = {}; a = {};
if (typeof a.polluted !== 'undefined') { if (typeof a.polluted !== 'undefined') {

View File

@@ -96,7 +96,7 @@
// var diagram = ` graph TD // var diagram = ` graph TD
// A --> B["&lt;a href='javasc`; // A --> B["&lt;a href='javasc`;
// diagram += `ript#colon;xssAttack()'&gt;AAA&lt;/a&gt;"]`; // diagram += `ript#colon;xssAttack()'&gt;AAA&lt;/a&gt;"]`;
var diagram = ` graph TD let diagram = ` graph TD
A --> B["<a href='javasc`; A --> B["<a href='javasc`;
diagram += `ript#colon;xssAttack()'>AAA</a>"]`; diagram += `ript#colon;xssAttack()'>AAA</a>"]`;
// diagram += '//via.placeholder.com/64\' width=64 />"]'; // diagram += '//via.placeholder.com/64\' width=64 />"]';

View File

@@ -96,7 +96,7 @@
// var diagram = ` graph TD // var diagram = ` graph TD
// A --> B["&lt;a href='javasc`; // A --> B["&lt;a href='javasc`;
// diagram += `ript#colon;xssAttack()'&gt;AAA&lt;/a&gt;"]`; // diagram += `ript#colon;xssAttack()'&gt;AAA&lt;/a&gt;"]`;
var diagram = ` graph TD let diagram = ` graph TD
A --> B["<a href='javasc`; A --> B["<a href='javasc`;
diagram += `ript#9;t#colon;xssAttack()'>AAA</a>"]`; diagram += `ript#9;t#colon;xssAttack()'>AAA</a>"]`;
// diagram += '//via.placeholder.com/64\' width=64 />"]'; // diagram += '//via.placeholder.com/64\' width=64 />"]';

View File

@@ -42,9 +42,9 @@
startOnLoad: true, startOnLoad: true,
useMaxWidth: true, useMaxWidth: true,
}); });
var cnt = 0; let cnt = 0;
var a; let a;
var handler = setInterval(() => { const handler = setInterval(() => {
cnt++; cnt++;
a = {}; a = {};
if (typeof a.polluted !== 'undefined') { if (typeof a.polluted !== 'undefined') {

View File

@@ -85,7 +85,7 @@
alert('It worked'); alert('It worked');
} }
var diagram = '%%{init: {"flowchart": {"htmlLabels": "true"}} }%%\n'; let diagram = '%%{init: {"flowchart": {"htmlLabels": "true"}} }%%\n';
diagram += 'flowchart\n'; diagram += 'flowchart\n';
diagram += 'A["<ifra'; diagram += 'A["<ifra';
diagram += "me srcdoc='<scrip"; diagram += "me srcdoc='<scrip";

View File

@@ -92,7 +92,7 @@
document.getElementsByTagName('body')[0].appendChild(div); document.getElementsByTagName('body')[0].appendChild(div);
throw new Error('XSS Succeeded'); throw new Error('XSS Succeeded');
} }
var diagram = 'graph LR\n'; let diagram = 'graph LR\n';
diagram += 'B-->D("<img onerror=location=`java'; diagram += 'B-->D("<img onerror=location=`java';
// diagram += "script\u003aalert\u0028document.domain\u0029\` src=x>\"\);\n"; // diagram += "script\u003aalert\u0028document.domain\u0029\` src=x>\"\);\n";
diagram += 'script\x3a;xssAttack\u0028\u0029` src=x>");\n'; diagram += 'script\x3a;xssAttack\u0028\u0029` src=x>");\n';

View File

@@ -92,7 +92,7 @@
document.getElementsByTagName('body')[0].appendChild(div); document.getElementsByTagName('body')[0].appendChild(div);
throw new Error('XSS Succeeded'); throw new Error('XSS Succeeded');
} }
var diagram = 'graph LR\n'; let diagram = 'graph LR\n';
diagram += 'A(<img/src/onerror=xssAttack`1`>)'; diagram += 'A(<img/src/onerror=xssAttack`1`>)';
// diagram += "script\u003aalert\u0028document.domain\u0029\` src=x>\"\);\n"; // diagram += "script\u003aalert\u0028document.domain\u0029\` src=x>\"\);\n";
console.log(diagram); console.log(diagram);

View File

@@ -92,7 +92,7 @@
document.getElementsByTagName('body')[0].appendChild(div); document.getElementsByTagName('body')[0].appendChild(div);
throw new Error('XSS Succeeded'); throw new Error('XSS Succeeded');
} }
var diagram = 'graph LR\n'; let diagram = 'graph LR\n';
diagram += " B(<a href='<"; diagram += " B(<a href='<";
diagram += 'script></'; diagram += 'script></';
diagram += "script>Javascript:xssAttack`1`'>Click)"; diagram += "script>Javascript:xssAttack`1`'>Click)";

View File

@@ -93,7 +93,7 @@
throw new Error('XSS Succeeded'); throw new Error('XSS Succeeded');
} }
var diagram = 'stateDiagram-v2\n'; let diagram = 'stateDiagram-v2\n';
diagram += "<img/src='1'/onerror=xssAttack()> --> B"; diagram += "<img/src='1'/onerror=xssAttack()> --> B";
// diagram += "script\u003aalert\u0028document.domain\u0029\` src=x>\"\);\n"; // diagram += "script\u003aalert\u0028document.domain\u0029\` src=x>\"\);\n";
console.log(diagram); console.log(diagram);

View File

@@ -93,7 +93,7 @@
throw new Error('XSS Succeeded'); throw new Error('XSS Succeeded');
} }
var diagram = 'stateDiagram-v2\n'; let diagram = 'stateDiagram-v2\n';
diagram += "<img/src='1'/onerror=xssAttack()> --> B"; diagram += "<img/src='1'/onerror=xssAttack()> --> B";
// diagram += "script\u003aalert\u0028document.domain\u0029\` src=x>\"\);\n"; // diagram += "script\u003aalert\u0028document.domain\u0029\` src=x>\"\);\n";
console.log(diagram); console.log(diagram);

View File

@@ -277,7 +277,7 @@
<script> <script>
function testClick(nodeId) { function testClick(nodeId) {
console.log('clicked', 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'; document.querySelector('body').style.backgroundColor = 'yellow';
setTimeout(function () { setTimeout(function () {
document.querySelector('body').style.backgroundColor = originalBgColor; document.querySelector('body').style.backgroundColor = originalBgColor;

View File

@@ -46,7 +46,7 @@
<script> <script>
function testClick(nodeId) { function testClick(nodeId) {
console.log('clicked', 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'; document.querySelector('body').style.backgroundColor = 'yellow';
setTimeout(function () { setTimeout(function () {
document.querySelector('body').style.backgroundColor = originalBgColor; document.querySelector('body').style.backgroundColor = originalBgColor;

View File

@@ -1513,7 +1513,7 @@
<script> <script>
function testClick(nodeId) { function testClick(nodeId) {
console.log('clicked', 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'; document.querySelector('body').style.backgroundColor = 'yellow';
setTimeout(function () { setTimeout(function () {
document.querySelector('body').style.backgroundColor = originalBgColor; document.querySelector('body').style.backgroundColor = originalBgColor;

View File

@@ -174,7 +174,7 @@
} }
function testClick(nodeId) { function testClick(nodeId) {
console.log('clicked', 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'; document.querySelector('body').style.backgroundColor = 'yellow';
setTimeout(function () { setTimeout(function () {
document.querySelector('body').style.backgroundColor = originalBgColor; document.querySelector('body').style.backgroundColor = originalBgColor;

View File

@@ -10,7 +10,7 @@ It is a JavaScript based diagramming and charting tool that renders Markdown-ins
<img src="img/header.png" alt="" /> <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 --> <!-- Mermaid book banner -->
@@ -271,16 +271,16 @@ To Deploy Mermaid:
### [Mermaid API](./Setup.md): ### [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 ```html
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script> <script type="module">
<script> import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@9/dist/mermaid.esm.min.mjs';
mermaid.initialize({ startOnLoad: true }); mermaid.initialize({ startOnLoad: true });
</script> </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) **Examples can be found at** [Other examples](/examples)
@@ -347,7 +347,7 @@ Update version number in `package.json`.
npm publish npm publish
``` ```
The above command generates files into the `dist` folder and publishes them to npmjs.org. The above command generates files into the `dist` folder and publishes them to \<npmjs.org>.
## Related projects ## Related projects
@@ -363,7 +363,7 @@ Detailed information about how to contribute can be found in the [contribution g
## Security and safe diagrams ## Security and safe diagrams
For public sites, it can be precarious to retrieve text from users on the internet, storing that content for presentation in a browser at a later stage. The reason is that the user content can contain embedded malicious scripts that will run when the data is presented. For Mermaid this is a risk, specially as mermaid diagrams contain many characters that are used in html which makes the standard sanitation unusable as it also breaks the diagrams. We still make an effort to sanitise the incoming code and keep refining the process but it is hard to guarantee that there are no loop holes. For public sites, it can be precarious to retrieve text from users on the internet, storing that content for presentation in a browser at a later stage. The reason is that the user content can contain embedded malicious scripts that will run when the data is presented. For Mermaid this is a risk, specially as mermaid diagrams contain many characters that are used in html which makes the standard sanitation unusable as it also breaks the diagrams. We still make an effort to sanitize the incoming code and keep refining the process but it is hard to guarantee that there are no loop holes.
As an extra level of security for sites with external users we are happy to introduce a new security level in which the diagram is rendered in a sandboxed iframe preventing JavaScript in the code from being executed. This is a great step forward for better security. As an extra level of security for sites with external users we are happy to introduce a new security level in which the diagram is rendered in a sandboxed iframe preventing JavaScript in the code from being executed. This is a great step forward for better security.

View File

@@ -74,15 +74,15 @@ Theme , the CSS style sheet
| Parameter | Description | Type | Required | Values | | Parameter | Description | Type | Required | Values |
| ------------- | --------------------------------- | ------ | -------- | ------------------------------------------ | | ------------- | --------------------------------- | ------ | -------- | ------------------------------------------ |
| securityLevel | Level of trust for parsed diagram | string | Required | 'sandbox', 'strict', 'loose', 'antiscript' | | securityLevel | Level of trust for parsed diagram | string | Required | `sandbox`, `strict`, `loose`, `antiscript` |
**Notes**: **Notes**:
- **strict**: (**default**) tags in text are encoded, click functionality is disabled - **`strict`**: (**default**) tags in text are encoded, click functionality is disabled
- **loose**: tags in text are allowed, click functionality is enabled - **`loose`**: tags in text are allowed, click functionality is enabled
- **antiscript**: html tags in text are allowed, (only script element is removed), click - **`antiscript`**: html tags in text are allowed, (only script element is removed), click
functionality is enabled functionality is enabled
- **sandbox**: With this security level all rendering takes place in a sandboxed iframe. This - **`sandbox`**: With this security level all rendering takes place in a sandboxed iframe. This
prevent any JavaScript from running in the context. This may hinder interactive functionality prevent any JavaScript from running in the context. This may hinder interactive functionality
of the diagram like scripts, popups in sequence diagram or links to other tabs/targets etc. of the diagram like scripts, popups in sequence diagram or links to other tabs/targets etc.
@@ -121,7 +121,7 @@ Default value: \['secure', 'securityLevel', 'startOnLoad', 'maxTextSize']
This option controls if the generated ids of nodes in the SVG are generated randomly or based This option controls if the generated ids of nodes in the SVG are generated randomly or based
on a seed. If set to false, the IDs are generated based on the current date and thus are not on a seed. If set to false, the IDs are generated based on the current date and thus are not
deterministic. This is the default behaviour. deterministic. This is the default behavior.
**Notes**: **Notes**:
@@ -213,15 +213,15 @@ Default value: true
### defaultRenderer ### defaultRenderer
| Parameter | Description | Type | Required | Values | | Parameter | Description | Type | Required | Values |
| --------------- | ----------- | ------- | -------- | ----------------------- | | --------------- | ----------- | ------- | -------- | --------------------------- |
| defaultRenderer | See notes | boolean | 4 | dagre-d3, dagre-wrapper | | defaultRenderer | See notes | boolean | 4 | `dagre-d3`, `dagre-wrapper` |
**Notes:** **Notes:**
Decides which rendering engine that is to be used for the rendering. Legal values are: Decides which rendering engine that is to be used for the rendering. Legal values are:
dagre-d3 dagre-wrapper - wrapper for dagre implemented in mermaid `dagre-d3` `dagre-wrapper` - wrapper for `dagre` implemented in mermaid
Default value: 'dagre-wrapper' Default value: `dagre-wrapper`
## sequence ## sequence
@@ -738,15 +738,15 @@ Default value: true
## defaultRenderer ## defaultRenderer
| Parameter | Description | Type | Required | Values | | Parameter | Description | Type | Required | Values |
| --------------- | ----------- | ------- | -------- | ----------------------- | | --------------- | ----------- | ------- | -------- | --------------------------- |
| defaultRenderer | See notes | boolean | 4 | dagre-d3, dagre-wrapper | | defaultRenderer | See notes | boolean | 4 | `dagre-d3`, `dagre-wrapper` |
**Notes**: **Notes**:
Decides which rendering engine that is to be used for the rendering. Legal values are: Decides which rendering engine that is to be used for the rendering. Legal values are:
dagre-d3 dagre-wrapper - wrapper for dagre implemented in mermaid `dagre-d3` `dagre-wrapper` - wrapper for `dagre` implemented in mermaid
Default value: 'dagre-d3' Default value: `dagre-d3`
## useMaxWidth ## useMaxWidth
@@ -764,15 +764,15 @@ Default value: true
## defaultRenderer ## defaultRenderer
| Parameter | Description | Type | Required | Values | | Parameter | Description | Type | Required | Values |
| --------------- | ----------- | ------- | -------- | ----------------------- | | --------------- | ----------- | ------- | -------- | --------------------------- |
| defaultRenderer | See notes | boolean | 4 | dagre-d3, dagre-wrapper | | defaultRenderer | See notes | boolean | 4 | `dagre-d3`, `dagre-wrapper` |
**Notes:** **Notes:**
Decides which rendering engine that is to be used for the rendering. Legal values are: Decides which rendering engine that is to be used for the rendering. Legal values are:
dagre-d3 dagre-wrapper - wrapper for dagre implemented in mermaid `dagre-d3` `dagre-wrapper` - wrapper for `dagre` implemented in mermaid
Default value: 'dagre-d3' Default value: `dagre-d3`
## er ## er
@@ -994,7 +994,7 @@ Default value: 4
| --------------- | ----------- | ------- | -------- | ------------------ | | --------------- | ----------- | ------- | -------- | ------------------ |
| c4BoundaryInRow | See Notes | Integer | Required | Any Positive Value | | c4BoundaryInRow | See Notes | Integer | Required | Any Positive Value |
**Notes:** How many boundarys to place in each row. **Notes:** How many boundaries to place in each row.
Default value: 2 Default value: 2
@@ -1561,7 +1561,7 @@ Returns **void**
```html ```html
<script> <script>
var config = { const config = {
theme: 'default', theme: 'default',
logLevel: 'fatal', logLevel: 'fatal',
securityLevel: 'strict', securityLevel: 'strict',

View File

@@ -19,7 +19,7 @@ The diagram authors can now add the accessibility options in the diagram definit
- `accTitle: "Your Accessibility Title"` or - `accTitle: "Your Accessibility Title"` or
- `accDescr: "Your Accessibility Description"` - `accDescr: "Your Accessibility Description"`
**When these two options are defined, they will add a coressponding `<title>` and `<desc>` tag in the SVG.** **When these two options are defined, they will add a corresponding `<title>` and `<desc>` tag in the SVG.**
Let us take a look at the following example with a flowchart diagram: Let us take a look at the following example with a flowchart diagram:

View File

@@ -589,7 +589,7 @@ click Shape2 call callbackFunction() "This is a tooltip for a callback"
```html ```html
<script> <script>
var callbackFunction = function () { const callbackFunction = function () {
alert('A callback was triggered'); alert('A callback was triggered');
}; };
</script> </script>
@@ -653,10 +653,10 @@ Beginner's tip—a full example using interactive links in an HTML page:
</pre> </pre>
<script> <script>
var callback = function () { const callback = function () {
alert('A callback was triggered'); alert('A callback was triggered');
}; };
var config = { const config = {
startOnLoad: true, startOnLoad: true,
securityLevel: 'loose', securityLevel: 'loose',
}; };

View File

@@ -649,7 +649,7 @@ A node can have click events bound that lead to either a JavaScript callback or
```html ```html
<script> <script>
var callback = function (nodeId) { const callback = function (nodeId) {
alert('A callback was triggered on ' + nodeId); alert('A callback was triggered on ' + nodeId);
}; };
</script> </script>
@@ -727,10 +727,10 @@ Beginner's tip—here's a full example of using interactive links in HTML:
</pre> </pre>
<script> <script>
var callback = function () { const callback = function () {
alert('A callback was triggered'); alert('A callback was triggered');
}; };
var config = { const config = {
startOnLoad: true, startOnLoad: true,
flowchart: { flowchart: {
useMaxWidth: true, useMaxWidth: true,

View File

@@ -264,6 +264,20 @@ flowchart LR
A --- B A --- B
``` ```
### An invisisble link
This can be a usefull tool in some instances where you want to alter the default positining of a node.
```mermaid-example
flowchart LR
A ~~~ B
```
```mermaid
flowchart LR
A ~~~ B
```
### Text on links ### Text on links
```mermaid-example ```mermaid-example
@@ -695,7 +709,7 @@ Examples of tooltip usage below:
```html ```html
<script> <script>
var callback = function () { const callback = function () {
alert('A callback was triggered'); alert('A callback was triggered');
}; };
</script> </script>
@@ -771,10 +785,10 @@ Beginner's tip—a full example using interactive links in a html context:
</pre> </pre>
<script> <script>
var callback = function () { const callback = function () {
alert('A callback was triggered'); alert('A callback was triggered');
}; };
var config = { const config = {
startOnLoad: true, startOnLoad: true,
flowchart: { useMaxWidth: true, htmlLabels: true, curve: 'cardinal' }, flowchart: { useMaxWidth: true, htmlLabels: true, curve: 'cardinal' },
securityLevel: 'loose', securityLevel: 'loose',

View File

@@ -391,13 +391,13 @@ Beginner's tip—a full example using interactive links in an html context:
</pre> </pre>
<script> <script>
var printArguments = function (arg1, arg2, arg3) { const printArguments = function (arg1, arg2, arg3) {
alert('printArguments called with arguments: ' + arg1 + ', ' + arg2 + ', ' + arg3); alert('printArguments called with arguments: ' + arg1 + ', ' + arg2 + ', ' + arg3);
}; };
var printTask = function (taskId) { const printTask = function (taskId) {
alert('taskId: ' + taskId); alert('taskId: ' + taskId);
}; };
var config = { const config = {
startOnLoad: true, startOnLoad: true,
securityLevel: 'loose', securityLevel: 'loose',
}; };

View File

@@ -21,15 +21,13 @@
rel="stylesheet" rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css" 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 <script
defer="" defer=""
data-domain="mermaid-js.github.io" data-domain="mermaid-js.github.io"
src="https://plausible.io/js/plausible.js" src="https://plausible.io/js/plausible.js"
></script> ></script>
<script> <script>
var require = { const require = {
paths: { vs: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.29.1/min/vs' }, paths: { vs: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.29.1/min/vs' },
}; };
</script> </script>
@@ -50,17 +48,46 @@
<body> <body>
<div id="app"></div> <div id="app"></div>
<script type="module">
// import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@9/dist/mermaid.esm.min.mjs';
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@9.2.0/dist/mermaid.esm.min.mjs';
// import mermaid from 'http://localhost:9000/mermaid.esm.mjs';
console.log(mermaid); // eslint-disable-line
window.mermaid = mermaid;
const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
const conf = {
logLevel: 4,
startOnLoad: true,
themeCSS: '.label { font-family: Source Sans Pro,Helvetica Neue,Arial,sans-serif; }',
lazyLoadedDiagrams: [
'https://cdn.jsdelivr.net/npm/@mermaid-js/mermaid-mindmap@9.2.0/dist/mermaid-mindmap-detector.esm.mjs',
// 'http://localhost:9000/mermaid-mindmap-detector.esm.mjs',
],
};
if (isDarkMode) conf.theme = 'dark';
async function loadMermaid() {
await mermaid.initialize(conf);
console.log('mermaid initialized'); // eslint-disable-line
}
mermaid.parseError = (e) => {
console.log('parse error', e); // eslint-disable-line
};
await loadMermaid();
</script>
<script> <script>
var initEditor = exports.default; let initEditor = exports.default;
var parser = new DOMParser(); let parser = new DOMParser();
var currentCodeExample = 0; let currentCodeExample = 0;
var colorize = []; let colorize = [];
let num = 0;
function colorizeEverything(html) { function colorizeEverything(html) {
initEditor(monaco); initEditor(monaco);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
monaco.editor.setTheme('mermaid'); monaco.editor.setTheme('mermaid');
var parsed = parser.parseFromString(html, 'text/html').body; const parsed = parser.parseFromString(html, 'text/html').body;
Promise.all( Promise.all(
[...parsed.querySelectorAll('pre[id*="code"]')].map((codeBlock) => [...parsed.querySelectorAll('pre[id*="code"]')].map((codeBlock) =>
monaco.editor.colorize(codeBlock.innerText, 'mermaid') monaco.editor.colorize(codeBlock.innerText, 'mermaid')
@@ -95,13 +122,12 @@
renderer: { renderer: {
code: function (code, lang) { code: function (code, lang) {
if (lang === 'mermaid-example') { if (lang === 'mermaid-example') {
console.log('An example'); // eslint-disable-line
currentCodeExample++; currentCodeExample++;
colorize.push(currentCodeExample); colorize.push(currentCodeExample);
return '<pre id="code' + currentCodeExample + '">' + escapeHTML(code) + '</pre>'; return '<pre id="code' + currentCodeExample + '">' + escapeHTML(code) + '</pre>';
} else if (lang === 'mermaid') { } else if (lang === 'mermaid') {
return ( return '<pre class="mermaid">' + code + '</pre>';
'<pre class="mermaid">' + mermaid.render('mermaid-svg-' + num++, code) + '</pre>'
);
} }
return this.origin.code.apply(this, arguments); return this.origin.code.apply(this, arguments);
}, },
@@ -117,9 +143,13 @@
function (hook, vm) { function (hook, vm) {
hook.beforeEach(function (html) { hook.beforeEach(function (html) {
url = 'https://github.com/mermaid-js/mermaid/blob/develop/src/docs/' + vm.route.file; 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; return editHtml + html;
}); });
// Invoked on each page load after new HTML has been appended to the DOM
hook.doneEach(function () {
window.mermaid.init();
});
hook.afterEach(function (html, next) { hook.afterEach(function (html, next) {
next(html); next(html);
@@ -135,29 +165,17 @@
}, },
], ],
}; };
var num = 0;
const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
const conf = {
logLevel: 4,
startOnLoad: false,
themeCSS: '.label { font-family: Source Sans Pro,Helvetica Neue,Arial,sans-serif; }',
};
if (isDarkMode) conf.theme = 'dark';
mermaid.initialize(conf);
</script> </script>
<script> <script>
window.onhashchange = function (a) { window.onhashchange = function (a) {
//code // if (location && ga) {
if (location) { // ga('send', 'pageview', location.hash);
ga('send', 'pageview', location.hash); // }
}
}; };
</script> </script>
<script src="//cdn.jsdelivr.net/npm/docsify/lib/docsify.min.js"></script> <script src="//cdn.jsdelivr.net/npm/docsify/lib/docsify.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/search.min.js"></script> <script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/search.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/ga.min.js"></script> <!-- <script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/ga.min.js"></script> -->
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-coffeescript.min.js"></script> <script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-coffeescript.min.js"></script>
</body> </body>
</html> </html>

View File

@@ -33,7 +33,7 @@ They also serve as proof of concept, for the variety of things that can be built
- [Mermaid Macro](https://www.redmine.org/plugins/redmine_mermaid_macro) - [Mermaid Macro](https://www.redmine.org/plugins/redmine_mermaid_macro)
- [redmine-mermaid](https://github.com/styz/redmine_mermaid) - [redmine-mermaid](https://github.com/styz/redmine_mermaid)
- [markdown-for-mermaid-plugin](https://github.com/jamieh-mongolian/markdown-for-mermaid-plugin) - [markdown-for-mermaid-plugin](https://github.com/jamieh-mongolian/markdown-for-mermaid-plugin)
- [Jetsbrain IDE eg Pycharm](https://www.jetbrains.com/go/guide/tips/mermaid-js-support-in-markdown/) - [JetBrains IDE eg Pycharm](https://www.jetbrains.com/go/guide/tips/mermaid-js-support-in-markdown/)
- [mermerd](https://github.com/KarnerTh/mermerd) - [mermerd](https://github.com/KarnerTh/mermerd)
## CRM/ERP/Similar ## CRM/ERP/Similar

View File

@@ -2,7 +2,7 @@
# Mindmap # Mindmap
> Mindmap: This is an experimental diagram for now. The syntax and properties can change in future releases. The syntax is stabel except for the icon integration which is the experimental part. > Mindmap: This is an experimental diagram for now. The syntax and properties can change in future releases. The syntax is stable except for the icon integration which is the experimental part.
"A mind map is a diagram used to visually organize information into a hierarchy, showing relationships among pieces of the whole. It is often created around a single concept, drawn as an image in the center of a blank page, to which associated representations of ideas such as images, words and parts of words are added. Major ideas are connected directly to the central concept, and other ideas branch out from those major ideas." Wikipedia "A mind map is a diagram used to visually organize information into a hierarchy, showing relationships among pieces of the whole. It is often created around a single concept, drawn as an image in the center of a blank page, to which associated representations of ideas such as images, words and parts of words are added. Major ideas are connected directly to the central concept, and other ideas branch out from those major ideas." Wikipedia
@@ -26,7 +26,6 @@ mindmap
Tools Tools
Pen and paper Pen and paper
Mermaid Mermaid
``` ```
```mermaid ```mermaid
@@ -47,14 +46,13 @@ mindmap
Tools Tools
Pen and paper Pen and paper
Mermaid Mermaid
``` ```
## Syntax ## Syntax
The syntax for creating Mindmaps is simple and relies on indentation for setting the levels in the hierarchy. The syntax for creating Mindmaps is simple and relies on indentation for setting the levels in the hierarchy.
In the following example you can see how there are 3 dufferent levels. One with starting at the left of the text and another level with two rows starting at the same column, defining the node A. At the end there is one more level where the text is indented further then the prevoius lines defining the nodes B and C. In the following example you can see how there are 3 different levels of indentation. The leftmost indentation is the root of the mindmap. There can only be one root and if you by misstake add two of them on the same level there will be a syntax error. Rows with larger indentation will be connected as children to the previous row with lower indentation. Based on that you can see in the example how the nodes B and C both are children to node A whci in turn is a child of the node Root.
mindmap mindmap
Root Root
@@ -62,7 +60,7 @@ In the following example you can see how there are 3 dufferent levels. One with
B B
C C
In summary is a simple text outline where there are one node at the root level called `Root` which has one child `A`. `A` in turn has two children `B`and `C`. In the diagram below we can see this rendered as a mindmap. In the diagram below you can see the example rendered as a mindmap.
```mermaid-example ```mermaid-example
mindmap mindmap
@@ -220,7 +218,7 @@ The actual indentation does not really matter only compared with the previous ro
B B
C C
This outline is unclear as `B` clearly is a child of `A` but when we move on to `C` the clarity is lost. `C` is not a child of `B` with a higher indentation nor does it have the same indentation as `B`. The only thing that is clear is that the first node with smaller indentation, indicating a parent, is A. Then Mermaid relies on this known truth and compensates for the unclear indentation and selects `A` as a parent of `C` leading till the same diagram with `B` and `C` as siblings. This outline is unclear as `B` clearly is a child of `A` but when we move on to `C` the clarity is lost. `C` is not a child of `B` with a higher indentation nor does it have the same indentation as `B`. The only thing that is clear is that the first node with smaller indentation, indicating a parent, is A. Mermaid will rely on this known truth and compensates for the unclear indentation and selects `A` as a parent of `C` leading till the same diagram with `B` and `C` as siblings.
```mermaid-example ```mermaid-example
mindmap mindmap

View File

@@ -75,23 +75,13 @@ The API works by pulling rendering instructions from the source `mermaid.js` in
### Requirements for the Mermaid API. ### 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. The embedded mermaid diagram definition inside a `<pre class="mermaid">`:**
**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">`:**
```html ```html
<body> <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. **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: `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 ```html
<body> <body>
<script> <script type="module">
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@9/dist/mermaid.esm.min.mjs';
mermaid.initialize({ startOnLoad: true }); mermaid.initialize({ startOnLoad: true });
</script> </script>
</body> </body>
@@ -135,11 +126,6 @@ Rendering in Mermaid is initialized by `mermaid.initialize()` call. You can plac
```html ```html
<html> <html>
<body> <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: Here is one mermaid diagram:
<pre class="mermaid"> <pre class="mermaid">
graph TD 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| C[Server1]
B -->|tcp_456| D[Server2] B -->|tcp_456| D[Server2]
</pre> </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> </body>
</html> </html>
``` ```
@@ -181,8 +172,8 @@ In this example mermaid.js is referenced in `src` as a separate JavaScript file,
B --> C[Server1] B --> C[Server1]
B --> D[Server2] B --> D[Server2]
</pre> </pre>
<script src="The\Path\In\Your\Package\mermaid.js"></script> <script type="module">
<script> import mermaid from 'The/Path/In/Your/Package/mermaid.esm.mjs';
mermaid.initialize({ startOnLoad: true }); mermaid.initialize({ startOnLoad: true });
</script> </script>
</body> </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:** **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.

View File

@@ -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) > 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: - A graph definition, inside `<pre>` tags labeled `class=mermaid`. 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:
```html ```html
<pre class="mermaid"> <pre class="mermaid">
@@ -66,8 +52,18 @@ The easiest way to integrate mermaid on a web page requires three elements:
</pre> </pre>
``` ```
**Following these directions, mermaid starts at page load and (when the page has loaded) it will - Inclusion of the mermaid address in the html page body using a `script` tag as an ESM import, and the `mermaidAPI` call.
locate the graph definitions inside the `div` tags with `class="mermaid"` and return diagrams in SVG form, following given definitions.**
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: ## 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-->C[fa:fa-ban forbidden]
B-->D(fa:fa-spinner); B-->D(fa:fa-spinner);
</pre> </pre>
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script> <script type="module">
<script> import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@9/dist/mermaid.esm.min.mjs';
mermaid.initialize({ startOnLoad: true }); mermaid.initialize({ startOnLoad: true });
</script> </script>
</body> </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. The example below show an outline of how this could be used. The example just logs the resulting SVG to the JavaScript console.
```html ```html
<script src="mermaid.js"></script> <script type="module">
import mermaid from './mermaid.mjs';
<script>
mermaid.mermaidAPI.initialize({ startOnLoad: false }); mermaid.mermaidAPI.initialize({ startOnLoad: false });
$(function () { $(async function () {
// Example of using the API var // Example of using the API var
element = document.querySelector('#graphDiv'); element = document.querySelector('#graphDiv');
var insertSvg = function (svgCode, bindFunctions) { const insertSvg = function (svgCode, bindFunctions) {
element.innerHTML = svgCode; element.innerHTML = svgCode;
}; };
var graphDefinition = 'graph TB\na-->b'; const graphDefinition = 'graph TB\na-->b';
var graph = mermaid.mermaidAPI.render('graphDiv', graphDefinition, insertSvg); const graph = await mermaid.mermaidAPI.render('graphDiv', graphDefinition, insertSvg);
}); });
</script> </script>
``` ```
@@ -339,7 +334,7 @@ on what kind of integration you use.
```html ```html
<script src="../dist/mermaid.js"></script> <script src="../dist/mermaid.js"></script>
<script> <script>
var config = { startOnLoad: true, flowchart: { useMaxWidth: false, htmlLabels: true } }; let config = { startOnLoad: true, flowchart: { useMaxWidth: false, htmlLabels: true } };
mermaid.initialize(config); mermaid.initialize(config);
</script> </script>
``` ```

View File

@@ -1,7 +1,7 @@
{ {
"name": "mermaid-monorepo", "name": "mermaid-monorepo",
"private": true, "private": true,
"version": "9.2.0-rc2", "version": "9.2.0-rc4",
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.", "description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
"main": "dist/mermaid.core.mjs", "main": "dist/mermaid.core.mjs",
"module": "dist/mermaid.core.mjs", "module": "dist/mermaid.core.mjs",
@@ -26,12 +26,12 @@
"git graph" "git graph"
], ],
"scripts": { "scripts": {
"clean": "rimraf dist", "build:mermaid": "ts-node-esm --transpileOnly --project=.vite/tsconfig.json .vite/build.ts --mermaid",
"build:vite": "ts-node-esm --transpileOnly --project=.vite/tsconfig.json .vite/build.ts", "build:vite": "ts-node-esm --transpileOnly --project=.vite/tsconfig.json .vite/build.ts",
"build:types": "concurrently \"tsc -p ./packages/mermaid/tsconfig.json --emitDeclarationOnly\" \"tsc -p ./packages/mermaid-mindmap/tsconfig.json --emitDeclarationOnly\"", "build:types": "tsc -p ./packages/mermaid/tsconfig.json --emitDeclarationOnly && tsc -p ./packages/mermaid-mindmap/tsconfig.json --emitDeclarationOnly",
"build:watch": "pnpm build:vite --watch", "build:watch": "pnpm build:vite --watch",
"build": "pnpm clean; concurrently \"pnpm build:vite\" \"pnpm build:types\"", "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:build": "ts-node-esm --transpileOnly packages/mermaid/src/docs.mts",
"docs:verify": "pnpm docs:build --verify", "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", "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",
@@ -48,7 +48,8 @@
"e2e": "start-server-and-test dev http://localhost:9000/ cypress", "e2e": "start-server-and-test dev http://localhost:9000/ cypress",
"ci": "vitest run", "ci": "vitest run",
"test": "pnpm lint && 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", "prepublishOnly": "pnpm build && pnpm test",
"prepare": "concurrently \"husky install\" \"pnpm build\"", "prepare": "concurrently \"husky install\" \"pnpm build\"",
"pre-commit": "lint-staged" "pre-commit": "lint-staged"
@@ -97,6 +98,7 @@
"@types/express": "^4.17.14", "@types/express": "^4.17.14",
"@types/jsdom": "^20.0.0", "@types/jsdom": "^20.0.0",
"@types/lodash": "^4.14.186", "@types/lodash": "^4.14.186",
"@types/mdast": "^3.0.10",
"@types/prettier": "^2.7.1", "@types/prettier": "^2.7.1",
"@types/stylis": "^4.0.2", "@types/stylis": "^4.0.2",
"@typescript-eslint/eslint-plugin": "^5.39.0", "@typescript-eslint/eslint-plugin": "^5.39.0",
@@ -151,5 +153,8 @@
"sideEffects": [ "sideEffects": [
"**/*.css", "**/*.css",
"**/*.scss" "**/*.scss"
] ],
"volta": {
"node": "18.5.0"
}
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "@mermaid-js/mermaid-mindmap", "name": "@mermaid-js/mermaid-mindmap",
"version": "9.2.0-rc2", "version": "9.2.0",
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.", "description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
"main": "dist/mermaid-mindmap.core.mjs", "main": "dist/mermaid-mindmap.core.mjs",
"module": "dist/mermaid-mindmap.core.mjs", "module": "dist/mermaid-mindmap.core.mjs",
@@ -58,6 +58,7 @@
}, },
"devDependencies": { "devDependencies": {
"concurrently": "^7.4.0", "concurrently": "^7.4.0",
"mermaid": "workspace:*",
"rimraf": "^3.0.2" "rimraf": "^3.0.2"
}, },
"resolutions": { "resolutions": {

View File

@@ -1,3 +1,5 @@
import type { MermaidConfig } from 'mermaid';
const warning = (s: string) => { const warning = (s: string) => {
// Todo remove debug code // Todo remove debug code
console.error('Log function was called before initialization', s); // eslint-disable-line console.error('Log function was called before initialization', s); // eslint-disable-line
@@ -24,7 +26,7 @@ export const log: Record<keyof typeof LEVELS, typeof console.log> = {
}; };
export let setLogLevel: (level: keyof typeof LEVELS | number | string) => void; export let setLogLevel: (level: keyof typeof LEVELS | number | string) => void;
export let getConfig: () => object; export let getConfig: () => MermaidConfig;
export let sanitizeText: (str: string) => string; export let sanitizeText: (str: string) => string;
// eslint-disable @typescript-eslint/no-explicit-any // eslint-disable @typescript-eslint/no-explicit-any
export let setupGraphViewbox: ( export let setupGraphViewbox: (

View File

@@ -1,16 +1,28 @@
/** Created by knut on 15-01-14. */ /** Created by knut on 23-07-2022. */
import { sanitizeText, getConfig, log } from './mermaidUtils'; import { sanitizeText, getConfig, log } from './mermaidUtils';
import type { DetailedError } from 'mermaid';
let nodes = []; interface Node {
id: number;
nodeId: string;
level: number;
descr: string;
type: number;
children: Node[];
width: number;
padding: number;
icon?: string;
class?: string;
}
let nodes: Node[] = [];
let cnt = 0; let cnt = 0;
let elements = {};
export const clear = () => { export const clear = () => {
nodes = []; nodes = [];
cnt = 0; cnt = 0;
elements = {};
}; };
const getParent = function (level) { const getParent = function (level: number) {
for (let i = nodes.length - 1; i >= 0; i--) { for (let i = nodes.length - 1; i >= 0; i--) {
if (nodes[i].level < level) { if (nodes[i].level < level) {
return nodes[i]; return nodes[i];
@@ -23,28 +35,21 @@ const getParent = function (level) {
export const getMindmap = () => { export const getMindmap = () => {
return nodes.length > 0 ? nodes[0] : null; return nodes.length > 0 ? nodes[0] : null;
}; };
export const addNode = (level, id, descr, type) => {
export const addNode = (level: number, id: string, descr: string, type: number) => {
log.info('addNode', level, id, descr, type); log.info('addNode', level, id, descr, type);
const conf = getConfig(); const conf = getConfig();
const node = { const padding = conf.mindmap?.padding ?? 15;
const node: Node = {
id: cnt++, id: cnt++,
nodeId: sanitizeText(id), nodeId: sanitizeText(id),
level, level,
descr: sanitizeText(descr), descr: sanitizeText(descr),
type, type,
children: [], children: [],
width: getConfig().mindmap.maxNodeWidth, width: getConfig().mindmap?.maxNodeWidth ?? 200,
padding: type === nodeType.ROUNDED_RECT || type === nodeType.RECT ? 2 * padding : padding,
}; };
switch (node.type) {
case nodeType.ROUNDED_RECT:
node.padding = 2 * conf.mindmap.padding;
break;
case nodeType.RECT:
node.padding = 2 * conf.mindmap.padding;
break;
default:
node.padding = conf.mindmap.padding;
}
const parent = getParent(level); const parent = getParent(level);
if (parent) { if (parent) {
parent.children.push(node); parent.children.push(node);
@@ -56,9 +61,10 @@ export const addNode = (level, id, descr, type) => {
nodes.push(node); nodes.push(node);
} else { } else {
// Syntax error ... there can only bee one root // Syntax error ... there can only bee one root
let error = new Error( const error = new Error(
'There can be only one root. No parent could be found for ("' + node.descr + '")' 'There can be only one root. No parent could be found for ("' + node.descr + '")'
); );
// @ts-ignore TODO: Add mermaid error
error.hash = { error.hash = {
text: 'branch ' + name, text: 'branch ' + name,
token: 'branch ' + name, token: 'branch ' + name,
@@ -81,7 +87,7 @@ export const nodeType = {
BANG: 5, BANG: 5,
}; };
export const getType = (startStr, endStr) => { export const getType = (startStr: string, endStr: string): number => {
log.debug('In get type', startStr, endStr); log.debug('In get type', startStr, endStr);
switch (startStr) { switch (startStr) {
case '[': case '[':
@@ -99,11 +105,7 @@ export const getType = (startStr, endStr) => {
} }
}; };
export const setElementForId = (id, element) => { export const decorateNode = (decoration: { icon: string; class: string }) => {
elements[id] = element;
};
export const decorateNode = (decoration) => {
const node = nodes[nodes.length - 1]; const node = nodes[nodes.length - 1];
if (decoration && decoration.icon) { if (decoration && decoration.icon) {
node.icon = sanitizeText(decoration.icon); node.icon = sanitizeText(decoration.icon);
@@ -113,7 +115,7 @@ export const decorateNode = (decoration) => {
} }
}; };
export const type2Str = (type) => { export const type2Str = (type: number) => {
switch (type) { switch (type) {
case nodeType.DEFAULT: case nodeType.DEFAULT:
return 'no-border'; return 'no-border';
@@ -132,13 +134,13 @@ export const type2Str = (type) => {
} }
}; };
export let parseError; export type ParseErrorFunction = (err: string | DetailedError, hash?: any) => void;
export const setErrorHandler = (handler) => { export let parseError: ParseErrorFunction;
export const setErrorHandler = (handler: ParseErrorFunction) => {
parseError = handler; parseError = handler;
}; };
// Expose logger to grammar // Expose logger to grammar
export const getLogger = () => log; export const getLogger = () => log;
export const getNodeById = (id) => nodes[id]; export const getNodeById = (id: number): Node => nodes[id];
export const getElementById = (id) => elements[id];

View File

@@ -1,10 +1,9 @@
/** Created by knut on 14-12-11. */ /** Created by knut on 23-07-2022. */
import { select } from 'd3'; import { select } from 'd3';
import { log, getConfig, setupGraphViewbox } from './mermaidUtils'; import { log, getConfig, setupGraphViewbox } from './mermaidUtils';
import svgDraw from './svgDraw'; import svgDraw, { getElementById, clearElementRefs } from './svgDraw';
import cytoscape from 'cytoscape'; import cytoscape from 'cytoscape';
import coseBilkent from 'cytoscape-cose-bilkent'; import coseBilkent from 'cytoscape-cose-bilkent';
import * as db from './mindmapDb';
// Inject the layout algorithm into cytoscape // Inject the layout algorithm into cytoscape
cytoscape.use(coseBilkent); cytoscape.use(coseBilkent);
@@ -34,7 +33,7 @@ function drawNodes(svg, mindmap, section, conf) {
* @param cy * @param cy
*/ */
function drawEdges(edgesEl, cy) { function drawEdges(edgesEl, cy) {
cy.edges().map((edge, id) => { cy?.edges().map((edge, id) => {
const data = edge.data(); const data = edge.data();
if (edge[0]._private.bodyBounds) { if (edge[0]._private.bodyBounds) {
const bounds = edge[0]._private.rscratch; const bounds = edge[0]._private.rscratch;
@@ -100,9 +99,10 @@ function addNodes(mindmap, cy, conf, level) {
*/ */
function layoutMindmap(node, conf) { function layoutMindmap(node, conf) {
return new Promise((resolve) => { return new Promise((resolve) => {
if (node.children.length === 0) { // if (node.children.length === 0) {
return node; // resolve(node);
} // return;
// }
// Add temporary render element // Add temporary render element
const renderEl = select('body').append('div').attr('id', 'cy').attr('style', 'display:none'); const renderEl = select('body').append('div').attr('id', 'cy').attr('style', 'display:none');
@@ -154,7 +154,7 @@ function positionNodes(cy) {
data.x = node.position().x; data.x = node.position().x;
data.y = node.position().y; data.y = node.position().y;
svgDraw.positionNode(data); svgDraw.positionNode(data);
const el = db.getElementById(data.nodeId); const el = getElementById(data.nodeId);
log.info('Id:', id, 'Position: (', node.position().x, ', ', node.position().y, ')', data); log.info('Id:', id, 'Position: (', node.position().x, ', ', node.position().y, ')', data);
el.attr( el.attr(
'transform', 'transform',
@@ -178,6 +178,7 @@ export const draw = async (text, id, version, diagObj) => {
// This is done only for throwing the error if the text is not valid. // This is done only for throwing the error if the text is not valid.
diagObj.db.clear(); diagObj.db.clear();
clearElementRefs();
// Parse the graph definition // Parse the graph definition
diagObj.parser.parse(text); diagObj.parser.parse(text);

View File

@@ -22,12 +22,10 @@ const genSections = (options) => {
} }
.section-${i - 1} text { .section-${i - 1} text {
fill: ${options['cScaleLabel' + i]}; fill: ${options['cScaleLabel' + i]};
// fill: ${options['gitInv' + i]};
} }
.node-icon-${i - 1} { .node-icon-${i - 1} {
font-size: 40px; font-size: 40px;
color: ${options['cScaleLabel' + i]}; color: ${options['cScaleLabel' + i]};
// color: ${options['gitInv' + i]};
} }
.section-edge-${i - 1}{ .section-edge-${i - 1}{
stroke: ${options['cScale' + i]}; stroke: ${options['cScale' + i]};
@@ -36,7 +34,7 @@ const genSections = (options) => {
stroke-width: ${sw}; stroke-width: ${sw};
} }
.section-${i - 1} line { .section-${i - 1} line {
stroke: ${options['lineColor' + i]} ; stroke: ${options['cScaleInv' + i]} ;
stroke-width: 3; stroke-width: 3;
} }

View File

@@ -259,7 +259,7 @@ export const drawNode = function (elem, node, fullSection, conf) {
// if (typeof node.x !== 'undefined' && typeof node.y !== 'undefined') { // if (typeof node.x !== 'undefined' && typeof node.y !== 'undefined') {
// nodeElem.attr('transform', 'translate(' + node.x + ',' + node.y + ')'); // nodeElem.attr('transform', 'translate(' + node.x + ',' + node.y + ')');
// } // }
db.setElementForId(node.id, nodeElem); setElementById(node.id, nodeElem);
return node.height; return node.height;
}; };
@@ -286,7 +286,7 @@ export const drawEdge = function drawEdge(edgesElem, mindmap, parent, depth, ful
}; };
export const positionNode = function (node) { export const positionNode = function (node) {
const nodeElem = db.getElementById(node.id); const nodeElem = getElementById(node.id);
const x = node.x || 0; const x = node.x || 0;
const y = node.y || 0; const y = node.y || 0;
@@ -294,4 +294,18 @@ export const positionNode = function (node) {
nodeElem.attr('transform', 'translate(' + x + ',' + y + ')'); nodeElem.attr('transform', 'translate(' + x + ',' + y + ')');
}; };
let elements = {};
const setElementById = (id, element) => {
elements[id] = element;
};
export const getElementById = (id) => {
return elements[id];
};
export const clearElementRefs = () => {
elements = {};
};
export default { drawNode, positionNode, drawEdge }; export default { drawNode, positionNode, drawEdge };

View File

@@ -1,6 +1,6 @@
{ {
"name": "mermaid", "name": "mermaid",
"version": "9.2.0-rc2", "version": "9.2.0",
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.", "description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
"main": "./dist/mermaid.core.mjs", "main": "./dist/mermaid.core.mjs",
"module": "./dist/mermaid.core.mjs", "module": "./dist/mermaid.core.mjs",
@@ -72,7 +72,8 @@
"lodash": "^4.17.21", "lodash": "^4.17.21",
"moment-mini": "^2.24.0", "moment-mini": "^2.24.0",
"non-layered-tidy-tree-layout": "^2.0.2", "non-layered-tidy-tree-layout": "^2.0.2",
"stylis": "^4.1.2" "stylis": "^4.1.2",
"uuid": "^9.0.0"
}, },
"devDependencies": { "devDependencies": {
"@applitools/eyes-cypress": "^3.25.7", "@applitools/eyes-cypress": "^3.25.7",
@@ -86,6 +87,7 @@
"@types/lodash": "^4.14.185", "@types/lodash": "^4.14.185",
"@types/prettier": "^2.7.0", "@types/prettier": "^2.7.0",
"@types/stylis": "^4.0.2", "@types/stylis": "^4.0.2",
"@types/uuid": "^8.3.4",
"@typescript-eslint/eslint-plugin": "^5.37.0", "@typescript-eslint/eslint-plugin": "^5.37.0",
"@typescript-eslint/parser": "^5.37.0", "@typescript-eslint/parser": "^5.37.0",
"concurrently": "^7.4.0", "concurrently": "^7.4.0",

View File

@@ -1,6 +1,6 @@
import * as configApi from './config'; import * as configApi from './config';
import { log } from './logger'; import { log } from './logger';
import { getDiagram, registerDiagram } from './diagram-api/diagramAPI'; import { DiagramNotFoundError, getDiagram, registerDiagram } from './diagram-api/diagramAPI';
import { detectType, getDiagramLoader } from './diagram-api/detectType'; import { detectType, getDiagramLoader } from './diagram-api/detectType';
import { isDetailedError } from './utils'; import { isDetailedError } from './utils';
export class Diagram { export class Diagram {
@@ -8,11 +8,18 @@ export class Diagram {
parser; parser;
renderer; renderer;
db; db;
private detectTypeFailed = false;
// eslint-disable-next-line @typescript-eslint/ban-types // eslint-disable-next-line @typescript-eslint/ban-types
constructor(public txt: string, parseError?: Function) { constructor(public txt: string, parseError?: Function) {
const cnf = configApi.getConfig(); const cnf = configApi.getConfig();
this.txt = txt; this.txt = txt;
try {
this.type = detectType(txt, cnf); this.type = detectType(txt, cnf);
} catch (e) {
this.handleError(e, parseError);
this.type = 'error';
this.detectTypeFailed = true;
}
const diagram = getDiagram(this.type); const diagram = getDiagram(this.type);
log.debug('Type ' + this.type); log.debug('Type ' + this.type);
// Setup diagram // Setup diagram
@@ -32,12 +39,22 @@ export class Diagram {
// eslint-disable-next-line @typescript-eslint/ban-types // eslint-disable-next-line @typescript-eslint/ban-types
parse(text: string, parseError?: Function): boolean { parse(text: string, parseError?: Function): boolean {
if (this.detectTypeFailed) {
return false;
}
try { try {
text = text + '\n'; text = text + '\n';
this.db.clear(); this.db.clear();
this.parser.parse(text); this.parser.parse(text);
return true; return true;
} catch (error) { } catch (error) {
this.handleError(error, parseError);
}
return false;
}
// eslint-disable-next-line @typescript-eslint/ban-types
handleError(error: unknown, parseError?: Function) {
// Is this the correct way to access mermiad's parseError() // Is this the correct way to access mermiad's parseError()
// method ? (or global.mermaid.parseError()) ? // method ? (or global.mermaid.parseError()) ?
if (parseError) { if (parseError) {
@@ -54,8 +71,6 @@ export class Diagram {
throw error; throw error;
} }
} }
return false;
}
getParser() { getParser() {
return this.parser; return this.parser;
@@ -66,37 +81,36 @@ export class Diagram {
} }
} }
export default Diagram; export const getDiagramFromText = (
txt: string,
// eslint-disable-next-line @typescript-eslint/ban-types // eslint-disable-next-line @typescript-eslint/ban-types
export const getDiagramFromText = async (txt: string, parseError?: Function) => { parseError?: Function
): Diagram | Promise<Diagram> => {
const type = detectType(txt, configApi.getConfig()); const type = detectType(txt, configApi.getConfig());
try { try {
// Trying to find the diagram // Trying to find the diagram
getDiagram(type); getDiagram(type);
return new Diagram(txt, parseError);
} catch (error) { } catch (error) {
if (!(error instanceof DiagramNotFoundError)) {
log.error(error);
throw error;
}
const loader = getDiagramLoader(type); const loader = getDiagramLoader(type);
if (!loader) { if (!loader) {
throw new Error(`Diagram ${type} not found.`); throw new Error(`Loader for ${type} not found.`);
} }
// Diagram not avaiable, loading it // TODO: Uncomment for v10
// const path = getPathForDiagram(type); // // Diagram not available, loading it
const { diagram } = await loader(); // eslint-disable-line @typescript-eslint/no-explicit-any // const { diagram } = await loader();
registerDiagram( // registerDiagram(type, diagram, undefined, diagram.injectUtils);
type, // // new diagram will try getDiagram again and if fails then it is a valid throw
{ return loader().then(({ diagram }) => {
db: diagram.db, registerDiagram(type, diagram, undefined, diagram.injectUtils);
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');
// 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); return new Diagram(txt, parseError);
});
}
// return new Diagram(txt, parseError);
}; };
export default Diagram;

View File

@@ -11,17 +11,13 @@ import Diagram from '../Diagram';
// Normally, we could just do the following to get the original `parse()` // 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. // implementation, however, requireActual returns a promise and it's not documented how to use withing mock file.
let hasLoadedDiagrams = false;
/** /**
* @param text * @param text
* @param parseError * @param parseError
*/ */
// eslint-disable-next-line @typescript-eslint/ban-types // eslint-disable-next-line @typescript-eslint/ban-types
function parse(text: string, parseError?: Function): boolean { function parse(text: string, parseError?: Function): boolean {
if (!hasLoadedDiagrams) {
addDiagrams(); addDiagrams();
hasLoadedDiagrams = true;
}
const diagram = new Diagram(text, parseError); const diagram = new Diagram(text, parseError);
return diagram.parse(text, parseError); return diagram.parse(text, parseError);
} }
@@ -29,6 +25,7 @@ function parse(text: string, parseError?: Function): boolean {
// original version cannot be modified since it was frozen with `Object.freeze()` // original version cannot be modified since it was frozen with `Object.freeze()`
export const mermaidAPI = { export const mermaidAPI = {
render: vi.fn(), render: vi.fn(),
renderAsync: vi.fn(),
parse, parse,
parseDirective: vi.fn(), parseDirective: vi.fn(),
initialize: vi.fn(), initialize: vi.fn(),

View File

@@ -3,7 +3,8 @@
import DOMPurify from 'dompurify'; import DOMPurify from 'dompurify';
export interface MermaidConfig { export interface MermaidConfig {
lazyLoadedDiagrams?: any; lazyLoadedDiagrams?: string[];
loadExternalDiagramsAtStartup?: boolean;
theme?: string; theme?: string;
themeVariables?: any; themeVariables?: any;
themeCSS?: string; themeCSS?: string;

View File

@@ -438,6 +438,9 @@ export const insertEdge = function (elem, e, edge, clusterDb, diagramType, graph
case 'thick': case 'thick':
strokeClasses = 'edge-thickness-thick'; strokeClasses = 'edge-thickness-thick';
break; break;
case 'invisible':
strokeClasses = 'edge-thickness-thick';
break;
default: default:
strokeClasses = ''; strokeClasses = '';
} }

View File

@@ -1,8 +1,7 @@
import { MermaidConfig } from '../config.type'; 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 = const directive =
/[%]{2}[{]\s*(?:(?:(\w+)\s*:|(\w+))\s*(?:(?:(\w+))|((?:(?![}][%]{2}).|\r?\n)*))?\s*)(?:[}][%]{2})?/gi; /[%]{2}[{]\s*(?:(?:(\w+)\s*:|(\w+))\s*(?:(?:(\w+))|((?:(?![}][%]{2}).|\r?\n)*))?\s*)(?:[}][%]{2})?/gi;
const anyComment = /\s*%%.*\n/gm; const anyComment = /\s*%%.*\n/gm;
@@ -34,26 +33,22 @@ const detectors: Record<string, DetectorRecord> = {};
*/ */
export const detectType = function (text: string, config?: MermaidConfig): string { export const detectType = function (text: string, config?: MermaidConfig): string {
text = text.replace(directive, '').replace(anyComment, '\n'); text = text.replace(directive, '').replace(anyComment, '\n');
// console.log(detectors);
for (const [key, { detector }] of Object.entries(detectors)) { for (const [key, { detector }] of Object.entries(detectors)) {
const diagram = detector(text, config); const diagram = detector(text, config);
if (diagram) { if (diagram) {
return key; return key;
} }
} }
// TODO: #3391
// throw new Error(`No diagram type detected for text: ${text}`); throw new Error(`No diagram type detected for text: ${text}`);
return 'flowchart';
}; };
export const addDetector = ( export const addDetector = (key: string, detector: DiagramDetector, loader?: DiagramLoader) => {
key: string, if (detectors[key]) {
detector: DiagramDetector, throw new Error(`Detector with key ${key} already exists`);
loader: DiagramLoader | null }
) => {
detectors[key] = { detector, loader }; detectors[key] = { detector, loader };
log.debug(`Detector with key ${key} added${loader ? ' with loader' : ''}`);
}; };
export const getDiagramLoader = (key: string) => detectors[key].loader; export const getDiagramLoader = (key: string) => detectors[key].loader;

View File

@@ -1,16 +1,4 @@
import { import { registerDiagram } from './diagramAPI';
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';
// @ts-ignore: TODO Fix ts errors // @ts-ignore: TODO Fix ts errors
import gitGraphParser from '../diagrams/git/parser/gitGraph'; import gitGraphParser from '../diagrams/git/parser/gitGraph';
@@ -106,17 +94,15 @@ import { setConfig } from '../config';
import errorRenderer from '../diagrams/error/errorRenderer'; import errorRenderer from '../diagrams/error/errorRenderer';
import errorStyles from '../diagrams/error/styles'; import errorStyles from '../diagrams/error/styles';
const registerDiagramAndDetector = ( let hasLoadedDiagrams = false;
id: string,
diagram: DiagramDefinition,
detector: DiagramDetector
) => {
registerDiagram(id, diagram);
registerDetector(id, detector);
};
export const addDiagrams = () => { 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', 'error',
// Special diagram with error messages but setup as a regular diagram // Special diagram with error messages but setup as a regular diagram
{ {
@@ -140,7 +126,7 @@ export const addDiagrams = () => {
(text) => text.toLowerCase().trim() === 'error' (text) => text.toLowerCase().trim() === 'error'
); );
registerDiagramAndDetector( registerDiagram(
'c4', 'c4',
{ {
parser: c4Parser, parser: c4Parser,
@@ -153,7 +139,7 @@ export const addDiagrams = () => {
}, },
c4Detector c4Detector
); );
registerDiagramAndDetector( registerDiagram(
'class', 'class',
{ {
parser: classParser, parser: classParser,
@@ -170,7 +156,7 @@ export const addDiagrams = () => {
}, },
classDetector classDetector
); );
registerDiagramAndDetector( registerDiagram(
'classDiagram', 'classDiagram',
{ {
parser: classParser, parser: classParser,
@@ -187,7 +173,7 @@ export const addDiagrams = () => {
}, },
classDetectorV2 classDetectorV2
); );
registerDiagramAndDetector( registerDiagram(
'er', 'er',
{ {
parser: erParser, parser: erParser,
@@ -197,7 +183,7 @@ export const addDiagrams = () => {
}, },
erDetector erDetector
); );
registerDiagramAndDetector( registerDiagram(
'gantt', 'gantt',
{ {
parser: ganttParser, parser: ganttParser,
@@ -207,7 +193,7 @@ export const addDiagrams = () => {
}, },
ganttDetector ganttDetector
); );
registerDiagramAndDetector( registerDiagram(
'info', 'info',
{ {
parser: infoParser, parser: infoParser,
@@ -217,7 +203,7 @@ export const addDiagrams = () => {
}, },
infoDetector infoDetector
); );
registerDiagramAndDetector( registerDiagram(
'pie', 'pie',
{ {
parser: pieParser, parser: pieParser,
@@ -227,7 +213,7 @@ export const addDiagrams = () => {
}, },
pieDetector pieDetector
); );
registerDiagramAndDetector( registerDiagram(
'requirement', 'requirement',
{ {
parser: requirementParser, parser: requirementParser,
@@ -237,7 +223,7 @@ export const addDiagrams = () => {
}, },
requirementDetector requirementDetector
); );
registerDiagramAndDetector( registerDiagram(
'sequence', 'sequence',
{ {
parser: sequenceParser, parser: sequenceParser,
@@ -260,7 +246,7 @@ export const addDiagrams = () => {
}, },
sequenceDetector sequenceDetector
); );
registerDiagramAndDetector( registerDiagram(
'state', 'state',
{ {
parser: stateParser, parser: stateParser,
@@ -277,7 +263,7 @@ export const addDiagrams = () => {
}, },
stateDetector stateDetector
); );
registerDiagramAndDetector( registerDiagram(
'stateDiagram', 'stateDiagram',
{ {
parser: stateParser, parser: stateParser,
@@ -294,7 +280,7 @@ export const addDiagrams = () => {
}, },
stateDetectorV2 stateDetectorV2
); );
registerDiagramAndDetector( registerDiagram(
'journey', 'journey',
{ {
parser: journeyParser, parser: journeyParser,
@@ -309,7 +295,7 @@ export const addDiagrams = () => {
journeyDetector journeyDetector
); );
registerDiagramAndDetector( registerDiagram(
'flowchart', 'flowchart',
{ {
parser: flowParser, parser: flowParser,
@@ -329,7 +315,7 @@ export const addDiagrams = () => {
}, },
flowDetector flowDetector
); );
registerDiagramAndDetector( registerDiagram(
'flowchart-v2', 'flowchart-v2',
{ {
parser: flowParser, parser: flowParser,
@@ -350,14 +336,9 @@ export const addDiagrams = () => {
}, },
flowDetectorV2 flowDetectorV2
); );
registerDiagramAndDetector( registerDiagram(
'gitGraph', 'gitGraph',
{ parser: gitGraphParser, db: gitGraphDb, renderer: gitGraphRenderer, styles: gitGraphStyles }, { parser: gitGraphParser, db: gitGraphDb, renderer: gitGraphRenderer, styles: gitGraphStyles },
gitGraphDetector gitGraphDetector
); );
// registerDiagram(
// 'mindmap',
// { parser: mindmapParser, db: mindmapDb, renderer: mindmapRenderer, styles: mindmapStyles },
// mindmapDetector
// );
}; };

View File

@@ -1,6 +1,7 @@
import { detectType, DiagramDetector } from './detectType'; import { detectType } from './detectType';
import { getDiagram, registerDiagram, registerDetector } from './diagramAPI'; import { getDiagram, registerDiagram } from './diagramAPI';
import { addDiagrams } from './diagram-orchestration'; import { addDiagrams } from './diagram-orchestration';
import { DiagramDetector } from './types';
addDiagrams(); addDiagrams();
@@ -15,17 +16,22 @@ describe('DiagramAPI', () => {
it('should handle diagram registrations', () => { it('should handle diagram registrations', () => {
expect(() => getDiagram('loki')).toThrow(); 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) => { const detector: DiagramDetector = (str: string) => {
return str.match('loki') !== null; return str.match('loki') !== null;
}; };
registerDetector('loki', detector); registerDiagram(
registerDiagram('loki', { 'loki',
{
db: {}, db: {},
parser: {}, parser: {},
renderer: {}, renderer: {},
styles: {}, styles: {},
}); },
detector
);
expect(getDiagram('loki')).not.toBeNull(); expect(getDiagram('loki')).not.toBeNull();
expect(detectType('loki diagram')).toBe('loki'); expect(detectType('loki diagram')).toBe('loki');
}); });

View File

@@ -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 { log as _log, setLogLevel as _setLogLevel } from '../logger';
import { getConfig as _getConfig } from '../config'; import { getConfig as _getConfig } from '../config';
import { sanitizeText as _sanitizeText } from '../diagrams/common/common'; import { sanitizeText as _sanitizeText } from '../diagrams/common/common';
import { MermaidConfig } from '../config.type';
import { setupGraphViewbox as _setupGraphViewbox } from '../setupGraphViewbox'; import { setupGraphViewbox as _setupGraphViewbox } from '../setupGraphViewbox';
import { addStylesForDiagram } from '../styles'; import { addStylesForDiagram } from '../styles';
import { DiagramDefinition, DiagramDetector } from './types';
/* /*
Packaging and exposing resources for externa diagrams so that they can import Packaging and exposing resources for externa diagrams so that they can import
@@ -13,41 +13,19 @@ import { addStylesForDiagram } from '../styles';
*/ */
export const log = _log; export const log = _log;
export const setLogLevel = _setLogLevel; export const setLogLevel = _setLogLevel;
export type DiagramDetector = _DiagramDetector;
export const getConfig = _getConfig; export const getConfig = _getConfig;
export const sanitizeText = (text: string) => _sanitizeText(text, getConfig()); export const sanitizeText = (text: string) => _sanitizeText(text, getConfig());
export const setupGraphViewbox = _setupGraphViewbox; 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 diagrams: Record<string, DiagramDefinition> = {};
const connectCallbacks: Record<string, any> = {}; // TODO fix, eslint-disable-line @typescript-eslint/no-explicit-any
export interface Detectors { export interface Detectors {
[key: string]: DiagramDetector; [key: string]: DiagramDetector;
} }
export const registerDetector = (id: string, detector: DiagramDetector) => {
addDetector(id, detector, null);
};
export const registerDiagram = ( export const registerDiagram = (
id: string, id: string,
diagram: DiagramDefinition, diagram: DiagramDefinition,
detector?: DiagramDetector,
callback?: ( callback?: (
_log: any, _log: any,
_setLogLevel: any, _setLogLevel: any,
@@ -56,35 +34,36 @@ export const registerDiagram = (
_setupGraphViewbox: any _setupGraphViewbox: any
) => void ) => void
) => { ) => {
log.debug(`Registering diagram ${id}`);
if (diagrams[id]) { if (diagrams[id]) {
log.warn(`Diagram ${id} already registered.`); log.warn(`Diagram ${id} already registered.`);
// The error throw is commented out to as it breaks pages where you have multiple diagrams,
// it can happen that rendering of the same type of diagram is initiated while the previous
// one is still being imported. import deals with this and only one diagram is imported in
// the end.
// throw new Error(`Diagram ${id} already registered.`);
} }
diagrams[id] = diagram; diagrams[id] = diagram;
if (detector) {
addDetector(id, detector);
}
addStylesForDiagram(id, diagram.styles); addStylesForDiagram(id, diagram.styles);
if (typeof callback !== 'undefined') { if (typeof callback !== 'undefined') {
callback(log, setLogLevel, getConfig, sanitizeText, setupGraphViewbox); callback(log, setLogLevel, getConfig, sanitizeText, setupGraphViewbox);
} }
log.debug(`Registered diagram ${id}. ${Object.keys(diagrams).join(', ')} diagrams registered.`);
}; };
export const getDiagram = (name: string): DiagramDefinition => { export const getDiagram = (name: string): DiagramDefinition => {
log.debug(`Getting diagram ${name}. ${Object.keys(diagrams).join(', ')} diagrams registered.`);
if (name in diagrams) { if (name in diagrams) {
return diagrams[name]; return diagrams[name];
} }
throw new Error(`Diagram ${name} not found.`); throw new DiagramNotFoundError(name);
}; };
/** export class DiagramNotFoundError extends Error {
* constructor(message: string) {
* @param sScriptSrc super(`Diagram ${message} not found.`);
*/ }
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);
};
});

View File

@@ -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}`
);

View 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;

View File

@@ -1,4 +1,4 @@
import type { DiagramDetector } from '../../diagram-api/detectType'; import type { DiagramDetector } from '../../diagram-api/types';
export const c4Detector: DiagramDetector = (txt) => { export const c4Detector: DiagramDetector = (txt) => {
return txt.match(/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/) !== null; return txt.match(/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/) !== null;

View File

@@ -1,4 +1,4 @@
import type { DiagramDetector } from '../../diagram-api/detectType'; import type { DiagramDetector } from '../../diagram-api/types';
export const classDetectorV2: DiagramDetector = (txt, config) => { export const classDetectorV2: DiagramDetector = (txt, config) => {
// If we have confgured to use dagre-wrapper then we should return true in this function for classDiagram code thus making it use the new class diagram // If we have confgured to use dagre-wrapper then we should return true in this function for classDiagram code thus making it use the new class diagram

View File

@@ -1,4 +1,4 @@
import type { DiagramDetector } from '../../diagram-api/detectType'; import type { DiagramDetector } from '../../diagram-api/types';
export const classDetector: DiagramDetector = (txt, config) => { export const classDetector: DiagramDetector = (txt, config) => {
// If we have confgured to use dagre-wrapper then we should never return true in this function // If we have confgured to use dagre-wrapper then we should never return true in this function

View File

@@ -1,4 +1,4 @@
import type { DiagramDetector } from '../../diagram-api/detectType'; import type { DiagramDetector } from '../../diagram-api/types';
export const erDetector: DiagramDetector = (txt) => { export const erDetector: DiagramDetector = (txt) => {
return txt.match(/^\s*erDiagram/) !== null; return txt.match(/^\s*erDiagram/) !== null;

View File

@@ -429,8 +429,7 @@ export const clear = function (ver = 'gen-1') {
vertices = {}; vertices = {};
classes = {}; classes = {};
edges = []; edges = [];
funs = []; funs = [setupToolTips];
funs.push(setupToolTips);
subGraphs = []; subGraphs = [];
subGraphLookup = {}; subGraphLookup = {};
subCount = 0; subCount = 0;
@@ -457,8 +456,8 @@ export const defaultStyle = function () {
export const addSubGraph = function (_id, list, _title) { export const addSubGraph = function (_id, list, _title) {
// console.log('addSubGraph', _id, list, _title); // console.log('addSubGraph', _id, list, _title);
let id = _id.trim(); let id = _id.trim();
let title = _title; let title = _title.trim();
if (_id === _title && _title.match(/\s/)) { if (id === title && title.match(/\s/)) {
id = undefined; id = undefined;
} }
/** @param a */ /** @param a */
@@ -675,6 +674,10 @@ const destructEndLink = (_str) => {
stroke = 'thick'; stroke = 'thick';
} }
if (line[0] === '~') {
stroke = 'invisible';
}
let dots = countChar('.', line); let dots = countChar('.', line);
if (dots) { if (dots) {

View File

@@ -1,4 +1,4 @@
import type { DiagramDetector } from '../../diagram-api/detectType'; import type { DiagramDetector } from '../../diagram-api/types';
export const flowDetectorV2: DiagramDetector = (txt, config) => { export const flowDetectorV2: DiagramDetector = (txt, config) => {
// If we have confgured to use dagre-wrapper then we should return true in this function for graph code thus making it use the new flowchart diagram // If we have confgured to use dagre-wrapper then we should return true in this function for graph code thus making it use the new flowchart diagram

View File

@@ -1,4 +1,4 @@
import type { DiagramDetector } from '../../diagram-api/detectType'; import type { DiagramDetector } from '../../diagram-api/types';
export const flowDetector: DiagramDetector = (txt, config) => { export const flowDetector: DiagramDetector = (txt, config) => {
// If we have confired to only use new flow charts this function shohuld always return false // If we have confired to only use new flow charts this function shohuld always return false

View File

@@ -280,6 +280,11 @@ export const addEdges = function (edges, g, diagObj) {
edgeData.pattern = 'solid'; edgeData.pattern = 'solid';
edgeData.style = 'stroke-width: 3.5px;fill:none;'; edgeData.style = 'stroke-width: 3.5px;fill:none;';
break; break;
case 'invisible':
edgeData.thickness = 'invisible';
edgeData.pattern = 'solid';
edgeData.style = 'stroke-width: 0;fill:none;';
break;
} }
if (typeof edge.style !== 'undefined') { if (typeof edge.style !== 'undefined') {
const styles = getStylesFromArray(edge.style); const styles = getStylesFromArray(edge.style);

View File

@@ -120,6 +120,7 @@ that id.
\s*[xo<]?\-\-+[-xo>]\s* return 'LINK'; \s*[xo<]?\-\-+[-xo>]\s* return 'LINK';
\s*[xo<]?\=\=+[=xo>]\s* return 'LINK'; \s*[xo<]?\=\=+[=xo>]\s* return 'LINK';
\s*[xo<]?\-?\.+\-[xo>]?\s* return 'LINK'; \s*[xo<]?\-?\.+\-[xo>]?\s* return 'LINK';
\s*\~\~[\~]+\s* return 'LINK';
\s*[xo<]?\-\-\s* return 'START_LINK'; \s*[xo<]?\-\-\s* return 'START_LINK';
\s*[xo<]?\=\=\s* return 'START_LINK'; \s*[xo<]?\=\=\s* return 'START_LINK';
\s*[xo<]?\-\.\s* return 'START_LINK'; \s*[xo<]?\-\.\s* return 'START_LINK';

View File

@@ -1,4 +1,4 @@
import type { DiagramDetector } from '../../diagram-api/detectType'; import type { DiagramDetector } from '../../diagram-api/types';
export const ganttDetector: DiagramDetector = (txt) => { export const ganttDetector: DiagramDetector = (txt) => {
return txt.match(/^\s*gantt/) !== null; return txt.match(/^\s*gantt/) !== null;

View File

@@ -1,4 +1,4 @@
import type { DiagramDetector } from '../../diagram-api/detectType'; import type { DiagramDetector } from '../../diagram-api/types';
export const gitGraphDetector: DiagramDetector = (txt) => { export const gitGraphDetector: DiagramDetector = (txt) => {
return txt.match(/^\s*gitGraph/) !== null; return txt.match(/^\s*gitGraph/) !== null;

View File

@@ -1,4 +1,4 @@
import type { DiagramDetector } from '../../diagram-api/detectType'; import type { DiagramDetector } from '../../diagram-api/types';
export const infoDetector: DiagramDetector = (txt) => { export const infoDetector: DiagramDetector = (txt) => {
return txt.match(/^\s*info/) !== null; return txt.match(/^\s*info/) !== null;

View File

@@ -1,4 +1,4 @@
import type { DiagramDetector } from '../../diagram-api/detectType'; import type { DiagramDetector } from '../../diagram-api/types';
export const pieDetector: DiagramDetector = (txt) => { export const pieDetector: DiagramDetector = (txt) => {
return txt.match(/^\s*pie/) !== null; return txt.match(/^\s*pie/) !== null;

View File

@@ -1,4 +1,4 @@
import type { DiagramDetector } from '../../diagram-api/detectType'; import type { DiagramDetector } from '../../diagram-api/types';
export const requirementDetector: DiagramDetector = (txt) => { export const requirementDetector: DiagramDetector = (txt) => {
return txt.match(/^\s*requirement(Diagram)?/) !== null; return txt.match(/^\s*requirement(Diagram)?/) !== null;

View File

@@ -1,4 +1,4 @@
import type { DiagramDetector } from '../../diagram-api/detectType'; import type { DiagramDetector } from '../../diagram-api/types';
export const sequenceDetector: DiagramDetector = (txt) => { export const sequenceDetector: DiagramDetector = (txt) => {
return txt.match(/^\s*sequenceDiagram/) !== null; return txt.match(/^\s*sequenceDiagram/) !== null;

View File

@@ -1,4 +1,4 @@
import type { DiagramDetector } from '../../diagram-api/detectType'; import type { DiagramDetector } from '../../diagram-api/types';
export const stateDetectorV2: DiagramDetector = (text, config) => { export const stateDetectorV2: DiagramDetector = (text, config) => {
if (text.match(/^\s*stateDiagram-v2/) !== null) return true; if (text.match(/^\s*stateDiagram-v2/) !== null) return true;

Some files were not shown because too many files have changed in this diff Show More