From 7e5802e79959bf3c5c4d33c98de8df13d69a7ecd Mon Sep 17 00:00:00 2001 From: knsv Date: Thu, 12 Sep 2019 12:59:13 -0700 Subject: [PATCH] #931 Last code standard fixes --- src/mermaid.js | 132 +++++++------ src/mermaid.spec.js | 320 +++++++++++++++--------------- src/mermaidAPI.js | 429 ++++++++++++++++++++++------------------- src/mermaidAPI.spec.js | 68 +++---- 4 files changed, 497 insertions(+), 452 deletions(-) diff --git a/src/mermaid.js b/src/mermaid.js index ebfc87532..76b644ef2 100644 --- a/src/mermaid.js +++ b/src/mermaid.js @@ -2,10 +2,10 @@ * Web page integration module for the mermaid framework. It uses the mermaidAPI for mermaid functionality and to render * the diagrams to svg code. */ -import he from 'he' +import he from 'he'; -import mermaidAPI from './mermaidAPI' -import { logger } from './logger' +import mermaidAPI from './mermaidAPI'; +import { logger } from './logger'; /** * ## init @@ -28,126 +28,142 @@ import { logger } from './logger' * Renders the mermaid diagrams * @param nodes a css selector or an array of nodes */ -const init = function () { - const conf = mermaidAPI.getConfig() - logger.debug('Starting rendering diagrams') - let nodes +const init = function() { + const conf = mermaidAPI.getConfig(); + logger.debug('Starting rendering diagrams'); + let nodes; if (arguments.length >= 2) { /*! sequence config was passed as #1 */ if (typeof arguments[0] !== 'undefined') { - mermaid.sequenceConfig = arguments[0] + mermaid.sequenceConfig = arguments[0]; } - nodes = arguments[1] + nodes = arguments[1]; } else { - nodes = arguments[0] + nodes = arguments[0]; } // if last argument is a function this is the callback function - let callback + let callback; if (typeof arguments[arguments.length - 1] === 'function') { - callback = arguments[arguments.length - 1] - logger.debug('Callback function found') + callback = arguments[arguments.length - 1]; + logger.debug('Callback function found'); } else { if (typeof conf.mermaid !== 'undefined') { if (typeof conf.mermaid.callback === 'function') { - callback = conf.mermaid.callback - logger.debug('Callback function found') + callback = conf.mermaid.callback; + logger.debug('Callback function found'); } else { - logger.debug('No Callback function found') + logger.debug('No Callback function found'); } } } - nodes = nodes === undefined ? document.querySelectorAll('.mermaid') - : typeof nodes === 'string' ? document.querySelectorAll(nodes) - : nodes instanceof window.Node ? [nodes] - : nodes // Last case - sequence config was passed pick next + nodes = + nodes === undefined + ? document.querySelectorAll('.mermaid') + : typeof nodes === 'string' + ? document.querySelectorAll(nodes) + : nodes instanceof window.Node + ? [nodes] + : nodes; // Last case - sequence config was passed pick next - logger.debug('Start On Load before: ' + mermaid.startOnLoad) + logger.debug('Start On Load before: ' + mermaid.startOnLoad); if (typeof mermaid.startOnLoad !== 'undefined') { - logger.debug('Start On Load inner: ' + mermaid.startOnLoad) - mermaidAPI.initialize({ startOnLoad: mermaid.startOnLoad }) + logger.debug('Start On Load inner: ' + mermaid.startOnLoad); + mermaidAPI.initialize({ startOnLoad: mermaid.startOnLoad }); } if (typeof mermaid.ganttConfig !== 'undefined') { - mermaidAPI.initialize({ gantt: mermaid.ganttConfig }) + mermaidAPI.initialize({ gantt: mermaid.ganttConfig }); } - let txt + let txt; for (let i = 0; i < nodes.length; i++) { - const element = nodes[i] + const element = nodes[i]; /*! Check if previously processed */ if (!element.getAttribute('data-processed')) { - element.setAttribute('data-processed', true) + element.setAttribute('data-processed', true); } else { - continue + continue; } - const id = `mermaid-${Date.now()}` + const id = `mermaid-${Date.now()}`; // Fetch the graph definition including tags - txt = element.innerHTML + txt = element.innerHTML; // transforms the html to pure text - txt = he.decode(txt).trim().replace(/
/ig, '
') + txt = he + .decode(txt) + .trim() + .replace(/
/gi, '
'); - mermaidAPI.render(id, txt, (svgCode, bindFunctions) => { - element.innerHTML = svgCode - if (typeof callback !== 'undefined') { - callback(id) - } - if (bindFunctions) bindFunctions(element) - }, element) + mermaidAPI.render( + id, + txt, + (svgCode, bindFunctions) => { + element.innerHTML = svgCode; + if (typeof callback !== 'undefined') { + callback(id); + } + if (bindFunctions) bindFunctions(element); + }, + element + ); } -} +}; -const initialize = function (config) { - logger.debug('Initializing mermaid ') +const initialize = function(config) { + logger.debug('Initializing mermaid '); if (typeof config.mermaid !== 'undefined') { if (typeof config.mermaid.startOnLoad !== 'undefined') { - mermaid.startOnLoad = config.mermaid.startOnLoad + mermaid.startOnLoad = config.mermaid.startOnLoad; } if (typeof config.mermaid.htmlLabels !== 'undefined') { - mermaid.htmlLabels = config.mermaid.htmlLabels + mermaid.htmlLabels = config.mermaid.htmlLabels; } } - mermaidAPI.initialize(config) -} + mermaidAPI.initialize(config); +}; /** * ##contentLoaded * Callback function that is called when page is loaded. This functions fetches configuration for mermaid rendering and * calls init for rendering the mermaid diagrams on the page. */ -const contentLoaded = function () { - let config +const contentLoaded = function() { + let config; if (mermaid.startOnLoad) { // No config found, do check API config - config = mermaidAPI.getConfig() + config = mermaidAPI.getConfig(); if (config.startOnLoad) { - mermaid.init() + mermaid.init(); } } else { if (typeof mermaid.startOnLoad === 'undefined') { - logger.debug('In start, no config') - config = mermaidAPI.getConfig() + logger.debug('In start, no config'); + config = mermaidAPI.getConfig(); if (config.startOnLoad) { - mermaid.init() + mermaid.init(); } } } -} +}; if (typeof document !== 'undefined') { /*! * Wait for document loaded before starting the execution */ - window.addEventListener('load', function () { - contentLoaded() - }, false) + window.addEventListener( + 'load', + function() { + contentLoaded(); + }, + false + ); } const mermaid = { @@ -162,6 +178,6 @@ const mermaid = { initialize, contentLoaded -} +}; -export default mermaid +export default mermaid; diff --git a/src/mermaid.spec.js b/src/mermaid.spec.js index 996ad21f5..8bfbc1995 100644 --- a/src/mermaid.spec.js +++ b/src/mermaid.spec.js @@ -1,195 +1,200 @@ /* eslint-env jasmine */ -import mermaid from './mermaid' -import flowDb from './diagrams/flowchart/flowDb' -import flowParser from './diagrams/flowchart/parser/flow' -import flowRenderer from './diagrams/flowchart/flowRenderer' +import mermaid from './mermaid'; +import flowDb from './diagrams/flowchart/flowDb'; +import flowParser from './diagrams/flowchart/parser/flow'; +import flowRenderer from './diagrams/flowchart/flowRenderer'; -describe('when using mermaid and ', function () { - describe('when detecting chart type ', function () { - it('should not start rendering with mermaid.startOnLoad set to false', function () { - mermaid.startOnLoad = false - document.body.innerHTML = '
graph TD;\na;
' - spyOn(mermaid, 'init') - mermaid.contentLoaded() - expect(mermaid.init).not.toHaveBeenCalled() - }) +describe('when using mermaid and ', function() { + describe('when detecting chart type ', function() { + it('should not start rendering with mermaid.startOnLoad set to false', function() { + mermaid.startOnLoad = false; + document.body.innerHTML = '
graph TD;\na;
'; + spyOn(mermaid, 'init'); + mermaid.contentLoaded(); + expect(mermaid.init).not.toHaveBeenCalled(); + }); - it('should start rendering with both startOnLoad set', function () { - mermaid.startOnLoad = true - document.body.innerHTML = '
graph TD;\na;
' - spyOn(mermaid, 'init') - mermaid.contentLoaded() - expect(mermaid.init).toHaveBeenCalled() - }) + it('should start rendering with both startOnLoad set', function() { + mermaid.startOnLoad = true; + document.body.innerHTML = '
graph TD;\na;
'; + spyOn(mermaid, 'init'); + mermaid.contentLoaded(); + expect(mermaid.init).toHaveBeenCalled(); + }); - it('should start rendering with mermaid.startOnLoad', function () { - mermaid.startOnLoad = true - document.body.innerHTML = '
graph TD;\na;
' - spyOn(mermaid, 'init') - mermaid.contentLoaded() - expect(mermaid.init).toHaveBeenCalled() - }) + it('should start rendering with mermaid.startOnLoad', function() { + mermaid.startOnLoad = true; + document.body.innerHTML = '
graph TD;\na;
'; + spyOn(mermaid, 'init'); + mermaid.contentLoaded(); + expect(mermaid.init).toHaveBeenCalled(); + }); - it('should start rendering as a default with no changes performed', function () { - document.body.innerHTML = '
graph TD;\na;
' - spyOn(mermaid, 'init') - mermaid.contentLoaded() - expect(mermaid.init).toHaveBeenCalled() - }) - }) + it('should start rendering as a default with no changes performed', function() { + document.body.innerHTML = '
graph TD;\na;
'; + spyOn(mermaid, 'init'); + mermaid.contentLoaded(); + expect(mermaid.init).toHaveBeenCalled(); + }); + }); - describe('when calling addEdges ', function () { - beforeEach(function () { - flowParser.parser.yy = flowDb - flowDb.clear() - }) - it('it should handle edges with text', function () { - flowParser.parser.parse('graph TD;A-->|text ex|B;') - flowParser.parser.yy.getVertices() - const edges = flowParser.parser.yy.getEdges() + describe('when calling addEdges ', function() { + beforeEach(function() { + flowParser.parser.yy = flowDb; + flowDb.clear(); + }); + it('it should handle edges with text', function() { + flowParser.parser.parse('graph TD;A-->|text ex|B;'); + flowParser.parser.yy.getVertices(); + const edges = flowParser.parser.yy.getEdges(); const mockG = { - setEdge: function (start, end, options) { - expect(start).toBe('A') - expect(end).toBe('B') - expect(options.arrowhead).toBe('normal') - expect(options.label.match('text ex')).toBeTruthy() + setEdge: function(start, end, options) { + expect(start).toBe('A'); + expect(end).toBe('B'); + expect(options.arrowhead).toBe('normal'); + expect(options.label.match('text ex')).toBeTruthy(); } - } + }; - flowRenderer.addEdges(edges, mockG) - }) + flowRenderer.addEdges(edges, mockG); + }); - it('should handle edges without text', function () { - flowParser.parser.parse('graph TD;A-->B;') - flowParser.parser.yy.getVertices() - const edges = flowParser.parser.yy.getEdges() + it('should handle edges without text', function() { + flowParser.parser.parse('graph TD;A-->B;'); + flowParser.parser.yy.getVertices(); + const edges = flowParser.parser.yy.getEdges(); const mockG = { - setEdge: function (start, end, options) { - expect(start).toBe('A') - expect(end).toBe('B') - expect(options.arrowhead).toBe('normal') + setEdge: function(start, end, options) { + expect(start).toBe('A'); + expect(end).toBe('B'); + expect(options.arrowhead).toBe('normal'); } - } + }; - flowRenderer.addEdges(edges, mockG) - }) + flowRenderer.addEdges(edges, mockG); + }); - it('should handle open-ended edges', function () { - flowParser.parser.parse('graph TD;A---B;') - flowParser.parser.yy.getVertices() - const edges = flowParser.parser.yy.getEdges() + it('should handle open-ended edges', function() { + flowParser.parser.parse('graph TD;A---B;'); + flowParser.parser.yy.getVertices(); + const edges = flowParser.parser.yy.getEdges(); const mockG = { - setEdge: function (start, end, options) { - expect(start).toBe('A') - expect(end).toBe('B') - expect(options.arrowhead).toBe('none') + setEdge: function(start, end, options) { + expect(start).toBe('A'); + expect(end).toBe('B'); + expect(options.arrowhead).toBe('none'); } - } + }; - flowRenderer.addEdges(edges, mockG) - }) + flowRenderer.addEdges(edges, mockG); + }); - it('should handle edges with styles defined', function () { - flowParser.parser.parse('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2;') - flowParser.parser.yy.getVertices() - const edges = flowParser.parser.yy.getEdges() + it('should handle edges with styles defined', function() { + flowParser.parser.parse('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2;'); + flowParser.parser.yy.getVertices(); + const edges = flowParser.parser.yy.getEdges(); const mockG = { - setEdge: function (start, end, options) { - expect(start).toBe('A') - expect(end).toBe('B') - expect(options.arrowhead).toBe('none') - expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:none;') + setEdge: function(start, end, options) { + expect(start).toBe('A'); + expect(end).toBe('B'); + expect(options.arrowhead).toBe('none'); + expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:none;'); } - } + }; - flowRenderer.addEdges(edges, mockG) - }) - it('should handle edges with interpolation defined', function () { - flowParser.parser.parse('graph TD;A---B; linkStyle 0 interpolate basis') - flowParser.parser.yy.getVertices() - const edges = flowParser.parser.yy.getEdges() + flowRenderer.addEdges(edges, mockG); + }); + it('should handle edges with interpolation defined', function() { + flowParser.parser.parse('graph TD;A---B; linkStyle 0 interpolate basis'); + flowParser.parser.yy.getVertices(); + const edges = flowParser.parser.yy.getEdges(); const mockG = { - setEdge: function (start, end, options) { - expect(start).toBe('A') - expect(end).toBe('B') - expect(options.arrowhead).toBe('none') - expect(options.curve).toBe('basis') // mocked as string + setEdge: function(start, end, options) { + expect(start).toBe('A'); + expect(end).toBe('B'); + expect(options.arrowhead).toBe('none'); + expect(options.curve).toBe('basis'); // mocked as string } - } + }; - flowRenderer.addEdges(edges, mockG) - }) - it('should handle edges with text and styles defined', function () { - flowParser.parser.parse('graph TD;A---|the text|B; linkStyle 0 stroke:val1,stroke-width:val2;') - flowParser.parser.yy.getVertices() - const edges = flowParser.parser.yy.getEdges() + flowRenderer.addEdges(edges, mockG); + }); + it('should handle edges with text and styles defined', function() { + flowParser.parser.parse( + 'graph TD;A---|the text|B; linkStyle 0 stroke:val1,stroke-width:val2;' + ); + flowParser.parser.yy.getVertices(); + const edges = flowParser.parser.yy.getEdges(); const mockG = { - setEdge: function (start, end, options) { - expect(start).toBe('A') - expect(end).toBe('B') - expect(options.arrowhead).toBe('none') - expect(options.label.match('the text')).toBeTruthy() - expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:none;') + setEdge: function(start, end, options) { + expect(start).toBe('A'); + expect(end).toBe('B'); + expect(options.arrowhead).toBe('none'); + expect(options.label.match('the text')).toBeTruthy(); + expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:none;'); } - } + }; - flowRenderer.addEdges(edges, mockG) - }) + flowRenderer.addEdges(edges, mockG); + }); - it('should set fill to "none" by default when handling edges', function () { - flowParser.parser.parse('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2;') - flowParser.parser.yy.getVertices() - const edges = flowParser.parser.yy.getEdges() + it('should set fill to "none" by default when handling edges', function() { + flowParser.parser.parse('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2;'); + flowParser.parser.yy.getVertices(); + const edges = flowParser.parser.yy.getEdges(); const mockG = { - setEdge: function (start, end, options) { - expect(start).toBe('A') - expect(end).toBe('B') - expect(options.arrowhead).toBe('none') - expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:none;') + setEdge: function(start, end, options) { + expect(start).toBe('A'); + expect(end).toBe('B'); + expect(options.arrowhead).toBe('none'); + expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:none;'); } - } + }; - flowRenderer.addEdges(edges, mockG) - }) + flowRenderer.addEdges(edges, mockG); + }); - it('should not set fill to none if fill is set in linkStyle', function () { - flowParser.parser.parse('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2,fill:blue;') - flowParser.parser.yy.getVertices() - const edges = flowParser.parser.yy.getEdges() + it('should not set fill to none if fill is set in linkStyle', function() { + flowParser.parser.parse( + 'graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2,fill:blue;' + ); + flowParser.parser.yy.getVertices(); + const edges = flowParser.parser.yy.getEdges(); const mockG = { - setEdge: function (start, end, options) { - expect(start).toBe('A') - expect(end).toBe('B') - expect(options.arrowhead).toBe('none') - expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:blue;') + setEdge: function(start, end, options) { + expect(start).toBe('A'); + expect(end).toBe('B'); + expect(options.arrowhead).toBe('none'); + expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:blue;'); } - } + }; - flowRenderer.addEdges(edges, mockG) - }) - }) + flowRenderer.addEdges(edges, mockG); + }); + }); - describe('checking validity of input ', function () { - it('it should throw for an invalid definiton', function () { - expect(() => mermaid.parse('this is not a mermaid diagram definition')).toThrow() - }) + describe('checking validity of input ', function() { + it('it should throw for an invalid definiton', function() { + expect(() => mermaid.parse('this is not a mermaid diagram definition')).toThrow(); + }); - it('it should not throw for a valid flow definition', function () { - expect(() => mermaid.parse('graph TD;A--x|text including URL space|B;')).not.toThrow() - }) - it('it should throw for an invalid flow definition', function () { - expect(() => mermaid.parse('graph TQ;A--x|text including URL space|B;')).toThrow() - }) + it('it should not throw for a valid flow definition', function() { + expect(() => mermaid.parse('graph TD;A--x|text including URL space|B;')).not.toThrow(); + }); + it('it should throw for an invalid flow definition', function() { + expect(() => mermaid.parse('graph TQ;A--x|text including URL space|B;')).toThrow(); + }); - it('it should not throw for a valid sequenceDiagram definition', function () { - const text = 'sequenceDiagram\n' + + it('it should not throw for a valid sequenceDiagram definition', function() { + const text = + 'sequenceDiagram\n' + 'Alice->Bob: Hello Bob, how are you?\n\n' + '%% Comment\n' + 'Note right of Bob: Bob thinks\n' + @@ -197,12 +202,13 @@ describe('when using mermaid and ', function () { 'Bob-->Alice: I am good thanks!\n' + 'else isSick\n' + 'Bob-->Alice: Feel sick...\n' + - 'end' - expect(() => mermaid.parse(text)).not.toThrow() - }) + 'end'; + expect(() => mermaid.parse(text)).not.toThrow(); + }); - it('it should throw for an invalid sequenceDiagram definition', function () { - const text = 'sequenceDiagram\n' + + it('it should throw for an invalid sequenceDiagram definition', function() { + const text = + 'sequenceDiagram\n' + 'Alice:->Bob: Hello Bob, how are you?\n\n' + '%% Comment\n' + 'Note right of Bob: Bob thinks\n' + @@ -210,8 +216,8 @@ describe('when using mermaid and ', function () { 'Bob-->Alice: I am good thanks!\n' + 'else isSick\n' + 'Bob-->Alice: Feel sick...\n' + - 'end' - expect(() => mermaid.parse(text)).toThrow() - }) - }) -}) + 'end'; + expect(() => mermaid.parse(text)).toThrow(); + }); + }); +}); diff --git a/src/mermaidAPI.js b/src/mermaidAPI.js index 522bdafbd..855d16b7f 100644 --- a/src/mermaidAPI.js +++ b/src/mermaidAPI.js @@ -9,38 +9,38 @@ * In addition to the render function, a number of behavioral configuration options are available. * * @name mermaidAPI -*/ -import * as d3 from 'd3' -import scope from 'scope-css' -import pkg from '../package.json' -import { setConfig, getConfig } from './config' -import { logger, setLogLevel } from './logger' -import utils from './utils' -import flowRenderer from './diagrams/flowchart/flowRenderer' -import flowParser from './diagrams/flowchart/parser/flow' -import flowDb from './diagrams/flowchart/flowDb' -import sequenceRenderer from './diagrams/sequence/sequenceRenderer' -import sequenceParser from './diagrams/sequence/parser/sequenceDiagram' -import sequenceDb from './diagrams/sequence/sequenceDb' -import ganttRenderer from './diagrams/gantt/ganttRenderer' -import ganttParser from './diagrams/gantt/parser/gantt' -import ganttDb from './diagrams/gantt/ganttDb' -import classRenderer from './diagrams/class/classRenderer' -import classParser from './diagrams/class/parser/classDiagram' -import classDb from './diagrams/class/classDb' -import gitGraphRenderer from './diagrams/git/gitGraphRenderer' -import gitGraphParser from './diagrams/git/parser/gitGraph' -import gitGraphAst from './diagrams/git/gitGraphAst' -import infoRenderer from './diagrams/info/infoRenderer' -import infoParser from './diagrams/info/parser/info' -import infoDb from './diagrams/info/infoDb' -import pieRenderer from './diagrams/pie/pieRenderer' -import pieParser from './diagrams/pie/parser/pie' -import pieDb from './diagrams/pie/pieDb' + */ +import * as d3 from 'd3'; +import scope from 'scope-css'; +import pkg from '../package.json'; +import { setConfig, getConfig } from './config'; +import { logger, setLogLevel } from './logger'; +import utils from './utils'; +import flowRenderer from './diagrams/flowchart/flowRenderer'; +import flowParser from './diagrams/flowchart/parser/flow'; +import flowDb from './diagrams/flowchart/flowDb'; +import sequenceRenderer from './diagrams/sequence/sequenceRenderer'; +import sequenceParser from './diagrams/sequence/parser/sequenceDiagram'; +import sequenceDb from './diagrams/sequence/sequenceDb'; +import ganttRenderer from './diagrams/gantt/ganttRenderer'; +import ganttParser from './diagrams/gantt/parser/gantt'; +import ganttDb from './diagrams/gantt/ganttDb'; +import classRenderer from './diagrams/class/classRenderer'; +import classParser from './diagrams/class/parser/classDiagram'; +import classDb from './diagrams/class/classDb'; +import gitGraphRenderer from './diagrams/git/gitGraphRenderer'; +import gitGraphParser from './diagrams/git/parser/gitGraph'; +import gitGraphAst from './diagrams/git/gitGraphAst'; +import infoRenderer from './diagrams/info/infoRenderer'; +import infoParser from './diagrams/info/parser/info'; +import infoDb from './diagrams/info/infoDb'; +import pieRenderer from './diagrams/pie/pieRenderer'; +import pieParser from './diagrams/pie/parser/pie'; +import pieDb from './diagrams/pie/pieDb'; -const themes = {} +const themes = {}; for (const themeName of ['default', 'forest', 'dark', 'neutral']) { - themes[themeName] = require(`./themes/${themeName}/index.scss`) + themes[themeName] = require(`./themes/${themeName}/index.scss`); } /** @@ -75,22 +75,21 @@ for (const themeName of ['default', 'forest', 'dark', 'neutral']) { * @name Configuration */ const config = { - /** theme , the CSS style sheet - * - * **theme** - Choose one of the built-in themes: - * * default - * * forest - * * dark - * * neutral. - * To disable any pre-defined mermaid theme, use "null". - * - * **themeCSS** - Use your own CSS. This overrides **theme**. - *
-  *  "theme": "forest",
-  *  "themeCSS": ".node rect { fill: red; }"
-  * 
- */ + * + * **theme** - Choose one of the built-in themes: + * * default + * * forest + * * dark + * * neutral. + * To disable any pre-defined mermaid theme, use "null". + * + * **themeCSS** - Use your own CSS. This overrides **theme**. + *
+   *  "theme": "forest",
+   *  "themeCSS": ".node rect { fill: red; }"
+   * 
+ */ theme: 'default', themeCSS: undefined, @@ -149,7 +148,6 @@ const config = { * The object containing configurations specific for sequence diagrams */ sequence: { - /** * margin to the right and left of the sequence diagram. * **Default value 50**. @@ -234,7 +232,6 @@ const config = { * **Default value false**. */ showSequenceNumbers: false - }, /** @@ -303,100 +300,100 @@ const config = { }, class: {}, git: {} -} +}; -setLogLevel(config.logLevel) -setConfig(config) +setLogLevel(config.logLevel); +setConfig(config); -function parse (text) { - const graphType = utils.detectType(text) - let parser +function parse(text) { + const graphType = utils.detectType(text); + let parser; - logger.debug('Type ' + graphType) + logger.debug('Type ' + graphType); switch (graphType) { case 'git': - parser = gitGraphParser - parser.parser.yy = gitGraphAst - break + parser = gitGraphParser; + parser.parser.yy = gitGraphAst; + break; case 'flowchart': - parser = flowParser - parser.parser.yy = flowDb - break + parser = flowParser; + parser.parser.yy = flowDb; + break; case 'sequence': - parser = sequenceParser - parser.parser.yy = sequenceDb - break + parser = sequenceParser; + parser.parser.yy = sequenceDb; + break; case 'gantt': - parser = ganttParser - parser.parser.yy = ganttDb - break + parser = ganttParser; + parser.parser.yy = ganttDb; + break; case 'class': - parser = classParser - parser.parser.yy = classDb - break + parser = classParser; + parser.parser.yy = classDb; + break; case 'info': - logger.debug('info info info') - console.warn('In API', pkg.version) + logger.debug('info info info'); + console.warn('In API', pkg.version); - parser = infoParser - parser.parser.yy = infoDb - break + parser = infoParser; + parser.parser.yy = infoDb; + break; case 'pie': - logger.debug('pie') - parser = pieParser - parser.parser.yy = pieDb - break + logger.debug('pie'); + parser = pieParser; + parser.parser.yy = pieDb; + break; } parser.parser.yy.parseError = (str, hash) => { - const error = { str, hash } - throw error - } + const error = { str, hash }; + throw error; + }; - parser.parse(text) + parser.parse(text); } -export const encodeEntities = function (text) { - let txt = text +export const encodeEntities = function(text) { + let txt = text; - txt = txt.replace(/style.*:\S*#.*;/g, function (s) { - const innerTxt = s.substring(0, s.length - 1) - return innerTxt - }) - txt = txt.replace(/classDef.*:\S*#.*;/g, function (s) { - const innerTxt = s.substring(0, s.length - 1) - return innerTxt - }) + txt = txt.replace(/style.*:\S*#.*;/g, function(s) { + const innerTxt = s.substring(0, s.length - 1); + return innerTxt; + }); + txt = txt.replace(/classDef.*:\S*#.*;/g, function(s) { + const innerTxt = s.substring(0, s.length - 1); + return innerTxt; + }); - txt = txt.replace(/#\w+;/g, function (s) { - const innerTxt = s.substring(1, s.length - 1) + txt = txt.replace(/#\w+;/g, function(s) { + const innerTxt = s.substring(1, s.length - 1); - const isInt = /^\+?\d+$/.test(innerTxt) + const isInt = /^\+?\d+$/.test(innerTxt); if (isInt) { - return 'fl°°' + innerTxt + '¶ß' + return 'fl°°' + innerTxt + '¶ß'; } else { - return 'fl°' + innerTxt + '¶ß' + return 'fl°' + innerTxt + '¶ß'; } - }) + }); - return txt -} + return txt; +}; -export const decodeEntities = function (text) { - let txt = text +export const decodeEntities = function(text) { + let txt = text; - txt = txt.replace(/fl°°/g, function () { - return '&#' - }) - txt = txt.replace(/fl°/g, function () { - return '&' - }) - txt = txt.replace(/¶ß/g, function () { - return ';' - }) + txt = txt.replace(/fl°°/g, function() { + return '&#'; + }); + txt = txt.replace(/fl°/g, function() { + return '&'; + }); + txt = txt.replace(/¶ß/g, function() { + return ';'; + }); - return txt -} + return txt; +}; /** * Function that renders an svg with a graph from a chart definition. Usage example below. * @@ -419,183 +416,209 @@ export const decodeEntities = function (text) { * provided a hidden div will be inserted in the body of the page instead. The element will be removed when rendering is * completed. */ -const render = function (id, txt, cb, container) { +const render = function(id, txt, cb, container) { if (typeof container !== 'undefined') { - container.innerHTML = '' + container.innerHTML = ''; - d3.select(container).append('div') + d3.select(container) + .append('div') .attr('id', 'd' + id) .append('svg') .attr('id', id) .attr('width', '100%') .attr('xmlns', 'http://www.w3.org/2000/svg') - .append('g') + .append('g'); } else { - const element = document.querySelector('#' + 'd' + id) + const element = document.querySelector('#' + 'd' + id); if (element) { - element.innerHTML = '' + element.innerHTML = ''; } - d3.select('body').append('div') + d3.select('body') + .append('div') .attr('id', 'd' + id) .append('svg') .attr('id', id) .attr('width', '100%') .attr('xmlns', 'http://www.w3.org/2000/svg') - .append('g') + .append('g'); } - window.txt = txt - txt = encodeEntities(txt) + window.txt = txt; + txt = encodeEntities(txt); - const element = d3.select('#d' + id).node() - const graphType = utils.detectType(txt) + const element = d3.select('#d' + id).node(); + const graphType = utils.detectType(txt); // insert inline style into svg - const svg = element.firstChild - const firstChild = svg.firstChild + const svg = element.firstChild; + const firstChild = svg.firstChild; // pre-defined theme - let style = themes[config.theme] + let style = themes[config.theme]; if (style === undefined) { - style = '' + style = ''; } // user provided theme CSS if (config.themeCSS !== undefined) { - style += `\n${config.themeCSS}` + style += `\n${config.themeCSS}`; } // classDef if (graphType === 'flowchart') { - const classes = flowRenderer.getClasses(txt) + const classes = flowRenderer.getClasses(txt); for (const className in classes) { - style += `\n.${className} > * { ${classes[className].styles.join(' !important; ')} !important; }` + style += `\n.${className} > * { ${classes[className].styles.join( + ' !important; ' + )} !important; }`; } } - const style1 = document.createElement('style') - style1.innerHTML = scope(style, `#${id}`) - svg.insertBefore(style1, firstChild) + const style1 = document.createElement('style'); + style1.innerHTML = scope(style, `#${id}`); + svg.insertBefore(style1, firstChild); - const style2 = document.createElement('style') - const cs = window.getComputedStyle(svg) + const style2 = document.createElement('style'); + const cs = window.getComputedStyle(svg); style2.innerHTML = `#${id} { color: ${cs.color}; font: ${cs.font}; - }` - svg.insertBefore(style2, firstChild) + }`; + svg.insertBefore(style2, firstChild); switch (graphType) { case 'git': - config.flowchart.arrowMarkerAbsolute = config.arrowMarkerAbsolute - gitGraphRenderer.setConf(config.git) - gitGraphRenderer.draw(txt, id, false) - break + config.flowchart.arrowMarkerAbsolute = config.arrowMarkerAbsolute; + gitGraphRenderer.setConf(config.git); + gitGraphRenderer.draw(txt, id, false); + break; case 'flowchart': - config.flowchart.arrowMarkerAbsolute = config.arrowMarkerAbsolute - flowRenderer.setConf(config.flowchart) - flowRenderer.draw(txt, id, false) - break + config.flowchart.arrowMarkerAbsolute = config.arrowMarkerAbsolute; + flowRenderer.setConf(config.flowchart); + flowRenderer.draw(txt, id, false); + break; case 'sequence': - config.sequence.arrowMarkerAbsolute = config.arrowMarkerAbsolute - if (config.sequenceDiagram) { // backwards compatibility - sequenceRenderer.setConf(Object.assign(config.sequence, config.sequenceDiagram)) - console.error('`mermaid config.sequenceDiagram` has been renamed to `config.sequence`. Please update your mermaid config.') + config.sequence.arrowMarkerAbsolute = config.arrowMarkerAbsolute; + if (config.sequenceDiagram) { + // backwards compatibility + sequenceRenderer.setConf(Object.assign(config.sequence, config.sequenceDiagram)); + console.error( + '`mermaid config.sequenceDiagram` has been renamed to `config.sequence`. Please update your mermaid config.' + ); } else { - sequenceRenderer.setConf(config.sequence) + sequenceRenderer.setConf(config.sequence); } - sequenceRenderer.draw(txt, id) - break + sequenceRenderer.draw(txt, id); + break; case 'gantt': - config.gantt.arrowMarkerAbsolute = config.arrowMarkerAbsolute - ganttRenderer.setConf(config.gantt) - ganttRenderer.draw(txt, id) - break + config.gantt.arrowMarkerAbsolute = config.arrowMarkerAbsolute; + ganttRenderer.setConf(config.gantt); + ganttRenderer.draw(txt, id); + break; case 'class': - config.class.arrowMarkerAbsolute = config.arrowMarkerAbsolute - classRenderer.setConf(config.class) - classRenderer.draw(txt, id) - break + config.class.arrowMarkerAbsolute = config.arrowMarkerAbsolute; + classRenderer.setConf(config.class); + classRenderer.draw(txt, id); + break; case 'info': - config.class.arrowMarkerAbsolute = config.arrowMarkerAbsolute - infoRenderer.setConf(config.class) - infoRenderer.draw(txt, id, pkg.version) - break + config.class.arrowMarkerAbsolute = config.arrowMarkerAbsolute; + infoRenderer.setConf(config.class); + infoRenderer.draw(txt, id, pkg.version); + break; case 'pie': - config.class.arrowMarkerAbsolute = config.arrowMarkerAbsolute - pieRenderer.setConf(config.class) - pieRenderer.draw(txt, id, pkg.version) - break + config.class.arrowMarkerAbsolute = config.arrowMarkerAbsolute; + pieRenderer.setConf(config.class); + pieRenderer.draw(txt, id, pkg.version); + break; } - d3.select(`[id="${id}"]`).selectAll('foreignobject > *').attr('xmlns', 'http://www.w3.org/1999/xhtml') + d3.select(`[id="${id}"]`) + .selectAll('foreignobject > *') + .attr('xmlns', 'http://www.w3.org/1999/xhtml'); - let url = '' + let url = ''; if (config.arrowMarkerAbsolute) { - url = window.location.protocol + '//' + window.location.host + window.location.pathname + window.location.search - url = url.replace(/\(/g, '\\(') - url = url.replace(/\)/g, '\\)') + url = + window.location.protocol + + '//' + + window.location.host + + window.location.pathname + + window.location.search; + url = url.replace(/\(/g, '\\('); + url = url.replace(/\)/g, '\\)'); } // Fix for when the base tag is used - let svgCode = d3.select('#d' + id).node().innerHTML.replace(/url\(#arrowhead/g, 'url(' + url + '#arrowhead', 'g') + let svgCode = d3 + .select('#d' + id) + .node() + .innerHTML.replace(/url\(#arrowhead/g, 'url(' + url + '#arrowhead', 'g'); - svgCode = decodeEntities(svgCode) + svgCode = decodeEntities(svgCode); if (typeof cb !== 'undefined') { switch (graphType) { case 'flowchart': - cb(svgCode, flowDb.bindFunctions) - break + cb(svgCode, flowDb.bindFunctions); + break; case 'gantt': - cb(svgCode, ganttDb.bindFunctions) - break + cb(svgCode, ganttDb.bindFunctions); + break; default: - cb(svgCode) + cb(svgCode); } } else { - logger.debug('CB = undefined!') + logger.debug('CB = undefined!'); } - const node = d3.select('#d' + id).node() + const node = d3.select('#d' + id).node(); if (node !== null && typeof node.remove === 'function') { - d3.select('#d' + id).node().remove() + d3.select('#d' + id) + .node() + .remove(); } - return svgCode -} + return svgCode; +}; -const setConf = function (cnf) { +const setConf = function(cnf) { // Top level initially mermaid, gflow, sequenceDiagram and gantt - const lvl1Keys = Object.keys(cnf) + const lvl1Keys = Object.keys(cnf); for (let i = 0; i < lvl1Keys.length; i++) { if (typeof cnf[lvl1Keys[i]] === 'object' && cnf[lvl1Keys[i]] != null) { - const lvl2Keys = Object.keys(cnf[lvl1Keys[i]]) + const lvl2Keys = Object.keys(cnf[lvl1Keys[i]]); for (let j = 0; j < lvl2Keys.length; j++) { - logger.debug('Setting conf ', lvl1Keys[i], '-', lvl2Keys[j]) + logger.debug('Setting conf ', lvl1Keys[i], '-', lvl2Keys[j]); if (typeof config[lvl1Keys[i]] === 'undefined') { - config[lvl1Keys[i]] = {} + config[lvl1Keys[i]] = {}; } - logger.debug('Setting config: ' + lvl1Keys[i] + ' ' + lvl2Keys[j] + ' to ' + cnf[lvl1Keys[i]][lvl2Keys[j]]) - config[lvl1Keys[i]][lvl2Keys[j]] = cnf[lvl1Keys[i]][lvl2Keys[j]] + logger.debug( + 'Setting config: ' + + lvl1Keys[i] + + ' ' + + lvl2Keys[j] + + ' to ' + + cnf[lvl1Keys[i]][lvl2Keys[j]] + ); + config[lvl1Keys[i]][lvl2Keys[j]] = cnf[lvl1Keys[i]][lvl2Keys[j]]; } } else { - config[lvl1Keys[i]] = cnf[lvl1Keys[i]] + config[lvl1Keys[i]] = cnf[lvl1Keys[i]]; } } -} +}; -function initialize (options) { - logger.debug('Initializing mermaidAPI ', pkg.version) +function initialize(options) { + logger.debug('Initializing mermaidAPI ', pkg.version); // Update default config with options supplied at initialization if (typeof options === 'object') { - setConf(options) + setConf(options); } - setConfig(config) - setLogLevel(config.logLevel) + setConfig(config); + setLogLevel(config.logLevel); } // function getConfig () { @@ -608,9 +631,9 @@ const mermaidAPI = { parse, initialize, getConfig -} +}; -export default mermaidAPI +export default mermaidAPI; /** * ## mermaidAPI configuration defaults *
diff --git a/src/mermaidAPI.spec.js b/src/mermaidAPI.spec.js
index 51749677c..a5114356f 100644
--- a/src/mermaidAPI.spec.js
+++ b/src/mermaidAPI.spec.js
@@ -1,45 +1,45 @@
 /* eslint-env jasmine */
-import mermaidAPI from './mermaidAPI'
+import mermaidAPI from './mermaidAPI';
 
-describe('when using mermaidAPI and ', function () {
-  describe('doing initialize ', function () {
-    beforeEach(function () {
-      document.body.innerHTML = ''
-    })
+describe('when using mermaidAPI and ', function() {
+  describe('doing initialize ', function() {
+    beforeEach(function() {
+      document.body.innerHTML = '';
+    });
 
-    it('should copy a literal into the configuration', function () {
-      const orgConfig = mermaidAPI.getConfig()
-      expect(orgConfig.testLiteral).toBe(undefined)
+    it('should copy a literal into the configuration', function() {
+      const orgConfig = mermaidAPI.getConfig();
+      expect(orgConfig.testLiteral).toBe(undefined);
 
-      mermaidAPI.initialize({ 'testLiteral': true })
-      const config = mermaidAPI.getConfig()
+      mermaidAPI.initialize({ testLiteral: true });
+      const config = mermaidAPI.getConfig();
 
-      expect(config.testLiteral).toBe(true)
-    })
-    it('should copy a an object into the configuration', function () {
-      const orgConfig = mermaidAPI.getConfig()
-      expect(orgConfig.testObject).toBe(undefined)
+      expect(config.testLiteral).toBe(true);
+    });
+    it('should copy a an object into the configuration', function() {
+      const orgConfig = mermaidAPI.getConfig();
+      expect(orgConfig.testObject).toBe(undefined);
 
       const object = {
         test1: 1,
         test2: false
-      }
+      };
 
-      mermaidAPI.initialize({ 'testObject': object })
-      mermaidAPI.initialize({ 'testObject': { 'test3': true } })
-      const config = mermaidAPI.getConfig()
+      mermaidAPI.initialize({ testObject: object });
+      mermaidAPI.initialize({ testObject: { test3: true } });
+      const config = mermaidAPI.getConfig();
 
-      expect(config.testObject.test1).toBe(1)
-      expect(config.testObject.test2).toBe(false)
-      expect(config.testObject.test3).toBe(true)
-    })
-  })
-  describe('checking validity of input ', function () {
-    it('it should throw for an invalid definiton', function () {
-      expect(() => mermaidAPI.parse('this is not a mermaid diagram definition')).toThrow()
-    })
-    it('it should not throw for a valid definiton', function () {
-      expect(() => mermaidAPI.parse('graph TD;A--x|text including URL space|B;')).not.toThrow()
-    })
-  })
-})
+      expect(config.testObject.test1).toBe(1);
+      expect(config.testObject.test2).toBe(false);
+      expect(config.testObject.test3).toBe(true);
+    });
+  });
+  describe('checking validity of input ', function() {
+    it('it should throw for an invalid definiton', function() {
+      expect(() => mermaidAPI.parse('this is not a mermaid diagram definition')).toThrow();
+    });
+    it('it should not throw for a valid definiton', function() {
+      expect(() => mermaidAPI.parse('graph TD;A--x|text including URL space|B;')).not.toThrow();
+    });
+  });
+});