{"version":3,"file":"stateDiagram-v2-3a9af217.js","sources":["../src/diagrams/state/stateRenderer-v2.js","../src/diagrams/state/stateDiagram-v2.ts"],"sourcesContent":["import * as graphlib from 'dagre-d3-es/src/graphlib/index.js';\nimport { select } from 'd3';\nimport { getConfig } from '../../config';\nimport { render } from '../../dagre-wrapper/index.js';\nimport { log } from '../../logger';\nimport { configureSvgSize } from '../../setupGraphViewbox';\nimport common from '../common/common';\nimport utils from '../../utils';\n\nimport {\n DEFAULT_DIAGRAM_DIRECTION,\n DEFAULT_NESTED_DOC_DIR,\n STMT_STATE,\n STMT_RELATION,\n DEFAULT_STATE_TYPE,\n DIVIDER_TYPE,\n} from './stateCommon';\n\n// --------------------------------------\n// Shapes\nconst SHAPE_STATE = 'rect';\nconst SHAPE_STATE_WITH_DESC = 'rectWithTitle';\nconst SHAPE_START = 'start';\nconst SHAPE_END = 'end';\nconst SHAPE_DIVIDER = 'divider';\nconst SHAPE_GROUP = 'roundedWithTitle';\nconst SHAPE_NOTE = 'note';\nconst SHAPE_NOTEGROUP = 'noteGroup';\n\n// --------------------------------------\n// CSS classes\nconst CSS_DIAGRAM = 'statediagram';\nconst CSS_STATE = 'state';\nconst CSS_DIAGRAM_STATE = `${CSS_DIAGRAM}-${CSS_STATE}`;\nconst CSS_EDGE = 'transition';\nconst CSS_NOTE = 'note';\nconst CSS_NOTE_EDGE = 'note-edge';\nconst CSS_EDGE_NOTE_EDGE = `${CSS_EDGE} ${CSS_NOTE_EDGE}`;\nconst CSS_DIAGRAM_NOTE = `${CSS_DIAGRAM}-${CSS_NOTE}`;\nconst CSS_CLUSTER = 'cluster';\nconst CSS_DIAGRAM_CLUSTER = `${CSS_DIAGRAM}-${CSS_CLUSTER}`;\nconst CSS_CLUSTER_ALT = 'cluster-alt';\nconst CSS_DIAGRAM_CLUSTER_ALT = `${CSS_DIAGRAM}-${CSS_CLUSTER_ALT}`;\n\n// --------------------------------------\n// DOM and element IDs\nconst PARENT = 'parent';\nconst NOTE = 'note';\nconst DOMID_STATE = 'state';\nconst DOMID_TYPE_SPACER = '----';\nconst NOTE_ID = `${DOMID_TYPE_SPACER}${NOTE}`;\nconst PARENT_ID = `${DOMID_TYPE_SPACER}${PARENT}`;\n// --------------------------------------\n// Graph edge settings\nconst G_EDGE_STYLE = 'fill:none';\nconst G_EDGE_ARROWHEADSTYLE = 'fill: #333';\nconst G_EDGE_LABELPOS = 'c';\nconst G_EDGE_LABELTYPE = 'text';\nconst G_EDGE_THICKNESS = 'normal';\n\n// --------------------------------------\n// List of nodes created from the parsed diagram statement items\nlet nodeDb = {};\n\nlet graphItemCount = 0; // used to construct ids, etc.\n\n// Configuration\nconst conf = {};\n\n// -----------------------------------------------------------------------\n\nexport const setConf = function (cnf) {\n const keys = Object.keys(cnf);\n for (const key of keys) {\n conf[key] = cnf[key];\n }\n};\n\n/**\n * Returns the all the classdef styles (a.k.a. classes) from classDef statements in the graph definition.\n *\n * @param {string} text - the diagram text to be parsed\n * @param diagramObj\n * @returns {object} ClassDef styles (a Map with keys = strings, values = )\n */\nexport const getClasses = function (text, diagramObj) {\n log.trace('Extracting classes');\n diagramObj.db.clear();\n try {\n // Parse the graph definition\n diagramObj.parser.parse(text);\n // must run extract() to turn the parsed statements into states, relationships, classes, etc.\n diagramObj.db.extract(diagramObj.db.getRootDocV2());\n return diagramObj.db.getClasses();\n } catch (e) {\n return e;\n }\n};\n\n/**\n * Get classes from the db for the info item.\n * If there aren't any or if dbInfoItem isn't defined, return an empty string.\n * Else create 1 string from the list of classes found\n *\n * @param {undefined | null | object} dbInfoItem\n * @returns {string}\n */\nfunction getClassesFromDbInfo(dbInfoItem) {\n if (dbInfoItem === undefined || dbInfoItem === null) {\n return '';\n } else {\n if (dbInfoItem.classes) {\n return dbInfoItem.classes.join(' ');\n } else {\n return '';\n }\n }\n}\n\n/**\n * Create a standard string for the dom ID of an item.\n * If a type is given, insert that before the counter, preceded by the type spacer\n *\n * @param itemId\n * @param counter\n * @param {string | null} type\n * @param typeSpacer\n * @returns {string}\n */\nexport function stateDomId(itemId = '', counter = 0, type = '', typeSpacer = DOMID_TYPE_SPACER) {\n const typeStr = type !== null && type.length > 0 ? `${typeSpacer}${type}` : '';\n return `${DOMID_STATE}-${itemId}${typeStr}-${counter}`;\n}\n\n/**\n * Create a graph node based on the statement information\n *\n * @param g - graph\n * @param {object} parent\n * @param {object} parsedItem - parsed statement item\n * @param {object[]} diagramStates - the list of all known states for the diagram\n * @param {object} diagramDb\n * @param {boolean} altFlag - for clusters, add the \"statediagram-cluster-alt\" CSS class\n */\nconst setupNode = (g, parent, parsedItem, diagramStates, diagramDb, altFlag) => {\n const itemId = parsedItem.id;\n const classStr = getClassesFromDbInfo(diagramStates[itemId]);\n\n if (itemId !== 'root') {\n let shape = SHAPE_STATE;\n if (parsedItem.start === true) {\n shape = SHAPE_START;\n }\n if (parsedItem.start === false) {\n shape = SHAPE_END;\n }\n if (parsedItem.type !== DEFAULT_STATE_TYPE) {\n shape = parsedItem.type;\n }\n\n // Add the node to our list (nodeDb)\n if (!nodeDb[itemId]) {\n nodeDb[itemId] = {\n id: itemId,\n shape,\n description: common.sanitizeText(itemId, getConfig()),\n classes: `${classStr} ${CSS_DIAGRAM_STATE}`,\n };\n }\n\n const newNode = nodeDb[itemId];\n\n // Save data for description and group so that for instance a statement without description overwrites\n // one with description @todo TODO What does this mean? If important, add a test for it\n\n // Build of the array of description strings\n if (parsedItem.description) {\n if (Array.isArray(newNode.description)) {\n // There already is an array of strings,add to it\n newNode.shape = SHAPE_STATE_WITH_DESC;\n newNode.description.push(parsedItem.description);\n } else {\n if (newNode.description.length > 0) {\n // if there is a description already transform it to an array\n newNode.shape = SHAPE_STATE_WITH_DESC;\n if (newNode.description === itemId) {\n // If the previous description was this, remove it\n newNode.description = [parsedItem.description];\n } else {\n newNode.description = [newNode.description, parsedItem.description];\n }\n } else {\n newNode.shape = SHAPE_STATE;\n newNode.description = parsedItem.description;\n }\n }\n newNode.description = common.sanitizeTextOrArray(newNode.description, getConfig());\n }\n\n // If there's only 1 description entry, just use a regular state shape\n if (newNode.description.length === 1 && newNode.shape === SHAPE_STATE_WITH_DESC) {\n newNode.shape = SHAPE_STATE;\n }\n\n // group\n if (!newNode.type && parsedItem.doc) {\n log.info('Setting cluster for ', itemId, getDir(parsedItem));\n newNode.type = 'group';\n newNode.dir = getDir(parsedItem);\n newNode.shape = parsedItem.type === DIVIDER_TYPE ? SHAPE_DIVIDER : SHAPE_GROUP;\n newNode.classes =\n newNode.classes +\n ' ' +\n CSS_DIAGRAM_CLUSTER +\n ' ' +\n (altFlag ? CSS_DIAGRAM_CLUSTER_ALT : '');\n }\n\n // This is what will be added to the graph\n const nodeData = {\n labelStyle: '',\n shape: newNode.shape,\n labelText: newNode.description,\n // typeof newNode.description === 'object'\n // ? newNode.description[0]\n // : newNode.description,\n classes: newNode.classes,\n style: '', //styles.style,\n id: itemId,\n dir: newNode.dir,\n domId: stateDomId(itemId, graphItemCount),\n type: newNode.type,\n padding: 15, //getConfig().flowchart.padding\n };\n\n if (parsedItem.note) {\n // Todo: set random id\n const noteData = {\n labelStyle: '',\n shape: SHAPE_NOTE,\n labelText: parsedItem.note.text,\n classes: CSS_DIAGRAM_NOTE,\n style: '', // styles.style,\n id: itemId + NOTE_ID + '-' + graphItemCount,\n domId: stateDomId(itemId, graphItemCount, NOTE),\n type: newNode.type,\n padding: 15, //getConfig().flowchart.padding\n };\n const groupData = {\n labelStyle: '',\n shape: SHAPE_NOTEGROUP,\n labelText: parsedItem.note.text,\n classes: newNode.classes,\n style: '', // styles.style,\n id: itemId + PARENT_ID,\n domId: stateDomId(itemId, graphItemCount, PARENT),\n type: 'group',\n padding: 0, //getConfig().flowchart.padding\n };\n graphItemCount++;\n\n const parentNodeId = itemId + PARENT_ID;\n g.setNode(parentNodeId, groupData);\n\n g.setNode(noteData.id, noteData);\n g.setNode(itemId, nodeData);\n\n g.setParent(itemId, parentNodeId);\n g.setParent(noteData.id, parentNodeId);\n\n let from = itemId;\n let to = noteData.id;\n\n if (parsedItem.note.position === 'left of') {\n from = noteData.id;\n to = itemId;\n }\n g.setEdge(from, to, {\n arrowhead: 'none',\n arrowType: '',\n style: G_EDGE_STYLE,\n labelStyle: '',\n classes: CSS_EDGE_NOTE_EDGE,\n arrowheadStyle: G_EDGE_ARROWHEADSTYLE,\n labelpos: G_EDGE_LABELPOS,\n labelType: G_EDGE_LABELTYPE,\n thickness: G_EDGE_THICKNESS,\n });\n } else {\n g.setNode(itemId, nodeData);\n }\n }\n\n if (parent && parent.id !== 'root') {\n log.trace('Setting node ', itemId, ' to be child of its parent ', parent.id);\n g.setParent(itemId, parent.id);\n }\n if (parsedItem.doc) {\n log.trace('Adding nodes children ');\n setupDoc(g, parsedItem, parsedItem.doc, diagramStates, diagramDb, !altFlag);\n }\n};\n\n/**\n * Turn parsed statements (item.stmt) into nodes, relationships, etc. for a document.\n * (A document may be nested within others.)\n *\n * @param g\n * @param parentParsedItem - parsed Item that is the parent of this document (doc)\n * @param doc - the document to set up; it is a list of parsed statements\n * @param {object[]} diagramStates - the list of all known states for the diagram\n * @param diagramDb\n * @param {boolean} altFlag\n * @todo This duplicates some of what is done in stateDb.js extract method\n */\nconst setupDoc = (g, parentParsedItem, doc, diagramStates, diagramDb, altFlag) => {\n // graphItemCount = 0;\n log.trace('items', doc);\n doc.forEach((item) => {\n switch (item.stmt) {\n case STMT_STATE:\n setupNode(g, parentParsedItem, item, diagramStates, diagramDb, altFlag);\n break;\n case DEFAULT_STATE_TYPE:\n setupNode(g, parentParsedItem, item, diagramStates, diagramDb, altFlag);\n break;\n case STMT_RELATION:\n {\n setupNode(g, parentParsedItem, item.state1, diagramStates, diagramDb, altFlag);\n setupNode(g, parentParsedItem, item.state2, diagramStates, diagramDb, altFlag);\n const edgeData = {\n id: 'edge' + graphItemCount,\n arrowhead: 'normal',\n arrowTypeEnd: 'arrow_barb',\n style: G_EDGE_STYLE,\n labelStyle: '',\n label: common.sanitizeText(item.description, getConfig()),\n arrowheadStyle: G_EDGE_ARROWHEADSTYLE,\n labelpos: G_EDGE_LABELPOS,\n labelType: G_EDGE_LABELTYPE,\n thickness: G_EDGE_THICKNESS,\n classes: CSS_EDGE,\n };\n g.setEdge(item.state1.id, item.state2.id, edgeData, graphItemCount);\n graphItemCount++;\n }\n break;\n }\n });\n};\n\n/**\n * Get the direction from the statement items.\n * Look through all of the documents (docs) in the parsedItems\n * Because is a _document_ direction, the default direction is not necessarily the same as the overall default _diagram_ direction.\n * @param {object[]} parsedItem - the parsed statement item to look through\n * @param [defaultDir=DEFAULT_NESTED_DOC_DIR] - the direction to use if none is found\n * @returns {string}\n */\nconst getDir = (parsedItem, defaultDir = DEFAULT_NESTED_DOC_DIR) => {\n let dir = defaultDir;\n if (parsedItem.doc) {\n for (let i = 0; i < parsedItem.doc.length; i++) {\n const parsedItemDoc = parsedItem.doc[i];\n if (parsedItemDoc.stmt === 'dir') {\n dir = parsedItemDoc.value;\n }\n }\n }\n return dir;\n};\n\n/**\n * Draws a state diagram in the tag with id: id based on the graph definition in text.\n *\n * @param {any} text\n * @param {any} id\n * @param _version\n * @param diag\n */\nexport const draw = function (text, id, _version, diag) {\n log.info('Drawing state diagram (v2)', id);\n // diag.sb.clear();\n nodeDb = {};\n // Fetch the default direction, use TD if none was found\n let dir = diag.db.getDirection();\n if (dir === undefined) {\n dir = DEFAULT_DIAGRAM_DIRECTION;\n }\n\n const { securityLevel, state: conf } = getConfig();\n const nodeSpacing = conf.nodeSpacing || 50;\n const rankSpacing = conf.rankSpacing || 50;\n\n log.info(diag.db.getRootDocV2());\n\n // This parses the diagram text and sets the classes, relations, styles, classDefs, etc.\n diag.db.extract(diag.db.getRootDocV2());\n log.info(diag.db.getRootDocV2());\n\n const diagramStates = diag.db.getStates();\n\n // Create the input mermaid.graph\n const g = new graphlib.Graph({\n multigraph: true,\n compound: true,\n })\n .setGraph({\n rankdir: getDir(diag.db.getRootDocV2()),\n nodesep: nodeSpacing,\n ranksep: rankSpacing,\n marginx: 8,\n marginy: 8,\n })\n .setDefaultEdgeLabel(function () {\n return {};\n });\n\n setupNode(g, undefined, diag.db.getRootDocV2(), diagramStates, diag.db, true);\n\n // Set up an SVG group so that we can translate the final graph.\n let sandboxElement;\n if (securityLevel === 'sandbox') {\n sandboxElement = select('#i' + id);\n }\n const root =\n securityLevel === 'sandbox'\n ? select(sandboxElement.nodes()[0].contentDocument.body)\n : select('body');\n const svg = root.select(`[id=\"${id}\"]`);\n\n // Run the renderer. This is what draws the final graph.\n\n const element = root.select('#' + id + ' g');\n render(element, g, ['barb'], CSS_DIAGRAM, id);\n\n const padding = 8;\n\n utils.insertTitle(svg, 'statediagramTitleText', conf.titleTopMargin, diag.db.getDiagramTitle());\n\n const bounds = svg.node().getBBox();\n const width = bounds.width + padding * 2;\n const height = bounds.height + padding * 2;\n\n // Zoom in a bit\n svg.attr('class', CSS_DIAGRAM);\n\n const svgBounds = svg.node().getBBox();\n\n configureSvgSize(svg, height, width, conf.useMaxWidth);\n\n // Ensure the viewBox includes the whole svgBounds area with extra space for padding\n const vBox = `${svgBounds.x - padding} ${svgBounds.y - padding} ${width} ${height}`;\n log.debug(`viewBox ${vBox}`);\n svg.attr('viewBox', vBox);\n\n // Add label rects for non html labels\n // if (!evaluate(conf.htmlLabels) || true) {\n const labels = document.querySelectorAll('[id=\"' + id + '\"] .edgeLabel .label');\n for (const label of labels) {\n // Get dimensions of label\n const dim = label.getBBox();\n\n const rect = document.createElementNS('http://www.w3.org/2000/svg', SHAPE_STATE);\n rect.setAttribute('rx', 0);\n rect.setAttribute('ry', 0);\n rect.setAttribute('width', dim.width);\n rect.setAttribute('height', dim.height);\n\n label.insertBefore(rect, label.firstChild);\n // }\n }\n};\n\nexport default {\n setConf,\n getClasses,\n draw,\n};\n","import { DiagramDefinition } from '../../diagram-api/types';\n// @ts-ignore: TODO Fix ts errors\nimport parser from './parser/stateDiagram';\nimport db from './stateDb';\nimport styles from './styles';\nimport renderer from './stateRenderer-v2';\n\nexport const diagram: DiagramDefinition = {\n parser,\n db,\n renderer,\n styles,\n init: (cnf) => {\n if (!cnf.state) {\n cnf.state = {};\n }\n cnf.state.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;\n db.clear();\n },\n};\n"],"names":["graphlib.Graph"],"mappings":"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"}