Merge branch 'release/8.10.2'

This commit is contained in:
Knut Sveidqvist 2021-06-06 08:43:03 +02:00
commit 5251dfaa97
42 changed files with 1096 additions and 641 deletions

View File

@ -53,5 +53,10 @@ describe('XSS', () => {
cy.wait(1000);
cy.get('#the-malware').should('not.exist');
})
it('should not allow maniplulating htmlLabels into a false positive', () => {
cy.visit('http://localhost:9000/xss4.html');
cy.wait(1000);
cy.get('#the-malware').should('not.exist');
})
})

View File

@ -371,25 +371,25 @@ flowchart TD
E[(red text)] -->|default style| F((blue text))
G>red text] -->|default style| H{blue text}
I{{red text}} -->|default style| J[/blue text/]
K[\ red text\] -->|default style| L[/blue text\]
M[\ red text/] -->|default style| N[blue text]
K[\\ red text\\] -->|default style| L[/blue text\\]
M[\\ red text/] -->|default style| N[blue text];
linkStyle default color:Sienna;
style A stroke:#ff0000,fill:#ffcccc,color:#ff0000
style B stroke:#0000ff,fill:#ccccff,color:#0000ff
style C stroke:#ff0000,fill:#ffcccc,color:#ff0000
style D stroke:#0000ff,fill:#ccccff,color:#0000ff
style E stroke:#ff0000,fill:#ffcccc,color:#ff0000
style F stroke:#0000ff,fill:#ccccff,color:#0000ff
style G stroke:#ff0000,fill:#ffcccc,color:#ff0000
style H stroke:#0000ff,fill:#ccccff,color:#0000ff
style I stroke:#ff0000,fill:#ffcccc,color:#ff0000
style J stroke:#0000ff,fill:#ccccff,color:#0000ff
style K stroke:#ff0000,fill:#ffcccc,color:#ff0000
style L stroke:#0000ff,fill:#ccccff,color:#0000ff
style M stroke:#ff0000,fill:#ffcccc,color:#ff0000
style N stroke:#0000ff,fill:#ccccff,color:#0000ff
style A stroke:#ff0000,fill:#ffcccc,color:#ff0000;
style B stroke:#0000ff,fill:#ccccff,color:#0000ff;
style C stroke:#ff0000,fill:#ffcccc,color:#ff0000;
style D stroke:#0000ff,fill:#ccccff,color:#0000ff;
style E stroke:#ff0000,fill:#ffcccc,color:#ff0000;
style F stroke:#0000ff,fill:#ccccff,color:#0000ff;
style G stroke:#ff0000,fill:#ffcccc,color:#ff0000;
style H stroke:#0000ff,fill:#ccccff,color:#0000ff;
style I stroke:#ff0000,fill:#ffcccc,color:#ff0000;
style J stroke:#0000ff,fill:#ccccff,color:#0000ff;
style K stroke:#ff0000,fill:#ffcccc,color:#ff0000;
style L stroke:#0000ff,fill:#ccccff,color:#0000ff;
style M stroke:#ff0000,fill:#ffcccc,color:#ff0000;
style N stroke:#0000ff,fill:#ccccff,color:#0000ff;
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose', logLevel:2}
);
});
it('61: fontawesome icons in edge labels', () => {
@ -610,4 +610,27 @@ flowchart RL
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
);
});
it('2050: handling of different rendering direction in subgraphs', () => {
imgSnapshotTest(
`
flowchart LR
subgraph TOP
direction TB
subgraph B1
direction RL
i1 -->f1
end
subgraph B2
direction BT
i2 -->f2
end
end
A --> TOP --> B
B1 --> B2
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
);
});
});

View File

@ -401,7 +401,7 @@ stateDiagram-v2
it('v2 should handle different rendering directions in composite states', () => {
imgSnapshotTest(
`
stateDiagram
stateDiagram-v2
direction LR
state A {
direction BT

View File

@ -0,0 +1,6 @@
const div = parent.document.createElement('div');
div.id = 'the-malware';
div.className = 'malware';
div.innerHTML = 'XSS Succeeded';
parent.document.getElementsByTagName('body')[0].appendChild(div);
throw new Error('XSS Succeded');

View File

@ -15,7 +15,7 @@
/* font-size: 18px !important; */
}
h1 { color: grey;}
.mermaid2 {
.mermaid2,.mermaid3 {
display: none;
}
.mermaid svg {
@ -27,14 +27,27 @@
<div>info below</div>
<div class="flex">
<div class="mermaid" style="width: 100%; height: 20%;">
<div class="mermaid3" style="width: 100%; height: 20%;">
stateDiagram-v2
state S1 {
sub1 -->sub2
}
state S2 {
sub4
}
S1 --> S2
sub1 --> sub4
</div>
<div class="mermaid3" style="width: 100%; height: 20%;">
stateDiagram
state CompositeState {
YourState123456789012345123456789123456789012345123456789123456789012345123456789123456789012345123456789 --> MyState:a label
}
</div>
<div class="mermaid" style="width: 100%; height: 20%;">
<div class="mermaid3" style="width: 100%; height: 20%;">
flowchart
subgraph CompositeState
subgraph AnotherCompositeStateCompositeStateCompositeStateCompositeState
@ -43,7 +56,7 @@ subgraph CompositeState
end
</div>
<div class="mermaid" style="width: 100%; height: 20%;">
<div class="mermaid3" style="width: 100%; height: 20%;">
stateDiagram-v2
state CompositeState {
state AnotherCompositeState1234567890 {
@ -52,14 +65,18 @@ stateDiagram-v2
}
</div>
<div class="mermaid2" style="width: 100%; height: 20%;">
sequenceDiagram
Alice->>+John: Hello John, how are you?
Alice->>+John: John, can you hear me?
John-->>-Alice: Hi Alice, I can hear you!
John-->>-Alice: I feel great!
note right of John: Hello note reader
</div>
<div class="mermaid" style="width: 100%; height: 20%;">
%%{init:{"theme":"forest", "themeVariables": {
"specialStateColor":"red",
"innerEndBackground":"lightgreen"
}}}%%
stateDiagram-v2
state fork [[fork]]
state join [[join]]
[*] --> fork
fork --> join
join --> [*]
</div>
<script src="./mermaid.js"></script>
<script>
mermaid.parseError = function (err, hash) {

View File

@ -21,155 +21,28 @@
.mermaid svg {
/* font-size: 18px !important; */
}
.malware {
position: fixed;
bottom:0;
left:0;
right:0;
height: 150px;
background: red;
color: black;
display: flex;
display: flex;
justify-content: center;
align-items: center;
font-family: monospace;
font-size: 72px;
}
</style>
</head>
<body>
<div>info below</div>
<div>Security check</div>
<div class="flex">
<div class="mermaid2" style="width: 100%; height: 400px;">
%%{init: { "logLevel": 1, "er": {"fontSize":18 }} }%%
erDiagram
CUSTOMER }|..|{ DELIVERY-ADDRESS : has
CUSTOMER ||--o{ ORDER : places
CUSTOMER ||--o{ INVOICE : "liable for"
DELIVERY-ADDRESS ||--o{ ORDER : receives
INVOICE ||--|{ ORDER : covers
ORDER ||--|{ ORDER-ITEM : includes
PRODUCT-CATEGORY ||--|{ PRODUCT : contains
PRODUCT ||--o{ ORDER-ITEM : "ordered in"
</div>
<div class="mermaid2" style="width: 50%; height: 400px;">
flowchart TD
A[Christmas] ==> D
A[Christmas] -->|Get money| B(Go shopping)
A[Christmas] ==> C
subgraph T ["Test"]
A
B
C
end
classDef Test fill:#F84E68,stroke:#333,color:white;
class A,T Test
classDef TestSub fill:green;
class T TestSub
linkStyle 0,1 color:orange, stroke: orange;
</div>
<div class="mermaid" style="width: 100%; height: 20%;">
graph TD
subgraph S1
sub1 -->sub2
end
subgraph S2
sub4
end
S1 --> S2
sub1 --> sub4
</div>
<div class="mermaid" style="width: 100%; height: 20%;">
graph TB
A --> B
</div>
<div class="mermaid2" style="width: 100%; height: 20%;">
stateDiagram-v2
state S1 {
sub1 -->sub2
}
state S2 {
sub4
}
S1 --> S2
sub1 --> sub4
</div>
<div class="mermaid2" style="width: 100%; height: 20%;">
requirementDiagram
requirement test_req {
id: 1
text: the test text.
risk: high
verifymethod: test
}
functionalRequirement test_req2 {
id: 1.1
text: the second test text.
risk: low
verifymethod: inspection
}
performanceRequirement test_req3 {
id: 1.2
text: the third test text.
risk: medium
verifymethod: demonstration
}
element test_entity {
type: simulation
}
element test_entity2 {
type: word doc
docRef: reqs/test_entity
}
test_entity - satisfies -> test_req2
test_req - traces -> test_req2
test_req - contains -> test_req3
test_req <- copies - test_entity2
</div>
<div class="mermaid2" style="width: 50%; height: 20%;">
flowchart LR
classDef dark fill:#000,stroke:#000,stroke-width:4px,color:#fff
Lorem --> Ipsum --> Dolor
class Lorem,Dolor dark
</div>
<div class="mermaid2" style="width: 50%; height: 20%;">
%%{init: {'theme': 'base' }}%%
%%{init2: { 'logLevel': 0, 'theme': 'forest'} }%%
flowchart TD
L1 --- L2
L2 --- C
M1 ---> C
R1 .-> R2
R2 <.-> C
C -->|Label 1| E1
C <-- Label 2 ---> E2
C ----> E3
C <-...-> E4
C ======> E5
</div>
<div class="mermaid2" style="width: 50%; height: 21%;">
flowchart LR
A[red text] -->|default style| B(blue text)
C([red text]) -->|default style| D[[blue text]]
E[(red text)] -->|default style| F((blue text))
G>red text] -->|default style| H{blue text}
I{{red text}} -->|default style| J[/blue text/]
K[
ed text] -->|default style| L[/blue text]
M[
ed text/] -->|default style| N[blue text]
linkStyle default color:Sienna;
style A stroke:#ff0000,fill:#ffcccc,color:#ff0000
style B stroke:#0000ff,fill:#ccccff,color:#0000ff
style C stroke:#ff0000,fill:#ffcccc,color:#ff0000
style D stroke:#0000ff,fill:#ccccff,color:#0000ff
style E stroke:#ff0000,fill:#ffcccc,color:#ff0000
style F stroke:#0000ff,fill:#ccccff,color:#0000ff
style G stroke:#ff0000,fill:#ffcccc,color:#ff0000
style H stroke:#0000ff,fill:#ccccff,color:#0000ff
style I stroke:#ff0000,fill:#ffcccc,color:#ff0000
style J stroke:#0000ff,fill:#ccccff,color:#0000ff
style K stroke:#ff0000,fill:#ffcccc,color:#ff0000
style L stroke:#0000ff,fill:#ccccff,color:#0000ff
style M stroke:#ff0000,fill:#ffcccc,color:#ff0000
style N stroke:#0000ff,fill:#ccccff,color:#0000ff
</div>
<div id="diagram" class="mermaid"></div>
<div id="res" class=""></div>
<script src="./mermaid.js"></script>
<script>
mermaid.parseError = function (err, hash) {
@ -187,7 +60,7 @@ style N stroke:#0000ff,fill:#ccccff,color:#0000ff
// defaultRenderer: 'dagre-wrapper',
nodeSpacing: 10, curve: 'cardinal', htmlLabels: true
},
htmlLabels: true,
htmlLabels: false,
// gantt: { axisFormat: '%m/%d/%Y' },
sequence: { actorFontFamily: 'courier',actorMargin: 50, showSequenceNumbers: false },
// sequenceDiagram: { actorMargin: 300 } // deprecated
@ -195,10 +68,26 @@ style N stroke:#0000ff,fill:#ccccff,color:#0000ff
// fontFamily: 'courier',
fontSize: 18,
curve: 'basis',
securityLevel: 'loose',
securityLevel: 'strict',
startOnLoad: false
// themeVariables: {relationLabelColor: 'red'}
});
function callback(){alert('It worked');}
var diagram = "%%{init: {\"flowchart\": {\"htmlLabels\": \"false\"}} }%%\n";
diagram += "flowchart\n";
diagram += "A[\"<ifra";
diagram += "me srcdoc='<scrip";
diagram += "t src=http://localhost:9000/exploit.js>";
diagram += "</scr"
diagram += "ipt>'></iframe>\"]";
console.log(diagram);
// document.querySelector('#diagram').innerHTML = diagram;
mermaid.render('diagram', diagram, (res) => {
document.querySelector('#res').innerHTML = res;
});
</script>
</body>
</html>

View File

@ -0,0 +1,94 @@
<html>
<head>
<link
href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
rel="stylesheet"
/>
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
<style>
body {
/* background: rgb(221, 208, 208); */
/* background:#333; */
font-family: 'Arial';
/* font-size: 18px !important; */
}
h1 { color: grey;}
.mermaid2 {
display: none;
}
.mermaid svg {
/* font-size: 18px !important; */
}
.malware {
position: fixed;
bottom:0;
left:0;
right:0;
height: 150px;
background: red;
color: black;
display: flex;
display: flex;
justify-content: center;
align-items: center;
font-family: monospace;
font-size: 72px;
}
</style>
</head>
<body>
<div>Security check</div>
<div class="flex">
<div id="diagram" class="mermaid"></div>
<div id="res" class=""></div>
<script src="./mermaid.js"></script>
<script>
mermaid.parseError = function (err, hash) {
// console.error('Mermaid error: ', err);
};
mermaid.initialize({
theme: 'forest',
arrowMarkerAbsolute: true,
// themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
logLevel: 0,
state: {
defaultRenderer: 'dagre-wrapper',
},
flowchart: {
// defaultRenderer: 'dagre-wrapper',
nodeSpacing: 10, curve: 'cardinal', htmlLabels: true
},
htmlLabels: false,
// gantt: { axisFormat: '%m/%d/%Y' },
sequence: { actorFontFamily: 'courier',actorMargin: 50, showSequenceNumbers: false },
// sequenceDiagram: { actorMargin: 300 } // deprecated
// fontFamily: '"times", sans-serif',
// fontFamily: 'courier',
fontSize: 18,
curve: 'basis',
securityLevel: 'strict',
startOnLoad: false,
secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize']
// themeVariables: {relationLabelColor: 'red'}
});
function callback(){alert('It worked');}
var diagram = "%%{init: {\"flowchart\": {\"htmlLabels\": \"true\"}} }%%\n";
diagram += "flowchart\n";
diagram += "A[\"<ifra";
diagram += "me srcdoc='<scrip";
diagram += "t src=http://localhost:9000/exploit.js>";
diagram += "</scr"
diagram += "ipt>'></iframe>\"]";
console.log(diagram);
// document.querySelector('#diagram').innerHTML = diagram;
mermaid.render('diagram', diagram, (res) => {
document.querySelector('#res').innerHTML = res;
});
</script>
</body>
</html>

478
dist/mermaid.core.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

478
dist/mermaid.js vendored

File diff suppressed because one or more lines are too long

2
dist/mermaid.js.map vendored

File diff suppressed because one or more lines are too long

8
dist/mermaid.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -2,12 +2,12 @@
**Edit this Page** [![N|Solid](img/GitHub-Mark-32px.png)](https://github.com/mermaid-js/mermaid/blob/develop/docs/flowchart.md)
All Flowcharts are composed of **nodes**, the geometric shapes and **edges**, the arrows or lines. The mermaid code defines the way that these **nodes** and **edges** are made and interact.
All Flowcharts are composed of **nodes**, the geometric shapes and **edges**, the arrows or lines. The mermaid code defines the way that these **nodes** and **edges** are made and interact.
It can also accomodate different arrow types, multi directional arrows, and linking to and from subgraphs.
> **Important note**: Do not type the word "end" as a Flowchart node. Capitalize all or any one the letters to keep the flowchart from breaking, i.e, "End" or "END". Or you can apply this [workaround](https://github.com/mermaid-js/mermaid/issues/1444#issuecomment-639528897).**
Node
Node
### A node (default)
```
@ -585,6 +585,45 @@ flowchart TB
two --> c2
```
## Direction in subgraphs
With the graphtype flowcharts you can use the direction state4ment to set the direction which the subgraph will render like in this example.
```
flowchart LR
subgraph TOP
direction TB
subgraph B1
direction RL
i1 -->f1
end
subgraph B2
direction BT
i2 -->f2
end
end
A --> TOP --> B
B1 --> B2
```
```mermaid
flowchart LR
subgraph TOP
direction TB
subgraph B1
direction RL
i1 -->f1
end
subgraph B2
direction BT
i2 -->f2
end
end
A --> TOP --> B
B1 --> B2
```
## Interaction
It is possible to bind a click event to a node, the click can lead to either a javascript callback or to a link which will be opened in a new browser tab. **Note**: This functionality is disabled when using `securityLevel='strict'` and enabled when using `securityLevel='loose'`.

View File

@ -112,6 +112,8 @@ They also serve as proof of concept, for the variety of things that can be built
- [iodide-mermaid-plugin](https://github.com/iodide-project/iodide-mermaid-plugin)
- [Google docs](https://docs.google.com/)
- [Mermaid plugin for google docs](https://workspace.google.com/marketplace/app/mermaid/636321283856)
- [Podlite](https://github.com/zag/podlite-desktop)
- [Named block =Diagram](https://github.com/zag/podlite/tree/main/packages/podlite-diagrams)
## Document Generation

View File

@ -2,27 +2,27 @@
**Explaining with a Diagram**
A picture is worth a thousand words, a good diagram is certainly worth more.
A picture is worth a thousand words, a good diagram is undoubtedly worth more. They make understanding easier.
## Creating and Maintaining Diagrams
Anyone who has used Visio, or (God Forbid) Excel to make a Gantt Chart, knows how hard it is to make, edit and maintain good visualizations.
Anyone who has used Visio, or (God Forbid) Excel to make a Gantt Chart, knows how hard it is to create, edit and maintain good visualizations.
Diagrams/Charts are both very important but also become obsolete/inaccurate very fast. This catch-22 hobbles the productivity of teams.
Diagrams/Charts are significant but also become obsolete/inaccurate very fast. This catch-22 hobbles the productivity of teams.
# Doc Rot in Diagrams
Doc-Rot kills diagrams as quickly as it does text, but it takes hours in a desktop application to produce a diagram.
mermaid seeks to change that. mermaid creates diagrams using markdown inspired syntax. The process is quicker, less complicated and more convenient way of going from concept to visualization
Mermaid seeks to change using markdown-inspired syntax. The process is a quicker, less complicated, and more convenient way of going from concept to visualization.
This is a relatively straightforward solution to a major hurdle in software teams.
It is a relatively straightforward solution to a significant hurdle with the software teams.
# Definition of Terms/ Dictionary
**Mermaid text definitions can be saved for later reuse and editing.**
>These are the Mermaid diagram deffinitions inside `<div>` tags, with the `class=mermaid`.
>These are the Mermaid diagram definitions inside `<div>` tags, with the `class=mermaid`.
```html
<div class="mermaid">
@ -35,33 +35,33 @@ This is a relatively straightforward solution to a major hurdle in software team
**render**
>This is the core function of the Mermaid API, it reads all the `Mermaid Definitions` inside `div` tags and returns an SVG file, based on the definitions.
>This is the core function of the Mermaid API. It reads all the `Mermaid Definitions` inside `div` tags and returns an SVG file, based on the definition.
**Nodes**
>These are the boxes that contain text or otherwise discrete pieces of each diagram, separated generally by arrows, except for Gantt Charts and User Journey Diagrams. They will be referred to often in the instructions. Read for Diagram Specific [Syntax](./n00b-syntaxReference)
>These are the boxes that contain text or otherwise discrete pieces of each diagram, separated generally by arrows, except for Gantt Charts and User Journey Diagrams. They will be referred often in the instructions. Read for Diagram Specific [Syntax](./n00b-syntaxReference)
## Advantages of Using Mermaid
## Advantages of using Mermaid
- Ease of generate, modify and render diagrams, when you make
- Ease to generate, modify and render diagrams when you make them.
- The number of integrations and plugins it has.
- It can be added to your or your company's website.
- You can add it to your or companies website.
- Diagrams can be created through comments like this in a script:
## The catch-22 of Diagrams and Charts:
**Diagramming and charting is a gigantic waste of developer time, but not having diagrams ruins productivity.**
**Diagramming and charting is a large waste of developer's time, but not having diagrams ruins productivity.**
mermaid solves this by cutting the time, effort and tooling that is required to create diagrams and charts.
Mermaid solves this by reducing the timeand effort required to create diagrams and charts.
Because, the text base for diagrams allows for it to be updated easily, it can also be made part of production scripts (and other pieces of code). So less time needs be spent on documenting, as a separate task.
Because, the text base for the diagrams allows it to be updated easily. Also, it can be made part of production scripts (and other pieces of code). So less time is spent on documenting, as a separate task.
## Catching up with Development
Being based on markdown, mermaid can be used, not only by accomplished front-end developers, but by most computer savvy people to render diagrams, at much faster speeds.
In fact one can pick up the syntax for it quite easily from the examples given and there are many tutorials in the internet.
Being based on markdown, Mermaid can be used, not only by accomplished front-end developers, but by most computer savvy people to render diagrams, at much faster speeds.
In fact one can pick up the syntax for it quite easily from the examples given and there are many tutorials available in the internet.
## Mermaid is for everyone.
Video [Tutorials](https://mermaid-js.github.io/mermaid/#/./Tutorials) are also available for the mermaid [live editor](https://mermaid-js.github.io/mermaid-live-editor/).

View File

@ -228,6 +228,28 @@ stateDiagram-v2
*You can not define transitions between internal states belonging to different composite states*
## Choice
Sometimes you need to model a choice between two or more paths, you can do so using &lt;&lt;choice&gt;&gt;.
```
stateDiagram-v2
state if_state <<choice>>
[*] --> IsPositive
IsPositive --> if_state
if_state --> False: if n < 0
if_state --> True : if n >= 0
```
```mermaid
stateDiagram-v2
state if_state <<choice>>
[*] --> IsPositive
IsPositive --> if_state
if_state --> False: if n < 0
if_state --> True : if n >= 0
```
## Forks
It is possible to specify a fork in the diagram using &lt;&lt;fork&gt;&gt; &lt;&lt;join&gt;&gt;.

View File

@ -1,6 +1,6 @@
{
"name": "mermaid",
"version": "8.10.1",
"version": "8.10.2",
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
"main": "dist/mermaid.core.js",
"keywords": [

View File

@ -3,6 +3,7 @@ import { log } from '../logger';
import createLabel from './createLabel';
import { select } from 'd3';
import { getConfig } from '../config';
import { evaluate } from '../diagrams/common/common';
const rect = (parent, node) => {
log.trace('Creating subgraph rect for ', node.id, node);
@ -26,7 +27,7 @@ const rect = (parent, node) => {
// Get the size of the label
let bbox = text.getBBox();
if (getConfig().flowchart.htmlLabels) {
if (evaluate(getConfig().flowchart.htmlLabels)) {
const div = text.children[0];
const dv = select(text);
bbox = div.getBoundingClientRect();
@ -37,15 +38,22 @@ const rect = (parent, node) => {
const padding = 0 * node.padding;
const halfPadding = padding / 2;
const width = node.width <= bbox.width + padding ? bbox.width + padding : node.width;
if (node.width <= bbox.width + padding) {
node.diff = (bbox.width - node.width) / 2;
} else {
node.diff = -node.padding / 2;
}
log.trace('Data ', node, JSON.stringify(node));
// center the rect around its coordinate
rect
.attr('style', node.style)
.attr('rx', node.rx)
.attr('ry', node.ry)
.attr('x', node.x - node.width / 2 - halfPadding)
.attr('x', node.x - width / 2)
.attr('y', node.y - node.height / 2 - halfPadding)
.attr('width', node.width + padding)
.attr('width', width)
.attr('height', node.height + padding);
// Center the label
@ -125,7 +133,7 @@ const roundedWithTitle = (parent, node) => {
// Get the size of the label
let bbox = text.getBBox();
if (getConfig().flowchart.htmlLabels) {
if (evaluate(getConfig().flowchart.htmlLabels)) {
const div = text.children[0];
const dv = select(text);
bbox = div.getBoundingClientRect();
@ -136,10 +144,11 @@ const roundedWithTitle = (parent, node) => {
const padding = 0 * node.padding;
const halfPadding = padding / 2;
const width =
node.width > bbox.width + node.padding ? node.width + node.padding : bbox.width + node.padding;
const width = node.width <= bbox.width + node.padding ? bbox.width + node.padding : node.width;
if (node.width <= bbox.width + node.padding) {
node.diff = (bbox.width - node.width) / 2;
node.diff = (bbox.width + node.padding - node.width) / 2;
} else {
node.diff = -node.padding / 2;
}
// center the rect around its coordinate
@ -162,7 +171,10 @@ const roundedWithTitle = (parent, node) => {
'translate(' +
(node.x - bbox.width / 2) +
', ' +
(node.y - node.height / 2 - node.padding / 3 + (getConfig().flowchart.htmlLabels ? 5 : 3)) +
(node.y -
node.height / 2 -
node.padding / 3 +
(evaluate(getConfig().flowchart.htmlLabels) ? 5 : 3)) +
')'
);

View File

@ -1,7 +1,8 @@
import { select } from 'd3';
import { log } from '../logger'; // eslint-disable-line
import { evaluate } from '../diagrams/common/common';
// let vertexNode;
// if (getConfig().flowchart.htmlLabels) {
// if (evaluate(getConfig().flowchart.htmlLabels)) {
// // TODO: addHtmlLabel accepts a labelStyle. Do we possibly have that?
// const node = {
// label: vertexText.replace(/fa[lrsb]?:fa-[\w-]+/g, s => `<i class='${s.replace(':', ' ')}'></i>`)
@ -86,7 +87,7 @@ function addHtmlLabel(node) {
const createLabel = (_vertexText, style, isTitle, isNode) => {
let vertexText = _vertexText || '';
if (typeof vertexText === 'object') vertexText = vertexText[0];
if (getConfig().flowchart.htmlLabels) {
if (evaluate(getConfig().flowchart.htmlLabels)) {
// TODO: addHtmlLabel accepts a labelStyle. Do we possibly have that?
vertexText = vertexText.replace(/\\n|\n/g, '<br />');
log.info('vertexText' + vertexText);

View File

@ -4,7 +4,7 @@ import createLabel from './createLabel';
import { line, curveBasis, select } from 'd3';
import { getConfig } from '../config';
import utils from '../utils';
// import { calcLabelPosition } from '../utils';
import { evaluate } from '../diagrams/common/common';
let edgeLabels = {};
let terminalLabels = {};
@ -27,7 +27,7 @@ export const insertEdgeLabel = (elem, edge) => {
// Center the label
let bbox = labelElement.getBBox();
if (getConfig().flowchart.htmlLabels) {
if (evaluate(getConfig().flowchart.htmlLabels)) {
const div = labelElement.children[0];
const dv = select(labelElement);
bbox = div.getBoundingClientRect();

View File

@ -55,7 +55,7 @@ const recursiveRender = (_elem, graph, diagramtype, parentCluster) => {
const newEl = o.elem;
updateNodeBounds(node, newEl);
node.diff = o.diff || 0;
log.info('Node nounds ', v, node, node.width, node.x, node.y);
log.info('Node bounds (abc123)', v, node, node.width, node.x, node.y);
setNodeElem(newEl, node);
log.warn('Recursive render complete ', newEl, node);

View File

@ -6,6 +6,7 @@ import intersect from './intersect/index.js';
import createLabel from './createLabel';
import note from './shapes/note';
import { parseMember } from '../diagrams/class/svgDraw';
import { evaluate } from '../diagrams/common/common';
const question = (parent, node) => {
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
@ -370,7 +371,7 @@ const rectWithTitle = (parent, node) => {
const text = label.node().appendChild(createLabel(title, node.labelStyle, true, true));
let bbox;
if (getConfig().flowchart.htmlLabels) {
if (evaluate(getConfig().flowchart.htmlLabels)) {
const div = text.children[0];
const dv = select(text);
bbox = div.getBoundingClientRect();
@ -386,7 +387,7 @@ const rectWithTitle = (parent, node) => {
createLabel(textRows.join ? textRows.join('<br/>') : textRows, node.labelStyle, true, true)
);
if (getConfig().flowchart.htmlLabels) {
if (evaluate(getConfig().flowchart.htmlLabels)) {
const div = descr.children[0];
const dv = select(descr);
bbox = div.getBoundingClientRect();
@ -567,8 +568,6 @@ const forkJoin = (parent, node, dir) => {
const shape = shapeSvg
.append('rect')
.style('stroke', 'black')
.style('fill', 'black')
.attr('x', (-1 * width) / 2)
.attr('y', (-1 * height) / 2)
.attr('width', width)
@ -650,7 +649,7 @@ const class_box = (parent, node) => {
.node()
.appendChild(createLabel(interfaceLabelText, node.labelStyle, true, true));
let interfaceBBox = interfaceLabel.getBBox();
if (getConfig().flowchart.htmlLabels) {
if (evaluate(getConfig().flowchart.htmlLabels)) {
const div = interfaceLabel.children[0];
const dv = select(interfaceLabel);
interfaceBBox = div.getBoundingClientRect();
@ -672,7 +671,7 @@ const class_box = (parent, node) => {
.appendChild(createLabel(classTitleString, node.labelStyle, true, true));
select(classTitleLabel).attr('class', 'classTitle');
let classTitleBBox = classTitleLabel.getBBox();
if (getConfig().flowchart.htmlLabels) {
if (evaluate(getConfig().flowchart.htmlLabels)) {
const div = classTitleLabel.children[0];
const dv = select(classTitleLabel);
classTitleBBox = div.getBoundingClientRect();
@ -690,7 +689,7 @@ const class_box = (parent, node) => {
.node()
.appendChild(createLabel(parsedText, node.labelStyle, true, true));
let bbox = lbl.getBBox();
if (getConfig().flowchart.htmlLabels) {
if (evaluate(getConfig().flowchart.htmlLabels)) {
const div = lbl.children[0];
const dv = select(lbl);
bbox = div.getBoundingClientRect();
@ -713,7 +712,7 @@ const class_box = (parent, node) => {
.node()
.appendChild(createLabel(parsedText, node.labelStyle, true, true));
let bbox = lbl.getBBox();
if (getConfig().flowchart.htmlLabels) {
if (evaluate(getConfig().flowchart.htmlLabels)) {
const div = lbl.children[0];
const dv = select(lbl);
bbox = div.getBoundingClientRect();
@ -793,7 +792,7 @@ const class_box = (parent, node) => {
});
//
// let bbox;
// if (getConfig().flowchart.htmlLabels) {
// if (evaluate(getConfig().flowchart.htmlLabels)) {
// const div = interfaceLabel.children[0];
// const dv = select(interfaceLabel);
// bbox = div.getBoundingClientRect();
@ -809,7 +808,7 @@ const class_box = (parent, node) => {
// .node()
// .appendChild(createLabel(textRows.join('<br/>'), node.labelStyle, true, true));
// if (getConfig().flowchart.htmlLabels) {
// if (evaluate(getConfig().flowchart.htmlLabels)) {
// const div = descr.children[0];
// const dv = select(descr);
// bbox = div.getBoundingClientRect();

View File

@ -1,6 +1,7 @@
import createLabel from '../createLabel';
import { getConfig } from '../../config';
import { select } from 'd3';
import { evaluate } from '../../diagrams/common/common';
export const labelHelper = (parent, node, _classes, isNode) => {
let classes;
if (!_classes) {
@ -27,7 +28,7 @@ export const labelHelper = (parent, node, _classes, isNode) => {
// Get the size of the label
let bbox = text.getBBox();
if (getConfig().flowchart.htmlLabels) {
if (evaluate(getConfig().flowchart.htmlLabels)) {
const div = text.children[0];
const dv = select(text);
bbox = div.getBoundingClientRect();

View File

@ -57,7 +57,7 @@ export const addClasses = function(classes, g) {
// We create a SVG label, either by delegating to addHtmlLabel or manually
// let vertexNode;
// if (getConfig().flowchart.htmlLabels) {
// if (evaluate(getConfig().flowchart.htmlLabels)) {
// const node = {
// label: vertexText.replace(
// /fa[lrsb]?:fa-[\w-]+/g,

View File

@ -90,6 +90,8 @@ const getUrl = useAbsolute => {
return url;
};
export const evaluate = val => (val === 'false' || val === false ? false : true);
export default {
getRows,
sanitizeText,
@ -97,5 +99,6 @@ export default {
splitBreaks,
lineBreakRegex,
removeScript,
getUrl
getUrl,
evaluate
};

View File

@ -50,7 +50,7 @@ export const lookUpDomId = function(id) {
* @param style
* @param classes
*/
export const addVertex = function(_id, text, type, style, classes) {
export const addVertex = function(_id, text, type, style, classes, dir) {
let txt;
let id = _id;
if (typeof id === 'undefined') {
@ -103,6 +103,9 @@ export const addVertex = function(_id, text, type, style, classes) {
});
}
}
if (typeof dir !== 'undefined') {
vertices[id].dir = dir;
}
};
/**
@ -431,6 +434,7 @@ export const defaultStyle = function() {
* Clears the internal graph db so that a new graph can be parsed.
*/
export const addSubGraph = function(_id, list, _title) {
// console.log('addSubGraph', _id, list, _title);
let id = _id.trim();
let title = _title;
if (_id === _title && _title.match(/\s/)) {
@ -440,8 +444,13 @@ export const addSubGraph = function(_id, list, _title) {
const prims = { boolean: {}, number: {}, string: {} };
const objs = [];
return a.filter(function(item) {
let dir; // = unbdefined; direction.trim();
const nodeList = a.filter(function(item) {
const type = typeof item;
if (item.stmt && item.stmt === 'dir') {
dir = item.value;
return false;
}
if (item.trim() === '') {
return false;
}
@ -451,11 +460,13 @@ export const addSubGraph = function(_id, list, _title) {
return objs.indexOf(item) >= 0 ? false : objs.push(item);
}
});
return { nodeList, dir };
}
let nodeList = [];
nodeList = uniq(nodeList.concat.apply(nodeList, list));
const { nodeList: nl, dir } = uniq(nodeList.concat.apply(nodeList, list));
nodeList = nl;
if (version === 'gen-1') {
log.warn('LOOKING UP');
for (let i = 0; i < nodeList.length; i++) {
@ -468,9 +479,9 @@ export const addSubGraph = function(_id, list, _title) {
title = title || '';
title = common.sanitizeText(title, config);
subCount = subCount + 1;
const subGraph = { id: id, nodes: nodeList, title: title.trim(), classes: [] };
const subGraph = { id: id, nodes: nodeList, title: title.trim(), classes: [], dir };
log.info('Adding', subGraph.id, subGraph.nodes);
log.info('Adding', subGraph.id, subGraph.nodes, subGraph.dir);
/**
* Deletes an id from all subgraphs

View File

@ -8,7 +8,7 @@ import { getConfig } from '../../config';
import { render } from '../../dagre-wrapper/index.js';
import addHtmlLabel from 'dagre-d3/lib/label/add-html-label.js';
import { log } from '../../logger';
import common from '../common/common';
import common, { evaluate } from '../common/common';
import { interpolateToCurve, getStylesFromArray, configureSvgSize } from '../../utils';
const conf = {};
@ -48,7 +48,7 @@ export const addVertices = function(vert, g, svgId) {
// We create a SVG label, either by delegating to addHtmlLabel or manually
let vertexNode;
if (getConfig().flowchart.htmlLabels) {
if (evaluate(getConfig().flowchart.htmlLabels)) {
// TODO: addHtmlLabel accepts a labelStyle. Do we possibly have that?
const node = {
label: vertexText.replace(
@ -147,6 +147,7 @@ export const addVertices = function(vert, g, svgId) {
domId: flowDb.lookUpDomId(vertex.id),
haveCallback: vertex.haveCallback,
width: vertex.type === 'group' ? 500 : undefined,
dir: vertex.dir,
type: vertex.type,
padding: getConfig().flowchart.padding
});
@ -163,6 +164,7 @@ export const addVertices = function(vert, g, svgId) {
domId: flowDb.lookUpDomId(vertex.id),
width: vertex.type === 'group' ? 500 : undefined,
type: vertex.type,
dir: vertex.dir,
padding: getConfig().flowchart.padding
});
});
@ -290,7 +292,7 @@ export const addEdges = function(edges, g) {
edgeData.arrowheadStyle = 'fill: #333';
edgeData.labelpos = 'c';
}
// if (getConfig().flowchart.htmlLabels && false) {
// if (evaluate(getConfig().flowchart.htmlLabels) && false) {
// // eslint-disable-line
// edgeData.labelType = 'html';
// edgeData.label = `<span id="L-${linkId}" class="edgeLabel L-${linkNameStart}' L-${linkNameEnd}">${edge.text}</span>`;
@ -385,7 +387,7 @@ export const draw = function(text, id) {
for (let i = subGraphs.length - 1; i >= 0; i--) {
subG = subGraphs[i];
log.info('Subgraph - ', subG);
flowDb.addVertex(subG.id, subG.title, 'group', undefined, subG.classes);
flowDb.addVertex(subG.id, subG.title, 'group', undefined, subG.classes, subG.dir);
}
// Fetch the verices/nodes and edges/links from the parsed graph definition

View File

@ -8,7 +8,7 @@ import { getConfig } from '../../config';
import dagreD3 from 'dagre-d3';
import addHtmlLabel from 'dagre-d3/lib/label/add-html-label.js';
import { log } from '../../logger';
import common from '../common/common';
import common, { evaluate } from '../common/common';
import { interpolateToCurve, getStylesFromArray, configureSvgSize } from '../../utils';
import flowChartShapes from './flowChartShapes';
@ -49,7 +49,7 @@ export const addVertices = function(vert, g, svgId) {
// We create a SVG label, either by delegating to addHtmlLabel or manually
let vertexNode;
if (getConfig().flowchart.htmlLabels) {
if (evaluate(getConfig().flowchart.htmlLabels)) {
// TODO: addHtmlLabel accepts a labelStyle. Do we possibly have that?
const node = {
label: vertexText.replace(
@ -228,7 +228,7 @@ export const addEdges = function(edges, g) {
edgeData.arrowheadStyle = 'fill: #333';
edgeData.labelpos = 'c';
if (getConfig().flowchart.htmlLabels) {
if (evaluate(getConfig().flowchart.htmlLabels)) {
edgeData.labelType = 'html';
edgeData.label = `<span id="L-${linkId}" class="edgeLabel L-${linkNameStart}' L-${linkNameEnd}">${edge.text.replace(
/fa[lrsb]?:fa-[\w-]+/g,
@ -451,7 +451,7 @@ export const draw = function(text, id) {
}
// Add label rects for non html labels
if (!conf.htmlLabels || true) { // eslint-disable-line
if (!evaluate(conf.htmlLabels) || true) { // eslint-disable-line
const labels = document.querySelectorAll('[id="' + id + '"] .edgeLabel .label');
for (let k = 0; k < labels.length; k++) {
const label = labels[k];

View File

@ -0,0 +1,95 @@
import flowDb from '../flowDb';
import flow from './flow';
import filter from 'lodash/filter';
import { setConfig } from '../../../config';
setConfig({
securityLevel: 'strict'
});
describe('when parsing directions', function() {
beforeEach(function() {
flow.parser.yy = flowDb;
flow.parser.yy.clear();
flow.parser.yy.setGen('gen-2');
});
it('should use default direction from top level', function() {
const res = flow.parser.parse(`flowchart TB
subgraph A
a --> b
end`);
const subgraphs = flow.parser.yy.getSubGraphs();
expect(subgraphs.length).toBe(1);
const subgraph = subgraphs[0];
expect(subgraph.nodes.length).toBe(2);
expect(subgraph.nodes[0]).toBe('b');
expect(subgraph.nodes[1]).toBe('a');
expect(subgraph.id).toBe('A');
expect(subgraph.dir).toBe(undefined);
});
it('should handle a subgraph with a direction', function() {
const res = flow.parser.parse(`flowchart TB
subgraph A
direction BT
a --> b
end`);
const subgraphs = flow.parser.yy.getSubGraphs();
expect(subgraphs.length).toBe(1);
const subgraph = subgraphs[0];
expect(subgraph.nodes.length).toBe(2);
expect(subgraph.nodes[0]).toBe('b');
expect(subgraph.nodes[1]).toBe('a');
expect(subgraph.id).toBe('A');
expect(subgraph.dir).toBe('BT');
});
it('should use the last defined direction', function() {
const res = flow.parser.parse(`flowchart TB
subgraph A
direction BT
a --> b
direction RL
end`);
const subgraphs = flow.parser.yy.getSubGraphs();
expect(subgraphs.length).toBe(1);
const subgraph = subgraphs[0];
expect(subgraph.nodes.length).toBe(2);
expect(subgraph.nodes[0]).toBe('b');
expect(subgraph.nodes[1]).toBe('a');
expect(subgraph.id).toBe('A');
expect(subgraph.dir).toBe('RL');
});
it('should handle nested subgraphs 1', function() {
const res = flow.parser.parse(`flowchart TB
subgraph A
direction RL
b-->B
a
end
a-->c
subgraph B
direction LR
c
end`);
const subgraphs = flow.parser.yy.getSubGraphs();
expect(subgraphs.length).toBe(2);
const subgraphA = filter(subgraphs,o => o.id === 'A')[0];
const subgraphB = filter(subgraphs,o => o.id === 'B')[0];
expect(subgraphB.nodes[0]).toBe('c');
expect(subgraphB.dir).toBe('LR');
expect(subgraphA.nodes).toContain('B');
expect(subgraphA.nodes).toContain('b');
expect(subgraphA.nodes).toContain('a');
expect(subgraphA.nodes).not.toContain('c');
expect(subgraphA.dir).toBe('RL');
});
});

View File

@ -92,6 +92,12 @@ that id.
<dir>\s*">" { this.popState(); return 'DIR'; }
<dir>\s*"^" { this.popState(); return 'DIR'; }
<dir>\s*"v" { this.popState(); return 'DIR'; }
.*direction\s+TB[^\n]* return 'direction_tb';
.*direction\s+BT[^\n]* return 'direction_bt';
.*direction\s+RL[^\n]* return 'direction_rl';
.*direction\s+LR[^\n]* return 'direction_lr';
[0-9]+ { return 'NUM';}
\# return 'BRKT';
":::" return 'STYLE_SEPARATOR';
@ -327,6 +333,7 @@ statement
// {$$=yy.addSubGraph($3,$5,$3);}
| subgraph separator document end
{$$=yy.addSubGraph(undefined,$3,undefined);}
| direction
;
separator: NEWLINE | SEMI | EOF ;
@ -537,6 +544,17 @@ alphaNumStatement
{$$='-';}
;
direction
: direction_tb
{ $$={stmt:'dir', value:'TB'};}
| direction_bt
{ $$={stmt:'dir', value:'BT'};}
| direction_rl
{ $$={stmt:'dir', value:'RL'};}
| direction_lr
{ $$={stmt:'dir', value:'LR'};}
;
alphaNumToken : PUNCTUATION | AMP | UNICODE_TEXT | NUM| ALPHA | COLON | COMMA | PLUS | EQUALS | MULT | DOT | BRKT| UNDERSCORE ;
idStringToken : ALPHA|UNDERSCORE |UNICODE_TEXT | NUM| COLON | COMMA | PLUS | MINUS | DOWN |EQUALS | MULT | BRKT | DOT | PUNCTUATION | AMP;

View File

@ -3,7 +3,7 @@ import { select } from 'd3';
import stateDb from './stateDb';
import state from './parser/stateDiagram';
import { getConfig } from '../../config';
// import { evaluate } from '../common/common';
import { render } from '../../dagre-wrapper/index.js';
import { log } from '../../logger';
import { configureSvgSize } from '../../utils';
@ -295,22 +295,22 @@ export const draw = function(text, id) {
svg.attr('viewBox', vBox);
// Add label rects for non html labels
if (!conf.htmlLabels) {
const labels = document.querySelectorAll('[id="' + id + '"] .edgeLabel .label');
for (let k = 0; k < labels.length; k++) {
const label = labels[k];
// if (!evaluate(conf.htmlLabels) || true) {
const labels = document.querySelectorAll('[id="' + id + '"] .edgeLabel .label');
for (let k = 0; k < labels.length; k++) {
const label = labels[k];
// Get dimensions of label
const dim = label.getBBox();
// Get dimensions of label
const dim = label.getBBox();
const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
rect.setAttribute('rx', 0);
rect.setAttribute('ry', 0);
rect.setAttribute('width', dim.width);
rect.setAttribute('height', dim.height);
const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
rect.setAttribute('rx', 0);
rect.setAttribute('ry', 0);
rect.setAttribute('width', dim.width);
rect.setAttribute('height', dim.height);
label.insertBefore(rect, label.firstChild);
}
label.insertBefore(rect, label.firstChild);
// }
}
};

View File

@ -82,11 +82,17 @@ g.stateGroup line {
}
.node circle.state-start {
fill: ${options.lineColor};
stroke: black;
fill: ${options.specialStateColor};
stroke: ${options.specialStateColor};
}
.node .fork-join {
fill: ${options.specialStateColor};
stroke: ${options.specialStateColor};
}
.node circle.state-end {
fill: ${options.primaryBorderColor};
fill: ${options.innerEndBackground};
stroke: ${options.background};
stroke-width: 1.5
}

View File

@ -137,7 +137,8 @@ const initialize = function(config) {
mermaid.startOnLoad = config.mermaid.startOnLoad;
}
if (typeof config.mermaid.htmlLabels !== 'undefined') {
mermaid.htmlLabels = config.mermaid.htmlLabels;
mermaid.htmlLabels =
config.mermaid.htmlLabels === 'false' || config.mermaid.htmlLabels === false ? false : true;
}
}
mermaidAPI.initialize(config);

View File

@ -297,8 +297,9 @@ const render = function(id, _txt, cb, container) {
// classDef
if (graphType === 'flowchart' || graphType === 'flowchart-v2' || graphType === 'graph') {
const classes = flowRenderer.getClasses(txt);
const htmlLabels = cnf.htmlLabels || cnf.flowchart.htmlLabels;
for (const className in classes) {
if (cnf.htmlLabels || cnf.flowchart.htmlLabels) {
if (htmlLabels) {
userStyles += `\n.${className} > * { ${classes[className].styles.join(
' !important; '
)} !important; }`;
@ -306,7 +307,6 @@ const render = function(id, _txt, cb, container) {
' !important; '
)} !important; }`;
} else {
// console.log('classes[className].styles', classes[className].styles, cnf.htmlLabels);
userStyles += `\n.${className} path { ${classes[className].styles.join(
' !important; '
)} !important; }`;

View File

@ -121,10 +121,11 @@ class Theme {
this.altBackground = this.altBackground || this.tertiaryColor;
this.compositeTitleBackground = this.compositeTitleBackground || this.mainBkg;
this.compositeBorder = this.compositeBorder || this.nodeBorder;
this.innerEndBackground = this.nodeBorder;
this.errorBkgColor = this.errorBkgColor || this.tertiaryColor;
this.errorTextColor = this.errorTextColor || this.tertiaryTextColor;
this.transitionColor = this.transitionColor || this.lineColor;
this.specialStateColor = this.lineColor;
/* class */
this.classText = this.classText || this.textColor;

View File

@ -136,6 +136,8 @@ class Theme {
this.altBackground = this.altBackground || '#555';
this.compositeTitleBackground = this.compositeTitleBackground || this.mainBkg;
this.compositeBorder = this.compositeBorder || this.nodeBorder;
this.innerEndBackground = this.primaryBorderColor;
this.specialStateColor = '#f4f4f4'; // this.lineColor;
this.errorBkgColor = this.errorBkgColor || this.tertiaryColor;
this.errorTextColor = this.errorTextColor || this.tertiaryTextColor;

View File

@ -149,6 +149,8 @@ class Theme {
this.altBackground = this.altBackground || '#f0f0f0';
this.compositeTitleBackground = this.compositeTitleBackground || this.mainBkg;
this.compositeBorder = this.compositeBorder || this.nodeBorder;
this.innerEndBackground = this.nodeBorder;
this.specialStateColor = this.lineColor;
this.errorBkgColor = this.errorBkgColor || this.tertiaryColor;
this.errorTextColor = this.errorTextColor || this.tertiaryTextColor;

View File

@ -119,6 +119,8 @@ class Theme {
this.altBackground = this.altBackground || '#f0f0f0';
this.compositeTitleBackground = this.compositeTitleBackground || this.mainBkg;
this.compositeBorder = this.compositeBorder || this.nodeBorder;
this.innerEndBackground = this.primaryBorderColor;
this.specialStateColor = this.lineColor;
this.errorBkgColor = this.errorBkgColor || this.tertiaryColor;
this.errorTextColor = this.errorTextColor || this.tertiaryTextColor;

View File

@ -156,6 +156,8 @@ class Theme {
this.altBackground = this.altBackground || '#f4f4f4';
this.compositeTitleBackground = this.compositeTitleBackground || this.mainBkg;
this.stateBorder = this.stateBorder || '#000';
this.innerEndBackground = this.primaryBorderColor;
this.specialStateColor = '#222';
this.errorBkgColor = this.errorBkgColor || this.tertiaryColor;
this.errorTextColor = this.errorTextColor || this.tertiaryTextColor;