diff --git a/src/diagrams/flowchart/flowDb.js b/src/diagrams/flowchart/flowDb.js
index 4217cebd1..b34db18ed 100644
--- a/src/diagrams/flowchart/flowDb.js
+++ b/src/diagrams/flowchart/flowDb.js
@@ -247,7 +247,7 @@ const setTooltip = function(ids, tooltip) {
});
};
-const setClickFun = function(id, functionName) {
+const setClickFun = function(id, functionName, functionArgs) {
let domId = lookUpDomId(id);
// if (_id[0].match(/\d/)) id = MERMAID_DOM_ID_PREFIX + id;
if (configApi.getConfig().securityLevel !== 'loose') {
@@ -256,6 +256,29 @@ const setClickFun = function(id, functionName) {
if (typeof functionName === 'undefined') {
return;
}
+ let argList = [];
+ if (typeof functionArgs === 'string') {
+ /* Splits functionArgs by ',', ignoring all ',' in double quoted strings */
+ argList = functionArgs.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);
+ for (let i = 0; i < argList.length; i++) {
+ let item = argList[i].trim();
+ /* Removes all double quotes at the start and end of an argument */
+ /* This preserves all starting and ending whitespace inside */
+ if (item.charAt(0) === '"' && item.charAt(item.length - 1) === '"') {
+ item = item.substr(1, item.length - 2);
+
+
+
+ }
+ argList[i] = item;
+ }
+ }
+
+ /* if no arguments passed into callback, default to passing in id */
+ if (argList.length === 0) {
+ argList.push(id);
+ }
+
if (typeof vertices[id] !== 'undefined') {
vertices[id].haveCallback = true;
funs.push(function() {
@@ -264,7 +287,7 @@ const setClickFun = function(id, functionName) {
elem.addEventListener(
'click',
function() {
- utils.runFunc(functionName, id);
+ utils.runFunc(functionName, ...argList);
},
false
);
@@ -277,16 +300,14 @@ const setClickFun = function(id, functionName) {
* Called by parser when a link is found. Adds the URL to the vertex data.
* @param ids Comma separated list of ids
* @param linkStr URL to create a link for
- * @param tooltip Tooltip for the clickable element
*/
-export const setLink = function(ids, linkStr, tooltip, target) {
+export const setLink = function(ids, linkStr, target) {
ids.split(',').forEach(function(id) {
if (typeof vertices[id] !== 'undefined') {
vertices[id].link = utils.formatUrl(linkStr, config);
vertices[id].linkTarget = target;
}
});
- setTooltip(ids, tooltip);
setClass(ids, 'clickable');
};
export const getTooltip = function(id) {
@@ -299,11 +320,10 @@ export const getTooltip = function(id) {
* @param functionName Function to be called on click
* @param tooltip Tooltip for the clickable element
*/
-export const setClickEvent = function(ids, functionName, tooltip) {
+export const setClickEvent = function(ids, functionName, functionArgs) {
ids.split(',').forEach(function(id) {
- setClickFun(id, functionName);
+ setClickFun(id, functionName, functionArgs);
});
- setTooltip(ids, tooltip);
setClass(ids, 'clickable');
};
diff --git a/src/diagrams/flowchart/parser/flow.jison b/src/diagrams/flowchart/parser/flow.jison
index 794e9839c..f8e2e3529 100644
--- a/src/diagrams/flowchart/parser/flow.jison
+++ b/src/diagrams/flowchart/parser/flow.jison
@@ -9,6 +9,10 @@
%x string
%x dir
%x vertex
+%x click
+%x href
+%x callbackname
+%x callbackargs
%x open_directive
%x type_directive
%x arg_directive
@@ -31,7 +35,42 @@
"interpolate" return 'INTERPOLATE';
"classDef" return 'CLASSDEF';
"class" return 'CLASS';
-"click" return 'CLICK';
+
+/*
+---interactivity command---
+'href' adds a link to the specified task. 'href' can only be specified when the
+line was introduced with 'click'.
+'href ""' attaches the specified link to the node that was specified by 'click'.
+*/
+"href"[\s]+["] this.begin("href");
+["] this.popState();
+[^"]* return 'HREF';
+
+/*
+---interactivity command---
+'call' adds a callback to the specified task. 'call' can only be specified when
+the line was introduced with 'click'.
+'call ()' attaches the function 'callbackname' with the specified
+arguments to the task that was specified by 'click'.
+Function arguments are optional: 'call ()' simply executes 'callbackname' without any arguments.
+*/
+"call"[\s]+ this.begin("callbackname");
+\([\s]*\) this.popState();
+\( this.popState(); this.begin("callbackargs");
+[^(]* return 'CALLBACKNAME';
+\) this.popState();
+[^)]* return 'CALLBACKARGS';
+
+/*
+'click' is the keyword to introduce a line that contains interactivity commands.
+'click' must be followed by an existing node-id. All commands are attached to
+that id.
+'click ' can be followed by href or call commands in any desired order
+*/
+"click"[\s]+ this.begin("click");
+[\s\n] this.popState();
+[^\s\n]* return 'CLICK';
+
"graph" {if(yy.lex.firstGraph()){this.begin("dir");} return 'GRAPH';}
"flowchart" {if(yy.lex.firstGraph()){this.begin("dir");} return 'GRAPH';}
"subgraph" return 'subgraph';
@@ -411,12 +450,26 @@ 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, 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 );}
+ : CLICK CALLBACKNAME {$$ = $1;yy.setClickEvent($1, $2);
+ | CLICK CALLBACKNAME CALLBACKARGS {$$ = $1;yy.setClickEvent($1, $2, $3);}
+ | CLICK CALLBACKNAME CALLBACKARGS HREF {$$ = $1;yy.setClickEvent($1, $2, $3);yy.setLink($1,$4);}
+ | CLICK CALLBACKNAME CALLBACKARGS SPACE STR {$$ = $1;yy.setClickEvent($1, $2, $3);yy.setTooltip($1, $4)}
+ | CLICK CALLBACKNAME CALLBACKARGS HREF SPACE STR {$$ = $1;yy.setClickEvent($1, $2, $3);yy.setLink($1,$4);yy.setTooltip($1, $6)}
+ | CLICK CALLBACKNAME CALLBACKARGS HREF SPACE LINK_TARGET {$$ = $1;yy.setClickEvent($1, $2, $3);yy.setLink($1,$4, $6)}
+ | CLICK CALLBACKNAME CALLBACKARGS HREF SPACE STR SPACE LINK_TARGET {$$ = $1;yy.setClickEvent($1, $2, $3);yy.setLink($1,$4, $8);yy.setTooltip($1, $6)}
+
+ | CLICK CALLBACKNAME HREF {$$ = $1;yy.setClickEvent($1, $2);yy.setLink($1,$3);}
+ | CLICK CALLBACKNAME SPACE STR {$$ = $1;yy.setClickEvent($1, $2);yy.setTooltip($1, $4)}
+ | CLICK CALLBACKNAME HREF SPACE STR {$$ = $1;yy.setClickEvent($1, $2);yy.setLink($1,$3);yy.setTooltip($1, $5)}
+ | CLICK CALLBACKNAME HREF SPACE LINK_TARGET {$$ = $1;yy.setClickEvent($1, $2, $3);yy.setLink($1,$4, $5)}
+ | CLICK CALLBACKNAME HREF SPACE STR SPACE LINK_TARGET {$$ = $1;yy.setClickEvent($1, $2, $3);yy.setLink($1,$4, $7);yy.setTooltip($1, $5)}
+
+ | CLICK HREF {$$ = $1;yy.setLink($1, $2);}
+ | CLICK HREF CALLBACKNAME {$$ = $1;yy.setClickEvent($1, $3);yy.setLink($1,$2);}
+ | CLICK HREF CALLBACKNAME CALLBACKARGS {$$ = $1;yy.setClickEvent($1, $3, $4);yy.setLink($1,$2);}
+ | CLICK HREF SPACE STR {$$ = $1;yy.setLink($1, $2);yy.setTooltip($1, $4)}
+ | CLICK HREF SPACE LINK_TARGET {$$ = $1;yy.setLink($1, $2, $4);}
+ | CLICK HREF SPACE STR SPACE LINK_TARGET {$$ = $1;yy.setLink($1, $2, $7);yy.setTooltip($1, $4)}
;
styleStatement:STYLE SPACE alphaNum SPACE stylesOpt