mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-02-04 07:13:25 +08:00
chore: Add type checked rules, auto fix
This commit is contained in:
parent
51fc56b95d
commit
6b87fb3418
@ -82,7 +82,7 @@ async function createServer() {
|
|||||||
if (!['add', 'change'].includes(event)) {
|
if (!['add', 'change'].includes(event)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (/\.langium$/.test(path)) {
|
if (path.endsWith('.langium')) {
|
||||||
await generateLangium();
|
await generateLangium();
|
||||||
}
|
}
|
||||||
console.log(`${path} changed. Rebuilding...`);
|
console.log(`${path} changed. Rebuilding...`);
|
||||||
|
@ -35,7 +35,7 @@ export const mermaidUrl = (
|
|||||||
};
|
};
|
||||||
const objStr: string = JSON.stringify(codeObject);
|
const objStr: string = JSON.stringify(codeObject);
|
||||||
let url = `http://localhost:9000/e2e.html?graph=${utf8ToB64(objStr)}`;
|
let url = `http://localhost:9000/e2e.html?graph=${utf8ToB64(objStr)}`;
|
||||||
if (api) {
|
if (api && typeof graphStr === 'string') {
|
||||||
url = `http://localhost:9000/xss.html?graph=${graphStr}`;
|
url = `http://localhost:9000/xss.html?graph=${graphStr}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,8 +60,7 @@ export const imgSnapshotTest = (
|
|||||||
sequence: {
|
sequence: {
|
||||||
...(_options.sequence || {}),
|
...(_options.sequence || {}),
|
||||||
actorFontFamily: 'courier',
|
actorFontFamily: 'courier',
|
||||||
noteFontFamily:
|
noteFontFamily: _options.sequence?.noteFontFamily
|
||||||
_options.sequence && _options.sequence.noteFontFamily
|
|
||||||
? _options.sequence.noteFontFamily
|
? _options.sequence.noteFontFamily
|
||||||
: 'courier',
|
: 'courier',
|
||||||
messageFontFamily: 'courier',
|
messageFontFamily: 'courier',
|
||||||
|
@ -27,7 +27,7 @@ const code3 = `flowchart TD
|
|||||||
A(<img scr='https://iconscout.com/ms-icon-310x310.png' width='20' height='20' />)
|
A(<img scr='https://iconscout.com/ms-icon-310x310.png' width='20' height='20' />)
|
||||||
B(<b>Bold text!</b>)`;
|
B(<b>Bold text!</b>)`;
|
||||||
|
|
||||||
if (location.href.match('test-html-escaping')) {
|
if (/test-html-escaping/.exec(location.href)) {
|
||||||
code = code3;
|
code = code3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ if (typeof document !== 'undefined') {
|
|||||||
window.addEventListener(
|
window.addEventListener(
|
||||||
'load',
|
'load',
|
||||||
function () {
|
function () {
|
||||||
if (this.location.href.match('xss.html')) {
|
if (/xss.html/.exec(this.location.href)) {
|
||||||
this.console.log('Using api');
|
this.console.log('Using api');
|
||||||
void contentLoadedApi().finally(markRendered);
|
void contentLoadedApi().finally(markRendered);
|
||||||
} else {
|
} else {
|
||||||
|
@ -13,7 +13,8 @@ import tseslint from 'typescript-eslint';
|
|||||||
|
|
||||||
export default tseslint.config(
|
export default tseslint.config(
|
||||||
eslint.configs.recommended,
|
eslint.configs.recommended,
|
||||||
...tseslint.configs.recommended,
|
...tseslint.configs.recommendedTypeChecked,
|
||||||
|
...tseslint.configs.stylisticTypeChecked,
|
||||||
{
|
{
|
||||||
ignores: [
|
ignores: [
|
||||||
'**/dist/',
|
'**/dist/',
|
||||||
@ -68,6 +69,15 @@ export default tseslint.config(
|
|||||||
'@typescript-eslint/no-floating-promises': 'error',
|
'@typescript-eslint/no-floating-promises': 'error',
|
||||||
'@typescript-eslint/no-misused-promises': 'error',
|
'@typescript-eslint/no-misused-promises': 'error',
|
||||||
'@typescript-eslint/no-unused-vars': 'warn',
|
'@typescript-eslint/no-unused-vars': 'warn',
|
||||||
|
'@typescript-eslint/no-unsafe-argument': 'off',
|
||||||
|
'@typescript-eslint/no-unsafe-member-access': 'off',
|
||||||
|
'@typescript-eslint/no-unsafe-call': 'off',
|
||||||
|
'@typescript-eslint/no-unsafe-return': 'off',
|
||||||
|
'@typescript-eslint/no-empty-function': 'off',
|
||||||
|
'@typescript-eslint/prefer-nullish-coalescing': 'warn',
|
||||||
|
'@typescript-eslint/prefer-promise-reject-errors': 'off',
|
||||||
|
'@typescript-eslint/only-throw-error': 'off',
|
||||||
|
'@typescript-eslint/no-unsafe-assignment': 'off',
|
||||||
'@typescript-eslint/consistent-type-definitions': 'error',
|
'@typescript-eslint/consistent-type-definitions': 'error',
|
||||||
'@typescript-eslint/ban-ts-comment': [
|
'@typescript-eslint/ban-ts-comment': [
|
||||||
'error',
|
'error',
|
||||||
|
@ -25,7 +25,7 @@ export const log: Record<keyof typeof LEVELS, typeof console.log> = {
|
|||||||
fatal: warning,
|
fatal: warning,
|
||||||
};
|
};
|
||||||
|
|
||||||
export let setLogLevel: (level: keyof typeof LEVELS | number | string) => void;
|
export let setLogLevel: (level: keyof typeof LEVELS | number) => void;
|
||||||
export let getConfig: () => object;
|
export let getConfig: () => object;
|
||||||
export let sanitizeText: (str: string) => string;
|
export let sanitizeText: (str: string) => string;
|
||||||
export let commonDb: () => object;
|
export let commonDb: () => object;
|
||||||
|
@ -26,7 +26,7 @@ export const log: Record<keyof typeof LEVELS, typeof console.log> = {
|
|||||||
fatal: warning,
|
fatal: warning,
|
||||||
};
|
};
|
||||||
|
|
||||||
export let setLogLevel: (level: keyof typeof LEVELS | number | string) => void;
|
export let setLogLevel: (level: keyof typeof LEVELS | number) => void;
|
||||||
export let getConfig: () => MermaidConfig;
|
export let getConfig: () => MermaidConfig;
|
||||||
export let sanitizeText: (str: string) => string;
|
export let sanitizeText: (str: string) => string;
|
||||||
// eslint-disable @typescript-eslint/no-explicit-any
|
// eslint-disable @typescript-eslint/no-explicit-any
|
||||||
|
@ -9,7 +9,7 @@ function createTemporaryZenumlContainer(id: string) {
|
|||||||
container.id = `container-${id}`;
|
container.id = `container-${id}`;
|
||||||
container.style.display = 'flex';
|
container.style.display = 'flex';
|
||||||
container.innerHTML = `<div id="zenUMLApp-${id}"></div>`;
|
container.innerHTML = `<div id="zenUMLApp-${id}"></div>`;
|
||||||
const app = container.querySelector(`#zenUMLApp-${id}`) as HTMLElement;
|
const app = container.querySelector(`#zenUMLApp-${id}`)!;
|
||||||
return { container, app };
|
return { container, app };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ async function generateTypescript(mermaidConfigSchema: JSONSchemaType<MermaidCon
|
|||||||
* @returns The schema with `allOf` replaced with `extends`.
|
* @returns The schema with `allOf` replaced with `extends`.
|
||||||
*/
|
*/
|
||||||
function replaceAllOfWithExtends(schema: JSONSchemaType<Record<string, any>>) {
|
function replaceAllOfWithExtends(schema: JSONSchemaType<Record<string, any>>) {
|
||||||
if (schema['allOf']) {
|
if (schema.allOf) {
|
||||||
const { allOf, ...schemaWithoutAllOf } = schema;
|
const { allOf, ...schemaWithoutAllOf } = schema;
|
||||||
return {
|
return {
|
||||||
...schemaWithoutAllOf,
|
...schemaWithoutAllOf,
|
||||||
|
@ -88,9 +88,9 @@ const WARN_DOCSDIR_DOESNT_MATCH = `Changed files were transformed in ${SOURCE_DO
|
|||||||
const prettierConfig = (await prettier.resolveConfig('.')) ?? {};
|
const prettierConfig = (await prettier.resolveConfig('.')) ?? {};
|
||||||
// From https://github.com/vuejs/vitepress/blob/428eec3750d6b5648a77ac52d88128df0554d4d1/src/node/markdownToVue.ts#L20-L21
|
// From https://github.com/vuejs/vitepress/blob/428eec3750d6b5648a77ac52d88128df0554d4d1/src/node/markdownToVue.ts#L20-L21
|
||||||
const includesRE = /<!--\s*@include:\s*(.*?)\s*-->/g;
|
const includesRE = /<!--\s*@include:\s*(.*?)\s*-->/g;
|
||||||
const includedFiles: Set<string> = new Set();
|
const includedFiles = new Set<string>();
|
||||||
|
|
||||||
const filesTransformed: Set<string> = new Set();
|
const filesTransformed = new Set<string>();
|
||||||
|
|
||||||
const generateHeader = (file: string): string => {
|
const generateHeader = (file: string): string => {
|
||||||
// path from file in docs/* to repo root, e.g ../ or ../../ */
|
// path from file in docs/* to repo root, e.g ../ or ../../ */
|
||||||
@ -201,6 +201,7 @@ const transformIncludeStatements = (file: string, text: string): string => {
|
|||||||
includedFiles.add(changeToFinalDocDir(includePath));
|
includedFiles.add(changeToFinalDocDir(includePath));
|
||||||
return content;
|
return content;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||||
throw new Error(`Failed to resolve include "${m1}" in "${file}": ${error}`);
|
throw new Error(`Failed to resolve include "${m1}" in "${file}": ${error}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -6,6 +6,7 @@ import { encodeEntities } from './utils.js';
|
|||||||
import type { DetailedError } from './utils.js';
|
import type { DetailedError } from './utils.js';
|
||||||
import type { DiagramDefinition, DiagramMetadata } from './diagram-api/types.js';
|
import type { DiagramDefinition, DiagramMetadata } from './diagram-api/types.js';
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
|
||||||
export type ParseErrorFunction = (err: string | DetailedError | unknown, hash?: any) => void;
|
export type ParseErrorFunction = (err: string | DetailedError | unknown, hash?: any) => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -189,7 +189,7 @@ export const addDirective = (directive: MermaidConfig) => {
|
|||||||
sanitizeDirective(directive);
|
sanitizeDirective(directive);
|
||||||
|
|
||||||
// If the directive has a fontFamily, but no themeVariables, add the fontFamily to the themeVariables
|
// If the directive has a fontFamily, but no themeVariables, add the fontFamily to the themeVariables
|
||||||
if (directive.fontFamily && (!directive.themeVariables || !directive.themeVariables.fontFamily)) {
|
if (directive.fontFamily && !directive.themeVariables?.fontFamily) {
|
||||||
directive.themeVariables = { fontFamily: directive.fontFamily };
|
directive.themeVariables = { fontFamily: directive.fontFamily };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.info('(Insert) Node XXX' + v + ': ' + JSON.stringify(graph.node(v)));
|
log.info('(Insert) Node XXX' + v + ': ' + JSON.stringify(graph.node(v)));
|
||||||
if (node && node.clusterNode) {
|
if (node?.clusterNode) {
|
||||||
// const children = graph.children(v);
|
// const children = graph.children(v);
|
||||||
log.info('Cluster identified', v, node.width, graph.node(v));
|
log.info('Cluster identified', v, node.width, graph.node(v));
|
||||||
// `node.graph.setGraph` applies the graph configurations such as nodeSpacing to subgraphs as without this the default values would be used
|
// `node.graph.setGraph` applies the graph configurations such as nodeSpacing to subgraphs as without this the default values would be used
|
||||||
@ -130,7 +130,7 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit
|
|||||||
' height: ',
|
' height: ',
|
||||||
node.height
|
node.height
|
||||||
);
|
);
|
||||||
if (node && node.clusterNode) {
|
if (node?.clusterNode) {
|
||||||
// clusterDb[node.id].node = node;
|
// clusterDb[node.id].node = node;
|
||||||
node.y += subGraphTitleTotalMargin;
|
node.y += subGraphTitleTotalMargin;
|
||||||
positionNode(node);
|
positionNode(node);
|
||||||
|
@ -399,7 +399,7 @@ export const extractor = (graph, depth) => {
|
|||||||
|
|
||||||
const graphSettings = graph.graph();
|
const graphSettings = graph.graph();
|
||||||
let dir = graphSettings.rankdir === 'TB' ? 'LR' : 'TB';
|
let dir = graphSettings.rankdir === 'TB' ? 'LR' : 'TB';
|
||||||
if (clusterDb[node] && clusterDb[node].clusterData && clusterDb[node].clusterData.dir) {
|
if (clusterDb[node]?.clusterData?.dir) {
|
||||||
dir = clusterDb[node].clusterData.dir;
|
dir = clusterDb[node].clusterData.dir;
|
||||||
log.warn('Fixing dir', clusterDb[node].clusterData.dir, dir);
|
log.warn('Fixing dir', clusterDb[node].clusterData.dir, dir);
|
||||||
}
|
}
|
||||||
|
@ -901,7 +901,7 @@ const class_box = (parent, node) => {
|
|||||||
|
|
||||||
const labelContainer = shapeSvg.insert('g').attr('class', 'label');
|
const labelContainer = shapeSvg.insert('g').attr('class', 'label');
|
||||||
let verticalPos = 0;
|
let verticalPos = 0;
|
||||||
const hasInterface = node.classData.annotations && node.classData.annotations[0];
|
const hasInterface = node.classData.annotations?.[0];
|
||||||
|
|
||||||
// 1. Create the labels
|
// 1. Create the labels
|
||||||
const interfaceLabelText = node.classData.annotations[0]
|
const interfaceLabelText = node.classData.annotations[0]
|
||||||
|
@ -23,7 +23,7 @@ const config: RequiredDeep<MermaidConfig> = {
|
|||||||
themeCSS: undefined,
|
themeCSS: undefined,
|
||||||
|
|
||||||
// add non-JSON default config values
|
// add non-JSON default config values
|
||||||
themeVariables: theme['default'].getThemeVariables(),
|
themeVariables: theme.default.getThemeVariables(),
|
||||||
sequence: {
|
sequence: {
|
||||||
...defaultConfigJson.sequence,
|
...defaultConfigJson.sequence,
|
||||||
messageFont: function () {
|
messageFont: function () {
|
||||||
@ -272,5 +272,5 @@ const keyify = (obj: any, prefix = ''): string[] =>
|
|||||||
return [...res, prefix + el];
|
return [...res, prefix + el];
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
export const configKeys: Set<string> = new Set(keyify(config, ''));
|
export const configKeys = new Set<string>(keyify(config, ''));
|
||||||
export default config;
|
export default config;
|
||||||
|
@ -29,7 +29,7 @@ describe('DiagramAPI', () => {
|
|||||||
`[UnknownDiagramError: No diagram type detected matching given configuration for text: loki diagram]`
|
`[UnknownDiagramError: No diagram type detected matching given configuration for text: loki diagram]`
|
||||||
);
|
);
|
||||||
const detector: DiagramDetector = (str: string) => {
|
const detector: DiagramDetector = (str: string) => {
|
||||||
return str.match('loki') !== null;
|
return /loki/.exec(str) !== null;
|
||||||
};
|
};
|
||||||
registerDiagram(
|
registerDiagram(
|
||||||
'loki',
|
'loki',
|
||||||
|
@ -30,9 +30,7 @@ export const getCommonDb = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const diagrams: Record<string, DiagramDefinition> = {};
|
const diagrams: Record<string, DiagramDefinition> = {};
|
||||||
export interface Detectors {
|
export type Detectors = Record<string, DiagramDetector>;
|
||||||
[key: string]: DiagramDetector;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers the given diagram with Mermaid.
|
* Registers the given diagram with Mermaid.
|
||||||
|
@ -30,12 +30,12 @@ const getDummyDiagram = (id: string, title?: string): Awaited<ReturnType<Diagram
|
|||||||
|
|
||||||
describe('diagram detection', () => {
|
describe('diagram detection', () => {
|
||||||
test('should detect inbuilt diagrams', async () => {
|
test('should detect inbuilt diagrams', async () => {
|
||||||
const graph = (await Diagram.fromText('graph TD; A-->B')) as Diagram;
|
const graph = await Diagram.fromText('graph TD; A-->B');
|
||||||
expect(graph).toBeInstanceOf(Diagram);
|
expect(graph).toBeInstanceOf(Diagram);
|
||||||
expect(graph.type).toBe('flowchart-v2');
|
expect(graph.type).toBe('flowchart-v2');
|
||||||
const sequence = (await Diagram.fromText(
|
const sequence = await Diagram.fromText(
|
||||||
'sequenceDiagram; Alice->>+John: Hello John, how are you?'
|
'sequenceDiagram; Alice->>+John: Hello John, how are you?'
|
||||||
)) as Diagram;
|
);
|
||||||
expect(sequence).toBeInstanceOf(Diagram);
|
expect(sequence).toBeInstanceOf(Diagram);
|
||||||
expect(sequence.type).toBe('sequence');
|
expect(sequence.type).toBe('sequence');
|
||||||
});
|
});
|
||||||
|
@ -8,9 +8,9 @@ import { clear as commonClear } from '../common/commonDb.js';
|
|||||||
import type { Block, ClassDef } from './blockTypes.js';
|
import type { Block, ClassDef } from './blockTypes.js';
|
||||||
|
|
||||||
// Initialize the node database for simple lookups
|
// Initialize the node database for simple lookups
|
||||||
let blockDatabase: Map<string, Block> = new Map();
|
let blockDatabase = new Map<string, Block>();
|
||||||
let edgeList: Block[] = [];
|
let edgeList: Block[] = [];
|
||||||
let edgeCount: Map<string, number> = new Map();
|
let edgeCount = new Map<string, number>();
|
||||||
|
|
||||||
const COLOR_KEYWORD = 'color';
|
const COLOR_KEYWORD = 'color';
|
||||||
const FILL_KEYWORD = 'fill';
|
const FILL_KEYWORD = 'fill';
|
||||||
@ -18,7 +18,7 @@ const BG_FILL = 'bgFill';
|
|||||||
const STYLECLASS_SEP = ',';
|
const STYLECLASS_SEP = ',';
|
||||||
const config = getConfig();
|
const config = getConfig();
|
||||||
|
|
||||||
let classes: Map<string, ClassDef> = new Map();
|
let classes = new Map<string, ClassDef>();
|
||||||
|
|
||||||
const sanitizeText = (txt: string) => common.sanitizeText(txt, config);
|
const sanitizeText = (txt: string) => common.sanitizeText(txt, config);
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ export const addStyleClass = function (id: string, styleAttributes = '') {
|
|||||||
const fixedAttrib = attrib.replace(/([^;]*);/, '$1').trim();
|
const fixedAttrib = attrib.replace(/([^;]*);/, '$1').trim();
|
||||||
|
|
||||||
// replace some style keywords
|
// replace some style keywords
|
||||||
if (attrib.match(COLOR_KEYWORD)) {
|
if (RegExp(COLOR_KEYWORD).exec(attrib)) {
|
||||||
const newStyle1 = fixedAttrib.replace(FILL_KEYWORD, BG_FILL);
|
const newStyle1 = fixedAttrib.replace(FILL_KEYWORD, BG_FILL);
|
||||||
const newStyle2 = newStyle1.replace(COLOR_KEYWORD, FILL_KEYWORD);
|
const newStyle2 = newStyle1.replace(COLOR_KEYWORD, FILL_KEYWORD);
|
||||||
foundClass.textStyles.push(newStyle2);
|
foundClass.textStyles.push(newStyle2);
|
||||||
@ -89,7 +89,7 @@ export const setCssClass = function (itemIds: string, cssClassName: string) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const populateBlockDatabase = (_blockList: Block[] | Block[][], parent: Block): void => {
|
const populateBlockDatabase = (_blockList: Block[], parent: Block): void => {
|
||||||
const blockList = _blockList.flat();
|
const blockList = _blockList.flat();
|
||||||
const children = [];
|
const children = [];
|
||||||
for (const block of blockList) {
|
for (const block of blockList) {
|
||||||
@ -168,7 +168,7 @@ const clear = (): void => {
|
|||||||
commonClear();
|
commonClear();
|
||||||
rootBlock = { id: 'root', type: 'composite', children: [], columns: -1 } as Block;
|
rootBlock = { id: 'root', type: 'composite', children: [], columns: -1 } as Block;
|
||||||
blockDatabase = new Map([['root', rootBlock]]);
|
blockDatabase = new Map([['root', rootBlock]]);
|
||||||
blocks = [] as Block[];
|
blocks = [];
|
||||||
classes = new Map();
|
classes = new Map();
|
||||||
|
|
||||||
edgeList = [];
|
edgeList = [];
|
||||||
|
@ -75,7 +75,7 @@ export const draw = async function (
|
|||||||
const magicFactor = Math.max(1, Math.round(0.125 * (bounds2.width / bounds2.height)));
|
const magicFactor = Math.max(1, Math.round(0.125 * (bounds2.width / bounds2.height)));
|
||||||
const height = bounds2.height + magicFactor + 10;
|
const height = bounds2.height + magicFactor + 10;
|
||||||
const width = bounds2.width + 10;
|
const width = bounds2.width + 10;
|
||||||
const { useMaxWidth } = conf as Exclude<MermaidConfig['block'], undefined>;
|
const { useMaxWidth } = conf!;
|
||||||
configureSvgSize(svg, height, width, !!useMaxWidth);
|
configureSvgSize(svg, height, width, !!useMaxWidth);
|
||||||
log.debug('Here Bounds', bounds, bounds2);
|
log.debug('Here Bounds', bounds, bounds2);
|
||||||
svg.attr(
|
svg.attr(
|
||||||
|
@ -104,7 +104,7 @@ function setBlockSizes(block: Block, db: BlockDB, siblingWidth = 0, siblingHeigh
|
|||||||
for (const child of block.children) {
|
for (const child of block.children) {
|
||||||
if (child.size) {
|
if (child.size) {
|
||||||
log.debug(
|
log.debug(
|
||||||
`abc95 Setting size of children of ${block.id} id=${child.id} ${maxWidth} ${maxHeight} ${child.size}`
|
`abc95 Setting size of children of ${block.id} id=${child.id} ${maxWidth} ${maxHeight} ${JSON.stringify(child.size)}`
|
||||||
);
|
);
|
||||||
child.size.width =
|
child.size.width =
|
||||||
maxWidth * (child.widthInColumns || 1) + padding * ((child.widthInColumns || 1) - 1);
|
maxWidth * (child.widthInColumns || 1) + padding * ((child.widthInColumns || 1) - 1);
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
// @ts-ignore: jison doesn't export types
|
// @ts-ignore: jison doesn't export types
|
||||||
import block from './block.jison';
|
import block from './block.jison';
|
||||||
import db from '../blockDB.js';
|
import db from '../blockDB.js';
|
||||||
import { cleanupComments } from '../../../diagram-api/comments.js';
|
|
||||||
import { prepareTextForParsing } from '../blockUtils.js';
|
|
||||||
import { setConfig } from '../../../config.js';
|
|
||||||
|
|
||||||
describe('Block diagram', function () {
|
describe('Block diagram', function () {
|
||||||
describe('when parsing an block diagram graph it should handle > ', function () {
|
describe('when parsing an block diagram graph it should handle > ', function () {
|
||||||
@ -13,7 +10,7 @@ describe('Block diagram', function () {
|
|||||||
block.parser.yy.getLogger = () => console;
|
block.parser.yy.getLogger = () => console;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('a diagram with a node', async () => {
|
it('a diagram with a node', () => {
|
||||||
const str = `block-beta
|
const str = `block-beta
|
||||||
id
|
id
|
||||||
`;
|
`;
|
||||||
@ -24,7 +21,7 @@ describe('Block diagram', function () {
|
|||||||
expect(blocks[0].id).toBe('id');
|
expect(blocks[0].id).toBe('id');
|
||||||
expect(blocks[0].label).toBe('id');
|
expect(blocks[0].label).toBe('id');
|
||||||
});
|
});
|
||||||
it('a node with a square shape and a label', async () => {
|
it('a node with a square shape and a label', () => {
|
||||||
const str = `block-beta
|
const str = `block-beta
|
||||||
id["A label"]
|
id["A label"]
|
||||||
`;
|
`;
|
||||||
@ -36,7 +33,7 @@ describe('Block diagram', function () {
|
|||||||
expect(blocks[0].label).toBe('A label');
|
expect(blocks[0].label).toBe('A label');
|
||||||
expect(blocks[0].type).toBe('square');
|
expect(blocks[0].type).toBe('square');
|
||||||
});
|
});
|
||||||
it('a diagram with multiple nodes', async () => {
|
it('a diagram with multiple nodes', () => {
|
||||||
const str = `block-beta
|
const str = `block-beta
|
||||||
id1
|
id1
|
||||||
id2
|
id2
|
||||||
@ -52,7 +49,7 @@ describe('Block diagram', function () {
|
|||||||
expect(blocks[1].label).toBe('id2');
|
expect(blocks[1].label).toBe('id2');
|
||||||
expect(blocks[1].type).toBe('na');
|
expect(blocks[1].type).toBe('na');
|
||||||
});
|
});
|
||||||
it('a diagram with multiple nodes', async () => {
|
it('a diagram with multiple nodes', () => {
|
||||||
const str = `block-beta
|
const str = `block-beta
|
||||||
id1
|
id1
|
||||||
id2
|
id2
|
||||||
@ -73,7 +70,7 @@ describe('Block diagram', function () {
|
|||||||
expect(blocks[2].type).toBe('na');
|
expect(blocks[2].type).toBe('na');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('a node with a square shape and a label', async () => {
|
it('a node with a square shape and a label', () => {
|
||||||
const str = `block-beta
|
const str = `block-beta
|
||||||
id["A label"]
|
id["A label"]
|
||||||
id2`;
|
id2`;
|
||||||
@ -88,7 +85,7 @@ describe('Block diagram', function () {
|
|||||||
expect(blocks[1].label).toBe('id2');
|
expect(blocks[1].label).toBe('id2');
|
||||||
expect(blocks[1].type).toBe('na');
|
expect(blocks[1].type).toBe('na');
|
||||||
});
|
});
|
||||||
it('a diagram with multiple nodes with edges abc123', async () => {
|
it('a diagram with multiple nodes with edges abc123', () => {
|
||||||
const str = `block-beta
|
const str = `block-beta
|
||||||
id1["first"] --> id2["second"]
|
id1["first"] --> id2["second"]
|
||||||
`;
|
`;
|
||||||
@ -102,7 +99,7 @@ describe('Block diagram', function () {
|
|||||||
expect(edges[0].end).toBe('id2');
|
expect(edges[0].end).toBe('id2');
|
||||||
expect(edges[0].arrowTypeEnd).toBe('arrow_point');
|
expect(edges[0].arrowTypeEnd).toBe('arrow_point');
|
||||||
});
|
});
|
||||||
it('a diagram with multiple nodes with edges abc123', async () => {
|
it('a diagram with multiple nodes with edges abc123', () => {
|
||||||
const str = `block-beta
|
const str = `block-beta
|
||||||
id1["first"] -- "a label" --> id2["second"]
|
id1["first"] -- "a label" --> id2["second"]
|
||||||
`;
|
`;
|
||||||
@ -117,7 +114,7 @@ describe('Block diagram', function () {
|
|||||||
expect(edges[0].arrowTypeEnd).toBe('arrow_point');
|
expect(edges[0].arrowTypeEnd).toBe('arrow_point');
|
||||||
expect(edges[0].label).toBe('a label');
|
expect(edges[0].label).toBe('a label');
|
||||||
});
|
});
|
||||||
it('a diagram with column statements', async () => {
|
it('a diagram with column statements', () => {
|
||||||
const str = `block-beta
|
const str = `block-beta
|
||||||
columns 2
|
columns 2
|
||||||
block1["Block 1"]
|
block1["Block 1"]
|
||||||
@ -128,7 +125,7 @@ describe('Block diagram', function () {
|
|||||||
const blocks = db.getBlocks();
|
const blocks = db.getBlocks();
|
||||||
expect(blocks.length).toBe(1);
|
expect(blocks.length).toBe(1);
|
||||||
});
|
});
|
||||||
it('a diagram withput column statements', async () => {
|
it('a diagram withput column statements', () => {
|
||||||
const str = `block-beta
|
const str = `block-beta
|
||||||
block1["Block 1"]
|
block1["Block 1"]
|
||||||
`;
|
`;
|
||||||
@ -138,7 +135,7 @@ describe('Block diagram', function () {
|
|||||||
const blocks = db.getBlocks();
|
const blocks = db.getBlocks();
|
||||||
expect(blocks.length).toBe(1);
|
expect(blocks.length).toBe(1);
|
||||||
});
|
});
|
||||||
it('a diagram with auto column statements', async () => {
|
it('a diagram with auto column statements', () => {
|
||||||
const str = `block-beta
|
const str = `block-beta
|
||||||
columns auto
|
columns auto
|
||||||
block1["Block 1"]
|
block1["Block 1"]
|
||||||
@ -150,7 +147,7 @@ describe('Block diagram', function () {
|
|||||||
expect(blocks.length).toBe(1);
|
expect(blocks.length).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('blocks next to each other', async () => {
|
it('blocks next to each other', () => {
|
||||||
const str = `block-beta
|
const str = `block-beta
|
||||||
columns 2
|
columns 2
|
||||||
block1["Block 1"]
|
block1["Block 1"]
|
||||||
@ -164,7 +161,7 @@ describe('Block diagram', function () {
|
|||||||
expect(blocks.length).toBe(2);
|
expect(blocks.length).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('blocks on top of each other', async () => {
|
it('blocks on top of each other', () => {
|
||||||
const str = `block-beta
|
const str = `block-beta
|
||||||
columns 1
|
columns 1
|
||||||
block1["Block 1"]
|
block1["Block 1"]
|
||||||
@ -178,7 +175,7 @@ describe('Block diagram', function () {
|
|||||||
expect(blocks.length).toBe(2);
|
expect(blocks.length).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('compound blocks 2', async () => {
|
it('compound blocks 2', () => {
|
||||||
const str = `block-beta
|
const str = `block-beta
|
||||||
block
|
block
|
||||||
aBlock["ABlock"]
|
aBlock["ABlock"]
|
||||||
@ -206,7 +203,7 @@ describe('Block diagram', function () {
|
|||||||
expect(bBlock.label).toBe('BBlock');
|
expect(bBlock.label).toBe('BBlock');
|
||||||
expect(bBlock.type).toBe('square');
|
expect(bBlock.type).toBe('square');
|
||||||
});
|
});
|
||||||
it('compound blocks of compound blocks', async () => {
|
it('compound blocks of compound blocks', () => {
|
||||||
const str = `block-beta
|
const str = `block-beta
|
||||||
block
|
block
|
||||||
aBlock["ABlock"]
|
aBlock["ABlock"]
|
||||||
@ -241,7 +238,7 @@ describe('Block diagram', function () {
|
|||||||
expect(bBlock.label).toBe('BBlock');
|
expect(bBlock.label).toBe('BBlock');
|
||||||
expect(bBlock.type).toBe('square');
|
expect(bBlock.type).toBe('square');
|
||||||
});
|
});
|
||||||
it('compound blocks with title', async () => {
|
it('compound blocks with title', () => {
|
||||||
const str = `block-beta
|
const str = `block-beta
|
||||||
block:compoundBlock["Compound block"]
|
block:compoundBlock["Compound block"]
|
||||||
columns 1
|
columns 1
|
||||||
@ -266,7 +263,7 @@ describe('Block diagram', function () {
|
|||||||
expect(block2.label).toBe('Block 2');
|
expect(block2.label).toBe('Block 2');
|
||||||
expect(block2.type).toBe('square');
|
expect(block2.type).toBe('square');
|
||||||
});
|
});
|
||||||
it('blocks mixed with compound blocks', async () => {
|
it('blocks mixed with compound blocks', () => {
|
||||||
const str = `block-beta
|
const str = `block-beta
|
||||||
columns 1
|
columns 1
|
||||||
block1["Block 1"]
|
block1["Block 1"]
|
||||||
@ -293,7 +290,7 @@ describe('Block diagram', function () {
|
|||||||
expect(block2.type).toBe('square');
|
expect(block2.type).toBe('square');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Arrow blocks', async () => {
|
it('Arrow blocks', () => {
|
||||||
const str = `block-beta
|
const str = `block-beta
|
||||||
columns 3
|
columns 3
|
||||||
block1["Block 1"]
|
block1["Block 1"]
|
||||||
@ -317,7 +314,7 @@ describe('Block diagram', function () {
|
|||||||
expect(blockArrow.type).toBe('block_arrow');
|
expect(blockArrow.type).toBe('block_arrow');
|
||||||
expect(blockArrow.directions).toContain('right');
|
expect(blockArrow.directions).toContain('right');
|
||||||
});
|
});
|
||||||
it('Arrow blocks with multiple points', async () => {
|
it('Arrow blocks with multiple points', () => {
|
||||||
const str = `block-beta
|
const str = `block-beta
|
||||||
columns 1
|
columns 1
|
||||||
A
|
A
|
||||||
@ -340,7 +337,7 @@ describe('Block diagram', function () {
|
|||||||
expect(blockArrow.directions).toContain('down');
|
expect(blockArrow.directions).toContain('down');
|
||||||
expect(blockArrow.directions).not.toContain('right');
|
expect(blockArrow.directions).not.toContain('right');
|
||||||
});
|
});
|
||||||
it('blocks with different widths', async () => {
|
it('blocks with different widths', () => {
|
||||||
const str = `block-beta
|
const str = `block-beta
|
||||||
columns 3
|
columns 3
|
||||||
one["One Slot"]
|
one["One Slot"]
|
||||||
@ -355,7 +352,7 @@ describe('Block diagram', function () {
|
|||||||
const two = blocks[1];
|
const two = blocks[1];
|
||||||
expect(two.widthInColumns).toBe(2);
|
expect(two.widthInColumns).toBe(2);
|
||||||
});
|
});
|
||||||
it('empty blocks', async () => {
|
it('empty blocks', () => {
|
||||||
const str = `block-beta
|
const str = `block-beta
|
||||||
columns 3
|
columns 3
|
||||||
space
|
space
|
||||||
@ -374,7 +371,7 @@ describe('Block diagram', function () {
|
|||||||
expect(sp2.type).toBe('space');
|
expect(sp2.type).toBe('space');
|
||||||
expect(middle.label).toBe('In the middle');
|
expect(middle.label).toBe('In the middle');
|
||||||
});
|
});
|
||||||
it('classDef statements applied to a block', async () => {
|
it('classDef statements applied to a block', () => {
|
||||||
const str = `block-beta
|
const str = `block-beta
|
||||||
classDef black color:#ffffff, fill:#000000;
|
classDef black color:#ffffff, fill:#000000;
|
||||||
|
|
||||||
@ -392,7 +389,7 @@ describe('Block diagram', function () {
|
|||||||
expect(black.id).toBe('black');
|
expect(black.id).toBe('black');
|
||||||
expect(black.styles[0]).toEqual('color:#ffffff');
|
expect(black.styles[0]).toEqual('color:#ffffff');
|
||||||
});
|
});
|
||||||
it('style statements applied to a block', async () => {
|
it('style statements applied to a block', () => {
|
||||||
const str = `block-beta
|
const str = `block-beta
|
||||||
columns 1
|
columns 1
|
||||||
B["A wide one in the middle"]
|
B["A wide one in the middle"]
|
||||||
|
@ -218,7 +218,7 @@ export async function insertEdges(
|
|||||||
{ x: end.x, y: end.y },
|
{ x: end.x, y: end.y },
|
||||||
];
|
];
|
||||||
// edge.points = points;
|
// edge.points = points;
|
||||||
await insertEdge(
|
insertEdge(
|
||||||
elem,
|
elem,
|
||||||
{ v: edge.start, w: edge.end, name: edge.id },
|
{ v: edge.start, w: edge.end, name: edge.id },
|
||||||
{
|
{
|
||||||
@ -243,7 +243,7 @@ export async function insertEdges(
|
|||||||
points,
|
points,
|
||||||
classes: 'edge-thickness-normal edge-pattern-solid flowchart-link LS-a1 LE-b1',
|
classes: 'edge-thickness-normal edge-pattern-solid flowchart-link LS-a1 LE-b1',
|
||||||
});
|
});
|
||||||
await positionEdgeLabel(
|
positionEdgeLabel(
|
||||||
{ ...edge, x: points[1].x, y: points[1].y },
|
{ ...edge, x: points[1].x, y: points[1].y },
|
||||||
{
|
{
|
||||||
originalPath: points,
|
originalPath: points,
|
||||||
|
@ -258,21 +258,21 @@ export const drawC4ShapeArray = function (currentBounds, diagram, c4ShapeArray,
|
|||||||
c4ShapeLabelConf.fontSize = c4ShapeLabelConf.fontSize + 2;
|
c4ShapeLabelConf.fontSize = c4ShapeLabelConf.fontSize + 2;
|
||||||
c4ShapeLabelConf.fontWeight = 'bold';
|
c4ShapeLabelConf.fontWeight = 'bold';
|
||||||
calcC4ShapeTextWH('label', c4Shape, c4ShapeTextWrap, c4ShapeLabelConf, textLimitWidth);
|
calcC4ShapeTextWH('label', c4Shape, c4ShapeTextWrap, c4ShapeLabelConf, textLimitWidth);
|
||||||
c4Shape['label'].Y = Y + 8;
|
c4Shape.label.Y = Y + 8;
|
||||||
Y = c4Shape['label'].Y + c4Shape['label'].height;
|
Y = c4Shape.label.Y + c4Shape.label.height;
|
||||||
|
|
||||||
if (c4Shape.type && c4Shape.type.text !== '') {
|
if (c4Shape.type && c4Shape.type.text !== '') {
|
||||||
c4Shape.type.text = '[' + c4Shape.type.text + ']';
|
c4Shape.type.text = '[' + c4Shape.type.text + ']';
|
||||||
let c4ShapeTypeConf = c4ShapeFont(conf, c4Shape.typeC4Shape.text);
|
let c4ShapeTypeConf = c4ShapeFont(conf, c4Shape.typeC4Shape.text);
|
||||||
calcC4ShapeTextWH('type', c4Shape, c4ShapeTextWrap, c4ShapeTypeConf, textLimitWidth);
|
calcC4ShapeTextWH('type', c4Shape, c4ShapeTextWrap, c4ShapeTypeConf, textLimitWidth);
|
||||||
c4Shape['type'].Y = Y + 5;
|
c4Shape.type.Y = Y + 5;
|
||||||
Y = c4Shape['type'].Y + c4Shape['type'].height;
|
Y = c4Shape.type.Y + c4Shape.type.height;
|
||||||
} else if (c4Shape.techn && c4Shape.techn.text !== '') {
|
} else if (c4Shape.techn && c4Shape.techn.text !== '') {
|
||||||
c4Shape.techn.text = '[' + c4Shape.techn.text + ']';
|
c4Shape.techn.text = '[' + c4Shape.techn.text + ']';
|
||||||
let c4ShapeTechnConf = c4ShapeFont(conf, c4Shape.techn.text);
|
let c4ShapeTechnConf = c4ShapeFont(conf, c4Shape.techn.text);
|
||||||
calcC4ShapeTextWH('techn', c4Shape, c4ShapeTextWrap, c4ShapeTechnConf, textLimitWidth);
|
calcC4ShapeTextWH('techn', c4Shape, c4ShapeTextWrap, c4ShapeTechnConf, textLimitWidth);
|
||||||
c4Shape['techn'].Y = Y + 5;
|
c4Shape.techn.Y = Y + 5;
|
||||||
Y = c4Shape['techn'].Y + c4Shape['techn'].height;
|
Y = c4Shape.techn.Y + c4Shape.techn.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
let rectHeight = Y;
|
let rectHeight = Y;
|
||||||
@ -281,11 +281,11 @@ export const drawC4ShapeArray = function (currentBounds, diagram, c4ShapeArray,
|
|||||||
if (c4Shape.descr && c4Shape.descr.text !== '') {
|
if (c4Shape.descr && c4Shape.descr.text !== '') {
|
||||||
let c4ShapeDescrConf = c4ShapeFont(conf, c4Shape.typeC4Shape.text);
|
let c4ShapeDescrConf = c4ShapeFont(conf, c4Shape.typeC4Shape.text);
|
||||||
calcC4ShapeTextWH('descr', c4Shape, c4ShapeTextWrap, c4ShapeDescrConf, textLimitWidth);
|
calcC4ShapeTextWH('descr', c4Shape, c4ShapeTextWrap, c4ShapeDescrConf, textLimitWidth);
|
||||||
c4Shape['descr'].Y = Y + 20;
|
c4Shape.descr.Y = Y + 20;
|
||||||
Y = c4Shape['descr'].Y + c4Shape['descr'].height;
|
Y = c4Shape.descr.Y + c4Shape.descr.height;
|
||||||
|
|
||||||
rectWidth = Math.max(c4Shape.label.width, c4Shape.descr.width);
|
rectWidth = Math.max(c4Shape.label.width, c4Shape.descr.width);
|
||||||
rectHeight = Y - c4Shape['descr'].textLines * 5;
|
rectHeight = Y - c4Shape.descr.textLines * 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
rectWidth = rectWidth + conf.c4ShapePadding;
|
rectWidth = rectWidth + conf.c4ShapePadding;
|
||||||
@ -482,8 +482,8 @@ function drawInsideBoundary(
|
|||||||
currentBoundaryLabelConf,
|
currentBoundaryLabelConf,
|
||||||
currentBounds.data.widthLimit
|
currentBounds.data.widthLimit
|
||||||
);
|
);
|
||||||
currentBoundary['label'].Y = Y + 8;
|
currentBoundary.label.Y = Y + 8;
|
||||||
Y = currentBoundary['label'].Y + currentBoundary['label'].height;
|
Y = currentBoundary.label.Y + currentBoundary.label.height;
|
||||||
|
|
||||||
if (currentBoundary.type && currentBoundary.type.text !== '') {
|
if (currentBoundary.type && currentBoundary.type.text !== '') {
|
||||||
currentBoundary.type.text = '[' + currentBoundary.type.text + ']';
|
currentBoundary.type.text = '[' + currentBoundary.type.text + ']';
|
||||||
@ -495,8 +495,8 @@ function drawInsideBoundary(
|
|||||||
currentBoundaryTypeConf,
|
currentBoundaryTypeConf,
|
||||||
currentBounds.data.widthLimit
|
currentBounds.data.widthLimit
|
||||||
);
|
);
|
||||||
currentBoundary['type'].Y = Y + 5;
|
currentBoundary.type.Y = Y + 5;
|
||||||
Y = currentBoundary['type'].Y + currentBoundary['type'].height;
|
Y = currentBoundary.type.Y + currentBoundary.type.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentBoundary.descr && currentBoundary.descr.text !== '') {
|
if (currentBoundary.descr && currentBoundary.descr.text !== '') {
|
||||||
@ -509,8 +509,8 @@ function drawInsideBoundary(
|
|||||||
currentBoundaryDescrConf,
|
currentBoundaryDescrConf,
|
||||||
currentBounds.data.widthLimit
|
currentBounds.data.widthLimit
|
||||||
);
|
);
|
||||||
currentBoundary['descr'].Y = Y + 20;
|
currentBoundary.descr.Y = Y + 20;
|
||||||
Y = currentBoundary['descr'].Y + currentBoundary['descr'].height;
|
Y = currentBoundary.descr.Y + currentBoundary.descr.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == 0 || i % c4BoundaryInRow === 0) {
|
if (i == 0 || i % c4BoundaryInRow === 0) {
|
||||||
|
@ -26,10 +26,10 @@ import type {
|
|||||||
const MERMAID_DOM_ID_PREFIX = 'classId-';
|
const MERMAID_DOM_ID_PREFIX = 'classId-';
|
||||||
|
|
||||||
let relations: ClassRelation[] = [];
|
let relations: ClassRelation[] = [];
|
||||||
let classes: Map<string, ClassNode> = new Map();
|
let classes = new Map<string, ClassNode>();
|
||||||
let notes: ClassNote[] = [];
|
let notes: ClassNote[] = [];
|
||||||
let classCounter = 0;
|
let classCounter = 0;
|
||||||
let namespaces: Map<string, NamespaceNode> = new Map();
|
let namespaces = new Map<string, NamespaceNode>();
|
||||||
let namespaceCounter = 0;
|
let namespaceCounter = 0;
|
||||||
|
|
||||||
let functions: any[] = [];
|
let functions: any[] = [];
|
||||||
@ -223,7 +223,7 @@ export const cleanupLabel = function (label: string) {
|
|||||||
export const setCssClass = function (ids: string, className: string) {
|
export const setCssClass = function (ids: string, className: string) {
|
||||||
ids.split(',').forEach(function (_id) {
|
ids.split(',').forEach(function (_id) {
|
||||||
let id = _id;
|
let id = _id;
|
||||||
if (_id[0].match(/\d/)) {
|
if (/\d/.exec(_id[0])) {
|
||||||
id = MERMAID_DOM_ID_PREFIX + id;
|
id = MERMAID_DOM_ID_PREFIX + id;
|
||||||
}
|
}
|
||||||
const classNode = classes.get(id);
|
const classNode = classes.get(id);
|
||||||
@ -266,7 +266,7 @@ export const setLink = function (ids: string, linkStr: string, target: string) {
|
|||||||
const config = getConfig();
|
const config = getConfig();
|
||||||
ids.split(',').forEach(function (_id) {
|
ids.split(',').forEach(function (_id) {
|
||||||
let id = _id;
|
let id = _id;
|
||||||
if (_id[0].match(/\d/)) {
|
if (/\d/.exec(_id[0])) {
|
||||||
id = MERMAID_DOM_ID_PREFIX + id;
|
id = MERMAID_DOM_ID_PREFIX + id;
|
||||||
}
|
}
|
||||||
const theClass = classes.get(id);
|
const theClass = classes.get(id);
|
||||||
@ -320,7 +320,7 @@ const setClickFunc = function (_domId: string, functionName: string, functionArg
|
|||||||
let item = argList[i].trim();
|
let item = argList[i].trim();
|
||||||
/* Removes all double quotes at the start and end of an argument */
|
/* Removes all double quotes at the start and end of an argument */
|
||||||
/* This preserves all starting and ending whitespace inside */
|
/* This preserves all starting and ending whitespace inside */
|
||||||
if (item.charAt(0) === '"' && item.charAt(item.length - 1) === '"') {
|
if (item.startsWith('"') && item.endsWith('"')) {
|
||||||
item = item.substr(1, item.length - 2);
|
item = item.substr(1, item.length - 2);
|
||||||
}
|
}
|
||||||
argList[i] = item;
|
argList[i] = item;
|
||||||
|
@ -343,7 +343,7 @@ export const draw = async function (text: string, id: string, _version: string,
|
|||||||
}
|
}
|
||||||
const root =
|
const root =
|
||||||
securityLevel === 'sandbox'
|
securityLevel === 'sandbox'
|
||||||
? select(sandboxElement!.nodes()[0]!.contentDocument.body)
|
? select(sandboxElement.nodes()[0]!.contentDocument.body)
|
||||||
: select('body');
|
: select('body');
|
||||||
const svg = root.select(`[id="${id}"]`);
|
const svg = root.select(`[id="${id}"]`);
|
||||||
|
|
||||||
@ -363,8 +363,7 @@ export const draw = async function (text: string, id: string, _version: string,
|
|||||||
|
|
||||||
// Add label rects for non html labels
|
// Add label rects for non html labels
|
||||||
if (!conf?.htmlLabels) {
|
if (!conf?.htmlLabels) {
|
||||||
const doc =
|
const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0]!.contentDocument : document;
|
||||||
securityLevel === 'sandbox' ? sandboxElement!.nodes()[0]!.contentDocument : document;
|
|
||||||
const labels = doc.querySelectorAll('[id="' + id + '"] .edgeLabel .label');
|
const labels = doc.querySelectorAll('[id="' + id + '"] .edgeLabel .label');
|
||||||
for (const label of labels) {
|
for (const label of labels) {
|
||||||
// Get dimensions of label
|
// Get dimensions of label
|
||||||
|
@ -77,7 +77,7 @@ export class ClassMember {
|
|||||||
|
|
||||||
if (this.memberType === 'method') {
|
if (this.memberType === 'method') {
|
||||||
const methodRegEx = /([#+~-])?(.+)\((.*)\)([\s$*])?(.*)([$*])?/;
|
const methodRegEx = /([#+~-])?(.+)\((.*)\)([\s$*])?(.*)([$*])?/;
|
||||||
const match = input.match(methodRegEx);
|
const match = methodRegEx.exec(input);
|
||||||
if (match) {
|
if (match) {
|
||||||
const detectedVisibility = match[1] ? match[1].trim() : '';
|
const detectedVisibility = match[1] ? match[1].trim() : '';
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ export class ClassMember {
|
|||||||
|
|
||||||
if (potentialClassifier === '') {
|
if (potentialClassifier === '') {
|
||||||
const lastChar = this.returnType.substring(this.returnType.length - 1);
|
const lastChar = this.returnType.substring(this.returnType.length - 1);
|
||||||
if (lastChar.match(/[$*]/)) {
|
if (/[$*]/.exec(lastChar)) {
|
||||||
potentialClassifier = lastChar;
|
potentialClassifier = lastChar;
|
||||||
this.returnType = this.returnType.substring(0, this.returnType.length - 1);
|
this.returnType = this.returnType.substring(0, this.returnType.length - 1);
|
||||||
}
|
}
|
||||||
@ -107,7 +107,7 @@ export class ClassMember {
|
|||||||
this.visibility = firstChar as Visibility;
|
this.visibility = firstChar as Visibility;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastChar.match(/[$*]/)) {
|
if (/[$*]/.exec(lastChar)) {
|
||||||
potentialClassifier = lastChar;
|
potentialClassifier = lastChar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,6 +83,7 @@ export const sanitizeText = (text: string, config: MermaidConfig): string => {
|
|||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
if (config.dompurifyConfig) {
|
if (config.dompurifyConfig) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
||||||
text = DOMPurify.sanitize(sanitizeMore(text, config), config.dompurifyConfig).toString();
|
text = DOMPurify.sanitize(sanitizeMore(text, config), config.dompurifyConfig).toString();
|
||||||
} else {
|
} else {
|
||||||
text = DOMPurify.sanitize(sanitizeMore(text, config), {
|
text = DOMPurify.sanitize(sanitizeMore(text, config), {
|
||||||
|
@ -17,12 +17,12 @@ import type { FlowVertex, FlowClass, FlowSubGraph, FlowText, FlowEdge, FlowLink
|
|||||||
const MERMAID_DOM_ID_PREFIX = 'flowchart-';
|
const MERMAID_DOM_ID_PREFIX = 'flowchart-';
|
||||||
let vertexCounter = 0;
|
let vertexCounter = 0;
|
||||||
let config = getConfig();
|
let config = getConfig();
|
||||||
let vertices: Map<string, FlowVertex> = new Map();
|
let vertices = new Map<string, FlowVertex>();
|
||||||
let edges: FlowEdge[] & { defaultInterpolate?: string; defaultStyle?: string[] } = [];
|
let edges: FlowEdge[] & { defaultInterpolate?: string; defaultStyle?: string[] } = [];
|
||||||
let classes: Map<string, FlowClass> = new Map();
|
let classes = new Map<string, FlowClass>();
|
||||||
let subGraphs: FlowSubGraph[] = [];
|
let subGraphs: FlowSubGraph[] = [];
|
||||||
let subGraphLookup: Map<string, FlowSubGraph> = new Map();
|
let subGraphLookup = new Map<string, FlowSubGraph>();
|
||||||
let tooltips: Map<string, string> = new Map();
|
let tooltips = new Map<string, string>();
|
||||||
let subCount = 0;
|
let subCount = 0;
|
||||||
let firstGraphFlag = true;
|
let firstGraphFlag = true;
|
||||||
let direction: string;
|
let direction: string;
|
||||||
@ -84,7 +84,7 @@ export const addVertex = function (
|
|||||||
txt = sanitizeText(textObj.text.trim());
|
txt = sanitizeText(textObj.text.trim());
|
||||||
vertex.labelType = textObj.type;
|
vertex.labelType = textObj.type;
|
||||||
// strip quotes if string starts and ends with a quote
|
// strip quotes if string starts and ends with a quote
|
||||||
if (txt[0] === '"' && txt[txt.length - 1] === '"') {
|
if (txt.startsWith('"') && txt.endsWith('"')) {
|
||||||
txt = txt.substring(1, txt.length - 1);
|
txt = txt.substring(1, txt.length - 1);
|
||||||
}
|
}
|
||||||
vertex.text = txt;
|
vertex.text = txt;
|
||||||
@ -132,7 +132,7 @@ export const addSingleLink = function (_start: string, _end: string, type: any)
|
|||||||
edge.text = sanitizeText(linkTextObj.text.trim());
|
edge.text = sanitizeText(linkTextObj.text.trim());
|
||||||
|
|
||||||
// strip quotes if string starts and ends with a quote
|
// strip quotes if string starts and ends with a quote
|
||||||
if (edge.text[0] === '"' && edge.text[edge.text.length - 1] === '"') {
|
if (edge.text.startsWith('"') && edge.text.endsWith('"')) {
|
||||||
edge.text = edge.text.substring(1, edge.text.length - 1);
|
edge.text = edge.text.substring(1, edge.text.length - 1);
|
||||||
}
|
}
|
||||||
edge.labelType = linkTextObj.type;
|
edge.labelType = linkTextObj.type;
|
||||||
@ -218,7 +218,7 @@ export const addClass = function (ids: string, style: string[]) {
|
|||||||
|
|
||||||
if (style !== undefined && style !== null) {
|
if (style !== undefined && style !== null) {
|
||||||
style.forEach(function (s) {
|
style.forEach(function (s) {
|
||||||
if (s.match('color')) {
|
if (/color/.exec(s)) {
|
||||||
const newStyle = s.replace('fill', 'bgFill').replace('color', 'fill');
|
const newStyle = s.replace('fill', 'bgFill').replace('color', 'fill');
|
||||||
classNode.textStyles.push(newStyle);
|
classNode.textStyles.push(newStyle);
|
||||||
}
|
}
|
||||||
@ -234,16 +234,16 @@ export const addClass = function (ids: string, style: string[]) {
|
|||||||
*/
|
*/
|
||||||
export const setDirection = function (dir: string) {
|
export const setDirection = function (dir: string) {
|
||||||
direction = dir;
|
direction = dir;
|
||||||
if (direction.match(/.*</)) {
|
if (/.*</.exec(direction)) {
|
||||||
direction = 'RL';
|
direction = 'RL';
|
||||||
}
|
}
|
||||||
if (direction.match(/.*\^/)) {
|
if (/.*\^/.exec(direction)) {
|
||||||
direction = 'BT';
|
direction = 'BT';
|
||||||
}
|
}
|
||||||
if (direction.match(/.*>/)) {
|
if (/.*>/.exec(direction)) {
|
||||||
direction = 'LR';
|
direction = 'LR';
|
||||||
}
|
}
|
||||||
if (direction.match(/.*v/)) {
|
if (/.*v/.exec(direction)) {
|
||||||
direction = 'TB';
|
direction = 'TB';
|
||||||
}
|
}
|
||||||
if (direction === 'TD') {
|
if (direction === 'TD') {
|
||||||
@ -297,7 +297,7 @@ const setClickFun = function (id: string, functionName: string, functionArgs: st
|
|||||||
let item = argList[i].trim();
|
let item = argList[i].trim();
|
||||||
/* Removes all double quotes at the start and end of an argument */
|
/* Removes all double quotes at the start and end of an argument */
|
||||||
/* This preserves all starting and ending whitespace inside */
|
/* This preserves all starting and ending whitespace inside */
|
||||||
if (item.charAt(0) === '"' && item.charAt(item.length - 1) === '"') {
|
if (item.startsWith('"') && item.endsWith('"')) {
|
||||||
item = item.substr(1, item.length - 2);
|
item = item.substr(1, item.length - 2);
|
||||||
}
|
}
|
||||||
argList[i] = item;
|
argList[i] = item;
|
||||||
@ -469,7 +469,7 @@ export const addSubGraph = function (
|
|||||||
) {
|
) {
|
||||||
let id: string | undefined = _id.text.trim();
|
let id: string | undefined = _id.text.trim();
|
||||||
let title = _title.text;
|
let title = _title.text;
|
||||||
if (_id === _title && _title.text.match(/\s/)) {
|
if (_id === _title && /\s/.exec(_title.text)) {
|
||||||
id = undefined;
|
id = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -651,21 +651,21 @@ const destructEndLink = (_str: string) => {
|
|||||||
switch (str.slice(-1)) {
|
switch (str.slice(-1)) {
|
||||||
case 'x':
|
case 'x':
|
||||||
type = 'arrow_cross';
|
type = 'arrow_cross';
|
||||||
if (str[0] === 'x') {
|
if (str.startsWith('x')) {
|
||||||
type = 'double_' + type;
|
type = 'double_' + type;
|
||||||
line = line.slice(1);
|
line = line.slice(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '>':
|
case '>':
|
||||||
type = 'arrow_point';
|
type = 'arrow_point';
|
||||||
if (str[0] === '<') {
|
if (str.startsWith('<')) {
|
||||||
type = 'double_' + type;
|
type = 'double_' + type;
|
||||||
line = line.slice(1);
|
line = line.slice(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
type = 'arrow_circle';
|
type = 'arrow_circle';
|
||||||
if (str[0] === 'o') {
|
if (str.startsWith('o')) {
|
||||||
type = 'double_' + type;
|
type = 'double_' + type;
|
||||||
line = line.slice(1);
|
line = line.slice(1);
|
||||||
}
|
}
|
||||||
@ -675,11 +675,11 @@ const destructEndLink = (_str: string) => {
|
|||||||
let stroke = 'normal';
|
let stroke = 'normal';
|
||||||
let length = line.length - 1;
|
let length = line.length - 1;
|
||||||
|
|
||||||
if (line[0] === '=') {
|
if (line.startsWith('=')) {
|
||||||
stroke = 'thick';
|
stroke = 'thick';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (line[0] === '~') {
|
if (line.startsWith('~')) {
|
||||||
stroke = 'invisible';
|
stroke = 'invisible';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -676,7 +676,7 @@ const setClickFun = function (id, functionName, functionArgs) {
|
|||||||
let item = argList[i].trim();
|
let item = argList[i].trim();
|
||||||
/* Removes all double quotes at the start and end of an argument */
|
/* Removes all double quotes at the start and end of an argument */
|
||||||
/* This preserves all starting and ending whitespace inside */
|
/* This preserves all starting and ending whitespace inside */
|
||||||
if (item.charAt(0) === '"' && item.charAt(item.length - 1) === '"') {
|
if (item.startsWith('"') && item.endsWith('"')) {
|
||||||
item = item.substr(1, item.length - 2);
|
item = item.substr(1, item.length - 2);
|
||||||
}
|
}
|
||||||
argList[i] = item;
|
argList[i] = item;
|
||||||
|
@ -90,7 +90,7 @@ export const setDirection = function (dir) {
|
|||||||
let options = {};
|
let options = {};
|
||||||
export const setOptions = function (rawOptString) {
|
export const setOptions = function (rawOptString) {
|
||||||
log.debug('options str', rawOptString);
|
log.debug('options str', rawOptString);
|
||||||
rawOptString = rawOptString && rawOptString.trim();
|
rawOptString = rawOptString?.trim();
|
||||||
rawOptString = rawOptString || '{}';
|
rawOptString = rawOptString || '{}';
|
||||||
try {
|
try {
|
||||||
options = JSON.parse(rawOptString);
|
options = JSON.parse(rawOptString);
|
||||||
|
@ -36,7 +36,7 @@ describe('when parsing a gitGraph', function () {
|
|||||||
|
|
||||||
parser.parse(str);
|
parser.parse(str);
|
||||||
const commits = parser.yy.getCommits();
|
const commits = parser.yy.getCommits();
|
||||||
expect(parser.yy.getOptions()['key']).toBe('value');
|
expect(parser.yy.getOptions().key).toBe('value');
|
||||||
expect(commits.size).toBe(1);
|
expect(commits.size).toBe(1);
|
||||||
expect(parser.yy.getCurrentBranch()).toBe('main');
|
expect(parser.yy.getCurrentBranch()).toBe('main');
|
||||||
expect(parser.yy.getDirection()).toBe('LR');
|
expect(parser.yy.getDirection()).toBe('LR');
|
||||||
|
@ -127,7 +127,7 @@ export class QuadrantBuilder {
|
|||||||
private config: QuadrantBuilderConfig;
|
private config: QuadrantBuilderConfig;
|
||||||
private themeConfig: QuadrantBuilderThemeConfig;
|
private themeConfig: QuadrantBuilderThemeConfig;
|
||||||
private data: QuadrantBuilderData;
|
private data: QuadrantBuilderData;
|
||||||
private classes: Map<string, StylesObject> = new Map();
|
private classes = new Map<string, StylesObject>();
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.config = this.getDefaultConfig();
|
this.config = this.getDefaultConfig();
|
||||||
|
@ -13,7 +13,7 @@ describe('Sankey diagram', function () {
|
|||||||
sankey.parser.yy.clear();
|
sankey.parser.yy.clear();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('parses csv', async () => {
|
it('parses csv', () => {
|
||||||
const csv = path.resolve(__dirname, './energy.csv');
|
const csv = path.resolve(__dirname, './energy.csv');
|
||||||
const data = fs.readFileSync(csv, 'utf8');
|
const data = fs.readFileSync(csv, 'utf8');
|
||||||
const graphDefinition = prepareTextForParsing(cleanupComments('sankey-beta\n\n ' + data));
|
const graphDefinition = prepareTextForParsing(cleanupComments('sankey-beta\n\n ' + data));
|
||||||
|
@ -15,7 +15,7 @@ let links: SankeyLink[] = [];
|
|||||||
// Array of nodes guarantees their order
|
// Array of nodes guarantees their order
|
||||||
let nodes: SankeyNode[] = [];
|
let nodes: SankeyNode[] = [];
|
||||||
// We also have to track nodes uniqueness (by ID)
|
// We also have to track nodes uniqueness (by ID)
|
||||||
let nodesMap: Map<string, SankeyNode> = new Map();
|
let nodesMap = new Map<string, SankeyNode>();
|
||||||
|
|
||||||
const clear = (): void => {
|
const clear = (): void => {
|
||||||
links = [];
|
links = [];
|
||||||
@ -28,7 +28,7 @@ class SankeyLink {
|
|||||||
constructor(
|
constructor(
|
||||||
public source: SankeyNode,
|
public source: SankeyNode,
|
||||||
public target: SankeyNode,
|
public target: SankeyNode,
|
||||||
public value: number = 0
|
public value = 0
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ const alignmentsMap: Record<
|
|||||||
export const draw = function (text: string, id: string, _version: string, diagObj: Diagram): void {
|
export const draw = function (text: string, id: string, _version: string, diagObj: Diagram): void {
|
||||||
// Get Sankey config
|
// Get Sankey config
|
||||||
const { securityLevel, sankey: conf } = getConfig();
|
const { securityLevel, sankey: conf } = getConfig();
|
||||||
const defaultSankeyConfig = defaultConfig!.sankey!;
|
const defaultSankeyConfig = defaultConfig.sankey!;
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// This code repeats for every diagram
|
// This code repeats for every diagram
|
||||||
|
@ -80,7 +80,7 @@ export const addActor = function (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Don't allow null descriptions, either
|
// Don't allow null descriptions, either
|
||||||
if (description == null || description.text == null) {
|
if (description?.text == null) {
|
||||||
description = { text: name, wrap: null, type };
|
description = { text: name, wrap: null, type };
|
||||||
}
|
}
|
||||||
if (type == null || description.text == null) {
|
if (type == null || description.text == null) {
|
||||||
@ -155,7 +155,7 @@ export const addSignal = function (
|
|||||||
idTo?: Message['to'],
|
idTo?: Message['to'],
|
||||||
message?: { text: string; wrap: boolean },
|
message?: { text: string; wrap: boolean },
|
||||||
messageType?: number,
|
messageType?: number,
|
||||||
activate: boolean = false
|
activate = false
|
||||||
) {
|
) {
|
||||||
if (messageType === LINETYPE.ACTIVE_END) {
|
if (messageType === LINETYPE.ACTIVE_END) {
|
||||||
const cnt = activationCount(idFrom || '');
|
const cnt = activationCount(idFrom || '');
|
||||||
@ -247,13 +247,13 @@ export const parseMessage = function (str: string) {
|
|||||||
const message = {
|
const message = {
|
||||||
text: trimmedStr.replace(/^:?(?:no)?wrap:/, '').trim(),
|
text: trimmedStr.replace(/^:?(?:no)?wrap:/, '').trim(),
|
||||||
wrap:
|
wrap:
|
||||||
trimmedStr.match(/^:?wrap:/) !== null
|
/^:?wrap:/.exec(trimmedStr) !== null
|
||||||
? true
|
? true
|
||||||
: trimmedStr.match(/^:?nowrap:/) !== null
|
: /^:?nowrap:/.exec(trimmedStr) !== null
|
||||||
? false
|
? false
|
||||||
: undefined,
|
: undefined,
|
||||||
};
|
};
|
||||||
log.debug(`parseMessage: ${message}`);
|
log.debug(`parseMessage: ${JSON.stringify(message)}`);
|
||||||
return message;
|
return message;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -261,12 +261,12 @@ export const parseMessage = function (str: string) {
|
|||||||
// The color can be rgb,rgba,hsl,hsla, or css code names #hex codes are not supported for now because of the way the char # is handled
|
// The color can be rgb,rgba,hsl,hsla, or css code names #hex codes are not supported for now because of the way the char # is handled
|
||||||
// We extract first segment as color, the rest of the line is considered as text
|
// We extract first segment as color, the rest of the line is considered as text
|
||||||
export const parseBoxData = function (str: string) {
|
export const parseBoxData = function (str: string) {
|
||||||
const match = str.match(/^((?:rgba?|hsla?)\s*\(.*\)|\w*)(.*)$/);
|
const match = /^((?:rgba?|hsla?)\s*\(.*\)|\w*)(.*)$/.exec(str);
|
||||||
let color = match != null && match[1] ? match[1].trim() : 'transparent';
|
let color = match?.[1] ? match[1].trim() : 'transparent';
|
||||||
let title = match != null && match[2] ? match[2].trim() : undefined;
|
let title = match?.[2] ? match[2].trim() : undefined;
|
||||||
|
|
||||||
// check that the string is a color
|
// check that the string is a color
|
||||||
if (window && window.CSS) {
|
if (window?.CSS) {
|
||||||
if (!window.CSS.supports('color', color)) {
|
if (!window.CSS.supports('color', color)) {
|
||||||
color = 'transparent';
|
color = 'transparent';
|
||||||
title = str.trim();
|
title = str.trim();
|
||||||
@ -288,9 +288,9 @@ export const parseBoxData = function (str: string) {
|
|||||||
: undefined,
|
: undefined,
|
||||||
wrap:
|
wrap:
|
||||||
title !== undefined
|
title !== undefined
|
||||||
? title.match(/^:?wrap:/) !== null
|
? /^:?wrap:/.exec(title) !== null
|
||||||
? true
|
? true
|
||||||
: title.match(/^:?nowrap:/) !== null
|
: /^:?nowrap:/.exec(title) !== null
|
||||||
? false
|
? false
|
||||||
: undefined
|
: undefined
|
||||||
: undefined,
|
: undefined,
|
||||||
@ -461,12 +461,12 @@ export const addDetails = function (actorId: string, text: { text: string }) {
|
|||||||
const text = elem.innerHTML;
|
const text = elem.innerHTML;
|
||||||
const details = JSON.parse(text);
|
const details = JSON.parse(text);
|
||||||
// add the deserialized text to the actor's property field.
|
// add the deserialized text to the actor's property field.
|
||||||
if (details['properties']) {
|
if (details.properties) {
|
||||||
insertProperties(actor, details['properties']);
|
insertProperties(actor, details.properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (details['links']) {
|
if (details.links) {
|
||||||
insertLinks(actor, details['links']);
|
insertLinks(actor, details.links);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log.error('error while parsing actor details text', e);
|
log.error('error while parsing actor details text', e);
|
||||||
@ -474,13 +474,14 @@ export const addDetails = function (actorId: string, text: { text: string }) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getActorProperty = function (actor: Actor, key: string) {
|
export const getActorProperty = function (actor: Actor, key: string) {
|
||||||
if (actor !== undefined && actor.properties !== undefined) {
|
if (actor?.properties !== undefined) {
|
||||||
return actor.properties[key];
|
return actor.properties[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-redundant-type-constituents
|
||||||
export const apply = function (param: any | AddMessageParams | AddMessageParams[]) {
|
export const apply = function (param: any | AddMessageParams | AddMessageParams[]) {
|
||||||
if (Array.isArray(param)) {
|
if (Array.isArray(param)) {
|
||||||
param.forEach(function (item) {
|
param.forEach(function (item) {
|
||||||
@ -544,7 +545,7 @@ export const apply = function (param: any | AddMessageParams | AddMessageParams[
|
|||||||
if (param.to !== state.records.lastCreated) {
|
if (param.to !== state.records.lastCreated) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'The created participant ' +
|
'The created participant ' +
|
||||||
state.records.lastCreated +
|
state.records.lastCreated.name +
|
||||||
' does not have an associated creating message after its declaration. Please check the sequence diagram.'
|
' does not have an associated creating message after its declaration. Please check the sequence diagram.'
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@ -557,7 +558,7 @@ export const apply = function (param: any | AddMessageParams | AddMessageParams[
|
|||||||
) {
|
) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'The destroyed participant ' +
|
'The destroyed participant ' +
|
||||||
state.records.lastDestroyed +
|
state.records.lastDestroyed.name +
|
||||||
' does not have an associated destroying message after its declaration. Please check the sequence diagram.'
|
' does not have an associated destroying message after its declaration. Please check the sequence diagram.'
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1339,15 +1339,15 @@ link a: Tests @ https://tests.contoso.com/?svc=alice@contoso.com
|
|||||||
|
|
||||||
await mermaidAPI.parse(str);
|
await mermaidAPI.parse(str);
|
||||||
const actors = diagram.db.getActors();
|
const actors = diagram.db.getActors();
|
||||||
expect(actors.get('a').links['Repo']).toBe('https://repo.contoso.com/');
|
expect(actors.get('a').links.Repo).toBe('https://repo.contoso.com/');
|
||||||
expect(actors.get('b').links['Repo']).toBe(undefined);
|
expect(actors.get('b').links.Repo).toBe(undefined);
|
||||||
expect(actors.get('a').links['Dashboard']).toBe('https://dashboard.contoso.com/');
|
expect(actors.get('a').links.Dashboard).toBe('https://dashboard.contoso.com/');
|
||||||
expect(actors.get('b').links['Dashboard']).toBe('https://dashboard.contoso.com/');
|
expect(actors.get('b').links.Dashboard).toBe('https://dashboard.contoso.com/');
|
||||||
expect(actors.get('a').links['On-Call']).toBe('https://oncall.contoso.com/?svc=alice');
|
expect(actors.get('a').links['On-Call']).toBe('https://oncall.contoso.com/?svc=alice');
|
||||||
expect(actors.get('c').links['Dashboard']).toBe(undefined);
|
expect(actors.get('c').links.Dashboard).toBe(undefined);
|
||||||
expect(actors.get('a').links['Endpoint']).toBe('https://alice.contoso.com');
|
expect(actors.get('a').links.Endpoint).toBe('https://alice.contoso.com');
|
||||||
expect(actors.get('a').links['Swagger']).toBe('https://swagger.contoso.com');
|
expect(actors.get('a').links.Swagger).toBe('https://swagger.contoso.com');
|
||||||
expect(actors.get('a').links['Tests']).toBe('https://tests.contoso.com/?svc=alice@contoso.com');
|
expect(actors.get('a').links.Tests).toBe('https://tests.contoso.com/?svc=alice@contoso.com');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle properties EXPERIMENTAL: USE WITH CAUTION', async () => {
|
it('should handle properties EXPERIMENTAL: USE WITH CAUTION', async () => {
|
||||||
@ -1363,11 +1363,11 @@ properties b: {"class": "external-service-actor", "icon": "@computer"}
|
|||||||
|
|
||||||
await mermaidAPI.parse(str);
|
await mermaidAPI.parse(str);
|
||||||
const actors = diagram.db.getActors();
|
const actors = diagram.db.getActors();
|
||||||
expect(actors.get('a').properties['class']).toBe('internal-service-actor');
|
expect(actors.get('a').properties.class).toBe('internal-service-actor');
|
||||||
expect(actors.get('b').properties['class']).toBe('external-service-actor');
|
expect(actors.get('b').properties.class).toBe('external-service-actor');
|
||||||
expect(actors.get('a').properties['icon']).toBe('@clock');
|
expect(actors.get('a').properties.icon).toBe('@clock');
|
||||||
expect(actors.get('b').properties['icon']).toBe('@computer');
|
expect(actors.get('b').properties.icon).toBe('@computer');
|
||||||
expect(actors.get('c').properties['class']).toBe(undefined);
|
expect(actors.get('c').properties.class).toBe(undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle box', async () => {
|
it('should handle box', async () => {
|
||||||
|
@ -359,8 +359,8 @@ const drawActorTypeParticipant = async function (elem, actor, conf, isFooter) {
|
|||||||
|
|
||||||
const rect = svgDrawCommon.getNoteRect();
|
const rect = svgDrawCommon.getNoteRect();
|
||||||
var cssclass = 'actor';
|
var cssclass = 'actor';
|
||||||
if (actor.properties != null && actor.properties['class']) {
|
if (actor.properties?.class) {
|
||||||
cssclass = actor.properties['class'];
|
cssclass = actor.properties.class;
|
||||||
} else {
|
} else {
|
||||||
rect.fill = '#eaeaea';
|
rect.fill = '#eaeaea';
|
||||||
}
|
}
|
||||||
@ -380,8 +380,8 @@ const drawActorTypeParticipant = async function (elem, actor, conf, isFooter) {
|
|||||||
const rectElem = drawRect(g, rect);
|
const rectElem = drawRect(g, rect);
|
||||||
actor.rectData = rect;
|
actor.rectData = rect;
|
||||||
|
|
||||||
if (actor.properties != null && actor.properties['icon']) {
|
if (actor.properties?.icon) {
|
||||||
const iconSrc = actor.properties['icon'].trim();
|
const iconSrc = actor.properties.icon.trim();
|
||||||
if (iconSrc.charAt(0) === '@') {
|
if (iconSrc.charAt(0) === '@') {
|
||||||
svgDrawCommon.drawEmbeddedImage(g, rect.x + rect.width - 20, rect.y + 10, iconSrc.substr(1));
|
svgDrawCommon.drawEmbeddedImage(g, rect.x + rect.width - 20, rect.y + 10, iconSrc.substr(1));
|
||||||
} else {
|
} else {
|
||||||
|
@ -78,8 +78,7 @@ export interface AddMessageParams {
|
|||||||
| 'breakEnd'
|
| 'breakEnd'
|
||||||
| 'parOverStart'
|
| 'parOverStart'
|
||||||
| 'parOverEnd'
|
| 'parOverEnd'
|
||||||
| 'parOverAnd'
|
| 'parOverAnd';
|
||||||
| 'parOverEnd';
|
|
||||||
|
|
||||||
activate: boolean;
|
activate: boolean;
|
||||||
}
|
}
|
||||||
|
@ -465,7 +465,7 @@ export const addStyleClass = function (id, styleAttributes = '') {
|
|||||||
const fixedAttrib = attrib.replace(/([^;]*);/, '$1').trim();
|
const fixedAttrib = attrib.replace(/([^;]*);/, '$1').trim();
|
||||||
|
|
||||||
// replace some style keywords
|
// replace some style keywords
|
||||||
if (attrib.match(COLOR_KEYWORD)) {
|
if (RegExp(COLOR_KEYWORD).exec(attrib)) {
|
||||||
const newStyle1 = fixedAttrib.replace(FILL_KEYWORD, BG_FILL);
|
const newStyle1 = fixedAttrib.replace(FILL_KEYWORD, BG_FILL);
|
||||||
const newStyle2 = newStyle1.replace(COLOR_KEYWORD, FILL_KEYWORD);
|
const newStyle2 = newStyle1.replace(COLOR_KEYWORD, FILL_KEYWORD);
|
||||||
foundClass.textStyles.push(newStyle2);
|
foundClass.textStyles.push(newStyle2);
|
||||||
|
@ -533,8 +533,7 @@ export const drawNode = function (elem, node, fullSection, conf) {
|
|||||||
.attr('text-anchor', 'middle')
|
.attr('text-anchor', 'middle')
|
||||||
.call(wrap, node.width);
|
.call(wrap, node.width);
|
||||||
const bbox = txt.node().getBBox();
|
const bbox = txt.node().getBBox();
|
||||||
const fontSize =
|
const fontSize = conf.fontSize?.replace ? conf.fontSize.replace('px', '') : conf.fontSize;
|
||||||
conf.fontSize && conf.fontSize.replace ? conf.fontSize.replace('px', '') : conf.fontSize;
|
|
||||||
node.height = bbox.height + fontSize * 1.1 * 0.5 + node.padding;
|
node.height = bbox.height + fontSize * 1.1 * 0.5 + node.padding;
|
||||||
node.height = Math.max(node.height, node.maxHeight);
|
node.height = Math.max(node.height, node.maxHeight);
|
||||||
node.width = node.width + 2 * node.padding;
|
node.width = node.width + 2 * node.padding;
|
||||||
@ -558,8 +557,7 @@ export const getVirtualNodeHeight = function (elem, node, conf) {
|
|||||||
.attr('text-anchor', 'middle')
|
.attr('text-anchor', 'middle')
|
||||||
.call(wrap, node.width);
|
.call(wrap, node.width);
|
||||||
const bbox = txt.node().getBBox();
|
const bbox = txt.node().getBBox();
|
||||||
const fontSize =
|
const fontSize = conf.fontSize?.replace ? conf.fontSize.replace('px', '') : conf.fontSize;
|
||||||
conf.fontSize && conf.fontSize.replace ? conf.fontSize.replace('px', '') : conf.fontSize;
|
|
||||||
textElem.remove();
|
textElem.remove();
|
||||||
return bbox.height + fontSize * 1.1 * 0.5 + node.padding;
|
return bbox.height + fontSize * 1.1 * 0.5 + node.padding;
|
||||||
};
|
};
|
||||||
|
@ -58,7 +58,7 @@ export abstract class BaseAxis implements Axis {
|
|||||||
|
|
||||||
abstract recalculateScale(): void;
|
abstract recalculateScale(): void;
|
||||||
|
|
||||||
abstract getTickValues(): Array<string | number>;
|
abstract getTickValues(): (string | number)[];
|
||||||
|
|
||||||
getTickDistance(): number {
|
getTickDistance(): number {
|
||||||
const range = this.getRange();
|
const range = this.getRange();
|
||||||
|
@ -5,7 +5,7 @@ import { addDiagrams } from './diagram-api/diagram-orchestration.js';
|
|||||||
import { beforeAll, describe, it, expect, vi, afterEach } from 'vitest';
|
import { beforeAll, describe, it, expect, vi, afterEach } from 'vitest';
|
||||||
import type { DiagramDefinition } from './diagram-api/types.js';
|
import type { DiagramDefinition } from './diagram-api/types.js';
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(() => {
|
||||||
addDiagrams();
|
addDiagrams();
|
||||||
});
|
});
|
||||||
const spyOn = vi.spyOn;
|
const spyOn = vi.spyOn;
|
||||||
@ -18,7 +18,7 @@ afterEach(() => {
|
|||||||
|
|
||||||
describe('when using mermaid and ', () => {
|
describe('when using mermaid and ', () => {
|
||||||
describe('when detecting chart type ', () => {
|
describe('when detecting chart type ', () => {
|
||||||
it('should not start rendering with mermaid.startOnLoad set to false', async () => {
|
it('should not start rendering with mermaid.startOnLoad set to false', () => {
|
||||||
mermaid.startOnLoad = false;
|
mermaid.startOnLoad = false;
|
||||||
document.body.innerHTML = '<div class="mermaid">graph TD;\na;</div>';
|
document.body.innerHTML = '<div class="mermaid">graph TD;\na;</div>';
|
||||||
spyOn(mermaid, 'run');
|
spyOn(mermaid, 'run');
|
||||||
@ -26,7 +26,7 @@ describe('when using mermaid and ', () => {
|
|||||||
expect(mermaid.run).not.toHaveBeenCalled();
|
expect(mermaid.run).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should start rendering with both startOnLoad set', async () => {
|
it('should start rendering with both startOnLoad set', () => {
|
||||||
mermaid.startOnLoad = true;
|
mermaid.startOnLoad = true;
|
||||||
document.body.innerHTML = '<div class="mermaid">graph TD;\na;</div>';
|
document.body.innerHTML = '<div class="mermaid">graph TD;\na;</div>';
|
||||||
spyOn(mermaid, 'run');
|
spyOn(mermaid, 'run');
|
||||||
@ -34,7 +34,7 @@ describe('when using mermaid and ', () => {
|
|||||||
expect(mermaid.run).toHaveBeenCalled();
|
expect(mermaid.run).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should start rendering with mermaid.startOnLoad', async () => {
|
it('should start rendering with mermaid.startOnLoad', () => {
|
||||||
mermaid.startOnLoad = true;
|
mermaid.startOnLoad = true;
|
||||||
document.body.innerHTML = '<div class="mermaid">graph TD;\na;</div>';
|
document.body.innerHTML = '<div class="mermaid">graph TD;\na;</div>';
|
||||||
spyOn(mermaid, 'run');
|
spyOn(mermaid, 'run');
|
||||||
@ -42,7 +42,7 @@ describe('when using mermaid and ', () => {
|
|||||||
expect(mermaid.run).toHaveBeenCalled();
|
expect(mermaid.run).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should start rendering as a default with no changes performed', async () => {
|
it('should start rendering as a default with no changes performed', () => {
|
||||||
document.body.innerHTML = '<div class="mermaid">graph TD;\na;</div>';
|
document.body.innerHTML = '<div class="mermaid">graph TD;\na;</div>';
|
||||||
spyOn(mermaid, 'run');
|
spyOn(mermaid, 'run');
|
||||||
mermaid.contentLoaded();
|
mermaid.contentLoaded();
|
||||||
@ -74,7 +74,7 @@ describe('when using mermaid and ', () => {
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
id: 'dummyError',
|
id: 'dummyError',
|
||||||
detector: (text) => /dummyError/.test(text),
|
detector: (text) => text.includes('dummyError'),
|
||||||
loader: () => Promise.reject('dummyError'),
|
loader: () => Promise.reject('dummyError'),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -114,7 +114,7 @@ describe('when using mermaid and ', () => {
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
id: 'dummy',
|
id: 'dummy',
|
||||||
detector: (text) => /dummy/.test(text),
|
detector: (text) => text.includes('dummy'),
|
||||||
loader: () => {
|
loader: () => {
|
||||||
loaded = true;
|
loaded = true;
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
@ -133,7 +133,7 @@ describe('when using mermaid and ', () => {
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
id: 'dummy2',
|
id: 'dummy2',
|
||||||
detector: (text) => /dummy2/.test(text),
|
detector: (text) => text.includes('dummy2'),
|
||||||
loader: () => {
|
loader: () => {
|
||||||
loaded = true;
|
loaded = true;
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
|
@ -606,26 +606,26 @@ describe('mermaidAPI', () => {
|
|||||||
let error: any = { message: '' };
|
let error: any = { message: '' };
|
||||||
try {
|
try {
|
||||||
// @ts-ignore This is a read-only property. Typescript will not allow assignment, but regular javascript might.
|
// @ts-ignore This is a read-only property. Typescript will not allow assignment, but regular javascript might.
|
||||||
mermaidAPI['defaultConfig'] = config;
|
mermaidAPI.defaultConfig = config;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
error = e;
|
error = e;
|
||||||
}
|
}
|
||||||
expect(error.message).toBe(
|
expect(error.message).toBe(
|
||||||
"Cannot assign to read only property 'defaultConfig' of object '#<Object>'"
|
"Cannot assign to read only property 'defaultConfig' of object '#<Object>'"
|
||||||
);
|
);
|
||||||
expect(mermaidAPI.defaultConfig['logLevel']).toBe(5);
|
expect(mermaidAPI.defaultConfig.logLevel).toBe(5);
|
||||||
});
|
});
|
||||||
it('prevents changes to global defaults (direct)', () => {
|
it('prevents changes to global defaults (direct)', () => {
|
||||||
let error: any = { message: '' };
|
let error: any = { message: '' };
|
||||||
try {
|
try {
|
||||||
mermaidAPI.defaultConfig['logLevel'] = 0;
|
mermaidAPI.defaultConfig.logLevel = 0;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
error = e;
|
error = e;
|
||||||
}
|
}
|
||||||
expect(error.message).toBe(
|
expect(error.message).toBe(
|
||||||
"Cannot assign to read only property 'logLevel' of object '#<Object>'"
|
"Cannot assign to read only property 'logLevel' of object '#<Object>'"
|
||||||
);
|
);
|
||||||
expect(mermaidAPI.defaultConfig['logLevel']).toBe(5);
|
expect(mermaidAPI.defaultConfig.logLevel).toBe(5);
|
||||||
});
|
});
|
||||||
it('prevents sneaky changes to global defaults (assignWithDepth)', () => {
|
it('prevents sneaky changes to global defaults (assignWithDepth)', () => {
|
||||||
const config = {
|
const config = {
|
||||||
@ -640,7 +640,7 @@ describe('mermaidAPI', () => {
|
|||||||
expect(error.message).toBe(
|
expect(error.message).toBe(
|
||||||
"Cannot assign to read only property 'logLevel' of object '#<Object>'"
|
"Cannot assign to read only property 'logLevel' of object '#<Object>'"
|
||||||
);
|
);
|
||||||
expect(mermaidAPI.defaultConfig['logLevel']).toBe(5);
|
expect(mermaidAPI.defaultConfig.logLevel).toBe(5);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -648,7 +648,7 @@ describe('mermaidAPI', () => {
|
|||||||
it('allows dompurify config to be set', () => {
|
it('allows dompurify config to be set', () => {
|
||||||
mermaidAPI.initialize({ dompurifyConfig: { ADD_ATTR: ['onclick'] } });
|
mermaidAPI.initialize({ dompurifyConfig: { ADD_ATTR: ['onclick'] } });
|
||||||
|
|
||||||
expect(mermaidAPI!.getConfig()!.dompurifyConfig!.ADD_ATTR).toEqual(['onclick']);
|
expect(mermaidAPI.getConfig().dompurifyConfig!.ADD_ATTR).toEqual(['onclick']);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -17,8 +17,8 @@ const getStyles = (
|
|||||||
} & FlowChartStyleOptions
|
} & FlowChartStyleOptions
|
||||||
) => {
|
) => {
|
||||||
let diagramStyles = '';
|
let diagramStyles = '';
|
||||||
if (type in themes && themes[type as keyof typeof themes]) {
|
if (type in themes && themes[type]) {
|
||||||
diagramStyles = themes[type as keyof typeof themes](options);
|
diagramStyles = themes[type](options);
|
||||||
} else {
|
} else {
|
||||||
log.warn(`No theme found for ${type}`);
|
log.warn(`No theme found for ${type}`);
|
||||||
}
|
}
|
||||||
|
@ -156,8 +156,8 @@ class Theme {
|
|||||||
// Setup the label color for the set
|
// Setup the label color for the set
|
||||||
this.scaleLabelColor = this.scaleLabelColor || (this.darkMode ? 'black' : this.labelTextColor);
|
this.scaleLabelColor = this.scaleLabelColor || (this.darkMode ? 'black' : this.labelTextColor);
|
||||||
|
|
||||||
this['cScaleLabel0'] = this['cScaleLabel0'] || this.cScale1;
|
this.cScaleLabel0 = this.cScaleLabel0 || this.cScale1;
|
||||||
this['cScaleLabel2'] = this['cScaleLabel2'] || this.cScale1;
|
this.cScaleLabel2 = this.cScaleLabel2 || this.cScale1;
|
||||||
for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) {
|
for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) {
|
||||||
this['cScaleLabel' + i] = this['cScaleLabel' + i] || this.scaleLabelColor;
|
this['cScaleLabel' + i] = this['cScaleLabel' + i] || this.scaleLabelColor;
|
||||||
}
|
}
|
||||||
|
@ -177,11 +177,7 @@ export const detectDirective = function (
|
|||||||
if (match.index === directiveRegex.lastIndex) {
|
if (match.index === directiveRegex.lastIndex) {
|
||||||
directiveRegex.lastIndex++;
|
directiveRegex.lastIndex++;
|
||||||
}
|
}
|
||||||
if (
|
if ((match && !type) || (type && match[1]?.match(type)) || (type && match[2]?.match(type))) {
|
||||||
(match && !type) ||
|
|
||||||
(type && match[1] && match[1].match(type)) ||
|
|
||||||
(type && match[2] && match[2].match(type))
|
|
||||||
) {
|
|
||||||
const type = match[1] ? match[1] : match[2];
|
const type = match[1] ? match[1] : match[2];
|
||||||
const args = match[3] ? match[3].trim() : match[4] ? JSON.parse(match[4].trim()) : null;
|
const args = match[3] ? match[3].trim() : match[4] ? JSON.parse(match[4].trim()) : null;
|
||||||
result.push({ type, args });
|
result.push({ type, args });
|
||||||
|
@ -9,17 +9,17 @@ const initializers = {
|
|||||||
info: async () => {
|
info: async () => {
|
||||||
const { createInfoServices } = await import('./language/info/index.js');
|
const { createInfoServices } = await import('./language/info/index.js');
|
||||||
const parser = createInfoServices().Info.parser.LangiumParser;
|
const parser = createInfoServices().Info.parser.LangiumParser;
|
||||||
parsers['info'] = parser;
|
parsers.info = parser;
|
||||||
},
|
},
|
||||||
packet: async () => {
|
packet: async () => {
|
||||||
const { createPacketServices } = await import('./language/packet/index.js');
|
const { createPacketServices } = await import('./language/packet/index.js');
|
||||||
const parser = createPacketServices().Packet.parser.LangiumParser;
|
const parser = createPacketServices().Packet.parser.LangiumParser;
|
||||||
parsers['packet'] = parser;
|
parsers.packet = parser;
|
||||||
},
|
},
|
||||||
pie: async () => {
|
pie: async () => {
|
||||||
const { createPieServices } = await import('./language/pie/index.js');
|
const { createPieServices } = await import('./language/pie/index.js');
|
||||||
const parser = createPieServices().Pie.parser.LangiumParser;
|
const parser = createPieServices().Pie.parser.LangiumParser;
|
||||||
parsers['pie'] = parser;
|
parsers.pie = parser;
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user