Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f9b92d6026 | ||
|
|
952791cb5f | ||
|
|
d4110403e6 | ||
|
|
533970d83f | ||
|
|
bcd6bb5f11 | ||
|
|
d40d476ea1 | ||
|
|
90bc10577e | ||
|
|
6d0919fcda | ||
|
|
5818db68f7 | ||
|
|
8a0a2c83eb | ||
|
|
2c516f395e | ||
|
|
7738e3ee48 | ||
|
|
f4fd865c81 | ||
|
|
8bbfa59a32 | ||
|
|
c3ed8ae636 | ||
|
|
c0215f0e04 | ||
|
|
644faf8700 | ||
|
|
17a1ce6548 | ||
|
|
a5cf1a1cd6 | ||
|
|
23ffef7843 | ||
|
|
ec23d055cc | ||
|
|
3402c86bf2 | ||
|
|
5a307c3547 | ||
|
|
8c46f9a892 | ||
|
|
48f5853d03 | ||
|
|
8b39836353 | ||
|
|
3c6b14cee3 | ||
|
|
015e112e6b | ||
|
|
cb6bf6570d | ||
|
|
8ee71a6f08 | ||
|
|
7ad1c2098c | ||
|
|
2c0d7db7cc | ||
|
|
5ce24780c0 | ||
|
|
ad1cec76c7 | ||
|
|
bdd6ca2c3d | ||
|
|
9f05ec4460 | ||
|
|
6701dd2dd7 | ||
|
|
5bcb495569 | ||
|
|
4bdb5a0750 | ||
|
|
51c9488d0e | ||
|
|
65a1fa72a0 | ||
|
|
abc63488a1 | ||
|
|
a49819e120 | ||
|
|
980706b487 | ||
|
|
7fc789ab0f | ||
|
|
f245180882 | ||
|
|
bb7b4d3f78 | ||
|
|
d617524172 | ||
|
|
834db65ecd | ||
|
|
4238f1285c | ||
|
|
bba0ae4ba1 | ||
|
|
f612a5c703 | ||
|
|
0b6dbf6857 | ||
|
|
1358185692 | ||
|
|
b8d4ada693 | ||
|
|
b34942355f | ||
|
|
c8e217d0c9 | ||
|
|
536db58698 | ||
|
|
d6d987e962 | ||
|
|
4ae314c5c0 | ||
|
|
6868b0d761 | ||
|
|
0dd010336a | ||
|
|
d7e7121666 | ||
|
|
bfa35ca86e | ||
|
|
d7a6ac2aa7 | ||
|
|
3f843f29bf | ||
|
|
bcb8031c8f | ||
|
|
b60718a18e | ||
|
|
db5ce6b74b | ||
|
|
a1a085e526 | ||
|
|
6675267d45 | ||
|
|
00bdd4500e | ||
|
|
7a04384b7d | ||
|
|
ea0e8b9883 | ||
|
|
7ef1f1325b | ||
|
|
3b5af96ab0 | ||
|
|
3a4c437536 | ||
|
|
dcaa313c0b | ||
|
|
2c31be0b02 | ||
|
|
0f63e777ae | ||
|
|
64a2fd8843 | ||
|
|
d40c8ee085 | ||
|
|
61bafa4836 | ||
|
|
eeadbfdaa2 | ||
|
|
32f3832565 | ||
|
|
8ab28182d7 | ||
|
|
81137e058c | ||
|
|
c9fdba6cd3 | ||
|
|
9318bde5cf | ||
|
|
33fd537826 | ||
|
|
5af4466e6f | ||
|
|
4aa4641c6a | ||
|
|
b001e6d2a6 | ||
|
|
7812d9c241 | ||
|
|
e7e4d7cf88 | ||
|
|
863c3ea717 | ||
|
|
86b25a272f | ||
|
|
a7428ed0e5 | ||
|
|
27f56d309a | ||
|
|
c5348e9a81 | ||
|
|
7983b5d94c | ||
|
|
ff48d906ae | ||
|
|
ae2880c8a2 | ||
|
|
ca07ed764d | ||
|
|
76a70be939 | ||
|
|
56cd1b5a78 | ||
|
|
3b63e9a9aa | ||
|
|
b73afb400b | ||
|
|
a1b01cae2c | ||
|
|
64b213aad9 | ||
|
|
a67481a4e7 | ||
|
|
b7f8b8aee3 | ||
|
|
b4814d7b13 | ||
|
|
45b1c9f32c | ||
|
|
660e4c6bf1 | ||
|
|
041ec91c6b | ||
|
|
c5de0dca9f | ||
|
|
76aef33868 | ||
|
|
f50d202fdf | ||
|
|
9403e617c1 | ||
|
|
095767ad21 | ||
|
|
0493b744e7 | ||
|
|
0d15a2e487 | ||
|
|
01efb70cf3 | ||
|
|
57f3288de3 | ||
|
|
eaa84ee5d6 | ||
|
|
f1f028737a | ||
|
|
4428038b66 | ||
|
|
a230130db5 | ||
|
|
f3681b582d | ||
|
|
dec0c58092 | ||
|
|
0578294579 | ||
|
|
fc47fcf75b | ||
|
|
bceca50b0e | ||
|
|
d062dd7132 | ||
|
|
57bb0fa248 | ||
|
|
bcb8a948a5 | ||
|
|
81589e5d98 | ||
|
|
6becf69630 | ||
|
|
1ee1701530 | ||
|
|
0828d4393e | ||
|
|
1777df6ab4 | ||
|
|
e9a982d813 | ||
|
|
8c0aaa94a4 | ||
|
|
bf8afc0c13 | ||
|
|
9c315b2d0d | ||
|
|
d0a0c0a82d | ||
|
|
6c44a7218b | ||
|
|
01162adbd1 | ||
|
|
8e304d2568 | ||
|
|
1af139ce23 | ||
|
|
18fad37944 | ||
|
|
0dc04419c1 | ||
|
|
1dfa32c6e5 | ||
|
|
c3b055b235 | ||
|
|
63e45c9120 | ||
|
|
5d3e7fbbf0 | ||
|
|
f9e6635d53 | ||
|
|
61ce370074 | ||
|
|
a6209977b1 | ||
|
|
7c693363ae | ||
|
|
23091491ba | ||
|
|
540df1f96f | ||
|
|
0d40be232f | ||
|
|
df2e097007 | ||
|
|
be83fa2e08 | ||
|
|
19c0ddca94 | ||
|
|
3533564c00 | ||
|
|
4585fd2994 | ||
|
|
425bd40805 | ||
|
|
411f7e9d70 | ||
|
|
79850eccef | ||
|
|
7792d26d53 | ||
|
|
3a8bc1d5ea | ||
|
|
7309aa6c42 | ||
|
|
d8d994581f | ||
|
|
b3537d5dbe | ||
|
|
fdcb1b7f1b | ||
|
|
a2b212f6e4 | ||
|
|
282d039076 | ||
|
|
030df21e4d | ||
|
|
cb2806b572 | ||
|
|
f287a643ce | ||
|
|
cd8894a27b | ||
|
|
13d1a6099a | ||
|
|
0d7ea7f4f3 | ||
|
|
39cdaff57b | ||
|
|
31ae188af3 | ||
|
|
8cde5eb23e | ||
|
|
7400507689 | ||
|
|
3bd1ea8c2e | ||
|
|
ef9395fd0e | ||
|
|
f5503f88a7 | ||
|
|
74d47a38b1 | ||
|
|
f2606d7341 | ||
|
|
1cc3478512 | ||
|
|
5e6231e3f9 | ||
|
|
775c5765a3 | ||
|
|
f05ccf497d | ||
|
|
5472528ce0 | ||
|
|
2b358ccd80 | ||
|
|
39b2ebde32 | ||
|
|
e8fad2b91c | ||
|
|
f337d16caf | ||
|
|
5773558e84 | ||
|
|
8fe4b7f536 | ||
|
|
765ed2f012 | ||
|
|
63c23b9e0b | ||
|
|
0288392a61 | ||
|
|
21072d343c | ||
|
|
9801dd606d | ||
|
|
b762d1a44a | ||
|
|
1324242337 | ||
|
|
af64307067 | ||
|
|
be6931d0ca | ||
|
|
a907674539 | ||
|
|
fbe2f127b8 | ||
|
|
81a5181877 | ||
|
|
3848f9d618 | ||
|
|
4f52a37e1d | ||
|
|
6c8c0f20c8 | ||
|
|
570d5c79a8 | ||
|
|
5548625536 | ||
|
|
bb2f5b46a8 | ||
|
|
559feacae0 | ||
|
|
ecc514816c | ||
|
|
8d2d6a83ae | ||
|
|
9ca183e654 | ||
|
|
f65dba35c4 | ||
|
|
65a1e067ab | ||
|
|
14bfbb1607 | ||
|
|
49a812c43f | ||
|
|
45010e17d2 | ||
|
|
60f553f9eb | ||
|
|
cdf9ccd3c9 | ||
|
|
566c696be8 | ||
|
|
abde98bd5f | ||
|
|
5c9afbc1ed | ||
|
|
cec1dc4df9 | ||
|
|
1096d10cb4 | ||
|
|
d5ecf60c84 | ||
|
|
4d48a14100 | ||
|
|
d751945e94 | ||
|
|
aa74eaff95 | ||
|
|
35bf065120 | ||
|
|
0604c27b56 | ||
|
|
956d5d0684 | ||
|
|
4cba8bdb72 | ||
|
|
09f4b4f35e | ||
|
|
c751fc3c01 | ||
|
|
65ab28d03b | ||
|
|
f4d6ca8c92 | ||
|
|
86953aadc7 | ||
|
|
876b419c04 | ||
|
|
8bb611c50c | ||
|
|
13286ff4d1 | ||
|
|
88f9c3b6ea | ||
|
|
29ffa1a0a4 | ||
|
|
103f02bb90 | ||
|
|
a6db07a4c1 | ||
|
|
8d8ae6a366 | ||
|
|
e81e09ab23 | ||
|
|
bf8160e31e | ||
|
|
5961c7d451 | ||
|
|
cc3f4fabc2 | ||
|
|
aed37c19c7 | ||
|
|
43bac28b30 | ||
|
|
ed2057312a | ||
|
|
fdff260f7f | ||
|
|
f5878feaa5 | ||
|
|
aef1afe3f4 | ||
|
|
f2cf3e8111 | ||
|
|
32351ab24e | ||
|
|
bd3b39a2c5 | ||
|
|
e286fb2fb7 | ||
|
|
3097161aa8 | ||
|
|
b222e37457 | ||
|
|
0d5240dfef | ||
|
|
09c3fbb13c | ||
|
|
dd66ed095b | ||
|
|
d7308f019b | ||
|
|
634403dac7 | ||
|
|
3bfc932ff7 | ||
|
|
16e22b52a2 | ||
|
|
7773252302 | ||
|
|
d59859abc6 | ||
|
|
2702f7b045 | ||
|
|
d392347bc0 | ||
|
|
38aecc2a3e | ||
|
|
a549c4021d | ||
|
|
d4d7fd351b | ||
|
|
d5548805d0 | ||
|
|
708effa0b0 | ||
|
|
afeb08fa39 | ||
|
|
3df6b6d3f6 | ||
|
|
298ca8cc6a | ||
|
|
6c06c72614 | ||
|
|
b431571662 | ||
|
|
4d6a2478ab | ||
|
|
1064f3ce81 | ||
|
|
8db133e240 | ||
|
|
4cba7c86d5 | ||
|
|
6622cb3968 | ||
|
|
84b0db4dbc | ||
|
|
4c4427a4b9 | ||
|
|
c6d0e3d4b3 | ||
|
|
c4796f7dd7 | ||
|
|
1e787a5c16 | ||
|
|
0bc637f606 | ||
|
|
bb70e37492 | ||
|
|
e09d2f93f8 | ||
|
|
66061ef8e0 | ||
|
|
e13e09de25 | ||
|
|
3931ebbfc2 | ||
|
|
893144d16f | ||
|
|
e44fad0e85 | ||
|
|
7055b6e8ee | ||
|
|
44ef76f086 | ||
|
|
411bbcf5e5 | ||
|
|
025c524012 | ||
|
|
446e1c49c7 | ||
|
|
742cef3870 | ||
|
|
8b681530cd | ||
|
|
8c3951a5e1 | ||
|
|
cdbf3f150e | ||
|
|
1bd5b00a66 | ||
|
|
6fc5a8f696 | ||
|
|
2ae15aa74e | ||
|
|
998cc45b01 | ||
|
|
a9dcc95f8c | ||
|
|
0b7f1a8e4e | ||
|
|
8ba1651135 | ||
|
|
12d997fc61 | ||
|
|
ba6db70e96 | ||
|
|
77cf436225 | ||
|
|
6708615c48 | ||
|
|
28181f7872 |
+12
-3
@@ -8,7 +8,16 @@ module.exports = {
|
||||
'prettier'
|
||||
],
|
||||
plugins: ['svelte3', 'tailwindcss', '@typescript-eslint'],
|
||||
ignorePatterns: ['docs/*', '*.cjs', 'snapshots.js', 'svelte.config.js', 'package.json'],
|
||||
ignorePatterns: [
|
||||
'docs/*',
|
||||
'*.cjs',
|
||||
'*.md',
|
||||
'snapshots.js',
|
||||
'svelte.config.js',
|
||||
'renovate.json',
|
||||
'package.json',
|
||||
'tsconfig.json'
|
||||
],
|
||||
overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }],
|
||||
settings: {
|
||||
'svelte3/typescript': () => require('typescript')
|
||||
@@ -32,7 +41,7 @@ module.exports = {
|
||||
'ts-ignore': 'allow-with-description'
|
||||
}
|
||||
],
|
||||
'@typescript-eslint/no-unsafe-member-access': 'warn',
|
||||
'@typescript-eslint/no-unsafe-assignment': 'warn'
|
||||
'@typescript-eslint/no-unsafe-member-access': 'off',
|
||||
'@typescript-eslint/no-unsafe-assignment': 'off'
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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/develop/CONTRIBUTING.md)
|
||||
- [ ] :book: have read the [contribution guidelines](https://github.com/mermaid-js/mermaid/blob/master/CONTRIBUTING.md)
|
||||
- [ ] :computer: have added unit/e2e tests (if appropriate)
|
||||
- [ ] :bookmark: targeted `master` branch
|
||||
- [ ] :bookmark: targeted `develop` branch
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
name: Cypress Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
|
||||
jobs:
|
||||
cypress-run:
|
||||
@@ -26,6 +26,11 @@ jobs:
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node_modules-build-
|
||||
|
||||
- name: Lint
|
||||
run: |
|
||||
yarn install
|
||||
yarn run lint
|
||||
|
||||
# Install NPM dependencies, cache them correctly
|
||||
# and run all Cypress tests
|
||||
- name: Cypress run
|
||||
@@ -34,8 +39,7 @@ jobs:
|
||||
build: yarn build
|
||||
start: yarn preview
|
||||
wait-on: 'http://localhost:3000'
|
||||
wait-on-timeout: 120
|
||||
# record: true
|
||||
record: true
|
||||
headless: true
|
||||
env:
|
||||
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
|
||||
|
||||
@@ -17,41 +17,35 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Get yarn cache directory path
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
|
||||
- uses: actions/cache@v2
|
||||
id: yarn-and-build-cache
|
||||
id: yarn-cache
|
||||
with:
|
||||
path: |
|
||||
node_modules
|
||||
key: ${{ runner.os }}-node_modules-build-deploy-${{ hashFiles('**/yarn.lock') }}
|
||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node_modules-build-deploy-
|
||||
|
||||
- name: Setup Beta
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
run: |
|
||||
export BETA=true
|
||||
rm -rf docs/beta/
|
||||
|
||||
- name: Cleanup build
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
run: |
|
||||
rm -rf docs/_app/
|
||||
${{ runner.os }}-yarn-
|
||||
|
||||
- name: Build & Deploy
|
||||
run: |
|
||||
npm i -g yarn
|
||||
export DEPLOY=true
|
||||
echo "$GITHUB_EVENT_NAME"
|
||||
[ "$GITHUB_EVENT_NAME" == "pull_request" ] && export BETA=true && rm -rf docs/beta/
|
||||
[ "$GITHUB_EVENT_NAME" != "pull_request" ] && rm -rf docs/_app/
|
||||
yarn install
|
||||
# yarn run lint
|
||||
yarn run lint
|
||||
version=$(yarn version --patch --no-git-tag-version | grep "New version" | cut -d':' -f 2)
|
||||
yarn build
|
||||
cd bin
|
||||
./fix-path
|
||||
cd ..
|
||||
git config user.name github-actions
|
||||
git config user.email github-actions@github.com
|
||||
git pull origin gh-pages
|
||||
git add .
|
||||
git commit -nm "Release $version"
|
||||
git push origin gh-pages
|
||||
|
||||
- name: Deploy
|
||||
uses: peaceiris/actions-gh-pages@v3
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_dir: ./docs
|
||||
keep_files: true
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
name: Docker
|
||||
|
||||
on:
|
||||
push:
|
||||
# Publish `master` as Docker `latest` image.
|
||||
branches:
|
||||
- master
|
||||
|
||||
# Publish `v1.2.3` tags as releases.
|
||||
tags:
|
||||
- v*
|
||||
|
||||
# Run tests for all PRs to master and develop.
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
|
||||
env:
|
||||
IMAGE_NAME: mermaid-live-editor
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Run tests
|
||||
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@v2
|
||||
|
||||
- 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
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
npm run pre-commit
|
||||
yarn pre-commit
|
||||
|
||||
+1
-2
@@ -6,8 +6,7 @@
|
||||
# Stop : press ctrl + c
|
||||
# or
|
||||
# docker stop mermaid-live-editor
|
||||
|
||||
FROM node:14.16.0-alpine3.13 as mermaid-live-editor-builder
|
||||
FROM node:14.17.0 as mermaid-live-editor-builder
|
||||
COPY --chown=node:node . /home
|
||||
WORKDIR /home
|
||||
RUN yarn install
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE)
|
||||
[](https://dashboard.cypress.io/projects/2ckppp/runs) [](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE)
|
||||
|
||||
# Contributors are welcome
|
||||
# Contributors are welcome!
|
||||
|
||||
If you want to speed up the progress for mermaid-live-editor, join the slack channel and contact knsv.
|
||||
|
||||
@@ -19,30 +19,24 @@ Edit, preview and share mermaid charts/diagrams.
|
||||
|
||||
You can try out a live version [here](https://mermaid-js.github.io/mermaid-live-editor/).
|
||||
|
||||
## Docker
|
||||
|
||||
```bash
|
||||
docker run --publish 8000:80 ghcr.io/mermaid-js/mermaid-live-editor
|
||||
```
|
||||
|
||||
Then open http://localhost:8000
|
||||
|
||||
## Setup
|
||||
|
||||
[Volta](https://volta.sh) is used for managing node and yarn versions.
|
||||
|
||||
This project is set up using [Yarn](https://classic.yarnpkg.com/en/docs/getting-started). :
|
||||
This project is set up using [Yarn](https://classic.yarnpkg.com/en/docs/getting-started):
|
||||
|
||||
```
|
||||
yarn install
|
||||
```
|
||||
|
||||
or in develop branch to use the beta version of mermaid use
|
||||
|
||||
```
|
||||
yarn install --update-checksums
|
||||
```
|
||||
|
||||
This together with a .npmrc file:
|
||||
|
||||
```
|
||||
registry=https://registry.npmjs.com/
|
||||
@mermaid-js:registry=https://npm.pkg.github.com
|
||||
//npm.pkg.github.com/:_authToken="XXXXXXXXX"
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
```
|
||||
@@ -53,6 +47,6 @@ This app is created with Svelte Kit.
|
||||
|
||||
## Release
|
||||
|
||||
```
|
||||
yarn release
|
||||
```
|
||||
When a PR is created targeting master, it will be built and deployed as a beta in http://mermaid-js.github.io/mermaid-live-editor/beta
|
||||
|
||||
Once the PR is merged, it will automatically be released.
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
describe('Check actions', () => {
|
||||
// eslint-disable-next-line mocha/no-hooks-for-single-case
|
||||
beforeEach(() => {
|
||||
cy.clearLocalStorage();
|
||||
cy.visit('/edit');
|
||||
cy.contains('Actions').click();
|
||||
});
|
||||
it('should update markdown code', () => {
|
||||
cy.get('#markdown')
|
||||
@@ -17,4 +15,10 @@ describe('Check actions', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should load gists from URL', () => {
|
||||
cy.get('#gist').type('https://gist.github.com/sidharthv96/6268a23e673a533dcb198f241fd7012a');
|
||||
cy.contains('Load Gist').click();
|
||||
cy.contains('Go shopping!!');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
describe('Save History', () => {
|
||||
beforeEach(() => {
|
||||
cy.clock();
|
||||
cy.clearLocalStorage();
|
||||
cy.visit('/edit');
|
||||
cy.contains('Actions').click();
|
||||
cy.contains('History').click();
|
||||
});
|
||||
|
||||
it('should save when clicked', () => {
|
||||
cy.get('#historyList').find('li').should('have.length', 0);
|
||||
cy.get('#historyList').contains('No items in History');
|
||||
@@ -43,7 +47,6 @@ describe('Save History', () => {
|
||||
});
|
||||
|
||||
it('should auto save history', () => {
|
||||
cy.clock();
|
||||
cy.get('#editor').type(' C --> HistoryTest');
|
||||
cy.tick(70000);
|
||||
cy.contains('Timeline').click();
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { toBase64 } from 'js-base64';
|
||||
|
||||
describe('Site Loads', () => {
|
||||
beforeEach(() => {
|
||||
cy.clearLocalStorage();
|
||||
@@ -29,4 +31,61 @@ describe('Site Loads', () => {
|
||||
cy.contains('Class Diagram').click();
|
||||
cy.contains('classDiagram');
|
||||
});
|
||||
|
||||
it('should load diagram from gist', () => {
|
||||
cy.visit(`/edit?gist=https://gist.github.com/sidharthv96/6268a23e673a533dcb198f241fd7012a`);
|
||||
cy.contains('History').click();
|
||||
cy.contains('Go shopping!!');
|
||||
cy.contains('Revisions');
|
||||
cy.contains('sidharthv96 v8f8f1e2');
|
||||
cy.contains('sidharthv96 v7851e19');
|
||||
cy.getLocalStorage('codeStore').snapshot();
|
||||
});
|
||||
|
||||
it('should load diagram from gist revision', () => {
|
||||
cy.visit(
|
||||
'/edit?gist=https://gist.github.com/sidharthv96/6268a23e673a533dcb198f241fd7012a/ec9b4ab0e41e4ff6287326cd3cb47affd7851e19'
|
||||
);
|
||||
cy.contains('History').click();
|
||||
cy.contains('Party');
|
||||
cy.contains('Revisions');
|
||||
cy.contains('sidharthv96 v7851e19');
|
||||
cy.getLocalStorage('codeStore').snapshot();
|
||||
});
|
||||
|
||||
it('should load diagram from raw files', () => {
|
||||
cy.visit(
|
||||
'/edit?code=https://gist.githubusercontent.com/sidharthv96/6268a23e673a533dcb198f241fd7012a/raw/4eb03887e6a41397e80bdcdbf94017c498f8f1e2/code.mmd&config=https://gist.githubusercontent.com/sidharthv96/6268a23e673a533dcb198f241fd7012a/raw/4eb03887e6a41397e80bdcdbf94017c498f8f1e2/config.json'
|
||||
);
|
||||
cy.contains('Party');
|
||||
cy.getLocalStorage('codeStore').snapshot();
|
||||
});
|
||||
|
||||
it('should prevent setting the "securityLevel" option via URL', () => {
|
||||
const b64State = toBase64(
|
||||
`{"code":"graph TD\\nA[\\"<img src='https://via.placeholder.com/64' width=64 />\\"]","mermaid":"{\\"securityLevel\\": \\"loose\\", \\"theme\\": \\"forest\\"}","updateEditor":true,"autoSync":true,"updateDiagram":true}`,
|
||||
true
|
||||
);
|
||||
cy.on('window:confirm', () => true);
|
||||
cy.visit(`/edit#${b64State}`);
|
||||
cy.contains('Config').click();
|
||||
cy.contains('forest');
|
||||
cy.contains('securityLevel').should('not.exist');
|
||||
cy.get('#view').find('img').should('not.exist');
|
||||
cy.get('#view').contains('<img');
|
||||
cy.get('#view').contains('src="https://via.placeholder.com/64"');
|
||||
});
|
||||
|
||||
it('should allow persisting "securityLevel" using confirm dialogue', () => {
|
||||
const b64State = toBase64(
|
||||
`{"code":"graph TD\\nA[\\"<img src='https://via.placeholder.com/64' width=64/>\\"]","mermaid":"{\\"securityLevel\\": \\"loose\\", \\"theme\\": \\"forest\\"}","updateEditor":true,"autoSync":true,"updateDiagram":true}`,
|
||||
true
|
||||
);
|
||||
cy.on('window:confirm', () => false);
|
||||
cy.visit(`/edit#${b64State}`);
|
||||
cy.contains('Config').click();
|
||||
cy.contains('forest');
|
||||
cy.contains('securityLevel');
|
||||
cy.get('#view').find('img').should('be.visible');
|
||||
});
|
||||
});
|
||||
|
||||
+11
-2
@@ -4,10 +4,19 @@ module.exports = {
|
||||
"1": "{\"code\":\"graph TD\\n A[Christmas] -->|Get money| B(Go shopping)\\n B --> C{Let me think}\\n C -->|One| D[Laptop]\\n C -->|Two| E[iPhone]\\n C -->|Three| F[fa:fa-car Car]\\n \",\"mermaid\":\"{\\n \\\"theme\\\": \\\"default\\\"\\n}\",\"updateEditor\":true,\"autoSync\":true,\"updateDiagram\":true}"
|
||||
},
|
||||
"Check Redirect from old URL": {
|
||||
"1": "{\"code\":\"graph TD\\n A[Christmas] -->|Get money| B(Go shopping)\\n B --> C{Let me think}\\n C -->|One| D[Laptop]\\n C -->|Two| E[iPhone]\\n C -->|Three| F[fa:fa-car Car]\",\"mermaid\":\"{\\n \\\"theme\\\": \\\"default\\\"\\n}\",\"updateEditor\":false,\"autoSync\":true,\"updateDiagram\":false}"
|
||||
"1": "{\"code\":\"graph TD\\n A[Christmas] -->|Get money| B(Go shopping)\\n B --> C{Let me think}\\n C -->|One| D[Laptop]\\n C -->|Two| E[iPhone]\\n C -->|Three| F[fa:fa-car Car]\",\"mermaid\":\"{\\n \\\"theme\\\": \\\"default\\\"\\n}\",\"updateEditor\":false,\"autoSync\":true,\"updateDiagram\":true}"
|
||||
},
|
||||
"should load diagram from gist": {
|
||||
"1": "{\"code\":\"graph TD\\n A[Party] -->|Get money| B(Go shopping!!)\\n \",\"mermaid\":\"{\\n \\\"theme\\\": \\\"forest\\\",\\n \\\"test\\\": \\\"hello world\\\"\\n}\",\"updateEditor\":false,\"autoSync\":true,\"updateDiagram\":true,\"loader\":{\"type\":\"gist\",\"config\":{\"url\":\"https://gist.github.com/sidharthv96/6268a23e673a533dcb198f241fd7012a\"}}}"
|
||||
},
|
||||
"should load diagram from gist revision": {
|
||||
"1": "{\"code\":\"graph TD\\n A[Party] -->|Get money| B(Go shopping)\\n \",\"mermaid\":\"{\\n \\\"theme\\\": \\\"forest\\\",\\n \\\"test\\\": \\\"hello\\\"\\n}\",\"updateEditor\":false,\"autoSync\":true,\"updateDiagram\":true,\"loader\":{\"type\":\"gist\",\"config\":{\"url\":\"https://gist.github.com/sidharthv96/6268a23e673a533dcb198f241fd7012a/ec9b4ab0e41e4ff6287326cd3cb47affd7851e19\"}}}"
|
||||
},
|
||||
"should load diagram from raw files": {
|
||||
"1": "{\"code\":\"graph TD\\n A[Party] -->|Get money| B(Go shopping!!)\\n \",\"mermaid\":\"{\\n \\\"theme\\\": \\\"forest\\\",\\n \\\"test\\\": \\\"hello world\\\"\\n}\",\"updateEditor\":false,\"autoSync\":true,\"updateDiagram\":true,\"loader\":{\"type\":\"files\",\"config\":{\"codeURL\":\"https://gist.githubusercontent.com/sidharthv96/6268a23e673a533dcb198f241fd7012a/raw/4eb03887e6a41397e80bdcdbf94017c498f8f1e2/code.mmd\",\"configURL\":\"https://gist.githubusercontent.com/sidharthv96/6268a23e673a533dcb198f241fd7012a/raw/4eb03887e6a41397e80bdcdbf94017c498f8f1e2/config.json\"}}}"
|
||||
}
|
||||
},
|
||||
"__version": "7.3.0",
|
||||
"__version": "8.3.1",
|
||||
"Auto sync tests": {
|
||||
"should dim diagram when code is edited": {
|
||||
"1": "{\"code\":\"graph TD\\n A[Christmas] -->|Get money| B(Go shopping)\\n B --> C{Let me think}\\n C -->|One| D[Laptop]\\n C -->|Two| E[iPhone]\\n C -->|Three| F[fa:fa-car Car]\\n C --> Test\",\"mermaid\":\"{\\n \\\"theme\\\": \\\"default\\\"\\n}\",\"updateEditor\":false,\"autoSync\":false,\"updateDiagram\":false}"
|
||||
|
||||
@@ -18,10 +18,10 @@ import './commands';
|
||||
|
||||
// Alternatively you can use CommonJS syntax:
|
||||
// require('./commands')
|
||||
const resizeObserverLoopErrRe = /^[^(ResizeObserver loop limit exceeded)]/;
|
||||
|
||||
Cypress.on('uncaught:exception', (err) => {
|
||||
/* returning false here prevents Cypress from failing the test */
|
||||
if (resizeObserverLoopErrRe.test(err.message)) {
|
||||
if (err.message.includes('ResizeObserver loop limit exceeded')) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
#menu-toggle.svelte-qevfgi:checked+#menu.svelte-qevfgi{display:block}header.svelte-qevfgi.svelte-qevfgi{z-index:10000}.icon.svelte-1qkpo3v{transition-duration:.5s}.isOpen.svelte-1qkpo3v{transform:rotate(90deg)}#resizeHandler.svelte-ub8fux{cursor:col-resize;padding:0 2px}#resizeHandler.svelte-ub8fux:after{background-color:#ccc;content:"";height:100%;margin-left:-1px;position:absolute;top:0;width:2px}#resizeHandler.svelte-ub8fux:hover:after{background-color:#818cf8;margin-left:-2px;width:4px}@media screen and (max-width:768px){#resizeHandler.svelte-ub8fux{display:none}}
|
||||
@@ -1 +0,0 @@
|
||||
#svelte-announcer.svelte-1pdgbjn{clip:rect(0 0 0 0);-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;left:0;overflow:hidden;position:absolute;top:0;white-space:nowrap;width:1px}
|
||||
@@ -1 +0,0 @@
|
||||
#view.svelte-7vvt6c{border:1px #8b0000;flex:1}.error.svelte-7vvt6c,.outOfSync.svelte-7vvt6c{opacity:.5}
|
||||
@@ -1 +0,0 @@
|
||||
function e(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function t(t){for(var n=1;n<arguments.length;n++){var a=null!=arguments[n]?arguments[n]:{},i=Object.keys(a);"function"==typeof Object.getOwnPropertySymbols&&(i=i.concat(Object.getOwnPropertySymbols(a).filter((function(e){return Object.getOwnPropertyDescriptor(a,e).enumerable})))),i.forEach((function(n){e(t,n,a[n])}))}return t}var n={trackingId:null,debug:!1,anonymizeIp:!1,customDimensions:{},resetCustomDimensionsOnPage:[],setCustomDimensionsToPage:!0},a={};function i(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},i=!1,u=r(e),d=u.instanceName,p=u.instancePrefix;return{name:"google-analytics",config:t({},n,e),initialize:function(e){var n=e.config,i=e.instance;if(!n.trackingId)throw new Error("No GA trackingId defined");var r,c,s,u,g,f,v,m=n.customScriptSrc||"https://www.google-analytics.com/analytics.js";if(o(m)&&(r=window,c=document,s="script",u=m,g="ga",r.GoogleAnalyticsObject=g,r.ga=r.ga||function(){(r.ga.q=r.ga.q||[]).push(arguments)},r.ga.l=1*new Date,f=c.createElement(s),v=c.getElementsByTagName(s)[0],f.async=1,f.src=u,v.parentNode.insertBefore(f,v)),!a[d]){var y=t({cookieDomain:n.domain||"auto",siteSpeedSampleRate:n.siteSpeedSampleRate||1,sampleRate:n.sampleRate||100,allowLinker:!0},n.cookieConfig);if(d&&(y.name=d),ga("create",n.trackingId,y),n.debug&&(ga("".concat(p,"set"),"sendHitTask",null),window.ga_debug={trace:!0}),n.anonymizeIp&&ga("".concat(p,"set"),"anonymizeIp",!0),n.tasks){["customTask","previewTask","checkProtocolTask","validationTask","checkStorageTask","historyImportTask","samplerTask","buildHitTask","sendHitTask","timingTask","displayFeaturesTask"].forEach((function(e){if(n.tasks.hasOwnProperty(e)){var t=n.tasks[e];"function"==typeof t?ga(n.tasks[e]):null===t&&ga("".concat(p,"set"),e,t)}}))}var k=(i.user()||{}).traits||{};if(Object.keys(k).length){var h=l(k,n);ga("".concat(p,"set"),h)}a[d]=!0}},page:function(e){var n=e.payload,a=e.config,r=e.instance,c=n.properties,l=a.resetCustomDimensionsOnPage,u=a.customDimensions,f=r.getState("context.campaign");if(!o()){if(l&&l.length){var d=l.reduce((function(e,t){return u[t]&&(e[u[t]]=null),e}),{});Object.keys(d).length&&ga("".concat(p,"set"),d)}var v=c.path||document.location.pathname,m={page:v,title:c.title,location:c.url},y={page:v,title:c.title};c.referrer!==document.referrer&&(y.referrer=c.referrer);var k=t({},m,s(f),g(c,a,p));ga("".concat(p,"set"),y),i&&delete k.location,ga("".concat(p,"send"),"pageview",k),i=!0}},track:function(e){var t=e.payload,n=e.config,a=e.instance,i=t.properties,o=t.event,r=i.label,s=i.value;c({hitType:"event",event:o,label:r,category:i.category||"All",value:s,nonInteraction:i.nonInteraction,campaign:a.getState("context.campaign")},n,t)},identify:function(e){var t=e.payload,n=e.config;f(t.userId,t.traits,n)},loaded:function(){return!!window.gaplugins}}}function o(e){return e?!function(e){var t=document.querySelectorAll("script[src]");return!!Object.keys(t).filter((function(n){return(t[n].src||"")===e})).length}(e):"undefined"==typeof ga}function r(e){var t=e.instanceName;return{instancePrefix:t?"".concat(t,"."):"",instanceName:t}}function c(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},a=arguments.length>2?arguments[2]:void 0;if(!o()){var i=r(n),c=i.instancePrefix,l={hitType:e.hitType||"event",eventAction:e.event,eventLabel:e.label,eventCategory:e.category||"All",nonInteraction:void 0!==e.nonInteraction&&!!e.nonInteraction};e.value&&(l.eventValue=d(e.value));var u=s(e),f=g(a.properties,n,c),p=t({},l,u,f);return ga("".concat(c,"send"),"event",p),p}}function s(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t={},n=e.name,a=e.source,i=e.medium,o=e.content,r=e.keyword;return n&&(t.campaignName=n),a&&(t.campaignSource=a),i&&(t.campaignMedium=i),o&&(t.campaignContent=o),r&&(t.campaignKeyword=r),t}function l(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.customDimensions;return Object.keys(n).reduce((function(t,a){var i=n[a],o=u(e,a)||e[a];return"boolean"==typeof o&&(o=o.toString()),o||0===o?(t[i]=o,t):t}),{})}function u(e,t,n,a,i){for(t=t.split?t.split("."):t,a=0;a<t.length;a++)e=e?e[t[a]]:i;return e===i?n:e}function g(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1?arguments[1]:void 0,n=arguments.length>2?arguments[2]:void 0,a=l(e,t);return Object.keys(a).length?t.setCustomDimensionsToPage?(ga("".concat(n,"set"),a),{}):a:{}}function f(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if(!o()){var a=r(n),i=a.instancePrefix;if(e&&ga("".concat(i,"set"),"userId",e),Object.keys(t).length){var c=l(t,n);ga("".concat(i,"set"),c)}}}function d(e){return!e||e<0?0:Math.round(e)}var p=i,v=i,m=void 0,y=void 0,k=c,h=f;export default p;export{h as identify,v as init,m as initialize,y as page,k as track};
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
let s="",a="/.";function e(e){({base:s,assets:a}=e)}export{s as b,e as s};
|
||||
@@ -1 +0,0 @@
|
||||
let e;const r={},t=function(t,n){if(!n)return t();if(void 0===e){const r=document.createElement("link").relList;e=r&&r.supports&&r.supports("modulepreload")?"modulepreload":"preload"}return Promise.all(n.map((t=>{if(t in r)return;r[t]=!0;const n=t.endsWith(".css"),o=n?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${t}"]${o}`))return;const s=document.createElement("link");return s.rel=n?"stylesheet":e,n||(s.as="script",s.crossOrigin=""),s.href=t,document.head.appendChild(s),n?new Promise(((e,r)=>{s.addEventListener("load",e),s.addEventListener("error",r)})):void 0}))).then((()=>t()))};export{t as _};
|
||||
@@ -1 +0,0 @@
|
||||
let t;function a(a){t=a}export{a as i,t as r};
|
||||
@@ -1 +0,0 @@
|
||||
var e=Object.defineProperty,a=Object.defineProperties,t=Object.getOwnPropertyDescriptors,r=Object.getOwnPropertySymbols,s=Object.prototype.hasOwnProperty,o=Object.prototype.propertyIsEnumerable,n=(a,t,r)=>t in a?e(a,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):a[t]=r,i=(e,a)=>{for(var t in a||(a={}))s.call(a,t)&&n(e,t,a[t]);if(r)for(var t of r(a))o.call(a,t)&&n(e,t,a[t]);return e},c=(e,r)=>a(e,t(r));import{a2 as l,a3 as d,C as p,a4 as u,Z as m,a6 as f,a9 as g,S as y,i as h,s as b,e as v,c as O,a as E,d as S,b as w,N as T,f as D,F as j,G as _,H as x,z as C,a8 as P,J as A}from"./vendor-8b597521.js";import{_ as I}from"./preload-helper-9f12a5fd.js";let J;let L;const N=l(p({code:"graph TD\n A[Christmas] --\x3e|Get money| B(Go shopping)\n B --\x3e C{Let me think}\n C --\x3e|One| D[Laptop]\n C --\x3e|Two| E[iPhone]\n C --\x3e|Three| F[fa:fa-car Car]\n ",mermaid:JSON.stringify({theme:"default"},null,2),updateEditor:!1,autoSync:!0,updateDiagram:!0}),d(),"codeStore"),k=u([N],(([e],a)=>{a(m(JSON.stringify(e),!0))})),V=e=>{N.update((a=>i(i({},a),e)))};let G=!1;const H=(e,a,t=!1)=>{var r;r=e,J&&(clearTimeout(L),L=setTimeout((function(){const e=r.replace(/^\s*%%.*\n/g,"\n").trimStart().split(" ")[0];console.debug("ga:","send","event","render",e),J.track("render",{graphType:e})}),5e3));if((e.match(/\n/g)||"").length+1>50&&!G&&f(N).autoSync){const e=confirm("Long diagram deteced. Turn off Auto Sync? Click the sync logo to manually sync.");G=!0,e&&V({autoSync:!1})}N.update((r=>c(i({},r),{code:e,updateEditor:a,updateDiagram:t})))},z=(e,a)=>{N.update((t=>c(i({},t),{mermaid:e,updateEditor:a})))},B=()=>JSON.stringify(f(N)),F=p(void 0);function M(e){let a,t;return{c(){a=v("div"),t=v("div"),this.h()},l(e){a=O(e,"DIV",{id:!0,class:!0});var r=E(a);t=O(r,"DIV",{id:!0,class:!0}),E(t).forEach(S),r.forEach(S),this.h()},h(){w(t,"id","container"),w(t,"class","flex-1 overflow-auto"),w(a,"id","view"),w(a,"class","p-2 svelte-7vvt6c"),T(a,"error",e[1]),T(a,"outOfSync",e[2])},m(r,s){D(r,a,s),j(a,t),e[3](t)},p(e,[t]){2&t&&T(a,"error",e[1]),4&t&&T(a,"outOfSync",e[2])},i:_,o:_,d(t){t&&S(a),e[3](null)}}}function R(e,a,t){let r;x(e,N,(e=>t(6,r=e)));const s=window.mermaid;let o,n="",i=!1,c=!1,l=!0;return C((()=>{N.subscribe((e=>{try{if(o&&e&&(e.updateDiagram||e.autoSync)){e.autoSync||P(N,r.updateDiagram=!1,r),t(2,c=!1),l=!0,n=e.code;const a=o.parentElement.parentElement.parentElement.scrollTop;t(0,o.innerHTML=n,o),delete o.dataset.processed,s.initialize(Object.assign({},JSON.parse(e.mermaid))),s.render("graph-div",n,(e=>{t(0,o.innerHTML=e,o)})),t(0,o.parentElement.parentElement.parentElement.scrollTop=a,o),t(1,i=!1)}else l?l=!1:t(2,c=!0)}catch(a){console.log("view fail",a),t(1,i=!0)}})),F.subscribe((e=>{void 0===e?t(1,i=!1):(t(1,i=!0),console.log("Error: ",e))}))})),[o,i,c,function(e){A[e?"unshift":"push"]((()=>{o=e,t(0,o)}))}]}class $ extends y{constructor(e){super(),h(this,e,R,M,b,{})}}const U=()=>{(e=>{let a;try{const t=g(e);console.log(`Tring to load state: ${t}`),a=JSON.parse(t),"string"!=typeof a.mermaid&&(a.mermaid=JSON.stringify(a.mermaid,null,2))}catch(t){e&&console.error("Init error",t),a=f(N),console.log(a)}V(c(i({},a),{updateEditor:!0}))})(window.location.hash.slice(1))},Z=()=>{V({updateDiagram:!0})},q=async()=>{U(),Z(),k.subscribe((e=>{history.replaceState(void 0,void 0,`#${e}`)})),await(async()=>{if(!J)try{const{Analytics:e}=await I((()=>import("./analytics.browser.es-eaddcc60.js")),void 0),a=await I((()=>import("./analytics-plugin-ga.browser.es-9bc8c1dc.js")),void 0);J=e({app:"mermaid-live-editor",plugins:[a.init({trackingId:"UA-153180559-1"})]})}catch{console.info("Analytics blocked ;)")}})(),null==J||J.page()};export{$ as V,J as a,k as b,N as c,z as d,F as e,B as g,q as i,Z as s,H as u};
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
import{S as s,i as r,s as a,e as t,t as e,c as o,a as n,g as c,d as u,f as p,F as l,h as f,k as i,l as d,n as m,G as h}from"./chunks/vendor-8b597521.js";function k(s){let r,a,i=s[1].stack+"";return{c(){r=t("pre"),a=e(i)},l(s){r=o(s,"PRE",{});var t=n(r);a=c(t,i),t.forEach(u)},m(s,t){p(s,r,t),l(r,a)},p(s,r){2&r&&i!==(i=s[1].stack+"")&&f(a,i)},d(s){s&&u(r)}}}function v(s){let r,a,v,E,g,x,P,$=s[1].message+"",b=s[1].stack&&k(s);return{c(){r=t("h1"),a=e(s[0]),v=i(),E=t("p"),g=e($),x=i(),b&&b.c(),P=d()},l(t){r=o(t,"H1",{});var e=n(r);a=c(e,s[0]),e.forEach(u),v=m(t),E=o(t,"P",{});var p=n(E);g=c(p,$),p.forEach(u),x=m(t),b&&b.l(t),P=d()},m(s,t){p(s,r,t),l(r,a),p(s,v,t),p(s,E,t),l(E,g),p(s,x,t),b&&b.m(s,t),p(s,P,t)},p(s,[r]){1&r&&f(a,s[0]),2&r&&$!==($=s[1].message+"")&&f(g,$),s[1].stack?b?b.p(s,r):(b=k(s),b.c(),b.m(P.parentNode,P)):b&&(b.d(1),b=null)},i:h,o:h,d(s){s&&u(r),s&&u(v),s&&u(E),s&&u(x),b&&b.d(s),s&&u(P)}}}function E({error:s,status:r}){return{props:{error:s,status:r}}}function g(s,r,a){let{status:t}=r,{error:e}=r;return s.$$set=s=>{"status"in s&&a(0,t=s.status),"error"in s&&a(1,e=s.error)},[t,e]}export default class extends s{constructor(s){super(),r(this,s,g,v,a,{status:0,error:1})}}export{E as load};
|
||||
@@ -1 +0,0 @@
|
||||
import{S as s,i as e,s as r,D as o,e as a,c,a as t,d as n,b as i,f as l,E as u,v as h,r as p,z as f}from"../chunks/vendor-8b597521.js";import{b as $}from"../chunks/paths-45dac81d.js";function d(s){let e,r;const f=s[1].default,$=o(f,s,s[0],null);return{c(){e=a("main"),$&&$.c(),this.h()},l(s){e=c(s,"MAIN",{class:!0});var r=t(e);$&&$.l(r),r.forEach(n),this.h()},h(){i(e,"class","h-screen")},m(s,o){l(s,e,o),$&&$.m(e,null),r=!0},p(s,[e]){$&&$.p&&(!r||1&e)&&u($,f,s,s[0],e,null,null)},i(s){r||(h($,s),r=!0)},o(s){p($,s),r=!1},d(s){s&&n(e),$&&$.d(s)}}}function v(s,e,r){let{$$slots:o={},$$scope:a}=e;return f((()=>{"serviceWorker"in navigator&&navigator.serviceWorker.register(`${$}/service-worker.js`,{scope:`${$}/`}).then((function(s){console.log("Registration successful, scope is:",s.scope)})).catch((function(s){console.log("Service worker registration failed, error:",s)}))})),s.$$set=s=>{"$$scope"in s&&r(0,a=s.$$scope)},[a,o]}export default class extends s{constructor(s){super(),e(this,s,v,d,r,{})}}
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
import{S as t,i as n,s as o,z as s}from"../chunks/vendor-8b597521.js";import{r as e}from"../chunks/singletons-bb9012b7.js";import{b as i}from"../chunks/paths-45dac81d.js";const c=async function(t,n){return e.goto(t,n,[])};function r(t){var n=this&&this.__awaiter||function(t,n,o,s){return new(o||(o=Promise))((function(e,i){function c(t){try{a(s.next(t))}catch(n){i(n)}}function r(t){try{a(s.throw(t))}catch(n){i(n)}}function a(t){var n;t.done?e(t.value):(n=t.value,n instanceof o?n:new o((function(t){t(n)}))).then(c,r)}a((s=s.apply(t,n||[])).next())}))};return s((()=>n(void 0,void 0,void 0,(function*(){const t=window.location.hash.split("/");let n="edit";t.length>2&&(n=`${t[1]}#${t[2]}`),yield c(`${i}/${n}`,{replaceState:!0})})))),[]}export default class extends t{constructor(t){super(),n(this,t,r,null,o,{})}}
|
||||
@@ -1 +0,0 @@
|
||||
import{S as s,i as a,s as r,j as t,m as e,o as n,G as o,v as f,r as m,w as u,z as i}from"../chunks/vendor-8b597521.js";import{V as c,i as p}from"../chunks/util-b71e0722.js";import"../chunks/preload-helper-9f12a5fd.js";function $(s){let a,r;return a=new c({}),{c(){t(a.$$.fragment)},l(s){e(a.$$.fragment,s)},m(s,t){n(a,s,t),r=!0},p:o,i(s){r||(f(a.$$.fragment,s),r=!0)},o(s){m(a.$$.fragment,s),r=!1},d(s){u(a,s)}}}function l(s){return i(p),[]}export default class extends s{constructor(s){super(),a(this,s,l,$,r,{})}}
|
||||
File diff suppressed because one or more lines are too long
@@ -1,89 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Online FlowChart & Diagrams Editor - Mermaid Live Editor</title>
|
||||
<meta
|
||||
name="og:image"
|
||||
content="https://github.com/mermaid-js/mermaid/raw/develop/img/header.png"
|
||||
/>
|
||||
<link rel="canonical" href="https://mermaid-js.github.io/mermaid-live-editor/" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Simplify documentation and avoid heavy tools. Open source Visio Alternative. Commonly used for explaining your code! Mermaid is a simple markdown-like script language for generating charts from text via javascript."
|
||||
/>
|
||||
<link rel="icon" type="image/png" href="/mermaid-live-editor/favicon.png" />
|
||||
<link rel="manifest" href="/mermaid-live-editor/manifest.json" />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css"
|
||||
/>
|
||||
<script
|
||||
src="https://cdn.jsdelivr.net/npm/mermaid@8.10.1/dist/mermaid.min.js"
|
||||
integrity="sha256-aQCGsx3/OLAXwNyOUrAedielIQAjIrMFkcWdXMlIkGc="
|
||||
crossorigin="anonymous"
|
||||
></script>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/editor/editor.main.min.css"
|
||||
integrity="sha512-RhnuJxgda82cBylRysVDqdpwnBcSkMzxz1+BxGwBPNMzBJlvaOjHz7P2kXELC0bdNxazsNSyJb7KAww0T5iUdQ=="
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
/>
|
||||
<script>
|
||||
var require = {
|
||||
paths: { vs: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs' }
|
||||
};
|
||||
</script>
|
||||
<script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/loader.min.js"
|
||||
integrity="sha512-+8+MX2hyUZxaUfMJT0ew+rPsrTGiTmCg8oksa6uVE/ZlR/g3SJtyozqcqDGkw/W785xYAvcx1LxXPP+ywD0SNw=="
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
></script>
|
||||
<script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/editor/editor.main.nls.min.js"
|
||||
integrity="sha512-3aAqsDS5ClTlwyzxufRhW9WMwZlYn3V8GLRl324pMIftp+CA6kvxfjlm8TG7Wi53eBcerEdX0YfXm3QLvf1Pqg=="
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
></script>
|
||||
<script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/editor/editor.main.js"
|
||||
integrity="sha512-sOJZBKiSvh/6vxIimdXkjO45Nd3v2n3ZYtrwktgj5SJh0+PCqNQ5oqzxEr6c/o4ULczn1Wo2yh1qrz+ghduDUA=="
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
></script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<link rel="modulepreload" href="/mermaid-live-editor/_app/start-50d0be99.js">
|
||||
<link rel="modulepreload" href="/mermaid-live-editor/_app/chunks/vendor-8b597521.js">
|
||||
<link rel="modulepreload" href="/mermaid-live-editor/_app/chunks/preload-helper-9f12a5fd.js">
|
||||
<link rel="modulepreload" href="/mermaid-live-editor/_app/chunks/singletons-bb9012b7.js">
|
||||
<link rel="modulepreload" href="/mermaid-live-editor/_app/chunks/paths-45dac81d.js">
|
||||
<link rel="stylesheet" href="/mermaid-live-editor/_app/assets/start-0826e215.css">
|
||||
|
||||
<script type="module">
|
||||
import { start } from "/mermaid-live-editor/_app/start-50d0be99.js";
|
||||
start({
|
||||
target: document.querySelector("#svelte"),
|
||||
paths: {"base":"/mermaid-live-editor","assets":"/mermaid-live-editor"},
|
||||
session: {},
|
||||
host: location.host,
|
||||
route: true,
|
||||
spa: true,
|
||||
trailing_slash: "ignore",
|
||||
hydrate: null
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="svelte">
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 16 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 16 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 78 KiB |
@@ -1,89 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Online FlowChart & Diagrams Editor - Mermaid Live Editor</title>
|
||||
<meta
|
||||
name="og:image"
|
||||
content="https://github.com/mermaid-js/mermaid/raw/develop/img/header.png"
|
||||
/>
|
||||
<link rel="canonical" href="https://mermaid-js.github.io/mermaid-live-editor/" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Simplify documentation and avoid heavy tools. Open source Visio Alternative. Commonly used for explaining your code! Mermaid is a simple markdown-like script language for generating charts from text via javascript."
|
||||
/>
|
||||
<link rel="icon" type="image/png" href="/mermaid-live-editor/favicon.png" />
|
||||
<link rel="manifest" href="/mermaid-live-editor/manifest.json" />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css"
|
||||
/>
|
||||
<script
|
||||
src="https://cdn.jsdelivr.net/npm/mermaid@8.10.1/dist/mermaid.min.js"
|
||||
integrity="sha256-aQCGsx3/OLAXwNyOUrAedielIQAjIrMFkcWdXMlIkGc="
|
||||
crossorigin="anonymous"
|
||||
></script>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/editor/editor.main.min.css"
|
||||
integrity="sha512-RhnuJxgda82cBylRysVDqdpwnBcSkMzxz1+BxGwBPNMzBJlvaOjHz7P2kXELC0bdNxazsNSyJb7KAww0T5iUdQ=="
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
/>
|
||||
<script>
|
||||
var require = {
|
||||
paths: { vs: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs' }
|
||||
};
|
||||
</script>
|
||||
<script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/loader.min.js"
|
||||
integrity="sha512-+8+MX2hyUZxaUfMJT0ew+rPsrTGiTmCg8oksa6uVE/ZlR/g3SJtyozqcqDGkw/W785xYAvcx1LxXPP+ywD0SNw=="
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
></script>
|
||||
<script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/editor/editor.main.nls.min.js"
|
||||
integrity="sha512-3aAqsDS5ClTlwyzxufRhW9WMwZlYn3V8GLRl324pMIftp+CA6kvxfjlm8TG7Wi53eBcerEdX0YfXm3QLvf1Pqg=="
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
></script>
|
||||
<script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/editor/editor.main.js"
|
||||
integrity="sha512-sOJZBKiSvh/6vxIimdXkjO45Nd3v2n3ZYtrwktgj5SJh0+PCqNQ5oqzxEr6c/o4ULczn1Wo2yh1qrz+ghduDUA=="
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
></script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<link rel="modulepreload" href="/mermaid-live-editor/_app/start-50d0be99.js">
|
||||
<link rel="modulepreload" href="/mermaid-live-editor/_app/chunks/vendor-8b597521.js">
|
||||
<link rel="modulepreload" href="/mermaid-live-editor/_app/chunks/preload-helper-9f12a5fd.js">
|
||||
<link rel="modulepreload" href="/mermaid-live-editor/_app/chunks/singletons-bb9012b7.js">
|
||||
<link rel="modulepreload" href="/mermaid-live-editor/_app/chunks/paths-45dac81d.js">
|
||||
<link rel="stylesheet" href="/mermaid-live-editor/_app/assets/start-0826e215.css">
|
||||
|
||||
<script type="module">
|
||||
import { start } from "/mermaid-live-editor/_app/start-50d0be99.js";
|
||||
start({
|
||||
target: document.querySelector("#svelte"),
|
||||
paths: {"base":"/mermaid-live-editor","assets":"/mermaid-live-editor"},
|
||||
session: {},
|
||||
host: location.host,
|
||||
route: true,
|
||||
spa: true,
|
||||
trailing_slash: "ignore",
|
||||
hydrate: null
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="svelte">
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1 +0,0 @@
|
||||
{"short_name":"Mermaid","name":"Mermaid Live Editor","icons":[{"src":"/mermaid-live-editor/icon-192.png","type":"image/png","sizes":"192x192"},{"src":"/mermaid-live-editor/icon-512.png","type":"image/png","sizes":"512x512"}],"start_url":"/mermaid-live-editor/edit/","background_color":"#6366F1","display":"standalone","scope":"/mermaid-live-editor/edit/","theme_color":"#6366F1","description":"FlowChart & Diagrams Editor.","orientation":"landscape"}
|
||||
@@ -1,3 +0,0 @@
|
||||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
Disallow:
|
||||
@@ -1,2 +0,0 @@
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
self.addEventListener('fetch', (e) => {});
|
||||
@@ -1,89 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Online FlowChart & Diagrams Editor - Mermaid Live Editor</title>
|
||||
<meta
|
||||
name="og:image"
|
||||
content="https://github.com/mermaid-js/mermaid/raw/develop/img/header.png"
|
||||
/>
|
||||
<link rel="canonical" href="https://mermaid-js.github.io/mermaid-live-editor/" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Simplify documentation and avoid heavy tools. Open source Visio Alternative. Commonly used for explaining your code! Mermaid is a simple markdown-like script language for generating charts from text via javascript."
|
||||
/>
|
||||
<link rel="icon" type="image/png" href="/mermaid-live-editor/favicon.png" />
|
||||
<link rel="manifest" href="/mermaid-live-editor/manifest.json" />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css"
|
||||
/>
|
||||
<script
|
||||
src="https://cdn.jsdelivr.net/npm/mermaid@8.10.1/dist/mermaid.min.js"
|
||||
integrity="sha256-aQCGsx3/OLAXwNyOUrAedielIQAjIrMFkcWdXMlIkGc="
|
||||
crossorigin="anonymous"
|
||||
></script>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/editor/editor.main.min.css"
|
||||
integrity="sha512-RhnuJxgda82cBylRysVDqdpwnBcSkMzxz1+BxGwBPNMzBJlvaOjHz7P2kXELC0bdNxazsNSyJb7KAww0T5iUdQ=="
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
/>
|
||||
<script>
|
||||
var require = {
|
||||
paths: { vs: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs' }
|
||||
};
|
||||
</script>
|
||||
<script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/loader.min.js"
|
||||
integrity="sha512-+8+MX2hyUZxaUfMJT0ew+rPsrTGiTmCg8oksa6uVE/ZlR/g3SJtyozqcqDGkw/W785xYAvcx1LxXPP+ywD0SNw=="
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
></script>
|
||||
<script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/editor/editor.main.nls.min.js"
|
||||
integrity="sha512-3aAqsDS5ClTlwyzxufRhW9WMwZlYn3V8GLRl324pMIftp+CA6kvxfjlm8TG7Wi53eBcerEdX0YfXm3QLvf1Pqg=="
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
></script>
|
||||
<script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/editor/editor.main.js"
|
||||
integrity="sha512-sOJZBKiSvh/6vxIimdXkjO45Nd3v2n3ZYtrwktgj5SJh0+PCqNQ5oqzxEr6c/o4ULczn1Wo2yh1qrz+ghduDUA=="
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
></script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<link rel="modulepreload" href="/mermaid-live-editor/_app/start-50d0be99.js">
|
||||
<link rel="modulepreload" href="/mermaid-live-editor/_app/chunks/vendor-8b597521.js">
|
||||
<link rel="modulepreload" href="/mermaid-live-editor/_app/chunks/preload-helper-9f12a5fd.js">
|
||||
<link rel="modulepreload" href="/mermaid-live-editor/_app/chunks/singletons-bb9012b7.js">
|
||||
<link rel="modulepreload" href="/mermaid-live-editor/_app/chunks/paths-45dac81d.js">
|
||||
<link rel="stylesheet" href="/mermaid-live-editor/_app/assets/start-0826e215.css">
|
||||
|
||||
<script type="module">
|
||||
import { start } from "/mermaid-live-editor/_app/start-50d0be99.js";
|
||||
start({
|
||||
target: document.querySelector("#svelte"),
|
||||
paths: {"base":"/mermaid-live-editor","assets":"/mermaid-live-editor"},
|
||||
session: {},
|
||||
host: location.host,
|
||||
route: true,
|
||||
spa: true,
|
||||
trailing_slash: "ignore",
|
||||
hydrate: null
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="svelte">
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
+34
-32
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mermaid-live-editor",
|
||||
"version": "2.0.65",
|
||||
"version": "2.0.67",
|
||||
"scripts": {
|
||||
"dev": "svelte-kit dev",
|
||||
"build": "svelte-kit build",
|
||||
@@ -9,50 +9,52 @@
|
||||
"lint:fix": "prettier --write --plugin-search-dir=. . && eslint --fix --ignore-path .gitignore .",
|
||||
"format": "prettier --write --plugin-search-dir=. .",
|
||||
"pre-commit": "lint-staged",
|
||||
"postinstall": "husky install"
|
||||
"postinstall": "husky install",
|
||||
"test": "cypress run",
|
||||
"cy": "cypress open"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@cypress/snapshot": "^2.1.7",
|
||||
"@sveltejs/adapter-static": "^1.0.0-next.11",
|
||||
"@sveltejs/kit": "^1.0.0-next.109",
|
||||
"@types/mermaid": "^8.2.5",
|
||||
"@typescript-eslint/eslint-plugin": "^4.19.0",
|
||||
"@typescript-eslint/parser": "^4.19.0",
|
||||
"autoprefixer": "^10.2.5",
|
||||
"@sveltejs/adapter-static": "1.0.0-next.17",
|
||||
"@sveltejs/kit": "1.0.0-next.147",
|
||||
"@types/mermaid": "^8.2.7",
|
||||
"@typescript-eslint/eslint-plugin": "^4.30.0",
|
||||
"@typescript-eslint/parser": "^4.30.0",
|
||||
"autoprefixer": "^10.3.3",
|
||||
"chai": "^4.3.4",
|
||||
"cssnano": "^5.0.1",
|
||||
"cypress": "^7.3.0",
|
||||
"cypress-localstorage-commands": "^1.4.4",
|
||||
"eslint": "^7.27.0",
|
||||
"cssnano": "^5.0.8",
|
||||
"cypress": "8.3.1",
|
||||
"cypress-localstorage-commands": "^1.5.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-prettier": "^8.1.0",
|
||||
"eslint-plugin-cypress": "^2.11.3",
|
||||
"eslint-plugin-mocha": "^8.1.0",
|
||||
"eslint-plugin-mocha": "^9.0.0",
|
||||
"eslint-plugin-postcss-modules": "^1.2.1",
|
||||
"eslint-plugin-svelte3": "^3.2.0",
|
||||
"eslint-plugin-tailwindcss": "^1.8.0",
|
||||
"husky": "^6.0.0",
|
||||
"lint-staged": "^11.0.0",
|
||||
"mocha": "^8.4.0",
|
||||
"postcss": "^8.2.10",
|
||||
"postcss-load-config": "^3.0.1",
|
||||
"prettier": "~2.2.1",
|
||||
"prettier-plugin-svelte": "^2.2.0",
|
||||
"svelte": "^3.34.0",
|
||||
"svelte-preprocess": "^4.7.1",
|
||||
"tailwindcss": "^2.1.1",
|
||||
"tslib": "^2.0.0",
|
||||
"typescript": "^4.0.0"
|
||||
"eslint-plugin-tailwindcss": "^1.14.3",
|
||||
"husky": "^7.0.2",
|
||||
"lint-staged": "^11.1.2",
|
||||
"mocha": "^9.1.1",
|
||||
"postcss": "^8.3.6",
|
||||
"postcss-load-config": "^3.1.0",
|
||||
"prettier": "~2.3.2",
|
||||
"prettier-plugin-svelte": "^2.4.0",
|
||||
"svelte": "^3.42.4",
|
||||
"svelte-preprocess": "^4.8.0",
|
||||
"tailwindcss": "^2.2.9",
|
||||
"tslib": "^2.3.1",
|
||||
"typescript": "^4.4.2"
|
||||
},
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@analytics/google-analytics": "^0.5.2",
|
||||
"@macfja/svelte-persistent-store": "^1.1.0",
|
||||
"analytics": "^0.7.5",
|
||||
"@analytics/google-analytics": "^0.5.3",
|
||||
"@macfja/svelte-persistent-store": "^1.2.0",
|
||||
"analytics": "^0.7.14",
|
||||
"js-base64": "^3.6.1",
|
||||
"mermaid": "^8.10.1",
|
||||
"mermaid": "^8.11.4",
|
||||
"moment": "^2.29.1",
|
||||
"monaco-editor": "^0.24.0",
|
||||
"random-word-slugs": "^0.0.2"
|
||||
"monaco-editor": "^0.27.0",
|
||||
"random-word-slugs": "^0.0.5"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{ts,svelte,js,css,md,json}": [
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"extends": [
|
||||
"config:base",
|
||||
":rebaseStalePrs",
|
||||
"group:allNonMajor",
|
||||
"schedule:earlyMondays",
|
||||
":automergeMinor",
|
||||
":automergeTesters",
|
||||
":automergeLinters",
|
||||
":automergeTypes",
|
||||
":automergePatch"
|
||||
],
|
||||
"packageRules": [
|
||||
{
|
||||
"matchUpdateTypes": ["minor", "patch", "pin", "digest"],
|
||||
"automerge": true
|
||||
},
|
||||
{
|
||||
"matchDatasources": ["npm"],
|
||||
"stabilityDays": 3
|
||||
}
|
||||
],
|
||||
"dependencyDashboard": true,
|
||||
"major": {
|
||||
"dependencyDashboardApproval": true
|
||||
},
|
||||
"dependencyDashboardAutoclose": true
|
||||
}
|
||||
+5
-14
@@ -19,38 +19,29 @@
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css"
|
||||
/>
|
||||
<script
|
||||
src="https://cdn.jsdelivr.net/npm/mermaid@8.10.1/dist/mermaid.min.js"
|
||||
integrity="sha256-aQCGsx3/OLAXwNyOUrAedielIQAjIrMFkcWdXMlIkGc="
|
||||
crossorigin="anonymous"
|
||||
></script>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/editor/editor.main.min.css"
|
||||
integrity="sha512-RhnuJxgda82cBylRysVDqdpwnBcSkMzxz1+BxGwBPNMzBJlvaOjHz7P2kXELC0bdNxazsNSyJb7KAww0T5iUdQ=="
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.27.0/min/vs/editor/editor.main.min.css"
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
/>
|
||||
<script>
|
||||
var require = {
|
||||
paths: { vs: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs' }
|
||||
paths: { vs: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.27.0/min/vs' }
|
||||
};
|
||||
</script>
|
||||
<script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/loader.min.js"
|
||||
integrity="sha512-+8+MX2hyUZxaUfMJT0ew+rPsrTGiTmCg8oksa6uVE/ZlR/g3SJtyozqcqDGkw/W785xYAvcx1LxXPP+ywD0SNw=="
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.27.0/min/vs/loader.min.js"
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
></script>
|
||||
<script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/editor/editor.main.nls.min.js"
|
||||
integrity="sha512-3aAqsDS5ClTlwyzxufRhW9WMwZlYn3V8GLRl324pMIftp+CA6kvxfjlm8TG7Wi53eBcerEdX0YfXm3QLvf1Pqg=="
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.27.0/min/vs/editor/editor.main.nls.min.js"
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
></script>
|
||||
<script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.23.0/min/vs/editor/editor.main.js"
|
||||
integrity="sha512-sOJZBKiSvh/6vxIimdXkjO45Nd3v2n3ZYtrwktgj5SJh0+PCqNQ5oqzxEr6c/o4ULczn1Wo2yh1qrz+ghduDUA=="
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.27.0/min/vs/editor/editor.main.js"
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
></script>
|
||||
|
||||
@@ -12,3 +12,7 @@
|
||||
.action-btn {
|
||||
@apply rounded p-2 bg-indigo-400 shadow flex-auto text-white hover:bg-indigo-500;
|
||||
}
|
||||
|
||||
.input {
|
||||
@apply flex-1 border-indigo-400 border-solid border-2 rounded;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
<script lang="ts">
|
||||
import { browser } from '$app/env';
|
||||
|
||||
import Card from '$lib/components/card/card.svelte';
|
||||
import type { State } from '$lib/types';
|
||||
import { base64State, codeStore } from '$lib/util/state';
|
||||
import { codeStore } from '$lib/util/state';
|
||||
import { toBase64 } from 'js-base64';
|
||||
import moment from 'moment';
|
||||
|
||||
@@ -13,7 +15,9 @@
|
||||
if (!svg) {
|
||||
svg = document.querySelector('#container svg');
|
||||
}
|
||||
const svgString = svg.outerHTML.replaceAll('<br>', '<br/>');
|
||||
const svgString = svg.outerHTML
|
||||
.replaceAll('<br>', '<br/>')
|
||||
.replaceAll(/<img([^>]*)>/g, (m, g) => `<img ${g} />`);
|
||||
return toBase64(svgString);
|
||||
};
|
||||
|
||||
@@ -103,17 +107,36 @@
|
||||
);
|
||||
};
|
||||
|
||||
const onCopyMarkdown = (event: Event) => {
|
||||
event.target.select();
|
||||
const onCopyMarkdown = () => {
|
||||
document.getElementById('markdown').select();
|
||||
document.execCommand('Copy');
|
||||
};
|
||||
|
||||
let gistURL = '';
|
||||
codeStore.subscribe((state) => {
|
||||
if (state.loader?.type === 'gist') {
|
||||
// @ts-ignore Gist will have url
|
||||
gistURL = state.loader.config.url;
|
||||
}
|
||||
});
|
||||
|
||||
const loadGist = () => {
|
||||
if (!gistURL) {
|
||||
alert('Please enter a Gist URL first');
|
||||
}
|
||||
window.location.href = `${window.location.pathname}?gist=${gistURL}`;
|
||||
};
|
||||
|
||||
let iUrl: string;
|
||||
let svgUrl: string;
|
||||
let mdCode: string;
|
||||
let imagemodeselected = 'auto';
|
||||
let userimagesize = 1080;
|
||||
|
||||
let isNetlify = false;
|
||||
if (browser && ['mermaid.live', 'netlify'].some((path) => window.location.host.includes(path))) {
|
||||
isNetlify = true;
|
||||
}
|
||||
codeStore.subscribe((state: State) => {
|
||||
const stateCopy = JSON.parse(JSON.stringify(state));
|
||||
if (typeof stateCopy.mermaid === 'string') {
|
||||
@@ -126,7 +149,7 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
<Card title="Actions" isOpen={false}>
|
||||
<Card title="Actions" isOpen={true}>
|
||||
<div class="flex flex-wrap gap-2 m-2">
|
||||
{#if isClipboardAvailable()}
|
||||
<button class="action-btn w-full" on:click={onCopyClipboard}
|
||||
@@ -160,8 +183,29 @@
|
||||
</div>
|
||||
|
||||
<div class="w-full flex gap-2 items-center">
|
||||
<label for="markdown">Copy Markdown</label>
|
||||
<input class="flex-1" id="markdown" type="text" value={mdCode} on:click={onCopyMarkdown} />
|
||||
<input class="input" id="markdown" type="text" value={mdCode} on:click={onCopyMarkdown} />
|
||||
<label for="markdown">
|
||||
<button class="btn text-white flex-auto" on:click={onCopyMarkdown}> Copy Markdown </button>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="w-full flex gap-2 items-center">
|
||||
<input
|
||||
class="input"
|
||||
id="gist"
|
||||
type="text"
|
||||
bind:value={gistURL}
|
||||
placeholder="Enter Gist URL" />
|
||||
<label for="gist">
|
||||
<button class="btn text-white flex-auto" on:click={loadGist}> Load Gist </button>
|
||||
</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">
|
||||
This site is powered by Netlify
|
||||
</a>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
</script>
|
||||
|
||||
<div class="bg-white rounded overflow-hidden shadow m-2 flex-grow flex flex-col">
|
||||
<div class="bg-indigo-400 border-gray-400 p-2 flex-none" on:click={() => (isOpen = !isOpen)}>
|
||||
<div
|
||||
class="bg-indigo-400 border-gray-400 p-2 flex-none cursor-pointer"
|
||||
on:click={() => (isOpen = !isOpen)}>
|
||||
<div class="flex justify-between">
|
||||
<Tabs on:select {tabs} bind:isOpen {title} {isCloseable} />
|
||||
<div class="flex gap-x-4 items-center text-white">
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
export let title: string;
|
||||
export let isOpen = false;
|
||||
|
||||
let activeTabID: string = tabs[0]?.id;
|
||||
$: activeTabID = tabs[0]?.id;
|
||||
|
||||
const dispatch = createEventDispatcher<TabEvents>();
|
||||
const toggleTabs = (tab: Tab) => {
|
||||
@@ -27,12 +27,12 @@
|
||||
{#each tabs as tab}
|
||||
<li class="mr-2 last:mr-0 w-28 h-6 flex-auto text-center">
|
||||
<div
|
||||
class="text cursor-pointer font-semibold min-w-16 w-auto px-2 py-1 -mb-4 rounded-t block leading-normal {activeTabID ===
|
||||
class="text cursor-pointer font-semibold min-w-16 w-auto px-2 py-1 -mb-4 rounded-t flex justify-center items-center leading-normal {activeTabID ===
|
||||
tab.id
|
||||
? 'text-indigo-500 bg-white border-white'
|
||||
: 'text-white bg-indigo-500 border-indigo-500 hover:bg-indigo-600'}"
|
||||
on:click|stopPropagation={() => toggleTabs(tab)}>
|
||||
<i class={tab.icon} />
|
||||
<i class="{tab.icon} mr-1" />
|
||||
{tab.title}
|
||||
</div>
|
||||
</li>
|
||||
|
||||
@@ -14,16 +14,15 @@
|
||||
export let editorOptions: monaco.editor.IStandaloneEditorConstructionOptions = {
|
||||
value: text,
|
||||
language: language,
|
||||
scrollBeyondLastLine: false,
|
||||
minimap: {
|
||||
enabled: false
|
||||
},
|
||||
theme: 'myCoolTheme',
|
||||
theme: 'mermaidTheme',
|
||||
overviewRulerLanes: 0
|
||||
};
|
||||
export let errorMarkers: monaco.editor.IMarkerData[] = [];
|
||||
let oldText = text;
|
||||
$: Monaco?.editor.setModelLanguage(editor.getModel(), language);
|
||||
$: editor && Monaco?.editor.setModelLanguage(editor.getModel(), language);
|
||||
$: {
|
||||
if (text !== oldText) {
|
||||
if ($codeStore.updateEditor) {
|
||||
@@ -31,7 +30,7 @@
|
||||
}
|
||||
oldText = text;
|
||||
}
|
||||
Monaco?.editor.setModelMarkers(editor.getModel(), 'test', errorMarkers);
|
||||
editor && Monaco?.editor.setModelMarkers(editor.getModel(), 'test', errorMarkers);
|
||||
}
|
||||
|
||||
const dispatch = createEventDispatcher<EditorEvents>();
|
||||
@@ -39,7 +38,7 @@
|
||||
let i = 0;
|
||||
while (i++ < 10) {
|
||||
try {
|
||||
//@ts-ignore : This is a hack to handle a svelte-kit error when importing monaco.
|
||||
// @ts-ignore : This is a hack to handle a svelte-kit error when importing monaco.
|
||||
Monaco = monaco;
|
||||
return;
|
||||
} catch {
|
||||
@@ -49,7 +48,12 @@
|
||||
alert('Loading Monaco Editor failed. Please try refreshing the page.');
|
||||
};
|
||||
onMount(async () => {
|
||||
await loadMonaco(); // Fix https://github.com/mermaid-js/mermaid-live-editor/issues/175
|
||||
try {
|
||||
// @ts-ignore : This is a hack to handle a svelte-kit error when importing monaco.
|
||||
Monaco = monaco;
|
||||
} catch {
|
||||
await loadMonaco(); // Fix https://github.com/mermaid-js/mermaid-live-editor/issues/175
|
||||
}
|
||||
initEditor(Monaco);
|
||||
editor = Monaco.editor.create(divEl, editorOptions);
|
||||
editor.onDidChangeModelContent(() => {
|
||||
|
||||
@@ -5,73 +5,536 @@
|
||||
export const initEditor = (monacoEditor): void => {
|
||||
monacoEditor.languages.register({ id: 'mermaid' });
|
||||
|
||||
// Register a tokens provider for the language
|
||||
monacoEditor.languages.setMonarchTokensProvider('mermaid', {
|
||||
typeKeywords: [
|
||||
'graph',
|
||||
'stateDiagram',
|
||||
'sequenceDiagram',
|
||||
'classDiagram',
|
||||
'pie',
|
||||
'erDiagram',
|
||||
'flowchart',
|
||||
'gantt',
|
||||
'gitGraph',
|
||||
'journey'
|
||||
],
|
||||
keywords: ['patricipant', 'as'],
|
||||
arrows: ['---', '===', '-->', '==>', '->>', '->'],
|
||||
tokenizer: {
|
||||
root: [
|
||||
[/[{}]/, 'delimiter.bracket'],
|
||||
[/[a-z_$][\w$]*/, { cases: { '@typeKeywords': 'keyword', '@keywords': 'keyword' } }],
|
||||
[/[-=>ox]+/, { cases: { '@arrows': 'transition' } }],
|
||||
[/[[{(}]+.+?[)\]}]+/, 'string'],
|
||||
[/".*"/, 'string']
|
||||
const requirementDiagrams = [
|
||||
'requirement',
|
||||
'functionalRequirement',
|
||||
'interfaceRequirement',
|
||||
'performanceRequirement',
|
||||
'physicalRequirement',
|
||||
'designConstraint'
|
||||
];
|
||||
|
||||
const keywords: {
|
||||
[key: string]: {
|
||||
typeKeywords: string[];
|
||||
blockKeywords: string[];
|
||||
keywords: string[];
|
||||
};
|
||||
} = {
|
||||
flowchart: {
|
||||
typeKeywords: ['flowchart', 'flowchart-v2', 'graph'],
|
||||
blockKeywords: ['subgraph', 'end'],
|
||||
keywords: [
|
||||
'TB',
|
||||
'TD',
|
||||
'BT',
|
||||
'RL',
|
||||
'LR',
|
||||
'click',
|
||||
'call',
|
||||
'href',
|
||||
'_self',
|
||||
'_blank',
|
||||
'_parent',
|
||||
'_top',
|
||||
'linkStyle',
|
||||
'style',
|
||||
'classDef',
|
||||
'class',
|
||||
'direction',
|
||||
'interpolate'
|
||||
]
|
||||
},
|
||||
whitespace: [
|
||||
[/[ \t\r\n]+/, 'white'],
|
||||
[/%%.*$/, 'comment']
|
||||
]
|
||||
sequenceDiagram: {
|
||||
typeKeywords: ['sequenceDiagram'],
|
||||
blockKeywords: ['alt', 'par', 'and', 'loop', 'else', 'end', 'rect', 'opt', 'alt', 'rect'],
|
||||
keywords: [
|
||||
'participant',
|
||||
'as',
|
||||
'Note',
|
||||
'note',
|
||||
'right of',
|
||||
'left of',
|
||||
'over',
|
||||
'activate',
|
||||
'deactivate',
|
||||
'autonumber',
|
||||
'title'
|
||||
]
|
||||
},
|
||||
classDiagram: {
|
||||
typeKeywords: ['classDiagram', 'classDiagram-v2'],
|
||||
blockKeywords: ['class'],
|
||||
keywords: [
|
||||
'link',
|
||||
'click',
|
||||
'callback',
|
||||
'call',
|
||||
'href',
|
||||
'cssClass',
|
||||
'direction',
|
||||
'TB',
|
||||
'BT',
|
||||
'RL',
|
||||
'LR'
|
||||
]
|
||||
},
|
||||
stateDiagram: {
|
||||
typeKeywords: ['stateDiagram', 'stateDiagram-v2'],
|
||||
blockKeywords: ['state', 'note', 'end'],
|
||||
keywords: ['state', 'as', 'hide empty description', 'direction', 'TB', 'BT', 'RL', 'LR']
|
||||
},
|
||||
erDiagram: {
|
||||
typeKeywords: ['erDiagram'],
|
||||
blockKeywords: [],
|
||||
keywords: []
|
||||
},
|
||||
journey: {
|
||||
typeKeywords: ['journey'],
|
||||
blockKeywords: ['section'],
|
||||
keywords: ['title']
|
||||
},
|
||||
info: {
|
||||
typeKeywords: ['info'],
|
||||
blockKeywords: [],
|
||||
keywords: ['showInfo']
|
||||
},
|
||||
gantt: {
|
||||
typeKeywords: ['gantt'],
|
||||
blockKeywords: [],
|
||||
keywords: [
|
||||
'title',
|
||||
'dateFormat',
|
||||
'axisFormat',
|
||||
'todayMarker',
|
||||
'section',
|
||||
'excludes',
|
||||
'inclusiveEndDates'
|
||||
]
|
||||
},
|
||||
requirementDiagram: {
|
||||
typeKeywords: ['requirement', 'requirementDiagram'],
|
||||
blockKeywords: requirementDiagrams.concat('element'),
|
||||
keywords: []
|
||||
},
|
||||
gitGraph: {
|
||||
typeKeywords: ['gitGraph'],
|
||||
blockKeywords: [],
|
||||
keywords: ['commit', 'branch', 'merge', 'reset', 'checkout', 'LR', 'BT']
|
||||
},
|
||||
pie: {
|
||||
typeKeywords: ['pie'],
|
||||
blockKeywords: [],
|
||||
keywords: ['title', 'showData']
|
||||
}
|
||||
};
|
||||
|
||||
// Register a tokens provider for the mermaid language
|
||||
monacoEditor.languages.setMonarchTokensProvider('mermaid', {
|
||||
...Object.entries(keywords)
|
||||
.map((entry) =>
|
||||
Object.fromEntries(
|
||||
Object.entries(entry[1]).map((deepEntry) => [
|
||||
entry[0] + deepEntry[0][0].toUpperCase() + deepEntry[0].slice(1),
|
||||
deepEntry[1]
|
||||
])
|
||||
)
|
||||
)
|
||||
.reduce((overallKeywords, nextKeyword) => ({ ...overallKeywords, ...nextKeyword }), {}),
|
||||
tokenizer: {
|
||||
root: [
|
||||
[/%%(?=.*%%$)/, { token: 'string', nextEmbedded: 'json' }],
|
||||
[/%%$/, { token: 'string', nextEmbedded: '@pop' }],
|
||||
[/^\s*gitGraph/m, 'typeKeyword', 'gitGraph'],
|
||||
[/^\s*info/m, 'typeKeyword', 'info'],
|
||||
[/^\s*pie/m, 'typeKeyword', 'pie'],
|
||||
[/^\s*(flowchart|flowchart-v2|graph)/m, 'typeKeyword', 'flowchart'],
|
||||
[/^\s*sequenceDiagram/, 'typeKeyword', 'sequenceDiagram'],
|
||||
[/^\s*classDiagram(-v2)?/, 'typeKeyword', 'classDiagram'],
|
||||
[/^\s*journey/, 'typeKeyword', 'journey'],
|
||||
[/^\s*gantt/, 'typeKeyword', 'gantt'],
|
||||
[/^\s*stateDiagram(-v2)?/, 'typeKeyword', 'stateDiagram'],
|
||||
[/^\s*erDiagram/, 'typeKeyword', 'erDiagram'],
|
||||
[/^\s*requirement(Diagram)?/, 'typeKeyword', 'requirementDiagram'],
|
||||
[/%%.*(?<!%%)$/, 'comment']
|
||||
],
|
||||
gitGraph: [
|
||||
[/option(?=s)/, { token: 'typeKeyword', next: 'optionsGitGraph' }],
|
||||
[/(^\s*branch|reset|merge|checkout)(.*$)/, ['keyword', 'variable']],
|
||||
[
|
||||
/[a-zA-Z][\w$]*/,
|
||||
{
|
||||
cases: {
|
||||
'@gitGraphBlockKeywords': 'typeKeyword',
|
||||
'@gitGraphKeywords': 'keyword'
|
||||
}
|
||||
}
|
||||
],
|
||||
[/%%.*(?<!%%)$/, 'comment'],
|
||||
[/".*?"/, 'string'],
|
||||
[/\^/, 'delimiter.bracket']
|
||||
],
|
||||
optionsGitGraph: [
|
||||
[/s$/, { token: 'typeKeyword', nextEmbedded: 'json', matchOnlyAtLineStart: false }],
|
||||
['end', { token: 'typeKeyword', next: '@pop', nextEmbedded: '@pop' }]
|
||||
],
|
||||
info: [
|
||||
[
|
||||
/[a-zA-Z][\w$]*/,
|
||||
{
|
||||
cases: {
|
||||
'@infoBlockKeywords': 'typeKeyword',
|
||||
'@infoKeywords': 'keyword'
|
||||
}
|
||||
}
|
||||
]
|
||||
],
|
||||
pie: [
|
||||
[/(title)(.*$)/, ['keyword', 'string']],
|
||||
[
|
||||
/[a-zA-Z][\w$]*/,
|
||||
{
|
||||
cases: {
|
||||
'@pieBlockKeywords': 'typeKeyword',
|
||||
'@pieKeywords': 'keyword'
|
||||
}
|
||||
}
|
||||
],
|
||||
[/".*?"/, 'string'],
|
||||
[/\s*\d+/, 'number'],
|
||||
[/:/, 'delimiter.bracket'],
|
||||
[/%%.*(?<!%%)$/, 'comment']
|
||||
],
|
||||
flowchart: [
|
||||
[/[ox]?(--+|==+)[ox]/, 'transition'],
|
||||
[
|
||||
/[a-zA-Z][\w$]*/,
|
||||
{
|
||||
cases: {
|
||||
'@flowchartBlockKeywords': 'typeKeyword',
|
||||
'@flowchartKeywords': 'keyword',
|
||||
'@default': 'variable'
|
||||
}
|
||||
}
|
||||
],
|
||||
[/\|+.+?\|+/, 'string'],
|
||||
[/\[+(\\.+?[\\/]|\/.+?[/\\])\]+/, 'string'],
|
||||
[/[[>]+[^\]|[]+?\]+/, 'string'],
|
||||
[/{+.+?}+/, 'string'],
|
||||
[/\(+.+?\)+/, 'string'],
|
||||
[/-\.+->?/, 'transition'],
|
||||
[/(-[-.])([^->]+?)(-{3,}|-{2,}>|\.-+>)/, ['transition', 'string', 'transition']],
|
||||
[/(==+)([^=]+?)(={3,}|={2,}>)/, ['transition', 'string', 'transition']],
|
||||
[/<?(--+|==+)>|===+|---+/, 'transition'],
|
||||
[/:::/, 'transition'],
|
||||
[/[;&]/, 'delimiter.bracket'],
|
||||
[/".*?"/, 'string'],
|
||||
[/%%.*(?<!%%)$/, 'comment']
|
||||
],
|
||||
sequenceDiagram: [
|
||||
[
|
||||
/[a-zA-Z][\w$]*/,
|
||||
{
|
||||
cases: {
|
||||
'@sequenceDiagramBlockKeywords': 'typeKeyword',
|
||||
'@sequenceDiagramKeywords': 'keyword',
|
||||
'@default': 'variable'
|
||||
}
|
||||
}
|
||||
],
|
||||
[/(--?>?>|--?[)x])[+-]?/, 'transition'],
|
||||
[/(:)([^:\n]*?$)/, ['delimiter.bracket', 'string']],
|
||||
[/%%.*(?<!%%)$/, 'comment']
|
||||
],
|
||||
classDiagram: [
|
||||
[/(?!class\s)([a-zA-Z]+)(\s+[a-zA-Z]+)/, ['type', 'variable']],
|
||||
[/(\*|<\|?|o)?(--|\.\.)(\*|\|?>|o)?/, 'transition'],
|
||||
[/^\s*class\s(?!.*\{)/, 'keyword'],
|
||||
[
|
||||
/[a-zA-Z][\w$]*/,
|
||||
{
|
||||
cases: {
|
||||
'@classDiagramBlockKeywords': 'typeKeyword',
|
||||
'@classDiagramKeywords': 'keyword',
|
||||
'@default': 'variable'
|
||||
}
|
||||
}
|
||||
],
|
||||
[/%%.*(?<!%%)$/, 'comment'],
|
||||
[/(<<)(.+?)(>>)/, ['delimiter.bracket', 'annotation', 'delimiter.bracket']],
|
||||
[/".*?"/, 'string'],
|
||||
[/:::/, 'transition'],
|
||||
[/:|\+|-|#|~|\*\s*$|\$\s*$|\(|\)|{|}/, 'delimiter.bracket']
|
||||
],
|
||||
journey: [
|
||||
[/(title)(.*)/, ['keyword', 'string']],
|
||||
[/(section)(.*)/, ['typeKeyword', 'string']],
|
||||
[
|
||||
/[a-zA-Z][\w$]*/,
|
||||
{
|
||||
cases: {
|
||||
'@journeyBlockKeywords': 'typeKeyword',
|
||||
'@journeyKeywords': 'keyword',
|
||||
'@default': 'variable'
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
/(^\s*.+?)(:)(.*?)(:)(.*?)([,$])/,
|
||||
[
|
||||
'string',
|
||||
'delimiter.bracket',
|
||||
'number',
|
||||
'delimiter.bracket',
|
||||
'variable',
|
||||
'delimiter.bracket'
|
||||
]
|
||||
],
|
||||
[/,/, 'delimiter.bracket'],
|
||||
[/(^\s*.+?)(:)([^:]*?)$/, ['string', 'delimiter.bracket', 'variable']],
|
||||
[/%%.*(?<!%%)$/, 'comment']
|
||||
],
|
||||
gantt: [
|
||||
[/(title)(.*)/, ['keyword', 'string']],
|
||||
[/(section)(.*)/, ['typeKeyword', 'string']],
|
||||
[
|
||||
/[a-zA-Z][\w$]*/,
|
||||
{
|
||||
cases: {
|
||||
'@ganttBlockKeywords': 'typeKeyword',
|
||||
'@ganttKeywords': 'keyword'
|
||||
}
|
||||
}
|
||||
],
|
||||
[/(^\s*.*?)(:)/, ['string', 'delimiter.bracket']],
|
||||
[/%%.*(?<!%%)$/, 'comment'],
|
||||
[/:/, 'delimiter.bracket']
|
||||
],
|
||||
stateDiagram: [
|
||||
[/note[^:]*$/, { token: 'typeKeyword', next: 'stateDiagramNote' }],
|
||||
['hide empty description', 'keyword'],
|
||||
[/^\s*state\s(?!.*\{)/, 'keyword'],
|
||||
[/(<<)(fork|join|choice)(>>)/, 'annotation'],
|
||||
[/(\[\[)(fork|join|choice)(]])/, ['delimiter.bracket', 'annotation', 'delimiter.bracket']],
|
||||
[
|
||||
/[a-zA-Z][\w$]*/,
|
||||
{
|
||||
cases: {
|
||||
'@stateDiagramBlockKeywords': 'typeKeyword',
|
||||
'@stateDiagramKeywords': 'keyword',
|
||||
'@default': 'variable'
|
||||
}
|
||||
}
|
||||
],
|
||||
[/".*?"/, 'string'],
|
||||
[/(:)([^:\n]*?$)/, ['delimiter.bracket', 'string']],
|
||||
[/{|}/, 'delimiter.bracket'],
|
||||
[/%%.*(?<!%%)$/, 'comment'],
|
||||
[/-->/, 'transition'],
|
||||
[/\[.*?]/, 'string']
|
||||
],
|
||||
stateDiagramNote: [
|
||||
[/^\s*end note$/, { token: 'typeKeyword', next: '@pop' }],
|
||||
[/.*/, 'string']
|
||||
],
|
||||
erDiagram: [
|
||||
[/[}|][o|](--|\.\.)[o|][{|]/, 'transition'],
|
||||
[/".*?"/, 'string'],
|
||||
[/(:)(.*?$)/, ['delimiter.bracket', 'string']],
|
||||
[/:|{|}/, 'delimiter.bracket'],
|
||||
[/([a-zA-Z]+)(\s+[a-zA-Z]+)/, ['type', 'variable']],
|
||||
[/%%.*(?<!%%)$/, 'comment'],
|
||||
[/[a-zA-Z_-][\w$]*/, 'variable']
|
||||
],
|
||||
requirementDiagram: [
|
||||
[/->|<-|-/, 'transition'],
|
||||
[/(\d+\.)*\d+/, 'number'],
|
||||
[
|
||||
/[a-zA-Z_-][\w$]*/,
|
||||
{
|
||||
cases: {
|
||||
'@requirementDiagramBlockKeywords': 'typeKeyword',
|
||||
'@default': 'variable'
|
||||
}
|
||||
}
|
||||
],
|
||||
[/:|{|}|\//, 'delimiter.bracket'],
|
||||
[/%%.*(?<!%%)$/, 'comment'],
|
||||
[/".*?"/, 'string']
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
monacoEditor.editor.defineTheme('myCoolTheme', {
|
||||
monacoEditor.editor.defineTheme('mermaidTheme', {
|
||||
base: 'vs',
|
||||
inherit: false,
|
||||
rules: [
|
||||
{ token: 'keyword', foreground: '880000', fontStyle: 'bold' },
|
||||
{ token: 'typeKeyword', foreground: '9650c8', fontStyle: 'bold' },
|
||||
{ token: 'keyword', foreground: '649696' },
|
||||
{ token: 'custom-error', foreground: 'ff0000', fontStyle: 'bold' },
|
||||
{ token: 'string', foreground: 'AA8500' },
|
||||
{ token: 'transition', foreground: '008800', fontStyle: 'bold' },
|
||||
{ token: 'delimiter.bracket', foreground: '000000', fontStyle: 'bold' }
|
||||
{ token: 'delimiter.bracket', foreground: '000000', fontStyle: 'bold' },
|
||||
{ token: 'annotation', foreground: '4b4b96' },
|
||||
{ token: 'number', foreground: '4b4b96' },
|
||||
{ token: 'comment', foreground: '888c89' },
|
||||
{ token: 'variable', foreground: 'A22889' },
|
||||
{ token: 'type', foreground: '2BDEA8' }
|
||||
]
|
||||
});
|
||||
|
||||
// Register a completion item provider for the new language
|
||||
// Register a completion item provider for the mermaid language
|
||||
monacoEditor.languages.registerCompletionItemProvider('mermaid', {
|
||||
provideCompletionItems: () => {
|
||||
const suggestions = [
|
||||
{
|
||||
label: 'simpleText',
|
||||
kind: monacoEditor.languages.CompletionItemKind.Text,
|
||||
insertText: 'simpleText'
|
||||
},
|
||||
{
|
||||
label: 'testing',
|
||||
kind: monacoEditor.languages.CompletionItemKind.Keyword,
|
||||
insertText: 'testing(${1:condition})',
|
||||
insertTextRules: monacoEditor.languages.CompletionItemInsertTextRule.InsertAsSnippet
|
||||
},
|
||||
{
|
||||
label: 'ifelse',
|
||||
label: 'loop',
|
||||
kind: monacoEditor.languages.CompletionItemKind.Snippet,
|
||||
insertText: ['if (${1:condition}) {', '\t$0', '} else {', '\t', '}'].join('\n'),
|
||||
insertText: ['loop ${1:Loop text}', '\t$0', 'end'].join('\n'),
|
||||
insertTextRules: monacoEditor.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'If-Else Statement'
|
||||
}
|
||||
documentation: 'Sequence Diagram Loops'
|
||||
},
|
||||
{
|
||||
label: 'alt',
|
||||
kind: monacoEditor.languages.CompletionItemKind.Snippet,
|
||||
insertText: ['alt ${1:Describing text}', '\t$0', 'else', '\t', 'end'].join('\n'),
|
||||
insertTextRules: monacoEditor.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'Alternative Path'
|
||||
},
|
||||
{
|
||||
label: 'opt',
|
||||
kind: monacoEditor.languages.CompletionItemKind.Snippet,
|
||||
insertText: ['opt ${1:Describing text}', '\t$0', 'end'].join('\n'),
|
||||
insertTextRules: monacoEditor.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'Optional Path'
|
||||
},
|
||||
{
|
||||
label: 'par',
|
||||
kind: monacoEditor.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'par ${1:[Action 1]}',
|
||||
'\t$0',
|
||||
'and ${2:[Action 2]}',
|
||||
'\t',
|
||||
'and ${3:[Action 3]}',
|
||||
'\t',
|
||||
'end'
|
||||
].join('\n'),
|
||||
insertTextRules: monacoEditor.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'Parallel Actions'
|
||||
},
|
||||
{
|
||||
label: 'rect',
|
||||
kind: monacoEditor.languages.CompletionItemKind.Snippet,
|
||||
insertText: ['rect ${1:rgb(0, 255, 0)}', '\t$0', 'end'].join('\n'),
|
||||
insertTextRules: monacoEditor.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'Background Color'
|
||||
},
|
||||
{
|
||||
label: 'subgraph',
|
||||
kind: monacoEditor.languages.CompletionItemKind.Snippet,
|
||||
insertText: ['subgraph ${1:title}', '\t$0', 'end'].join('\n'),
|
||||
insertTextRules: monacoEditor.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'Subgraph'
|
||||
},
|
||||
{
|
||||
label: 'class',
|
||||
kind: monacoEditor.languages.CompletionItemKind.Snippet,
|
||||
insertText: ['class ${1:className} {', '\t$0', '}'].join('\n'),
|
||||
insertTextRules: monacoEditor.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'Class'
|
||||
},
|
||||
{
|
||||
label: 'state',
|
||||
kind: monacoEditor.languages.CompletionItemKind.Snippet,
|
||||
insertText: ['state ${1:stateName} {', '\t$0', '}'].join('\n'),
|
||||
insertTextRules: monacoEditor.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'State'
|
||||
},
|
||||
{
|
||||
label: 'note',
|
||||
kind: monacoEditor.languages.CompletionItemKind.Snippet,
|
||||
insertText: ['note ${1:right of State1}', '\t$0', 'end note'].join('\n'),
|
||||
insertTextRules: monacoEditor.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'State'
|
||||
},
|
||||
{
|
||||
label: 'section',
|
||||
kind: monacoEditor.languages.CompletionItemKind.Snippet,
|
||||
insertText: ['section ${1:Go to work}', '\t$0'].join('\n'),
|
||||
insertTextRules: monacoEditor.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'User-journey Section'
|
||||
},
|
||||
{
|
||||
label: 'element',
|
||||
kind: monacoEditor.languages.CompletionItemKind.Snippet,
|
||||
insertText: ['element ${1:test_entity} {', '\t$0', '}'].join('\n'),
|
||||
insertTextRules: monacoEditor.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'User-journey Section'
|
||||
},
|
||||
{
|
||||
label: 'options',
|
||||
kind: monacoEditor.languages.CompletionItemKind.Snippet,
|
||||
insertText: ['options', '{', ' $0', '}', 'end'].join('\n'),
|
||||
insertTextRules: monacoEditor.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'Git Graph Options'
|
||||
},
|
||||
...requirementDiagrams.map((requirementDiagramType) => ({
|
||||
label: requirementDiagramType,
|
||||
kind: monacoEditor.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
requirementDiagramType + ' ${1:test_req} {',
|
||||
'\tid: 1',
|
||||
'\ttext: the test text.',
|
||||
'\trisk: high',
|
||||
'\tverifyMethod: test',
|
||||
'}'
|
||||
].join('\n'),
|
||||
insertTextRules: monacoEditor.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: requirementDiagramType
|
||||
.split(/(?=[A-Z])/)
|
||||
.map((part) => part[0].toUpperCase() + part.slice(1))
|
||||
.join(' ')
|
||||
})),
|
||||
...[
|
||||
...new Set(
|
||||
Object.values(keywords)
|
||||
.map((diagramKeywords) =>
|
||||
Object.entries(diagramKeywords)
|
||||
.filter((keywordType) => keywordType[0] !== 'annotations')
|
||||
.map((entry) => entry[1])
|
||||
)
|
||||
.flat(2)
|
||||
)
|
||||
].map((keyword) => ({
|
||||
label: keyword,
|
||||
kind: monacoEditor.languages.CompletionItemKind.Keyword,
|
||||
insertText: keyword
|
||||
}))
|
||||
];
|
||||
return { suggestions: suggestions };
|
||||
}
|
||||
});
|
||||
|
||||
monacoEditor.languages.setLanguageConfiguration('mermaid', {
|
||||
autoClosingPairs: [
|
||||
{
|
||||
open: '(',
|
||||
close: ')'
|
||||
},
|
||||
{
|
||||
open: '{',
|
||||
close: '}'
|
||||
},
|
||||
{
|
||||
open: '[',
|
||||
close: ']'
|
||||
}
|
||||
],
|
||||
brackets: [
|
||||
['(', ')'],
|
||||
['{', '}'],
|
||||
['[', ']']
|
||||
]
|
||||
});
|
||||
};
|
||||
|
||||
@@ -3,29 +3,30 @@
|
||||
import { codeStore, getStateString } from '$lib/util/state';
|
||||
import {
|
||||
addHistoryEntry,
|
||||
autoHistoryMode,
|
||||
historyModeStore,
|
||||
clearHistoryData,
|
||||
getPreviousState,
|
||||
historyStore
|
||||
historyStore,
|
||||
loaderHistoryStore
|
||||
} from './history';
|
||||
import { notify, prompt } from '$lib/util/notify';
|
||||
import { onMount } from 'svelte';
|
||||
import moment from 'moment';
|
||||
import type { State, Tab } from '$lib/types';
|
||||
import type { HistoryType, State, Tab } from '$lib/types';
|
||||
|
||||
const HISTORY_SAVE_INTERVAL = 60000;
|
||||
|
||||
const tabSelectHandler = (message: CustomEvent<Tab>) => {
|
||||
autoHistoryMode.set('timeline' === message.detail.id);
|
||||
historyModeStore.set(message.detail.id as HistoryType);
|
||||
};
|
||||
const tabs: Tab[] = [
|
||||
let tabs: Tab[] = [
|
||||
{
|
||||
id: 'saved',
|
||||
id: 'manual',
|
||||
title: 'Saved',
|
||||
icon: 'far fa-bookmark'
|
||||
},
|
||||
{
|
||||
id: 'timeline',
|
||||
id: 'auto',
|
||||
title: 'Timeline',
|
||||
icon: 'fas fa-history'
|
||||
}
|
||||
@@ -38,7 +39,7 @@
|
||||
addHistoryEntry({
|
||||
state: $codeStore,
|
||||
time: Date.now(),
|
||||
auto
|
||||
type: auto ? 'auto' : 'manual'
|
||||
});
|
||||
} else if (!auto) {
|
||||
notify('State already saved.');
|
||||
@@ -62,13 +63,27 @@
|
||||
};
|
||||
|
||||
onMount(() => {
|
||||
autoHistoryMode.set(false);
|
||||
historyModeStore.set('manual');
|
||||
setInterval(() => {
|
||||
saveHistory(true);
|
||||
}, HISTORY_SAVE_INTERVAL);
|
||||
});
|
||||
|
||||
let isOpen = true;
|
||||
loaderHistoryStore.subscribe((entries) => {
|
||||
if (entries.length > 0 && tabs.length === 2) {
|
||||
tabs = [
|
||||
{
|
||||
id: 'loader',
|
||||
title: 'Revisions',
|
||||
icon: 'fab fa-git-alt'
|
||||
},
|
||||
...tabs
|
||||
];
|
||||
historyModeStore.set('loader');
|
||||
}
|
||||
});
|
||||
|
||||
let isOpen = false;
|
||||
</script>
|
||||
|
||||
<Card on:select={tabSelectHandler} bind:isOpen {tabs} title="History">
|
||||
@@ -78,20 +93,30 @@
|
||||
class="btn"
|
||||
on:click|stopPropagation={() => saveHistory()}
|
||||
title="Save current state"><i class="far fa-save" /></button>
|
||||
<button
|
||||
id="clearHistory"
|
||||
class="btn text-red-400"
|
||||
on:click|stopPropagation={() => clearHistory()}
|
||||
title="Delete all saved states"><i class="fas fa-trash-alt" /></button>
|
||||
{#if $historyModeStore !== 'loader'}
|
||||
<button
|
||||
id="clearHistory"
|
||||
class="btn text-red-400"
|
||||
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">
|
||||
{#if $historyStore.length > 0}
|
||||
{#each $historyStore as { state, time, name }}
|
||||
{#each $historyStore as { state, time, name, url, type }}
|
||||
<li class="rounded p-2 shadow flex-col">
|
||||
<div class="flex">
|
||||
<div class="flex-1">
|
||||
<div class="flex flex-col">
|
||||
<span>{name}</span>
|
||||
{#if url}
|
||||
<a
|
||||
href={url}
|
||||
target="_blank"
|
||||
title="Open revision in new tab"
|
||||
class="hover:underline text-blue-500">{name}</a>
|
||||
{:else}
|
||||
<span>{name}</span>
|
||||
{/if}
|
||||
<span class="text-gray-400 text-sm">{relativeTime(time)}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -99,9 +124,11 @@
|
||||
<button
|
||||
class="rounded px-2 w-24 bg-green-200 hover:bg-green-300"
|
||||
on:click={() => restoreHistory(state)}><i class="fas fa-undo" /> Restore</button>
|
||||
<button
|
||||
class="rounded px-2 w-24 bg-red-200 hover:bg-red-300"
|
||||
on:click={() => clearHistory(time)}><i class="fas fa-trash-alt" /> Delete</button>
|
||||
{#if type !== 'loader'}
|
||||
<button
|
||||
class="rounded px-2 w-24 bg-red-200 hover:bg-red-300"
|
||||
on:click={() => clearHistory(time)}><i class="fas fa-trash-alt" /> Delete</button>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { derived, Readable, Writable, writable, get } from 'svelte/store';
|
||||
import { derived, writable, get } from 'svelte/store';
|
||||
import type { Readable, Writable } from 'svelte/store';
|
||||
import { persist, localStorage } from '@macfja/svelte-persistent-store';
|
||||
import { generateSlug } from 'random-word-slugs';
|
||||
import type { HistoryEntry } from '../../types';
|
||||
import type { HistoryEntry, HistoryType } from '$lib/types';
|
||||
|
||||
const MAX_AUTO_HISTORY_LENGTH = 30;
|
||||
|
||||
export const autoHistoryMode: Writable<boolean> = persist(
|
||||
writable(true),
|
||||
export const historyModeStore: Writable<HistoryType> = persist(
|
||||
writable('manual'),
|
||||
localStorage(),
|
||||
'autoHistoryMode'
|
||||
);
|
||||
@@ -23,17 +24,30 @@ const manualHistoryStore: Writable<HistoryEntry[]> = persist(
|
||||
'manualHistoryStore'
|
||||
);
|
||||
|
||||
export const loaderHistoryStore: Writable<HistoryEntry[]> = writable([] as HistoryEntry[]);
|
||||
|
||||
export const historyStore: Readable<HistoryEntry[]> = derived(
|
||||
[autoHistoryMode, autoHistoryStore, manualHistoryStore],
|
||||
([autoMode, autoHistories, manualHistories], set) => {
|
||||
set(autoMode ? autoHistories : manualHistories);
|
||||
[historyModeStore, autoHistoryStore, manualHistoryStore, loaderHistoryStore],
|
||||
([historyMode, autoHistories, manualHistories, loadedHistories], set) => {
|
||||
if (historyMode === 'auto') {
|
||||
set(autoHistories);
|
||||
} else if (historyMode === 'manual') {
|
||||
set(manualHistories);
|
||||
} else if (historyMode === 'loader') {
|
||||
set(loadedHistories);
|
||||
} else {
|
||||
set(autoHistories);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
export const addHistoryEntry = (entry: HistoryEntry): void => {
|
||||
if (entry.type === 'loader') {
|
||||
loaderHistoryStore.update((entries) => [entry, ...entries]);
|
||||
return;
|
||||
}
|
||||
entry.name = generateSlug(2);
|
||||
|
||||
if (!entry.auto) {
|
||||
if (entry.type !== 'auto') {
|
||||
manualHistoryStore.update((entries) => [entry, ...entries]);
|
||||
return;
|
||||
}
|
||||
@@ -46,9 +60,12 @@ export const addHistoryEntry = (entry: HistoryEntry): void => {
|
||||
};
|
||||
|
||||
export const clearHistoryData = (time?: number): void => {
|
||||
(get(autoHistoryMode) ? autoHistoryStore : manualHistoryStore).update((entries) =>
|
||||
entries.filter((entry) => time && entry.time != time)
|
||||
);
|
||||
(get(historyModeStore) === 'auto' ? autoHistoryStore : manualHistoryStore).update((entries) => {
|
||||
if (get(historyModeStore) !== 'loader') {
|
||||
entries = entries.filter((entry) => time && entry.time != time);
|
||||
}
|
||||
return entries;
|
||||
});
|
||||
};
|
||||
|
||||
export const getPreviousState = (auto: boolean): string => {
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 20 20"
|
||||
><title>menu</title><path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z" /></svg
|
||||
><title>Menu</title><path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z" /></svg
|
||||
></label>
|
||||
<input class="hidden" type="checkbox" id="menu-toggle" />
|
||||
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
|
||||
import { codeStore } from '$lib/util/state';
|
||||
import { onMount } from 'svelte';
|
||||
import type { Mermaid } from 'mermaid';
|
||||
import * as mermaid from 'mermaid';
|
||||
|
||||
const mermaid: Mermaid = (window.mermaid as unknown) as Mermaid;
|
||||
let code = '';
|
||||
let config = '';
|
||||
let container: HTMLDivElement;
|
||||
let error = false;
|
||||
let outOfSync = false;
|
||||
@@ -20,10 +20,13 @@
|
||||
}
|
||||
outOfSync = false;
|
||||
manualUpdate = true;
|
||||
// Replacing special characters '<' and '>' with encoded '<' and '>'
|
||||
code = state.code; //.replace(/</g, '<').replace(/>/g, '>');
|
||||
if (code === state.code && config === state.mermaid) {
|
||||
// Do not render if there is no change in Code/Config
|
||||
return;
|
||||
}
|
||||
code = state.code;
|
||||
config = state.mermaid;
|
||||
const scroll = container.parentElement.parentElement.parentElement.scrollTop;
|
||||
container.innerHTML = code;
|
||||
delete container.dataset.processed;
|
||||
mermaid.initialize(Object.assign({}, JSON.parse(state.mermaid)));
|
||||
mermaid.render('graph-div', code, (svgCode) => {
|
||||
|
||||
Vendored
+22
-1
@@ -29,11 +29,32 @@ export interface State {
|
||||
updateEditor: boolean;
|
||||
updateDiagram: boolean;
|
||||
autoSync: boolean;
|
||||
loader?: LoaderConfig;
|
||||
}
|
||||
|
||||
export interface GistLoaderConfig {
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface LoadingState {
|
||||
loading: boolean;
|
||||
message?: string;
|
||||
}
|
||||
export interface FileLoaderConfig {
|
||||
codeURL: string;
|
||||
configURL?: string;
|
||||
}
|
||||
export interface LoaderConfig {
|
||||
type: 'gist' | 'files';
|
||||
config: GistLoaderConfig | FileLoaderConfig;
|
||||
}
|
||||
export type HistoryType = 'auto' | 'manual' | 'loader';
|
||||
export interface HistoryEntry {
|
||||
state: State;
|
||||
time: number;
|
||||
name?: string;
|
||||
auto: boolean;
|
||||
type: HistoryType;
|
||||
url?: string;
|
||||
}
|
||||
|
||||
type Loader = (url: string) => Promise<State>;
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import type { State } from '$lib/types';
|
||||
import { defaultState } from '../state';
|
||||
import { addHistoryEntry } from '../../components/history/history';
|
||||
|
||||
const codeFileName = 'code.mmd';
|
||||
const configFileName = 'config.json';
|
||||
|
||||
const isValidGist = (files: any): boolean => {
|
||||
return codeFileName in files;
|
||||
};
|
||||
|
||||
const getFileContent = async (file: any): Promise<string> => {
|
||||
if (file.truncated) {
|
||||
return await (await fetch(file.raw_url)).text();
|
||||
}
|
||||
return file.content;
|
||||
};
|
||||
|
||||
interface GistData {
|
||||
code: string;
|
||||
config?: string;
|
||||
author: string;
|
||||
time: number;
|
||||
version: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
const getGistData = async (gistURL: string): Promise<GistData> => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const [_, __, gistID, revisionID] = gistURL.split('github.com').pop().split('/');
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const { html_url, files, history } = await (
|
||||
await fetch(`https://api.github.com/gists/${gistID}${revisionID ? '/' + revisionID : ''}`)
|
||||
).json();
|
||||
if (isValidGist(files)) {
|
||||
const code = await getFileContent(files[codeFileName]);
|
||||
let config: string;
|
||||
if (configFileName in files) {
|
||||
config = await getFileContent(files[configFileName]);
|
||||
}
|
||||
const currentItem = history[0];
|
||||
return {
|
||||
url: `${html_url}/${currentItem.version}`,
|
||||
code,
|
||||
config,
|
||||
author: currentItem.user.login,
|
||||
time: new Date(currentItem.committed_at).getTime(),
|
||||
version: (currentItem.version as string).slice(-7)
|
||||
};
|
||||
} else {
|
||||
throw 'Invalid gist provided';
|
||||
}
|
||||
};
|
||||
|
||||
const getStateFromGist = (gist: GistData, gistURL: string = gist.url): State => {
|
||||
const state: State = {
|
||||
...defaultState,
|
||||
code: gist.code,
|
||||
loader: {
|
||||
type: 'gist',
|
||||
config: {
|
||||
url: gistURL
|
||||
}
|
||||
}
|
||||
};
|
||||
gist.config && (state.mermaid = gist.config);
|
||||
return state;
|
||||
};
|
||||
|
||||
export const loadGistData = async (gistURL: string): Promise<State> => {
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const [_, __, gistID, revisionID] = gistURL.split('github.com').pop().split('/');
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const { history } = await (
|
||||
await fetch(`https://api.github.com/gists/${gistID}${revisionID ? '/' + revisionID : ''}`)
|
||||
).json();
|
||||
const gistHistory: GistData[] = [];
|
||||
for (const entry of history) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const data: GistData = await getGistData(entry.url).catch(() => undefined);
|
||||
data && gistHistory.push(data);
|
||||
}
|
||||
if (gistHistory.length === 0) {
|
||||
throw 'Invalid gist provided';
|
||||
}
|
||||
gistHistory.reverse();
|
||||
const state = getStateFromGist(gistHistory.slice(-1).pop(), gistURL);
|
||||
for (const gist of gistHistory) {
|
||||
addHistoryEntry({
|
||||
state: getStateFromGist(gist),
|
||||
time: gist.time,
|
||||
type: 'loader',
|
||||
url: gist.url,
|
||||
name: `${gist.author} v${gist.version}`
|
||||
});
|
||||
}
|
||||
return state;
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,58 @@
|
||||
import { loadGistData } from './gist';
|
||||
import { updateCodeStore, defaultState } from '../state';
|
||||
import type { Loader, State } from '$lib/types';
|
||||
const loaders: Record<string, Loader> = {
|
||||
gist: loadGistData
|
||||
};
|
||||
|
||||
export const loadDataFromUrl = async (): Promise<void> => {
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
let state: State = defaultState;
|
||||
let code: string, config: string;
|
||||
let loaded = false;
|
||||
const codeURL: string = searchParams.get('code');
|
||||
const configURL: string = searchParams.get('config');
|
||||
|
||||
if (codeURL) {
|
||||
code = await (await fetch(codeURL)).text();
|
||||
loaded = true;
|
||||
}
|
||||
if (configURL) {
|
||||
config = await (await fetch(configURL)).text();
|
||||
} else {
|
||||
config = defaultState.mermaid;
|
||||
}
|
||||
if (!code) {
|
||||
for (const [key, value] of searchParams.entries()) {
|
||||
if (key in loaders) {
|
||||
try {
|
||||
state = await loaders[key](value);
|
||||
loaded = true;
|
||||
break;
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
state = {
|
||||
code,
|
||||
mermaid: config,
|
||||
loader: {
|
||||
type: 'files',
|
||||
config: {
|
||||
codeURL,
|
||||
configURL
|
||||
}
|
||||
}
|
||||
} as State;
|
||||
}
|
||||
loaded &&
|
||||
updateCodeStore({
|
||||
...state,
|
||||
autoSync: true,
|
||||
updateDiagram: true,
|
||||
updateEditor: true
|
||||
});
|
||||
// window.location.search = '';
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
import { writable } from 'svelte/store';
|
||||
import type { Writable } from 'svelte/store';
|
||||
import type { LoadingState } from '$lib/types';
|
||||
|
||||
const defaultLoading: LoadingState = {
|
||||
loading: false
|
||||
};
|
||||
|
||||
export const loadingStateStore: Writable<LoadingState> = writable(defaultLoading);
|
||||
export const initLoading = async <T>(message: string, task: Promise<T>): Promise<T> => {
|
||||
loadingStateStore.set({
|
||||
loading: true,
|
||||
message
|
||||
});
|
||||
const result: T = await task;
|
||||
loadingStateStore.set({
|
||||
loading: false
|
||||
});
|
||||
return result;
|
||||
};
|
||||
+13
-3
@@ -4,7 +4,7 @@ import { persist, localStorage } from '@macfja/svelte-persistent-store';
|
||||
import type { State } from '$lib/types';
|
||||
import { saveStatistcs } from './stats';
|
||||
|
||||
const defaultState: State = {
|
||||
export const defaultState: State = {
|
||||
code: `graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
@@ -35,9 +35,19 @@ export const loadState = (data: string): void => {
|
||||
const stateStr = fromBase64(data);
|
||||
console.log(`Tring to load state: ${stateStr}`);
|
||||
state = JSON.parse(stateStr);
|
||||
if (typeof state.mermaid !== 'string') {
|
||||
state.mermaid = JSON.stringify(state.mermaid, null, 2);
|
||||
const mermaidConfig =
|
||||
typeof state.mermaid === 'string' ? JSON.parse(state.mermaid) : state.mermaid;
|
||||
if (
|
||||
mermaidConfig.securityLevel &&
|
||||
mermaidConfig.securityLevel !== 'strict' &&
|
||||
confirm(
|
||||
`Removing "securityLevel":"${mermaidConfig.securityLevel}" from the config for safety.\nClick Cancel if you trust the source of this Diagram.`
|
||||
)
|
||||
) {
|
||||
delete mermaidConfig.securityLevel; // Prevent setting overriding securityLevel when loading state to mitigate possible XSS attack
|
||||
}
|
||||
|
||||
state.mermaid = JSON.stringify(mermaidConfig, null, 2);
|
||||
} catch (e) {
|
||||
if (data) {
|
||||
console.error('Init error', e);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import type { State } from '$lib/types';
|
||||
import { initURLSubscription, loadState, updateCodeStore } from './state';
|
||||
import { analytics, initAnalytics } from './stats';
|
||||
import { loadDataFromUrl } from './fileLoaders/loader';
|
||||
import { initLoading } from './loading';
|
||||
|
||||
export const loadStateFromURL = (): void => {
|
||||
loadState(window.location.hash.slice(1));
|
||||
@@ -14,6 +16,7 @@ export const syncDiagram = (): void => {
|
||||
|
||||
export const initHandler = async (): Promise<void> => {
|
||||
loadStateFromURL();
|
||||
await initLoading('Loading Gist...', loadDataFromUrl().catch(console.error));
|
||||
syncDiagram();
|
||||
initURLSubscription();
|
||||
await initAnalytics();
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import '../app.postcss';
|
||||
import { base } from '$app/paths';
|
||||
import { onMount } from 'svelte';
|
||||
import { loadingStateStore } from '$lib/util/loading';
|
||||
// This can be removed once https://github.com/sveltejs/kit/issues/1612 is fixed.
|
||||
// Then move it into src and vite will bundle it automatically.
|
||||
onMount(() => {
|
||||
@@ -23,3 +24,44 @@
|
||||
<main class="h-screen">
|
||||
<slot />
|
||||
</main>
|
||||
|
||||
{#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">
|
||||
<div class="loader mx-auto" />
|
||||
<div>{$loadingStateStore.message}</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.loader {
|
||||
border: 0.45em solid #f3f3f3;
|
||||
border-radius: 50%;
|
||||
border-top: 0.45em solid #6365f1;
|
||||
width: 3em;
|
||||
height: 3em;
|
||||
-webkit-animation: spin 2s linear infinite; /* Safari */
|
||||
animation: spin 2s linear infinite;
|
||||
}
|
||||
|
||||
/* Safari */
|
||||
@-webkit-keyframes spin {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -10,13 +10,11 @@
|
||||
import { initHandler, syncDiagram } from '$lib/util/util';
|
||||
import { errorStore } from '$lib/util/error';
|
||||
import { onMount } from 'svelte';
|
||||
import * as mermaid from 'mermaid';
|
||||
import type monaco from 'monaco-editor';
|
||||
import type { Mermaid } from 'mermaid';
|
||||
import type { EditorUpdateEvent, State, Tab } from '$lib/types';
|
||||
import { base } from '$app/paths';
|
||||
|
||||
const mermaid: Mermaid = (window.mermaid as unknown) as Mermaid;
|
||||
|
||||
let selectedMode = 'code';
|
||||
const languageMap = {
|
||||
code: 'mermaid',
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
self.addEventListener('fetch', (e) => {});
|
||||
self.addEventListener('fetch', () => {});
|
||||
|
||||
+5
-3
@@ -10,20 +10,22 @@ const config = {
|
||||
postcss: true
|
||||
})
|
||||
],
|
||||
|
||||
kit: {
|
||||
adapter: adapter({
|
||||
pages: `docs${process.env['BETA'] ? '/beta' : ''}`
|
||||
}),
|
||||
paths: process.env['DEPLOY']
|
||||
? {
|
||||
base: `${process.env['BETA'] ? '/beta' : ''}/mermaid-live-editor`
|
||||
base: `/mermaid-live-editor${process.env['BETA'] ? '/beta' : ''}`
|
||||
}
|
||||
: {},
|
||||
ssr: false,
|
||||
// hydrate the <div id="svelte"> element in src/app.html
|
||||
target: '#svelte',
|
||||
trailingSlash: 'ignore'
|
||||
trailingSlash: 'ignore',
|
||||
vite: {
|
||||
optimizeDeps: { include: ['mermaid'] }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "node",
|
||||
"module": "es2020",
|
||||
"lib": ["es2020", "ESNext"],
|
||||
"lib": ["es2020", "ESNext", "DOM.Iterable"],
|
||||
"target": "es2019",
|
||||
/**
|
||||
svelte-preprocess cannot figure out whether you have a value or a type, so tell TypeScript
|
||||
|
||||
Reference in New Issue
Block a user