mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-10-09 17:19:45 +02:00
Merge branch 'develop' into feature/hideUnusedParticipants_1210
This commit is contained in:
@@ -59,6 +59,7 @@ export const removeScript = (txt) => {
|
||||
let decodedText = removeEscapes(rs);
|
||||
decodedText = decodedText.replace(/script>/gi, '#');
|
||||
decodedText = decodedText.replace(/javascript:/gi, '#');
|
||||
decodedText = decodedText.replace(/javascript&colon/gi, '#');
|
||||
decodedText = decodedText.replace(/onerror=/gi, 'onerror:');
|
||||
decodedText = decodedText.replace(/<iframe/gi, '');
|
||||
return decodedText;
|
||||
|
@@ -136,7 +136,7 @@ export const branch = function (name) {
|
||||
}
|
||||
};
|
||||
|
||||
export const merge = function (otherBranch) {
|
||||
export const merge = function (otherBranch, tag) {
|
||||
otherBranch = common.sanitizeText(otherBranch, configApi.getConfig());
|
||||
const currentCommit = commits[branches[curBranch]];
|
||||
const otherCommit = commits[branches[otherBranch]];
|
||||
@@ -213,6 +213,7 @@ export const merge = function (otherBranch) {
|
||||
parents: [head == null ? null : head.id, branches[otherBranch]],
|
||||
branch: curBranch,
|
||||
type: commitType.MERGE,
|
||||
tag: tag ? tag : '',
|
||||
};
|
||||
head = commit;
|
||||
commits[commit.id] = commit;
|
||||
|
@@ -255,7 +255,7 @@ describe('when parsing a gitGraph', function () {
|
||||
it('should handle a gitGraph commit with custom type,tag, msg, commit id,', function () {
|
||||
const str = `gitGraph:
|
||||
commit type:REVERSE tag: "test tag" msg: "test msg" id: "1111"
|
||||
|
||||
|
||||
`;
|
||||
|
||||
parser.parse(str);
|
||||
@@ -336,6 +336,20 @@ describe('when parsing a gitGraph', function () {
|
||||
expect(Object.keys(parser.yy.getBranches()).length).toBe(2);
|
||||
});
|
||||
|
||||
it('should allow _-./ characters in branch names', function () {
|
||||
const str = `gitGraph:
|
||||
commit
|
||||
branch azAZ_-./test
|
||||
`;
|
||||
|
||||
parser.parse(str);
|
||||
const commits = parser.yy.getCommits();
|
||||
expect(Object.keys(commits).length).toBe(1);
|
||||
expect(parser.yy.getCurrentBranch()).toBe('azAZ_-./test');
|
||||
expect(parser.yy.getDirection()).toBe('LR');
|
||||
expect(Object.keys(parser.yy.getBranches()).length).toBe(2);
|
||||
});
|
||||
|
||||
it('should handle new branch checkout', function () {
|
||||
const str = `gitGraph:
|
||||
commit
|
||||
@@ -411,6 +425,41 @@ describe('when parsing a gitGraph', function () {
|
||||
]);
|
||||
});
|
||||
|
||||
it('should handle merge tags', function () {
|
||||
const str = `gitGraph:
|
||||
commit
|
||||
branch testBranch
|
||||
checkout testBranch
|
||||
commit
|
||||
checkout main
|
||||
merge testBranch tag: "merge-tag"
|
||||
`;
|
||||
|
||||
parser.parse(str);
|
||||
const commits = parser.yy.getCommits();
|
||||
expect(Object.keys(commits).length).toBe(3);
|
||||
expect(parser.yy.getCurrentBranch()).toBe('main');
|
||||
expect(parser.yy.getDirection()).toBe('LR');
|
||||
expect(Object.keys(parser.yy.getBranches()).length).toBe(2);
|
||||
const commit1 = Object.keys(commits)[0];
|
||||
const commit2 = Object.keys(commits)[1];
|
||||
const commit3 = Object.keys(commits)[2];
|
||||
|
||||
expect(commits[commit1].branch).toBe('main');
|
||||
expect(commits[commit1].parents).toStrictEqual([]);
|
||||
|
||||
expect(commits[commit2].branch).toBe('testBranch');
|
||||
expect(commits[commit2].parents).toStrictEqual([commits[commit1].id]);
|
||||
|
||||
expect(commits[commit3].branch).toBe('main');
|
||||
expect(commits[commit3].parents).toStrictEqual([commits[commit1].id, commits[commit2].id]);
|
||||
expect(commits[commit3].tag).toBe('merge-tag');
|
||||
expect(parser.yy.getBranchesAsObjArray()).toStrictEqual([
|
||||
{ name: 'main' },
|
||||
{ name: 'testBranch' },
|
||||
]);
|
||||
});
|
||||
|
||||
it('should throw error when try to branch existing branch: main', function () {
|
||||
const str = `gitGraph
|
||||
commit
|
||||
|
@@ -26,31 +26,31 @@
|
||||
\s+ /* skip all whitespace */
|
||||
\#[^\n]* /* skip comments */
|
||||
\%%[^\n]* /* skip comments */
|
||||
"gitGraph" return 'GG';
|
||||
"commit" return 'COMMIT';
|
||||
"id:" return 'COMMIT_ID';
|
||||
"type:" return 'COMMIT_TYPE';
|
||||
"msg:" return 'COMMIT_MSG';
|
||||
"NORMAL" return 'NORMAL';
|
||||
"REVERSE" return 'REVERSE';
|
||||
"HIGHLIGHT" return 'HIGHLIGHT';
|
||||
"tag:" return 'COMMIT_TAG';
|
||||
"branch" return 'BRANCH';
|
||||
"merge" return 'MERGE';
|
||||
// "reset" return 'RESET';
|
||||
"checkout" return 'CHECKOUT';
|
||||
"LR" return 'DIR';
|
||||
"BT" return 'DIR';
|
||||
":" return ':';
|
||||
"^" return 'CARET'
|
||||
"options"\r?\n this.begin("options");
|
||||
<options>"end"\r?\n this.popState();
|
||||
<options>[^\n]+\r?\n return 'OPT';
|
||||
["] this.begin("string");
|
||||
<string>["] this.popState();
|
||||
<string>[^"]* return 'STR';
|
||||
[a-zA-Z][-_\.a-zA-Z0-9]*[-_a-zA-Z0-9] return 'ID';
|
||||
<<EOF>> return 'EOF';
|
||||
"gitGraph" return 'GG';
|
||||
"commit" return 'COMMIT';
|
||||
"id:" return 'COMMIT_ID';
|
||||
"type:" return 'COMMIT_TYPE';
|
||||
"msg:" return 'COMMIT_MSG';
|
||||
"NORMAL" return 'NORMAL';
|
||||
"REVERSE" return 'REVERSE';
|
||||
"HIGHLIGHT" return 'HIGHLIGHT';
|
||||
"tag:" return 'COMMIT_TAG';
|
||||
"branch" return 'BRANCH';
|
||||
"merge" return 'MERGE';
|
||||
// "reset" return 'RESET';
|
||||
"checkout" return 'CHECKOUT';
|
||||
"LR" return 'DIR';
|
||||
"BT" return 'DIR';
|
||||
":" return ':';
|
||||
"^" return 'CARET'
|
||||
"options"\r?\n this.begin("options"); //
|
||||
<options>[ \r\n\t]+"end" this.popState(); // not used anymore in the renderer, fixed for backward compatibility
|
||||
<options>[\s\S]+(?=[ \r\n\t]+"end") return 'OPT'; //
|
||||
["] this.begin("string");
|
||||
<string>["] this.popState();
|
||||
<string>[^"]* return 'STR';
|
||||
[a-zA-Z][-_\./a-zA-Z0-9]*[-_a-zA-Z0-9] return 'ID';
|
||||
<<EOF>> return 'EOF';
|
||||
|
||||
/lex
|
||||
|
||||
@@ -89,11 +89,17 @@ line
|
||||
|
||||
statement
|
||||
: commitStatement
|
||||
| mergeStatement
|
||||
| BRANCH ID {yy.branch($2)}
|
||||
| CHECKOUT ID {yy.checkout($2)}
|
||||
| MERGE ID {yy.merge($2)}
|
||||
// | RESET reset_arg {yy.reset($2)}
|
||||
;
|
||||
|
||||
mergeStatement
|
||||
: MERGE ID {yy.merge($2)}
|
||||
| MERGE ID COMMIT_TAG STR {yy.merge($2, $4)}
|
||||
;
|
||||
|
||||
commitStatement
|
||||
: COMMIT commit_arg {yy.commit($2)}
|
||||
| COMMIT COMMIT_TAG STR {yy.commit('','',yy.commitType.NORMAL,$3)}
|
||||
|
@@ -32,6 +32,7 @@
|
||||
<INITIAL,ID,ALIAS,LINE,arg_directive,type_directive,open_directive>\#[^\n]* /* skip comments */
|
||||
\%%(?!\{)[^\n]* /* skip comments */
|
||||
[^\}]\%\%[^\n]* /* skip comments */
|
||||
[0-9]+(?=[ \n]+) return 'NUM';
|
||||
"participant" { this.begin('ID'); return 'participant'; }
|
||||
"actor" { this.begin('ID'); return 'participant_actor'; }
|
||||
<ID>[^\->:\n,;]+?(?=((?!\n)\s)+"as"(?!\n)\s|[#\n;]|$) { yytext = yytext.trim(); this.begin('ALIAS'); return 'ACTOR'; }
|
||||
@@ -58,9 +59,10 @@
|
||||
"deactivate" { this.begin('ID'); return 'deactivate'; }
|
||||
"title"\s[^#\n;]+ return 'title';
|
||||
"title:"\s[^#\n;]+ return 'legacy_title';
|
||||
"accDescription"\s[^#\n;]+ return 'accDescription';
|
||||
"accDescription"\s[^#\n;]+ return 'accDescription';
|
||||
"sequenceDiagram" return 'SD';
|
||||
"autonumber" return 'autonumber';
|
||||
"off" return 'off';
|
||||
"," return ',';
|
||||
";" return 'NEWLINE';
|
||||
[^\+\->:\n,;]+((?!(\-x|\-\-x|\-\)|\-\-\)))[\-]*[^\+\->:\n,;]+)* { yytext = yytext.trim(); return 'ACTOR'; }
|
||||
@@ -115,7 +117,10 @@ statement
|
||||
| 'participant_actor' actor 'AS' restOfLine 'NEWLINE' {$2.type='addActor';$2.description=yy.parseMessage($4); $$=$2;}
|
||||
| 'participant_actor' actor 'NEWLINE' {$2.type='addActor'; $$=$2;}
|
||||
| signal 'NEWLINE'
|
||||
| autonumber {yy.enableSequenceNumbers()}
|
||||
| autonumber NUM NUM 'NEWLINE' { $$= {type:'sequenceIndex',sequenceIndex: Number($2), sequenceIndexStep:Number($3), sequenceVisible:true, signalType:yy.LINETYPE.AUTONUMBER};}
|
||||
| autonumber NUM 'NEWLINE' { $$ = {type:'sequenceIndex',sequenceIndex: Number($2), sequenceIndexStep:1, sequenceVisible:true, signalType:yy.LINETYPE.AUTONUMBER};}
|
||||
| autonumber off 'NEWLINE' { $$ = {type:'sequenceIndex', sequenceVisible:false, signalType:yy.LINETYPE.AUTONUMBER};}
|
||||
| autonumber 'NEWLINE' {$$ = {type:'sequenceIndex', sequenceVisible:true, signalType:yy.LINETYPE.AUTONUMBER}; }
|
||||
| 'activate' actor 'NEWLINE' {$$={type: 'activeStart', signalType: yy.LINETYPE.ACTIVE_START, actor: $2};}
|
||||
| 'deactivate' actor 'NEWLINE' {$$={type: 'activeEnd', signalType: yy.LINETYPE.ACTIVE_END, actor: $2};}
|
||||
| note_statement 'NEWLINE'
|
||||
|
@@ -125,6 +125,9 @@ export const getTitle = function () {
|
||||
export const enableSequenceNumbers = function () {
|
||||
sequenceNumbersEnabled = true;
|
||||
};
|
||||
export const disableSequenceNumbers = function () {
|
||||
sequenceNumbersEnabled = false;
|
||||
};
|
||||
export const showSequenceNumbers = () => sequenceNumbersEnabled;
|
||||
|
||||
export const setWrap = function (wrapSetting) {
|
||||
@@ -178,6 +181,7 @@ export const LINETYPE = {
|
||||
RECT_END: 23,
|
||||
SOLID_POINT: 24,
|
||||
DOTTED_POINT: 25,
|
||||
AUTONUMBER: 26,
|
||||
};
|
||||
|
||||
export const ARROWTYPE = {
|
||||
@@ -333,6 +337,19 @@ export const apply = function (param) {
|
||||
});
|
||||
} else {
|
||||
switch (param.type) {
|
||||
case 'sequenceIndex':
|
||||
messages.push({
|
||||
from: undefined,
|
||||
to: undefined,
|
||||
message: {
|
||||
start: param.sequenceIndex,
|
||||
step: param.sequenceIndexStep,
|
||||
visible: param.sequenceVisible,
|
||||
},
|
||||
wrap: false,
|
||||
type: param.signalType,
|
||||
});
|
||||
break;
|
||||
case 'addParticipant':
|
||||
addActor(param.actor, param.actor, param.description, 'participant');
|
||||
break;
|
||||
@@ -425,6 +442,7 @@ export default {
|
||||
autoWrap,
|
||||
setWrap,
|
||||
enableSequenceNumbers,
|
||||
disableSequenceNumbers,
|
||||
showSequenceNumbers,
|
||||
getMessages,
|
||||
getActors,
|
||||
|
@@ -47,6 +47,7 @@ Note right of Bob: Bob thinks
|
||||
Bob-->Alice: I am good thanks!`;
|
||||
|
||||
mermaidAPI.parse(str);
|
||||
renderer.draw(str, 'tst'); // needs to be rendered for the correct value of visibility autonumbers
|
||||
expect(parser.yy.showSequenceNumbers()).toBe(false);
|
||||
});
|
||||
it('it should show sequence numbers when autonumber is enabled', function () {
|
||||
@@ -58,6 +59,7 @@ Note right of Bob: Bob thinks
|
||||
Bob-->Alice: I am good thanks!`;
|
||||
|
||||
mermaidAPI.parse(str);
|
||||
renderer.draw(str, 'tst'); // needs to be rendered for the correct value of visibility autonumbers
|
||||
expect(parser.yy.showSequenceNumbers()).toBe(true);
|
||||
});
|
||||
it('it should handle a sequenceDiagram definition with a title:', function () {
|
||||
@@ -1676,6 +1678,7 @@ Note right of Bob: Bob thinks
|
||||
Bob-->Alice: I am good thanks!`;
|
||||
|
||||
mermaidAPI.parse(str1);
|
||||
renderer.draw(str1, 'tst'); // needs to be rendered for the correct value of visibility autonumbers
|
||||
expect(parser.yy.showSequenceNumbers()).toBe(true);
|
||||
|
||||
const str2 = `
|
||||
@@ -1685,6 +1688,7 @@ Note right of Bob: Bob thinks
|
||||
Bob-->Alice: I am good thanks!`;
|
||||
|
||||
mermaidAPI.parse(str2);
|
||||
renderer.draw(str2, 'tst');
|
||||
expect(parser.yy.showSequenceNumbers()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
@@ -329,7 +329,7 @@ const boundMessage = function (diagram, msgModel) {
|
||||
* @param {float} lineStarty - The Y coordinate at which the message line starts
|
||||
*/
|
||||
const drawMessage = function (diagram, msgModel, lineStarty) {
|
||||
const { startx, stopx, starty, message, type, sequenceIndex } = msgModel;
|
||||
const { startx, stopx, starty, message, type, sequenceIndex, sequenceVisible } = msgModel;
|
||||
let textDims = utils.calculateTextDimensions(message, messageFont(conf));
|
||||
const textObj = svgDraw.getTextObj();
|
||||
textObj.x = startx;
|
||||
@@ -432,7 +432,7 @@ const drawMessage = function (diagram, msgModel, lineStarty) {
|
||||
}
|
||||
|
||||
// add node number
|
||||
if (sequenceDb.showSequenceNumbers() || conf.showSequenceNumbers) {
|
||||
if (sequenceVisible || conf.showSequenceNumbers) {
|
||||
line.attr('marker-start', 'url(' + url + '#sequencenumber)');
|
||||
diagram
|
||||
.append('text')
|
||||
@@ -653,6 +653,7 @@ export const draw = function (text, id) {
|
||||
|
||||
// Draw the messages/signals
|
||||
let sequenceIndex = 1;
|
||||
let sequenceIndexStep = 1;
|
||||
let messagesToDraw = Array();
|
||||
messages.forEach(function (msg) {
|
||||
let loopModel, noteModel, msgModel;
|
||||
@@ -757,12 +758,19 @@ export const draw = function (text, id) {
|
||||
bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos());
|
||||
bounds.models.addLoop(loopModel);
|
||||
break;
|
||||
case parser.yy.LINETYPE.AUTONUMBER:
|
||||
sequenceIndex = msg.message.start || sequenceIndex;
|
||||
sequenceIndexStep = msg.message.step || sequenceIndexStep;
|
||||
if (msg.message.visible) parser.yy.enableSequenceNumbers();
|
||||
else parser.yy.disableSequenceNumbers();
|
||||
break;
|
||||
default:
|
||||
try {
|
||||
// lastMsg = msg
|
||||
msgModel = msg.msgModel;
|
||||
msgModel.starty = bounds.getVerticalPos();
|
||||
msgModel.sequenceIndex = sequenceIndex;
|
||||
msgModel.sequenceVisible = parser.yy.showSequenceNumbers();
|
||||
let lineStarty = boundMessage(diagram, msgModel);
|
||||
messagesToDraw.push({ messageModel: msgModel, lineStarty: lineStarty });
|
||||
bounds.models.addMessage(msgModel);
|
||||
@@ -784,7 +792,7 @@ export const draw = function (text, id) {
|
||||
parser.yy.LINETYPE.DOTTED_POINT,
|
||||
].includes(msg.type)
|
||||
) {
|
||||
sequenceIndex++;
|
||||
sequenceIndex = sequenceIndex + sequenceIndexStep;
|
||||
}
|
||||
});
|
||||
|
||||
|
Reference in New Issue
Block a user