mirror of
				https://github.com/mermaid-js/mermaid.git
				synced 2025-11-04 12:54:08 +01:00 
			
		
		
		
	Adding "Critical Region" and "Break" blocks
This commit is contained in:
		@@ -452,6 +452,42 @@ context('Sequence diagram', () => {
 | 
				
			|||||||
        {}
 | 
					        {}
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					    it('should render rect around and inside criticals', () => {
 | 
				
			||||||
 | 
					      imgSnapshotTest(
 | 
				
			||||||
 | 
					        `
 | 
				
			||||||
 | 
					        sequenceDiagram
 | 
				
			||||||
 | 
					          A ->> B: 1
 | 
				
			||||||
 | 
					          rect rgb(204, 0, 102)
 | 
				
			||||||
 | 
					            critical yes
 | 
				
			||||||
 | 
					              C ->> C: 1
 | 
				
			||||||
 | 
					            option no
 | 
				
			||||||
 | 
					              rect rgb(0, 204, 204)
 | 
				
			||||||
 | 
					                C ->> C: 0
 | 
				
			||||||
 | 
					              end
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					          B ->> A: Return
 | 
				
			||||||
 | 
					      `,
 | 
				
			||||||
 | 
					        {}
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    it('should render rect around and inside breaks', () => {
 | 
				
			||||||
 | 
					      imgSnapshotTest(
 | 
				
			||||||
 | 
					        `
 | 
				
			||||||
 | 
					        sequenceDiagram
 | 
				
			||||||
 | 
					          A ->> B: 1
 | 
				
			||||||
 | 
					          rect rgb(204, 0, 102)
 | 
				
			||||||
 | 
					            break yes
 | 
				
			||||||
 | 
					              rect rgb(0, 204, 204)
 | 
				
			||||||
 | 
					                C ->> C: 0
 | 
				
			||||||
 | 
					              end
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					          B ->> A: Return
 | 
				
			||||||
 | 
					      `,
 | 
				
			||||||
 | 
					        {}
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
    it('should render autonumber when configured with such', () => {
 | 
					    it('should render autonumber when configured with such', () => {
 | 
				
			||||||
      imgSnapshotTest(
 | 
					      imgSnapshotTest(
 | 
				
			||||||
        `
 | 
					        `
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -230,6 +230,70 @@ sequenceDiagram
 | 
				
			|||||||
    end
 | 
					    end
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Critical Region
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					It is possible to show actions that must happen automatically with conditional handling of circumstances.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This is done by the notation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					critical [Action that must be performed]
 | 
				
			||||||
 | 
					... statements ...
 | 
				
			||||||
 | 
					option [Circumstance A]
 | 
				
			||||||
 | 
					... statements ...
 | 
				
			||||||
 | 
					option [Circumstance B]
 | 
				
			||||||
 | 
					... statements ...
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See the example below:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```mermaid-example
 | 
				
			||||||
 | 
					sequenceDiagram
 | 
				
			||||||
 | 
					    critical Establish a connection to the DB
 | 
				
			||||||
 | 
					        Service-->DB: connect
 | 
				
			||||||
 | 
					    option Network timeout
 | 
				
			||||||
 | 
					        Service-->Service: Log error
 | 
				
			||||||
 | 
					    option Credentials rejected
 | 
				
			||||||
 | 
					        Service-->Service: Log different error
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					It is also possible to have no options at all
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```mermaid-example
 | 
				
			||||||
 | 
					sequenceDiagram
 | 
				
			||||||
 | 
					    critical Establish a connection to the DB
 | 
				
			||||||
 | 
					        Service-->DB: connect
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This critical block can also be nested, equivalently to the `par` statement as seen above.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					It is possible to indicate a stop of the sequence within the flow (usually used to model exceptions).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This is done by the notation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					break [something happened]
 | 
				
			||||||
 | 
					... statements ...
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See the example below:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```mermaid-example
 | 
				
			||||||
 | 
					sequenceDiagram
 | 
				
			||||||
 | 
					    Consumer-->API: Book something
 | 
				
			||||||
 | 
					    API-->BookingService: Start booking process
 | 
				
			||||||
 | 
					    break when the booking process fails
 | 
				
			||||||
 | 
					        API-->Consumer: show failure
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					    API-->BillingService: Start billing process
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Background Highlighting
 | 
					## Background Highlighting
 | 
				
			||||||
 | 
					
 | 
				
			||||||
It is possible to highlight flows by providing colored background rects. This is done by the notation
 | 
					It is possible to highlight flows by providing colored background rects. This is done by the notation
 | 
				
			||||||
@@ -300,8 +364,8 @@ It is possible to get a sequence number attached to each arrow in a sequence dia
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
```html
 | 
					```html
 | 
				
			||||||
    <script>
 | 
					    <script>
 | 
				
			||||||
      mermaid.initialize({ sequence: { showSequenceNumbers: true }, });
 | 
					    mermaid.initialize({ sequence: { showSequenceNumbers: true }, });
 | 
				
			||||||
    </script>
 | 
					</script>
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
It can also be be turned on via the diagram code as in the diagram:
 | 
					It can also be be turned on via the diagram code as in the diagram:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -47,6 +47,9 @@
 | 
				
			|||||||
"else"                                                          { this.begin('LINE'); return 'else'; }
 | 
					"else"                                                          { this.begin('LINE'); return 'else'; }
 | 
				
			||||||
"par"                                                           { this.begin('LINE'); return 'par'; }
 | 
					"par"                                                           { this.begin('LINE'); return 'par'; }
 | 
				
			||||||
"and"                                                           { this.begin('LINE'); return 'and'; }
 | 
					"and"                                                           { this.begin('LINE'); return 'and'; }
 | 
				
			||||||
 | 
					"critical"                                                      { this.begin('LINE'); return 'critical'; }
 | 
				
			||||||
 | 
					"option"                                                        { this.begin('LINE'); return 'option'; }
 | 
				
			||||||
 | 
					"break"                                                         { this.begin('LINE'); return 'break'; }
 | 
				
			||||||
<LINE>(?:[:]?(?:no)?wrap:)?[^#\n;]*                             { this.popState(); return 'restOfLine'; }
 | 
					<LINE>(?:[:]?(?:no)?wrap:)?[^#\n;]*                             { this.popState(); return 'restOfLine'; }
 | 
				
			||||||
"end"                                                           return 'end';
 | 
					"end"                                                           return 'end';
 | 
				
			||||||
"left of"                                                       return 'left_of';
 | 
					"left of"                                                       return 'left_of';
 | 
				
			||||||
@@ -172,9 +175,28 @@ statement
 | 
				
			|||||||
		// End
 | 
							// End
 | 
				
			||||||
		$3.push({type: 'parEnd', signalType: yy.LINETYPE.PAR_END});
 | 
							$3.push({type: 'parEnd', signalType: yy.LINETYPE.PAR_END});
 | 
				
			||||||
		$$=$3;}
 | 
							$$=$3;}
 | 
				
			||||||
 | 
						| critical restOfLine option_sections end
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							// critical start
 | 
				
			||||||
 | 
							$3.unshift({type: 'criticalStart', criticalText:yy.parseMessage($2), signalType: yy.LINETYPE.CRITICAL_START});
 | 
				
			||||||
 | 
							// Content in critical is already in $3
 | 
				
			||||||
 | 
							// critical end
 | 
				
			||||||
 | 
							$3.push({type: 'criticalEnd', signalType: yy.LINETYPE.CRITICAL_END});
 | 
				
			||||||
 | 
							$$=$3;}
 | 
				
			||||||
 | 
						| break restOfLine document end
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							$3.unshift({type: 'breakStart', breakText:yy.parseMessage($2), signalType: yy.LINETYPE.BREAK_START});
 | 
				
			||||||
 | 
							$3.push({type: 'breakEnd', optText:yy.parseMessage($2), signalType: yy.LINETYPE.BREAK_END});
 | 
				
			||||||
 | 
							$$=$3;}
 | 
				
			||||||
  | directive
 | 
					  | directive
 | 
				
			||||||
	;
 | 
						;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					option_sections
 | 
				
			||||||
 | 
						: document
 | 
				
			||||||
 | 
						| document option restOfLine option_sections
 | 
				
			||||||
 | 
						{ $$ = $1.concat([{type: 'option', optionText:yy.parseMessage($3), signalType: yy.LINETYPE.CRITICAL_OPTION}, $4]); }
 | 
				
			||||||
 | 
						;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
par_sections
 | 
					par_sections
 | 
				
			||||||
	: document
 | 
						: document
 | 
				
			||||||
	| document and restOfLine par_sections
 | 
						| document and restOfLine par_sections
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -156,8 +156,8 @@ export const parseMessage = function (str) {
 | 
				
			|||||||
      _str.match(/^[:]?wrap:/) !== null
 | 
					      _str.match(/^[:]?wrap:/) !== null
 | 
				
			||||||
        ? true
 | 
					        ? true
 | 
				
			||||||
        : _str.match(/^[:]?nowrap:/) !== null
 | 
					        : _str.match(/^[:]?nowrap:/) !== null
 | 
				
			||||||
        ? false
 | 
					          ? false
 | 
				
			||||||
        : undefined,
 | 
					          : undefined,
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  log.debug('parseMessage:', message);
 | 
					  log.debug('parseMessage:', message);
 | 
				
			||||||
  return message;
 | 
					  return message;
 | 
				
			||||||
@@ -188,6 +188,11 @@ export const LINETYPE = {
 | 
				
			|||||||
  SOLID_POINT: 24,
 | 
					  SOLID_POINT: 24,
 | 
				
			||||||
  DOTTED_POINT: 25,
 | 
					  DOTTED_POINT: 25,
 | 
				
			||||||
  AUTONUMBER: 26,
 | 
					  AUTONUMBER: 26,
 | 
				
			||||||
 | 
					  CRITICAL_START: 27,
 | 
				
			||||||
 | 
					  CRITICAL_OPTION: 28,
 | 
				
			||||||
 | 
					  CRITICAL_END: 29,
 | 
				
			||||||
 | 
					  BREAK_START: 30,
 | 
				
			||||||
 | 
					  BREAK_END: 31,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const ARROWTYPE = {
 | 
					export const ARROWTYPE = {
 | 
				
			||||||
@@ -429,6 +434,21 @@ export const apply = function (param) {
 | 
				
			|||||||
      case 'parEnd':
 | 
					      case 'parEnd':
 | 
				
			||||||
        addSignal(undefined, undefined, undefined, param.signalType);
 | 
					        addSignal(undefined, undefined, undefined, param.signalType);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					      case 'criticalStart':
 | 
				
			||||||
 | 
					        addSignal(undefined, undefined, param.criticalText, param.signalType);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 'option':
 | 
				
			||||||
 | 
					        addSignal(undefined, undefined, param.optionText, param.signalType);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 'criticalEnd':
 | 
				
			||||||
 | 
					        addSignal(undefined, undefined, undefined, param.signalType);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 'breakStart':
 | 
				
			||||||
 | 
					        addSignal(undefined, undefined, param.breakText, param.signalType);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 'breakEnd':
 | 
				
			||||||
 | 
					        addSignal(undefined, undefined, undefined, param.signalType);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -843,6 +843,80 @@ end`;
 | 
				
			|||||||
    expect(messages[7].from).toBe('Bob');
 | 
					    expect(messages[7].from).toBe('Bob');
 | 
				
			||||||
    expect(messages[8].type).toBe(parser.yy.LINETYPE.ALT_END);
 | 
					    expect(messages[8].type).toBe(parser.yy.LINETYPE.ALT_END);
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					  it('it should handle critical statements without options', function () {
 | 
				
			||||||
 | 
					    const str = `
 | 
				
			||||||
 | 
					sequenceDiagram
 | 
				
			||||||
 | 
					    critical Establish a connection to the DB
 | 
				
			||||||
 | 
					        Service-->DB: connect
 | 
				
			||||||
 | 
					    end`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    mermaidAPI.parse(str);
 | 
				
			||||||
 | 
					    const actors = parser.yy.getActors();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(actors.Service.description).toBe('Service');
 | 
				
			||||||
 | 
					    expect(actors.DB.description).toBe('DB');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const messages = parser.yy.getMessages();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(messages.length).toBe(3);
 | 
				
			||||||
 | 
					    expect(messages[0].type).toBe(parser.yy.LINETYPE.CRITICAL_START);
 | 
				
			||||||
 | 
					    expect(messages[1].from).toBe('Service');
 | 
				
			||||||
 | 
					    expect(messages[2].type).toBe(parser.yy.LINETYPE.CRITICAL_END);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  it('it should handle critical statements with options', function () {
 | 
				
			||||||
 | 
					    const str = `
 | 
				
			||||||
 | 
					sequenceDiagram
 | 
				
			||||||
 | 
					    critical Establish a connection to the DB
 | 
				
			||||||
 | 
					        Service-->DB: connect
 | 
				
			||||||
 | 
					    option Network timeout
 | 
				
			||||||
 | 
					        Service-->Service: Log error
 | 
				
			||||||
 | 
					    option Credentials rejected
 | 
				
			||||||
 | 
					        Service-->Service: Log different error
 | 
				
			||||||
 | 
					    end`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    mermaidAPI.parse(str);
 | 
				
			||||||
 | 
					    const actors = parser.yy.getActors();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(actors.Service.description).toBe('Service');
 | 
				
			||||||
 | 
					    expect(actors.DB.description).toBe('DB');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const messages = parser.yy.getMessages();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(messages.length).toBe(7);
 | 
				
			||||||
 | 
					    expect(messages[0].type).toBe(parser.yy.LINETYPE.CRITICAL_START);
 | 
				
			||||||
 | 
					    expect(messages[1].from).toBe('Service');
 | 
				
			||||||
 | 
					    expect(messages[2].type).toBe(parser.yy.LINETYPE.CRITICAL_OPTION);
 | 
				
			||||||
 | 
					    expect(messages[3].from).toBe('Service');
 | 
				
			||||||
 | 
					    expect(messages[4].type).toBe(parser.yy.LINETYPE.CRITICAL_OPTION);
 | 
				
			||||||
 | 
					    expect(messages[5].from).toBe('Service');
 | 
				
			||||||
 | 
					    expect(messages[6].type).toBe(parser.yy.LINETYPE.CRITICAL_END);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  it('it should handle break statements', function () {
 | 
				
			||||||
 | 
					    const str = `
 | 
				
			||||||
 | 
					sequenceDiagram
 | 
				
			||||||
 | 
					    Consumer-->API: Book something
 | 
				
			||||||
 | 
					    API-->BookingService: Start booking process
 | 
				
			||||||
 | 
					    break when the booking process fails
 | 
				
			||||||
 | 
					        API-->Consumer: show failure
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					    API-->BillingService: Start billing process`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    mermaidAPI.parse(str);
 | 
				
			||||||
 | 
					    const actors = parser.yy.getActors();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(actors.Consumer.description).toBe('Consumer');
 | 
				
			||||||
 | 
					    expect(actors.API.description).toBe('API');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const messages = parser.yy.getMessages();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(messages.length).toBe(6);
 | 
				
			||||||
 | 
					    expect(messages[0].from).toBe('Consumer');
 | 
				
			||||||
 | 
					    expect(messages[1].from).toBe('API');
 | 
				
			||||||
 | 
					    expect(messages[2].type).toBe(parser.yy.LINETYPE.BREAK_START);
 | 
				
			||||||
 | 
					    expect(messages[3].from).toBe('API');
 | 
				
			||||||
 | 
					    expect(messages[4].type).toBe(parser.yy.LINETYPE.BREAK_END);
 | 
				
			||||||
 | 
					    expect(messages[5].from).toBe('API');
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
  it('it should handle par statements a sequenceDiagram', function () {
 | 
					  it('it should handle par statements a sequenceDiagram', function () {
 | 
				
			||||||
    const str = `
 | 
					    const str = `
 | 
				
			||||||
sequenceDiagram
 | 
					sequenceDiagram
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -367,21 +367,21 @@ const drawMessage = function (diagram, msgModel, lineStarty) {
 | 
				
			|||||||
        .attr(
 | 
					        .attr(
 | 
				
			||||||
          'd',
 | 
					          'd',
 | 
				
			||||||
          'M ' +
 | 
					          'M ' +
 | 
				
			||||||
            startx +
 | 
					          startx +
 | 
				
			||||||
            ',' +
 | 
					          ',' +
 | 
				
			||||||
            lineStarty +
 | 
					          lineStarty +
 | 
				
			||||||
            ' C ' +
 | 
					          ' C ' +
 | 
				
			||||||
            (startx + 60) +
 | 
					          (startx + 60) +
 | 
				
			||||||
            ',' +
 | 
					          ',' +
 | 
				
			||||||
            (lineStarty - 10) +
 | 
					          (lineStarty - 10) +
 | 
				
			||||||
            ' ' +
 | 
					          ' ' +
 | 
				
			||||||
            (startx + 60) +
 | 
					          (startx + 60) +
 | 
				
			||||||
            ',' +
 | 
					          ',' +
 | 
				
			||||||
            (lineStarty + 30) +
 | 
					          (lineStarty + 30) +
 | 
				
			||||||
            ' ' +
 | 
					          ' ' +
 | 
				
			||||||
            startx +
 | 
					          startx +
 | 
				
			||||||
            ',' +
 | 
					          ',' +
 | 
				
			||||||
            (lineStarty + 20)
 | 
					          (lineStarty + 20)
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
@@ -764,6 +764,45 @@ export const draw = function (text, id) {
 | 
				
			|||||||
        if (msg.message.visible) parser.yy.enableSequenceNumbers();
 | 
					        if (msg.message.visible) parser.yy.enableSequenceNumbers();
 | 
				
			||||||
        else parser.yy.disableSequenceNumbers();
 | 
					        else parser.yy.disableSequenceNumbers();
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					      case parser.yy.LINETYPE.CRITICAL_START:
 | 
				
			||||||
 | 
					        adjustLoopHeightForWrap(
 | 
				
			||||||
 | 
					          loopWidths,
 | 
				
			||||||
 | 
					          msg,
 | 
				
			||||||
 | 
					          conf.boxMargin,
 | 
				
			||||||
 | 
					          conf.boxMargin + conf.boxTextMargin,
 | 
				
			||||||
 | 
					          (message) => bounds.newLoop(message)
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case parser.yy.LINETYPE.CRITICAL_OPTION:
 | 
				
			||||||
 | 
					        adjustLoopHeightForWrap(
 | 
				
			||||||
 | 
					          loopWidths,
 | 
				
			||||||
 | 
					          msg,
 | 
				
			||||||
 | 
					          conf.boxMargin + conf.boxTextMargin,
 | 
				
			||||||
 | 
					          conf.boxMargin,
 | 
				
			||||||
 | 
					          (message) => bounds.addSectionToLoop(message)
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case parser.yy.LINETYPE.CRITICAL_END:
 | 
				
			||||||
 | 
					        loopModel = bounds.endLoop();
 | 
				
			||||||
 | 
					        svgDraw.drawLoop(diagram, loopModel, 'critical', conf);
 | 
				
			||||||
 | 
					        bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos());
 | 
				
			||||||
 | 
					        bounds.models.addLoop(loopModel);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case parser.yy.LINETYPE.BREAK_START:
 | 
				
			||||||
 | 
					        adjustLoopHeightForWrap(
 | 
				
			||||||
 | 
					          loopWidths,
 | 
				
			||||||
 | 
					          msg,
 | 
				
			||||||
 | 
					          conf.boxMargin,
 | 
				
			||||||
 | 
					          conf.boxMargin + conf.boxTextMargin,
 | 
				
			||||||
 | 
					          (message) => bounds.newLoop(message)
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case parser.yy.LINETYPE.BREAK_END:
 | 
				
			||||||
 | 
					        loopModel = bounds.endLoop();
 | 
				
			||||||
 | 
					        svgDraw.drawLoop(diagram, loopModel, 'break', conf);
 | 
				
			||||||
 | 
					        bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos());
 | 
				
			||||||
 | 
					        bounds.models.addLoop(loopModel);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
      default:
 | 
					      default:
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
          // lastMsg = msg
 | 
					          // lastMsg = msg
 | 
				
			||||||
@@ -848,13 +887,13 @@ export const draw = function (text, id) {
 | 
				
			|||||||
  diagram.attr(
 | 
					  diagram.attr(
 | 
				
			||||||
    'viewBox',
 | 
					    'viewBox',
 | 
				
			||||||
    box.startx -
 | 
					    box.startx -
 | 
				
			||||||
      conf.diagramMarginX +
 | 
					    conf.diagramMarginX +
 | 
				
			||||||
      ' -' +
 | 
					    ' -' +
 | 
				
			||||||
      (conf.diagramMarginY + extraVertForTitle) +
 | 
					    (conf.diagramMarginY + extraVertForTitle) +
 | 
				
			||||||
      ' ' +
 | 
					    ' ' +
 | 
				
			||||||
      width +
 | 
					    width +
 | 
				
			||||||
      ' ' +
 | 
					    ' ' +
 | 
				
			||||||
      (height + extraVertForTitle)
 | 
					    (height + extraVertForTitle)
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  addSVGAccessibilityFields(parser.yy, diagram, id);
 | 
					  addSVGAccessibilityFields(parser.yy, diagram, id);
 | 
				
			||||||
@@ -1056,17 +1095,17 @@ const buildNoteModel = function (msg, actors) {
 | 
				
			|||||||
    noteModel.width = shouldWrap
 | 
					    noteModel.width = shouldWrap
 | 
				
			||||||
      ? Math.max(conf.width, textDimensions.width)
 | 
					      ? Math.max(conf.width, textDimensions.width)
 | 
				
			||||||
      : Math.max(
 | 
					      : Math.max(
 | 
				
			||||||
          actors[msg.from].width / 2 + actors[msg.to].width / 2,
 | 
					        actors[msg.from].width / 2 + actors[msg.to].width / 2,
 | 
				
			||||||
          textDimensions.width + 2 * conf.noteMargin
 | 
					        textDimensions.width + 2 * conf.noteMargin
 | 
				
			||||||
        );
 | 
					      );
 | 
				
			||||||
    noteModel.startx = startx + (actors[msg.from].width + conf.actorMargin) / 2;
 | 
					    noteModel.startx = startx + (actors[msg.from].width + conf.actorMargin) / 2;
 | 
				
			||||||
  } else if (msg.placement === parser.yy.PLACEMENT.LEFTOF) {
 | 
					  } else if (msg.placement === parser.yy.PLACEMENT.LEFTOF) {
 | 
				
			||||||
    noteModel.width = shouldWrap
 | 
					    noteModel.width = shouldWrap
 | 
				
			||||||
      ? Math.max(conf.width, textDimensions.width + 2 * conf.noteMargin)
 | 
					      ? Math.max(conf.width, textDimensions.width + 2 * conf.noteMargin)
 | 
				
			||||||
      : Math.max(
 | 
					      : Math.max(
 | 
				
			||||||
          actors[msg.from].width / 2 + actors[msg.to].width / 2,
 | 
					        actors[msg.from].width / 2 + actors[msg.to].width / 2,
 | 
				
			||||||
          textDimensions.width + 2 * conf.noteMargin
 | 
					        textDimensions.width + 2 * conf.noteMargin
 | 
				
			||||||
        );
 | 
					      );
 | 
				
			||||||
    noteModel.startx = startx - noteModel.width + (actors[msg.from].width - conf.actorMargin) / 2;
 | 
					    noteModel.startx = startx - noteModel.width + (actors[msg.from].width - conf.actorMargin) / 2;
 | 
				
			||||||
  } else if (msg.to === msg.from) {
 | 
					  } else if (msg.to === msg.from) {
 | 
				
			||||||
    textDimensions = utils.calculateTextDimensions(
 | 
					    textDimensions = utils.calculateTextDimensions(
 | 
				
			||||||
@@ -1166,6 +1205,8 @@ const calculateLoopBounds = function (messages, actors) {
 | 
				
			|||||||
      case parser.yy.LINETYPE.ALT_START:
 | 
					      case parser.yy.LINETYPE.ALT_START:
 | 
				
			||||||
      case parser.yy.LINETYPE.OPT_START:
 | 
					      case parser.yy.LINETYPE.OPT_START:
 | 
				
			||||||
      case parser.yy.LINETYPE.PAR_START:
 | 
					      case parser.yy.LINETYPE.PAR_START:
 | 
				
			||||||
 | 
					      case parser.yy.LINETYPE.CRITICAL_START:
 | 
				
			||||||
 | 
					      case parser.yy.LINETYPE.BREAK_START:
 | 
				
			||||||
        stack.push({
 | 
					        stack.push({
 | 
				
			||||||
          id: msg.id,
 | 
					          id: msg.id,
 | 
				
			||||||
          msg: msg.message,
 | 
					          msg: msg.message,
 | 
				
			||||||
@@ -1176,6 +1217,7 @@ const calculateLoopBounds = function (messages, actors) {
 | 
				
			|||||||
        break;
 | 
					        break;
 | 
				
			||||||
      case parser.yy.LINETYPE.ALT_ELSE:
 | 
					      case parser.yy.LINETYPE.ALT_ELSE:
 | 
				
			||||||
      case parser.yy.LINETYPE.PAR_AND:
 | 
					      case parser.yy.LINETYPE.PAR_AND:
 | 
				
			||||||
 | 
					      case parser.yy.LINETYPE.CRITICAL_OPTION:
 | 
				
			||||||
        if (msg.message) {
 | 
					        if (msg.message) {
 | 
				
			||||||
          current = stack.pop();
 | 
					          current = stack.pop();
 | 
				
			||||||
          loops[current.id] = current;
 | 
					          loops[current.id] = current;
 | 
				
			||||||
@@ -1187,31 +1229,33 @@ const calculateLoopBounds = function (messages, actors) {
 | 
				
			|||||||
      case parser.yy.LINETYPE.ALT_END:
 | 
					      case parser.yy.LINETYPE.ALT_END:
 | 
				
			||||||
      case parser.yy.LINETYPE.OPT_END:
 | 
					      case parser.yy.LINETYPE.OPT_END:
 | 
				
			||||||
      case parser.yy.LINETYPE.PAR_END:
 | 
					      case parser.yy.LINETYPE.PAR_END:
 | 
				
			||||||
 | 
					      case parser.yy.LINETYPE.CRITICAL_END:
 | 
				
			||||||
 | 
					      case parser.yy.LINETYPE.BREAK_END:
 | 
				
			||||||
        current = stack.pop();
 | 
					        current = stack.pop();
 | 
				
			||||||
        loops[current.id] = current;
 | 
					        loops[current.id] = current;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      case parser.yy.LINETYPE.ACTIVE_START:
 | 
					      case parser.yy.LINETYPE.ACTIVE_START:
 | 
				
			||||||
        {
 | 
					      {
 | 
				
			||||||
          const actorRect = actors[msg.from ? msg.from.actor : msg.to.actor];
 | 
					        const actorRect = actors[msg.from ? msg.from.actor : msg.to.actor];
 | 
				
			||||||
          const stackedSize = actorActivations(msg.from ? msg.from.actor : msg.to.actor).length;
 | 
					        const stackedSize = actorActivations(msg.from ? msg.from.actor : msg.to.actor).length;
 | 
				
			||||||
          const x =
 | 
					        const x =
 | 
				
			||||||
            actorRect.x + actorRect.width / 2 + ((stackedSize - 1) * conf.activationWidth) / 2;
 | 
					          actorRect.x + actorRect.width / 2 + ((stackedSize - 1) * conf.activationWidth) / 2;
 | 
				
			||||||
          const toAdd = {
 | 
					        const toAdd = {
 | 
				
			||||||
            startx: x,
 | 
					          startx: x,
 | 
				
			||||||
            stopx: x + conf.activationWidth,
 | 
					          stopx: x + conf.activationWidth,
 | 
				
			||||||
            actor: msg.from.actor,
 | 
					          actor: msg.from.actor,
 | 
				
			||||||
            enabled: true,
 | 
					          enabled: true,
 | 
				
			||||||
          };
 | 
					        };
 | 
				
			||||||
          bounds.activations.push(toAdd);
 | 
					        bounds.activations.push(toAdd);
 | 
				
			||||||
        }
 | 
					      }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      case parser.yy.LINETYPE.ACTIVE_END:
 | 
					      case parser.yy.LINETYPE.ACTIVE_END:
 | 
				
			||||||
        {
 | 
					      {
 | 
				
			||||||
          const lastActorActivationIdx = bounds.activations
 | 
					        const lastActorActivationIdx = bounds.activations
 | 
				
			||||||
            .map((a) => a.actor)
 | 
					          .map((a) => a.actor)
 | 
				
			||||||
            .lastIndexOf(msg.from.actor);
 | 
					          .lastIndexOf(msg.from.actor);
 | 
				
			||||||
          delete bounds.activations.splice(lastActorActivationIdx, 1)[0];
 | 
					        delete bounds.activations.splice(lastActorActivationIdx, 1)[0];
 | 
				
			||||||
        }
 | 
					      }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    const isNote = msg.placement !== undefined;
 | 
					    const isNote = msg.placement !== undefined;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user