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