Compare commits

...
Author SHA1 Message Date
Sidharth VinodandGitHub cc2b574a6f Merge branch 'develop' into sidv/fixErrorDiagram 2024-06-16 20:09:53 +05:30
Sidharth VinodandGitHub 71f4a9bac7 Merge pull request #1461 from mermaid-js/renovate/patch-all-minor-patch
chore(deps): update all non-major dependencies (patch)
2024-06-16 13:46:44 +00:00
renovate[bot]andGitHub 915b8990ae chore(deps): update all non-major dependencies 2024-06-16 13:46:29 +00:00
Sidharth VinodandGitHub 262d9e972a Merge pull request #1462 from mermaid-js/renovate/all-minor-patch
chore(deps): update all non-major dependencies (minor)
2024-06-16 13:44:16 +00:00
Sidharth VinodandGitHub 77aa7d851a Merge pull request #1463 from mermaid-js/browserslist-update
build: update Browserslist db
2024-06-16 13:44:04 +00:00
Sidharth VinodandGitHub 6fbc5da142 Merge pull request #1412 from maxstanley/vendor-fa
Vendor Font-Awesome
2024-06-16 13:43:49 +00:00
renovate[bot]andGitHub 238557b911 chore(deps): update all non-major dependencies 2024-06-16 13:42:33 +00:00
Sidharth Vinod 81cc401bf2 Remove stalebot 2024-06-16 19:11:26 +05:30
Sidharth Vinod 7ce93ea210 Merge branch 'develop' into pr/maxstanley/1412
* develop: (34 commits)
  chore: Add isRough to stats
  Update snapshots
  feat: Add rough mode
  fix(deps): update dependency mermaid to v10.9.1
  chore(deps): update all non-major dependencies
  build: update Browserslist db
  chore(deps): update dependency svelte to v4.2.16
  chore(deps): update all non-major dependencies
  chore(deps): update all non-major dependencies
  chore(deps): update all non-major dependencies
  build: update Browserslist db
  build: update Browserslist db
  chore(deps): update all non-major dependencies
  chore(deps): update all non-major dependencies
  Update README.md
  fix(#1401): Handle error when loading gist
  chore(deps): update all non-major dependencies
  chore(deps): update all non-major dependencies
  Fix clicking issue in diagramUpdate.spec.ts
  Remove pnpm-lock.yaml
  ...
2024-06-16 19:07:48 +05:30
GitHub Action a09f5ee8b6 build: update Browserslist db 2024-06-15 02:24:59 +00:00
GitHub Action fa5bc5a5a1 build: update Browserslist db 2024-06-01 02:27:24 +00:00
Sidharth VinodandGitHub ca03a85221 Merge pull request #1457 from mermaid-js/sidv/rough
feat: Add rough mode
2024-05-23 12:55:33 +00:00
Sidharth Vinod 4525e0467c chore: Add isRough to stats 2024-05-23 18:25:13 +05:30
Sidharth Vinod 20b4ecc260 Update snapshots 2024-05-23 18:19:42 +05:30
Sidharth Vinod cba9a6754d feat: Add rough mode 2024-05-23 14:05:59 +05:30
Sidharth VinodandGitHub eb3b2d5446 Merge pull request #1450 from mermaid-js/browserslist-update
build: update Browserslist db
2024-05-21 06:52:10 +00:00
Sidharth VinodandGitHub 1e5248250d Merge pull request #1455 from mermaid-js/renovate/patch-mermaid-packages
fix(deps): update dependency mermaid to v10.9.1
2024-05-21 06:52:02 +00:00
renovate[bot]andGitHub b51ab519c2 fix(deps): update dependency mermaid to v10.9.1 2024-05-21 06:45:58 +00:00
Sidharth VinodandGitHub c91434346b Merge pull request #1454 from mermaid-js/renovate/patch-all-minor-patch
chore(deps): update all non-major dependencies (patch)
2024-05-21 06:44:54 +00:00
renovate[bot]andGitHub c9db1b90c4 chore(deps): update all non-major dependencies 2024-05-20 00:12:40 +00:00
GitHub Action 7b80de3683 build: update Browserslist db 2024-05-15 02:25:09 +00:00
Sidharth VinodandGitHub 116a84ea8d Merge pull request #1447 from mermaid-js/renovate/patch-all-minor-patch
chore(deps): update dependency svelte to v4.2.16
2024-05-13 05:42:19 +00:00
Sidharth VinodandGitHub 34a6d3c7b2 Merge pull request #1434 from kerwin612/patch-1
Update README.md
2024-05-13 11:12:02 +05:30
renovate[bot]andGitHub 386a19776b chore(deps): update dependency svelte to v4.2.16 2024-05-13 00:10:36 +00:00
Sidharth VinodandGitHub 528d2f0afe Merge pull request #1444 from mermaid-js/browserslist-update
build: update Browserslist db
2024-05-12 09:10:06 +05:30
Sidharth VinodandGitHub 8e7758a7be Merge pull request #1445 from mermaid-js/renovate/all-minor-patch
chore(deps): update all non-major dependencies (minor)
2024-05-12 09:09:19 +05:30
renovate[bot]andGitHub 61a9ecf702 chore(deps): update all non-major dependencies 2024-05-10 01:52:24 +00:00
Sidharth VinodandGitHub dc72838036 Merge pull request #1442 from mermaid-js/renovate/all-minor-patch
chore(deps): update all non-major dependencies (minor)
2024-05-03 07:03:47 +00:00
Sidharth VinodandGitHub 86a7909e2b Merge branch 'develop' into renovate/all-minor-patch 2024-05-03 12:33:35 +05:30
Sidharth VinodandGitHub 3dad6ebbb9 Merge pull request #1439 from mermaid-js/renovate/patch-all-minor-patch
chore(deps): update all non-major dependencies (patch)
2024-05-03 12:33:22 +05:30
renovate[bot]andGitHub 580e2f7506 chore(deps): update all non-major dependencies 2024-05-02 09:48:11 +00:00
renovate[bot]andGitHub cc227ea993 chore(deps): update all non-major dependencies 2024-05-01 15:30:24 +00:00
GitHub Action dcff346abd build: update Browserslist db 2024-05-01 02:23:10 +00:00
Sidharth VinodandGitHub 39e0293156 Merge pull request #1440 from mermaid-js/browserslist-update
build: update Browserslist db
2024-04-16 09:40:17 +05:30
GitHub Action 93b75efe71 build: update Browserslist db 2024-04-15 04:05:03 +00:00
Sidharth VinodandGitHub 68157f7e71 Merge pull request #1431 from mermaid-js/renovate/patch-all-minor-patch
chore(deps): update all non-major dependencies (patch)
2024-04-13 06:30:11 +00:00
renovate[bot]andGitHub 4eb23185a8 chore(deps): update all non-major dependencies 2024-04-13 06:29:55 +00:00
Sidharth VinodandGitHub 6d5a9acdc7 Merge pull request #1432 from mermaid-js/renovate/all-minor-patch
chore(deps): update all non-major dependencies (minor)
2024-04-13 06:28:49 +00:00
Sidharth VinodandGitHub f862d29791 Merge pull request #1424 from mermaid-js/fix/1423
fix: subscripts in corner safari, resolves #1423
2024-04-13 06:28:41 +00:00
renovate[bot]andGitHub c5d3eb322a chore(deps): update all non-major dependencies 2024-04-11 19:52:59 +00:00
Kerwin BryantandGitHub df66e433bf Update README.md 2024-04-09 14:00:30 +08:00
Sidharth VinodandGitHub 29b9188d88 Merge branch 'develop' into fix/1423 2024-04-05 19:07:12 +05:30
Sidharth VinodandGitHub 0e6c022a0f Merge pull request #1429 from mermaid-js/1401_LoadGist
fix(#1401): Handle error when loading gist
2024-04-05 19:06:56 +05:30
Sidharth Vinod 57eef9da5c fix(#1401): Handle error when loading gist 2024-04-05 18:58:02 +05:30
Sidharth VinodandGitHub e635b23694 Merge pull request #1421 from mermaid-js/renovate/all-minor-patch
chore(deps): update all non-major dependencies (minor)
2024-04-03 00:42:08 +05:30
Sidharth VinodandGitHub 36390c2034 Merge pull request #1425 from mermaid-js/renovate/patch-all-minor-patch
chore(deps): update all non-major dependencies (patch)
2024-04-03 00:41:53 +05:30
renovate[bot]andGitHub d2f5dd148f chore(deps): update all non-major dependencies 2024-03-31 02:17:36 +00:00
renovate[bot]andGitHub bc9e8c306b chore(deps): update all non-major dependencies 2024-03-29 10:19:32 +00:00
Sidharth VinodandGitHub 618ac917ec Merge pull request #1383 from dontry/feature/zenuml
Add @mermaid-js/mermaid-zenuml dependency and ZenUML sample diagram
2024-03-27 14:46:05 +05:30
dontry 329839a9a7 Fix clicking issue in diagramUpdate.spec.ts 2024-03-24 21:45:42 +11:00
Sidharth Vinod cfd8484f76 Remove pnpm-lock.yaml 2024-03-24 15:01:24 +05:30
DonandGitHub 6175a02d5a Merge branch 'mermaid-js:develop' into feature/zenuml 2024-03-24 13:58:26 +11:00
Yash Singh 3613b41875 fix: subscripts in corner safari, resolves #1423 2024-03-23 18:13:05 -07:00
Sidharth VinodandGitHub 44eeceb389 Merge pull request #1420 from mermaid-js/renovate/patch-all-minor-patch
chore(deps): update all non-major dependencies (patch)
2024-03-23 05:26:20 +00:00
renovate[bot]andGitHub 5276972caa chore(deps): update all non-major dependencies 2024-03-21 02:18:50 +00:00
dontry 664d81f6ea Refactor diagram registration without top-level promise 2024-03-15 23:22:01 +11:00
Sidharth Vinodanddontry 7eee9b7a42 Bump version 2024-03-15 23:22:01 +11:00
dontry 50b0d12353 Replace zenuml example with a more sophisticated one 2024-03-15 23:22:01 +11:00
dontry 19702f885a Update dependencies and error handling in mermaid.ts 2024-03-15 23:22:01 +11:00
dontry e74828b2c8 1. Add @mermaid-js/mermaid-zenuml dependency and register external diagrams
2. Add ZenUML sample diagram to Preset.svelte component
3. Refactor diagram button layout with grid layout
2024-03-15 23:22:01 +11:00
Sidharth VinodandGitHub 1e3248cdba Merge pull request #1399 from mermaid-js/renovate/all-minor-patch
chore(deps): update all non-major dependencies (minor)
2024-03-12 07:31:21 +00:00
renovate[bot]andGitHub 41e6dafd3b chore(deps): update all non-major dependencies 2024-03-11 17:37:50 +00:00
Sidharth VinodandGitHub ef1390f129 Merge pull request #1416 from mermaid-js/renovate/patch-all-minor-patch
chore(deps): update all non-major dependencies (patch)
2024-03-11 05:52:43 +00:00
renovate[bot]andGitHub e95ccb4029 chore(deps): update all non-major dependencies 2024-03-11 01:46:00 +00:00
Sidharth VinodandGitHub 301d39d50b Merge pull request #1413 from mermaid-js/sidv/10.9.0
Mermaid v10.9.0
2024-03-05 23:09:05 +05:30
Sidharth VinodandGitHub 6428d69952 Merge branch 'develop' into sidv/10.9.0 2024-03-05 23:04:09 +05:30
Sidharth VinodandGitHub 873481e5f0 Merge pull request #1398 from mermaid-js/renovate/patch-all-minor-patch
chore(deps): update all non-major dependencies (patch)
2024-03-05 23:03:40 +05:30
Sidharth Vinod c06d98c1ee Fix prettier 2024-03-05 23:03:22 +05:30
Sidharth Vinod 89d6d355b2 mermaid v10.9.0 2024-03-05 23:00:51 +05:30
renovate[bot]andGitHub 2d6e74a754 chore(deps): update all non-major dependencies 2024-03-05 17:28:42 +00:00
Sidharth VinodandGitHub ef34b4ca75 Merge pull request #1402 from mermaid-js/browserslist-update
build: update Browserslist db
2024-03-05 22:58:07 +05:30
Max Stanley 2d3f233b5d Include FA Stylesheet in SVG 2024-03-02 16:34:35 +00:00
Max Stanley ab2a024471 Formatting 2024-03-02 16:13:04 +00:00
Max Stanley 5a74e15a22 Remove whitespace 2024-03-02 16:10:35 +00:00
Max Stanley 74be138670 Add #681 TODO 2024-03-02 16:09:08 +00:00
Max Stanley fe3e283b3e Move FA CSS to app.postcss 2024-03-02 14:44:52 +00:00
Max Stanley e5e6045723 Fix indentation 2024-03-02 14:27:08 +00:00
Max Stanley d439963e4d Vendor Font-Awesome 2024-03-02 14:19:34 +00:00
GitHub Action 05a941e659 build: update Browserslist db 2024-03-01 02:18:16 +00:00
GitHub Action edc8af2157 build: update Browserslist db 2024-03-01 02:17:33 +00:00
Sidharth Vinod a14970d481 Bump node version 2024-02-26 21:32:31 +05:30
Sidharth Vinod 3e52f07364 Update node 2024-02-26 21:09:20 +05:30
Sidharth VinodandGitHub e6dd0fa83e Merge pull request #1404 from BaumiCoder/fixLinkToTutorial
Fix broken link to the tutorial page
2024-02-19 13:27:19 +05:30
Sidharth VinodandGitHub a5018276f3 Merge pull request #1405 from BaumiCoder/fixLinkToContributionGuidelines
Fix Link to contribution guidelines
2024-02-19 13:26:46 +05:30
Michael Baumgartner c005cf4bfa Fix Link to contribution guidelines
The linked markdown file in the github repository only contains
the path to the actual file with the guidelines. Furthermore,
there is a rendered version on the website, which shows the diagramms
and not the code of them.
2024-02-16 19:39:59 +01:00
Michael Baumgartner 9d2c8ea316 Fix broken link to the tutorial page 2024-02-16 19:17:13 +01:00
Sidharth Vinod b7ccfff91d Hide overflow for body 2024-02-12 14:12:57 +05:30
Sidharth Vinod ab7aed0146 feat: Add privacy modal 2024-02-09 11:16:31 +05:30
Sidharth VinodandGitHub 3f95ce271b Merge pull request #1394 from mermaid-js/renovate/patch-all-minor-patch
chore(deps): update all non-major dependencies (patch)
2024-02-06 14:49:22 +00:00
renovate[bot]andGitHub 2fb1ce7452 chore(deps): update all non-major dependencies 2024-02-06 13:21:27 +00:00
Sidharth VinodandGitHub b5e6fb255c Merge pull request #1393 from mermaid-js/mermaid/10.8.0
Add block diagram sample
2024-02-05 09:23:38 +00:00
Knut Sveidqvist 351d46c5e2 Updated block diagram example 2024-02-05 10:21:54 +01:00
Sidharth Vinod b3955bd85c Add block sample 2024-02-03 11:23:19 +05:30
Sidharth VinodandGitHub 756c8ae3ac Merge pull request #1389 from mermaid-js/browserslist-update
build: update Browserslist db
2024-02-03 11:08:51 +05:30
Sidharth VinodandGitHub 8c3e208be7 Merge pull request #1391 from mermaid-js/mermaid/10.8.0
Update mermaid v10.8.0
2024-02-03 11:08:42 +05:30
Sidharth VinodandGitHub 7714c8f8a5 Merge branch 'develop' into mermaid/10.8.0 2024-02-03 11:04:16 +05:30
Sidharth VinodandGitHub 9fb2c6ff9e Merge pull request #1388 from Abrifq/develop
Update the docs domain in the docMap test
2024-02-03 11:04:07 +05:30
Sidharth Vinod 1a935bce4f Update mermaid v10.8.0 2024-02-03 10:54:29 +05:30
GitHub Action 82d77ae2ad build: update Browserslist db 2024-02-01 02:17:52 +00:00
Abrifq b40990a528 Whoops! 2024-01-31 16:37:48 +03:00
Abrifq 66ef322a31 Updated docs domain name in the test as well 2024-01-31 16:29:05 +03:00
Sidharth VinodandGitHub 2f1c452021 Merge pull request #1384 from mermaid-js/renovate/patch-all-minor-patch
chore(deps): update all non-major dependencies (patch)
2024-01-30 15:27:33 +00:00
Sidharth VinodandGitHub d947dc9dfb Merge pull request #1335 from Abrifq/develop
Update docs links in the Editor's Docs button
2024-01-30 15:26:28 +00:00
Abrifq 57eea0f8d5 Changed docs domain to mermaid.js.org 2024-01-30 13:18:58 +03:00
Arda AydınandGitHub 193cbdde91 Merge branch 'mermaid-js:develop' into develop 2024-01-30 11:46:00 +02:00
renovate[bot]andGitHub c6de1cd453 chore(deps): update all non-major dependencies 2024-01-30 09:38:51 +00:00
Sidharth VinodandGitHub 0c6a43eac7 Merge pull request #1385 from mermaid-js/renovate/all-minor-patch
chore(deps): update all non-major dependencies (minor)
2024-01-30 09:38:01 +00:00
renovate[bot]andGitHub 45687fa76b chore(deps): update all non-major dependencies 2024-01-29 19:50:46 +00:00
Arda AydınandGitHub 6b6adf033a Merge branch 'develop' into develop 2024-01-28 18:06:29 +02:00
Sidharth VinodandGitHub 65d6931336 Merge pull request #1355 from mermaid-js/renovate/patch-all-minor-patch
chore(deps): update all non-major dependencies (patch)
2024-01-23 02:33:25 +00:00
renovate[bot]andGitHub 38a15f0a24 chore(deps): update all non-major dependencies 2024-01-23 01:46:19 +00:00
Sidharth VinodandGitHub 31187f8b73 Merge pull request #1377 from mermaid-js/intelligentAutoSync
feat: Adaptive auto sync
2024-01-22 14:41:04 +00:00
Sidharth VinodandGitHub 6f33a03e18 Merge branch 'develop' into intelligentAutoSync 2024-01-22 19:12:15 +05:30
Sidharth VinodandGitHub d3ecdfa9ef Merge pull request #1380 from mermaid-js/renovate/npm-vite-vulnerability
chore(deps): update dependency vite to v5.0.12 [security]
2024-01-22 13:41:15 +00:00
Sidharth VinodandGitHub 0181069a08 Merge pull request #1381 from mermaid-js/renovate/all-minor-patch
chore(deps): update dependency @sveltejs/kit to v2.4.1
2024-01-22 13:41:06 +00:00
renovate[bot]andGitHub a422ca03cb chore(deps): update dependency @sveltejs/kit to v2.4.1 2024-01-22 01:15:12 +00:00
renovate[bot]andGitHub 42779d7cec chore(deps): update dependency vite to v5.0.12 [security] 2024-01-19 22:39:12 +00:00
Sidharth Vinod 61928528a7 remove fontawesome 2024-01-18 23:20:33 +05:30
Sidharth Vinod 2acb84415a feat: waitForRender 2024-01-18 23:20:21 +05:30
Sidharth Vinod 2033f1add0 Wait to sync before export 2024-01-18 21:24:42 +05:30
Sidharth Vinod 675af38c49 Throw error if out of sync 2024-01-18 21:05:33 +05:30
Sidharth Vinod 0c7d48970c Strict match filename 2024-01-18 20:48:32 +05:30
Sidharth Vinod 71cf898f5c Wait for diagram to sync 2024-01-18 20:32:05 +05:30
Sidharth Vinod 3e457fb0bb Revert "Bump cypress"
This reverts commit d9eba9ceec.
2024-01-18 20:26:26 +05:30
Sidharth VinodandGitHub 2eb9cff6bb Merge pull request #1364 from mermaid-js/renovate/all-minor-patch
chore(deps): update all non-major dependencies (minor)
2024-01-18 14:52:51 +00:00
Sidharth Vinod 45d41b55eb Remove use of cy.clock 2024-01-18 20:16:40 +05:30
Sidharth Vinod 9bf4214617 Merge branch 'develop' into intelligentAutoSync
* develop:
  Mermaid 10.7.0
  Add UTM tags
  build: update Browserslist db
2024-01-18 19:20:49 +05:30
renovate[bot]andGitHub 59019417de chore(deps): update all non-major dependencies 2024-01-18 13:49:18 +00:00
Sidharth Vinod 91e6a3f1ba Mermaid 10.7.0 2024-01-18 19:18:23 +05:30
Sidharth Vinod d9eba9ceec Bump cypress 2024-01-18 19:17:05 +05:30
Sidharth Vinod e6e2b62e82 test: Verify adaptive auto sync 2024-01-17 22:28:43 +05:30
Sidharth VinodandGitHub c2beff5442 Merge pull request #1378 from mermaid-js/janPromo
Add UTM tags
2024-01-17 21:54:22 +05:30
Sidharth Vinod c08df23ca7 Merge branch 'develop' into janPromo
* develop:
  Fix XSS vulnerability
  chore: Update eslint plugin and fix errors
  build: update Browserslist db
  fix: Unit tests
  chore: Fix issues
  Add node-version
  chore: Auto format and fix warnings
  chore: Upgrade dependencies
  build: update Browserslist db
  build: update Browserslist db
2024-01-17 21:50:59 +05:30
Sidharth Vinod b9b2f6ba85 Add UTM tags 2024-01-17 21:49:10 +05:30
Sidharth Vinod f0951d575f feat: Adaptive auto sync 2024-01-17 18:53:57 +05:30
Sidharth VinodandGitHub 27b158e624 Merge pull request #1371 from mermaid-js/browserslist-update
build: update Browserslist db
2024-01-15 07:01:22 +00:00
Sidharth VinodandGitHub 2a3b12ca82 Merge pull request #1372 from mermaid-js/updateDeps
Update ESLint plugin
2024-01-15 12:30:42 +05:30
Sidharth Vinodandchbi afbc7f3de3 Fix XSS vulnerability
Co-authored-by: chbi <chbi@chbi.eu>
2024-01-15 12:15:57 +05:30
Sidharth Vinod 8667c6de33 chore: Update eslint plugin and fix errors 2024-01-15 12:13:13 +05:30
GitHub Action 67d934c12d build: update Browserslist db 2024-01-15 02:25:58 +00:00
Sidharth VinodandGitHub eaecb488ec Merge pull request #1368 from mermaid-js/updateDeps
UpdateDeps
2024-01-11 17:12:52 +00:00
Sidharth Vinod beb5a8935f fix: Unit tests 2024-01-11 22:39:50 +05:30
Sidharth Vinod 6a422ca643 chore: Fix issues 2024-01-11 22:23:18 +05:30
Sidharth Vinod b487ef67b3 Add node-version 2024-01-11 22:17:17 +05:30
Sidharth Vinod 44e0026e0d Merge branch 'develop' into updateDeps
* develop:
  feat: Jan 2024 Promo
  Update promo.ts
  build: update Browserslist db
  build: update Browserslist db
2024-01-11 22:14:17 +05:30
Sidharth Vinod 3da392a4a7 Merge branch 'develop' of github.com:mermaid-js/mermaid-live-editor into develop
* 'develop' of github.com:mermaid-js/mermaid-live-editor:
  feat: Jan 2024 Promo
  build: update Browserslist db
  build: update Browserslist db
2024-01-11 22:12:29 +05:30
Sidharth Vinod b69cca3763 Merge branch 'develop' into janPromo
* develop:
  Update promo.ts
2024-01-11 22:11:04 +05:30
Sidharth VinodandGitHub 539efbae7d Merge pull request #1363 from mermaid-js/browserslist-update
build: update Browserslist db
2024-01-11 16:39:41 +00:00
Sidharth VinodandGitHub 488f655e2f Merge pull request #1367 from mermaid-js/janPromo
feat: Jan 2024 Promo
2024-01-11 22:09:23 +05:30
Sidharth Vinod 087fb897a0 chore: Auto format and fix warnings 2024-01-11 22:06:29 +05:30
Sidharth Vinod d1cf590f20 chore: Upgrade dependencies 2024-01-11 22:03:44 +05:30
Sidharth Vinod 65587a6c7d feat: Jan 2024 Promo 2024-01-11 21:32:46 +05:30
Sidharth VinodandGitHub 027f7ae76f Update promo.ts 2024-01-03 12:30:51 +05:30
GitHub Action c278f200b9 build: update Browserslist db 2024-01-01 02:26:31 +00:00
GitHub Action a4638c7d1e build: update Browserslist db 2023-12-15 02:22:38 +00:00
Sidharth VinodandGitHub 75ab8c2c58 Merge pull request #1360 from mermaid-js/release-promotion
Release live editor
2023-12-14 10:50:53 +05:30
Sidharth VinodandGitHub 1412bed156 Merge pull request #1362 from mermaid-js/sidv/fixPlausible
Fix plausible tracking
2023-12-14 10:50:23 +05:30
Sidharth Vinod 4891fc8a84 Merge branch 'develop' into sidv/fixPlausible
* develop:
2023-12-14 10:44:02 +05:30
Sidharth Vinod 1a82978f2c chore: Use manual page tracking to avoid sending hash. 2023-12-14 10:37:19 +05:30
Sidharth VinodandGitHub f771662360 Merge pull request #1361 from mermaid-js/sidv/disableHostedAnalytics
feat: Add env vars to configure plausible
2023-12-12 07:48:28 +00:00
Sidharth Vinod 434a50f81c format netlify.toml 2023-12-11 18:00:20 +05:30
Sidharth Vinod e7293cc0a9 feat: Add env vars to configure plausible 2023-12-11 17:42:38 +05:30
Sidharth VinodandGitHub af4242a46a Merge pull request #1356 from mermaid-js/renovate/all-minor-patch
chore(deps): update all non-major dependencies (minor)
2023-12-11 04:28:14 +00:00
renovate[bot]andGitHub d022a22211 chore(deps): update all non-major dependencies 2023-12-11 03:52:50 +00:00
Arda AydınandGitHub db3a314589 Merge branch 'develop' into develop 2023-12-07 08:01:55 +03:00
Sidharth VinodandGitHub be2519f89c Merge pull request #1344 from mermaid-js/release-promotion
Release live editor
2023-12-06 11:32:01 +05:30
Sidharth VinodandGitHub 007b461d5e Merge pull request #1347 from maxstanley/docker_env
Provide environment variables to Docker build
2023-12-06 11:29:27 +05:30
Sidharth VinodandGitHub 0d4ae40f12 Merge pull request #1354 from mermaid-js/dependabot/npm_and_yarn/adobe/css-tools-4.3.2
build(deps): bump @adobe/css-tools from 4.3.1 to 4.3.2
2023-12-06 11:29:09 +05:30
Sidharth VinodandGitHub 5c747a1c03 Merge pull request #1357 from mermaid-js/dependabot/npm_and_yarn/vite-4.5.1
build(deps-dev): bump vite from 4.5.0 to 4.5.1
2023-12-06 11:28:54 +05:30
Sidharth Vinod f2fde65536 feat: trackBannerClick
Purposefully not enabling the outbound link tracking,
as it would track links people have embedded in diagrams
which will then be available in public analytics.
2023-12-06 11:27:16 +05:30
Sidharth Vinod 7ff3594df7 Merge branch 'master' into develop
* master:
  chore: Update MC promo link
  remove toSorted
  chore: Tweak start and end dates
  feat: Add Holiday2023 banner
2023-12-06 11:25:16 +05:30
dependabot[bot]andGitHub 47537f6594 build(deps-dev): bump vite from 4.5.0 to 4.5.1
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 4.5.0 to 4.5.1.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v4.5.1/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v4.5.1/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-06 00:04:15 +00:00
Sidharth VinodandGitHub f52699400e Merge pull request #1353 from mermaid-js/browserslist-update
build: update Browserslist db
2023-12-05 04:49:08 +00:00
Sidharth VinodandGitHub 5a165f0773 Apply suggestions from code review 2023-12-05 10:18:26 +05:30
Sidharth Vinod 19a15e9710 chore: Update MC promo link 2023-12-01 12:00:02 +05:30
dependabot[bot]andGitHub 697201f1e0 build(deps): bump @adobe/css-tools from 4.3.1 to 4.3.2
Bumps [@adobe/css-tools](https://github.com/adobe/css-tools) from 4.3.1 to 4.3.2.
- [Changelog](https://github.com/adobe/css-tools/blob/main/History.md)
- [Commits](https://github.com/adobe/css-tools/commits)

---
updated-dependencies:
- dependency-name: "@adobe/css-tools"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-01 05:24:23 +00:00
GitHub Action 4e93f44121 build: update Browserslist db 2023-12-01 02:26:53 +00:00
Max Stanley 5865b46a26 Simplify docker action 2023-11-30 18:06:19 +00:00
Sidharth VinodandGitHub 9507c67f73 Merge pull request #1348 from mermaid-js/renovate/patch-all-minor-patch
chore(deps): update dependency svelte-preprocess to v5.1.1
2023-11-30 04:41:49 +00:00
renovate[bot]andGitHub 4ccf0dc643 chore(deps): update dependency svelte-preprocess to v5.1.1 2023-11-29 16:28:09 +00:00
Sidharth VinodandGitHub 9bfec1f13d Merge pull request #1349 from mermaid-js/renovate/all-minor-patch
chore(deps): update all non-major dependencies (minor)
2023-11-29 16:27:26 +00:00
Sidharth VinodandGitHub dff33bc869 Merge pull request #1351 from mermaid-js/sidv/holiday2023
feat: Add Holiday2023 banner
2023-11-29 11:02:27 +05:30
Sidharth Vinod 670b298ba6 remove toSorted 2023-11-29 10:08:15 +05:30
renovate[bot]andGitHub b25a9d3e97 chore(deps): update all non-major dependencies 2023-11-28 21:12:26 +00:00
Sidharth Vinod 1f28dde6e7 chore: Tweak start and end dates 2023-11-28 14:27:17 +05:30
Sidharth Vinod 9ba2598b00 feat: Add Holiday2023 banner 2023-11-28 14:25:14 +05:30
Max Stanley d2d082ec08 Always push tag event 2023-11-21 22:08:25 +00:00
Max Stanley f6a729f871 Remove env 2023-11-21 22:06:16 +00:00
Max Stanley 6d983158b6 Fix env 2023-11-21 22:03:11 +00:00
Max Stanley 2d7f91ab26 Add new-line 2023-11-21 22:01:13 +00:00
Max Stanley 7db761fba7 Improved docker CI 2023-11-21 21:59:03 +00:00
Max Stanley 11a814ac7d Add environment arguments to Dockerfile 2023-11-21 21:00:14 +00:00
Sidharth VinodandGitHub 4ad6bf915b Merge pull request #1342 from mermaid-js/browserslist-update
build: update Browserslist db
2023-11-20 11:01:27 +00:00
Sidharth VinodandGitHub b156fe9966 Merge pull request #1345 from mermaid-js/renovate/patch-all-minor-patch
chore(deps): update all non-major dependencies (patch)
2023-11-20 11:01:04 +00:00
renovate[bot]andGitHub 2611664047 chore(deps): update all non-major dependencies 2023-11-20 01:29:47 +00:00
Sidharth VinodandGitHub d77f5c8399 Merge pull request #1339 from mermaid-js/renovate/patch-all-minor-patch
chore(deps): update all non-major dependencies (patch)
2023-11-19 18:19:55 +00:00
renovate[bot]andGitHub f5f9ec9560 chore(deps): update all non-major dependencies 2023-11-19 12:04:12 +00:00
Sidharth VinodandGitHub 454c6d836c Merge pull request #1340 from mermaid-js/renovate/all-minor-patch
chore(deps): update all non-major dependencies (minor)
2023-11-19 12:03:31 +00:00
renovate[bot]andGitHub 1b004a76b2 chore(deps): update all non-major dependencies 2023-11-17 23:09:27 +00:00
GitHub Action 517178a7e7 build: update Browserslist db 2023-11-15 02:20:31 +00:00
Arda AydınandGitHub d84947e33d Merge branch 'develop' into develop 2023-11-10 01:56:33 +03:00
Sidharth VinodandGitHub 3f64df7754 Merge pull request #1336 from mermaid-js/release-promotion
Release live editor
2023-11-09 23:33:14 +05:30
Sidharth VinodandGitHub fd411e46be Merge pull request #1302 from HK-SHAO/develop
fix: interface SVG was changed by mistake
2023-11-09 23:32:34 +05:30
Sidharth VinodandGitHub 796d1b98c6 Merge pull request #1321 from subhash-halder/add-xychart-to-mermaid-live-editor
Added XYChart sample in mermaid live ediror
2023-11-09 23:31:46 +05:30
Sidharth VinodandGitHub 8cb8b14093 Merge pull request #1309 from mermaid-js/renovate/all-minor-patch
chore(deps): update all non-major dependencies (minor)
2023-11-09 08:01:11 +00:00
Sidharth VinodandGitHub fad000984a Merge branch 'develop' into develop 2023-11-09 13:24:45 +05:30
renovate[bot]andGitHub 7c9ee990b5 chore(deps): update all non-major dependencies 2023-11-09 07:53:59 +00:00
Sidharth VinodandGitHub bbcd207cb7 Merge pull request #1317 from mozi47/fix/hambergur-menu-toggling
Hamberger Menu Fixed
2023-11-09 07:53:15 +00:00
Sidharth VinodandGitHub 93215b3391 Merge pull request #1308 from mermaid-js/renovate/patch-all-minor-patch
chore(deps): update all non-major dependencies (patch)
2023-11-09 07:50:16 +00:00
Sidharth VinodandGitHub 97dad2419b Merge pull request #1333 from mermaid-js/release-promotion
Release live editor
2023-11-09 11:51:59 +05:30
renovate[bot]andGitHub abb494d768 chore(deps): update all non-major dependencies 2023-11-09 06:21:06 +00:00
Sidharth VinodandGitHub 3c08315a85 Merge pull request #1310 from mermaid-js/dependabot/npm_and_yarn/get-func-name-2.0.2
build(deps): bump get-func-name from 2.0.0 to 2.0.2
2023-11-09 06:20:21 +00:00
Sidharth VinodandGitHub 863efb5746 Merge pull request #1327 from shubhusion/develop
Absolute path for /mermaidchart-logo.svg #1319
2023-11-09 06:18:21 +00:00
Sidharth VinodandGitHub 1250cc5456 Merge pull request #1316 from mermaid-js/renovate/npm-postcss-vulnerability
chore(deps): update dependency postcss to v8.4.31 [security]
2023-11-09 06:15:45 +00:00
Sidharth VinodandGitHub ecc6d2a539 Merge pull request #1318 from mermaid-js/browserslist-update
build: update Browserslist db
2023-11-09 06:15:21 +00:00
renovate[bot]andGitHub 4af85ae30b chore(deps): update dependency postcss to v8.4.31 [security] 2023-11-09 06:13:54 +00:00
Sidharth VinodandGitHub baff40a692 Merge pull request #1328 from mermaid-js/renovate/mermaid-packages
fix(deps): update dependency mermaid to v10.6.1
2023-11-09 11:42:28 +05:30
Sidharth VinodandGitHub 00b084721a Merge pull request #1330 from crpz1/bug/1181_export-png-with-theme-background
Use current theme's background color on PNG export
2023-11-09 06:11:50 +00:00
Abrifq 74c0e6dcad Update tests for the new doc links 2023-11-08 14:22:18 +03:00
renovate[bot]andGitHub 07b0a065fa fix(deps): update dependency mermaid to v10.6.1 2023-11-06 16:04:10 +00:00
Abrifq fd8bba4934 Fixed sankey's docKey
Whoops!
2023-11-05 22:04:37 +03:00
Arda AydınandGitHub 4f5b0cde29 Merge branch 'mermaid-js:develop' into develop 2023-11-05 21:46:47 +03:00
Abrifq e15e5378f7 Added new Mermaid types to Editor Doc Links 2023-11-05 21:45:38 +03:00
Arda AydınandGitHub 4eefa7083e Update Doc links on Editor 2023-11-03 04:25:25 +03:00
Sidharth VinodandGitHub ba12c7ab2f Merge pull request #1332 from zhzy0077/patch-1
DOCUMENTATION button goes to 404
2023-11-02 06:12:53 +00:00
Zhiyuan ZhengandGitHub df49ead019 DOCUMENTATION button goes to 404
This should be https://mermaid.js.org/intro/getting-started.html
2023-11-01 16:08:17 +08:00
GitHub Action 3ef4db3ecd build: update Browserslist db 2023-11-01 02:19:13 +00:00
crpz1 5d9d3feb59 Use current theme's background color on PNG export 2023-10-31 15:56:55 +00:00
shubhusion 5a155d285b Absolute path for /mermaidchart-logo.svg #1319 2023-10-27 22:35:43 +05:30
Subhash Halder d56d2678d4 Added XYChart sample in mermaid live ediror 2023-10-18 19:48:44 +05:30
GitHub Action 0a600d1c5a build: update Browserslist db 2023-10-15 02:17:46 +00:00
Muzakir ShahandGitHub f7f77f35d3 Hamberger Menu Fixed
Hamberger menu is fixed and the menu UI is also updated.
2023-10-06 18:26:52 +05:00
dependabot[bot]andGitHub 77ba621d90 build(deps): bump get-func-name from 2.0.0 to 2.0.2
Bumps [get-func-name](https://github.com/chaijs/get-func-name) from 2.0.0 to 2.0.2.
- [Release notes](https://github.com/chaijs/get-func-name/releases)
- [Commits](https://github.com/chaijs/get-func-name/commits/v2.0.2)

---
updated-dependencies:
- dependency-name: get-func-name
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-27 21:32:44 +00:00
HK-SHAOandGitHub bb09d2ed51 Merge pull request #1 from HK-SHAO/HK-SHAO-patch-interface-changed
fix: interface SVG was changed by mistake
2023-09-15 17:08:36 +08:00
HK-SHAOandGitHub f0ce4c9db6 fix: interface SVG was changed by mistake
When setting up an export of different sizes, click the Copy Image button or the Download button, and the SVG size of the user interface changes
2023-09-15 17:07:19 +08:00
Sidharth Vinod e530b3e35f Merge branch 'develop' into sidv/fixErrorDiagram
* develop:
  build: update Browserslist db
  Fix tests
  fix cypress
  chore(deps): update all non-major dependencies
  chore(deps): update all non-major dependencies
  Group mermaid release separately
  chore(deps): update all non-major dependencies
  build: update Browserslist db
  build: update Browserslist db
  Bump @adobe/css-tools from 4.3.0 to 4.3.1
  fix: add missing and remove duplicate keywords in pie
2023-09-15 10:36:37 +05:30
Sidharth Vinod 6334d4ab84 fix: Error diagram rendering 2023-08-17 14:26:04 +05:30
54 changed files with 3235 additions and 2004 deletions
+10 -1
View File
@@ -2,4 +2,13 @@
**/.git
**/.svelte-kit
**/dist
**/docs
**/docs
**/.github
**/.husky
**/.vscode
Dockerfile
.dockerignore
docker-compose.yml
README.md
+2
View File
@@ -0,0 +1,2 @@
MERMAID_DOMAIN="mermaid.live"
MERMAID_ANALYTICS_URL="https://p.mermaid.live"
+13 -16
View File
@@ -7,17 +7,11 @@ module.exports = {
// 'plugin:@typescript-eslint/recommended-requiring-type-checking',
'plugin:@typescript-eslint/strict',
'plugin:unicorn/recommended',
'plugin:svelte/recommended',
'plugin:svelte/prettier',
'prettier'
],
plugins: [
'svelte3',
'tailwindcss',
'@typescript-eslint',
'es',
'vitest',
'no-only-tests',
'unicorn'
],
plugins: ['tailwindcss', '@typescript-eslint', 'es', 'vitest', 'no-only-tests', 'unicorn'],
ignorePatterns: [
'docs/*',
'*.cjs',
@@ -30,7 +24,13 @@ module.exports = {
'tsconfig.json'
],
overrides: [
{ files: ['*.svelte'], processor: 'svelte3/svelte3' },
{
files: ['*.svelte'],
parser: 'svelte-eslint-parser',
parserOptions: {
parser: '@typescript-eslint/parser'
}
},
{
files: ['*.ts'],
extends: [
@@ -42,16 +42,12 @@ module.exports = {
]
}
],
settings: {
'svelte3/typescript': () => require('typescript')
},
parserOptions: {
sourceType: 'module',
ecmaVersion: 2020,
tsconfigRootDir: __dirname,
project: ['./tsconfig.json'],
extraFileExtensions: ['.svelte'],
allowAutomaticSingleRunInference: true
project: './tsconfig.json',
extraFileExtensions: ['.svelte']
},
env: {
browser: true,
@@ -76,6 +72,7 @@ module.exports = {
case: 'camelCase'
}
],
'unicorn/filename-case': 'off',
'unicorn/prevent-abbreviations': [
'error',
{
+1 -1
View File
@@ -12,6 +12,6 @@ Describe the way your implementation works or what design decisions you made if
Make sure you
- [ ] :book: have read the [contribution guidelines](https://github.com/mermaid-js/mermaid/blob/master/CONTRIBUTING.md)
- [ ] :book: have read the [contribution guidelines](https://mermaid.js.org/community/contributing.html)
- [ ] :computer: have added unit/e2e tests (if appropriate)
- [ ] :bookmark: targeted `develop` branch
+3
View File
@@ -20,6 +20,9 @@ jobs:
cache: yarn
- name: Build & Deploy
env:
MERMAID_DOMAIN: 'mermaid.live'
MERMAID_ANALYTICS_URL: 'https://p.mermaid.live'
run: |
export DEPLOY=true
[ "$GITHUB_EVENT_NAME" != "pull_request" ] && rm -rf docs/_app/
+31 -52
View File
@@ -2,13 +2,11 @@ name: Docker
on:
push:
# Publish `master` as Docker `latest` image.
branches:
# Publish `master` as Docker `latest` image.
- master
# Publish `v1.2.3` tags as releases.
tags:
- v*
# Publish `develop` as Docker `nightly` image.
- develop
# Run tests for all PRs to master and develop.
pull_request:
@@ -16,54 +14,35 @@ on:
- master
- develop
env:
IMAGE_NAME: mermaid-live-editor
jobs:
test:
docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run tests
- uses: actions/checkout@v4
- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Get release version
run: |
docker build . --file Dockerfile
push:
# Ensure test job passes before pushing image.
needs: test
runs-on: ubuntu-latest
if: github.event_name == 'push'
steps:
- uses: actions/checkout@v3
- name: Build image
run: docker build . --file Dockerfile --tag $IMAGE_NAME
- name: Log into registry
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
- name: Push image
run: |
IMAGE_ID=ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME
# Change all uppercase to lowercase
IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]')
# Strip git ref prefix from version
VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
# Strip "v" prefix from tag name
[[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')
# Use Docker `latest` tag convention
[ "$VERSION" == "master" ] && VERSION=latest
echo IMAGE_ID=$IMAGE_ID
echo VERSION=$VERSION
docker tag $IMAGE_NAME $IMAGE_ID:$VERSION
docker push $IMAGE_ID:$VERSION
RELEASE_VERSION=$([ "${{ github.ref_name }}" = "master" ] && echo "latest" || echo "nightly")
echo "RELEASE_VERSION=${RELEASE_VERSION}" >> "${GITHUB_ENV}"
- uses: docker/metadata-action@v5
id: meta
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=raw,value=${{ env.RELEASE_VERSION }}
- uses: docker/build-push-action@v5
with:
context: .
target: mermaid
push: ${{ github.event_name == 'push' }}
pull: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
-20
View File
@@ -1,20 +0,0 @@
name: Mark stale issues and pull requests
on:
schedule:
- cron: '0 0 * * 4'
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v8
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
exempt-issue-labels: 'retained'
exempt-pr-labels: 'retained'
stale-issue-message: 'This issue is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 30 days'
stale-pr-message: 'This pr is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 30 days'
days-before-stale: 90
days-before-close: 30
days-before-pr-close: -1
+1
View File
@@ -0,0 +1 @@
20.14.0
+3 -1
View File
@@ -3,5 +3,7 @@
"svelteSortOrder": "options-scripts-markup-styles",
"bracketSameLine": true,
"trailingComma": "none",
"printWidth": 100
"printWidth": 100,
"tailwindConfig": "./tailwind.config.cjs",
"plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"]
}
+6
View File
@@ -9,11 +9,17 @@
"cssnano",
"daisyui",
"esserializer",
"gantt",
"gitgraph",
"KROKI",
"localstorage",
"mermaidchart",
"mindmap",
"Pageview",
"pako",
"panzoom",
"pzoom",
"roughjs",
"Serde",
"serdes",
"tailwindcss",
+29 -13
View File
@@ -1,17 +1,33 @@
# Two-stage docker container for mermaid-js/mermaid-live-editor
# Build : docker build -t mermaid-js/mermaid-live-editor .
# Run : docker run --name mermaid-live-editor --publish 8080:8080 mermaid-js/mermaid-live-editor
# Start : docker start mermaid-live-editor
# Use webbrowser : http://localhost:8080
# Stop : press ctrl + c
# or
# docker stop mermaid-live-editor
FROM node:18.17.1 as mermaid-live-editor-builder
COPY --chown=node:node . /home
WORKDIR /home
FROM docker.io/library/node:20-alpine3.18 AS mermaid-live-editor-dependencies
RUN apk --no-cache add build-base git python3 && \
rm -rf /var/cache/apk/*
RUN yarn global add node-gyp
WORKDIR /app
COPY ./package.json .
COPY ./yarn.lock .
RUN yarn install
FROM mermaid-live-editor-dependencies AS mermaid-live-editor-builder
ARG MERMAID_RENDERER_URL
ARG MERMAID_KROKI_RENDERER_URL
ARG MERMAID_ANALYTICS_URL
ARG MERMAID_DOMAIN
COPY . ./
RUN yarn build
FROM nginxinc/nginx-unprivileged:alpine as mermaid-live-editor-runner
FROM mermaid-live-editor-builder AS mermaid-dev
ENTRYPOINT ["yarn", "dev"]
FROM nginx:1.25-alpine3.18 AS mermaid
COPY ./nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=mermaid-live-editor-builder --chown=nginx:nginx /home/docs /usr/share/nginx/html
COPY --from=mermaid-live-editor-builder /app/docs /usr/share/nginx/html
-8
View File
@@ -1,8 +0,0 @@
FROM node:18.17.1
WORKDIR /app
COPY package.json .
COPY yarn.lock .
RUN npm install
COPY . .
RUN ls
CMD ["yarn", "dev"]
+31 -3
View File
@@ -1,4 +1,4 @@
[![Mermaid Live Editor](https://img.shields.io/endpoint?url=https://dashboard.cypress.io/badge/detailed/2ckppp/master&style=flat&logo=cypress)](https://dashboard.cypress.io/projects/2ckppp/runs) [![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)[![Netlify Status](https://api.netlify.com/api/v1/badges/27fa023d-7c73-4a3f-9791-b3b657a47100/deploy-status)](https://app.netlify.com/sites/mermaidjs/deploys)
[![Mermaid Live Editor](https://img.shields.io/endpoint?url=https://dashboard.cypress.io/badge/detailed/2ckppp/master&style=flat&logo=cypress)](https://dashboard.cypress.io/projects/2ckppp/runs) [![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) [![Netlify Status](https://api.netlify.com/api/v1/badges/27fa023d-7c73-4a3f-9791-b3b657a47100/deploy-status)](https://app.netlify.com/sites/mermaidjs/deploys)
# Contributors are welcome!
@@ -29,14 +29,20 @@ docker run --platform linux/amd64 --publish 8000:8080 ghcr.io/mermaid-js/mermaid
### To configure renderer URL
When building, Set the Environment variable MERMAID_RENDERER_URL to the rendering service.
When building set the MERMAID_RENDERER_URL build argument to the rendering service.
Default is `https://mermaid.ink`
### To configure Kroki Instance URL
When building, Set the Environment variable MERMAID_KROKI_RENDERER_URL to your Kroki instance.
When building set the MERMAID_KROKI_RENDERER_URL build argument to your Kroki instance.
Default is `https://kroki.io`
### To configure Analytics
When building set the MERMAID_ANALYTICS_URL build argument to your plausible instance, and MERMAID_DOMAIN to your domain.
Default is empty, disabling analytics.
### Development
```bash
@@ -45,6 +51,28 @@ docker compose up --build
Then open http://localhost:3000
### Building and running images locally
#### Build
```bash
docker build -t mermaid-js/mermaid-live-editor .
```
#### Run
```bash
docker run --detach --name mermaid-live-editor --publish 8080:8080 mermaid-js/mermaid-live-editor
```
Visit: <http://localhost:8080>
#### Stop
```bash
docker stop mermaid-live-editor
```
## Setup
Below link will help you making a copy of the repository in your local system.
+13 -11
View File
@@ -1,6 +1,6 @@
import { defineConfig } from 'cypress';
import fs from 'fs';
import { isFileExist, findFiles } from 'cy-verify-downloads';
import path from 'path';
export default defineConfig({
projectId: '2ckppp',
viewportWidth: 1440,
@@ -15,17 +15,19 @@ export default defineConfig({
e2e: {
setupNodeEvents(on, config) {
on('task', {
isFileExist,
findFiles,
deleteFile(path) {
fs.rmSync(path);
return null;
},
readFileMaybe(filename) {
if (fs.existsSync(filename)) {
return fs.readFileSync(filename, 'utf8');
readAndDeleteFile({ fileNamePattern, folder, mode }) {
const fileNameRegex = new RegExp(fileNamePattern);
const files = fs.readdirSync(folder);
const filename = files.find((file) => file.match(fileNameRegex));
const filePath = path.join(folder, filename);
try {
if (mode === 'size') {
return fs.statSync(filePath).size;
}
return fs.readFileSync(filePath, 'utf8');
} finally {
fs.rmSync(filePath);
}
return null;
}
});
},
-4
View File
@@ -26,8 +26,6 @@ describe('Check actions', () => {
});
it('should download png and svg', () => {
cy.clock(new Date(2022, 0, 1).getTime());
cy.get(`#downloadPNG`).click();
verifyFileSizeGreaterThan('diagram', 'png', 34_000);
@@ -43,7 +41,5 @@ describe('Check actions', () => {
cy.get(`#downloadSVG`).click();
verifyFileSizeGreaterThan('diagram', 'svg', 11_000);
cy.clock().invoke('restore');
});
});
+19 -1
View File
@@ -50,8 +50,26 @@ describe('Auto sync tests', () => {
cy.getLocalStorage('codeStore').snapshot();
});
it('should automatically defer rendering when complex diagrams are edited', () => {
cy.get('#view').should('not.have.class', 'outOfSync');
typeInEditor(`
A & B & C & D & E --> F & G & K & Z & i
A & B & C & D & E --> F & G & K & Z & i
A & B & C & D & E --> F & G & K & Z & i
A & B & C & D & E --> F & G & K & Z & i
A & B & C & D & E --> F & G & K & Z & i
A & B & C & D & E --> F & G & K & Z & i
A & B & C & D & E --> F & G & K & Z & i
A & B & C & D & E --> F & G & K & Z & i
A & B & C & D & E --> F & G & K & Z & i`);
cy.get('#view').should('have.class', 'outOfSync');
cy.get('#errorContainer').should('contain.text', 'It will be updated automatically.');
// The class should be removed automatically after 1 second.
cy.get('#view').should('not.have.class', 'outOfSync');
});
it('supports commenting code out/in', () => {
cy.get('#editor').contains('Car').click();
cy.get('#editor').contains('Car').click({ force: true });
cy.get('#editor').get('textarea').type(`${cmd}/`, { force: true });
cy.get('#view').contains('Car').should('not.exist');
+7 -7
View File
@@ -9,28 +9,28 @@ describe('Editor docs tests', () => {
});
it('Test default loading', () => {
cy.get(`[data-cy=docs][href^="https://mermaid-js.github.io/mermaid"]`).should('exist');
cy.get(`[data-cy=docs][href^="https://mermaid.js.org/"]`).should('exist');
});
it('Test to see if the correct URL loads when changing from one diagram to other', () => {
cy.contains('Flow').click();
cy.get(`[data-cy=docs][href$="/#/flowchart"]`).should('exist');
cy.get(`[data-cy=docs][href$="/syntax/flowchart.html"]`).should('exist');
cy.contains('Config').click();
cy.get(`[data-cy=docs][href$="/#/flowchart?id=configuration"]`).should('exist');
cy.get(`[data-cy=docs][href$="/syntax/flowchart.html#configuration"]`).should('exist');
cy.contains('Sequence').click();
cy.get(`[data-cy=docs][href$="/#/sequenceDiagram?id=configuration"]`).should('exist');
cy.get(`[data-cy=docs][href$="/syntax/sequenceDiagram.html#configuration"]`).should('exist');
cy.contains('Code').click();
cy.get(`[data-cy=docs][href$="/#/sequenceDiagram"]`).should('exist');
cy.get(`[data-cy=docs][href$="/syntax/sequenceDiagram.html"]`).should('exist');
});
it("Test to check URLs for a case where config URL doesn't exist", () => {
cy.contains('State').click();
cy.get(`[data-cy=docs][href$="/#/stateDiagram"]`).should('exist');
cy.get(`[data-cy=docs][href$="/syntax/stateDiagram.html"]`).should('exist');
cy.contains('Config').click();
cy.get(`[data-cy=docs][href$="/#/stateDiagram"]`).should('exist');
cy.get(`[data-cy=docs][href$="/syntax/stateDiagram.html"]`).should('exist');
});
});
+16 -21
View File
@@ -11,7 +11,7 @@ export const typeInEditor = (
) => {
cy.window().should('have.property', 'editorLoaded', true);
cy.get('#editor').click();
cy.get('#editor').within(($editor) => {
cy.get('#editor').within(() => {
if (bottom) {
cy.get('textarea').type('{pageDown}', { force: true });
}
@@ -29,17 +29,15 @@ export const verifyFileSizeGreaterThan = (
extension: string,
size: number
) => {
const fileName = `mermaid-${fileType}-2022-01-01-000000.${extension}`;
const filePath = `${downloadsFolder}/${fileName}`;
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
cy.verifyDownload(fileName);
cy.readFile(filePath, null, {
log: false
}).then((buffer: ArrayBuffer) => {
expect(buffer.byteLength).to.be.gt(size);
expect(buffer.byteLength).to.be.lt(size * 1.3);
cy.get('#view').should('not.have.class', 'outOfSync');
cy.task('readAndDeleteFile', {
folder: downloadsFolder,
fileNamePattern: `^mermaid-${fileType}-.*.${extension}$`,
mode: 'size'
}).then((fileSize: number) => {
expect(fileSize).to.be.gt(size);
expect(fileSize).to.be.lt(size * 1.3);
});
cy.task('deleteFile', filePath);
};
export const verifyFileSnapshot = (
@@ -47,14 +45,11 @@ export const verifyFileSnapshot = (
extension: string,
content: string
) => {
const fileName = `mermaid-${fileType}-2022-01-01-000000.${extension}`;
const filePath = `${downloadsFolder}/${fileName}`;
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
cy.verifyDownload(fileName);
cy.readFile(filePath, null, {
log: false
}).then((buffer: ArrayBuffer) =>
expect(new TextDecoder('utf8').decode(buffer)).to.contain(content)
);
cy.task('deleteFile', filePath);
cy.task('readAndDeleteFile', {
folder: downloadsFolder,
fileNamePattern: `^mermaid-${fileType}-.*.${extension}$`,
mode: 'content'
}).then((fileContent: number) => {
expect(fileContent).to.contain(content);
});
};
-1
View File
@@ -15,7 +15,6 @@
// Import commands.js using ES2015 syntax:
import './commands';
require('cy-verify-downloads').addCustomCommand();
// Alternatively you can use CommonJS syntax:
// require('./commands')
+1 -1
View File
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"allowJs": true,
"types": ["cypress", "cypress-localstorage-commands", "cy-verify-downloads", "node"]
"types": ["cypress", "cypress-localstorage-commands", "node"]
},
"include": ["**/*.ts"]
}
+1 -1
View File
@@ -3,7 +3,7 @@ services:
mermaid:
build:
context: .
dockerfile: Dockerfile.dev
target: mermaid-dev
volumes:
- ./src:/app/src
ports:
+3
View File
@@ -0,0 +1,3 @@
[build.environment]
MERMAID_ANALYTICS_URL = 'https://p.mermaid.live'
MERMAID_DOMAIN = 'mermaid.live'
+49 -45
View File
@@ -9,9 +9,9 @@
"dev:test": "yarn dev",
"build": "vite build",
"preview": "vite preview",
"lint": "prettier --check --cache --plugin-search-dir=. .;eslint --ignore-path .gitignore .",
"lint:fix": "prettier --write --cache --plugin-search-dir=. .;eslint --fix --ignore-path .gitignore .",
"format": "prettier --write --cache --plugin-search-dir=. .",
"lint": "prettier --check --cache . && eslint --ignore-path .gitignore .",
"lint:fix": "prettier --write --cache . && eslint --fix --ignore-path .gitignore .",
"format": "prettier --write --cache .",
"pre-commit": "lint-staged",
"postinstall": "husky install && svelte-kit sync && (git config blame.ignoreRevsFile .git-blame-ignore-revs || true)",
"test:unit": "vitest",
@@ -23,61 +23,65 @@
},
"devDependencies": {
"@cypress/snapshot": "2.1.7",
"@sveltejs/adapter-static": "2.0.3",
"@sveltejs/kit": "1.25.0",
"@testing-library/jest-dom": "5.17.0",
"@testing-library/svelte": "3.2.2",
"@types/pako": "2.0.0",
"@types/uuid": "9.0.4",
"@typescript-eslint/eslint-plugin": "5.62.0",
"@typescript-eslint/parser": "5.62.0",
"@vitest/ui": "^0.34.0",
"@fortawesome/fontawesome-free": "^6.5.1",
"@sveltejs/adapter-static": "3.0.2",
"@sveltejs/kit": "2.5.16",
"@sveltejs/vite-plugin-svelte": "^3.0.1",
"@testing-library/svelte": "4.2.3",
"@types/lodash-es": "^4.17.12",
"@types/pako": "2.0.3",
"@types/uuid": "9.0.8",
"@typescript-eslint/eslint-plugin": "6.21.0",
"@typescript-eslint/parser": "6.21.0",
"@vitest/ui": "^1.1.3",
"autoprefixer": "^10.4.14",
"c8": "7.14.0",
"chai": "^4.3.7",
"cssnano": "^6.0.0",
"cy-verify-downloads": "0.2.0",
"cypress": "12.17.4",
"cypress-localstorage-commands": "2.2.4",
"eslint": "8.49.0",
"eslint-config-prettier": "8.10.0",
"eslint-plugin-cypress": "2.14.0",
"eslint-plugin-es": "4.1.0",
"cypress-localstorage-commands": "2.2.6",
"eslint": "8.57.0",
"eslint-config-prettier": "9.1.0",
"eslint-plugin-cypress": "2.15.2",
"eslint-plugin-es": "^4.1.0",
"eslint-plugin-no-only-tests": "^3.1.0",
"eslint-plugin-postcss-modules": "2.0.0",
"eslint-plugin-svelte3": "4.0.0",
"eslint-plugin-tailwindcss": "3.13.0",
"eslint-plugin-unicorn": "^46.0.0",
"eslint-plugin-vitest": "^0.3.0",
"esserializer": "1.3.11",
"font-awesome": "^4.7.0",
"eslint-plugin-postcss-modules": "^2.0.0",
"eslint-plugin-svelte": "^2.35.1",
"eslint-plugin-tailwindcss": "^3.13.1",
"eslint-plugin-unicorn": "^50.0.1",
"eslint-plugin-vitest": "^0.5.0",
"esserializer": "^1.3.11",
"husky": "^8.0.3",
"jsdom": "21.1.2",
"lint-staged": "13.3.0",
"jsdom": "^21.1.2",
"lint-staged": "^15.2.0",
"node-html-parser": "^6.1.5",
"postcss": "^8.4.21",
"postcss-load-config": "4.0.1",
"prettier": "2.8.8",
"prettier-plugin-svelte": "^2.10.0",
"svelte": "3.59.2",
"svelte-preprocess": "5.0.4",
"tailwindcss": "^3.3.1",
"tslib": "^2.5.0",
"typescript": "5.2.2",
"vite": "^4.3.9",
"vitest": "^0.34.0"
"postcss": "^8.4.33",
"postcss-load-config": "5.1.0",
"prettier": "^3.1.0",
"prettier-plugin-svelte": "^3.1.2",
"prettier-plugin-tailwindcss": "^0.6.0",
"svelte": "^4.2.8",
"svelte-preprocess": "^5.1.3",
"tailwindcss": "^3.4.1",
"tslib": "^2.6.2",
"typescript": "^5.3.3",
"vite": "^5.0.11",
"vitest": "^1.1.3",
"vitest-dom": "^0.1.1"
},
"dependencies": {
"analytics": "0.8.9",
"analytics-plugin-plausible": "0.0.6",
"@mermaid-js/mermaid-zenuml": "^0.2.0",
"daisyui": "2.52.0",
"dayjs": "^1.11.7",
"js-base64": "3.7.5",
"mermaid": "10.5.0",
"monaco-editor": "0.43.0",
"js-base64": "3.7.7",
"lodash-es": "^4.17.21",
"mermaid": "10.9.1",
"monaco-editor": "0.49.0",
"pako": "2.1.0",
"plausible-tracker": "^0.3.8",
"random-word-slugs": "0.1.7",
"svg-pan-zoom": "3.6.1",
"svg2roughjs": "^3.2.0",
"uuid": "9.0.1"
},
"lint-staged": {
@@ -87,8 +91,8 @@
]
},
"volta": {
"node": "18.17.1",
"yarn": "1.22.19"
"node": "18.20.3",
"yarn": "1.22.22"
},
"engines": {
"node": ">=16.7"
+2 -8
View File
@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
@@ -15,15 +15,9 @@
<link rel="mask-icon" href="%sveltekit.assets%/favicon.svg" color="#000000" />
<meta name="theme-color" content="#6366F1" />
<link rel="manifest" href="%sveltekit.assets%/manifest.json" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css"
integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA=="
crossorigin="anonymous"
referrerpolicy="no-referrer" />
%sveltekit.head%
</head>
<body>
<body style="overflow: hidden">
<div id="svelte">%sveltekit.body%</div>
</body>
</html>
+8 -1
View File
@@ -1,10 +1,17 @@
@import '@fortawesome/fontawesome-free/css/all.min.css';
@tailwind base;
@tailwind components;
@tailwind utilities;
.input {
@apply flex-1 border-primary border-solid border-2 rounded;
@apply flex-1 rounded border-2 border-solid border-primary;
}
.action-btn {
@apply btn btn-primary;
}
#graph-div sub,
#graph-div sup {
position: initial;
vertical-align: revert;
}
+2 -3
View File
@@ -3,9 +3,8 @@
interface ImportMetaEnv {
readonly MERMAID_RENDERER_URL?: string;
readonly MERMAID_KROKI_RENDERER_URL?: string;
readonly MERMAID_CDN_URL?: string;
readonly MERMAID_BASE_URL?: string;
readonly MERMAID_LOCAL?: boolean;
readonly MERMAID_ANALYTICS_URL?: string;
readonly MERMAID_DOMAIN?: string;
// more env variables...
}
-15
View File
@@ -1,16 +1 @@
/* eslint-disable @typescript-eslint/no-empty-interface */
/* eslint-disable @typescript-eslint/ban-types */
/* eslint-disable @typescript-eslint/no-unused-vars */
/// <reference types="@sveltejs/kit" />
import type { TestingLibraryMatchers } from '@testing-library/jest-dom/matchers';
declare global {
namespace jest {
interface Matchers<R = void>
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
// eslint-disable-next-line no-undef
extends TestingLibraryMatchers<typeof expect.stringContaining, R> {}
}
}
+40 -36
View File
@@ -1,34 +1,49 @@
<script lang="ts">
import { browser } from '$app/environment';
import Card from '$lib/components/Card/Card.svelte';
import { waitForRender } from '$lib/util/autoSync';
import { env } from '$lib/util/env';
import { pakoSerde } from '$lib/util/serde';
import { stateStore } from '$lib/util/state';
import { logEvent } from '$lib/util/stats';
import { toBase64 } from 'js-base64';
import dayjs from 'dayjs';
const { krokiRendererUrl, rendererUrl } = env;
import { toBase64 } from 'js-base64';
import { version as FAVersion } from '@fortawesome/fontawesome-free/package.json';
const FONT_AWESOME_URL = `https://cdnjs.cloudflare.com/ajax/libs/font-awesome/${FAVersion}/css/all.min.css`;
const { krokiRendererUrl, rendererUrl } = env;
type Exporter = (context: CanvasRenderingContext2D, image: HTMLImageElement) => () => void;
const getFileName = (ext: string) =>
`mermaid-diagram-${dayjs().format('YYYY-MM-DD-HHmmss')}.${ext}`;
const getFileName = (extension: string) =>
`mermaid-diagram-${dayjs().format('YYYY-MM-DD-HHmmss')}.${extension}`;
const getBase64SVG = (svg?: HTMLElement, width?: number, height?: number): string => {
if (svg) {
// Prevents the SVG size of the interface from being changed
svg = svg.cloneNode(true) as HTMLElement;
}
height && svg?.setAttribute('height', `${height}px`);
width && svg?.setAttribute('width', `${width}px`); // Workaround https://stackoverflow.com/questions/28690643/firefox-error-rendering-an-svg-image-to-html5-canvas-with-drawimage
if (!svg) {
svg = getSvgEl();
svg = getSvgElement();
}
const svgString = svg.outerHTML
.replaceAll('<br>', '<br/>')
.replaceAll(/<img([^>]*)>/g, (m, g: string) => `<img ${g} />`);
return toBase64(svgString);
return toBase64(`<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="${FONT_AWESOME_URL}" type="text/css"?>
${svgString}`);
};
const exportImage = (event: Event, exporter: Exporter) => {
const exportImage = async (event: Event, exporter: Exporter) => {
await waitForRender();
if (document.querySelector('.outOfSync')) {
throw new Error('Diagram is out of sync');
}
const canvas: HTMLCanvasElement = document.createElement('canvas');
const svg: HTMLElement | null = document.querySelector('#container svg');
const svg = document.querySelector<HTMLElement>('#container svg');
if (!svg) {
throw new Error('svg not found');
}
@@ -49,32 +64,21 @@
if (!context) {
throw new Error('context not found');
}
context.fillStyle = 'white';
context.fillStyle = `hsl(${window.getComputedStyle(document.body).getPropertyValue('--b1')})`;
context.fillRect(0, 0, canvas.width, canvas.height);
const image = new Image();
image.onload = exporter(context, image);
image.addEventListener('load', exporter(context, image));
image.src = `data:image/svg+xml;base64,${getBase64SVG(svg, canvas.width, canvas.height)}`;
event.stopPropagation();
event.preventDefault();
};
const getSvgEl = () => {
const svgEl: HTMLElement = document
.querySelector('#container svg')!
.cloneNode(true) as HTMLElement;
svgEl.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
const fontAwesomeCdnUrl = Array.from(document.head.getElementsByTagName('link'))
.map((l) => l.href)
.find((h) => h.includes('font-awesome'));
if (fontAwesomeCdnUrl == null) {
return svgEl;
}
const styleEl = document.createElement('style');
styleEl.innerText = `@import url("${fontAwesomeCdnUrl}");'`;
svgEl.prepend(styleEl);
return svgEl;
const getSvgElement = () => {
const svgElement = document.querySelector('#container svg')?.cloneNode(true) as HTMLElement;
svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
return svgElement;
};
const simulateDownload = (download: string, href: string): void => {
@@ -120,13 +124,13 @@
};
};
const onCopyClipboard = (event: Event) => {
exportImage(event, clipboardCopy);
const onCopyClipboard = async (event: Event) => {
await exportImage(event, clipboardCopy);
logEvent('copyClipboard');
};
const onDownloadPNG = (event: Event) => {
exportImage(event, downloadImage);
const onDownloadPNG = async (event: Event) => {
await exportImage(event, downloadImage);
logEvent('download', {
type: 'png'
});
@@ -140,7 +144,7 @@
};
const onCopyMarkdown = () => {
(document.getElementById('markdown') as HTMLInputElement).select();
document.querySelector<HTMLInputElement>('#markdown')?.select();
document.execCommand('Copy');
logEvent('copyMarkdown');
};
@@ -181,7 +185,7 @@
</script>
<Card title="Actions" isOpen={false}>
<div class="flex flex-wrap gap-2 m-2">
<div class="m-2 flex flex-wrap gap-2">
{#if isClipboardAvailable()}
<button class="action-btn w-full" on:click={onCopyClipboard}
><i class="far fa-copy mr-2" /> Copy Image to clipboard
@@ -209,7 +213,7 @@
</button>
</a>
<div class="flex gap-2 items-center">
<div class="flex items-center gap-2">
PNG size
<label for="autosize">
<input type="radio" value="auto" id="autosize" bind:group={imagemodeselected} /> Auto
@@ -234,7 +238,7 @@
{/if}
</div>
<div class="w-full flex gap-2 items-center">
<div class="flex w-full items-center gap-2">
<input class="input" id="markdown" type="text" value={mdCode} on:click={onCopyMarkdown} />
<label for="markdown">
<button class="btn btn-primary btn-md flex-auto" on:click={onCopyMarkdown}>
@@ -243,7 +247,7 @@
</label>
</div>
<div class="w-full flex gap-2 items-center">
<div class="flex w-full items-center gap-2">
<input
class="input"
id="gist"
@@ -255,8 +259,8 @@
</label>
</div>
{#if isNetlify}
<div class="w-full flex items-center justify-center">
<a class="link underline text-gray-500 text-sm" href="https://netlify.com">
<div class="flex w-full items-center justify-center">
<a class="link text-sm text-gray-500 underline" href="https://netlify.com">
This site is powered by Netlify
</a>
</div>
+5 -3
View File
@@ -11,20 +11,22 @@
$: isTabsShown = isOpen && tabs.length > 0;
</script>
<div class="card rounded overflow-hidden m-2 flex-grow flex flex-col shadow-2xl">
<div class="card m-2 flex flex-grow flex-col overflow-hidden rounded shadow-2xl">
<div
role="toolbar"
tabindex="0"
class="bg-primary p-2 {isTabsShown ? 'pb-0' : ''} flex-none cursor-pointer"
on:click={() => (isOpen = !isOpen)}
on:keypress={() => (isOpen = !isOpen)}>
<div class="flex justify-between">
<Tabs on:select {tabs} bind:isOpen {title} {isCloseable} {activeTabID} />
<div class="flex gap-x-4 items-center {isTabsShown ? '-mt-2' : ''}">
<div class="flex items-center gap-x-4 {isTabsShown ? '-mt-2' : ''}">
<slot name="actions" />
</div>
</div>
</div>
{#if isOpen}
<div class="card-body p-0 flex-grow overflow-auto text-base-content" transition:slide>
<div class="card-body flex-grow overflow-auto p-0 text-base-content" transition:slide>
<slot />
</div>
{/if}
+4
View File
@@ -20,6 +20,8 @@
<div class="flex cursor-default">
<span
role="menubar"
tabindex="0"
class="mr-2 font-semibold"
on:click|stopPropagation={() => (isOpen = !isOpen)}
on:keypress|stopPropagation={() => (isOpen = !isOpen)}>
@@ -31,6 +33,8 @@
<ul class="tabs" transition:fade>
{#each tabs as tab}
<div
role="tab"
tabindex="0"
class="tab tab-lifted {activeTabID === tab.id ? 'tab-active' : 'text-primary-content'}"
on:click|stopPropagation={() => toggleTabs(tab)}
on:keypress|stopPropagation={() => toggleTabs(tab)}>
+18 -13
View File
@@ -1,3 +1,12 @@
<script lang="ts" context="module">
declare global {
interface Window {
Cypress: boolean;
editorLoaded: boolean;
}
}
</script>
<script lang="ts">
import type { EditorMode } from '$lib/types';
import { stateStore, updateCode, updateConfig } from '$lib/util/state';
@@ -10,7 +19,7 @@
import { initEditor } from '$lib/util/monacoExtra';
import { logEvent } from '$lib/util/stats';
let divEl: HTMLDivElement | undefined = undefined;
let divElement: HTMLDivElement | undefined;
let editor: monaco.editor.IStandaloneCodeEditor | undefined;
let editorOptions: monaco.editor.IStandaloneEditorConstructionOptions = {
minimap: {
@@ -64,7 +73,7 @@
}
};
onMount(async () => {
onMount(() => {
self.MonacoEnvironment = {
getWorker(_, label) {
if (label === 'json') {
@@ -74,16 +83,15 @@
}
};
if (!divEl) {
if (!divElement) {
throw new Error('divEl is undefined');
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
initEditor(monaco);
errorDebug(100);
editor = monaco.editor.create(divEl, editorOptions);
editor.onDidChangeModelContent(({ isFlush, changes }) => {
errorDebug();
editor = monaco.editor.create(divElement, editorOptions);
editor.onDidChangeModelContent(({ isFlush }) => {
const newText = editor?.getValue();
// console.log('editor onDidChangeModelContent', { text, newText, isFlush, changes });
if (!newText || text === newText || isFlush) {
return;
}
@@ -109,20 +117,17 @@
});
});
if (divEl.parentElement) {
resizeObserver.observe(divEl.parentElement);
if (divElement.parentElement) {
resizeObserver.observe(divElement.parentElement);
}
// @ts-ignore
if (window.Cypress) {
// @ts-ignore
window.editorLoaded = true;
}
return () => {
// console.log(`editor disposed`);
editor?.dispose();
};
});
</script>
<div bind:this={divEl} id="editor" class="overflow-hidden" />
<div bind:this={divElement} id="editor" class="overflow-hidden" />
+14 -18
View File
@@ -20,7 +20,7 @@
dayjs.extend(dayjsRelativeTime);
const HISTORY_SAVE_INTERVAL = 60000;
const HISTORY_SAVE_INTERVAL = 60_000;
const tabSelectHandler = (message: CustomEvent<Tab>) => {
historyModeStore.set(message.detail.id as HistoryType);
@@ -56,17 +56,13 @@
const input = document.createElement('input');
input.type = 'file';
input.accept = 'application/json';
input.addEventListener('change', ({ target }: Event) => {
const file = (<HTMLInputElement>target).files[0];
input.addEventListener('change', async ({ target }: Event) => {
const file = (target as HTMLInputElement)?.files?.[0];
if (!file) {
return;
}
const reader = new FileReader();
reader.onload = (e) => {
const data: HistoryEntry[] = JSON.parse(e.target.result as string);
restoreHistory(data);
};
reader.readAsText(file);
const data: HistoryEntry[] = JSON.parse(await file.text());
restoreHistory(data);
});
input.click();
};
@@ -129,34 +125,34 @@
<div slot="actions">
<button
id="uploadHistory"
class="btn btn-xs btn-secondary w-12"
class="btn btn-secondary btn-xs w-12"
on:click|stopPropagation={() => uploadHistory()}
title="Upload history"><i class="fa fa-upload" /></button>
{#if $historyStore.length > 0}
<button
id="downloadHistory"
class="btn btn-xs btn-secondary w-12"
class="btn btn-secondary btn-xs w-12"
on:click|stopPropagation={() => downloadHistory()}
title="Download history"><i class="fa fa-download" /></button>
{/if}
|
<button
id="saveHistory"
class="btn btn-xs btn-success w-12"
class="btn btn-success btn-xs w-12"
on:click|stopPropagation={() => saveHistory()}
title="Save current state"><i class="far fa-save" /></button>
{#if $historyModeStore !== 'loader'}
<button
id="clearHistory"
class="btn btn-xs btn-error w-12"
class="btn btn-error btn-xs w-12"
on:click|stopPropagation={() => clearHistory()}
title="Delete all saved states"><i class="fas fa-trash-alt" /></button>
{/if}
</div>
<ul class="p-2 space-y-2 overflow-auto h-56" id="historyList">
<ul class="h-56 space-y-2 overflow-auto p-2" id="historyList">
{#if $historyStore.length > 0}
{#each $historyStore as { id, state, time, name, url, type }}
<li class="rounded p-2 shadow flex-col">
<li class="flex-col rounded p-2 shadow">
<div class="flex">
<div class="flex-1">
<div class="flex flex-col text-base-content">
@@ -165,14 +161,14 @@
href={url}
target="_blank"
title="Open revision in new tab"
class="hover:underline text-blue-500">{name}</a>
class="text-blue-500 hover:underline">{name}</a>
{:else}
<span>{name}</span>
{/if}
<span class="text-gray-400 text-sm">{relativeTime(time)}</span>
<span class="text-sm text-gray-400">{relativeTime(time)}</span>
</div>
</div>
<div class="flex gap-2 content-center">
<div class="flex content-center gap-2">
<button class="btn btn-success" on:click={() => restoreHistoryItem(state)}
><i class="fas fa-undo mr-1" />Restore</button>
{#if type !== 'loader'}
+95 -18
View File
@@ -1,13 +1,20 @@
<script context="module" lang="ts">
import { version } from 'mermaid/package.json';
import { analytics } from '$lib/util/stats';
void analytics?.track('version', {
import { logEvent, plausible } from '$lib/util/stats';
void logEvent('version', {
mermaidVersion: version
});
</script>
<script lang="ts">
import Theme from './Theme.svelte';
import { dismissPromotion, getActivePromotion } from '$lib/util/promos/promo';
import Privacy from './Privacy.svelte';
let isMenuOpen = false;
function toggleMenu() {
isMenuOpen = !isMenuOpen;
}
interface Link {
href: string;
@@ -18,11 +25,11 @@
const links: Link[] = [
{
title: 'Documentation',
href: 'https://mermaid.js.org/intro/n00b-gettingStarted.html'
href: 'https://mermaid.js.org/intro/getting-started.html'
},
{
title: 'Tutorial',
href: 'https://mermaid.js.org/config/Tutorials.html'
href: 'https://mermaid.js.org/ecosystem/tutorials.html'
},
{
title: 'Mermaid',
@@ -38,31 +45,96 @@
},
{
href: 'https://mermaidchart.com',
img: '/mermaidchart-logo.svg'
img: './mermaidchart-logo.svg'
}
];
let activePromotion = getActivePromotion();
const trackBannerClick = () => {
if (!plausible || !activePromotion) {
return;
}
logEvent('bannerClick', {
promotion: activePromotion.id
});
};
</script>
<div class="navbar shadow-lg bg-primary p-0">
<div class="flex-1 px-2 mx-2">
{#if activePromotion}
<div
class="top-bar z-10 flex h-fit w-full items-center justify-center bg-gradient-to-r from-[#bd34fe] to-[#ff3670] p-1 text-center text-white">
<div
class="flex flex-grow"
role="button"
tabindex="0"
on:click={trackBannerClick}
on:keypress={trackBannerClick}>
<svelte:component this={activePromotion.component} />
</div>
<button
title="Dismiss banner"
on:click={() => {
dismissPromotion(activePromotion?.id);
activePromotion = undefined;
}}>
<i class="fa fa-close px-2" />
</button>
</div>
{/if}
<div class="navbar bg-primary p-0 shadow-lg">
<div class="mx-2 flex-1 px-2">
<span class="text-lg font-bold">
<a href="/">Mermaid<span class="text-xs font-thin">v{version}</span> Live Editor</a>
</span>
</div>
<label for="menu-toggle" class="pointer-cursor lg:hidden block"
><svg
class="fill-current"
<label
for="menu-toggle"
class={isMenuOpen ? 'hidden' : 'pointer-cursor fixed right-4 z-[1000] lg:hidden'}>
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
class="fill-current"
width="20"
height="20"
viewBox="0 0 20 20"
><title>Menu</title><path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z" /></svg
></label>
<input class="hidden" type="checkbox" id="menu-toggle" />
viewBox="0 0 20 20">
<title>Menu</title>
<path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z" />
</svg>
</label>
<Theme />
<div class="hidden lg:flex lg:items-center lg:w-auto w-full" id="menu">
<ul class="lg:flex items-center justify-between text-base pt-4 lg:pt-0">
<!-- Cross SVG -->
<label
for="menu-toggle"
class={isMenuOpen ? 'pointer-cursor fixed right-4 z-[1000] lg:hidden' : 'hidden'}>
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
class="fill-current"
width="20"
height="20"
viewBox="0 0 20 20">
<title>Cross</title>
<line x1="5" y1="5" x2="15" y2="15" stroke="white" stroke-width="2" />
<line x1="5" y1="15" x2="15" y2="5" stroke="white" stroke-width="2" />
</svg>
</label>
<input
class="hidden"
type="checkbox"
id="menu-toggle"
bind:checked={isMenuOpen}
on:click={toggleMenu} />
<div class="hidden w-full lg:flex lg:w-auto lg:items-center" id="menu">
<Theme />
<ul class="items-center justify-between pt-4 text-base lg:flex lg:pt-0">
<li>
<Privacy />
</li>
{#each links as { title, href, icon, img }}
<li>
<a class="btn btn-ghost" target="_blank" {href}>
@@ -83,8 +155,13 @@
<style>
#menu-toggle:checked + #menu {
display: block;
position: absolute;
top: 2.5rem;
padding: 1rem 0;
background: #661ae6;
display: flex;
}
.navbar {
z-index: 10000;
}
+60 -7
View File
@@ -115,7 +115,57 @@
Campaign C: [0.57, 0.69]
Campaign D: [0.78, 0.34]
Campaign E: [0.40, 0.34]
Campaign F: [0.35, 0.78]`
Campaign F: [0.35, 0.78]`,
XYChart: `
xychart-beta
title "Sales Revenue"
x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
y-axis "Revenue (in $)" 4000 --> 11000
bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000]
line [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000]`,
Block: `block-beta
columns 3
doc>"Document"]:3
space down1<[" "]>(down) space
block:e:3
l["left"]
m("A wide one in the middle")
r["right"]
end
space down2<[" "]>(down) space
db[("DB")]:3
space:3
D space C
db --> D
C --> db
D --> C
style m fill:#d6d,stroke:#333,stroke-width:4px
`,
ZenUML: `zenuml
title Order Service
@Actor Client #FFEBE6
@Boundary OrderController #0747A6
@EC2 <<BFF>> OrderService #E3FCEF
group BusinessService {
@Lambda PurchaseService
@AzureFunction InvoiceService
}
@Starter(Client)
// \`POST /orders\`
OrderController.post(payload) {
OrderService.create(payload) {
order = new Order(payload)
if(order != null) {
par {
PurchaseService.createPO(order)
InvoiceService.createInvoice(order)
}
}
}
}
`
};
type SampleTypes = keyof typeof samples;
@@ -128,10 +178,10 @@
};
// Adding in this array will add an icon to the preset menu
const newDiagrams: SampleTypes[] = ['Mindmap', 'QuadrantChart'];
const newDiagrams: SampleTypes[] = ['QuadrantChart', 'XYChart', 'Block', 'ZenUML'];
const diagramOrder: SampleTypes[] = [
'Sequence',
'Flow',
'Sequence',
'Class',
'State',
'ER',
@@ -140,19 +190,22 @@
'Git',
'Pie',
'Mindmap',
'QuadrantChart'
'QuadrantChart',
'XYChart',
'Block',
'ZenUML'
];
</script>
<Card title="Sample Diagrams" isOpen={false}>
<div class="flex flex-wrap p-2 gap-2">
<div class="flex flex-wrap gap-2 p-2">
{#each diagramOrder as sample}
<button
class="btn btn-sm btn-primary w-28 normal-case flex-grow"
class="btn btn-primary btn-sm w-fit min-w-20 flex-grow normal-case"
on:click={() => loadSampleDiagram(sample)}>
{sample}
{#if newDiagrams.includes(sample)}
<span class="ml-2 fa fa-heart" />
<span class="fa fa-heart ml-2" />
{/if}
</button>
{/each}
+42
View File
@@ -0,0 +1,42 @@
<label for="privacyModal" class="btn btn-ghost flex gap-2">
<i class="fa-solid fa-shield-halved text-xl"></i> Security
</label>
<input type="checkbox" id="privacyModal" class="modal-toggle" />
<div class="modal" role="dialog">
<div class="modal-box flex flex-col gap-4 text-base-content">
<h1 class="text-3xl font-bold">Data security</h1>
<p>
<span class="text-xl font-extrabold">
The content of the diagrams you create never leaves your browser.
</span>
It's stored in the URL, and the browser's local storage only.
</p>
<p>
Mermaid live editor is a fully client side application, that will also work as an offline <a
href="https://web.dev/explore/progressive-web-apps"
class="link"
target="_blank">
PWA.
</a>
</p>
<p>
The only server we have is a self hosted version of the open source and privacy friendly
Plausible Analytics. We only collect data related to actions performed, like the type of
diagram rendered, number of times a feature was used, etc. <br /> All the data we collect is
anonymized and
<a href="https://p.mermaid.live/mermaid.live" class="link" target="_blank">
available publicly.
</a>
</p>
<p>
Additional services like the external PNG/SVG/Kroki links and "Save to Mermaid Chart" feature
will share your diagram with the respective 3rd party service.
</p>
<label class="btn btn-circle btn-ghost btn-sm absolute right-2 top-2" for="privacyModal">
X
</label>
</div>
</div>
+7 -5
View File
@@ -26,14 +26,14 @@
];
</script>
<div class="hidden lg:block dropdown">
<div class="dropdown hidden lg:block">
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
<div tabindex="0" class="btn btn-ghost">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
class="inline-block w-6 h-6 stroke-current md:mr-2"
class="inline-block h-6 w-6 stroke-current md:mr-2"
><path
stroke-linecap="round"
stroke-linejoin="round"
@@ -43,17 +43,19 @@
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 1792 1792"
class="inline-block w-4 h-4 ml-1 fill-current"
class="ml-1 inline-block h-4 w-4 fill-current"
><path
d="M1395 736q0 13-10 23l-466 466q-10 10-23 10t-23-10l-466-466q-10-10-10-23t10-23l50-50q10-10 23-10t23 10l393 393 393-393q10-10 23-10t23 10l50 50q10 10 10 23z" /></svg>
</div>
<div
class="mt-14 overflow-y-auto shadow-2xl top-px dropdown-content h-96 w-56 bg-base-200 text-base-content">
class="dropdown-content top-px mt-14 h-96 w-56 overflow-y-auto bg-base-200 text-base-content shadow-2xl">
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
<ul tabindex="0" class="p-4 menu compact">
<ul tabindex="0" class="menu compact p-4">
{#each themes as theme}
<li class:bordered={$themeStore.theme !== undefined && theme.includes($themeStore.theme)}>
<span
role="menuitem"
tabindex="0"
class="btn btn-ghost justify-start"
on:click={() => setTheme(theme)}
on:keypress={() => setTheme(theme)}>{theme}</span>
+68 -22
View File
@@ -1,18 +1,22 @@
<script lang="ts">
import type { State, ValidatedState } from '$lib/types';
import { recordRenderTime, shouldRefreshView } from '$lib/util/autoSync';
import { render as renderDiagram } from '$lib/util/mermaid';
import { inputStateStore, stateStore, updateCodeStore } from '$lib/util/state';
import { logEvent, saveStatistics } from '$lib/util/stats';
import { cmdKey } from '$lib/util/util';
import type { MermaidConfig } from 'mermaid';
import { onMount } from 'svelte';
import panzoom from 'svg-pan-zoom';
import type { State, ValidatedState } from '$lib/types';
import { logEvent } from '$lib/util/stats';
import { cmdKey } from '$lib/util/util';
import { render as renderDiagram } from '$lib/util/mermaid';
import type { MermaidConfig } from 'mermaid';
import { Svg2Roughjs } from 'svg2roughjs';
let code = '';
let config = '';
let container: HTMLDivElement;
let rough: boolean;
let view: HTMLDivElement;
let error = false;
let errorLines: string[] = [];
let outOfSync = false;
let hide = false;
let manualUpdate = true;
@@ -37,7 +41,7 @@
pzoom?.destroy();
pzoom = undefined;
void Promise.resolve().then(() => {
const graphDiv = document.getElementById('graph-div');
const graphDiv = document.querySelector<HTMLElement>('#graph-div');
if (!graphDiv) {
return;
}
@@ -58,8 +62,10 @@
};
const handleStateChange = async (state: ValidatedState) => {
const startTime = Date.now();
if (state.error !== undefined) {
error = true;
errorLines = state.error.toString().split('\n');
return;
}
error = false;
@@ -71,13 +77,25 @@
outOfSync = false;
manualUpdate = true;
// Do not render if there is no change in Code/Config/PanZoom
if (code === state.code && config === state.mermaid && panZoomEnabled === state.panZoom) {
if (
code === state.code &&
config === state.mermaid &&
panZoomEnabled === state.panZoom &&
rough === state.rough
) {
return;
}
if (!shouldRefreshView()) {
outOfSync = true;
return;
}
code = state.code;
config = state.mermaid;
panZoomEnabled = state.panZoom;
const scroll = view.parentElement!.scrollTop;
rough = state.rough;
const scroll = view.parentElement?.scrollTop;
delete container.dataset.processed;
const { svg, bindFunctions } = await renderDiagram(
Object.assign({}, JSON.parse(state.mermaid)) as MermaidConfig,
@@ -88,29 +106,51 @@
if (svg.length > 0) {
handlePanZoom(state);
container.innerHTML = svg;
console.log({ svg });
const graphDiv = document.getElementById('graph-div');
const graphDiv = document.querySelector<SVGSVGElement>('#graph-div');
if (!graphDiv) {
throw new Error('graph-div not found');
}
graphDiv.setAttribute('height', '100%');
graphDiv.style.maxWidth = '100%';
if (bindFunctions) {
bindFunctions(graphDiv);
if (state.rough) {
const svg2roughjs = new Svg2Roughjs('#container');
svg2roughjs.svg = graphDiv;
await svg2roughjs.sketch();
graphDiv.remove();
const sketch = document.querySelector<HTMLElement>('#container > svg');
if (!sketch) {
throw new Error('sketch not found');
}
const height = sketch.getAttribute('height');
const width = sketch.getAttribute('width');
sketch.setAttribute('height', '100%');
sketch.setAttribute('width', '100%');
sketch.setAttribute('viewBox', `0 0 ${width} ${height}`);
sketch.style.maxWidth = '100%';
} else {
graphDiv.setAttribute('height', '100%');
graphDiv.style.maxWidth = '100%';
if (bindFunctions) {
bindFunctions(graphDiv);
}
}
}
view.parentElement!.scrollTop = scroll;
if (view.parentElement && scroll) {
view.parentElement.scrollTop = scroll;
}
error = false;
} else if (manualUpdate) {
manualUpdate = false;
} else if (code !== state.code || config !== state.mermaid) {
outOfSync = true;
}
} catch (e) {
console.error('view fail', e);
} catch (error_) {
console.error('view fail', error_);
error = true;
}
const renderTime = Date.now() - startTime;
saveStatistics({ code, renderTime, isRough: state.rough });
recordRenderTime(renderTime, () => {
$inputStateStore.updateDiagram = true;
});
};
onMount(() => {
@@ -127,20 +167,26 @@
{#if (error && $stateStore.error instanceof Error) || outOfSync}
<div
class="absolute w-full p-2 z-10 font-mono {error
class="absolute z-10 w-full p-2 font-mono {error
? 'text-red-600'
: 'text-yellow-600'} bg-base-100 bg-opacity-80 text-left"
id="errorContainer">
{#if error}
{@html $stateStore.error?.toString().replace(/\n/g, '<br />')}
{#each errorLines as line}
{line}<br />
{/each}
{:else}
Diagram out of sync. <br />
Press <i class="fas fa-sync" /> (Sync button) or <kbd>{cmdKey} + Enter</kbd> to sync.
{#if $stateStore.autoSync}
It will be updated automatically.
{:else}
Press <i class="fas fa-sync" /> (Sync button) or <kbd>{cmdKey} + Enter</kbd> to sync.
{/if}
{/if}
</div>
{/if}
<div id="view" bind:this={view} class="p-2 h-full" class:error class:outOfSync>
<div id="view" bind:this={view} class="h-full p-2" class:error class:outOfSync>
<div id="container" bind:this={container} class="h-full overflow-auto" class:hide />
</div>
+1
View File
@@ -23,6 +23,7 @@ export interface State {
mermaid: string;
updateDiagram: boolean;
autoSync: boolean;
rough: boolean;
editorMode?: EditorMode;
panZoom?: boolean;
pan?: { x: number; y: number };
+49
View File
@@ -0,0 +1,49 @@
import debounce from 'lodash-es/debounce';
import { get } from 'svelte/store';
import { stateStore } from './state';
let shouldSync = true;
let updater: () => void;
let renderPromise: Promise<void> | undefined;
let resolveRenderPromise: (() => void) | undefined;
const renderDelay = 1000;
const slowRenderThreshold = 150;
const debouncedRender = debounce(() => {
shouldSync = true;
updater();
}, renderDelay);
export const recordRenderTime = (renderTimeMs: number, updaterFunction: () => void): void => {
resolveRenderPromise?.();
const { autoSync } = get(stateStore);
if (!autoSync) {
return;
}
updater = updaterFunction;
const isSlow = renderTimeMs > slowRenderThreshold;
if (!shouldSync) {
debouncedRender();
}
shouldSync = !isSlow;
};
export const shouldRefreshView = (): boolean => {
if (!renderPromise) {
renderPromise = new Promise((resolve) => {
resolveRenderPromise = () => {
renderPromise = undefined;
resolve();
};
});
}
if (!shouldSync) {
debouncedRender();
}
return shouldSync;
};
export const waitForRender = (): Promise<void> => {
return renderPromise ?? Promise.resolve();
};
+3 -6
View File
@@ -1,9 +1,6 @@
export const env = {
rendererUrl: import.meta.env.MERMAID_RENDERER_URL ?? 'https://mermaid.ink',
krokiRendererUrl: import.meta.env.MERMAID_KROKI_RENDERER_URL ?? 'https://kroki.io',
mermaidCDNUrl: import.meta.env.MERMAID_CDN_URL ?? 'https://unpkg.com/@mermaid-js',
mermaidBaseURL: import.meta.env.MERMAID_BASE_URL ?? 'http://localhost:9000',
useLocalMermaid: import.meta.env.MERMAID_LOCAL ?? false,
isDev: import.meta.env.DEV,
baseURL: import.meta.env.BASE_URL
};
analyticsUrl: import.meta.env.MERMAID_ANALYTICS_URL ?? '',
domain: import.meta.env.MERMAID_DOMAIN ?? 'mermaid.live'
} as const;
+8 -4
View File
@@ -2,9 +2,9 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-explicit-any */
import { addHistoryEntry } from '$lib/components/History/history';
import type { State } from '$lib/types';
import { defaultState } from '$lib/util/state';
import { addHistoryEntry } from '$lib/components/History/history';
import { fetchJSON, fetchText } from '$lib/util/util';
const codeFileName = 'code.mmd';
@@ -102,14 +102,18 @@ export const loadGistData = async (gistURL: string): Promise<State> => {
);
const gistHistory: GistData[] = [];
for (const entry of history) {
const data: GistData | undefined = await getGistData(entry.url).catch();
data && gistHistory.push(data);
try {
const data: GistData = await getGistData(entry.url);
gistHistory.push(data);
} catch (error) {
console.error(error);
}
}
if (gistHistory.length === 0) {
throw new Error('Invalid gist provided');
}
gistHistory.reverse();
const entry = gistHistory.slice(-1).pop();
const entry = gistHistory.at(-1);
if (!entry) {
throw new Error('Invalid gist provided');
}
+18 -1
View File
@@ -1,14 +1,31 @@
import mermaid from 'mermaid';
import type { MermaidConfig, RenderResult } from 'mermaid';
import zenuml from '@mermaid-js/mermaid-zenuml';
const init = mermaid.registerExternalDiagrams([zenuml]);
export const render = async (
config: MermaidConfig,
code: string,
id: string
): Promise<RenderResult> => {
await init;
// Should be able to call this multiple times without any issues.
mermaid.initialize(config);
return await mermaid.render(id, code);
try {
const result = await mermaid.render(id, code);
return result;
} catch {
const errorDiv = document.querySelector(`#d${id}`);
const svg = errorDiv?.innerHTML ?? '';
errorDiv?.remove();
return {
svg,
bindFunctions: undefined
};
}
};
export const parse = async (code: string): Promise<unknown> => {
+1 -1
View File
@@ -213,7 +213,7 @@ function getBrowserStorage(
disconnect();
}
},
getValue(key: string): any | null {
getValue(key: string): any {
const value = browserStorage.getItem(key);
return deserialize(value);
},
+7
View File
@@ -0,0 +1,7 @@
<a
href="https://www.mermaidchart.com/app/user/billing/checkout?coupon=HOLIDAYS2023"
target="_blank"
class="flex-grow tracking-wide">
Get AI, team collaboration, storage, and more with
<span class="font-bold underline">Mermaid Chart Pro. Start free trial today & get 25% off.</span>
</a>
+25
View File
@@ -0,0 +1,25 @@
<script lang="ts">
const taglines = {
announcement_bar_ai_diagramming: 'Try diagramming with ChatGPT at Mermaid Chart',
announcement_bar_visual_editor: "Try Mermaid's Visual Editor at Mermaid Chart",
announcement_bar_live_collaboration: 'Enjoy live collaboration with teammates at Mermaid Chart'
};
const taglineKeys = Object.keys(taglines);
const taglineKey = taglineKeys[Math.floor(Math.random() * taglineKeys.length)];
const tagline = taglines[taglineKey];
const url =
'https://www.mermaidchart.com/?' +
new URLSearchParams({
utm_source: 'mermaid_live_editor',
utm_medium: taglineKey,
utm_campaign: 'promo_2024'
}).toString();
</script>
<a
href={url}
target="_blank"
class="flex flex-grow justify-center gap-6 align-middle tracking-wide">
{tagline}
<button class="rounded bg-gray-800 p-1 px-4 text-sm font-light">Try it now</button>
</a>
+54
View File
@@ -0,0 +1,54 @@
import { writable, type Writable, get } from 'svelte/store';
import { persist, localStorage } from '../persist';
import Holiday2023 from './Holiday2023.svelte';
import Jan2024 from './Jan2024.svelte';
interface Promotion {
id: string;
startDate: Date;
endDate: Date;
component: ConstructorOfATypedSvelteComponent;
}
const promotions: Promotion[] = [
{
id: 'holiday-2023',
startDate: new Date('2023-11-27'),
endDate: new Date('2024-01-09'),
component: Holiday2023
},
{
id: 'jan-2024',
startDate: new Date('2024-01-10'),
endDate: new Date('2024-06-01'),
component: Jan2024
}
];
export const dismissPromotion = (id?: string): void => {
if (!id) {
return;
}
dismissedPromotionsStore.update((dismissedIDs: string[]) => {
dismissedIDs.push(id);
return dismissedIDs;
});
};
const dismissedPromotionsStore: Writable<string[]> = persist(
writable([]),
localStorage(),
'dismissedPromotions'
);
export const getActivePromotion = (): Promotion | undefined => {
const dismissedPromotions = get(dismissedPromotionsStore);
const now = new Date();
return promotions
.filter(
(p: Promotion) =>
p.startDate <= now && p.endDate >= now && !dismissedPromotions.includes(p.id)
)
.sort((a: Promotion, b: Promotion) => b.endDate.getTime() - a.endDate.getTime())
.pop();
};
+3 -3
View File
@@ -13,19 +13,19 @@ const verifySerde = (state: State, serde?: SerdeType): string => {
describe('Serde tests', () => {
it('should serialize and deserialize with default serde', () => {
expect(verifySerde(defaultState)).toMatchInlineSnapshot(
'"pako:eNpVjk2Lg0AMhv9KyGkL9Q94WGh1t5fCFurN6SFo7AztfDBGpKj_fcd62c0pvM_zhkzY-JYxx-7px0ZTFKhK5SDNoS50NL1Y6m-QZZ_ziQWsd_ya4fhx8tBrH4Jx993mH1cJium8agyijXssGyre_R_HM5T1mYL4cPtLqtHP8FWbi07n_xMdObW-647yjrKGIhQU3wru0XK0ZNr0_rQmCkWzZYV5WlvuaHiKQuWWpNIg_vpyDeYSB97jEFoSLg3dI9ktXH4B_cJWqw"'
`"pako:eNpVjs1qw0AMhF9F6NRC_AI-FBq7zSXQQnPz5iBs2bvE-8NaSwi2373r-NLqJM18M2jG1neMJfajv7eaosClVg7yvDeVjmYSS9MViuJtObGA9Y4fCxxfTh4m7UMwbnjd-eMGQTWfN4xBtHG3dbeqZ_7L8QJ1c6YgPlz_Ope7X-CjMd861_93dOSc-mx6KnsqWopQUXwieEDL0ZLp8vvzpigUzZYVlnntuKc0ikLl1oxSEv_zcC2WEhMfMPo0aMyd45SvFDoSrg0NkeyOrL_WfFuF"`
);
});
it('should serialize and deserialize with base64 serde', () => {
expect(verifySerde(defaultState, 'base64')).toMatchInlineSnapshot(
'"base64:eyJjb2RlIjoiZmxvd2NoYXJ0IFREXG4gICAgQVtDaHJpc3RtYXNdIC0tPnxHZXQgbW9uZXl8IEIoR28gc2hvcHBpbmcpXG4gICAgQiAtLT4gQ3tMZXQgbWUgdGhpbmt9XG4gICAgQyAtLT58T25lfCBEW0xhcHRvcF1cbiAgICBDIC0tPnxUd298IEVbaVBob25lXVxuICAgIEMgLS0-fFRocmVlfCBGW2ZhOmZhLWNhciBDYXJdXG4gICIsIm1lcm1haWQiOiJ7XG4gIFwidGhlbWVcIjogXCJkZWZhdWx0XCJcbn0iLCJhdXRvU3luYyI6dHJ1ZSwidXBkYXRlRGlhZ3JhbSI6dHJ1ZX0"'
`"base64:eyJjb2RlIjoiZmxvd2NoYXJ0IFREXG4gICAgQVtDaHJpc3RtYXNdIC0tPnxHZXQgbW9uZXl8IEIoR28gc2hvcHBpbmcpXG4gICAgQiAtLT4gQ3tMZXQgbWUgdGhpbmt9XG4gICAgQyAtLT58T25lfCBEW0xhcHRvcF1cbiAgICBDIC0tPnxUd298IEVbaVBob25lXVxuICAgIEMgLS0-fFRocmVlfCBGW2ZhOmZhLWNhciBDYXJdXG4gICIsIm1lcm1haWQiOiJ7XG4gIFwidGhlbWVcIjogXCJkZWZhdWx0XCJcbn0iLCJhdXRvU3luYyI6dHJ1ZSwicm91Z2giOmZhbHNlLCJ1cGRhdGVEaWFncmFtIjp0cnVlfQ"`
);
});
it('should serialize and deserialize with pako serde', () => {
expect(verifySerde(defaultState, 'pako')).toMatchInlineSnapshot(
'"pako:eNpVjk2Lg0AMhv9KyGkL9Q94WGh1t5fCFurN6SFo7AztfDBGpKj_fcd62c0pvM_zhkzY-JYxx-7px0ZTFKhK5SDNoS50NL1Y6m-QZZ_ziQWsd_ya4fhx8tBrH4Jx993mH1cJium8agyijXssGyre_R_HM5T1mYL4cPtLqtHP8FWbi07n_xMdObW-647yjrKGIhQU3wru0XK0ZNr0_rQmCkWzZYV5WlvuaHiKQuWWpNIg_vpyDeYSB97jEFoSLg3dI9ktXH4B_cJWqw"'
`"pako:eNpVjs1qw0AMhF9F6NRC_AI-FBq7zSXQQnPz5iBs2bvE-8NaSwi2373r-NLqJM18M2jG1neMJfajv7eaosClVg7yvDeVjmYSS9MViuJtObGA9Y4fCxxfTh4m7UMwbnjd-eMGQTWfN4xBtHG3dbeqZ_7L8QJ1c6YgPlz_Ope7X-CjMd861_93dOSc-mx6KnsqWopQUXwieEDL0ZLp8vvzpigUzZYVlnntuKc0ikLl1oxSEv_zcC2WEhMfMPo0aMyd45SvFDoSrg0NkeyOrL_WfFuF"`
);
});
+12 -27
View File
@@ -1,12 +1,11 @@
import { writable, get, type Readable, derived } from 'svelte/store';
import { persist, localStorage } from './persist';
import { saveStatistics, countLines } from './stats';
import { serializeState, deserializeState } from './serde';
import { cmdKey, errorDebug, formatJSON } from './util';
import { parse } from './mermaid';
import type { ErrorHash, MarkerData, State, ValidatedState } from '$lib/types';
import { debounce } from 'lodash-es';
import type { MermaidConfig } from 'mermaid';
import { derived, get, writable, type Readable } from 'svelte/store';
import { parse } from './mermaid';
import { localStorage, persist } from './persist';
import { deserializeState, serializeState } from './serde';
import { errorDebug, formatJSON } from './util';
export const defaultState: State = {
code: `flowchart TD
@@ -20,6 +19,7 @@ export const defaultState: State = {
theme: 'default'
}),
autoSync: true,
rough: false,
updateDiagram: true
};
@@ -134,7 +134,6 @@ export const updateCodeStore = (newState: Partial<State>): void => {
});
};
let prompted = false;
export const updateCode = (
code: string,
{
@@ -142,21 +141,7 @@ export const updateCode = (
resetPanZoom = false
}: { updateDiagram?: boolean; resetPanZoom?: boolean } = {}
): void => {
// console.log('updateCode', code);
const lines = countLines(code);
saveStatistics(code);
errorDebug();
if (lines > 50 && !prompted && get(stateStore).autoSync) {
const turnOff = confirm(
`Long diagram detected. Turn off Auto Sync? Use ${cmdKey} + Enter or click the sync logo to manually sync.`
);
prompted = true;
if (turnOff) {
updateCodeStore({
autoSync: false
});
}
}
inputStateStore.update((state) => {
if (resetPanZoom) {
@@ -185,13 +170,13 @@ export const toggleDarkTheme = (dark: boolean): void => {
});
};
let urlDebounce: number;
export const initURLSubscription = (): void => {
const updateHash = debounce((hash) => {
history.replaceState(undefined, '', `#${hash}`);
}, 250);
stateStore.subscribe(({ serialized }) => {
clearTimeout(urlDebounce);
urlDebounce = window.setTimeout(() => {
history.replaceState(undefined, '', `#${serialized}`);
}, 250);
updateHash(serialized);
});
};
+66 -44
View File
@@ -1,24 +1,17 @@
import { browser } from '$app/environment';
import type { AnalyticsInstance } from 'analytics';
export let analytics: AnalyticsInstance | undefined;
import type PlausibleInstance from 'plausible-tracker';
import { env } from './env';
export let plausible: ReturnType<typeof PlausibleInstance> | undefined;
export const initAnalytics = async (): Promise<void> => {
if (browser && !analytics) {
if (browser && !plausible) {
try {
const [{ Analytics }, { default: plausible }] = await Promise.all([
import('analytics'),
import('analytics-plugin-plausible')
]);
analytics = Analytics({
app: 'mermaid-live-editor',
plugins: [
plausible({
domain: 'mermaid.live',
hashMode: false,
// All tracked stats are public and available at https://p.mermaid.live/mermaid.live
apiHost: 'https://p.mermaid.live'
})
]
const { default: Plausible } = await import('plausible-tracker');
plausible = Plausible({
domain: env.domain,
hashMode: false,
// All tracked stats are public and available at https://p.mermaid.live/mermaid.live
apiHost: env.analyticsUrl
});
} catch (error) {
console.log(error);
@@ -42,7 +35,7 @@ export const detectType = (text: string): string | undefined => {
'mindmap'
];
const firstLine = text
.replace(/^\s*%%.*\n/g, '\n')
.replaceAll(/^\s*%%.*\n/g, '\n')
.trimStart()
.split(' ')[0]
.toLowerCase();
@@ -54,33 +47,53 @@ export const countLines = (code: string): number => {
return (code.match(/\n/g)?.length ?? 0) + 1;
};
export const saveStatistics = (graph: string): void => {
const graphType = detectType(graph);
export const saveStatistics = ({
code,
renderTime,
isRough
}: {
code: string;
renderTime: number;
isRough: boolean;
}): void => {
const graphType = detectType(code);
if (!graphType) {
return;
}
const length = countLines(graph);
const lengthBucket =
length < 10
? '0-10'
: length < 25
const length = countLines(code);
const lengthBucket = getBucket(length);
const renderTimeMsBucket = getBucket(renderTime);
logEvent('render', { graphType, length, lengthBucket, renderTimeMsBucket, isRough });
};
const getBucket = (length: number): string => {
return length < 10
? '0-10'
: length < 25
? '10-25'
: length < 50
? '25-50'
: length < 100
? '50-100'
: length < 200
? '100-200'
: length < 500
? '200-500'
: length < 700
? '500-700'
: length < 1000
? '700-1000'
: length < 1500
? '1000-1500'
: '1500+';
logEvent('render', { graphType, length, lengthBucket });
? '25-50'
: length < 100
? '50-100'
: length < 200
? '100-200'
: length < 500
? '200-500'
: length < 700
? '500-700'
: length < 1000
? '700-1000'
: length < 1500
? '1000-1500'
: length < 2500
? '1500-2500'
: length < 4500
? '2500-4500'
: length < 7000
? '4500-7000'
: length < 10_000
? '7000-10000'
: '10000+';
};
const minutesToMilliSeconds = (minutes: number): number => {
@@ -99,20 +112,29 @@ const delaysPerEvent = {
renderDiagram: defaultDelay,
history: defaultDelay,
migration: defaultDelay,
themeChange: defaultDelay
themeChange: defaultDelay,
bannerClick: defaultDelay,
version: defaultDelay
};
export type AnalyticsEvent = keyof typeof delaysPerEvent;
const timeouts: Map<string, number> = new Map<string, number>();
// manual debounce to reduce the number of events sent to analytics
export const logEvent = (name: AnalyticsEvent, data?: unknown): void => {
if (!analytics) {
export const logEvent = (
name: AnalyticsEvent,
data?: Record<string, string | number | boolean>
): void => {
if (!plausible) {
return;
}
const key = data ? JSON.stringify({ name, data }) : name;
if (timeouts.has(key)) {
clearTimeout(timeouts.get(key));
} else {
void analytics.track(name, data);
plausible.trackEvent(
name,
{ props: data },
{ url: window.location.origin + window.location.pathname }
);
}
timeouts.set(
key,
+3 -3
View File
@@ -1,5 +1,5 @@
import { initURLSubscription, loadState, updateCodeStore } from './state';
import { analytics, initAnalytics } from './stats';
import { plausible, initAnalytics } from './stats';
import { loadDataFromUrl } from './fileLoaders/loader';
import { initLoading } from './loading';
import { applyMigrations } from './migrations';
@@ -21,14 +21,14 @@ export const initHandler = async (): Promise<void> => {
syncDiagram();
initURLSubscription();
await initAnalytics();
await analytics?.page();
plausible?.trackPageview({ url: window.location.origin + window.location.pathname });
};
export const isMac = navigator.platform.toUpperCase().includes('MAC');
export const cmdKey = isMac ? 'Cmd' : 'Ctrl';
let count = 0;
export const errorDebug = (limit = 100) => {
export const errorDebug = (limit = 1000) => {
count += 1;
if (count > limit) {
console.log(count, limit);
+3 -3
View File
@@ -34,7 +34,7 @@
themeStore.subscribe(({ theme, isDark }) => {
if (theme) {
document.getElementsByTagName('html')[0].setAttribute('data-theme', theme);
document.querySelectorAll('html')[0].dataset.theme = theme;
toggleDarkTheme(isDark);
}
});
@@ -47,8 +47,8 @@
{#if $loadingStateStore.loading}
<div
class="w-screen h-screen z-50 absolute left-0 top-0 bg-gray-600 opacity-50 flex align-middle justify-center">
<div class="text-indigo-100 text-4xl font-bold my-auto">
class="absolute left-0 top-0 z-50 flex h-screen w-screen justify-center bg-gray-600 align-middle opacity-50">
<div class="my-auto text-4xl font-bold text-indigo-100">
<div class="loader mx-auto" />
<div>{$loadingStateStore.message}</div>
</div>
+83 -39
View File
@@ -1,57 +1,86 @@
<script lang="ts">
import { dev } from '$app/environment';
import { base } from '$app/paths';
import Actions from '$lib/components/Actions.svelte';
import Card from '$lib/components/Card/Card.svelte';
import Editor from '$lib/components/Editor.svelte';
import History from '$lib/components/History/History.svelte';
import Navbar from '$lib/components/Navbar.svelte';
import Preset from '$lib/components/Preset.svelte';
import Actions from '$lib/components/Actions.svelte';
import View from '$lib/components/View.svelte';
import Card from '$lib/components/Card/Card.svelte';
import History from '$lib/components/History/History.svelte';
import type { DocumentationConfig, EditorMode, Tab, ValidatedState } from '$lib/types';
import { inputStateStore, stateStore, updateCodeStore } from '$lib/util/state';
import { cmdKey, initHandler, syncDiagram } from '$lib/util/util';
import { onMount } from 'svelte';
import { base } from '$app/paths';
import { dev } from '$app/environment';
import type { Tab, DocumentationConfig, EditorMode, ValidatedState } from '$lib/types';
const MCBaseURL = dev ? 'http://localhost:5174' : 'https://mermaidchart.com';
const docURLBase = 'https://mermaid-js.github.io/mermaid';
const docURLBase = 'https://mermaid.js.org';
const docMap: DocumentationConfig = {
graph: {
code: '/#/flowchart',
config: '/#/flowchart?id=configuration'
code: '/syntax/.html',
config: '/syntax/.html#configuration'
},
flowchart: {
code: '/#/flowchart',
config: '/#/flowchart?id=configuration'
code: '/syntax/flowchart.html',
config: '/syntax/flowchart.html#configuration'
},
sequenceDiagram: {
code: '/#/sequenceDiagram',
config: '/#/sequenceDiagram?id=configuration'
code: '/syntax/sequenceDiagram.html',
config: '/syntax/sequenceDiagram.html#configuration'
},
classDiagram: {
code: '/#/classDiagram',
config: '/#/classDiagram?id=configuration'
code: '/syntax/classDiagram.html',
config: '/syntax/classDiagram.html#configuration'
},
'stateDiagram-v2': {
code: '/#/stateDiagram'
code: '/syntax/stateDiagram.html'
},
gantt: {
code: '/#/gantt',
config: '/#/gantt?id=configuration'
code: '/syntax/gantt.html',
config: '/syntax/gantt.html#configuration'
},
pie: {
code: '/#/pie'
code: '/syntax/pie.html',
config: '/syntax/pie.html#configuration'
},
erDiagram: {
code: '/#/entityRelationshipDiagram',
config: '/#/entityRelationshipDiagram?id=styling'
code: '/syntax/entityRelationshipDiagram.html',
config: '/syntax/entityRelationshipDiagram.html#styling'
},
journey: {
code: '/#/user-journey'
code: '/syntax/userJourney.html'
},
gitGraph: {
code: '/#/gitgraph',
config: '/#/gitgraph?id=gitgraph-specific-configuration-options'
code: '/syntax/gitgraph.html',
config: '/syntax/gitgraph.html#gitgraph-specific-configuration-options'
},
quadrantChart: {
code: '/syntax/quadrantChart.html',
config: '/syntax/quadrantChart.html#chart-configurations'
},
requirementDiagram: {
code: '/syntax/requirementDiagram.html'
},
C4Context: {
code: '/syntax/c4.html'
},
mindmap: {
code: '/syntax/mindmap.html'
},
timeline: {
code: '/syntax/timeline.html',
config: '/syntax/timeline.html#themes'
},
zenuml: {
code: '/syntax/zenuml.html'
},
'sankey-beta': {
code: '/syntax/sankey.html',
config: '/syntax/sankey.html#configuration'
},
'xychart-beta': {
code: '/syntax/xyChart.html',
config: '/syntax/xyChart.html#chart-configurations'
}
};
let docURL = docURLBase;
@@ -59,7 +88,7 @@
let docKey = '';
stateStore.subscribe(({ code, editorMode }: ValidatedState) => {
activeTabID = editorMode;
const codeTypeMatch = /([\S]+)[\s\n]/.exec(code);
const codeTypeMatch = /(\S+)\s/.exec(code);
if (codeTypeMatch && codeTypeMatch.length > 1) {
docKey = codeTypeMatch[1];
const docConfig = docMap[docKey] ?? { code: '' };
@@ -87,14 +116,14 @@
onMount(async () => {
await initHandler();
const resizer = document.getElementById('resizeHandler');
const element = document.getElementById('editorPane');
const resizer = document.querySelector<HTMLElement>('#resizeHandler');
const element = document.querySelector<HTMLElement>('#editorPane');
if (!resizer || !element) {
console.debug('Failed to find resize handler or editor pane', { resizer, element });
return;
}
const resize = (e: { pageX: number }) => {
const newWidth = e.pageX - element.getBoundingClientRect().left;
const resize = ({ pageX }: { pageX: number }) => {
const newWidth = pageX - element.getBoundingClientRect().left;
if (newWidth > 50) {
element.style.width = `${newWidth}px`;
}
@@ -103,22 +132,22 @@
const stopResize = () => {
window.removeEventListener('mousemove', resize);
};
resizer.addEventListener('mousedown', (e) => {
e.preventDefault();
resizer.addEventListener('mousedown', (event) => {
event.preventDefault();
window.addEventListener('mousemove', resize);
window.addEventListener('mouseup', stopResize);
});
});
</script>
<div class="h-full flex flex-col overflow-hidden">
<div class="flex h-full flex-col overflow-hidden">
<Navbar />
<div class="flex-1 flex overflow-hidden">
<div class="hidden md:flex flex-col" id="editorPane" style="width: 40%">
<div class="flex flex-1 overflow-hidden">
<div class="hidden flex-col md:flex" id="editorPane" style="width: 40%">
<Card on:select={tabSelectHandler} {tabs} isCloseable={false} {activeTabID} title="Mermaid">
<div slot="actions" class="flex flex-row items-center">
<div class="form-control flex-row items-center">
<label class="cursor-pointer label" for="autoSync">
<label class="label cursor-pointer" for="autoSync">
<span> Auto sync</span>
<input
type="checkbox"
@@ -155,15 +184,30 @@
</div>
</div>
<div id="resizeHandler" class="hidden md:block" />
<div class="flex-1 flex flex-col overflow-hidden">
<div class="flex flex-1 flex-col overflow-hidden">
<Card title="Diagram" isCloseable={false}>
<div slot="actions" class="flex flex-row items-center gap-2">
<label class="cursor-pointer label py-0" for="panZoom">
<label
class="label flex cursor-pointer gap-1 py-0"
title="Rough mode is in beta. Features like clickable nodes, Pan & Zoom, will be disabled."
for="rough">
<span>Rough</span>
<input
type="checkbox"
class="toggle {$stateStore.rough ? 'btn-secondary' : 'toggle-primary'}"
id="rough"
bind:checked={$inputStateStore.rough} />
</label>
<label
class="label flex cursor-pointer gap-1 py-0"
title={$stateStore.rough ? 'Pan & Zoom is disabled in rough mode.' : ''}
for="panZoom">
<span>Pan & Zoom</span>
<input
type="checkbox"
class="toggle {$stateStore.panZoom ? 'btn-secondary' : 'toggle-primary'}"
id="panZoom"
disabled={$stateStore.rough}
bind:checked={$inputStateStore.panZoom} />
</label>
<a
@@ -176,7 +220,7 @@
target="_blank"
class="btn btn-secondary btn-xs gap-1 bg-[#FF3570]"
title="Save diagram in Mermaid Chart"
><img src="/mermaidchart-logo.svg" class="w-5 h-5" alt="Mermaid chart logo" />Save to
><img src="./mermaidchart-logo.svg" class="h-5 w-5" alt="Mermaid chart logo" />Save to
Mermaid Chart</a>
</div>
@@ -184,7 +228,7 @@
<View />
</div>
</Card>
<div class="md:hidden rounded shadow p-2 mx-2">
<div class="mx-2 rounded p-2 shadow md:hidden">
Code editing not supported on mobile. Please use a desktop browser.
</div>
</div>
+2 -4
View File
@@ -1,7 +1,5 @@
import matchers from '@testing-library/jest-dom/matchers';
import { expect, beforeAll, vi } from 'vitest';
expect.extend(matchers);
import 'vitest-dom/extend-expect';
import { beforeAll, vi } from 'vitest';
// TODO: Remove once https://github.com/sveltejs/kit/issues/6259 is closed.
beforeAll(() => {
+2293 -1513
View File
File diff suppressed because it is too large Load Diff