diff --git a/docs/config/setup/interfaces/mermaidAPI.ParseOptions.md b/docs/config/setup/interfaces/mermaidAPI.ParseOptions.md index 56f9146419..ea390899e4 100644 --- a/docs/config/setup/interfaces/mermaidAPI.ParseOptions.md +++ b/docs/config/setup/interfaces/mermaidAPI.ParseOptions.md @@ -16,4 +16,4 @@ #### Defined in -[mermaidAPI.ts:76](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L76) +[mermaidAPI.ts:59](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L59) diff --git a/docs/config/setup/interfaces/mermaidAPI.RenderResult.md b/docs/config/setup/interfaces/mermaidAPI.RenderResult.md index 2c1504285d..18ee5e4316 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:96](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L96) +[mermaidAPI.ts:79](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L79) --- @@ -51,4 +51,4 @@ The svg code for the rendered graph. #### Defined in -[mermaidAPI.ts:86](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L86) +[mermaidAPI.ts:69](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L69) diff --git a/docs/config/setup/modules/mermaidAPI.md b/docs/config/setup/modules/mermaidAPI.md index 1ea19fac4e..0a948b6f39 100644 --- a/docs/config/setup/modules/mermaidAPI.md +++ b/docs/config/setup/modules/mermaidAPI.md @@ -25,7 +25,7 @@ Renames and re-exports [mermaidAPI](mermaidAPI.md#mermaidapi) #### Defined in -[mermaidAPI.ts:80](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L80) +[mermaidAPI.ts:63](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L63) ## Variables @@ -96,7 +96,7 @@ mermaid.initialize(config); #### Defined in -[mermaidAPI.ts:662](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L662) +[mermaidAPI.ts:641](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L641) ## Functions @@ -127,7 +127,7 @@ Return the last node appended #### Defined in -[mermaidAPI.ts:318](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L318) +[mermaidAPI.ts:299](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L299) --- @@ -153,13 +153,13 @@ the cleaned up svgCode #### Defined in -[mermaidAPI.ts:264](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L264) +[mermaidAPI.ts:245](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L245) --- ### createCssStyles -▸ **createCssStyles**(`config`, `graphType`, `classDefs?`): `string` +▸ **createCssStyles**(`config`, `classDefs?`): `string` Create the user styles @@ -168,7 +168,6 @@ Create the user styles | Name | Type | Description | | :---------- | :------------------------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------ | | `config` | `MermaidConfig` | configuration that has style and theme settings to use | -| `graphType` | `string` | used for checking if classDefs should be applied | | `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(...) | #### Returns @@ -179,7 +178,7 @@ the string with all the user styles #### Defined in -[mermaidAPI.ts:193](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L193) +[mermaidAPI.ts:175](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L175) --- @@ -189,12 +188,12 @@ the string with all the user styles #### Parameters -| Name | Type | -| :---------- | :----------------------------------------- | -| `config` | `MermaidConfig` | -| `graphType` | `string` | -| `classDefs` | `Record`<`string`, `DiagramStyleClassDef`> | -| `svgId` | `string` | +| Name | Type | +| :---------- | :-------------------------------------------------------- | +| `config` | `MermaidConfig` | +| `graphType` | `string` | +| `classDefs` | `undefined` \| `Record`<`string`, `DiagramStyleClassDef`> | +| `svgId` | `string` | #### Returns @@ -202,7 +201,7 @@ the string with all the user styles #### Defined in -[mermaidAPI.ts:241](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L241) +[mermaidAPI.ts:222](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L222) --- @@ -229,7 +228,7 @@ with an enclosing block that has each of the cssClasses followed by !important; #### Defined in -[mermaidAPI.ts:177](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L177) +[mermaidAPI.ts:160](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L160) --- @@ -249,7 +248,7 @@ with an enclosing block that has each of the cssClasses followed by !important; #### Defined in -[mermaidAPI.ts:163](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L163) +[mermaidAPI.ts:146](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L146) --- @@ -269,7 +268,7 @@ with an enclosing block that has each of the cssClasses followed by !important; #### Defined in -[mermaidAPI.ts:134](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L134) +[mermaidAPI.ts:117](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L117) --- @@ -295,7 +294,7 @@ Put the svgCode into an iFrame. Return the iFrame code #### Defined in -[mermaidAPI.ts:295](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L295) +[mermaidAPI.ts:276](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L276) --- @@ -320,4 +319,4 @@ Remove any existing elements from the given document #### Defined in -[mermaidAPI.ts:368](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L368) +[mermaidAPI.ts:349](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L349) diff --git a/packages/mermaid/package.json b/packages/mermaid/package.json index 7b4de70a98..e208d561e5 100644 --- a/packages/mermaid/package.json +++ b/packages/mermaid/package.json @@ -1,6 +1,6 @@ { "name": "mermaid", - "version": "10.4.0", + "version": "10.5.0-alpha.1", "description": "Markdown-ish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.", "type": "module", "module": "./dist/mermaid.core.mjs", diff --git a/packages/mermaid/src/diagram-api/diagram-orchestration.ts b/packages/mermaid/src/diagram-api/diagram-orchestration.ts index 80665cfa2e..0357ad7feb 100644 --- a/packages/mermaid/src/diagram-api/diagram-orchestration.ts +++ b/packages/mermaid/src/diagram-api/diagram-orchestration.ts @@ -43,7 +43,11 @@ export const addDiagrams = () => { }, }, styles: {}, // should never be used - renderer: {}, // should never be used + renderer: { + draw: () => { + // should never be used + }, + }, parser: { parser: { yy: {} }, parse: () => { diff --git a/packages/mermaid/src/diagram-api/diagramAPI.spec.ts b/packages/mermaid/src/diagram-api/diagramAPI.spec.ts index b82011f8de..2cafd695ba 100644 --- a/packages/mermaid/src/diagram-api/diagramAPI.spec.ts +++ b/packages/mermaid/src/diagram-api/diagramAPI.spec.ts @@ -41,7 +41,11 @@ describe('DiagramAPI', () => { }, parser: { yy: {} }, }, - renderer: {}, + renderer: { + draw: () => { + // no-op + }, + }, styles: {}, }, detector diff --git a/packages/mermaid/src/diagram-api/types.ts b/packages/mermaid/src/diagram-api/types.ts index 15aa4b0336..58d98107ea 100644 --- a/packages/mermaid/src/diagram-api/types.ts +++ b/packages/mermaid/src/diagram-api/types.ts @@ -39,9 +39,26 @@ export interface DiagramDB { bindFunctions?: (element: Element) => void; } +// This is what is returned from getClasses(...) methods. +// It is slightly renamed to ..StyleClassDef instead of just ClassDef because "class" is a greatly ambiguous and overloaded word. +// It makes it clear we're working with a style class definition, even though defining the type is currently difficult. +export interface DiagramStyleClassDef { + id: string; + styles?: string[]; + textStyles?: string[]; +} + +export interface DiagramRenderer { + draw: DrawDefinition; + getClasses?: ( + text: string, + diagram: Pick + ) => Record; +} + export interface DiagramDefinition { db: DiagramDB; - renderer: any; + renderer: DiagramRenderer; parser: ParserDefinition; styles?: any; init?: (config: MermaidConfig) => void; @@ -84,7 +101,7 @@ export type DrawDefinition = ( id: string, version: string, diagramObject: Diagram -) => void; +) => void | Promise; export interface ParserDefinition { parse: (text: string) => void; diff --git a/packages/mermaid/src/diagram.spec.ts b/packages/mermaid/src/diagram.spec.ts index 99ce4e2c66..19a65b716b 100644 --- a/packages/mermaid/src/diagram.spec.ts +++ b/packages/mermaid/src/diagram.spec.ts @@ -34,7 +34,11 @@ describe('diagram detection', () => { yy: {}, }, }, - renderer: {}, + renderer: { + draw: () => { + // no-op + }, + }, styles: {}, }, }) diff --git a/packages/mermaid/src/diagrams/flowchart/elk/flowRenderer-elk.js b/packages/mermaid/src/diagrams/flowchart/elk/flowRenderer-elk.js index c7bfdf5246..f1ad22f675 100644 --- a/packages/mermaid/src/diagrams/flowchart/elk/flowRenderer-elk.js +++ b/packages/mermaid/src/diagrams/flowchart/elk/flowRenderer-elk.js @@ -4,11 +4,10 @@ import insertMarkers from '../../../dagre-wrapper/markers.js'; import { insertEdgeLabel } from '../../../dagre-wrapper/edges.js'; import { findCommonAncestor } from './render-utils.js'; import { labelHelper } from '../../../dagre-wrapper/shapes/util.js'; -import { addHtmlLabel } from 'dagre-d3-es/src/dagre-js/label/add-html-label.js'; import { getConfig } from '../../../config.js'; import { log } from '../../../logger.js'; import { setupGraphViewbox } from '../../../setupGraphViewbox.js'; -import common, { evaluate } from '../../common/common.js'; +import common from '../../common/common.js'; import { interpolateToCurve, getStylesFromArray } from '../../../utils.js'; import ELK from 'elkjs/lib/elk.bundled.js'; const elk = new ELK(); @@ -651,7 +650,7 @@ const addMarkersToEdge = function (svgPath, edgeData, diagramType, arrowMarkerAb * * @param text * @param diagObj - * @returns {object} ClassDef styles + * @returns {Record} ClassDef styles */ export const getClasses = function (text, diagObj) { log.info('Extracting classes'); diff --git a/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js b/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js index 4a3b7a8ce5..576ee6b34d 100644 --- a/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js +++ b/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js @@ -338,7 +338,7 @@ export const addEdges = function (edges, g, diagObj) { * * @param text * @param diagObj - * @returns {object} ClassDef styles + * @returns {Record} ClassDef styles */ export const getClasses = function (text, diagObj) { return diagObj.db.getClasses(); diff --git a/packages/mermaid/src/diagrams/flowchart/flowRenderer.js b/packages/mermaid/src/diagrams/flowchart/flowRenderer.js index fc06cacd4d..8394b41e88 100644 --- a/packages/mermaid/src/diagrams/flowchart/flowRenderer.js +++ b/packages/mermaid/src/diagrams/flowchart/flowRenderer.js @@ -269,7 +269,7 @@ export const addEdges = function (edges, g, diagObj) { * * @param text * @param diagObj - * @returns {object} ClassDef styles + * @returns {Record} ClassDef styles */ export const getClasses = function (text, diagObj) { log.info('Extracting classes'); diff --git a/packages/mermaid/src/diagrams/state/stateRenderer-v2.js b/packages/mermaid/src/diagrams/state/stateRenderer-v2.js index 1c9b2d1d3c..0d3117b206 100644 --- a/packages/mermaid/src/diagrams/state/stateRenderer-v2.js +++ b/packages/mermaid/src/diagrams/state/stateRenderer-v2.js @@ -81,7 +81,7 @@ export const setConf = function (cnf) { * * @param {string} text - the diagram text to be parsed * @param diagramObj - * @returns {object} ClassDef styles (a Map with keys = strings, values = ) + * @returns {Record} ClassDef styles (a Map with keys = strings, values = ) */ export const getClasses = function (text, diagramObj) { diagramObj.db.extract(diagramObj.db.getRootDocV2()); diff --git a/packages/mermaid/src/mermaid.spec.ts b/packages/mermaid/src/mermaid.spec.ts index 0b4437d742..645b5b39cb 100644 --- a/packages/mermaid/src/mermaid.spec.ts +++ b/packages/mermaid/src/mermaid.spec.ts @@ -95,8 +95,10 @@ describe('when using mermaid and ', () => { let loaded = false; const dummyDiagram: DiagramDefinition = { db: {}, - renderer: () => { - // do nothing + renderer: { + draw: () => { + // no-op + }, }, parser: { parse: (_text) => { diff --git a/packages/mermaid/src/mermaidAPI.spec.ts b/packages/mermaid/src/mermaidAPI.spec.ts index d7c16a1cfb..a79fd44c4a 100644 --- a/packages/mermaid/src/mermaidAPI.spec.ts +++ b/packages/mermaid/src/mermaidAPI.spec.ts @@ -287,15 +287,15 @@ describe('mermaidAPI', () => { }; it('gets the cssStyles from the theme', () => { - const styles = createCssStyles(mocked_config_with_htmlLabels, 'graphType', null); + const styles = createCssStyles(mocked_config_with_htmlLabels, null); expect(styles).toMatch(/^\ndefault(.*)/); }); it('gets the fontFamily from the config', () => { - const styles = createCssStyles(mocked_config_with_htmlLabels, 'graphType', {}); + const styles = createCssStyles(mocked_config_with_htmlLabels, {}); expect(styles).toMatch(/(.*)\n:root { --mermaid-font-family: serif(.*)/); }); it('gets the alt fontFamily from the config', () => { - const styles = createCssStyles(mocked_config_with_htmlLabels, 'graphType', undefined); + const styles = createCssStyles(mocked_config_with_htmlLabels, undefined); expect(styles).toMatch(/(.*)\n:root { --mermaid-alt-font-family: sans-serif(.*)/); }); @@ -306,8 +306,6 @@ describe('mermaidAPI', () => { const classDefs = { classDef1, classDef2, classDef3 }; describe('the graph supports classDefs', () => { - const graphType = 'flowchart-v2'; - const REGEXP_SPECIALS = ['^', '$', '?', '(', '{', '[', '.', '*', '!']; // prefix any special RegExp characters in the given string with a \ so we can use the literal character in a RegExp @@ -373,7 +371,7 @@ describe('mermaidAPI', () => { // @todo TODO Can't figure out how to spy on the cssImportantStyles method. // That would be a much better approach than manually checking the result - const styles = createCssStyles(mocked_config, graphType, classDefs); + const styles = createCssStyles(mocked_config, classDefs); htmlElements.forEach((htmlElement) => { expect_styles_matchesHtmlElements(styles, htmlElement); }); @@ -411,7 +409,7 @@ describe('mermaidAPI', () => { it('creates CSS styles for every style and textStyle in every classDef', () => { // TODO Can't figure out how to spy on the cssImportantStyles method. That would be a much better approach than manually checking the result. - const styles = createCssStyles(mocked_config_no_htmlLabels, graphType, classDefs); + const styles = createCssStyles(mocked_config_no_htmlLabels, classDefs); htmlElements.forEach((htmlElement) => { expect_styles_matchesHtmlElements(styles, htmlElement); }); diff --git a/packages/mermaid/src/mermaidAPI.ts b/packages/mermaid/src/mermaidAPI.ts index 3649b50f53..5250f0b190 100644 --- a/packages/mermaid/src/mermaidAPI.ts +++ b/packages/mermaid/src/mermaidAPI.ts @@ -28,17 +28,9 @@ import type { MermaidConfig } from './config.type.js'; import { evaluate } from './diagrams/common/common.js'; import isEmpty from 'lodash-es/isEmpty.js'; import { setA11yDiagramInfo, addSVGa11yTitleDescription } from './accessibility.js'; +import type { DiagramStyleClassDef } from './diagram-api/types.js'; import { preprocessDiagram } from './preprocess.js'; -// diagram names that support classDef statements -const CLASSDEF_DIAGRAMS = [ - 'graph', - 'flowchart', - 'flowchart-v2', - 'flowchart-elk', - 'stateDiagram', - 'stateDiagram-v2', -]; const MAX_TEXTLENGTH = 50_000; const MAX_TEXTLENGTH_EXCEEDED_MSG = 'graph TB;a[Maximum text size in diagram exceeded];style a fill:#faa'; @@ -63,15 +55,6 @@ const IFRAME_NOT_SUPPORTED_MSG = 'The "iframe" tag is not supported by your brow const DOMPURIFY_TAGS = ['foreignobject']; const DOMPURIFY_ATTR = ['dominant-baseline']; -// This is what is returned from getClasses(...) methods. -// It is slightly renamed to ..StyleClassDef instead of just ClassDef because "class" is a greatly ambiguous and overloaded word. -// It makes it clear we're working with a style class definition, even though defining the type is currently difficult. -interface DiagramStyleClassDef { - id: string; - styles?: string[]; - textStyles?: string[]; -} - export interface ParseOptions { suppressErrors?: boolean; } @@ -184,15 +167,13 @@ export const cssImportantStyles = ( /** * Create the user styles - * + * @internal * @param config - configuration that has style and theme settings to use - * @param graphType - used for checking if classDefs should be applied * @param classDefs - the classDefs in the diagram text. Might be null if none were defined. Usually is the result of a call to getClasses(...) * @returns the string with all the user styles */ export const createCssStyles = ( config: MermaidConfig, - graphType: string, classDefs: Record | null | undefined = {} ): string => { let cssStyles = ''; @@ -212,7 +193,7 @@ export const createCssStyles = ( } // classDefs defined in the diagram text - if (!isEmpty(classDefs) && CLASSDEF_DIAGRAMS.includes(graphType)) { + if (!isEmpty(classDefs)) { const htmlLabels = config.htmlLabels || config.flowchart?.htmlLabels; // TODO why specifically check the Flowchart diagram config? const cssHtmlElements = ['> *', 'span']; // TODO make a constant @@ -241,10 +222,10 @@ export const createCssStyles = ( export const createUserStyles = ( config: MermaidConfig, graphType: string, - classDefs: Record, + classDefs: Record | undefined, svgId: string ): string => { - const userCSSstyles = createCssStyles(config, graphType, classDefs); + const userCSSstyles = createCssStyles(config, classDefs); const allStyles = getStyles(graphType, userCSSstyles, config.themeVariables); // Now turn all of the styles into a (compiled) string that starts with the id @@ -481,9 +462,7 @@ const render = async function ( // Insert an element into svg. This is where we put the styles const svg = element.firstChild; const firstChild = svg.firstChild; - const diagramClassDefs = CLASSDEF_DIAGRAMS.includes(diagramType) - ? diag.renderer.getClasses(text, diag) - : {}; + const diagramClassDefs = diag.renderer.getClasses?.(text, diag); const rules = createUserStyles(config, diagramType, diagramClassDefs, idSelector);