Merge pull request #1585 from GDFaber/feature/1460_add_link_target_to_flowchart_click

Add link target option to flowchart click
This commit is contained in:
Knut Sveidqvist 2020-07-29 15:13:35 +02:00 committed by GitHub
commit d215d31349
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 85 additions and 29 deletions

View File

@ -529,17 +529,19 @@ describe('Flowchart', () => {
imgSnapshotTest(
`graph TB
TITLE["Link Click Events<br>(click the nodes below)"]
A[link test]
B[anchor test]
C[mailto test]
D[other protocol test]
E[script test]
TITLE --> A & B & C & D & E
click A "https://mermaid-js.github.io/mermaid/#/" "link test"
click B "#link-clicked" "anchor test"
click C "mailto:user@user.user" "mailto test"
click D "notes://do-your-thing/id" "other protocol test"
click E "javascript:alert('test')" "script test"
A["link test (open in same tab)"]
B["link test (open in new tab)"]
C[anchor test]
D[mailto test]
E[other protocol test]
F[script test]
TITLE --> A & B & C & D & E & F
click A "https://mermaid-js.github.io/mermaid/#/" "link test (open in same tab)"
click B "https://mermaid-js.github.io/mermaid/#/" "link test (open in new tab)" _blank
click C "#link-clicked"
click D "mailto:user@user.user" "mailto test"
click E "notes://do-your-thing/id" "other protocol test"
click F "javascript:alert('test')" "script test"
`,
{ securityLevel: 'loose' }
);

24
dist/index.html vendored
View File

@ -393,17 +393,19 @@ graph TB
<div class="mermaid">
graph TB
TITLE["Link Click Events<br>(click the nodes below)"]
A[link test]
B[anchor test]
C[mailto test]
D[other protocol test]
E[script test]
TITLE --> A & B & C & D & E
click A "https://mermaid-js.github.io/mermaid/#/" "link test"
click B "#link-clicked" "anchor test"
click C "mailto:user@user.user" "mailto test"
click D "notes://do-your-thing/id" "other protocol test"
click E "javascript:alert('test')" "script test"
A["link test (open in same tab)"]
B["link test (open in new tab)"]
C[anchor test]
D[mailto test]
E[other protocol test]
F[script test]
TITLE --> A & B & C & D & E & F
click A "https://mermaid-js.github.io/mermaid/#/" "link test (open in same tab)"
click B "https://mermaid-js.github.io/mermaid/#/" "link test (open in new tab)" _blank
click C "#link-clicked"
click D "mailto:user@user.user" "mailto test"
click E "notes://do-your-thing/id" "other protocol test"
click F "javascript:alert('test')" "script test"
</div>
<hr/>
<div class="mermaid">

View File

@ -562,6 +562,23 @@ graph LR
?> Due to limitations with how Docsify handles JavaScript callback functions, an alternate working demo for the above code can be viewed at [this jsfiddle](https://jsfiddle.net/s37cjoau/3/).
Links are opened in the same browser tab/window by default. It is possible to change this by adding a link target to the click definition (`_self`, `_blank`, `_parent` and `_top` are supported):
```
graph LR;
A-->B;
B-->C;
click A "http://www.github.com" _blank
click B "http://www.github.com" "Open this in a new tab" _blank
```
```mermaid
graph LR;
A-->B;
B-->C;
click A "http://www.github.com" _blank
click B "http://www.github.com" "Open this in a new tab" _blank
```
Beginners tip, a full example using interactive links in a html context:
```
<body>

View File

@ -252,12 +252,13 @@ const setClickFun = function(_id, functionName) {
* @param linkStr URL to create a link for
* @param tooltip Tooltip for the clickable element
*/
export const setLink = function(ids, linkStr, tooltip) {
export const setLink = function(ids, linkStr, tooltip, target) {
ids.split(',').forEach(function(_id) {
let id = _id;
if (_id[0].match(/\d/)) id = MERMAID_DOM_ID_PREFIX + id;
if (typeof vertices[id] !== 'undefined') {
vertices[id].link = utils.formatUrl(linkStr, config);
vertices[id].linkTarget = target;
}
});
setTooltip(ids, tooltip);

View File

@ -486,6 +486,9 @@ export const draw = function(text, id) {
link.setAttributeNS('http://www.w3.org/2000/svg', 'class', vertex.classes.join(' '));
link.setAttributeNS('http://www.w3.org/2000/svg', 'href', vertex.link);
link.setAttributeNS('http://www.w3.org/2000/svg', 'rel', 'noopener');
if (vertex.linkTarget) {
link.setAttributeNS('http://www.w3.org/2000/svg', 'target', vertex.linkTarget);
}
const linkNode = node.insert(function() {
return link;

View File

@ -469,6 +469,9 @@ export const draw = function(text, id) {
link.setAttributeNS('http://www.w3.org/2000/svg', 'class', vertex.classes.join(' '));
link.setAttributeNS('http://www.w3.org/2000/svg', 'href', vertex.link);
link.setAttributeNS('http://www.w3.org/2000/svg', 'rel', 'noopener');
if (vertex.linkTarget) {
link.setAttributeNS('http://www.w3.org/2000/svg', 'target', vertex.linkTarget);
}
const linkNode = node.insert(function() {
return link;

View File

@ -39,7 +39,7 @@ describe('[Interactions] when parsing', () => {
const vert = flow.parser.yy.getVertices();
const edges = flow.parser.yy.getEdges();
expect(flowDb.setLink).toHaveBeenCalledWith('A', 'click.html', undefined);
expect(flowDb.setLink).toHaveBeenCalledWith('A', 'click.html', undefined, undefined);
});
it('should handle interaction - click to a link with tooltip', function() {
@ -49,6 +49,26 @@ describe('[Interactions] when parsing', () => {
const vert = flow.parser.yy.getVertices();
const edges = flow.parser.yy.getEdges();
expect(flowDb.setLink).toHaveBeenCalledWith('A', 'click.html', 'tooltip');
expect(flowDb.setLink).toHaveBeenCalledWith('A', 'click.html', 'tooltip', undefined);
});
it('should handle interaction - click to a link with target', function() {
spyOn(flowDb, 'setLink');
const res = flow.parser.parse('graph TD\nA-->B\nclick A "click.html" _blank');
const vert = flow.parser.yy.getVertices();
const edges = flow.parser.yy.getEdges();
expect(flowDb.setLink).toHaveBeenCalledWith('A', 'click.html', undefined, '_blank');
});
it('should handle interaction - click to a link with tooltip and target', function() {
spyOn(flowDb, 'setLink');
const res = flow.parser.parse('graph TD\nA-->B\nclick A "click.html" "tooltip" _blank');
const vert = flow.parser.yy.getVertices();
const edges = flow.parser.yy.getEdges();
expect(flowDb.setLink).toHaveBeenCalledWith('A', 'click.html', 'tooltip', '_blank');
});
});

View File

@ -36,6 +36,12 @@
"flowchart" {if(yy.lex.firstGraph()){this.begin("dir");} return 'GRAPH';}
"subgraph" return 'subgraph';
"end"\b\s* return 'end';
"_self" return 'LINK_TARGET';
"_blank" return 'LINK_TARGET';
"_parent" return 'LINK_TARGET';
"_top" return 'LINK_TARGET';
<dir>(\r?\n)*\s*\n { this.popState(); return 'NODIR'; }
<dir>\s*"LR" { this.popState(); return 'DIR'; }
<dir>\s*"RL" { this.popState(); return 'DIR'; }
@ -439,10 +445,12 @@ classStatement:CLASS SPACE alphaNum SPACE alphaNum
;
clickStatement
: CLICK SPACE alphaNum SPACE alphaNum {$$ = $1;yy.setClickEvent($3, $5, undefined);}
| CLICK SPACE alphaNum SPACE alphaNum SPACE STR {$$ = $1;yy.setClickEvent($3, $5, $7) ;}
| CLICK SPACE alphaNum SPACE STR {$$ = $1;yy.setLink($3, $5, undefined);}
| CLICK SPACE alphaNum SPACE STR SPACE STR {$$ = $1;yy.setLink($3, $5, $7 );}
: CLICK SPACE alphaNum SPACE alphaNum {$$ = $1;yy.setClickEvent($3, $5, undefined);}
| CLICK SPACE alphaNum SPACE alphaNum SPACE STR {$$ = $1;yy.setClickEvent($3, $5, $7) ;}
| CLICK SPACE alphaNum SPACE STR {$$ = $1;yy.setLink($3, $5, undefined, undefined);}
| CLICK SPACE alphaNum SPACE STR SPACE STR {$$ = $1;yy.setLink($3, $5, $7, undefined );}
| CLICK SPACE alphaNum SPACE STR SPACE LINK_TARGET {$$ = $1;yy.setLink($3, $5, undefined, $7 );}
| CLICK SPACE alphaNum SPACE STR SPACE STR SPACE LINK_TARGET {$$ = $1;yy.setLink($3, $5, $7, $9 );}
;
styleStatement:STYLE SPACE alphaNum SPACE stylesOpt