UNPKG

11.3 kBJavaScriptView Raw
1import { D as DEFAULT_STATE_TYPE, a as DIVIDER_TYPE, S as STMT_RELATION, b as STMT_STATE, c as DEFAULT_NESTED_DOC_DIR, p as parser, d as db, s as styles } from "./styles-0784dbeb.js";
2import * as graphlib from "dagre-d3-es/src/graphlib/index.js";
3import { select } from "d3";
4import { l as log, c as getConfig, u as utils, i as configureSvgSize, e as common } from "./mermaid-6dc72991.js";
5import { r as render } from "./index-01f381cb.js";
6import "ts-dedent";
7import "dayjs";
8import "@braintree/sanitize-url";
9import "dompurify";
10import "khroma";
11import "lodash-es/memoize.js";
12import "lodash-es/merge.js";
13import "stylis";
14import "lodash-es/isEmpty.js";
15import "dagre-d3-es/src/dagre/index.js";
16import "dagre-d3-es/src/graphlib/json.js";
17import "./edges-066a5561.js";
18import "./createText-ca0c5216.js";
19import "mdast-util-from-markdown";
20const SHAPE_STATE = "rect";
21const SHAPE_STATE_WITH_DESC = "rectWithTitle";
22const SHAPE_START = "start";
23const SHAPE_END = "end";
24const SHAPE_DIVIDER = "divider";
25const SHAPE_GROUP = "roundedWithTitle";
26const SHAPE_NOTE = "note";
27const SHAPE_NOTEGROUP = "noteGroup";
28const CSS_DIAGRAM = "statediagram";
29const CSS_STATE = "state";
30const CSS_DIAGRAM_STATE = `${CSS_DIAGRAM}-${CSS_STATE}`;
31const CSS_EDGE = "transition";
32const CSS_NOTE = "note";
33const CSS_NOTE_EDGE = "note-edge";
34const CSS_EDGE_NOTE_EDGE = `${CSS_EDGE} ${CSS_NOTE_EDGE}`;
35const CSS_DIAGRAM_NOTE = `${CSS_DIAGRAM}-${CSS_NOTE}`;
36const CSS_CLUSTER = "cluster";
37const CSS_DIAGRAM_CLUSTER = `${CSS_DIAGRAM}-${CSS_CLUSTER}`;
38const CSS_CLUSTER_ALT = "cluster-alt";
39const CSS_DIAGRAM_CLUSTER_ALT = `${CSS_DIAGRAM}-${CSS_CLUSTER_ALT}`;
40const PARENT = "parent";
41const NOTE = "note";
42const DOMID_STATE = "state";
43const DOMID_TYPE_SPACER = "----";
44const NOTE_ID = `${DOMID_TYPE_SPACER}${NOTE}`;
45const PARENT_ID = `${DOMID_TYPE_SPACER}${PARENT}`;
46const G_EDGE_STYLE = "fill:none";
47const G_EDGE_ARROWHEADSTYLE = "fill: #333";
48const G_EDGE_LABELPOS = "c";
49const G_EDGE_LABELTYPE = "text";
50const G_EDGE_THICKNESS = "normal";
51let nodeDb = {};
52let graphItemCount = 0;
53const setConf = function(cnf) {
54 const keys = Object.keys(cnf);
55 for (const key of keys) {
56 cnf[key];
57 }
58};
59const getClasses = function(text, diagramObj) {
60 diagramObj.db.extract(diagramObj.db.getRootDocV2());
61 return diagramObj.db.getClasses();
62};
63function getClassesFromDbInfo(dbInfoItem) {
64 if (dbInfoItem === void 0 || dbInfoItem === null) {
65 return "";
66 } else {
67 if (dbInfoItem.classes) {
68 return dbInfoItem.classes.join(" ");
69 } else {
70 return "";
71 }
72 }
73}
74function stateDomId(itemId = "", counter = 0, type = "", typeSpacer = DOMID_TYPE_SPACER) {
75 const typeStr = type !== null && type.length > 0 ? `${typeSpacer}${type}` : "";
76 return `${DOMID_STATE}-${itemId}${typeStr}-${counter}`;
77}
78const setupNode = (g, parent, parsedItem, diagramStates, diagramDb, altFlag) => {
79 const itemId = parsedItem.id;
80 const classStr = getClassesFromDbInfo(diagramStates[itemId]);
81 if (itemId !== "root") {
82 let shape = SHAPE_STATE;
83 if (parsedItem.start === true) {
84 shape = SHAPE_START;
85 }
86 if (parsedItem.start === false) {
87 shape = SHAPE_END;
88 }
89 if (parsedItem.type !== DEFAULT_STATE_TYPE) {
90 shape = parsedItem.type;
91 }
92 if (!nodeDb[itemId]) {
93 nodeDb[itemId] = {
94 id: itemId,
95 shape,
96 description: common.sanitizeText(itemId, getConfig()),
97 classes: `${classStr} ${CSS_DIAGRAM_STATE}`
98 };
99 }
100 const newNode = nodeDb[itemId];
101 if (parsedItem.description) {
102 if (Array.isArray(newNode.description)) {
103 newNode.shape = SHAPE_STATE_WITH_DESC;
104 newNode.description.push(parsedItem.description);
105 } else {
106 if (newNode.description.length > 0) {
107 newNode.shape = SHAPE_STATE_WITH_DESC;
108 if (newNode.description === itemId) {
109 newNode.description = [parsedItem.description];
110 } else {
111 newNode.description = [newNode.description, parsedItem.description];
112 }
113 } else {
114 newNode.shape = SHAPE_STATE;
115 newNode.description = parsedItem.description;
116 }
117 }
118 newNode.description = common.sanitizeTextOrArray(newNode.description, getConfig());
119 }
120 if (newNode.description.length === 1 && newNode.shape === SHAPE_STATE_WITH_DESC) {
121 newNode.shape = SHAPE_STATE;
122 }
123 if (!newNode.type && parsedItem.doc) {
124 log.info("Setting cluster for ", itemId, getDir(parsedItem));
125 newNode.type = "group";
126 newNode.dir = getDir(parsedItem);
127 newNode.shape = parsedItem.type === DIVIDER_TYPE ? SHAPE_DIVIDER : SHAPE_GROUP;
128 newNode.classes = newNode.classes + " " + CSS_DIAGRAM_CLUSTER + " " + (altFlag ? CSS_DIAGRAM_CLUSTER_ALT : "");
129 }
130 const nodeData = {
131 labelStyle: "",
132 shape: newNode.shape,
133 labelText: newNode.description,
134 // typeof newNode.description === 'object'
135 // ? newNode.description[0]
136 // : newNode.description,
137 classes: newNode.classes,
138 style: "",
139 //styles.style,
140 id: itemId,
141 dir: newNode.dir,
142 domId: stateDomId(itemId, graphItemCount),
143 type: newNode.type,
144 padding: 15
145 //getConfig().flowchart.padding
146 };
147 nodeData.centerLabel = true;
148 if (parsedItem.note) {
149 const noteData = {
150 labelStyle: "",
151 shape: SHAPE_NOTE,
152 labelText: parsedItem.note.text,
153 classes: CSS_DIAGRAM_NOTE,
154 // useHtmlLabels: false,
155 style: "",
156 // styles.style,
157 id: itemId + NOTE_ID + "-" + graphItemCount,
158 domId: stateDomId(itemId, graphItemCount, NOTE),
159 type: newNode.type,
160 padding: 15
161 //getConfig().flowchart.padding
162 };
163 const groupData = {
164 labelStyle: "",
165 shape: SHAPE_NOTEGROUP,
166 labelText: parsedItem.note.text,
167 classes: newNode.classes,
168 style: "",
169 // styles.style,
170 id: itemId + PARENT_ID,
171 domId: stateDomId(itemId, graphItemCount, PARENT),
172 type: "group",
173 padding: 0
174 //getConfig().flowchart.padding
175 };
176 graphItemCount++;
177 const parentNodeId = itemId + PARENT_ID;
178 g.setNode(parentNodeId, groupData);
179 g.setNode(noteData.id, noteData);
180 g.setNode(itemId, nodeData);
181 g.setParent(itemId, parentNodeId);
182 g.setParent(noteData.id, parentNodeId);
183 let from = itemId;
184 let to = noteData.id;
185 if (parsedItem.note.position === "left of") {
186 from = noteData.id;
187 to = itemId;
188 }
189 g.setEdge(from, to, {
190 arrowhead: "none",
191 arrowType: "",
192 style: G_EDGE_STYLE,
193 labelStyle: "",
194 classes: CSS_EDGE_NOTE_EDGE,
195 arrowheadStyle: G_EDGE_ARROWHEADSTYLE,
196 labelpos: G_EDGE_LABELPOS,
197 labelType: G_EDGE_LABELTYPE,
198 thickness: G_EDGE_THICKNESS
199 });
200 } else {
201 g.setNode(itemId, nodeData);
202 }
203 }
204 if (parent && parent.id !== "root") {
205 log.trace("Setting node ", itemId, " to be child of its parent ", parent.id);
206 g.setParent(itemId, parent.id);
207 }
208 if (parsedItem.doc) {
209 log.trace("Adding nodes children ");
210 setupDoc(g, parsedItem, parsedItem.doc, diagramStates, diagramDb, !altFlag);
211 }
212};
213const setupDoc = (g, parentParsedItem, doc, diagramStates, diagramDb, altFlag) => {
214 log.trace("items", doc);
215 doc.forEach((item) => {
216 switch (item.stmt) {
217 case STMT_STATE:
218 setupNode(g, parentParsedItem, item, diagramStates, diagramDb, altFlag);
219 break;
220 case DEFAULT_STATE_TYPE:
221 setupNode(g, parentParsedItem, item, diagramStates, diagramDb, altFlag);
222 break;
223 case STMT_RELATION:
224 {
225 setupNode(g, parentParsedItem, item.state1, diagramStates, diagramDb, altFlag);
226 setupNode(g, parentParsedItem, item.state2, diagramStates, diagramDb, altFlag);
227 const edgeData = {
228 id: "edge" + graphItemCount,
229 arrowhead: "normal",
230 arrowTypeEnd: "arrow_barb",
231 style: G_EDGE_STYLE,
232 labelStyle: "",
233 label: common.sanitizeText(item.description, getConfig()),
234 arrowheadStyle: G_EDGE_ARROWHEADSTYLE,
235 labelpos: G_EDGE_LABELPOS,
236 labelType: G_EDGE_LABELTYPE,
237 thickness: G_EDGE_THICKNESS,
238 classes: CSS_EDGE
239 };
240 g.setEdge(item.state1.id, item.state2.id, edgeData, graphItemCount);
241 graphItemCount++;
242 }
243 break;
244 }
245 });
246};
247const getDir = (parsedItem, defaultDir = DEFAULT_NESTED_DOC_DIR) => {
248 let dir = defaultDir;
249 if (parsedItem.doc) {
250 for (let i = 0; i < parsedItem.doc.length; i++) {
251 const parsedItemDoc = parsedItem.doc[i];
252 if (parsedItemDoc.stmt === "dir") {
253 dir = parsedItemDoc.value;
254 }
255 }
256 }
257 return dir;
258};
259const draw = async function(text, id, _version, diag) {
260 log.info("Drawing state diagram (v2)", id);
261 nodeDb = {};
262 diag.db.getDirection();
263 const { securityLevel, state: conf } = getConfig();
264 const nodeSpacing = conf.nodeSpacing || 50;
265 const rankSpacing = conf.rankSpacing || 50;
266 log.info(diag.db.getRootDocV2());
267 diag.db.extract(diag.db.getRootDocV2());
268 log.info(diag.db.getRootDocV2());
269 const diagramStates = diag.db.getStates();
270 const g = new graphlib.Graph({
271 multigraph: true,
272 compound: true
273 }).setGraph({
274 rankdir: getDir(diag.db.getRootDocV2()),
275 nodesep: nodeSpacing,
276 ranksep: rankSpacing,
277 marginx: 8,
278 marginy: 8
279 }).setDefaultEdgeLabel(function() {
280 return {};
281 });
282 setupNode(g, void 0, diag.db.getRootDocV2(), diagramStates, diag.db, true);
283 let sandboxElement;
284 if (securityLevel === "sandbox") {
285 sandboxElement = select("#i" + id);
286 }
287 const root = securityLevel === "sandbox" ? select(sandboxElement.nodes()[0].contentDocument.body) : select("body");
288 const svg = root.select(`[id="${id}"]`);
289 const element = root.select("#" + id + " g");
290 await render(element, g, ["barb"], CSS_DIAGRAM, id);
291 const padding = 8;
292 utils.insertTitle(svg, "statediagramTitleText", conf.titleTopMargin, diag.db.getDiagramTitle());
293 const bounds = svg.node().getBBox();
294 const width = bounds.width + padding * 2;
295 const height = bounds.height + padding * 2;
296 svg.attr("class", CSS_DIAGRAM);
297 const svgBounds = svg.node().getBBox();
298 configureSvgSize(svg, height, width, conf.useMaxWidth);
299 const vBox = `${svgBounds.x - padding} ${svgBounds.y - padding} ${width} ${height}`;
300 log.debug(`viewBox ${vBox}`);
301 svg.attr("viewBox", vBox);
302 const labels = document.querySelectorAll('[id="' + id + '"] .edgeLabel .label');
303 for (const label of labels) {
304 const dim = label.getBBox();
305 const rect = document.createElementNS("http://www.w3.org/2000/svg", SHAPE_STATE);
306 rect.setAttribute("rx", 0);
307 rect.setAttribute("ry", 0);
308 rect.setAttribute("width", dim.width);
309 rect.setAttribute("height", dim.height);
310 label.insertBefore(rect, label.firstChild);
311 }
312};
313const renderer = {
314 setConf,
315 getClasses,
316 draw
317};
318const diagram = {
319 parser,
320 db,
321 renderer,
322 styles,
323 init: (cnf) => {
324 if (!cnf.state) {
325 cnf.state = {};
326 }
327 cnf.state.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
328 db.clear();
329 }
330};
331export {
332 diagram
333};