parent
6011de1c4a
commit
c14a87e5ad
File diff suppressed because one or more lines are too long
|
@ -1,10 +1,10 @@
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'bpmn';
|
font-family: 'bpmn';
|
||||||
src: url('../font/bpmn.eot?37618458');
|
src: url('../font/bpmn.eot?84549978');
|
||||||
src: url('../font/bpmn.eot?37618458#iefix') format('embedded-opentype'),
|
src: url('../font/bpmn.eot?84549978#iefix') format('embedded-opentype'),
|
||||||
url('../font/bpmn.woff?37618458') format('woff'),
|
url('../font/bpmn.woff?84549978') format('woff'),
|
||||||
url('../font/bpmn.ttf?37618458') format('truetype'),
|
url('../font/bpmn.ttf?84549978') format('truetype'),
|
||||||
url('../font/bpmn.svg?37618458#bpmn') format('svg');
|
url('../font/bpmn.svg?84549978#bpmn') format('svg');
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'bpmn';
|
font-family: 'bpmn';
|
||||||
src: url('../font/bpmn.svg?37618458#bpmn') format('svg');
|
src: url('../font/bpmn.svg?84549978#bpmn') format('svg');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
@ -150,3 +150,4 @@
|
||||||
.icon-edit-default:before { content: '\e85d'; } /* '' */
|
.icon-edit-default:before { content: '\e85d'; } /* '' */
|
||||||
.icon-edit-navigation:before { content: '\e85e'; } /* '' */
|
.icon-edit-navigation:before { content: '\e85e'; } /* '' */
|
||||||
.icon-edit-space-tool:before { content: '\e85f'; } /* '' */
|
.icon-edit-space-tool:before { content: '\e85f'; } /* '' */
|
||||||
|
.icon-connection-multi:before { content: '\e860'; } /* '' */
|
Binary file not shown.
|
@ -102,6 +102,7 @@
|
||||||
<glyph glyph-name="edit-default" unicode="" d="m14 839l0-1 0-1 0 0 35-600 0 0 0 0 133 170 120-219 0 0 1 0 95 56-123 215 202 18-1 0 3 0-465 362z m1-2l461-359-1 0-460 358 0 1z m259-379l123-213 0-1-124 214 1 0z m196-59l0-139 40 0 0 99 80 0 19 0 0 40-19 0-120 0z m200 0l0-40 120 0 0 40-120 0z m180 0l0-40 100 0 0-100 40 0 0 140-140 0z m-380-220l0-120 40 0 0 120-40 0z m480 0l0-120 40 0 0 120-40 0z m0-180l0-100-100 0 0-40 140 0 0 140-40 0z m-480-1l0-140 140 0 0 40-100 0 0 100-40 0z m200-100l0-40 120 0 0 40-120 0z" horiz-adv-x="1000" />
|
<glyph glyph-name="edit-default" unicode="" d="m14 839l0-1 0-1 0 0 35-600 0 0 0 0 133 170 120-219 0 0 1 0 95 56-123 215 202 18-1 0 3 0-465 362z m1-2l461-359-1 0-460 358 0 1z m259-379l123-213 0-1-124 214 1 0z m196-59l0-139 40 0 0 99 80 0 19 0 0 40-19 0-120 0z m200 0l0-40 120 0 0 40-120 0z m180 0l0-40 100 0 0-100 40 0 0 140-140 0z m-380-220l0-120 40 0 0 120-40 0z m480 0l0-120 40 0 0 120-40 0z m0-180l0-100-100 0 0-40 140 0 0 140-40 0z m-480-1l0-140 140 0 0 40-100 0 0 100-40 0z m200-100l0-40 120 0 0 40-120 0z" horiz-adv-x="1000" />
|
||||||
<glyph glyph-name="edit-navigation" unicode="" d="m506 826l-223-240 6 0 1 0 193 0 0-219-214 0 0 200-5-4-236-206 241-230 0 200 214 0 0-211-200 0 4-4 220-236 216 235-1 0 0 2 0 3-199 0 0 211 216 0 0-200 240 210-2 2-238 228 0-200-216 0 0 219 200 0-4 4-213 236z" horiz-adv-x="1000" />
|
<glyph glyph-name="edit-navigation" unicode="" d="m506 826l-223-240 6 0 1 0 193 0 0-219-214 0 0 200-5-4-236-206 241-230 0 200 214 0 0-211-200 0 4-4 220-236 216 235-1 0 0 2 0 3-199 0 0 211 216 0 0-200 240 210-2 2-238 228 0-200-216 0 0 219 200 0-4 4-213 236z" horiz-adv-x="1000" />
|
||||||
<glyph glyph-name="edit-space-tool" unicode="" d="m366 810l0-920 38 0 0 920-38 0z m233 0l0-920 38 0 0 920-38 0z m-394-297l-164-163 164-163 0 111 93 0 0 105-29 0-64 0 0 110z m595 0l0-108-94-1 0-29 0-77 94 0 0-111 163 163-163 163z" horiz-adv-x="1000" />
|
<glyph glyph-name="edit-space-tool" unicode="" d="m366 810l0-920 38 0 0 920-38 0z m233 0l0-920 38 0 0 920-38 0z m-394-297l-164-163 164-163 0 111 93 0 0 105-29 0-64 0 0 110z m595 0l0-108-94-1 0-29 0-77 94 0 0-111 163 163-163 163z" horiz-adv-x="1000" />
|
||||||
|
<glyph glyph-name="connection-multi" unicode="" d="m916 798l-410-109 64-95-486-327 25-38 486 328 62-92 259 333 0 0z m0-328l-411-109 151-224 260 333 0 0z m-409-245l-63-43 25-37 63 42-25 38z m-126-85l-62-42 25-38 62 43-25 37z m-133-90l-63-43 25-37 63 43-25 37z m-126-85l-38-26 25-37 38 26-25 37z" horiz-adv-x="1000" />
|
||||||
</font>
|
</font>
|
||||||
</defs>
|
</defs>
|
||||||
</svg>
|
</svg>
|
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 130 KiB |
Binary file not shown.
Binary file not shown.
|
@ -116,15 +116,7 @@ ContextPadProvider.prototype.getContextPadEntries = function(element) {
|
||||||
'append.gateway': appendAction('bpmn:ExclusiveGateway', 'icon-gateway-xor'),
|
'append.gateway': appendAction('bpmn:ExclusiveGateway', 'icon-gateway-xor'),
|
||||||
'append.append-task': appendAction('bpmn:Task', 'icon-task'),
|
'append.append-task': appendAction('bpmn:Task', 'icon-task'),
|
||||||
'append.intermediate-event': appendAction('bpmn:IntermediateThrowEvent',
|
'append.intermediate-event': appendAction('bpmn:IntermediateThrowEvent',
|
||||||
'icon-intermediate-event-none'),
|
'icon-intermediate-event-none')
|
||||||
'connect': {
|
|
||||||
group: 'connect',
|
|
||||||
className: 'icon-connection',
|
|
||||||
action: {
|
|
||||||
click: startConnect,
|
|
||||||
dragstart: startConnect
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,10 +147,6 @@ ContextPadProvider.prototype.getContextPadEntries = function(element) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
assign(actions, {
|
|
||||||
'append.text-annotation': appendAction('bpmn:TextAnnotation', 'icon-text-annotation')
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// Replace menu entry
|
// Replace menu entry
|
||||||
if (!bpmnElement.$instanceOf('bpmn:SubProcess')) {
|
if (!bpmnElement.$instanceOf('bpmn:SubProcess')) {
|
||||||
|
@ -176,6 +164,23 @@ ContextPadProvider.prototype.getContextPadEntries = function(element) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bpmnElement.$instanceOf('bpmn:FlowNode') ||
|
||||||
|
bpmnElement.$instanceOf('bpmn:InteractionNode')) {
|
||||||
|
|
||||||
|
assign(actions, {
|
||||||
|
'append.text-annotation': appendAction('bpmn:TextAnnotation', 'icon-text-annotation'),
|
||||||
|
|
||||||
|
'connect': {
|
||||||
|
group: 'connect',
|
||||||
|
className: 'icon-connection-multi',
|
||||||
|
action: {
|
||||||
|
click: startConnect,
|
||||||
|
dragstart: startConnect
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Delete Element Entry
|
// Delete Element Entry
|
||||||
assign(actions, {
|
assign(actions, {
|
||||||
'delete': {
|
'delete': {
|
||||||
|
|
|
@ -15,6 +15,7 @@ BpmnFactory.$inject = [ 'moddle' ];
|
||||||
BpmnFactory.prototype._needsId = function(element) {
|
BpmnFactory.prototype._needsId = function(element) {
|
||||||
return element.$instanceOf('bpmn:RootElement') ||
|
return element.$instanceOf('bpmn:RootElement') ||
|
||||||
element.$instanceOf('bpmn:FlowElement') ||
|
element.$instanceOf('bpmn:FlowElement') ||
|
||||||
|
element.$instanceOf('bpmn:MessageFlow') ||
|
||||||
element.$instanceOf('bpmn:Artifact') ||
|
element.$instanceOf('bpmn:Artifact') ||
|
||||||
element.$instanceOf('bpmn:Participant') ||
|
element.$instanceOf('bpmn:Participant') ||
|
||||||
element.$instanceOf('bpmn:Process') ||
|
element.$instanceOf('bpmn:Process') ||
|
||||||
|
|
|
@ -208,6 +208,7 @@ BpmnUpdater.prototype.updateSemanticParent = function(businessObject, newParent)
|
||||||
}
|
}
|
||||||
|
|
||||||
containment = 'flowElements';
|
containment = 'flowElements';
|
||||||
|
|
||||||
} else
|
} else
|
||||||
|
|
||||||
if (businessObject.$instanceOf('bpmn:Artifact')) {
|
if (businessObject.$instanceOf('bpmn:Artifact')) {
|
||||||
|
@ -226,7 +227,12 @@ BpmnUpdater.prototype.updateSemanticParent = function(businessObject, newParent)
|
||||||
}
|
}
|
||||||
|
|
||||||
containment = 'artifacts';
|
containment = 'artifacts';
|
||||||
}
|
} else
|
||||||
|
|
||||||
|
if (businessObject.$instanceOf('bpmn:MessageFlow')) {
|
||||||
|
containment = 'messageFlows';
|
||||||
|
|
||||||
|
} else
|
||||||
|
|
||||||
if (businessObject.$instanceOf('bpmn:Participant')) {
|
if (businessObject.$instanceOf('bpmn:Participant')) {
|
||||||
containment = 'participants';
|
containment = 'participants';
|
||||||
|
|
|
@ -14,14 +14,17 @@ var UpdatePropertiesHandler = require('./cmd/UpdatePropertiesHandler'),
|
||||||
* @param {EventBus} eventBus
|
* @param {EventBus} eventBus
|
||||||
* @param {ElementFactory} elementFactory
|
* @param {ElementFactory} elementFactory
|
||||||
* @param {CommandStack} commandStack
|
* @param {CommandStack} commandStack
|
||||||
|
* @param {BpmnRules} bpmnRules
|
||||||
*/
|
*/
|
||||||
function Modeling(eventBus, elementFactory, commandStack) {
|
function Modeling(eventBus, elementFactory, commandStack, bpmnRules) {
|
||||||
BaseModeling.call(this, eventBus, elementFactory, commandStack);
|
BaseModeling.call(this, eventBus, elementFactory, commandStack);
|
||||||
|
|
||||||
|
this._bpmnRules = bpmnRules;
|
||||||
}
|
}
|
||||||
|
|
||||||
inherits(Modeling, BaseModeling);
|
inherits(Modeling, BaseModeling);
|
||||||
|
|
||||||
Modeling.$inject = [ 'eventBus', 'elementFactory', 'commandStack' ];
|
Modeling.$inject = [ 'eventBus', 'elementFactory', 'commandStack', 'bpmnRules' ];
|
||||||
|
|
||||||
module.exports = Modeling;
|
module.exports = Modeling;
|
||||||
|
|
||||||
|
@ -44,17 +47,19 @@ Modeling.prototype.updateLabel = function(element, newLabel) {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var getSharedParent = require('./ModelingUtil').getSharedParent;
|
||||||
|
|
||||||
Modeling.prototype.connect = function(source, target, attrs) {
|
Modeling.prototype.connect = function(source, target, attrs) {
|
||||||
|
|
||||||
var sourceBo = source.businessObject,
|
var bpmnRules = this._bpmnRules;
|
||||||
targetBo = target.businessObject;
|
|
||||||
|
|
||||||
if (!attrs) {
|
if (!attrs) {
|
||||||
if (sourceBo.$instanceOf('bpmn:FlowNode') &&
|
if (bpmnRules.canConnectMessageFlow(source, target)) {
|
||||||
targetBo.$instanceOf('bpmn:FlowNode') &&
|
attrs = {
|
||||||
!sourceBo.$instanceOf('bpmn:EndEvent') &&
|
type: 'bpmn:MessageFlow'
|
||||||
!targetBo.$instanceOf('bpmn:StartEvent')) {
|
};
|
||||||
|
} else
|
||||||
|
if (bpmnRules.canConnectSequenceFlow(source, target)) {
|
||||||
attrs = {
|
attrs = {
|
||||||
type: 'bpmn:SequenceFlow'
|
type: 'bpmn:SequenceFlow'
|
||||||
};
|
};
|
||||||
|
@ -65,7 +70,7 @@ Modeling.prototype.connect = function(source, target, attrs) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.createConnection(source, target, attrs, source.parent);
|
return this.createConnection(source, target, attrs, getSharedParent(source, target));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var find = require('lodash/collection/find');
|
||||||
|
|
||||||
|
|
||||||
|
function getParents(element) {
|
||||||
|
|
||||||
|
var parents = [];
|
||||||
|
|
||||||
|
while (element) {
|
||||||
|
element = element.parent;
|
||||||
|
|
||||||
|
if (element) {
|
||||||
|
parents.push(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return parents;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.getParents = getParents;
|
||||||
|
|
||||||
|
|
||||||
|
function getSharedParent(a, b) {
|
||||||
|
|
||||||
|
var parentsA = getParents(a),
|
||||||
|
parentsB = getParents(b);
|
||||||
|
|
||||||
|
return find(parentsA, function(parent) {
|
||||||
|
return parentsB.indexOf(parent) !== -1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.getSharedParent = getSharedParent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is an element of the given BPMN type?
|
||||||
|
*
|
||||||
|
* @param {djs.model.Base|ModdleElement} element
|
||||||
|
* @param {String} type
|
||||||
|
* @return {Boolean}
|
||||||
|
*/
|
||||||
|
function is(element, type) {
|
||||||
|
var bo = getBusinessObject(element);
|
||||||
|
|
||||||
|
return bo && bo.$instanceOf(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.is = is;
|
||||||
|
|
||||||
|
|
||||||
|
function getBusinessObject(element) {
|
||||||
|
return (element && element.businessObject) || element;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.getBusinessObject = getBusinessObject;
|
|
@ -0,0 +1,374 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var groupBy = require('lodash/collection/groupBy'),
|
||||||
|
size = require('lodash/collection/size'),
|
||||||
|
find = require('lodash/collection/find'),
|
||||||
|
inherits = require('inherits');
|
||||||
|
|
||||||
|
var getParents = require('../ModelingUtil').getParents,
|
||||||
|
is = require('../ModelingUtil').is,
|
||||||
|
getBusinessObject = require('../ModelingUtil').getBusinessObject;
|
||||||
|
|
||||||
|
|
||||||
|
var RuleProvider = require('diagram-js/lib/features/rules/RuleProvider');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BPMN specific modeling rule
|
||||||
|
*/
|
||||||
|
function BpmnRules(eventBus) {
|
||||||
|
RuleProvider.call(this, eventBus);
|
||||||
|
}
|
||||||
|
|
||||||
|
inherits(BpmnRules, RuleProvider);
|
||||||
|
|
||||||
|
BpmnRules.$inject = [ 'eventBus' ];
|
||||||
|
|
||||||
|
module.exports = BpmnRules;
|
||||||
|
|
||||||
|
BpmnRules.prototype.init = function() {
|
||||||
|
|
||||||
|
this.addRule('connection.create', function(context) {
|
||||||
|
var source = context.source,
|
||||||
|
target = context.target;
|
||||||
|
|
||||||
|
return canConnect(source, target);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.addRule('connection.reconnectStart', function(context) {
|
||||||
|
|
||||||
|
var connection = context.connection,
|
||||||
|
source = context.hover || context.source,
|
||||||
|
target = connection.target;
|
||||||
|
|
||||||
|
return canConnect(source, target, connection);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.addRule('connection.reconnectEnd', function(context) {
|
||||||
|
|
||||||
|
var connection = context.connection,
|
||||||
|
source = connection.source,
|
||||||
|
target = context.hover || context.target;
|
||||||
|
|
||||||
|
return canConnect(source, target, connection);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.addRule('connection.updateWaypoints', function(context) {
|
||||||
|
// OK! but visually ignore
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.addRule('shape.resize', function(context) {
|
||||||
|
|
||||||
|
var shape = context.shape,
|
||||||
|
newBounds = context.newBounds;
|
||||||
|
|
||||||
|
return canResize(shape, newBounds);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.addRule('shapes.move', function(context) {
|
||||||
|
|
||||||
|
var target = context.newParent,
|
||||||
|
shapes = context.shapes;
|
||||||
|
|
||||||
|
return canMove(shapes, target);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.addRule([ 'shape.create', 'shape.append' ], function(context) {
|
||||||
|
var target = context.parent,
|
||||||
|
shape = context.shape,
|
||||||
|
source = context.source;
|
||||||
|
|
||||||
|
return canCreate(shape, target, source);
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
BpmnRules.prototype.canConnectMessageFlow = canConnectMessageFlow;
|
||||||
|
|
||||||
|
BpmnRules.prototype.canConnectSequenceFlow = canConnectSequenceFlow;
|
||||||
|
|
||||||
|
BpmnRules.prototype.canConnectAssociation = canConnectAssociation;
|
||||||
|
|
||||||
|
BpmnRules.prototype.canMove = canMove;
|
||||||
|
|
||||||
|
BpmnRules.prototype.canDrop = canDrop;
|
||||||
|
|
||||||
|
BpmnRules.prototype.canCreate = canCreate;
|
||||||
|
|
||||||
|
BpmnRules.prototype.canConnect = canConnect;
|
||||||
|
|
||||||
|
BpmnRules.prototype.canResize = canResize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility functions for rule checking
|
||||||
|
*/
|
||||||
|
|
||||||
|
function nonExistantOrLabel(element) {
|
||||||
|
return !element || isLabel(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isSame(a, b) {
|
||||||
|
return a === b;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOrganizationalParent(element) {
|
||||||
|
|
||||||
|
var bo = getBusinessObject(element);
|
||||||
|
|
||||||
|
while (bo && !is(bo, 'bpmn:Process')) {
|
||||||
|
if (is(bo, 'bpmn:Participant')) {
|
||||||
|
return bo.processRef || bo;
|
||||||
|
}
|
||||||
|
|
||||||
|
bo = bo.$parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bo;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isSameOrganization(a, b) {
|
||||||
|
var parentA = getOrganizationalParent(a),
|
||||||
|
parentB = getOrganizationalParent(b);
|
||||||
|
|
||||||
|
return parentA === parentB;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isMessageFlowSource(element) {
|
||||||
|
return is(element, 'bpmn:InteractionNode') && (
|
||||||
|
!is(element, 'bpmn:Event') || is(element, 'bpmn:ThrowEvent')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isMessageFlowTarget(element) {
|
||||||
|
return is(element, 'bpmn:InteractionNode') && (
|
||||||
|
!is(element, 'bpmn:Event') || is(element, 'bpmn:CatchEvent')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getScopeParent(element) {
|
||||||
|
|
||||||
|
var bo = getBusinessObject(element);
|
||||||
|
|
||||||
|
if (is(bo, 'bpmn:Participant')) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (bo) {
|
||||||
|
bo = bo.$parent;
|
||||||
|
|
||||||
|
if (is(bo, 'bpmn:FlowElementsContainer')) {
|
||||||
|
return bo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bo;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isExpanded(element) {
|
||||||
|
var bo = getBusinessObject(element);
|
||||||
|
return bo.di.isExpanded;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isSameScope(a, b) {
|
||||||
|
var scopeParentA = getScopeParent(a),
|
||||||
|
scopeParentB = getScopeParent(b);
|
||||||
|
|
||||||
|
return scopeParentA && (scopeParentA === scopeParentB);
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasEventDefinition(element, eventDefinition) {
|
||||||
|
var bo = getBusinessObject(element);
|
||||||
|
|
||||||
|
return find(bo.eventDefinitions || [], function(definition) {
|
||||||
|
return is(definition, eventDefinition);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function isSequenceFlowSource(element) {
|
||||||
|
return is(element, 'bpmn:FlowNode') && !is(element, 'bpmn:EndEvent') && !(
|
||||||
|
is(element, 'bpmn:IntermediateThrowEvent') &&
|
||||||
|
hasEventDefinition(element, 'bpmn:LinkEventDefinition')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isSequenceFlowTarget(element) {
|
||||||
|
return is(element, 'bpmn:FlowNode') && !is(element, 'bpmn:StartEvent') && !(
|
||||||
|
is(element, 'bpmn:IntermediateCatchEvent') &&
|
||||||
|
hasEventDefinition(element, 'bpmn:LinkEventDefinition')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isEventBasedTarget(element) {
|
||||||
|
return is(element, 'bpmn:ReceiveTask') || (
|
||||||
|
is(element, 'bpmn:IntermediateCatchEvent') && (
|
||||||
|
hasEventDefinition(element, 'bpmn:MessageEventDefinition') ||
|
||||||
|
hasEventDefinition(element, 'bpmn:TimerEventDefinition') ||
|
||||||
|
hasEventDefinition(element, 'bpmn:ConditionalEventDefinition') ||
|
||||||
|
hasEventDefinition(element, 'bpmn:SignalEventDefinition')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isLabel(element) {
|
||||||
|
return element.labelTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isConnection(element) {
|
||||||
|
return element.waypoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isParent(possibleParent, element) {
|
||||||
|
var allParents = getParents(element);
|
||||||
|
return allParents.indexOf(possibleParent) !== -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function canConnect(source, target, connection) {
|
||||||
|
|
||||||
|
if (nonExistantOrLabel(source) || nonExistantOrLabel(target)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// See https://github.com/bpmn-io/bpmn-js/issues/178
|
||||||
|
// as a workround we disallow connections with same
|
||||||
|
// target and source element.
|
||||||
|
// This rule must be removed if a auto layout for this
|
||||||
|
// connections is implemented.
|
||||||
|
if (isSame(source, target)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (canConnectMessageFlow(source, target) ||
|
||||||
|
canConnectSequenceFlow(source, target)) {
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is(connection, 'bpmn:Association')) {
|
||||||
|
return canConnectAssociation(source, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can an element be dropped into the target element
|
||||||
|
*
|
||||||
|
* @return {Boolean}
|
||||||
|
*/
|
||||||
|
function canDrop(element, target) {
|
||||||
|
|
||||||
|
// can move labels everywhere
|
||||||
|
if (isLabel(element) && !isConnection(target)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// allow to create new participants on
|
||||||
|
// on existing collaboration and process diagrams
|
||||||
|
if (is(element, 'bpmn:Participant')) {
|
||||||
|
return is(target, 'bpmn:Process') || is(target, 'bpmn:Collaboration');
|
||||||
|
}
|
||||||
|
|
||||||
|
// drop flow elements onto flow element containers
|
||||||
|
// and participants
|
||||||
|
if (is(element, 'bpmn:FlowElement')) {
|
||||||
|
if (is(target, 'bpmn:FlowElementsContainer')) {
|
||||||
|
return isExpanded(target) !== false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return is(target, 'bpmn:Participant');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is(element, 'bpmn:Artifact')) {
|
||||||
|
return is(target, 'bpmn:Collaboration') ||
|
||||||
|
is(target, 'bpmn:Participant') ||
|
||||||
|
is(target, 'bpmn:Process');
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function canMove(elements, target) {
|
||||||
|
|
||||||
|
// only move if they have the same parent
|
||||||
|
var sameParent = size(groupBy(elements, function(s) { return s.parent && s.parent.id; })) === 1;
|
||||||
|
|
||||||
|
if (!sameParent) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!target) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return elements.every(function(element) {
|
||||||
|
return canDrop(element, target);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function canCreate(shape, target, source) {
|
||||||
|
|
||||||
|
if (!target) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isLabel(target)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isSame(source, target)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure we do not drop the element
|
||||||
|
// into source
|
||||||
|
if (source && isParent(source, target)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return canDrop(shape, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
function canResize(shape, newBounds) {
|
||||||
|
if (is(shape, 'bpmn:SubProcess')) {
|
||||||
|
return isExpanded(shape) && (
|
||||||
|
!newBounds || (newBounds.width >= 100 && newBounds.height >= 80)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is(shape, 'bpmn:Participant')) {
|
||||||
|
return !newBounds || (newBounds.width >= 100 && newBounds.height >= 80);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is(shape, 'bpmn:TextAnnotation')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function canConnectAssociation(source, target) {
|
||||||
|
|
||||||
|
// do not connect connections
|
||||||
|
if (isConnection(source) || isConnection(target)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// connect if different parent
|
||||||
|
return !isParent(target, source) &&
|
||||||
|
!isParent(source, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
function canConnectMessageFlow(source, target) {
|
||||||
|
|
||||||
|
return isMessageFlowSource(source) &&
|
||||||
|
isMessageFlowTarget(target) &&
|
||||||
|
!isSameOrganization(source, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
function canConnectSequenceFlow(source, target) {
|
||||||
|
|
||||||
|
return isSequenceFlowSource(source) &&
|
||||||
|
isSequenceFlowTarget(target) &&
|
||||||
|
isSameScope(source, target) &&
|
||||||
|
!(is(source, 'bpmn:EventBasedGateway') && !isEventBasedTarget(target));
|
||||||
|
}
|
|
@ -1,292 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var groupBy = require('lodash/collection/groupBy'),
|
|
||||||
size = require('lodash/collection/size'),
|
|
||||||
forEach = require('lodash/collection/forEach'),
|
|
||||||
inherits = require('inherits');
|
|
||||||
|
|
||||||
var RuleProvider = require('diagram-js/lib/features/rules/RuleProvider');
|
|
||||||
|
|
||||||
|
|
||||||
function ModelingRules(eventBus) {
|
|
||||||
RuleProvider.call(this, eventBus);
|
|
||||||
}
|
|
||||||
|
|
||||||
inherits(ModelingRules, RuleProvider);
|
|
||||||
|
|
||||||
ModelingRules.$inject = [ 'eventBus' ];
|
|
||||||
|
|
||||||
module.exports = ModelingRules;
|
|
||||||
|
|
||||||
ModelingRules.prototype.init = function() {
|
|
||||||
|
|
||||||
function nonExistantOrLabel(element) {
|
|
||||||
return !element || element.labelTarget;
|
|
||||||
}
|
|
||||||
|
|
||||||
function isSame(a, b) {
|
|
||||||
return a === b;
|
|
||||||
}
|
|
||||||
|
|
||||||
function isEventConnectionInvalid(source, target) {
|
|
||||||
|
|
||||||
var sourceBo = source.businessObject,
|
|
||||||
targetBo = target.businessObject;
|
|
||||||
|
|
||||||
// handle start and end event cases
|
|
||||||
var startEventCheck = targetBo.$instanceOf('bpmn:StartEvent') ||
|
|
||||||
sourceBo.$instanceOf('bpmn:EndEvent');
|
|
||||||
|
|
||||||
// handle event based gateway cases
|
|
||||||
var eventBasedGatewayCheck = false;
|
|
||||||
|
|
||||||
// Ensure target of event based gateway is one of:
|
|
||||||
// receive task, receiving message, timer, signal, condition event
|
|
||||||
if (sourceBo.$instanceOf('bpmn:EventBasedGateway')) {
|
|
||||||
|
|
||||||
eventBasedGatewayCheck = true;
|
|
||||||
|
|
||||||
if (targetBo.$instanceOf('bpmn:ReceiveTask')) {
|
|
||||||
eventBasedGatewayCheck = false;
|
|
||||||
} else if (isEventType(targetBo, 'bpmn:IntermediateCatchEvent', 'bpmn:MessageEventDefinition') ||
|
|
||||||
isEventType(targetBo, 'bpmn:IntermediateCatchEvent', 'bpmn:TimerEventDefinition') ||
|
|
||||||
isEventType(targetBo, 'bpmn:IntermediateCatchEvent', 'bpmn:ConditionalEventDefinition') ||
|
|
||||||
isEventType(targetBo, 'bpmn:IntermediateCatchEvent', 'bpmn:SignalEventDefinition')) {
|
|
||||||
|
|
||||||
eventBasedGatewayCheck = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle link event
|
|
||||||
var linkEventCheck = false;
|
|
||||||
if (isEventType(targetBo, 'bpmn:IntermediateCatchEvent', 'bpmn:LinkEventDefinition') ||
|
|
||||||
isEventType(sourceBo, 'bpmn:IntermediateThrowEvent', 'bpmn:LinkEventDefinition')) {
|
|
||||||
linkEventCheck = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return startEventCheck || eventBasedGatewayCheck || linkEventCheck;
|
|
||||||
}
|
|
||||||
|
|
||||||
function isEventType(eventBo, type, definition) {
|
|
||||||
|
|
||||||
var isType = eventBo.$instanceOf(type);
|
|
||||||
var isDefinition = false;
|
|
||||||
|
|
||||||
var definitions = eventBo.eventDefinitions || [];
|
|
||||||
forEach(definitions, function(def) {
|
|
||||||
if (def.$type === definition) {
|
|
||||||
isDefinition = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return isType && isDefinition;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// rules
|
|
||||||
function canConnect(source, target, connection) {
|
|
||||||
|
|
||||||
if (nonExistantOrLabel(source) || nonExistantOrLabel(target)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// See https://github.com/bpmn-io/bpmn-js/issues/178
|
|
||||||
// as a workround we disallow connections with same
|
|
||||||
// target and source element.
|
|
||||||
// This rule must be removed if a auto layout for this
|
|
||||||
// connections is implemented.
|
|
||||||
if (isSame(source, target)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// allow all associations between elements
|
|
||||||
if (connection && connection.businessObject.$instanceOf('bpmn:Association')) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// only move between the same parent
|
|
||||||
if (!isSame(source.parent, target.parent)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var sourceBo = source.businessObject,
|
|
||||||
targetBo = target.businessObject,
|
|
||||||
connectionBo = connection && connection.businessObject;
|
|
||||||
|
|
||||||
if (connectionBo && connectionBo.$instanceOf('bpmn:SequenceFlow')) {
|
|
||||||
|
|
||||||
if (!sourceBo.$instanceOf('bpmn:FlowNode') ||
|
|
||||||
!targetBo.$instanceOf('bpmn:FlowNode') ||
|
|
||||||
sourceBo.$instanceOf('bpmn:EndEvent') ||
|
|
||||||
targetBo.$instanceOf('bpmn:StartEvent')) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do not allow incoming connections on StartEvents
|
|
||||||
// and outgoing connections on EndEvents
|
|
||||||
if (isEventConnectionInvalid(source, target)) {
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (sourceBo.$instanceOf('bpmn:FlowNode') ||
|
|
||||||
sourceBo.$instanceOf('bpmn:TextAnnotation')) &&
|
|
||||||
(targetBo.$instanceOf('bpmn:FlowNode') ||
|
|
||||||
targetBo.$instanceOf('bpmn:TextAnnotation'));
|
|
||||||
}
|
|
||||||
|
|
||||||
this.addRule('connection.create', function(context) {
|
|
||||||
var source = context.source,
|
|
||||||
target = context.target;
|
|
||||||
|
|
||||||
return canConnect(source, target);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.addRule('connection.reconnectStart', function(context) {
|
|
||||||
|
|
||||||
var connection = context.connection,
|
|
||||||
source = context.hover || context.source,
|
|
||||||
target = connection.target;
|
|
||||||
|
|
||||||
return canConnect(source, target, connection);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.addRule('connection.reconnectEnd', function(context) {
|
|
||||||
|
|
||||||
var connection = context.connection,
|
|
||||||
source = connection.source,
|
|
||||||
target = context.hover || context.target;
|
|
||||||
|
|
||||||
return canConnect(source, target, connection);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.addRule('connection.updateWaypoints', function(context) {
|
|
||||||
// OK! but visually ignore
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.addRule('shape.resize', function(context) {
|
|
||||||
|
|
||||||
var shape = context.shape,
|
|
||||||
newBounds = context.newBounds,
|
|
||||||
bo = shape.businessObject;
|
|
||||||
|
|
||||||
if (bo.$instanceOf('bpmn:SubProcess') && bo.di.isExpanded) {
|
|
||||||
return !newBounds || (newBounds.width >= 100 && newBounds.height >= 80);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bo.$instanceOf('bpmn:Participant')) {
|
|
||||||
return !newBounds || (newBounds.width >= 100 && newBounds.height >= 80);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Can an element be dropped into the target element
|
|
||||||
*
|
|
||||||
* @return {Boolean}
|
|
||||||
*/
|
|
||||||
function canDrop(businessObject, targetBusinessObject, targetDi) {
|
|
||||||
|
|
||||||
// allow to create new participants on
|
|
||||||
// on existing collaboration and process diagrams
|
|
||||||
if (businessObject.$instanceOf('bpmn:Participant') &&
|
|
||||||
(targetBusinessObject.$instanceOf('bpmn:Process') ||
|
|
||||||
targetBusinessObject.$instanceOf('bpmn:Collaboration'))) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (businessObject.$instanceOf('bpmn:FlowElement') &&
|
|
||||||
targetBusinessObject.$instanceOf('bpmn:FlowElementsContainer')) {
|
|
||||||
|
|
||||||
// may not drop into collapsed sub processes
|
|
||||||
if (targetDi.isExpanded === false) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (targetBusinessObject.$instanceOf('bpmn:Collaboration') &&
|
|
||||||
!businessObject.$instanceOf('bpmn:Participant') &&
|
|
||||||
!targetBusinessObject.participants.length) {
|
|
||||||
|
|
||||||
// TODO: transform collaboration into process
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (businessObject.$instanceOf('bpmn:FlowElement') &&
|
|
||||||
targetBusinessObject.$instanceOf('bpmn:Participant') &&
|
|
||||||
targetBusinessObject.processRef) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (businessObject.$instanceOf('bpmn:TextAnnotation') &&
|
|
||||||
(targetBusinessObject.$instanceOf('bpmn:FlowElementsContainer') ||
|
|
||||||
targetBusinessObject.$instanceOf('bpmn:Participant'))) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (businessObject.$instanceOf('bpmn:Association') &&
|
|
||||||
(targetBusinessObject.$instanceOf('bpmn:FlowElementsContainer') ||
|
|
||||||
targetBusinessObject.$instanceOf('bpmn:Participant'))) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.addRule('shapes.move', function(context) {
|
|
||||||
|
|
||||||
var target = context.newParent,
|
|
||||||
shapes = context.shapes;
|
|
||||||
|
|
||||||
// only move if they have the same parent
|
|
||||||
var sameParent = size(groupBy(shapes, function(s) { return s.parent && s.parent.id; })) === 1;
|
|
||||||
|
|
||||||
if (!sameParent) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!target) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
var targetBusinessObject = target.businessObject,
|
|
||||||
targetDi = targetBusinessObject.di;
|
|
||||||
|
|
||||||
return shapes.every(function(s) {
|
|
||||||
return canDrop(s.businessObject, targetBusinessObject, targetDi);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
this.addRule([ 'shape.create', 'shape.append' ], function(context) {
|
|
||||||
var target = context.parent,
|
|
||||||
shape = context.shape,
|
|
||||||
source = context.source;
|
|
||||||
|
|
||||||
// ensure we do not drop the element
|
|
||||||
// into source
|
|
||||||
var t = target;
|
|
||||||
while (t) {
|
|
||||||
if (isSame(t, source)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
t = t.parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!target) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target.labelTarget) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return canDrop(shape.businessObject, target.businessObject, target.businessObject.di);
|
|
||||||
});
|
|
||||||
|
|
||||||
};
|
|
|
@ -2,6 +2,6 @@ module.exports = {
|
||||||
__depends__: [
|
__depends__: [
|
||||||
require('diagram-js/lib/features/rules')
|
require('diagram-js/lib/features/rules')
|
||||||
],
|
],
|
||||||
__init__: [ 'modelingRules' ],
|
__init__: [ 'bpmnRules' ],
|
||||||
modelingRules: [ 'type', require('./ModelingRules') ]
|
bpmnRules: [ 'type', require('./BpmnRules') ]
|
||||||
};
|
};
|
||||||
|
|
|
@ -209,6 +209,16 @@ module.exports.bootstrapViewer = (window || global).bootstrapViewer = bootstrapV
|
||||||
module.exports.inject = (window || global).inject = inject;
|
module.exports.inject = (window || global).inject = inject;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current active BpmnJS instance.
|
||||||
|
*
|
||||||
|
* @return {BpmnJS}
|
||||||
|
*/
|
||||||
|
module.exports.getBpmnJS = function() {
|
||||||
|
return BPMN_JS;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
function insertCSS(name, css) {
|
function insertCSS(name, css) {
|
||||||
if (document.querySelector('[data-css-file="' + name + '"]')) {
|
if (document.querySelector('[data-css-file="' + name + '"]')) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -28,6 +28,12 @@ describe('Modeler', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('should import collaboration', function(done) {
|
||||||
|
var xml = require('../fixtures/bpmn/collaboration-message-flows.bpmn');
|
||||||
|
createModeler(xml, done);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
it('should import empty definitions', function(done) {
|
it('should import empty definitions', function(done) {
|
||||||
var xml = require('../fixtures/bpmn/empty-definitions.bpmn');
|
var xml = require('../fixtures/bpmn/empty-definitions.bpmn');
|
||||||
createModeler(xml, done);
|
createModeler(xml, done);
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd" id="_biH3sOTeEeS2YerRfpjPrw" exporter="camunda modeler" exporterVersion="2.6.0" targetNamespace="http://activiti.org/bpmn">
|
||||||
|
<bpmn2:collaboration id="Collaboration">
|
||||||
|
<bpmn2:participant id="Participant" name="Pool" processRef="Process"/>
|
||||||
|
<bpmn2:participant id="OtherParticipant" name="Pool" processRef="OtherProcess"/>
|
||||||
|
</bpmn2:collaboration>
|
||||||
|
<bpmn2:process id="Process" isExecutable="false">
|
||||||
|
<bpmn2:subProcess id="SubProcess">
|
||||||
|
<bpmn2:task id="Task_in_SubProcess"/>
|
||||||
|
<bpmn2:endEvent id="EndEvent_in_SubProcess"/>
|
||||||
|
</bpmn2:subProcess>
|
||||||
|
<bpmn2:startEvent id="StartEvent_None"/>
|
||||||
|
<bpmn2:intermediateThrowEvent id="IntermediateThrowEvent_Message">
|
||||||
|
<bpmn2:messageEventDefinition id="MessageEventDefinition_1"/>
|
||||||
|
</bpmn2:intermediateThrowEvent>
|
||||||
|
<bpmn2:endEvent id="EndEvent_None"/>
|
||||||
|
<bpmn2:textAnnotation id="TextAnnotation_Global"/>
|
||||||
|
</bpmn2:process>
|
||||||
|
<bpmn2:process id="OtherProcess" isExecutable="false">
|
||||||
|
<bpmn2:task id="Task_in_OtherParticipant"/>
|
||||||
|
<bpmn2:textAnnotation id="TextAnnotation_OtherParticipant"/>
|
||||||
|
</bpmn2:process>
|
||||||
|
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||||
|
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration">
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_Participant_3" bpmnElement="Participant" isHorizontal="true">
|
||||||
|
<dc:Bounds height="265.0" width="697.0" x="72.0" y="48.0"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_SubProcess_3" bpmnElement="SubProcess" isExpanded="true">
|
||||||
|
<dc:Bounds height="205.0" width="248.0" x="468.0" y="72.0"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_Task_3" bpmnElement="Task_in_SubProcess">
|
||||||
|
<dc:Bounds height="80.0" width="100.0" x="493.0" y="95.0"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_3" bpmnElement="StartEvent_None">
|
||||||
|
<dc:Bounds height="36.0" width="36.0" x="144.0" y="157.0"/>
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds height="0.0" width="0.0" x="162.0" y="198.0"/>
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_EndEvent_3" bpmnElement="EndEvent_in_SubProcess">
|
||||||
|
<dc:Bounds height="36.0" width="36.0" x="660.0" y="117.0"/>
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds height="0.0" width="0.0" x="678.0" y="158.0"/>
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_Participant_4" bpmnElement="OtherParticipant" isHorizontal="true">
|
||||||
|
<dc:Bounds height="157.0" width="697.0" x="72.0" y="432.0"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_Task_7" bpmnElement="Task_in_OtherParticipant">
|
||||||
|
<dc:Bounds height="80.0" width="100.0" x="408.0" y="465.0"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_IntermediateCatchEvent_2" bpmnElement="IntermediateThrowEvent_Message">
|
||||||
|
<dc:Bounds height="36.0" width="36.0" x="264.0" y="157.0"/>
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds height="0.0" width="0.0" x="282.0" y="198.0"/>
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_EndEvent_4" bpmnElement="EndEvent_None">
|
||||||
|
<dc:Bounds height="36.0" width="36.0" x="373.0" y="156.0"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_TextAnnotation_3" bpmnElement="TextAnnotation_OtherParticipant">
|
||||||
|
<dc:Bounds height="88.0" width="103.0" x="162.0" y="465.0"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_TextAnnotation_4" bpmnElement="TextAnnotation_Global">
|
||||||
|
<dc:Bounds height="88.0" width="96.0" x="900.0" y="180.0"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
</bpmndi:BPMNPlane>
|
||||||
|
</bpmndi:BPMNDiagram>
|
||||||
|
</bpmn2:definitions>
|
|
@ -0,0 +1,83 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd" id="_e9eVgOdVEeSyFtFBe7wX5g" exporter="camunda modeler" exporterVersion="2.6.0" targetNamespace="http://activiti.org/bpmn">
|
||||||
|
<bpmn2:process id="Process" isExecutable="false">
|
||||||
|
<bpmn2:intermediateCatchEvent id="IntermediateCatchEvent_Message">
|
||||||
|
<bpmn2:messageEventDefinition id="_MessageEventDefinition_3"/>
|
||||||
|
</bpmn2:intermediateCatchEvent>
|
||||||
|
<bpmn2:intermediateThrowEvent id="IntermediateThrowEvent_Message">
|
||||||
|
<bpmn2:messageEventDefinition id="_MessageEventDefinition_4"/>
|
||||||
|
</bpmn2:intermediateThrowEvent>
|
||||||
|
<bpmn2:intermediateCatchEvent id="IntermediateCatchEvent_Signal">
|
||||||
|
<bpmn2:signalEventDefinition id="_SignalEventDefinition_2"/>
|
||||||
|
</bpmn2:intermediateCatchEvent>
|
||||||
|
<bpmn2:intermediateCatchEvent id="IntermediateCatchEvent_Condition">
|
||||||
|
<bpmn2:conditionalEventDefinition id="_ConditionalEventDefinition_2"/>
|
||||||
|
</bpmn2:intermediateCatchEvent>
|
||||||
|
<bpmn2:intermediateCatchEvent id="IntermediateCatchEvent_Timer">
|
||||||
|
<bpmn2:timerEventDefinition id="_TimerEventDefinition_2"/>
|
||||||
|
</bpmn2:intermediateCatchEvent>
|
||||||
|
<bpmn2:intermediateCatchEvent id="IntermediateCatchEvent"/>
|
||||||
|
<bpmn2:receiveTask id="ReceiveTask"/>
|
||||||
|
<bpmn2:parallelGateway id="ParallelGateway"/>
|
||||||
|
<bpmn2:task id="Task_None"/>
|
||||||
|
<bpmn2:eventBasedGateway id="EventBasedGateway"/>
|
||||||
|
</bpmn2:process>
|
||||||
|
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||||
|
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process">
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_EventBasedGateway_2" bpmnElement="EventBasedGateway">
|
||||||
|
<dc:Bounds height="50.0" width="50.0" x="269.0" y="204.0"/>
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds height="0.0" width="0.0" x="294.0" y="259.0"/>
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_IntermediateThrowEvent_3" bpmnElement="IntermediateCatchEvent_Message">
|
||||||
|
<dc:Bounds height="36.0" width="36.0" x="433.0" y="212.0"/>
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds height="0.0" width="0.0" x="451.0" y="253.0"/>
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_IntermediateThrowEvent_4" bpmnElement="IntermediateThrowEvent_Message">
|
||||||
|
<dc:Bounds height="36.0" width="36.0" x="433.0" y="288.0"/>
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds height="0.0" width="0.0" x="451.0" y="329.0"/>
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_Task_10" bpmnElement="ReceiveTask">
|
||||||
|
<dc:Bounds height="80.0" width="100.0" x="401.0" y="360.0"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_ParallelGateway_2" bpmnElement="ParallelGateway">
|
||||||
|
<dc:Bounds height="50.0" width="50.0" x="425.0" y="472.0"/>
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds height="0.0" width="0.0" x="450.0" y="527.0"/>
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_IntermediateCatchEvent_4" bpmnElement="IntermediateCatchEvent_Signal">
|
||||||
|
<dc:Bounds height="36.0" width="36.0" x="529.0" y="212.0"/>
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds height="0.0" width="0.0" x="547.0" y="253.0"/>
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_IntermediateCatchEvent_5" bpmnElement="IntermediateCatchEvent_Condition">
|
||||||
|
<dc:Bounds height="36.0" width="36.0" x="624.0" y="212.0"/>
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds height="0.0" width="0.0" x="642.0" y="253.0"/>
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_IntermediateCatchEvent_6" bpmnElement="IntermediateCatchEvent_Timer">
|
||||||
|
<dc:Bounds height="36.0" width="36.0" x="711.0" y="212.0"/>
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds height="0.0" width="0.0" x="729.0" y="253.0"/>
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_IntermediateCatchEvent_7" bpmnElement="IntermediateCatchEvent">
|
||||||
|
<dc:Bounds height="36.0" width="36.0" x="804.0" y="212.0"/>
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds height="0.0" width="0.0" x="822.0" y="253.0"/>
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_Task_11" bpmnElement="Task_None">
|
||||||
|
<dc:Bounds height="80.0" width="100.0" x="547.0" y="360.0"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
</bpmndi:BPMNPlane>
|
||||||
|
</bpmndi:BPMNDiagram>
|
||||||
|
</bpmn2:definitions>
|
|
@ -0,0 +1,72 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd" id="_biH3sOTeEeS2YerRfpjPrw" exporter="camunda modeler" exporterVersion="2.6.0" targetNamespace="http://activiti.org/bpmn">
|
||||||
|
<bpmn2:process id="Process" isExecutable="false">
|
||||||
|
<bpmn2:startEvent id="StartEvent_None"/>
|
||||||
|
<bpmn2:subProcess id="EventSubProcess" triggeredByEvent="true">
|
||||||
|
<bpmn2:startEvent id="StartEvent_Message_in_EventSubProcess">
|
||||||
|
<bpmn2:messageEventDefinition id="MessageEventDefinition_1"/>
|
||||||
|
</bpmn2:startEvent>
|
||||||
|
</bpmn2:subProcess>
|
||||||
|
<bpmn2:task id="Task"/>
|
||||||
|
<bpmn2:intermediateThrowEvent id="IntermediateThrowEvent_Link">
|
||||||
|
<bpmn2:linkEventDefinition id="_LinkEventDefinition_2"/>
|
||||||
|
</bpmn2:intermediateThrowEvent>
|
||||||
|
<bpmn2:intermediateCatchEvent id="IntermediateCatchEvent_Link">
|
||||||
|
<bpmn2:linkEventDefinition id="_LinkEventDefinition_3"/>
|
||||||
|
</bpmn2:intermediateCatchEvent>
|
||||||
|
<bpmn2:subProcess id="SubProcess">
|
||||||
|
<bpmn2:endEvent id="EndEvent_in_SubProcess"/>
|
||||||
|
</bpmn2:subProcess>
|
||||||
|
<bpmn2:endEvent id="EndEvent_None"/>
|
||||||
|
<bpmn2:textAnnotation id="TextAnnotation"/>
|
||||||
|
</bpmn2:process>
|
||||||
|
<bpmndi:BPMNDiagram id="_BPMNDiagram_2">
|
||||||
|
<bpmndi:BPMNPlane id="_BPMNPlane_2" bpmnElement="Process">
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_Task_8" bpmnElement="Task">
|
||||||
|
<dc:Bounds height="80.0" width="100.0" x="172.0" y="147.0"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_4" bpmnElement="StartEvent_None">
|
||||||
|
<dc:Bounds height="36.0" width="36.0" x="65.0" y="169.0"/>
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds height="0.0" width="0.0" x="83.0" y="210.0"/>
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_SubProcess_4" bpmnElement="EventSubProcess" isExpanded="true">
|
||||||
|
<dc:Bounds height="169.0" width="313.0" x="132.0" y="360.0"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_5" bpmnElement="StartEvent_Message_in_EventSubProcess">
|
||||||
|
<dc:Bounds height="36.0" width="36.0" x="171.0" y="419.0"/>
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds height="0.0" width="0.0" x="189.0" y="460.0"/>
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_IntermediateCatchEvent_3" bpmnElement="IntermediateThrowEvent_Link">
|
||||||
|
<dc:Bounds height="36.0" width="36.0" x="336.0" y="168.0"/>
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds height="0.0" width="0.0" x="354.0" y="209.0"/>
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_IntermediateThrowEvent_2" bpmnElement="IntermediateCatchEvent_Link">
|
||||||
|
<dc:Bounds height="36.0" width="36.0" x="425.0" y="168.0"/>
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds height="0.0" width="0.0" x="443.0" y="209.0"/>
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_SubProcess_5" bpmnElement="SubProcess" isExpanded="true">
|
||||||
|
<dc:Bounds height="169.0" width="205.0" x="516.0" y="360.0"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_TextAnnotation_2" bpmnElement="TextAnnotation">
|
||||||
|
<dc:Bounds height="85.0" width="85.0" x="576.0" y="36.0"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_EndEvent_5" bpmnElement="EndEvent_in_SubProcess">
|
||||||
|
<dc:Bounds height="36.0" width="36.0" x="639.0" y="451.0"/>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_EndEvent_6" bpmnElement="EndEvent_None">
|
||||||
|
<dc:Bounds height="36.0" width="36.0" x="516.0" y="168.0"/>
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds height="0.0" width="0.0" x="534.0" y="209.0"/>
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
</bpmndi:BPMNPlane>
|
||||||
|
</bpmndi:BPMNDiagram>
|
||||||
|
</bpmn2:definitions>
|
|
@ -0,0 +1,384 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var TestHelper = require('../../../../TestHelper');
|
||||||
|
|
||||||
|
/* global bootstrapModeler, inject */
|
||||||
|
|
||||||
|
|
||||||
|
var rulesModule = require('../../../../../lib/features/modeling/rules'),
|
||||||
|
coreModule = require('../../../../../lib/core');
|
||||||
|
|
||||||
|
|
||||||
|
function expectCanConnect(source, target, rules) {
|
||||||
|
|
||||||
|
var results = {};
|
||||||
|
|
||||||
|
TestHelper.getBpmnJS().invoke(function(elementRegistry, bpmnRules) {
|
||||||
|
|
||||||
|
source = elementRegistry.get(source);
|
||||||
|
target = elementRegistry.get(target);
|
||||||
|
|
||||||
|
expect(source).toBeDefined();
|
||||||
|
expect(target).toBeDefined();
|
||||||
|
|
||||||
|
if ('sequenceFlow' in rules) {
|
||||||
|
results.sequenceFlow = bpmnRules.canConnectSequenceFlow(source, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('messageFlow' in rules) {
|
||||||
|
results.messageFlow = bpmnRules.canConnectMessageFlow(source, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('association' in rules) {
|
||||||
|
results.association = bpmnRules.canConnectAssociation(source, target);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(results).toEqual(rules);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function expectCanDrop(element, target, expectedResult) {
|
||||||
|
|
||||||
|
var result;
|
||||||
|
|
||||||
|
TestHelper.getBpmnJS().invoke(function(elementRegistry, bpmnRules) {
|
||||||
|
|
||||||
|
element = elementRegistry.get(element);
|
||||||
|
target = elementRegistry.get(target);
|
||||||
|
|
||||||
|
expect(element).toBeDefined();
|
||||||
|
expect(target).toBeDefined();
|
||||||
|
|
||||||
|
result = bpmnRules.canDrop(element, target);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result).toEqual(expectedResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
describe('features/modeling/rules - BpmnRules', function() {
|
||||||
|
|
||||||
|
var testModules = [ coreModule, rulesModule ];
|
||||||
|
|
||||||
|
|
||||||
|
describe('on process diagram', function() {
|
||||||
|
|
||||||
|
var testXML = require('./BpmnRules.process.bpmn');
|
||||||
|
|
||||||
|
beforeEach(bootstrapModeler(testXML, { modules: testModules }));
|
||||||
|
|
||||||
|
|
||||||
|
it('connect StartEvent_None -> Task', inject(function(bpmnRules) {
|
||||||
|
|
||||||
|
expectCanConnect('StartEvent_None', 'Task', {
|
||||||
|
sequenceFlow: true,
|
||||||
|
messageFlow: false,
|
||||||
|
association: true
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('connect StartEvent_None -> TextAnnotation', inject(function(bpmnRules) {
|
||||||
|
|
||||||
|
expectCanConnect('StartEvent_None', 'TextAnnotation', {
|
||||||
|
sequenceFlow: false,
|
||||||
|
messageFlow: false,
|
||||||
|
association: true
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('connect Task -> IntermediateThrowEvent_Link', inject(function(bpmnRules) {
|
||||||
|
|
||||||
|
expectCanConnect('Task', 'IntermediateThrowEvent_Link', {
|
||||||
|
sequenceFlow: true,
|
||||||
|
messageFlow: false,
|
||||||
|
association: true
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('connect IntermediateThrowEvent_Link -> EndEvent_None', inject(function(bpmnRules) {
|
||||||
|
|
||||||
|
expectCanConnect('IntermediateThrowEvent_Link', 'EndEvent_None', {
|
||||||
|
sequenceFlow: false,
|
||||||
|
messageFlow: false,
|
||||||
|
association: true
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('connect StartEvent_None -> IntermediateCatchEvent_Link', inject(function(bpmnRules) {
|
||||||
|
|
||||||
|
expectCanConnect('StartEvent_None', 'IntermediateCatchEvent_Link', {
|
||||||
|
sequenceFlow: false,
|
||||||
|
messageFlow: false,
|
||||||
|
association: true
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('connect IntermediateCatchEvent_Link -> ', inject(function(bpmnRules) {
|
||||||
|
|
||||||
|
expectCanConnect('IntermediateCatchEvent_Link', 'Task', {
|
||||||
|
sequenceFlow: true,
|
||||||
|
messageFlow: false,
|
||||||
|
association: true
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('drop TextAnnotation -> Process', inject(function(bpmnRules) {
|
||||||
|
|
||||||
|
expectCanDrop('TextAnnotation', 'Process', true);
|
||||||
|
}));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('event based gateway', function() {
|
||||||
|
|
||||||
|
var testXML = require('./BpmnRules.eventBasedGateway.bpmn');
|
||||||
|
|
||||||
|
beforeEach(bootstrapModeler(testXML, { modules: testModules }));
|
||||||
|
|
||||||
|
|
||||||
|
it('connect EventBasedGateway -> IntermediateCatchEvent_Message', inject(function(bpmnRules) {
|
||||||
|
|
||||||
|
expectCanConnect('EventBasedGateway', 'IntermediateCatchEvent_Message', {
|
||||||
|
sequenceFlow: true,
|
||||||
|
messageFlow: false,
|
||||||
|
association: true
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('connect EventBasedGateway -> IntermediateCatchEvent_Message', inject(function(bpmnRules) {
|
||||||
|
|
||||||
|
expectCanConnect('EventBasedGateway', 'IntermediateCatchEvent_Message', {
|
||||||
|
sequenceFlow: true,
|
||||||
|
messageFlow: false,
|
||||||
|
association: true
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('connect EventBasedGateway -> IntermediateCatchEvent_Signal', inject(function(bpmnRules) {
|
||||||
|
|
||||||
|
expectCanConnect('EventBasedGateway', 'IntermediateCatchEvent_Signal', {
|
||||||
|
sequenceFlow: true,
|
||||||
|
messageFlow: false,
|
||||||
|
association: true
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('connect EventBasedGateway -> IntermediateCatchEvent_Condition', inject(function(bpmnRules) {
|
||||||
|
|
||||||
|
expectCanConnect('EventBasedGateway', 'IntermediateCatchEvent_Condition', {
|
||||||
|
sequenceFlow: true,
|
||||||
|
messageFlow: false,
|
||||||
|
association: true
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('connect EventBasedGateway -> IntermediateCatchEvent_Timer', inject(function(bpmnRules) {
|
||||||
|
|
||||||
|
expectCanConnect('EventBasedGateway', 'IntermediateCatchEvent_Timer', {
|
||||||
|
sequenceFlow: true,
|
||||||
|
messageFlow: false,
|
||||||
|
association: true
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('connect EventBasedGateway -> IntermediateCatchEvent', inject(function(bpmnRules) {
|
||||||
|
|
||||||
|
expectCanConnect('EventBasedGateway', 'IntermediateCatchEvent', {
|
||||||
|
sequenceFlow: false,
|
||||||
|
messageFlow: false,
|
||||||
|
association: true
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('connect EventBasedGateway -> IntermediateThrowEvent_Message', inject(function(bpmnRules) {
|
||||||
|
|
||||||
|
expectCanConnect('EventBasedGateway', 'IntermediateThrowEvent_Message', {
|
||||||
|
sequenceFlow: false,
|
||||||
|
messageFlow: false,
|
||||||
|
association: true
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('connect EventBasedGateway -> ReceiveTask', inject(function(bpmnRules) {
|
||||||
|
|
||||||
|
expectCanConnect('EventBasedGateway', 'ReceiveTask', {
|
||||||
|
sequenceFlow: true,
|
||||||
|
messageFlow: false,
|
||||||
|
association: true
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('connect EventBasedGateway -> Task_None', inject(function(bpmnRules) {
|
||||||
|
|
||||||
|
expectCanConnect('EventBasedGateway', 'Task_None', {
|
||||||
|
sequenceFlow: false,
|
||||||
|
messageFlow: false,
|
||||||
|
association: true
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('connect EventBasedGateway -> ParallelGateway', inject(function(bpmnRules) {
|
||||||
|
|
||||||
|
expectCanConnect('EventBasedGateway', 'ParallelGateway', {
|
||||||
|
sequenceFlow: false,
|
||||||
|
messageFlow: false,
|
||||||
|
association: true
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('on collaboration diagram', function() {
|
||||||
|
|
||||||
|
var testXML = require('./BpmnRules.collaboration.bpmn');
|
||||||
|
|
||||||
|
beforeEach(bootstrapModeler(testXML, { modules: testModules }));
|
||||||
|
|
||||||
|
|
||||||
|
it('connect StartEvent_None -> IntermediateEvent', inject(function(bpmnRules) {
|
||||||
|
|
||||||
|
expectCanConnect('StartEvent_None', 'IntermediateThrowEvent_Message', {
|
||||||
|
sequenceFlow: true,
|
||||||
|
messageFlow: false,
|
||||||
|
association: true
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('connect StartEvent_None -> OtherParticipant', inject(function(bpmnRules) {
|
||||||
|
|
||||||
|
expectCanConnect('StartEvent_None', 'OtherParticipant', {
|
||||||
|
sequenceFlow: false,
|
||||||
|
messageFlow: false,
|
||||||
|
association: true
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('connect OtherParticipant -> StartEvent_None', inject(function(bpmnRules) {
|
||||||
|
|
||||||
|
expectCanConnect('OtherParticipant', 'StartEvent_None', {
|
||||||
|
sequenceFlow: false,
|
||||||
|
messageFlow: true,
|
||||||
|
association: true
|
||||||
|
});
|
||||||
|
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('connect EndEvent_None -> OtherParticipant', inject(function(bpmnRules) {
|
||||||
|
|
||||||
|
expectCanConnect('EndEvent_None', 'OtherParticipant', {
|
||||||
|
sequenceFlow: false,
|
||||||
|
messageFlow: true,
|
||||||
|
association: true
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('connect OtherParticipant -> EndEvent_None', inject(function(bpmnRules) {
|
||||||
|
|
||||||
|
expectCanConnect('OtherParticipant', 'EndEvent_None', {
|
||||||
|
sequenceFlow: false,
|
||||||
|
messageFlow: false,
|
||||||
|
association: true
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('connect IntermediateThrowEvent_Message -> OtherParticipant', inject(function(bpmnRules) {
|
||||||
|
|
||||||
|
expectCanConnect('IntermediateThrowEvent_Message', 'OtherParticipant', {
|
||||||
|
sequenceFlow: false,
|
||||||
|
messageFlow: true,
|
||||||
|
association: true
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('connect OtherParticipant -> IntermediateThrowEvent_Message', inject(function(bpmnRules) {
|
||||||
|
|
||||||
|
expectCanConnect('OtherParticipant', 'IntermediateThrowEvent_Message', {
|
||||||
|
sequenceFlow: false,
|
||||||
|
messageFlow: false,
|
||||||
|
association: true
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('connect Task_in_SubProcess -> OtherParticipant', inject(function(bpmnRules) {
|
||||||
|
|
||||||
|
expectCanConnect('Task_in_SubProcess', 'OtherParticipant', {
|
||||||
|
sequenceFlow: false,
|
||||||
|
messageFlow: true,
|
||||||
|
association: true
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('connect OtherParticipant -> Task_in_SubProcess', inject(function(bpmnRules) {
|
||||||
|
|
||||||
|
expectCanConnect('OtherParticipant', 'Task_in_SubProcess', {
|
||||||
|
sequenceFlow: false,
|
||||||
|
messageFlow: true,
|
||||||
|
association: true
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('connect Participant -> OtherParticipant', inject(function(bpmnRules) {
|
||||||
|
|
||||||
|
expectCanConnect('Participant', 'OtherParticipant', {
|
||||||
|
sequenceFlow: false,
|
||||||
|
messageFlow: true,
|
||||||
|
association: true
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('connect StartEvent_None -> TextAnnotation_OtherParticipant', inject(function(bpmnRules) {
|
||||||
|
|
||||||
|
expectCanConnect('StartEvent_None', 'TextAnnotation_OtherParticipant', {
|
||||||
|
sequenceFlow: false,
|
||||||
|
messageFlow: false,
|
||||||
|
association: true
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('connect StartEvent_None -> TextAnnotation_Global', inject(function(bpmnRules) {
|
||||||
|
|
||||||
|
expectCanConnect('StartEvent_None', 'TextAnnotation_Global', {
|
||||||
|
sequenceFlow: false,
|
||||||
|
messageFlow: false,
|
||||||
|
association: true
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('drop TextAnnotation_Global -> Participant', inject(function(bpmnRules) {
|
||||||
|
|
||||||
|
expectCanDrop('TextAnnotation_Global', 'Participant', true);
|
||||||
|
}));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
|
@ -1,315 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
/* global bootstrapModeler, inject */
|
|
||||||
|
|
||||||
var modelingModule = require('../../../../lib/features/modeling'),
|
|
||||||
rulesModule = require('../../../../lib/features/modeling/rules'),
|
|
||||||
coreModule = require('../../../../lib/core');
|
|
||||||
|
|
||||||
|
|
||||||
describe('features/ModelingRules', function() {
|
|
||||||
|
|
||||||
var sequenceXML = require('../../../fixtures/bpmn/sequence-flows.bpmn');
|
|
||||||
var eventGatewaysEdgeXML = require('../../../fixtures/bpmn/features/rules/event-based-gateway-outgoing-edge.bpmn');
|
|
||||||
var linkEventXML = require('../../../fixtures/bpmn/features/rules/link-event.bpmn');
|
|
||||||
var textAnnotationXML = require('../../../fixtures/bpmn/features/rules/text-annotation-association.bpmn');
|
|
||||||
|
|
||||||
|
|
||||||
var testModules = [ coreModule, modelingModule, rulesModule ];
|
|
||||||
|
|
||||||
|
|
||||||
// See workaround https://github.com/bpmn-io/bpmn-js/issues/176
|
|
||||||
// The wanted behavior until https://github.com/bpmn-io/bpmn-js/issues/176 is fixed
|
|
||||||
describe('connect with source == target', function() {
|
|
||||||
|
|
||||||
beforeEach(bootstrapModeler(sequenceXML, { modules: testModules }));
|
|
||||||
|
|
||||||
it('should not allow connection', inject(function(elementRegistry, modeling, rules) {
|
|
||||||
|
|
||||||
// given
|
|
||||||
var taskShape = elementRegistry.get('Task_1');
|
|
||||||
|
|
||||||
// when
|
|
||||||
var allowed = rules.allowed('connection.create', {
|
|
||||||
connection: null,
|
|
||||||
source: taskShape,
|
|
||||||
target: taskShape
|
|
||||||
});
|
|
||||||
|
|
||||||
// then
|
|
||||||
// connection should not be allowed
|
|
||||||
expect(allowed).toBe(false);
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
describe('eventbased gateway', function() {
|
|
||||||
|
|
||||||
beforeEach(bootstrapModeler(eventGatewaysEdgeXML, { modules: testModules }));
|
|
||||||
|
|
||||||
it('should allow catching message intermediate event on outgoing edges',
|
|
||||||
inject(function(elementRegistry, modeling, rules) {
|
|
||||||
|
|
||||||
// given
|
|
||||||
var eventGateway = elementRegistry.get('EventBasedGateway_1'),
|
|
||||||
messageEvent = elementRegistry.get('IntermediateCatchEvent_0');
|
|
||||||
|
|
||||||
|
|
||||||
// when
|
|
||||||
var allowed = rules.allowed('connection.create', {
|
|
||||||
connection: null,
|
|
||||||
source: eventGateway,
|
|
||||||
target: messageEvent
|
|
||||||
});
|
|
||||||
|
|
||||||
// then
|
|
||||||
// connection should not be allowed
|
|
||||||
expect(allowed).toBe(true);
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
it('should allow catching timer intermediate event on outgoing edges',
|
|
||||||
inject(function(elementRegistry, modeling, rules) {
|
|
||||||
|
|
||||||
// given
|
|
||||||
var eventGateway = elementRegistry.get('EventBasedGateway_1'),
|
|
||||||
timerEvent = elementRegistry.get('IntermediateCatchEvent_1');
|
|
||||||
|
|
||||||
|
|
||||||
// when
|
|
||||||
var allowed = rules.allowed('connection.create', {
|
|
||||||
connection: null,
|
|
||||||
source: eventGateway,
|
|
||||||
target: timerEvent
|
|
||||||
});
|
|
||||||
|
|
||||||
// then
|
|
||||||
// connection should not be allowed
|
|
||||||
expect(allowed).toBe(true);
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
it('should allow catching condition intermediate event on outgoing edges',
|
|
||||||
inject(function(elementRegistry, modeling, rules) {
|
|
||||||
|
|
||||||
// given
|
|
||||||
var eventGateway = elementRegistry.get('EventBasedGateway_1'),
|
|
||||||
conditionEvent = elementRegistry.get('IntermediateCatchEvent_2');
|
|
||||||
|
|
||||||
|
|
||||||
// when
|
|
||||||
var allowed = rules.allowed('connection.create', {
|
|
||||||
connection: null,
|
|
||||||
source: eventGateway,
|
|
||||||
target: conditionEvent
|
|
||||||
});
|
|
||||||
|
|
||||||
// then
|
|
||||||
// connection should not be allowed
|
|
||||||
expect(allowed).toBe(true);
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
it('should allow catching signal intermediate event on outgoing edges',
|
|
||||||
inject(function(elementRegistry, modeling, rules) {
|
|
||||||
|
|
||||||
// given
|
|
||||||
var eventGateway = elementRegistry.get('EventBasedGateway_1'),
|
|
||||||
signalEvent = elementRegistry.get('IntermediateCatchEvent_3');
|
|
||||||
|
|
||||||
|
|
||||||
// when
|
|
||||||
var allowed = rules.allowed('connection.create', {
|
|
||||||
connection: null,
|
|
||||||
source: eventGateway,
|
|
||||||
target: signalEvent
|
|
||||||
});
|
|
||||||
|
|
||||||
// then
|
|
||||||
// connection should not be allowed
|
|
||||||
expect(allowed).toBe(true);
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
it('should allow receive task on outgoing edges',
|
|
||||||
inject(function(elementRegistry, modeling, rules) {
|
|
||||||
|
|
||||||
// given
|
|
||||||
var eventGateway = elementRegistry.get('EventBasedGateway_1'),
|
|
||||||
receiveTask = elementRegistry.get('ReceiveTask_1');
|
|
||||||
|
|
||||||
|
|
||||||
// when
|
|
||||||
var allowed = rules.allowed('connection.create', {
|
|
||||||
connection: null,
|
|
||||||
source: eventGateway,
|
|
||||||
target: receiveTask
|
|
||||||
});
|
|
||||||
|
|
||||||
// then
|
|
||||||
// connection should not be allowed
|
|
||||||
expect(allowed).toBe(true);
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
it('should not allow throw event on outgoing edges',
|
|
||||||
inject(function(elementRegistry, modeling, rules) {
|
|
||||||
|
|
||||||
// given
|
|
||||||
var eventGateway = elementRegistry.get('EventBasedGateway_1'),
|
|
||||||
throwEvent = elementRegistry.get('IntermediateThrowEvent_0');
|
|
||||||
|
|
||||||
|
|
||||||
// when
|
|
||||||
var allowed = rules.allowed('connection.create', {
|
|
||||||
connection: null,
|
|
||||||
source: eventGateway,
|
|
||||||
target: throwEvent
|
|
||||||
});
|
|
||||||
|
|
||||||
// then
|
|
||||||
// connection should not be allowed
|
|
||||||
expect(allowed).toBe(false);
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
it('should not allow task on outgoing edges',
|
|
||||||
inject(function(elementRegistry, modeling, rules) {
|
|
||||||
|
|
||||||
// given
|
|
||||||
var eventGateway = elementRegistry.get('EventBasedGateway_1'),
|
|
||||||
task = elementRegistry.get('Task_1');
|
|
||||||
|
|
||||||
|
|
||||||
// when
|
|
||||||
var allowed = rules.allowed('connection.create', {
|
|
||||||
connection: null,
|
|
||||||
source: eventGateway,
|
|
||||||
target: task
|
|
||||||
});
|
|
||||||
|
|
||||||
// then
|
|
||||||
// connection should not be allowed
|
|
||||||
expect(allowed).toBe(false);
|
|
||||||
}));
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
describe('catch link events', function() {
|
|
||||||
|
|
||||||
beforeEach(bootstrapModeler(linkEventXML, { modules: testModules }));
|
|
||||||
|
|
||||||
it('should not have incoming sequence flows ', inject(function(elementRegistry, modeling, rules) {
|
|
||||||
|
|
||||||
// given
|
|
||||||
var catchEvent = elementRegistry.get('IntermediateCatchEvent'),
|
|
||||||
incomingTask = elementRegistry.get('Task_incoming');
|
|
||||||
|
|
||||||
|
|
||||||
// when
|
|
||||||
var allowed = rules.allowed('connection.create', {
|
|
||||||
connection: null,
|
|
||||||
source: incomingTask,
|
|
||||||
target: catchEvent
|
|
||||||
});
|
|
||||||
|
|
||||||
// then
|
|
||||||
// connection should not be allowed
|
|
||||||
expect(allowed).toBe(false);
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
it('should be allowed to have outgoing sequence flows ',
|
|
||||||
inject(function(elementRegistry, modeling, rules) {
|
|
||||||
|
|
||||||
// given
|
|
||||||
var catchEvent = elementRegistry.get('IntermediateCatchEvent'),
|
|
||||||
outgoingTask = elementRegistry.get('Task_outgoing');
|
|
||||||
|
|
||||||
// when
|
|
||||||
var allowed = rules.allowed('connection.create', {
|
|
||||||
connection: null,
|
|
||||||
source: catchEvent,
|
|
||||||
target: outgoingTask
|
|
||||||
});
|
|
||||||
|
|
||||||
// then
|
|
||||||
// connection should not be allowed
|
|
||||||
expect(allowed).toBe(true);
|
|
||||||
}));
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
describe('throwing link events', function() {
|
|
||||||
|
|
||||||
beforeEach(bootstrapModeler(linkEventXML, { modules: testModules }));
|
|
||||||
|
|
||||||
it('should not have outgoing sequence flows', inject(function(elementRegistry, modeling, rules) {
|
|
||||||
|
|
||||||
// given
|
|
||||||
var catchEvent = elementRegistry.get('IntermediateThrowEvent'),
|
|
||||||
outgoingTask = elementRegistry.get('Task_outgoing');
|
|
||||||
|
|
||||||
|
|
||||||
// when
|
|
||||||
var allowed = rules.allowed('connection.create', {
|
|
||||||
connection: null,
|
|
||||||
source: catchEvent,
|
|
||||||
target: outgoingTask
|
|
||||||
});
|
|
||||||
|
|
||||||
// then
|
|
||||||
// connection should not be allowed
|
|
||||||
expect(allowed).toBe(false);
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
it('should be allowed to have incoming sequence flows ',
|
|
||||||
inject(function(elementRegistry, modeling, rules) {
|
|
||||||
|
|
||||||
// given
|
|
||||||
var catchEvent = elementRegistry.get('IntermediateThrowEvent'),
|
|
||||||
incomingTask = elementRegistry.get('Task_incoming');
|
|
||||||
|
|
||||||
|
|
||||||
// when
|
|
||||||
var allowed = rules.allowed('connection.create', {
|
|
||||||
connection: null,
|
|
||||||
source: incomingTask,
|
|
||||||
target: catchEvent
|
|
||||||
});
|
|
||||||
|
|
||||||
// then
|
|
||||||
// connection should not be allowed
|
|
||||||
expect(allowed).toBe(true);
|
|
||||||
}));
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
describe('Association', function() {
|
|
||||||
|
|
||||||
beforeEach(bootstrapModeler(textAnnotationXML, { modules: testModules }));
|
|
||||||
|
|
||||||
it('should allow drop on process', inject(function(elementRegistry, rules) {
|
|
||||||
|
|
||||||
// given
|
|
||||||
var association = elementRegistry.get('Association_1'),
|
|
||||||
parent = elementRegistry.get('Process_1');
|
|
||||||
|
|
||||||
// when
|
|
||||||
var allowed = rules.allowed('shapes.move', {
|
|
||||||
connection: null,
|
|
||||||
shapes: [ association ],
|
|
||||||
newParent: parent
|
|
||||||
});
|
|
||||||
|
|
||||||
// then
|
|
||||||
expect(allowed).toBe(true);
|
|
||||||
}));
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
Loading…
Reference in New Issue