From 6d74c5663f56d6b617ae38146da12f75c4c48552 Mon Sep 17 00:00:00 2001 From: Justin Greywolf Date: Fri, 21 Feb 2020 13:49:05 -0800 Subject: [PATCH 1/9] 1169- break out getRows Moved getRows function from `state/stateRenderer.js` and `state/shapes.js` into `common/common.js`. Broke out section into small one line functions for replacing line breaks, then moved the `sanitize` function from `utils.js` to this new module as there is shared functionality --- src/diagrams/class/classDb.js | 5 ++-- src/diagrams/common/common.js | 39 +++++++++++++++++++++++++++++ src/diagrams/flowchart/flowDb.js | 9 ++++--- src/diagrams/state/shapes.js | 9 ++----- src/diagrams/state/stateRenderer.js | 11 ++------ src/utils.js | 20 --------------- 6 files changed, 51 insertions(+), 42 deletions(-) create mode 100644 src/diagrams/common/common.js diff --git a/src/diagrams/class/classDb.js b/src/diagrams/class/classDb.js index dcb62164c..9bf00913a 100644 --- a/src/diagrams/class/classDb.js +++ b/src/diagrams/class/classDb.js @@ -1,6 +1,7 @@ import * as d3 from 'd3'; import { logger } from '../../logger'; import { getConfig } from '../../config'; +import common from '../common/common'; import utils from '../../utils'; const MERMAID_DOM_ID_PREFIX = 'classid-'; @@ -175,7 +176,7 @@ export const setLink = function(ids, linkStr, tooltip) { classes[id].link = utils.formatUrl(linkStr, config); if (tooltip) { - classes[id].tooltip = utils.sanitize(tooltip, config); + classes[id].tooltip = common.sanitizeText(tooltip, config); } } }); @@ -207,7 +208,7 @@ const setClickFunc = function(domId, functionName, tooltip) { } if (typeof classes[id] !== 'undefined') { if (tooltip) { - classes[id].tooltip = utils.sanitize(tooltip, config); + classes[id].tooltip = common.sanitizeText(tooltip, config); } funs.push(function() { diff --git a/src/diagrams/common/common.js b/src/diagrams/common/common.js new file mode 100644 index 000000000..cc91948fc --- /dev/null +++ b/src/diagrams/common/common.js @@ -0,0 +1,39 @@ +export const getRows = s => { + if (!s) return 1; + let str = breakToPlaceholder(s); + str = str.replace(/\\n/g, '#br#'); + return str.split('#br#'); +}; + +export const sanitizeText = (text, config) => { + let txt = text; + let htmlLabels = true; + if ( + config.flowchart && + (config.flowchart.htmlLabels === false || config.flowchart.htmlLabels === 'false') + ) + htmlLabels = false; + + if (config.securityLevel !== 'loose' && htmlLabels) { + // eslint-disable-line + txt = breakToPlaceholder(txt); + txt = txt.replace(//g, '>'); + txt = txt.replace(/=/g, '='); + txt = placeholderToBreak(txt); + } + + return txt; +}; + +const breakToPlaceholder = s => { + return s.replace(//gi, '#br#'); +}; + +const placeholderToBreak = s => { + return s.replace(/#br#/g, '
'); +}; + +export default { + getRows, + sanitizeText +}; diff --git a/src/diagrams/flowchart/flowDb.js b/src/diagrams/flowchart/flowDb.js index 404fdfceb..4917a54a7 100644 --- a/src/diagrams/flowchart/flowDb.js +++ b/src/diagrams/flowchart/flowDb.js @@ -2,6 +2,7 @@ import * as d3 from 'd3'; import { logger } from '../../logger'; import utils from '../../utils'; import { getConfig } from '../../config'; +import common from '../common/common'; // const MERMAID_DOM_ID_PREFIX = 'mermaid-dom-id-'; const MERMAID_DOM_ID_PREFIX = ''; @@ -43,7 +44,7 @@ export const addVertex = function(_id, text, type, style, classes) { vertices[id] = { id: id, styles: [], classes: [] }; } if (typeof text !== 'undefined') { - txt = utils.sanitize(text.trim(), config); + txt = common.sanitizeText(text.trim(), config); // strip quotes if string starts and ends with a quote if (txt[0] === '"' && txt[txt.length - 1] === '"') { @@ -93,7 +94,7 @@ export const addSingleLink = function(_start, _end, type, linktext) { linktext = type.text; if (typeof linktext !== 'undefined') { - edge.text = utils.sanitize(linktext.trim(), config); + edge.text = common.sanitizeText(linktext.trim(), config); // strip quotes if string starts and exnds with a quote if (edge.text[0] === '"' && edge.text[edge.text.length - 1] === '"') { @@ -210,7 +211,7 @@ export const setClass = function(ids, className) { const setTooltip = function(ids, tooltip) { ids.split(',').forEach(function(id) { if (typeof tooltip !== 'undefined') { - tooltips[id] = utils.sanitize(tooltip, config); + tooltips[id] = common.sanitizeText(tooltip, config); } }); }; @@ -410,7 +411,7 @@ export const addSubGraph = function(_id, list, _title) { id = id || 'subGraph' + subCount; if (id[0].match(/\d/)) id = MERMAID_DOM_ID_PREFIX + id; title = title || ''; - title = utils.sanitize(title, config); + title = common.sanitizeText(title, config); subCount = subCount + 1; const subGraph = { id: id, nodes: nodeList, title: title.trim(), classes: [] }; subGraphs.push(subGraph); diff --git a/src/diagrams/state/shapes.js b/src/diagrams/state/shapes.js index d42228e41..dcd5cf21f 100644 --- a/src/diagrams/state/shapes.js +++ b/src/diagrams/state/shapes.js @@ -2,6 +2,7 @@ import * as d3 from 'd3'; import idCache from './id-cache.js'; import stateDb from './stateDb'; import utils from '../../utils'; +import common from '../common/common'; import { getConfig } from '../../config'; // let conf; @@ -391,12 +392,6 @@ export const drawState = function(elem, stateDef) { return stateInfo; }; -const getRows = s => { - let str = s.replace(//gi, '#br#'); - str = str.replace(/\\n/g, '#br#'); - return str.split('#br#'); -}; - let edgeCount = 0; export const drawEdge = function(elem, path, relation) { const getRelationType = function(type) { @@ -455,7 +450,7 @@ export const drawEdge = function(elem, path, relation) { const { x, y } = utils.calcLabelPosition(path.points); - const rows = getRows(relation.title); + const rows = common.getRows(relation.title); // console.warn(rows); diff --git a/src/diagrams/state/stateRenderer.js b/src/diagrams/state/stateRenderer.js index 396bb976d..e11fbba79 100644 --- a/src/diagrams/state/stateRenderer.js +++ b/src/diagrams/state/stateRenderer.js @@ -3,6 +3,7 @@ import dagre from 'dagre'; import graphlib from 'graphlib'; import { logger } from '../../logger'; import stateDb from './stateDb'; +import common from '../common/common'; import { parser } from './parser/stateDiagram'; // import idCache from './id-cache'; import { drawState, addTitleAndBox, drawEdge } from './shapes'; @@ -99,14 +100,6 @@ const getLabelWidth = text => { return text ? text.length * conf.fontSizeFactor : 1; }; -/* TODO: REMOVE DUPLICATION, SEE SHAPES */ -const getRows = s => { - if (!s) return 1; - let str = s.replace(//gi, '#br#'); - str = str.replace(/\\n/g, '#br#'); - return str.split('#br#'); -}; - const renderDoc = (doc, diagram, parentId, altBkg) => { // // Layout graph, Create a new directed graph const graph = new graphlib.Graph({ @@ -239,7 +232,7 @@ const renderDoc = (doc, diagram, parentId, altBkg) => { { relation: relation, width: getLabelWidth(relation.title), - height: conf.labelHeight * getRows(relation.title).length, + height: conf.labelHeight * common.getRows(relation.title).length, labelpos: 'c' }, 'id' + cnt diff --git a/src/utils.js b/src/utils.js index 002dcc8b7..1aec62d4f 100644 --- a/src/utils.js +++ b/src/utils.js @@ -74,25 +74,6 @@ export const interpolateToCurve = (interpolate, defaultCurve) => { return d3[curveName] || defaultCurve; }; -export const sanitize = (text, config) => { - let txt = text; - let htmlLabels = true; - if ( - config.flowchart && - (config.flowchart.htmlLabels === false || config.flowchart.htmlLabels === 'false') - ) - htmlLabels = false; - - if (config.securityLevel !== 'loose' && htmlLabels) { // eslint-disable-line - txt = txt.replace(//gi, '#br#'); - txt = txt.replace(//g, '>'); - txt = txt.replace(/=/g, '='); - txt = txt.replace(/#br#/g, '
'); - } - - return txt; -}; - export const formatUrl = (linkStr, config) => { let url = linkStr.trim(); @@ -225,7 +206,6 @@ export default { interpolateToCurve, calcLabelPosition, calcCardinalityPosition, - sanitize, formatUrl, getStylesFromArray }; From 6789f2c1e3ebef79cf20058625aa4c2f35b241f7 Mon Sep 17 00:00:00 2001 From: mvandermade <33425497+mvandermade@users.noreply.github.com> Date: Sun, 23 Feb 2020 10:47:51 +0100 Subject: [PATCH 2/9] Removed GitBook, add howto contribute docs. Also added the online submission step-by-step via github.com. --- docs/development.md | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/docs/development.md b/docs/development.md index af2805afd..1a26f91e8 100644 --- a/docs/development.md +++ b/docs/development.md @@ -3,9 +3,31 @@ ## Updating the documentation -We write documention with GitBook. +Please continue writing documentation at [mermaid-js/mermaid/docs](https://github.com/mermaid-js/mermaid/tree/develop/docs). -Please continue with the [mermaid-gitbook](https://github.com/mermaidjs/mermaid-gitbook) project. +We publish documentation using GitHub Pages. + + +### Questions and/or suggestions ? +After logging in at [GitHub.com](https://www.github.com), open or append to an issue [using the GitHub issue tracker of the mermaid-js repository](https://github.com/mermaid-js/mermaid/issues?q=is%3Aissue+is%3Aopen+label%3A%22Area%3A+Documentation%22). + +### How to contribute a suggestion +Markdown is used to format the text, for more information about Markdown [see the GitHub Markdown help page](https://help.github.com/en/github/writing-on-github/basic-writing-and-formatting-syntax). + +If you want to use an editor on your own computer, you may follow these steps: +* Find the Markdown file (.md) to edit in the [mermaid-js/mermaid/docs](https://github.com/mermaid-js/mermaid/tree/develop/docs) directory on the develop branch. +* Create a fork of the develop branch. +* Make changes or add new documentation. +* Commit changes to your fork and push it to GitHub. +* Create a pull request of your fork. + +If you don't have such editor on your computer, you may follow these steps: +* Login at [GitHub.com](https://www.github.com). +* Navigate to [mermaid-js/mermaid/docs](https://github.com/mermaid-js/mermaid/tree/develop/docs). +* To edit a file, click the pencil icon at the top-right of the file contents panel. +* Describe what you changed in the "Propose file change" section, located at the bottom of the page. +* Submit your changes by clicking the button "Propose file change" at the bottom (by automatic creation of a fork and a new branch). +* Create a pull request of your newly forked branch, by clicking the green "Create pull request" button. ## How to add a new diagram type From d67e49400f20ae4d7c2cb9c840c84bfecefe1344 Mon Sep 17 00:00:00 2001 From: Marc Faber Date: Mon, 24 Feb 2020 01:31:39 +0100 Subject: [PATCH 3/9] #684 Fix applying default class to flowchart nodes --- .../integration/rendering/flowchart.spec.js | 36 ++++++++++++++++++- dist/index.html | 11 ++++++ src/diagrams/flowchart/flowRenderer.js | 2 +- src/diagrams/flowchart/flowRenderer.spec.js | 34 ++++++++++++++++++ 4 files changed, 81 insertions(+), 2 deletions(-) diff --git a/cypress/integration/rendering/flowchart.spec.js b/cypress/integration/rendering/flowchart.spec.js index bc6c68f6e..c88129ddc 100644 --- a/cypress/integration/rendering/flowchart.spec.js +++ b/cypress/integration/rendering/flowchart.spec.js @@ -524,7 +524,8 @@ describe('Flowchart', () => { { flowchart: { htmlLabels: false } } ); }); -it('25: Handle link click events (link, anchor, mailto, other protocol, script)', () => { + + it('25: Handle link click events (link, anchor, mailto, other protocol, script)', () => { imgSnapshotTest( `graph TB TITLE["Link Click Events
(click the nodes below)"] @@ -583,6 +584,39 @@ it('25: Handle link click events (link, anchor, mailto, other protocol, script)' { flowchart: { htmlLabels: false } } ); }); + + it('28: Apply default class to all nodes which do not have another class assigned (htmlLabels enabled)', () => { + imgSnapshotTest( + `graph TD + A[myClass1] --> B[default] & C[default] + B[default] & C[default] --> D[myClass2] + classDef default stroke-width:2px,fill:none,stroke:silver + classDef node color:red + classDef myClass1 color:#0000ff + classDef myClass2 stroke:#0000ff,fill:#ccccff + class A myClass1 + class D myClass2 + `, + { flowchart: { htmlLabels: true } } + ); + }); + + it('29: Apply default class to all nodes which do not have another class assigned (htmlLabels disabled)', () => { + imgSnapshotTest( + `graph TD + A[myClass1] --> B[default] & C[default] + B[default] & C[default] --> D[myClass2] + classDef default stroke-width:2px,fill:none,stroke:silver + classDef node color:red + classDef myClass1 color:#0000ff + classDef myClass2 stroke:#0000ff,fill:#ccccff + class A myClass1 + class D myClass2 + `, + { flowchart: { htmlLabels: false } } + ); + }); + it('30: Possibility to style text color of nodes and subgraphs as well as apply classes to subgraphs', () => { imgSnapshotTest( `graph LR diff --git a/dist/index.html b/dist/index.html index e28890ce7..46af0d709 100644 --- a/dist/index.html +++ b/dist/index.html @@ -384,6 +384,17 @@ graph TB click B "index.html#link-clicked" "link test" click D testClick "click test" +
+ graph TD + A[myClass1] --> B[default] & C[default] + B[default] & C[default] --> D[myClass2] + classDef default stroke-width:2px,fill:none,stroke:silver + classDef node color:red + classDef myClass1 color:#0000ff + classDef myClass2 stroke:#0000ff,fill:#ccccff + class A myClass1 + class D myClass2 +

diff --git a/src/diagrams/flowchart/flowRenderer.js b/src/diagrams/flowchart/flowRenderer.js index 8b1a95046..e572f9188 100644 --- a/src/diagrams/flowchart/flowRenderer.js +++ b/src/diagrams/flowchart/flowRenderer.js @@ -36,7 +36,7 @@ export const addVertices = function(vert, g, svgId) { * Variable for storing the classes for the vertex * @type {string} */ - let classStr = ''; + let classStr = 'default'; if (vertex.classes.length > 0) { classStr = vertex.classes.join(' '); } diff --git a/src/diagrams/flowchart/flowRenderer.spec.js b/src/diagrams/flowchart/flowRenderer.spec.js index e3980ef1f..95419a5df 100644 --- a/src/diagrams/flowchart/flowRenderer.spec.js +++ b/src/diagrams/flowchart/flowRenderer.spec.js @@ -127,6 +127,40 @@ describe('the flowchart renderer', function() { expect(addedNodes[0][1]).toHaveProperty('labelStyle', expectedLabelStyle); }); }); + + it(`should add default class to all nodes which do not have another class assigned`, function() { + const addedNodes = []; + const mockG = { + setNode: function(id, object) { + addedNodes.push([id, object]); + } + }; + addVertices( + { + v1: { + type: 'rect', + id: 'defaultNode', + classes: [], + styles: [], + text: 'my vertex text' + }, + v2: { + type: 'rect', + id: 'myNode', + classes: ['myClass'], + styles: [], + text: 'my vertex text' + } + }, + mockG, + 'svg-id' + ); + expect(addedNodes).toHaveLength(2); + expect(addedNodes[0][0]).toEqual('defaultNode'); + expect(addedNodes[0][1]).toHaveProperty('class', 'default'); + expect(addedNodes[1][0]).toEqual('myNode'); + expect(addedNodes[1][1]).toHaveProperty('class', 'myClass'); + }); }); describe('when adding edges to a graph', function() { From a7a4f38d585693cc70e1b4524bf64e59c074a430 Mon Sep 17 00:00:00 2001 From: Marc Faber Date: Mon, 24 Feb 2020 01:43:21 +0100 Subject: [PATCH 4/9] Trigger tests again From 54f55cc02143386920e49ba1f5166bd931cf5799 Mon Sep 17 00:00:00 2001 From: gino Date: Mon, 24 Feb 2020 13:41:47 +0900 Subject: [PATCH 5/9] #425: Add documentation on using `par` for sequence diagrams Support for `par` was already added here: https://github.com/mermaid-js/mermaid/issues/425 But is not in the docs: https://mermaid-js.github.io/mermaid/#/sequenceDiagram --- docs/sequenceDiagram.md | 47 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/docs/sequenceDiagram.md b/docs/sequenceDiagram.md index bf95d078c..3ea0b3db1 100755 --- a/docs/sequenceDiagram.md +++ b/docs/sequenceDiagram.md @@ -235,6 +235,52 @@ sequenceDiagram end ``` +## Parallel + +It is possible to show actions that are happening in parallel. + +This is done by the notation + +``` +par [Action 1] +... statements ... +and [Action 2] +... statements ... +and [Action N] +... statements ... +end +``` + +See the example below: + +```mermaid +sequenceDiagram + par Alice to Bob + Alice->>Bob: Hello guys! + and Alice to John + Alice->>John: Hello guys! + end + Bob-->>Alice: Hi Alice! + John-->>Alice: Hi Alice! +``` + +It is also possible to nest parallel blocks. + +```mermaid +sequenceDiagram + par Alice to Bob + Alice->>Bob: Go help John + and Alice to John + Alice->>John: I want this done today + par John to Charlie + John->>Charlie: Can we do this today? + and John to Diana + John->>Diana: Can you help us today? + end + end +``` + + ## Background Highlighting It is possible to highlight flows by providing colored background rects. This is done by the notation @@ -452,4 +498,3 @@ Param | Description | Default value --- | --- | --- mirrorActor | Turns on/off the rendering of actors below the diagram as well as above it | false bottomMarginAdj | Adjusts how far down the graph ended. Wide borders styles with css could generate unwanted clipping which is why this config param exists. | 1 - From f8481f8d4cd4ac02dd54109e37488f9718211e3c Mon Sep 17 00:00:00 2001 From: gino Date: Mon, 24 Feb 2020 13:49:18 +0900 Subject: [PATCH 6/9] docs: Fix markdown lint MD012 and MD022 MD012 Multiple Consecutive Blanks https://github.com/DavidAnson/markdownlint/blob/master/doc/Rules.md#md012---multiple-consecutive-blank-lines MD022 Headings should be surrounded by blank lines https://github.com/DavidAnson/markdownlint/blob/master/doc/Rules.md#md022---headings-should-be-surrounded-by-blank-lines --- docs/sequenceDiagram.md | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/docs/sequenceDiagram.md b/docs/sequenceDiagram.md index 3ea0b3db1..9f9f3d9d1 100755 --- a/docs/sequenceDiagram.md +++ b/docs/sequenceDiagram.md @@ -77,7 +77,6 @@ Type | Description -x | Solid line with a cross at the end (async) --x | Dotted line with a cross at the end (async) - ## Activations It is possible to activate and deactivate an actor. (de)activation can be dedicated declarations: @@ -127,7 +126,6 @@ sequenceDiagram John-->>-Alice: I feel great! ``` - ## Notes It is possible to add notes to a sequence diagram. This is done by the notation @@ -159,7 +157,6 @@ sequenceDiagram Note over Alice,John: A typical interaction ``` - ## Loops It is possible to express loops in a sequence diagram. This is done by the notation @@ -187,7 +184,6 @@ sequenceDiagram end ``` - ## Alt It is possible to express alternative paths in a sequence diagram. This is done by the notation @@ -280,8 +276,8 @@ sequenceDiagram end ``` - ## Background Highlighting + It is possible to highlight flows by providing colored background rects. This is done by the notation The colors are defined using rgb and rgba syntax. @@ -386,10 +382,8 @@ loopLine | Defines styles for the lines in the loop box. note | Styles for the note box. noteText | Styles for the text on in the note boxes. - ### Sample stylesheet - ```css body { background: white; @@ -472,7 +466,6 @@ text.actor { } ``` - ## Configuration Is it possible to adjust the margins for rendering the sequence diagram. From b376e4da1fd8aa521331c4bdf1f9ba1ea77201c1 Mon Sep 17 00:00:00 2001 From: gino Date: Mon, 24 Feb 2020 13:51:15 +0900 Subject: [PATCH 7/9] docs: Fix typo "possiebl" --- docs/sequenceDiagram.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sequenceDiagram.md b/docs/sequenceDiagram.md index 9f9f3d9d1..bc8262ebe 100755 --- a/docs/sequenceDiagram.md +++ b/docs/sequenceDiagram.md @@ -326,7 +326,7 @@ sequenceDiagram ## sequenceNumbers -It is possiebl to get a sequence number attached to each arrow in a sequence diagram. This can be configured when adding mermaid to the website as shown below: +It is possible to get a sequence number attached to each arrow in a sequence diagram. This can be configured when adding mermaid to the website as shown below: ```