parent
6011de1c4a
commit
c14a87e5ad
File diff suppressed because one or more lines are too long
|
@ -1,10 +1,10 @@
|
|||
@font-face {
|
||||
font-family: 'bpmn';
|
||||
src: url('../font/bpmn.eot?37618458');
|
||||
src: url('../font/bpmn.eot?37618458#iefix') format('embedded-opentype'),
|
||||
url('../font/bpmn.woff?37618458') format('woff'),
|
||||
url('../font/bpmn.ttf?37618458') format('truetype'),
|
||||
url('../font/bpmn.svg?37618458#bpmn') format('svg');
|
||||
src: url('../font/bpmn.eot?84549978');
|
||||
src: url('../font/bpmn.eot?84549978#iefix') format('embedded-opentype'),
|
||||
url('../font/bpmn.woff?84549978') format('woff'),
|
||||
url('../font/bpmn.ttf?84549978') format('truetype'),
|
||||
url('../font/bpmn.svg?84549978#bpmn') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
|||
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
||||
@font-face {
|
||||
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-navigation:before { content: '\e85e'; } /* '' */
|
||||
.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-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="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>
|
||||
</defs>
|
||||
</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.append-task': appendAction('bpmn:Task', 'icon-task'),
|
||||
'append.intermediate-event': appendAction('bpmn:IntermediateThrowEvent',
|
||||
'icon-intermediate-event-none'),
|
||||
'connect': {
|
||||
group: 'connect',
|
||||
className: 'icon-connection',
|
||||
action: {
|
||||
click: startConnect,
|
||||
dragstart: startConnect
|
||||
}
|
||||
}
|
||||
'icon-intermediate-event-none')
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -155,10 +147,6 @@ ContextPadProvider.prototype.getContextPadEntries = function(element) {
|
|||
});
|
||||
}
|
||||
|
||||
assign(actions, {
|
||||
'append.text-annotation': appendAction('bpmn:TextAnnotation', 'icon-text-annotation')
|
||||
});
|
||||
|
||||
|
||||
// Replace menu entry
|
||||
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
|
||||
assign(actions, {
|
||||
'delete': {
|
||||
|
|
|
@ -15,6 +15,7 @@ BpmnFactory.$inject = [ 'moddle' ];
|
|||
BpmnFactory.prototype._needsId = function(element) {
|
||||
return element.$instanceOf('bpmn:RootElement') ||
|
||||
element.$instanceOf('bpmn:FlowElement') ||
|
||||
element.$instanceOf('bpmn:MessageFlow') ||
|
||||
element.$instanceOf('bpmn:Artifact') ||
|
||||
element.$instanceOf('bpmn:Participant') ||
|
||||
element.$instanceOf('bpmn:Process') ||
|
||||
|
|
|
@ -208,6 +208,7 @@ BpmnUpdater.prototype.updateSemanticParent = function(businessObject, newParent)
|
|||
}
|
||||
|
||||
containment = 'flowElements';
|
||||
|
||||
} else
|
||||
|
||||
if (businessObject.$instanceOf('bpmn:Artifact')) {
|
||||
|
@ -226,7 +227,12 @@ BpmnUpdater.prototype.updateSemanticParent = function(businessObject, newParent)
|
|||
}
|
||||
|
||||
containment = 'artifacts';
|
||||
}
|
||||
} else
|
||||
|
||||
if (businessObject.$instanceOf('bpmn:MessageFlow')) {
|
||||
containment = 'messageFlows';
|
||||
|
||||
} else
|
||||
|
||||
if (businessObject.$instanceOf('bpmn:Participant')) {
|
||||
containment = 'participants';
|
||||
|
|
|
@ -14,14 +14,17 @@ var UpdatePropertiesHandler = require('./cmd/UpdatePropertiesHandler'),
|
|||
* @param {EventBus} eventBus
|
||||
* @param {ElementFactory} elementFactory
|
||||
* @param {CommandStack} commandStack
|
||||
* @param {BpmnRules} bpmnRules
|
||||
*/
|
||||
function Modeling(eventBus, elementFactory, commandStack) {
|
||||
function Modeling(eventBus, elementFactory, commandStack, bpmnRules) {
|
||||
BaseModeling.call(this, eventBus, elementFactory, commandStack);
|
||||
|
||||
this._bpmnRules = bpmnRules;
|
||||
}
|
||||
|
||||
inherits(Modeling, BaseModeling);
|
||||
|
||||
Modeling.$inject = [ 'eventBus', 'elementFactory', 'commandStack' ];
|
||||
Modeling.$inject = [ 'eventBus', 'elementFactory', 'commandStack', 'bpmnRules' ];
|
||||
|
||||
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) {
|
||||
|
||||
var sourceBo = source.businessObject,
|
||||
targetBo = target.businessObject;
|
||||
var bpmnRules = this._bpmnRules;
|
||||
|
||||
if (!attrs) {
|
||||
if (sourceBo.$instanceOf('bpmn:FlowNode') &&
|
||||
targetBo.$instanceOf('bpmn:FlowNode') &&
|
||||
!sourceBo.$instanceOf('bpmn:EndEvent') &&
|
||||
!targetBo.$instanceOf('bpmn:StartEvent')) {
|
||||
|
||||
if (bpmnRules.canConnectMessageFlow(source, target)) {
|
||||
attrs = {
|
||||
type: 'bpmn:MessageFlow'
|
||||
};
|
||||
} else
|
||||
if (bpmnRules.canConnectSequenceFlow(source, target)) {
|
||||
attrs = {
|
||||
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__: [
|
||||
require('diagram-js/lib/features/rules')
|
||||
],
|
||||
__init__: [ 'modelingRules' ],
|
||||
modelingRules: [ 'type', require('./ModelingRules') ]
|
||||
__init__: [ 'bpmnRules' ],
|
||||
bpmnRules: [ 'type', require('./BpmnRules') ]
|
||||
};
|
||||
|
|
|
@ -209,6 +209,16 @@ module.exports.bootstrapViewer = (window || global).bootstrapViewer = bootstrapV
|
|||
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) {
|
||||
if (document.querySelector('[data-css-file="' + name + '"]')) {
|
||||
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) {
|
||||
var xml = require('../fixtures/bpmn/empty-definitions.bpmn');
|
||||
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