From 9566f51ca8f77890ff566ac09d53c9599d916cc7 Mon Sep 17 00:00:00 2001 From: Knut Sveidqvist Date: Mon, 26 Sep 2022 08:01:23 +0200 Subject: [PATCH] Commiton issue #3061 Injecting mermaid utilities in registered diagram --- .vite/build.ts | 25 +++--- cypress/platform/knsv2.html | 15 ++-- .../mermaid-mindmap-detector/src/registry.ts | 18 ----- packages/mermaid-mindmap/src/diagram.ts | 18 ++++- packages/mermaid-mindmap/src/mermaidUtils.ts | 77 +++++++++++++++++++ packages/mermaid-mindmap/src/mindmapDb.js | 3 +- .../mermaid-mindmap/src/mindmapRenderer.js | 2 +- packages/mermaid-mindmap/src/registry.ts | 46 +++++------ packages/mermaid/src/Diagram.ts | 20 +++-- .../mermaid/src/diagram-api/diagramAPI.ts | 18 ++++- packages/mermaid/src/mermaid.ts | 31 ++++++++ packages/mermaid/src/utils.ts | 1 - .../package.json | 0 .../src/mindmapDetector.ts | 0 .../tsconfig.json | 0 15 files changed, 197 insertions(+), 77 deletions(-) delete mode 100644 packages/mermaid-mindmap-detector/src/registry.ts create mode 100644 packages/mermaid-mindmap/src/mermaidUtils.ts rename packages/{mermaid-mindmap-detector => rm-mermaid-mindmap-detector}/package.json (100%) rename packages/{mermaid-mindmap-detector => rm-mermaid-mindmap-detector}/src/mindmapDetector.ts (100%) rename packages/{mermaid-mindmap-detector => rm-mermaid-mindmap-detector}/tsconfig.json (100%) diff --git a/.vite/build.ts b/.vite/build.ts index f842e669a..fa57123ce 100644 --- a/.vite/build.ts +++ b/.vite/build.ts @@ -16,14 +16,17 @@ type OutputOptions = Exclude< const packageOptions = { mermaid: { name: 'mermaid', + packageName: 'mermaid', file: 'mermaid.ts', }, 'mermaid-mindmap': { name: 'mermaid-mindmap', + packageName: 'mermaid-mindmap', file: 'diagram.ts', }, 'mermaid-mindmap-detector': { name: 'mermaid-mindmap-detector', + packageName: 'mermaid-mindmap', file: 'registry.ts', }, }; @@ -32,17 +35,13 @@ interface BuildOptions { minify: boolean | 'esbuild'; core?: boolean; watch?: boolean; - packageName: keyof typeof packageOptions; + entryName: keyof typeof packageOptions; } -export const getBuildConfig = ({ - minify, - core, - watch, - packageName, -}: BuildOptions): InlineConfig => { +export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions): InlineConfig => { const external = ['require', 'fs', 'path']; - const { name, file } = packageOptions[packageName]; + console.log(entryName, packageOptions[entryName]); + const { name, file, packageName } = packageOptions[entryName]; let output: OutputOptions = [ { name, @@ -105,11 +104,11 @@ export const getBuildConfig = ({ return config; }; -const buildPackage = async (packageName: keyof typeof packageOptions) => { +const buildPackage = async (entryName: keyof typeof packageOptions) => { return Promise.allSettled([ - build(getBuildConfig({ minify: false, packageName })), - build(getBuildConfig({ minify: 'esbuild', packageName })), - build(getBuildConfig({ minify: false, core: true, packageName })), + build(getBuildConfig({ minify: false, entryName })), + build(getBuildConfig({ minify: 'esbuild', entryName })), + build(getBuildConfig({ minify: false, core: true, entryName })), ]); }; @@ -121,7 +120,7 @@ const main = async () => { }; if (watch) { - build(getBuildConfig({ minify: false, watch, packageName: 'mermaid' })); + build(getBuildConfig({ minify: false, watch, entryName: 'mermaid' })); } else { void main(); } diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html index a81816197..cc4e8f135 100644 --- a/cypress/platform/knsv2.html +++ b/cypress/platform/knsv2.html @@ -45,12 +45,17 @@
Security check
+
+flowchart LR
+      A --> B
+    
         mindmap
           root
             ch1
             ch2
     
