diff --git a/.github/lychee.toml b/.github/lychee.toml index c5a2f0e452..5f435fd37a 100644 --- a/.github/lychee.toml +++ b/.github/lychee.toml @@ -41,7 +41,10 @@ exclude = [ "https://bundlephobia.com", # Chrome webstore migration issue. Temporary -"https://chromewebstore.google.com" +"https://chromewebstore.google.com", + +# Drupal 403 +"https://www.drupal.org" ] # Exclude all private IPs from checking. diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 6477c9eb5c..a75bbf83d8 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -1,9 +1,3 @@ -# We use github cache to save snapshots between runs. -# For PRs and MergeQueues, the target commit is used, and for push events, github.event.previous is used. -# If a snapshot for a given Hash is not found, we checkout that commit, run the tests and cache the snapshots. -# These are then downloaded before running the E2E, providing the reference snapshots. -# If there are any errors, the diff image is uploaded to artifacts, and the user is notified. - name: E2E on: @@ -72,16 +66,6 @@ jobs: mkdir -p cypress/snapshots/stats/base mv stats cypress/snapshots/stats/base - - name: Cypress run - uses: cypress-io/github-action@v6 - id: cypress-snapshot-gen - if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }} - with: - install: false - start: pnpm run dev - wait-on: 'http://localhost:9000' - browser: chrome - e2e: runs-on: ubuntu-latest container: @@ -146,6 +130,10 @@ jobs: CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} VITEST_COVERAGE: true CYPRESS_COMMIT: ${{ github.sha }} + ARGOS_TOKEN: ${{ secrets.ARGOS_TOKEN }} + ARGOS_PARALLEL: ${{ secrets.CYPRESS_RECORD_KEY != '' }} + ARGOS_PARALLEL_TOTAL: 4 + ARGOS_PARALLEL_INDEX: ${{ matrix.containers }} - name: Upload Coverage to Codecov uses: codecov/codecov-action@v4 @@ -158,55 +146,3 @@ jobs: fail_ci_if_error: false verbose: true token: 6845cc80-77ee-4e17-85a1-026cd95e0766 - - # We upload the artifacts into numbered archives to prevent overwriting - - name: Upload Artifacts - uses: actions/upload-artifact@v4 - if: ${{ always() }} - with: - name: snapshots-${{ matrix.containers }} - retention-days: 1 - path: ./cypress/snapshots - - combineArtifacts: - needs: e2e - runs-on: ubuntu-latest - if: ${{ always() }} - steps: - # Download all snapshot artifacts and merge them into a single folder - - name: Download All Artifacts - uses: actions/download-artifact@v4 - with: - path: snapshots - pattern: snapshots-* - merge-multiple: true - - # For successful push events, we save the snapshots cache - - name: Save snapshots cache - id: cache-upload - if: ${{ github.event_name == 'push' && needs.e2e.result != 'failure' }} - uses: actions/cache/save@v4 - with: - path: ./snapshots - key: ${{ runner.os }}-snapshots-${{ github.event.after }} - - - name: Flatten images to a folder - if: ${{ needs.e2e.result == 'failure' }} - run: | - mkdir errors - cd snapshots - find . -mindepth 2 -type d -name "*__diff_output__*" -exec sh -c 'mv "$0"/*.png ../errors/' {} \; - - - name: Upload Error snapshots - if: ${{ needs.e2e.result == 'failure' }} - uses: actions/upload-artifact@v4 - id: upload-artifacts - with: - name: error-snapshots - retention-days: 10 - path: errors/ - - - name: Notify Users - if: ${{ needs.e2e.result == 'failure' }} - run: | - echo "::error title=Visual tests failed::You can view images that failed by downloading the error-snapshots artifact: ${{ steps.upload-artifacts.outputs.artifact-url }}" diff --git a/.gitignore b/.gitignore index a0fd1c50b8..7948faee49 100644 --- a/.gitignore +++ b/.gitignore @@ -48,6 +48,7 @@ demos/dev/** !/demos/dev/example.html !/demos/dev/reload.js tsx-0/** +vite.config.ts.timestamp-* # autogenereated by langium-cli -generated/ \ No newline at end of file +generated/ diff --git a/FUNDING.json b/FUNDING.json new file mode 100644 index 0000000000..a1df876f47 --- /dev/null +++ b/FUNDING.json @@ -0,0 +1,7 @@ +{ + "drips": { + "ethereum": { + "ownedBy": "0x0831DDFe60d009d9448CC976157b539089aB821E" + } + } +} diff --git a/README.md b/README.md index d368a43499..8d5eebfebe 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ Try Live Editor previews of future releases: diff --git a/cypress.config.ts b/cypress.config.ts index 4182d92a87..3346b5549b 100644 --- a/cypress.config.ts +++ b/cypress.config.ts @@ -2,6 +2,8 @@ import { defineConfig } from 'cypress'; import { addMatchImageSnapshotPlugin } from 'cypress-image-snapshot/plugin'; import coverage from '@cypress/code-coverage/task'; import eyesPlugin from '@applitools/eyes-cypress'; +import { registerArgosTask } from '@argos-ci/cypress/task'; + export default eyesPlugin( defineConfig({ projectId: 'n2sma2', @@ -17,10 +19,17 @@ export default eyesPlugin( } return launchOptions; }); - addMatchImageSnapshotPlugin(on, config); // copy any needed variables from process.env to config.env config.env.useAppli = process.env.USE_APPLI ? true : false; + config.env.useArgos = !!process.env.CI; + if (config.env.useArgos) { + registerArgosTask(on, config, { + token: 'fc3a35cf5200db928d65b2047861582d9444032b', + }); + } else { + addMatchImageSnapshotPlugin(on, config); + } // do not forget to return the changed config object! return config; }, diff --git a/cypress/helpers/util.ts b/cypress/helpers/util.ts index aed5d7973c..17bebeaef8 100644 --- a/cypress/helpers/util.ts +++ b/cypress/helpers/util.ts @@ -95,19 +95,8 @@ export const openURLAndVerifyRendering = ( options: CypressMermaidConfig, validation?: any ): void => { - const useAppli: boolean = Cypress.env('useAppli'); const name: string = (options.name || cy.state('runnable').fullTitle()).replace(/\s+/g, '-'); - if (useAppli) { - cy.log(`Opening eyes ${Cypress.spec.name} --- ${name}`); - cy.eyesOpen({ - appName: 'Mermaid', - testName: name, - batchName: Cypress.spec.name, - batchId: batchId + Cypress.spec.name, - }); - } - cy.visit(url); cy.window().should('have.property', 'rendered', true); cy.get('svg').should('be.visible'); @@ -116,11 +105,27 @@ export const openURLAndVerifyRendering = ( cy.get('svg').should(validation); } + verifyScreenshot(name); +}; + +export const verifyScreenshot = (name: string): void => { + const useAppli: boolean = Cypress.env('useAppli'); + const useArgos: boolean = Cypress.env('useArgos'); + if (useAppli) { + cy.log(`Opening eyes ${Cypress.spec.name} --- ${name}`); + cy.eyesOpen({ + appName: 'Mermaid', + testName: name, + batchName: Cypress.spec.name, + batchId: batchId + Cypress.spec.name, + }); cy.log(`Check eyes ${Cypress.spec.name}`); cy.eyesCheckWindow('Click!'); cy.log(`Closing eyes ${Cypress.spec.name}`); cy.eyesClose(); + } else if (useArgos) { + cy.argosScreenshot(name); } else { cy.matchImageSnapshot(name); } diff --git a/cypress/integration/other/configuration.spec.js b/cypress/integration/other/configuration.spec.js index 544eab40fb..ad6b21e298 100644 --- a/cypress/integration/other/configuration.spec.js +++ b/cypress/integration/other/configuration.spec.js @@ -1,4 +1,4 @@ -import { renderGraph } from '../../helpers/util.ts'; +import { renderGraph, verifyScreenshot } from '../../helpers/util.ts'; describe('Configuration', () => { describe('arrowMarkerAbsolute', () => { it('should handle default value false of arrowMarkerAbsolute', () => { @@ -119,8 +119,7 @@ describe('Configuration', () => { const url = 'http://localhost:9000/regression/issue-1874.html'; cy.visit(url); cy.window().should('have.property', 'rendered', true); - cy.get('svg').should('be.visible'); - cy.matchImageSnapshot( + verifyScreenshot( 'configuration.spec-should-not-taint-initial-configuration-when-using-multiple-directives' ); }); @@ -145,7 +144,7 @@ describe('Configuration', () => { // none of the diagrams should be error diagrams expect($svg).to.not.contain('Syntax error'); }); - cy.matchImageSnapshot( + verifyScreenshot( 'configuration.spec-should-not-render-error-diagram-if-suppressErrorRendering-is-set' ); }); @@ -162,7 +161,7 @@ describe('Configuration', () => { // some of the diagrams should be error diagrams expect($svg).to.contain('Syntax error'); }); - cy.matchImageSnapshot( + verifyScreenshot( 'configuration.spec-should-render-error-diagram-if-suppressErrorRendering-is-not-set' ); }); diff --git a/cypress/integration/other/xss.spec.js b/cypress/integration/other/xss.spec.js index 678040f98a..1e51d2f234 100644 --- a/cypress/integration/other/xss.spec.js +++ b/cypress/integration/other/xss.spec.js @@ -10,7 +10,6 @@ describe('XSS', () => { cy.wait(1000).then(() => { cy.get('.mermaid').should('exist'); }); - cy.get('svg'); }); it('should not allow tags in the css', () => { @@ -137,4 +136,9 @@ describe('XSS', () => { cy.wait(1000); cy.get('#the-malware').should('not.exist'); }); + it('should sanitize backticks block diagram labels properly', () => { + cy.visit('http://localhost:9000/xss25.html'); + cy.wait(1000); + cy.get('#the-malware').should('not.exist'); + }); }); diff --git a/cypress/integration/rendering/c4.spec.js b/cypress/integration/rendering/c4.spec.js index 59af6504b9..f699bd4298 100644 --- a/cypress/integration/rendering/c4.spec.js +++ b/cypress/integration/rendering/c4.spec.js @@ -30,7 +30,6 @@ describe('C4 diagram', () => { `, {} ); - cy.get('svg'); }); it('should render a simple C4Container diagram', () => { imgSnapshotTest( @@ -50,7 +49,6 @@ describe('C4 diagram', () => { `, {} ); - cy.get('svg'); }); it('should render a simple C4Component diagram', () => { imgSnapshotTest( @@ -69,7 +67,6 @@ describe('C4 diagram', () => { `, {} ); - cy.get('svg'); }); it('should render a simple C4Dynamic diagram', () => { imgSnapshotTest( @@ -93,7 +90,6 @@ describe('C4 diagram', () => { `, {} ); - cy.get('svg'); }); it('should render a simple C4Deployment diagram', () => { imgSnapshotTest( @@ -117,6 +113,5 @@ describe('C4 diagram', () => { `, {} ); - cy.get('svg'); }); }); diff --git a/cypress/integration/rendering/classDiagram.spec.js b/cypress/integration/rendering/classDiagram.spec.js index cab3649df4..a98a359edf 100644 --- a/cypress/integration/rendering/classDiagram.spec.js +++ b/cypress/integration/rendering/classDiagram.spec.js @@ -32,7 +32,6 @@ describe('Class diagram', () => { `, { logLevel: 1 } ); - cy.get('svg'); }); it('2: should render a simple class diagrams with cardinality', () => { @@ -61,7 +60,6 @@ describe('Class diagram', () => { `, {} ); - cy.get('svg'); }); it('3: should render a simple class diagram with different visibilities', () => { @@ -79,7 +77,6 @@ describe('Class diagram', () => { `, {} ); - cy.get('svg'); }); it('4: should render a simple class diagram with comments', () => { @@ -109,7 +106,6 @@ describe('Class diagram', () => { `, {} ); - cy.get('svg'); }); it('5: should render a simple class diagram with abstract method', () => { @@ -121,7 +117,6 @@ describe('Class diagram', () => { `, {} ); - cy.get('svg'); }); it('6: should render a simple class diagram with static method', () => { @@ -133,7 +128,6 @@ describe('Class diagram', () => { `, {} ); - cy.get('svg'); }); it('7: should render a simple class diagram with Generic class', () => { @@ -153,7 +147,6 @@ describe('Class diagram', () => { `, {} ); - cy.get('svg'); }); it('8: should render a simple class diagram with Generic class and relations', () => { @@ -174,7 +167,6 @@ describe('Class diagram', () => { `, {} ); - cy.get('svg'); }); it('9: should render a simple class diagram with clickable link', () => { @@ -196,7 +188,6 @@ describe('Class diagram', () => { `, {} ); - cy.get('svg'); }); it('10: should render a simple class diagram with clickable callback', () => { @@ -218,7 +209,6 @@ describe('Class diagram', () => { `, {} ); - cy.get('svg'); }); it('11: should render a simple class diagram with return type on method', () => { @@ -233,7 +223,6 @@ describe('Class diagram', () => { `, {} ); - cy.get('svg'); }); it('12: should render a simple class diagram with generic types', () => { @@ -249,7 +238,6 @@ describe('Class diagram', () => { `, {} ); - cy.get('svg'); }); it('13: should render a simple class diagram with css classes applied', () => { @@ -267,7 +255,6 @@ describe('Class diagram', () => { `, {} ); - cy.get('svg'); }); it('14: should render a simple class diagram with css classes applied directly', () => { @@ -283,7 +270,6 @@ describe('Class diagram', () => { `, {} ); - cy.get('svg'); }); it('15: should render a simple class diagram with css classes applied to multiple classes', () => { @@ -298,7 +284,6 @@ describe('Class diagram', () => { `, {} ); - cy.get('svg'); }); it('16: should render multiple class diagrams', () => { @@ -351,7 +336,6 @@ describe('Class diagram', () => { ], {} ); - cy.get('svg'); }); // it('17: should render a class diagram when useMaxWidth is true (default)', () => { @@ -421,7 +405,6 @@ describe('Class diagram', () => { `, { logLevel: 1 } ); - cy.get('svg'); }); it('should render class diagram with newlines in title', () => { @@ -439,7 +422,6 @@ describe('Class diagram', () => { +quack() } `); - cy.get('svg'); }); it('should render class diagram with many newlines in title', () => { diff --git a/cypress/integration/rendering/erDiagram.spec.js b/cypress/integration/rendering/erDiagram.spec.js index 578f5a3984..1a2340906a 100644 --- a/cypress/integration/rendering/erDiagram.spec.js +++ b/cypress/integration/rendering/erDiagram.spec.js @@ -218,7 +218,6 @@ describe('Entity Relationship Diagram', () => { `, { loglevel: 1 } ); - cy.get('svg'); }); it('should render entities with keys', () => { diff --git a/cypress/integration/rendering/quadrantChart.spec.js b/cypress/integration/rendering/quadrantChart.spec.js index 1be1f7deff..4830db6568 100644 --- a/cypress/integration/rendering/quadrantChart.spec.js +++ b/cypress/integration/rendering/quadrantChart.spec.js @@ -1,4 +1,4 @@ -import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts'; +import { imgSnapshotTest } from '../../helpers/util.ts'; describe('Quadrant Chart', () => { it('should render if only chart type is provided', () => { @@ -8,7 +8,6 @@ describe('Quadrant Chart', () => { `, {} ); - cy.get('svg'); }); it('should render a complete quadrant chart', () => { imgSnapshotTest( @@ -30,7 +29,6 @@ describe('Quadrant Chart', () => { `, {} ); - cy.get('svg'); }); it('should render without points', () => { imgSnapshotTest( @@ -46,7 +44,6 @@ describe('Quadrant Chart', () => { `, {} ); - cy.get('svg'); }); it('should able to render y-axix on right side', () => { imgSnapshotTest( @@ -63,7 +60,6 @@ describe('Quadrant Chart', () => { `, {} ); - cy.get('svg'); }); it('should able to render x-axix on bottom', () => { imgSnapshotTest( @@ -80,7 +76,6 @@ describe('Quadrant Chart', () => { `, {} ); - cy.get('svg'); }); it('should able to render x-axix on bottom and y-axis on right', () => { imgSnapshotTest( @@ -97,7 +92,6 @@ describe('Quadrant Chart', () => { `, {} ); - cy.get('svg'); }); it('should render without title', () => { imgSnapshotTest( @@ -112,7 +106,6 @@ describe('Quadrant Chart', () => { `, {} ); - cy.get('svg'); }); it('should use all the config', () => { imgSnapshotTest( @@ -135,7 +128,6 @@ describe('Quadrant Chart', () => { `, {} ); - cy.get('svg'); }); it('should use all the theme variable', () => { imgSnapshotTest( @@ -158,7 +150,6 @@ describe('Quadrant Chart', () => { `, {} ); - cy.get('svg'); }); it('should render x-axis labels in the center, if x-axis has two labels', () => { imgSnapshotTest( @@ -180,7 +171,6 @@ describe('Quadrant Chart', () => { `, {} ); - cy.get('svg'); }); it('should render y-axis labels in the center, if y-axis has two labels', () => { imgSnapshotTest( @@ -202,7 +192,6 @@ describe('Quadrant Chart', () => { `, {} ); - cy.get('svg'); }); it('should render both axes labels on the left and bottom, if both axes have only one label', () => { imgSnapshotTest( @@ -224,6 +213,52 @@ describe('Quadrant Chart', () => { `, {} ); - cy.get('svg'); + }); + + it('it should render data points with styles', () => { + imgSnapshotTest( + ` + quadrantChart + title Reach and engagement of campaigns + x-axis Reach --> + y-axis Engagement --> + quadrant-1 We should expand + quadrant-2 Need to promote + quadrant-3 Re-evaluate + quadrant-4 May be improved + Campaign A: [0.3, 0.6] radius: 20 + Campaign B: [0.45, 0.23] color: #ff0000 + Campaign C: [0.57, 0.69] stroke-color: #ff00ff + Campaign D: [0.78, 0.34] stroke-width: 3px + Campaign E: [0.40, 0.34] radius: 20, color: #ff0000 , stroke-color : #ff00ff, stroke-width : 3px + Campaign F: [0.35, 0.78] stroke-width: 3px , color: #ff0000, radius: 20, stroke-color: #ff00ff + Campaign G: [0.22, 0.22] stroke-width: 3px , color: #309708 , radius : 20 , stroke-color: #5060ff + Campaign H: [0.22, 0.44] + `, + {} + ); + }); + + it('it should render data points with styles + classes', () => { + imgSnapshotTest( + ` + quadrantChart + title Reach and engagement of campaigns + x-axis Reach --> + y-axis Engagement --> + quadrant-1 We should expand + quadrant-2 Need to promote + quadrant-3 Re-evaluate + quadrant-4 May be improved + Campaign A:::class1: [0.3, 0.6] radius: 20 + Campaign B: [0.45, 0.23] color: #ff0000 + Campaign C: [0.57, 0.69] stroke-color: #ff00ff + Campaign D:::class2: [0.78, 0.34] stroke-width: 3px + Campaign E:::class2: [0.40, 0.34] radius: 20, color: #ff0000, stroke-color: #ff00ff, stroke-width: 3px + Campaign F:::class1: [0.35, 0.78] + classDef class1 color: #908342, radius : 10, stroke-color: #310085, stroke-width: 10px + classDef class2 color: #f00fff, radius : 10 + ` + ); }); }); diff --git a/cypress/integration/rendering/requirement.spec.js b/cypress/integration/rendering/requirement.spec.js index f33ae7a0cb..3434418483 100644 --- a/cypress/integration/rendering/requirement.spec.js +++ b/cypress/integration/rendering/requirement.spec.js @@ -44,6 +44,5 @@ describe('Requirement diagram', () => { `, {} ); - cy.get('svg'); }); }); diff --git a/cypress/integration/rendering/sequencediagram.spec.js b/cypress/integration/rendering/sequencediagram.spec.js index 1285a0832d..7b4e98b4d5 100644 --- a/cypress/integration/rendering/sequencediagram.spec.js +++ b/cypress/integration/rendering/sequencediagram.spec.js @@ -1,4 +1,4 @@ -/// +// import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts'; @@ -68,6 +68,19 @@ context('Sequence diagram', () => { { sequence: { actorFontFamily: 'courier' } } ); }); + it('should render bidirectional arrows', () => { + imgSnapshotTest( + ` + sequenceDiagram + Alice<<->>John: Hello John, how are you? + Alice<<-->>John: Hi Alice, I can hear you! + John<<->>Alice: This also works the other way + John<<-->>Alice: Yes + Alice->John: Test + John->>Alice: Still works + ` + ); + }); it('should handle different line breaks', () => { imgSnapshotTest( ` @@ -464,6 +477,18 @@ context('Sequence diagram', () => { {} ); }); + it('should render notes over actors and participant', () => { + imgSnapshotTest( + ` + sequenceDiagram + actor Alice + participant Charlie + note over Alice: some note + note over Charlie: other note + `, + {} + ); + }); it('should render long messages from an actor to the left to one to the right', () => { imgSnapshotTest( ` diff --git a/cypress/integration/rendering/stateDiagram-v2.spec.js b/cypress/integration/rendering/stateDiagram-v2.spec.js index 9a1a27abe5..cb40aa8dc0 100644 --- a/cypress/integration/rendering/stateDiagram-v2.spec.js +++ b/cypress/integration/rendering/stateDiagram-v2.spec.js @@ -8,7 +8,6 @@ describe('State diagram', () => { `, { logLevel: 1, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render a simple state diagrams', () => { imgSnapshotTest( @@ -20,7 +19,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render a long descriptions instead of id when available', () => { imgSnapshotTest( @@ -32,7 +30,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render a long descriptions with additional descriptions', () => { imgSnapshotTest( @@ -44,7 +41,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render a single state with short descriptions', () => { imgSnapshotTest( @@ -55,7 +51,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render a transition descriptions with new lines', () => { imgSnapshotTest( @@ -69,7 +64,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render a state with a note', () => { imgSnapshotTest( @@ -83,7 +77,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render a state with on the left side when so specified', () => { imgSnapshotTest( @@ -97,7 +90,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render a state with a note together with another state', () => { imgSnapshotTest( @@ -113,7 +105,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render a note with multiple lines in it', () => { imgSnapshotTest( @@ -156,7 +147,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render a simple state diagrams 2', () => { imgSnapshotTest( @@ -169,7 +159,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render a simple state diagrams with labels', () => { imgSnapshotTest( @@ -185,7 +174,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render state descriptions', () => { imgSnapshotTest( @@ -198,7 +186,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render composite states', () => { imgSnapshotTest( @@ -217,7 +204,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render multiple composite states', () => { imgSnapshotTest( @@ -287,7 +273,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render concurrency states', () => { imgSnapshotTest( @@ -311,7 +296,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('v2 should render a state with states in it', () => { imgSnapshotTest( diff --git a/cypress/integration/rendering/stateDiagram.spec.js b/cypress/integration/rendering/stateDiagram.spec.js index 01e7a2b44e..9be1f23224 100644 --- a/cypress/integration/rendering/stateDiagram.spec.js +++ b/cypress/integration/rendering/stateDiagram.spec.js @@ -10,7 +10,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('should render a long descriptions instead of id when available', () => { imgSnapshotTest( @@ -22,7 +21,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('should render a long descriptions with additional descriptions', () => { imgSnapshotTest( @@ -34,7 +32,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('should render a single state with short descriptions', () => { imgSnapshotTest( @@ -45,7 +42,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('should render a transition descriptions with new lines', () => { imgSnapshotTest( @@ -59,7 +55,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('should render a state with a note', () => { imgSnapshotTest( @@ -73,7 +68,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('should render a state with on the left side when so specified', () => { imgSnapshotTest( @@ -87,7 +81,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('should render a state with a note together with another state', () => { imgSnapshotTest( @@ -103,7 +96,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('should render a note with multiple lines in it', () => { imgSnapshotTest( @@ -146,7 +138,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('should render a simple state diagrams 2', () => { imgSnapshotTest( @@ -159,7 +150,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('should render a simple state diagrams with labels', () => { imgSnapshotTest( @@ -175,7 +165,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('should render state descriptions', () => { imgSnapshotTest( @@ -188,7 +177,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('should render composite states', () => { imgSnapshotTest( @@ -207,7 +195,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('should render multiple composit states', () => { imgSnapshotTest( @@ -277,7 +264,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('should render concurrency states', () => { imgSnapshotTest( @@ -301,7 +287,6 @@ describe('State diagram', () => { `, { logLevel: 0, fontFamily: 'courier' } ); - cy.get('svg'); }); it('should render a state with states in it', () => { imgSnapshotTest( diff --git a/cypress/integration/rendering/theme.spec.js b/cypress/integration/rendering/theme.spec.js index c84ad0c4b7..1965f8c99b 100644 --- a/cypress/integration/rendering/theme.spec.js +++ b/cypress/integration/rendering/theme.spec.js @@ -10,7 +10,6 @@ describe('themeCSS balancing, it', () => { `, {} ); - cy.get('svg'); }); it('should not allow unbalanced CSS definitions 2', () => { imgSnapshotTest( @@ -21,7 +20,6 @@ describe('themeCSS balancing, it', () => { `, {} ); - cy.get('svg'); }); }); @@ -45,7 +43,6 @@ describe('Pie Chart', () => { `, { theme } ); - cy.get('svg'); }); it('should render a flowchart diagram', () => { imgSnapshotTest( @@ -70,7 +67,6 @@ describe('Pie Chart', () => { `, { theme } ); - cy.get('svg'); }); it('should render a new flowchart diagram', () => { imgSnapshotTest( @@ -96,7 +92,6 @@ describe('Pie Chart', () => { `, { theme } ); - cy.get('svg'); }); it('should render a sequence diagram', () => { imgSnapshotTest( @@ -125,7 +120,6 @@ describe('Pie Chart', () => { `, { theme } ); - cy.get('svg'); }); it('should render a class diagram', () => { @@ -175,7 +169,6 @@ describe('Pie Chart', () => { `, { theme } ); - cy.get('svg'); }); it('should render a state diagram', () => { imgSnapshotTest( @@ -210,7 +203,6 @@ stateDiagram `, { theme } ); - cy.get('svg'); }); it('should render a state diagram (v2)', () => { imgSnapshotTest( @@ -245,7 +237,6 @@ stateDiagram-v2 `, { theme } ); - cy.get('svg'); }); it('should render a er diagram', () => { imgSnapshotTest( @@ -266,7 +257,6 @@ erDiagram `, { theme } ); - cy.get('svg'); }); it('should render a user journey diagram', () => { imgSnapshotTest( @@ -287,7 +277,6 @@ erDiagram `, { theme } ); - cy.get('svg'); }); it('should render a gantt diagram', () => { cy.clock(new Date('2014-01-06').getTime()); @@ -326,7 +315,6 @@ erDiagram `, { theme } ); - cy.get('svg'); }); }); }); diff --git a/cypress/integration/rendering/xyChart.spec.js b/cypress/integration/rendering/xyChart.spec.js index 85d998c50b..94f11f5430 100644 --- a/cypress/integration/rendering/xyChart.spec.js +++ b/cypress/integration/rendering/xyChart.spec.js @@ -9,7 +9,6 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); it('Should render a complete chart', () => { imgSnapshotTest( @@ -35,7 +34,6 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); it('y-axis title not required', () => { imgSnapshotTest( @@ -48,7 +46,6 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); it('Should render a chart without y-axis with different range', () => { imgSnapshotTest( @@ -60,7 +57,6 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); it('x axis title not required', () => { imgSnapshotTest( @@ -72,7 +68,6 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); it('Multiple plots can be rendered', () => { imgSnapshotTest( @@ -87,7 +82,6 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); it('Decimals and negative numbers are supported', () => { imgSnapshotTest( @@ -98,7 +92,6 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); it('Render spark line with "plotReservedSpacePercent"', () => { imgSnapshotTest( @@ -116,7 +109,6 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); it('Render spark bar without displaying other property', () => { imgSnapshotTest( @@ -143,7 +135,6 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); it('Should use all the config from directive', () => { imgSnapshotTest( @@ -158,7 +149,6 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); it('Should use all the config from yaml', () => { imgSnapshotTest( @@ -199,7 +189,6 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); it('Render with show axis title false', () => { imgSnapshotTest( @@ -221,7 +210,6 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); it('Render with show axis label false', () => { imgSnapshotTest( @@ -243,7 +231,6 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); it('Render with show axis tick false', () => { imgSnapshotTest( @@ -265,7 +252,6 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); it('Render with show axis line false', () => { imgSnapshotTest( @@ -287,7 +273,6 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); it('Render all the theme color', () => { imgSnapshotTest( @@ -317,6 +302,5 @@ describe('XY Chart', () => { `, {} ); - cy.get('svg'); }); }); diff --git a/cypress/platform/xss25.html b/cypress/platform/xss25.html new file mode 100644 index 0000000000..251e1ec23f --- /dev/null +++ b/cypress/platform/xss25.html @@ -0,0 +1,108 @@ + + + + + + + + + + +
Security check
+
+
+
+
+ + + diff --git a/cypress/support/e2e.js b/cypress/support/e2e.js index ef985866e7..aa888465b9 100644 --- a/cypress/support/e2e.js +++ b/cypress/support/e2e.js @@ -15,6 +15,7 @@ import '@cypress/code-coverage/support'; import '@applitools/eyes-cypress/commands'; +import '@argos-ci/cypress/support'; // Import commands.js using ES2015 syntax: import './commands'; diff --git a/cypress/tsconfig.json b/cypress/tsconfig.json index baa9a72172..b01ce9bac1 100644 --- a/cypress/tsconfig.json +++ b/cypress/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "target": "es2020", "lib": ["es2020", "dom"], - "types": ["cypress", "node"], + "types": ["cypress", "node", "@argos-ci/cypress/dist/support.d.ts"], "allowImportingTsExtensions": true, "noEmit": true }, diff --git a/docker-compose.yml b/docker-compose.yml index d591073e8f..841f07ff9f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,3 @@ -version: '3.9' services: mermaid: build: @@ -8,7 +7,7 @@ services: tty: true working_dir: /mermaid mem_limit: '8G' - entrypoint: docker-entrypoint.sh + entrypoint: ./docker-entrypoint.sh environment: - NODE_OPTIONS=--max_old_space_size=8192 volumes: @@ -16,6 +15,7 @@ services: - root_cache:/root/.cache - root_local:/root/.local - root_npm:/root/.npm + - /tmp:/tmp ports: - 9000:9000 - 3333:3333 diff --git a/docs/community/contributing.md b/docs/community/contributing.md index 9cbff4814f..c78a3cb40f 100644 --- a/docs/community/contributing.md +++ b/docs/community/contributing.md @@ -56,7 +56,7 @@ The following commands must be sufficient enough to start with: ```bash curl -fsSL https://get.pnpm.io/install.sh | sh - -pnpm env use --global 18 +pnpm env use --global 20 ``` You may also need to reload `.shrc` or `.bashrc` afterwards. diff --git a/docs/config/img/mathMLDifferences.png b/docs/config/img/mathMLDifferences.png new file mode 100644 index 0000000000..6b7a86400f Binary files /dev/null and b/docs/config/img/mathMLDifferences.png differ diff --git a/docs/config/math.md b/docs/config/math.md index 1541585087..b2063e3af2 100644 --- a/docs/config/math.md +++ b/docs/config/math.md @@ -84,3 +84,13 @@ Example with legacy mode enabled (the latest version of KaTeX's stylesheet can b ``` + +## Handling Rendering Differences + +Due to differences between default fonts across operating systems and browser's MathML implementations, inconsistent results can be seen across platforms. If having consistent results are important, or the most optimal rendered results are desired, `forceLegacyMathML` can be enabled in the config. + +This option will always use KaTeX's stylesheet instead of only when MathML is not supported (as with `legacyMathML`). Note that only `forceLegacyMathML` needs to be set. + +If including KaTeX's stylesheet is not a concern, enabling this option is recommended to avoid scenarios where no MathML implementation within a browser provides the desired output (as seen below). + +![Image showing differences between Browsers](img/mathMLDifferences.png) diff --git a/docs/config/setup/interfaces/mermaidAPI.ParseOptions.md b/docs/config/setup/interfaces/mermaidAPI.ParseOptions.md index fa100744ed..c388a4f26f 100644 --- a/docs/config/setup/interfaces/mermaidAPI.ParseOptions.md +++ b/docs/config/setup/interfaces/mermaidAPI.ParseOptions.md @@ -19,4 +19,4 @@ The `parseError` function will not be called. #### Defined in -[mermaidAPI.ts:64](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L64) +[mermaidAPI.ts:65](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L65) diff --git a/docs/config/setup/interfaces/mermaidAPI.ParseResult.md b/docs/config/setup/interfaces/mermaidAPI.ParseResult.md index 9f912cc8c2..376f293462 100644 --- a/docs/config/setup/interfaces/mermaidAPI.ParseResult.md +++ b/docs/config/setup/interfaces/mermaidAPI.ParseResult.md @@ -18,4 +18,4 @@ The diagram type, e.g. 'flowchart', 'sequence', etc. #### Defined in -[mermaidAPI.ts:71](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L71) +[mermaidAPI.ts:72](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L72) diff --git a/docs/config/setup/interfaces/mermaidAPI.RenderResult.md b/docs/config/setup/interfaces/mermaidAPI.RenderResult.md index b5cc48038b..52ef3ec0cf 100644 --- a/docs/config/setup/interfaces/mermaidAPI.RenderResult.md +++ b/docs/config/setup/interfaces/mermaidAPI.RenderResult.md @@ -39,7 +39,7 @@ bindFunctions?.(div); // To call bindFunctions only if it's present. #### Defined in -[mermaidAPI.ts:94](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L94) +[mermaidAPI.ts:95](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L95) --- @@ -51,7 +51,7 @@ The diagram type, e.g. 'flowchart', 'sequence', etc. #### Defined in -[mermaidAPI.ts:84](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L84) +[mermaidAPI.ts:85](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L85) --- @@ -63,4 +63,4 @@ The svg code for the rendered graph. #### Defined in -[mermaidAPI.ts:80](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L80) +[mermaidAPI.ts:81](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L81) diff --git a/docs/config/setup/modules/mermaidAPI.md b/docs/config/setup/modules/mermaidAPI.md index 1a68b05bd0..d7bfe68efc 100644 --- a/docs/config/setup/modules/mermaidAPI.md +++ b/docs/config/setup/modules/mermaidAPI.md @@ -26,7 +26,7 @@ Renames and re-exports [mermaidAPI](mermaidAPI.md#mermaidapi) #### Defined in -[mermaidAPI.ts:74](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L74) +[mermaidAPI.ts:75](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L75) ## Variables @@ -98,7 +98,7 @@ mermaid.initialize(config); #### Defined in -[mermaidAPI.ts:635](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L635) +[mermaidAPI.ts:634](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L634) ## Functions @@ -129,7 +129,7 @@ Return the last node appended #### Defined in -[mermaidAPI.ts:277](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L277) +[mermaidAPI.ts:276](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L276) --- @@ -167,10 +167,10 @@ Create the user styles #### Parameters -| Name | Type | Description | -| :---------- | :------------------------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------ | -| `config` | `MermaidConfig` | configuration that has style and theme settings to use | -| `classDefs` | `undefined` \| `null` \| `Record`<`string`, `DiagramStyleClassDef`> | the classDefs in the diagram text. Might be null if none were defined. Usually is the result of a call to getClasses(...) | +| Name | Type | Description | +| :---------- | :--------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------ | +| `config` | `MermaidConfig` | configuration that has style and theme settings to use | +| `classDefs` | `undefined` \| `null` \| `Map`<`string`, `DiagramStyleClassDef`> | the classDefs in the diagram text. Might be null if none were defined. Usually is the result of a call to getClasses(...) | #### Returns @@ -180,7 +180,7 @@ the string with all the user styles #### Defined in -[mermaidAPI.ts:153](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L153) +[mermaidAPI.ts:154](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L154) --- @@ -190,12 +190,12 @@ the string with all the user styles #### Parameters -| Name | Type | -| :---------- | :-------------------------------------------------------- | -| `config` | `MermaidConfig` | -| `graphType` | `string` | -| `classDefs` | `undefined` \| `Record`<`string`, `DiagramStyleClassDef`> | -| `svgId` | `string` | +| Name | Type | +| :---------- | :----------------------------------------------------- | +| `config` | `MermaidConfig` | +| `graphType` | `string` | +| `classDefs` | `undefined` \| `Map`<`string`, `DiagramStyleClassDef`> | +| `svgId` | `string` | #### Returns @@ -230,7 +230,7 @@ with an enclosing block that has each of the cssClasses followed by !important; #### Defined in -[mermaidAPI.ts:138](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L138) +[mermaidAPI.ts:139](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L139) --- @@ -252,11 +252,10 @@ Put the svgCode into an iFrame. Return the iFrame code `string` - the code with the iFrame that now contains the svgCode - TODO replace btoa(). Replace with buf.toString('base64')? #### Defined in -[mermaidAPI.ts:254](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L254) +[mermaidAPI.ts:253](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L253) --- @@ -281,4 +280,4 @@ Remove any existing elements from the given document #### Defined in -[mermaidAPI.ts:327](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L327) +[mermaidAPI.ts:326](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L326) diff --git a/docs/ecosystem/integrations-community.md b/docs/ecosystem/integrations-community.md index 01a32ae435..b7dd757b73 100644 --- a/docs/ecosystem/integrations-community.md +++ b/docs/ecosystem/integrations-community.md @@ -240,6 +240,8 @@ Communication tools and platforms ### Other +- [Astro](https://astro.build/) + - [Adding diagrams to your Astro site with MermaidJS and Playwright](https://agramont.net/blog/diagraming-with-mermaidjs-astro/) - [Bisheng](https://www.npmjs.com/package/bisheng) - [bisheng-plugin-mermaid](https://github.com/yct21/bisheng-plugin-mermaid) - [Blazorade Mermaid: Render Mermaid diagrams in Blazor applications](https://github.com/Blazorade/Blazorade-Mermaid/wiki) @@ -249,6 +251,7 @@ Communication tools and platforms - [Jekyll](https://jekyllrb.com/) - [jekyll-mermaid](https://rubygems.org/gems/jekyll-mermaid) - [jekyll-mermaid-diagrams](https://github.com/fuzhibo/jekyll-mermaid-diagrams) +- [MarkChart: Preview Mermaid diagrams on macOS](https://markchart.app/) - [mermaid-isomorphic](https://github.com/remcohaszing/mermaid-isomorphic) - [mermaid-server: Generate diagrams using a HTTP request](https://github.com/TomWright/mermaid-server) - [NiceGUI: Let any browser be the frontend of your Python code](https://nicegui.io) ✅ diff --git a/docs/ecosystem/mermaid-chart.md b/docs/ecosystem/mermaid-chart.md index 07572d044f..f1ca85af0c 100644 --- a/docs/ecosystem/mermaid-chart.md +++ b/docs/ecosystem/mermaid-chart.md @@ -6,6 +6,10 @@ # Mermaid Chart +The Future of Diagramming & Visual Collaboration + +Try the Ultimate AI, Mermaid, and Visual Diagramming Suite by creating an account at [Mermaid Chart](https://www.mermaidchart.com/app/sign-up). +
Mermaid Chart - A smarter way to create diagrams | Product Hunt @@ -18,22 +22,26 @@ - **Editor** - A web based editor for creating and editing Mermaid diagrams. -- **Presentation** - A presentation mode for viewing Mermaid diagrams in a slideshow format. +- **Visual Editor** - The Visual Editor enables users of all skill levels to create diagrams easily and efficiently, with both GUI and code-based editing options. -- **Collaboration** - A web based collaboration feature for multi-user editing on Mermaid diagrams in real-time (Pro plan). +- **AI Chat** - Use our embedded AI Chat to generate diagrams from natural language descriptions. - **Plugins** - A plugin system for extending the functionality of Mermaid. - Plugins are available for: + Official Mermaid Chart plugins: - - [ChatGPT](https://docs.mermaidchart.com/plugins/chatgpt) + - [Mermaid Chart GPT](https://chat.openai.com/g/g-1IRFKwq4G-mermaid-chart) + - [Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=MermaidChart.vscode-mermaid-chart) - [JetBrains IDE](https://plugins.jetbrains.com/plugin/23043-mermaid-chart) - [Microsoft PowerPoint and Word](https://appsource.microsoft.com/en-us/product/office/WA200006214?tab=Overview) - - [Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=MermaidChart.vscode-mermaid-chart) -- **AI diagramming** - A feature for generating Mermaid diagrams from text using AI (Pro plan). + Visit our [Plugins](https://www.mermaidchart.com/plugins) page for more information. -- **More** - To learn more, visit our [Product](https://www.mermaidchart.com/product) page. +- **Collaboration** - A web based collaboration feature for multi-user editing on Mermaid diagrams in real-time (Pro and Enterprise plans). + +- **Comments** - Enhance collaboration by adding comments to diagrams. + +- **Presentations** - A presentation mode for viewing Mermaid diagrams in a slideshow format. ## Plans @@ -43,11 +51,9 @@ - **Enterprise** - A paid plan for enterprise use that includes all Pro features, and more. -## Access - -Sign up for a free account at [Mermaid Chart](https://www.mermaidchart.com/app/sign-up). +To learn more, visit our [Pricing](https://mermaidchart.com/pricing) page. -Mermaid Chart is currently offering a 14-day free trial of our newly-launched Pro tier. To learn more, visit our [Pricing](https://mermaidchart.com/pricing) page. +Mermaid Chart is currently offering a 14-day free trial on our Pro and Enterprise tiers. Sign up for a free account at [Mermaid Chart](https://www.mermaidchart.com/app/sign-up). ## Mermaid JS contributions diff --git a/docs/intro/getting-started.md b/docs/intro/getting-started.md index 7358596445..a626d1f538 100644 --- a/docs/intro/getting-started.md +++ b/docs/intro/getting-started.md @@ -157,7 +157,7 @@ For a list of Mermaid Plugins and Integrations, visit the [Integrations page](.. Mermaid Chart plugins are available for: -- [ChatGPT](https://docs.mermaidchart.com/plugins/chatgpt) +- [ChatGPT](https://docs.mermaidchart.com/plugins/mermaid-chart-gpt) - [JetBrains IDE](https://docs.mermaidchart.com/plugins/jetbrains-ide) - [Microsoft PowerPoint](https://docs.mermaidchart.com/plugins/microsoft-powerpoint) - [Microsoft Word](https://docs.mermaidchart.com/plugins/microsoft-word) diff --git a/docs/news/blog.md b/docs/news/blog.md index d88c9ed236..65fa9246e6 100644 --- a/docs/news/blog.md +++ b/docs/news/blog.md @@ -6,6 +6,18 @@ # Blog +## [How to Choose the Right Documentation Software](https://www.mermaidchart.com/blog/posts/how-to-choose-the-right-documentation-software/) + +7 May 2024 · 5 mins + +How to Choose the Right Documentation Software. Reliable and efficient documentation software is crucial in the fast-paced world of software development. + +## [AI in software diagramming: What trends will define the future?](https://www.mermaidchart.com/blog/posts/ai-in-software-diagramming/) + +24 April 2024 · 5 mins + +Artificial intelligence (AI) tools are changing the way developers work. + ## [Mermaid Chart Unveils Visual Editor for Sequence Diagrams](https://www.mermaidchart.com/blog/posts/mermaid-chart-unveils-visual-editor-for-sequence-diagrams/) 8 April 2024 · 5 mins diff --git a/docs/syntax/flowchart.md b/docs/syntax/flowchart.md index 8edb5e208d..7efc5497b6 100644 --- a/docs/syntax/flowchart.md +++ b/docs/syntax/flowchart.md @@ -881,7 +881,7 @@ Examples of tooltip usage below: ```html @@ -913,7 +913,7 @@ flowchart LR > **Success** The tooltip functionality and the ability to link to urls are available from version 0.5.2. -?> Due to limitations with how Docsify handles JavaScript callback functions, an alternate working demo for the above code can be viewed at [this jsfiddle](https://jsfiddle.net/Ogglas/2o73vdez/7). +?> Due to limitations with how Docsify handles JavaScript callback functions, an alternate working demo for the above code can be viewed at [this jsfiddle](https://jsfiddle.net/yk4h7qou/2/). Links are opened in the same browser tab/window by default. It is possible to change this by adding a link target to the click definition (`_self`, `_blank`, `_parent` and `_top` are supported): @@ -957,7 +957,7 @@ Beginner's tip—a full example using interactive links in a html context: ' ); let states = stateDb.getStates(); - expect(states[testStateId].descriptions[0]).toEqual('desc outside the script '); + expect(states.get(testStateId).descriptions[0]).toEqual('desc outside the script '); }); it('adds the description to the state with the given id', () => { stateDb.addDescription(testStateId, 'the description'); let states = stateDb.getStates(); - expect(states[testStateId].descriptions[0]).toEqual('the description'); + expect(states.get(testStateId).descriptions[0]).toEqual('the description'); }); }); }); diff --git a/packages/mermaid/src/diagrams/state/stateDiagram-v2.spec.js b/packages/mermaid/src/diagrams/state/stateDiagram-v2.spec.js index c387ff7b3d..53063f41a1 100644 --- a/packages/mermaid/src/diagrams/state/stateDiagram-v2.spec.js +++ b/packages/mermaid/src/diagrams/state/stateDiagram-v2.spec.js @@ -405,7 +405,7 @@ describe('state diagram V2, ', function () { stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2()); const states = stateDb.getStates(); - expect(states['Active'].doc[0].id).toEqual('Idle'); + expect(states.get('Active').doc[0].id).toEqual('Idle'); const rels = stateDb.getRelations(); const rel_Inactive_Idle = rels.find((rel) => rel.id1 === 'Inactive' && rel.id2 === 'Idle'); diff --git a/packages/mermaid/src/diagrams/state/stateRenderer-v2.js b/packages/mermaid/src/diagrams/state/stateRenderer-v2.js index 482e37caee..0ecc0a73af 100644 --- a/packages/mermaid/src/diagrams/state/stateRenderer-v2.js +++ b/packages/mermaid/src/diagrams/state/stateRenderer-v2.js @@ -5,7 +5,7 @@ import { render } from '../../dagre-wrapper/index.js'; import { log } from '../../logger.js'; import { configureSvgSize } from '../../setupGraphViewbox.js'; import common from '../common/common.js'; -import utils from '../../utils.js'; +import utils, { getEdgeId } from '../../utils.js'; import { DEFAULT_DIAGRAM_DIRECTION, @@ -81,7 +81,7 @@ export const setConf = function (cnf) { * * @param {string} text - the diagram text to be parsed * @param diagramObj - * @returns {Record} ClassDef styles (a Map with keys = strings, values = ) + * @returns {Map} ClassDef styles (a Map with keys = strings, values = ) */ export const getClasses = function (text, diagramObj) { diagramObj.db.extract(diagramObj.db.getRootDocV2()); @@ -129,13 +129,13 @@ export function stateDomId(itemId = '', counter = 0, type = '', typeSpacer = DOM * @param g - graph * @param {object} parent * @param {object} parsedItem - parsed statement item - * @param {object[]} diagramStates - the list of all known states for the diagram + * @param {Map} diagramStates - the list of all known states for the diagram * @param {object} diagramDb * @param {boolean} altFlag - for clusters, add the "statediagram-cluster-alt" CSS class */ const setupNode = (g, parent, parsedItem, diagramStates, diagramDb, altFlag) => { const itemId = parsedItem.id; - const classStr = getClassesFromDbInfo(diagramStates[itemId]); + const classStr = getClassesFromDbInfo(diagramStates.get(itemId)); if (itemId !== 'root') { let shape = SHAPE_STATE; @@ -252,7 +252,6 @@ const setupNode = (g, parent, parsedItem, diagramStates, diagramDb, altFlag) => type: 'group', padding: 0, //getConfig().flowchart.padding }; - graphItemCount++; const parentNodeId = itemId + PARENT_ID; g.setNode(parentNodeId, groupData); @@ -270,17 +269,23 @@ const setupNode = (g, parent, parsedItem, diagramStates, diagramDb, altFlag) => from = noteData.id; to = itemId; } + g.setEdge(from, to, { arrowhead: 'none', arrowType: '', style: G_EDGE_STYLE, labelStyle: '', + id: getEdgeId(from, to, { + counter: graphItemCount, + }), classes: CSS_EDGE_NOTE_EDGE, arrowheadStyle: G_EDGE_ARROWHEADSTYLE, labelpos: G_EDGE_LABELPOS, labelType: G_EDGE_LABELTYPE, thickness: G_EDGE_THICKNESS, }); + + graphItemCount++; } else { g.setNode(itemId, nodeData); } @@ -303,7 +308,7 @@ const setupNode = (g, parent, parsedItem, diagramStates, diagramDb, altFlag) => * @param g * @param parentParsedItem - parsed Item that is the parent of this document (doc) * @param doc - the document to set up; it is a list of parsed statements - * @param {object[]} diagramStates - the list of all known states for the diagram + * @param {Map} diagramStates - the list of all known states for the diagram * @param diagramDb * @param {boolean} altFlag * @todo This duplicates some of what is done in stateDb.js extract method @@ -324,7 +329,9 @@ const setupDoc = (g, parentParsedItem, doc, diagramStates, diagramDb, altFlag) = setupNode(g, parentParsedItem, item.state1, diagramStates, diagramDb, altFlag); setupNode(g, parentParsedItem, item.state2, diagramStates, diagramDb, altFlag); const edgeData = { - id: 'edge' + graphItemCount, + id: getEdgeId(item.state1.id, item.state2.id, { + counter: graphItemCount, + }), arrowhead: 'normal', arrowTypeEnd: 'arrow_barb', style: G_EDGE_STYLE, diff --git a/packages/mermaid/src/docs/.vitepress/config.ts b/packages/mermaid/src/docs/.vitepress/config.ts index d937daf634..a59b02688c 100644 --- a/packages/mermaid/src/docs/.vitepress/config.ts +++ b/packages/mermaid/src/docs/.vitepress/config.ts @@ -150,9 +150,9 @@ function sidebarSyntax() { { text: 'C4 Diagram 🦺⚠️', link: '/syntax/c4' }, { text: 'Mindmaps', link: '/syntax/mindmap' }, { text: 'Timeline', link: '/syntax/timeline' }, - { text: 'Zenuml', link: '/syntax/zenuml' }, + { text: 'ZenUML', link: '/syntax/zenuml' }, { text: 'Sankey 🔥', link: '/syntax/sankey' }, - { text: 'XYChart 🔥', link: '/syntax/xyChart' }, + { text: 'XY Chart 🔥', link: '/syntax/xyChart' }, { text: 'Block Diagram 🔥', link: '/syntax/block' }, { text: 'Packet 🔥', link: '/syntax/packet' }, { text: 'Other Examples', link: '/syntax/examples' }, diff --git a/packages/mermaid/src/docs/community/contributing.md b/packages/mermaid/src/docs/community/contributing.md index 195146a612..71048d0952 100644 --- a/packages/mermaid/src/docs/community/contributing.md +++ b/packages/mermaid/src/docs/community/contributing.md @@ -52,7 +52,7 @@ The following commands must be sufficient enough to start with: ```bash curl -fsSL https://get.pnpm.io/install.sh | sh - -pnpm env use --global 18 +pnpm env use --global 20 ``` You may also need to reload `.shrc` or `.bashrc` afterwards. diff --git a/packages/mermaid/src/docs/config/img/mathMLDifferences.png b/packages/mermaid/src/docs/config/img/mathMLDifferences.png new file mode 100644 index 0000000000..6b7a86400f Binary files /dev/null and b/packages/mermaid/src/docs/config/img/mathMLDifferences.png differ diff --git a/packages/mermaid/src/docs/config/math.md b/packages/mermaid/src/docs/config/math.md index 22b398e087..a53dceaf2a 100644 --- a/packages/mermaid/src/docs/config/math.md +++ b/packages/mermaid/src/docs/config/math.md @@ -60,3 +60,13 @@ Example with legacy mode enabled (the latest version of KaTeX's stylesheet can b ``` + +## Handling Rendering Differences + +Due to differences between default fonts across operating systems and browser's MathML implementations, inconsistent results can be seen across platforms. If having consistent results are important, or the most optimal rendered results are desired, `forceLegacyMathML` can be enabled in the config. + +This option will always use KaTeX's stylesheet instead of only when MathML is not supported (as with `legacyMathML`). Note that only `forceLegacyMathML` needs to be set. + +If including KaTeX's stylesheet is not a concern, enabling this option is recommended to avoid scenarios where no MathML implementation within a browser provides the desired output (as seen below). + +![Image showing differences between Browsers](img/mathMLDifferences.png) diff --git a/packages/mermaid/src/docs/ecosystem/integrations-community.md b/packages/mermaid/src/docs/ecosystem/integrations-community.md index 95e71d626d..54968471f9 100644 --- a/packages/mermaid/src/docs/ecosystem/integrations-community.md +++ b/packages/mermaid/src/docs/ecosystem/integrations-community.md @@ -235,6 +235,8 @@ Communication tools and platforms ### Other +- [Astro](https://astro.build/) + - [Adding diagrams to your Astro site with MermaidJS and Playwright](https://agramont.net/blog/diagraming-with-mermaidjs-astro/) - [Bisheng](https://www.npmjs.com/package/bisheng) - [bisheng-plugin-mermaid](https://github.com/yct21/bisheng-plugin-mermaid) - [Blazorade Mermaid: Render Mermaid diagrams in Blazor applications](https://github.com/Blazorade/Blazorade-Mermaid/wiki) @@ -244,6 +246,7 @@ Communication tools and platforms - [Jekyll](https://jekyllrb.com/) - [jekyll-mermaid](https://rubygems.org/gems/jekyll-mermaid) - [jekyll-mermaid-diagrams](https://github.com/fuzhibo/jekyll-mermaid-diagrams) +- [MarkChart: Preview Mermaid diagrams on macOS](https://markchart.app/) - [mermaid-isomorphic](https://github.com/remcohaszing/mermaid-isomorphic) - [mermaid-server: Generate diagrams using a HTTP request](https://github.com/TomWright/mermaid-server) - [NiceGUI: Let any browser be the frontend of your Python code](https://nicegui.io) ✅ diff --git a/packages/mermaid/src/docs/ecosystem/mermaid-chart.md b/packages/mermaid/src/docs/ecosystem/mermaid-chart.md index 94b6773e4b..732b9b68cd 100644 --- a/packages/mermaid/src/docs/ecosystem/mermaid-chart.md +++ b/packages/mermaid/src/docs/ecosystem/mermaid-chart.md @@ -1,5 +1,9 @@ # Mermaid Chart +The Future of Diagramming & Visual Collaboration + +Try the Ultimate AI, Mermaid, and Visual Diagramming Suite by creating an account at [Mermaid Chart](https://www.mermaidchart.com/app/sign-up). +
Mermaid Chart - A smarter way to create diagrams | Product Hunt @@ -12,22 +16,26 @@ - **Editor** - A web based editor for creating and editing Mermaid diagrams. -- **Presentation** - A presentation mode for viewing Mermaid diagrams in a slideshow format. +- **Visual Editor** - The Visual Editor enables users of all skill levels to create diagrams easily and efficiently, with both GUI and code-based editing options. -- **Collaboration** - A web based collaboration feature for multi-user editing on Mermaid diagrams in real-time (Pro plan). +- **AI Chat** - Use our embedded AI Chat to generate diagrams from natural language descriptions. - **Plugins** - A plugin system for extending the functionality of Mermaid. - Plugins are available for: + Official Mermaid Chart plugins: - - [ChatGPT](https://docs.mermaidchart.com/plugins/chatgpt) + - [Mermaid Chart GPT](https://chat.openai.com/g/g-1IRFKwq4G-mermaid-chart) + - [Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=MermaidChart.vscode-mermaid-chart) - [JetBrains IDE](https://plugins.jetbrains.com/plugin/23043-mermaid-chart) - [Microsoft PowerPoint and Word](https://appsource.microsoft.com/en-us/product/office/WA200006214?tab=Overview) - - [Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=MermaidChart.vscode-mermaid-chart) -- **AI diagramming** - A feature for generating Mermaid diagrams from text using AI (Pro plan). + Visit our [Plugins](https://www.mermaidchart.com/plugins) page for more information. -- **More** - To learn more, visit our [Product](https://www.mermaidchart.com/product) page. +- **Collaboration** - A web based collaboration feature for multi-user editing on Mermaid diagrams in real-time (Pro and Enterprise plans). + +- **Comments** - Enhance collaboration by adding comments to diagrams. + +- **Presentations** - A presentation mode for viewing Mermaid diagrams in a slideshow format. ## Plans @@ -37,11 +45,9 @@ - **Enterprise** - A paid plan for enterprise use that includes all Pro features, and more. -## Access - -Sign up for a free account at [Mermaid Chart](https://www.mermaidchart.com/app/sign-up). +To learn more, visit our [Pricing](https://mermaidchart.com/pricing) page. -Mermaid Chart is currently offering a 14-day free trial of our newly-launched Pro tier. To learn more, visit our [Pricing](https://mermaidchart.com/pricing) page. +Mermaid Chart is currently offering a 14-day free trial on our Pro and Enterprise tiers. Sign up for a free account at [Mermaid Chart](https://www.mermaidchart.com/app/sign-up). ## Mermaid JS contributions diff --git a/packages/mermaid/src/docs/intro/getting-started.md b/packages/mermaid/src/docs/intro/getting-started.md index 2bfa36bb74..574881c4fd 100644 --- a/packages/mermaid/src/docs/intro/getting-started.md +++ b/packages/mermaid/src/docs/intro/getting-started.md @@ -146,7 +146,7 @@ For a list of Mermaid Plugins and Integrations, visit the [Integrations page](.. Mermaid Chart plugins are available for: -- [ChatGPT](https://docs.mermaidchart.com/plugins/chatgpt) +- [ChatGPT](https://docs.mermaidchart.com/plugins/mermaid-chart-gpt) - [JetBrains IDE](https://docs.mermaidchart.com/plugins/jetbrains-ide) - [Microsoft PowerPoint](https://docs.mermaidchart.com/plugins/microsoft-powerpoint) - [Microsoft Word](https://docs.mermaidchart.com/plugins/microsoft-word) diff --git a/packages/mermaid/src/docs/news/blog.md b/packages/mermaid/src/docs/news/blog.md index 267bd48a61..4ada1e05cd 100644 --- a/packages/mermaid/src/docs/news/blog.md +++ b/packages/mermaid/src/docs/news/blog.md @@ -1,5 +1,17 @@ # Blog +## [How to Choose the Right Documentation Software](https://www.mermaidchart.com/blog/posts/how-to-choose-the-right-documentation-software/) + +7 May 2024 · 5 mins + +How to Choose the Right Documentation Software. Reliable and efficient documentation software is crucial in the fast-paced world of software development. + +## [AI in software diagramming: What trends will define the future?](https://www.mermaidchart.com/blog/posts/ai-in-software-diagramming/) + +24 April 2024 · 5 mins + +Artificial intelligence (AI) tools are changing the way developers work. + ## [Mermaid Chart Unveils Visual Editor for Sequence Diagrams](https://www.mermaidchart.com/blog/posts/mermaid-chart-unveils-visual-editor-for-sequence-diagrams/) 8 April 2024 · 5 mins diff --git a/packages/mermaid/src/docs/package.json b/packages/mermaid/src/docs/package.json index 5f6e338a09..146c4d2d88 100644 --- a/packages/mermaid/src/docs/package.json +++ b/packages/mermaid/src/docs/package.json @@ -34,7 +34,7 @@ "unplugin-vue-components": "^0.26.0", "vite": "^5.0.0", "vite-plugin-pwa": "^0.19.7", - "vitepress": "1.1.0", + "vitepress": "1.1.4", "workbox-window": "^7.0.0" } } diff --git a/packages/mermaid/src/docs/syntax/flowchart.md b/packages/mermaid/src/docs/syntax/flowchart.md index ba0e9ce9e9..acffbc6931 100644 --- a/packages/mermaid/src/docs/syntax/flowchart.md +++ b/packages/mermaid/src/docs/syntax/flowchart.md @@ -567,7 +567,7 @@ Examples of tooltip usage below: ```html @@ -588,7 +588,7 @@ flowchart LR > **Success** The tooltip functionality and the ability to link to urls are available from version 0.5.2. -?> Due to limitations with how Docsify handles JavaScript callback functions, an alternate working demo for the above code can be viewed at [this jsfiddle](https://jsfiddle.net/Ogglas/2o73vdez/7). +?> Due to limitations with how Docsify handles JavaScript callback functions, an alternate working demo for the above code can be viewed at [this jsfiddle](https://jsfiddle.net/yk4h7qou/2/). Links are opened in the same browser tab/window by default. It is possible to change this by adding a link target to the click definition (`_self`, `_blank`, `_parent` and `_top` are supported): @@ -620,7 +620,7 @@ Beginner's tip—a full example using interactive links in a html context: