align click on href or function syntax with other diagrams

This commit is contained in:
Matthieu MOREL
2020-12-06 22:23:13 +01:00
parent d8e57d1c01
commit 0b8561711b
6 changed files with 107 additions and 41 deletions

View File

@@ -69,7 +69,7 @@
int id
test()
}
callback Class01 "callback" "A Tooltip"
click Class01 call callback() "A Tooltip"
</div>
<div class="mermaid2" style="width: 100%; height: 20%;">

View File

@@ -41,16 +41,16 @@
<div id="FirstLine" class="mermaid">
classDiagram
class ShapeLink
link ShapeLink "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
click ShapeLink href "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
class ShapeCallback
callback ShapeCallback "clickByClass" "This is a tooltip for a callback"
click ShapeCallback call clickByClass() "This is a tooltip for a callback"
</div>
<div id="FirstLine" class="mermaid">
classDiagram-v2
class ShapeLink2
link ShapeLink2 "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
click ShapeLink2 href "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
class ShapeCallback2
callback ShapeCallback2 "clickByClass" "This is a tooltip for a callback"
click ShapeCallback2 call clickByClass() "This is a tooltip for a callback"
</div>
</div>

View File

@@ -30,19 +30,19 @@
classDiagram
class Test
class ShapeLink
link ShapeLink "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
click ShapeLink href "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
class ShapeCallback
callback ShapeCallback "clickByClass" "This is a tooltip for a callback"
click ShapeCallback call clickByClass() "This is a tooltip for a callback"
</div>
<div id="FirstLine" class="mermaid">
classDiagram-v2
class ShapeCallback
callback ShapeCallback "clickByClass" "This is a tooltip for a callback"
click ShapeCallback call clickByClass() "This is a tooltip for a callback"
</div>
<div id="FirstLine" class="mermaid">
classDiagram-v2
class ShapeLink
link ShapeLink "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
click ShapeLink href "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
</div>
</div>

View File

@@ -167,23 +167,29 @@ export const setCssClass = function(ids, className) {
});
};
const setTooltip = function(ids, tooltip) {
const config = configApi.getConfig();
ids.split(',').forEach(function(id) {
if (typeof tooltip !== 'undefined') {
classes[id].tooltip = common.sanitizeText(tooltip, config);
}
});
};
/**
* 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) {
export const setLink = function(ids, linkStr) {
const config = configApi.getConfig();
ids.split(',').forEach(function(_id) {
let id = _id;
if (_id[0].match(/\d/)) id = MERMAID_DOM_ID_PREFIX + id;
if (typeof classes[id] !== 'undefined') {
classes[id].link = utils.formatUrl(linkStr, config);
if (tooltip) {
classes[id].tooltip = common.sanitizeText(tooltip, config);
}
}
});
setCssClass(ids, 'clickable');
@@ -193,9 +199,9 @@ export const setLink = function(ids, linkStr, tooltip) {
* Called by parser when a click definition is found. Registers an event handler.
* @param ids Comma separated list of ids
* @param functionName Function to be called on click
* @param tooltip Tooltip for the clickable element
* @param functionArgs Function args the function should be called with
*/
export const setClickEvent = function(ids, functionName, tooltip) {
export const setClickEvent = function(ids, functionName, functionArgs) {
ids.split(',').forEach(function(id) {
setClickFunc(id, functionName, tooltip);
classes[id].haveCallback = true;
@@ -215,8 +221,24 @@ const setClickFunc = function(domId, functionName, tooltip) {
return;
}
if (typeof classes[id] !== 'undefined') {
if (tooltip) {
classes[id].tooltip = common.sanitizeText(tooltip, config);
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(elemId);
}
funs.push(function() {
@@ -225,7 +247,7 @@ const setClickFunc = function(domId, functionName, tooltip) {
elem.addEventListener(
'click',
function() {
utils.runFunc(functionName, elemId);
utils.runFunc(functionName, ...argList);
},
false
);
@@ -314,5 +336,6 @@ export default {
setClickEvent,
setCssClass,
setLink,
setTooltip,
lookUpDomId
};

View File

@@ -338,7 +338,7 @@ foo()
'test()\n' +
'foo()\n' +
'}\n' +
'link Class01 "google.com" ';
'click Class01 href "google.com" ';
parser.parse(str);
});
@@ -353,7 +353,7 @@ foo()
'test()\n' +
'foo()\n' +
'}\n' +
'link Class01 "google.com" "A Tooltip" ';
'click Class01 href "google.com" "A Tooltip" ';
parser.parse(str);
});
@@ -368,7 +368,7 @@ foo()
'test()\n' +
'foo()\n' +
'}\n' +
'callback Class01 "functionCall" ';
'click Class01 call functionCall() ';
parser.parse(str);
});
@@ -383,7 +383,7 @@ foo()
'test()\n' +
'foo()\n' +
'}\n' +
'callback Class01 "functionCall" "A Tooltip" ';
'click Class01 call functionCall() "A Tooltip" ';
parser.parse(str);
});
@@ -637,7 +637,7 @@ foo()
});
it('should associate link and css appropriately', function () {
const str = 'classDiagram\n' + 'class Class1\n' + 'Class1 : someMethod()\n' + 'link Class1 "google.com"';
const str = 'classDiagram\n' + 'class Class1\n' + 'Class1 : someMethod()\n' + 'click Class1 href "google.com"';
parser.parse(str);
const testClass = parser.yy.getClass('Class1');
@@ -647,7 +647,7 @@ foo()
});
it('should associate link with tooltip', function () {
const str = 'classDiagram\n' + 'class Class1\n' + 'Class1 : someMethod()\n' + 'link Class1 "google.com" "A tooltip"';
const str = 'classDiagram\n' + 'class Class1\n' + 'Class1 : someMethod()\n' + 'click Class1 href "google.com" "A tooltip"';
parser.parse(str);
const testClass = parser.yy.getClass('Class1');
@@ -659,18 +659,28 @@ foo()
it('should associate callback appropriately', function () {
spyOn(classDb, 'setClickEvent');
const str = 'classDiagram\n' + 'class Class1\n' + 'Class1 : someMethod()\n' + 'callback Class1 "functionCall"';
const str = 'classDiagram\n' + 'class Class1\n' + 'Class1 : someMethod()\n' + 'click Class1 call functionCall()';
parser.parse(str);
expect(classDb.setClickEvent).toHaveBeenCalledWith('Class1', 'functionCall', undefined);
expect(classDb.setClickEvent).toHaveBeenCalledWith('Class1', 'functionCall');
});
it('should associate callback appropriately with an arbitrary number of args', function () {
spyOn(classDb, 'setClickEvent');
const str = 'classDiagram\n' + 'class Class1\n' + 'Class1 : someMethod()\n' + 'click Class1 call functionCall("test0", test1, test2)';
parser.parse(str);
expect(classDb.setClickEvent).toHaveBeenCalledWith('Class1', 'functionCall','"test0", test1, test2');
});
it('should associate callback with tooltip', function () {
spyOn(classDb, 'setClickEvent');
const str = 'classDiagram\n' + 'class Class1\n' + 'Class1 : someMethod()\n' + 'callback Class1 "functionCall" "A tooltip"';
spyOn(classDb, 'setTooltip');
const str = 'classDiagram\n' + 'class Class1\n' + 'Class1 : someMethod()\n' + 'click Class1 functionCall() "A tooltip"';
parser.parse(str);
expect(classDb.setClickEvent).toHaveBeenCalledWith('Class1', 'functionCall', 'A tooltip');
expect(classDb.setClickEvent).toHaveBeenCalledWith('Class1', 'functionCall');
expect(classDb.setTooltip).toHaveBeenCalledWith('Class1', 'A tooltip');
});
});
});

View File

@@ -6,7 +6,15 @@
/* lexical grammar */
%lex
%x string generic struct open_directive type_directive arg_directive
%x string
%x generic
%x struct
%x href
%x callbackname
%x callbackargs
%x open_directive
%x type_directive
%x arg_directive
%%
\%\%\{ { this.begin('open_directive'); return 'open_directive'; }
@@ -29,8 +37,7 @@
"class" return 'CLASS';
"cssClass" return 'CSSCLASS';
"callback" return 'CALLBACK';
"link" return 'LINK';
"click" return 'CLICK';
"<<" return 'ANNOTATION_START';
">>" return 'ANNOTATION_END';
[~] this.begin("generic");
@@ -40,6 +47,30 @@
<string>["] this.popState();
<string>[^"]* return "STR";
/*
---interactivity command---
'href' adds a link to the specified task. 'href' can only be specified when the
line was introduced with 'click'.
'href "<link>"' attaches the specified link to the node that was specified by 'click'.
*/
"href"[\s]+["] this.begin("href");
<href>["] this.popState();
<href>[^"]* 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 <callbackname>(<args>)' attaches the function 'callbackname' with the specified
arguments to the task that was specified by 'click'.
Function arguments are optional: 'call <callbackname>()' simply executes 'callbackname' without any arguments.
*/
"call"[\s]+ this.begin("callbackname");
<callbackname>\([\s]*\) this.popState();
<callbackname>\( this.popState(); this.begin("callbackargs");
<callbackname>[^(]* return 'CALLBACKNAME';
<callbackargs>\) this.popState();
<callbackargs>[^)]* return 'CALLBACKARGS';
\s*\<\| return 'EXTENSION';
\s*\|\> return 'EXTENSION';
@@ -243,10 +274,12 @@ lineType
;
clickStatement
: CALLBACK className STR {$$ = $1;yy.setClickEvent($2, $3, undefined);}
| CALLBACK className STR STR {$$ = $1;yy.setClickEvent($2, $3, $4);}
| LINK className STR {$$ = $1;yy.setLink($2, $3, undefined);}
| LINK className STR STR {$$ = $1;yy.setLink($2, $3, $4);}
: CLICK className CALLBACKNAME {$$ = $1;yy.setClickEvent($2, $3);}
| CLICK className CALLBACKNAME STR {$$ = $1;yy.setClickEvent($2, $3);yy.setTooltip($2, $4);}
| CLICK className CALLBACKNAME CALLBACKARGS {$$ = $1;yy.setClickEvent($2, $3, $4);}
| CLICK className CALLBACKNAME CALLBACKARGS STR {$$ = $1;yy.setClickEvent($2, $3, $4);yy.setTooltip($2, $5);}
| CLICK className HREF {$$ = $1;yy.setLink($2, $3);}
| CLICK className HREF STR {$$ = $1;yy.setLink($2, $3);yy.setTooltip($2, $4);}
;
cssClassStatement