+ diff --git a/packages/mermaid-mindmap-detector/src/registry.ts b/packages/mermaid-mindmap-detector/src/registry.ts deleted file mode 100644 index bb121e5dc..000000000 --- a/packages/mermaid-mindmap-detector/src/registry.ts +++ /dev/null @@ -1,18 +0,0 @@ -// @ts-ignore: TODO Fix ts errors -import { mindmapDetector } from './mindmapDetector'; - -if (typeof document !== 'undefined') { - /*! - * Wait for document loaded before starting the execution - */ - window.addEventListener( - 'load', - () => { - if (window.mermaid && typeof window.mermaid.detectors === 'object') { - window.mermaid.detectors.push(mindmapDetector); - console.log(window.mermaid.detectors); // eslint-disable-line no-console - } - }, - false - ); -} diff --git a/packages/mermaid-mindmap/src/diagram.ts b/packages/mermaid-mindmap/src/diagram.ts index c0d32e82a..8161a8e98 100644 --- a/packages/mermaid-mindmap/src/diagram.ts +++ b/packages/mermaid-mindmap/src/diagram.ts @@ -3,7 +3,7 @@ import mindmapParser from './parser/mindmap'; import * as mindmapDb from './mindmapDb'; import mindmapRenderer from './mindmapRenderer'; import mindmapStyles from './styles'; - +import { injectUtils } from './mermaidUtils'; // import mermaid from 'mermaid'; // console.log('mindmapDb', mindmapDb.getMindmap()); // eslint-disable-line no-console @@ -13,12 +13,22 @@ if (typeof document !== 'undefined') { /*! * Wait for document loaded before starting the execution */ + // { parser: mindmapParser, db: mindmapDb, renderer: mindmapRenderer, styles: mindmapStyles }, + window.addEventListener( 'load', () => { - if (window.mermaid && typeof window.mermaid.detectors === 'object') { - // window.mermaid.detectors.push(mindmapDetector); - console.log(window.mermaid.detectors); // eslint-disable-line no-console + if (window.mermaid && typeof window.mermaid.c) { + window.mermaid.connectDiagram( + 'mindmap', + { + db: mindmapDb, + renderer: mindmapRenderer, + parser: mindmapParser, + styles: mindmapStyles, + }, + injectUtils + ); } }, false diff --git a/packages/mermaid-mindmap/src/mermaidUtils.ts b/packages/mermaid-mindmap/src/mermaidUtils.ts new file mode 100644 index 000000000..82bf3653b --- /dev/null +++ b/packages/mermaid-mindmap/src/mermaidUtils.ts @@ -0,0 +1,77 @@ +const warning = (s: string) => { + // Todo remove debug code + console.error('Log function was called before initialization', s); // eslint-disable-line +}; + +export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal'; + +export const LEVELS: Record = { + trace: 0, + debug: 1, + info: 2, + warn: 3, + error: 4, + fatal: 5, +}; + +export const log: Record = { + trace: warning, + debug: warning, + info: warning, + warn: warning, + error: warning, + fatal: warning, +}; + +export let setLogLevel: (level: keyof typeof LEVELS | number | string) => void; +export let getConfig: () => object; +export let sanitizeText: (str: string) => string; +// eslint-disable @typescript-eslint/no-explicit-any +export let setupGraphViewbox: ( + graph: any, + svgElem: any, + padding: any, + useMaxWidth: boolean +) => void; + +export const injectUtils = ( + _log: Record, + _setLogLevel: any, + _getConfig: any, + _sanitizeText: any, + _setupGraphViewbox: any +) => { + log.debug = _log.debug; + log.info = _log.info; + log.warn = _log.warn; + log.error = _log.error; + setLogLevel = _setLogLevel; + getConfig = _getConfig; + sanitizeText = _sanitizeText; + setupGraphViewbox = _setupGraphViewbox; +}; + +/* +const warning = (..._args: any[]) => { + console.error('Log function was called before initialization'); +}; +export let log = { + trace: warning, + debug: warning, + info: warning, + warn: warning, + error: warning, + fatal: warning, +}; +export let setLogLevel; +export let getConfig; +export let sanitizeText; +export let setupGraphViewbox; +export const injectUtils = (_log, _setLogLevel, _getConfig, _sanitizeText, _setupGraphViewbox) => { + log = _log; + setLogLevel = _setLogLevel; + getConfig = _getConfig; + sanitizeText = _sanitizeText; + setupGraphViewbox = _setupGraphViewbox; +}; +*/ diff --git a/packages/mermaid-mindmap/src/mindmapDb.js b/packages/mermaid-mindmap/src/mindmapDb.js index 9efebcca4..3b322b2b4 100644 --- a/packages/mermaid-mindmap/src/mindmapDb.js +++ b/packages/mermaid-mindmap/src/mindmapDb.js @@ -1,5 +1,5 @@ /** Created by knut on 15-01-14. */ -import { sanitizeText, getConfig, log as _log } from 'mermaid/diagramAPI'; +import { sanitizeText, getConfig, log as _log } from './mermaidUtils'; let nodes = []; let cnt = 0; @@ -133,6 +133,7 @@ export const type2Str = (type) => { }; // Expose logger to grammar export const log = _log; +export let graphType = 'mindmap'; export const getNodeById = (id) => nodes[id]; export const getElementById = (id) => elements[id]; // export default { diff --git a/packages/mermaid-mindmap/src/mindmapRenderer.js b/packages/mermaid-mindmap/src/mindmapRenderer.js index 2f2b06292..9ad81df9d 100644 --- a/packages/mermaid-mindmap/src/mindmapRenderer.js +++ b/packages/mermaid-mindmap/src/mindmapRenderer.js @@ -1,6 +1,6 @@ /** Created by knut on 14-12-11. */ import { select } from 'd3'; -import { log, getConfig, setupGraphViewbox } from '../../diagram-api/diagramAPI'; +import { log, getConfig, setupGraphViewbox } from './mermaidUtils'; import svgDraw from './svgDraw'; import { BoundingBox, Layout } from 'non-layered-tidy-tree-layout'; import clone from 'fast-clone'; diff --git a/packages/mermaid-mindmap/src/registry.ts b/packages/mermaid-mindmap/src/registry.ts index 7189578a6..837929f33 100644 --- a/packages/mermaid-mindmap/src/registry.ts +++ b/packages/mermaid-mindmap/src/registry.ts @@ -1,27 +1,27 @@ // @ts-ignore: TODO Fix ts errors -// import mindmapParser from './parser/mindmap'; -// import * as mindmapDb from './mindmapDb'; import { mindmapDetector } from './mindmapDetector'; -// import mindmapRenderer from './mindmapRenderer'; -// import mindmapStyles from './styles'; -import mermaid from 'mermaid'; +if (typeof document !== 'undefined') { + if (window.mermaid && typeof window.mermaid.detectors === 'object') { + window.mermaid.detectors.push({ id: 'mindmap', detector: mindmapDetector }); + } else { + console.error('window.mermaid.detectors not found'); // eslint-disable-line no-console + window.mermaid = {}; + window.mermaid.detectors = [{ id: 'mindmap', detector: mindmapDetector }]; + console.error('Detectors now:', window.mermaid.detectors); // eslint-disable-line no-console + } -console.log('mindmapDb', mermaid.mermaidAPI.getConfig()); // eslint-disable-line no-console -// registerDiagram() - -// if (typeof document !== 'undefined') { -// /*! -// * Wait for document loaded before starting the execution -// */ -// window.addEventListener( -// 'load', -// () => { -// if (window.mermaid && typeof window.mermaid.detectors === 'object') { -// window.mermaid.detectors.push(mindmapDetector); -// console.log(window.mermaid.detectors); // eslint-disable-line no-console -// } -// }, -// false -// ); -// } + /*! + * Wait for document loaded before starting the execution. + */ + window.addEventListener( + 'load', + () => { + if (window.mermaid && typeof window.mermaid.detectors === 'object') { + window.mermaid.detectors.push({ id: 'mindmap', detector: mindmapDetector }); + // console.error(window.mermaid.detectors); // eslint-disable-line no-console + } + }, + false + ); +} diff --git a/packages/mermaid/src/Diagram.ts b/packages/mermaid/src/Diagram.ts index a54cfbefd..eae576eec 100644 --- a/packages/mermaid/src/Diagram.ts +++ b/packages/mermaid/src/Diagram.ts @@ -26,12 +26,20 @@ export class Diagram { log.debug('Initialized diagram ' + this.type, cnf); } this.txt += '\n'; - this.parser.parser.yy.graphType = this.type; - this.parser.parser.yy.parseError = (str: string, hash: string) => { - const error = { str, hash }; - throw error; - }; - this.parse(this.txt, parseError); + try { + this.parser.parser.yy.graphType = this.type; + this.parser.parser.yy.parseError = (str: string, hash: string) => { + const error = { str, hash }; + throw error; + }; + } catch (error) { + log.error('error', error); + } + try { + this.parse(this.txt, parseError); + } catch (error) { + log.error('error', error); + } } // eslint-disable-next-line @typescript-eslint/ban-types diff --git a/packages/mermaid/src/diagram-api/diagramAPI.ts b/packages/mermaid/src/diagram-api/diagramAPI.ts index 9a86c5b51..3ade11b03 100644 --- a/packages/mermaid/src/diagram-api/diagramAPI.ts +++ b/packages/mermaid/src/diagram-api/diagramAPI.ts @@ -27,18 +27,32 @@ export interface DiagramDefinition { } const diagrams: Record = {}; +const connectCallbacks: Record = {}; // TODO fix, eslint-disable-line @typescript-eslint/no-explicit-any +export interface Detectors { + [key: string]: DiagramDetector; +} + +export const registerDetector = (id: string, detector: DiagramDetector) => { + addDetector(id, detector); +}; export const registerDiagram = ( id: string, diagram: DiagramDefinition, - detector: DiagramDetector + callback: ( + _log: any, + _setLogLevel: any, + _getConfig: any, + _sanitizeText: any, + _setupGraphViewbox: any + ) => void ) => { if (diagrams[id]) { log.warn(`Diagram ${id} already registered.`); } diagrams[id] = diagram; - addDetector(id, detector); addStylesForDiagram(id, diagram.styles); + connectCallbacks[id] = callback; }; export const getDiagram = (name: string): DiagramDefinition => { diff --git a/packages/mermaid/src/mermaid.ts b/packages/mermaid/src/mermaid.ts index 33556f8bc..1d63ba6c9 100644 --- a/packages/mermaid/src/mermaid.ts +++ b/packages/mermaid/src/mermaid.ts @@ -6,6 +6,15 @@ import { MermaidConfig } from './config.type'; import { log } from './logger'; import utils from './utils'; import { mermaidAPI } from './mermaidAPI'; +import { addDetector } from './diagram-api/detectType'; +import { + registerDiagram, + DiagramDefinition, + setLogLevel, + getConfig, + setupGraphViewbox, + sanitizeText, +} from './diagram-api/diagramAPI'; import { isDetailedError } from './utils'; /** @@ -44,6 +53,10 @@ const init = function ( callback?: Function ) { try { + console.error('Detectors in init', mermaid.detectors); // eslint-disable-line + mermaid.detectors.forEach(({ id, detector }) => { + addDetector(id, detector); + }); initThrowsErrors(config, nodes, callback); } catch (e) { log.warn('Syntax Error rendering'); @@ -197,6 +210,22 @@ const parse = (txt: string) => { return mermaidAPI.parse(txt, mermaid.parseError); }; +const connectDiagram = ( + id: string, + diagram: DiagramDefinition, + callback: ( + _log: any, + _setLogLevel: any, + _getConfig: any, + _sanitizeText: any, + _setupGraphViewbox: any + ) => void +) => { + registerDiagram(id, diagram, callback); + // Todo move this connect call to after the diagram is actually loaded + callback(log, setLogLevel, getConfig, sanitizeText, setupGraphViewbox); +}; + const mermaid: { startOnLoad: boolean; diagrams: any; @@ -212,6 +241,7 @@ const mermaid: { setParseErrorHandler: typeof setParseErrorHandler; // Array of functions to use for detecting diagram types detectors: Array; // eslint-disable-line @typescript-eslint/no-explicit-any + connectDiagram: (id: string, diagram: DiagramDefinition, callback: (id: string) => void) => void; } = { startOnLoad: true, diagrams: {}, @@ -225,6 +255,7 @@ const mermaid: { contentLoaded, setParseErrorHandler, detectors: [], + connectDiagram: connectDiagram, }; export default mermaid; diff --git a/packages/mermaid/src/utils.ts b/packages/mermaid/src/utils.ts index d6b317034..395e6fe2a 100644 --- a/packages/mermaid/src/utils.ts +++ b/packages/mermaid/src/utils.ts @@ -72,7 +72,6 @@ const directiveWithoutOpen = * g-->h * ``` * @param {string} text The text defining the graph - * @param {any} config * @returns {object} The json object representing the init passed to mermaid.initialize() */ export const detectInit = function (text: string, config?: MermaidConfig): MermaidConfig { diff --git a/packages/mermaid-mindmap-detector/package.json b/packages/rm-mermaid-mindmap-detector/package.json similarity index 100% rename from packages/mermaid-mindmap-detector/package.json rename to packages/rm-mermaid-mindmap-detector/package.json diff --git a/packages/mermaid-mindmap-detector/src/mindmapDetector.ts b/packages/rm-mermaid-mindmap-detector/src/mindmapDetector.ts similarity index 100% rename from packages/mermaid-mindmap-detector/src/mindmapDetector.ts rename to packages/rm-mermaid-mindmap-detector/src/mindmapDetector.ts diff --git a/packages/mermaid-mindmap-detector/tsconfig.json b/packages/rm-mermaid-mindmap-detector/tsconfig.json similarity index 100% rename from packages/mermaid-mindmap-detector/tsconfig.json rename to packages/rm-mermaid-mindmap-detector/tsconfig.json