mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-08-15 14:29:25 +02:00
fix: #4818 support getClasses
in external diagrams.
This commit is contained in:
@@ -16,4 +16,4 @@
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:78](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L78)
|
[mermaidAPI.ts:61](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L61)
|
||||||
|
@@ -39,7 +39,7 @@ bindFunctions?.(div); // To call bindFunctions only if it's present.
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:98](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L98)
|
[mermaidAPI.ts:81](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L81)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -51,4 +51,4 @@ The svg code for the rendered graph.
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:88](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L88)
|
[mermaidAPI.ts:71](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L71)
|
||||||
|
@@ -25,7 +25,7 @@ Renames and re-exports [mermaidAPI](mermaidAPI.md#mermaidapi)
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:82](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L82)
|
[mermaidAPI.ts:65](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L65)
|
||||||
|
|
||||||
## Variables
|
## Variables
|
||||||
|
|
||||||
@@ -96,7 +96,7 @@ mermaid.initialize(config);
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:673](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L673)
|
[mermaidAPI.ts:654](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L654)
|
||||||
|
|
||||||
## Functions
|
## Functions
|
||||||
|
|
||||||
@@ -127,7 +127,7 @@ Return the last node appended
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:310](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L310)
|
[mermaidAPI.ts:293](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L293)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -153,7 +153,7 @@ the cleaned up svgCode
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:256](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L256)
|
[mermaidAPI.ts:239](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L239)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -179,7 +179,7 @@ the string with all the user styles
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:185](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L185)
|
[mermaidAPI.ts:168](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L168)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -189,12 +189,12 @@ the string with all the user styles
|
|||||||
|
|
||||||
#### Parameters
|
#### Parameters
|
||||||
|
|
||||||
| Name | Type |
|
| Name | Type |
|
||||||
| :---------- | :----------------------------------------- |
|
| :---------- | :-------------------------------------------------------- |
|
||||||
| `config` | `MermaidConfig` |
|
| `config` | `MermaidConfig` |
|
||||||
| `graphType` | `string` |
|
| `graphType` | `string` |
|
||||||
| `classDefs` | `Record`<`string`, `DiagramStyleClassDef`> |
|
| `classDefs` | `undefined` \| `Record`<`string`, `DiagramStyleClassDef`> |
|
||||||
| `svgId` | `string` |
|
| `svgId` | `string` |
|
||||||
|
|
||||||
#### Returns
|
#### Returns
|
||||||
|
|
||||||
@@ -202,7 +202,7 @@ the string with all the user styles
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:233](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L233)
|
[mermaidAPI.ts:216](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L216)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -229,7 +229,7 @@ with an enclosing block that has each of the cssClasses followed by !important;
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:169](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L169)
|
[mermaidAPI.ts:152](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L152)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -249,7 +249,7 @@ with an enclosing block that has each of the cssClasses followed by !important;
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:155](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L155)
|
[mermaidAPI.ts:138](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L138)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -269,7 +269,7 @@ with an enclosing block that has each of the cssClasses followed by !important;
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:126](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L126)
|
[mermaidAPI.ts:109](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L109)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -295,7 +295,7 @@ Put the svgCode into an iFrame. Return the iFrame code
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:287](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L287)
|
[mermaidAPI.ts:270](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L270)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -320,4 +320,4 @@ Remove any existing elements from the given document
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:360](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L360)
|
[mermaidAPI.ts:343](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L343)
|
||||||
|
@@ -43,7 +43,11 @@ export const addDiagrams = () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
styles: {}, // should never be used
|
styles: {}, // should never be used
|
||||||
renderer: {}, // should never be used
|
renderer: {
|
||||||
|
draw: () => {
|
||||||
|
// should never be used
|
||||||
|
},
|
||||||
|
},
|
||||||
parser: {
|
parser: {
|
||||||
parser: { yy: {} },
|
parser: { yy: {} },
|
||||||
parse: () => {
|
parse: () => {
|
||||||
|
@@ -41,7 +41,11 @@ describe('DiagramAPI', () => {
|
|||||||
},
|
},
|
||||||
parser: { yy: {} },
|
parser: { yy: {} },
|
||||||
},
|
},
|
||||||
renderer: {},
|
renderer: {
|
||||||
|
draw: () => {
|
||||||
|
// no-op
|
||||||
|
},
|
||||||
|
},
|
||||||
styles: {},
|
styles: {},
|
||||||
},
|
},
|
||||||
detector
|
detector
|
||||||
|
@@ -32,9 +32,26 @@ export interface DiagramDB {
|
|||||||
bindFunctions?: (element: Element) => void;
|
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<DiagramDefinition, 'db'>
|
||||||
|
) => Record<string, DiagramStyleClassDef>;
|
||||||
|
}
|
||||||
|
|
||||||
export interface DiagramDefinition {
|
export interface DiagramDefinition {
|
||||||
db: DiagramDB;
|
db: DiagramDB;
|
||||||
renderer: any;
|
renderer: DiagramRenderer;
|
||||||
parser: ParserDefinition;
|
parser: ParserDefinition;
|
||||||
styles?: any;
|
styles?: any;
|
||||||
init?: (config: MermaidConfig) => void;
|
init?: (config: MermaidConfig) => void;
|
||||||
@@ -76,7 +93,7 @@ export type DrawDefinition = (
|
|||||||
id: string,
|
id: string,
|
||||||
version: string,
|
version: string,
|
||||||
diagramObject: Diagram
|
diagramObject: Diagram
|
||||||
) => void;
|
) => void | Promise<void>;
|
||||||
|
|
||||||
export interface ParserDefinition {
|
export interface ParserDefinition {
|
||||||
parse: (text: string) => void;
|
parse: (text: string) => void;
|
||||||
|
@@ -34,7 +34,11 @@ describe('diagram detection', () => {
|
|||||||
yy: {},
|
yy: {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
renderer: {},
|
renderer: {
|
||||||
|
draw: () => {
|
||||||
|
// no-op
|
||||||
|
},
|
||||||
|
},
|
||||||
styles: {},
|
styles: {},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@@ -4,11 +4,10 @@ import insertMarkers from '../../../dagre-wrapper/markers.js';
|
|||||||
import { insertEdgeLabel } from '../../../dagre-wrapper/edges.js';
|
import { insertEdgeLabel } from '../../../dagre-wrapper/edges.js';
|
||||||
import { findCommonAncestor } from './render-utils.js';
|
import { findCommonAncestor } from './render-utils.js';
|
||||||
import { labelHelper } from '../../../dagre-wrapper/shapes/util.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 { getConfig } from '../../../config.js';
|
||||||
import { log } from '../../../logger.js';
|
import { log } from '../../../logger.js';
|
||||||
import { setupGraphViewbox } from '../../../setupGraphViewbox.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 { interpolateToCurve, getStylesFromArray } from '../../../utils.js';
|
||||||
import ELK from 'elkjs/lib/elk.bundled.js';
|
import ELK from 'elkjs/lib/elk.bundled.js';
|
||||||
const elk = new ELK();
|
const elk = new ELK();
|
||||||
@@ -651,7 +650,7 @@ const addMarkersToEdge = function (svgPath, edgeData, diagramType, arrowMarkerAb
|
|||||||
*
|
*
|
||||||
* @param text
|
* @param text
|
||||||
* @param diagObj
|
* @param diagObj
|
||||||
* @returns {object} ClassDef styles
|
* @returns {Record<string, import('../../../diagram-api/types.js').DiagramStyleClassDef>} ClassDef styles
|
||||||
*/
|
*/
|
||||||
export const getClasses = function (text, diagObj) {
|
export const getClasses = function (text, diagObj) {
|
||||||
log.info('Extracting classes');
|
log.info('Extracting classes');
|
||||||
|
@@ -338,7 +338,7 @@ export const addEdges = function (edges, g, diagObj) {
|
|||||||
*
|
*
|
||||||
* @param text
|
* @param text
|
||||||
* @param diagObj
|
* @param diagObj
|
||||||
* @returns {object} ClassDef styles
|
* @returns {Record<string, import('../../diagram-api/types.js').DiagramStyleClassDef>} ClassDef styles
|
||||||
*/
|
*/
|
||||||
export const getClasses = function (text, diagObj) {
|
export const getClasses = function (text, diagObj) {
|
||||||
return diagObj.db.getClasses();
|
return diagObj.db.getClasses();
|
||||||
|
@@ -269,7 +269,7 @@ export const addEdges = function (edges, g, diagObj) {
|
|||||||
*
|
*
|
||||||
* @param text
|
* @param text
|
||||||
* @param diagObj
|
* @param diagObj
|
||||||
* @returns {object} ClassDef styles
|
* @returns {Record<string, import('../../diagram-api/types.js').DiagramStyleClassDef>} ClassDef styles
|
||||||
*/
|
*/
|
||||||
export const getClasses = function (text, diagObj) {
|
export const getClasses = function (text, diagObj) {
|
||||||
log.info('Extracting classes');
|
log.info('Extracting classes');
|
||||||
|
@@ -81,7 +81,7 @@ export const setConf = function (cnf) {
|
|||||||
*
|
*
|
||||||
* @param {string} text - the diagram text to be parsed
|
* @param {string} text - the diagram text to be parsed
|
||||||
* @param diagramObj
|
* @param diagramObj
|
||||||
* @returns {object} ClassDef styles (a Map with keys = strings, values = )
|
* @returns {Record<string, import('../../diagram-api/types.js').DiagramStyleClassDef>} ClassDef styles (a Map with keys = strings, values = )
|
||||||
*/
|
*/
|
||||||
export const getClasses = function (text, diagramObj) {
|
export const getClasses = function (text, diagramObj) {
|
||||||
diagramObj.db.extract(diagramObj.db.getRootDocV2());
|
diagramObj.db.extract(diagramObj.db.getRootDocV2());
|
||||||
|
@@ -95,8 +95,10 @@ describe('when using mermaid and ', () => {
|
|||||||
let loaded = false;
|
let loaded = false;
|
||||||
const dummyDiagram: DiagramDefinition = {
|
const dummyDiagram: DiagramDefinition = {
|
||||||
db: {},
|
db: {},
|
||||||
renderer: () => {
|
renderer: {
|
||||||
// do nothing
|
draw: () => {
|
||||||
|
// no-op
|
||||||
|
},
|
||||||
},
|
},
|
||||||
parser: {
|
parser: {
|
||||||
parse: (_text) => {
|
parse: (_text) => {
|
||||||
|
@@ -31,16 +31,8 @@ import isEmpty from 'lodash-es/isEmpty.js';
|
|||||||
import { setA11yDiagramInfo, addSVGa11yTitleDescription } from './accessibility.js';
|
import { setA11yDiagramInfo, addSVGa11yTitleDescription } from './accessibility.js';
|
||||||
import { parseDirective } from './directiveUtils.js';
|
import { parseDirective } from './directiveUtils.js';
|
||||||
import { extractFrontMatter } from './diagram-api/frontmatter.js';
|
import { extractFrontMatter } from './diagram-api/frontmatter.js';
|
||||||
|
import type { DiagramStyleClassDef } from './diagram-api/types.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 = 50_000;
|
||||||
const MAX_TEXTLENGTH_EXCEEDED_MSG =
|
const MAX_TEXTLENGTH_EXCEEDED_MSG =
|
||||||
'graph TB;a[Maximum text size in diagram exceeded];style a fill:#faa';
|
'graph TB;a[Maximum text size in diagram exceeded];style a fill:#faa';
|
||||||
@@ -65,15 +57,6 @@ const IFRAME_NOT_SUPPORTED_MSG = 'The "iframe" tag is not supported by your brow
|
|||||||
const DOMPURIFY_TAGS = ['foreignobject'];
|
const DOMPURIFY_TAGS = ['foreignobject'];
|
||||||
const DOMPURIFY_ATTR = ['dominant-baseline'];
|
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 {
|
export interface ParseOptions {
|
||||||
suppressErrors?: boolean;
|
suppressErrors?: boolean;
|
||||||
}
|
}
|
||||||
@@ -204,7 +187,7 @@ export const createCssStyles = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// classDefs defined in the diagram text
|
// 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 htmlLabels = config.htmlLabels || config.flowchart?.htmlLabels; // TODO why specifically check the Flowchart diagram config?
|
||||||
|
|
||||||
const cssHtmlElements = ['> *', 'span']; // TODO make a constant
|
const cssHtmlElements = ['> *', 'span']; // TODO make a constant
|
||||||
@@ -233,7 +216,7 @@ export const createCssStyles = (
|
|||||||
export const createUserStyles = (
|
export const createUserStyles = (
|
||||||
config: MermaidConfig,
|
config: MermaidConfig,
|
||||||
graphType: string,
|
graphType: string,
|
||||||
classDefs: Record<string, DiagramStyleClassDef>,
|
classDefs: Record<string, DiagramStyleClassDef> | undefined,
|
||||||
svgId: string
|
svgId: string
|
||||||
): string => {
|
): string => {
|
||||||
const userCSSstyles = createCssStyles(config, graphType, classDefs);
|
const userCSSstyles = createCssStyles(config, graphType, classDefs);
|
||||||
@@ -492,9 +475,7 @@ const render = async function (
|
|||||||
// Insert an element into svg. This is where we put the styles
|
// Insert an element into svg. This is where we put the styles
|
||||||
const svg = element.firstChild;
|
const svg = element.firstChild;
|
||||||
const firstChild = svg.firstChild;
|
const firstChild = svg.firstChild;
|
||||||
const diagramClassDefs = CLASSDEF_DIAGRAMS.includes(diagramType)
|
const diagramClassDefs = diag.renderer.getClasses?.(text, diag);
|
||||||
? diag.renderer.getClasses(text, diag)
|
|
||||||
: {};
|
|
||||||
|
|
||||||
const rules = createUserStyles(config, diagramType, diagramClassDefs, idSelector);
|
const rules = createUserStyles(config, diagramType, diagramClassDefs, idSelector);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user