185 lines
5.0 KiB
JavaScript
185 lines
5.0 KiB
JavaScript
import inherits from 'inherits';
|
|
|
|
import {
|
|
find,
|
|
isArray,
|
|
matchPattern,
|
|
some
|
|
} from 'min-dash';
|
|
|
|
import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
|
|
|
|
import {
|
|
add as collectionAdd,
|
|
remove as collectionRemove
|
|
} from 'diagram-js/lib/util/Collections';
|
|
|
|
import {
|
|
getBusinessObject,
|
|
is
|
|
} from '../../../util/ModelUtil';
|
|
|
|
import { isAny } from '../util/ModelingUtil';
|
|
|
|
import { hasEventDefinition } from '../../../util/DiUtil';
|
|
|
|
var LOW_PRIORITY = 500;
|
|
|
|
|
|
/**
|
|
* Add referenced root elements (error, escalation, message, signal) if they don't exist.
|
|
* Copy referenced root elements on copy & paste.
|
|
*/
|
|
export default function RootElementReferenceBehavior(
|
|
bpmnjs, eventBus, injector, moddleCopy, bpmnFactory
|
|
) {
|
|
injector.invoke(CommandInterceptor, this);
|
|
|
|
function canHaveRootElementReference(element) {
|
|
return isAny(element, [ 'bpmn:ReceiveTask', 'bpmn:SendTask' ]) ||
|
|
hasAnyEventDefinition(element, [
|
|
'bpmn:ErrorEventDefinition',
|
|
'bpmn:EscalationEventDefinition',
|
|
'bpmn:MessageEventDefinition',
|
|
'bpmn:SignalEventDefinition'
|
|
]);
|
|
}
|
|
|
|
function hasRootElement(rootElement) {
|
|
var definitions = bpmnjs.getDefinitions(),
|
|
rootElements = definitions.get('rootElements');
|
|
|
|
return !!find(rootElements, matchPattern({ id: rootElement.id }));
|
|
}
|
|
|
|
function getRootElementReferencePropertyName(eventDefinition) {
|
|
if (is(eventDefinition, 'bpmn:ErrorEventDefinition')) {
|
|
return 'errorRef';
|
|
} else if (is(eventDefinition, 'bpmn:EscalationEventDefinition')) {
|
|
return 'escalationRef';
|
|
} else if (is(eventDefinition, 'bpmn:MessageEventDefinition')) {
|
|
return 'messageRef';
|
|
} else if (is(eventDefinition, 'bpmn:SignalEventDefinition')) {
|
|
return 'signalRef';
|
|
}
|
|
}
|
|
|
|
function getRootElement(businessObject) {
|
|
if (isAny(businessObject, [ 'bpmn:ReceiveTask', 'bpmn:SendTask' ])) {
|
|
return businessObject.get('messageRef');
|
|
}
|
|
|
|
var eventDefinitions = businessObject.get('eventDefinitions'),
|
|
eventDefinition = eventDefinitions[ 0 ];
|
|
|
|
return eventDefinition.get(getRootElementReferencePropertyName(eventDefinition));
|
|
}
|
|
|
|
function setRootElement(businessObject, rootElement) {
|
|
if (isAny(businessObject, [ 'bpmn:ReceiveTask', 'bpmn:SendTask' ])) {
|
|
return businessObject.set('messageRef', rootElement);
|
|
}
|
|
|
|
var eventDefinitions = businessObject.get('eventDefinitions'),
|
|
eventDefinition = eventDefinitions[ 0 ];
|
|
|
|
return eventDefinition.set(getRootElementReferencePropertyName(eventDefinition), rootElement);
|
|
}
|
|
|
|
// create shape
|
|
this.executed('shape.create', function(context) {
|
|
var shape = context.shape;
|
|
|
|
if (!canHaveRootElementReference(shape)) {
|
|
return;
|
|
}
|
|
|
|
var businessObject = getBusinessObject(shape),
|
|
rootElement = getRootElement(businessObject),
|
|
rootElements;
|
|
|
|
if (rootElement && !hasRootElement(rootElement)) {
|
|
rootElements = bpmnjs.getDefinitions().get('rootElements');
|
|
|
|
// add root element
|
|
collectionAdd(rootElements, rootElement);
|
|
|
|
context.addedRootElement = rootElement;
|
|
}
|
|
}, true);
|
|
|
|
this.reverted('shape.create', function(context) {
|
|
var addedRootElement = context.addedRootElement;
|
|
|
|
if (!addedRootElement) {
|
|
return;
|
|
}
|
|
|
|
var rootElements = bpmnjs.getDefinitions().get('rootElements');
|
|
|
|
// remove root element
|
|
collectionRemove(rootElements, addedRootElement);
|
|
}, true);
|
|
|
|
eventBus.on('copyPaste.copyElement', function(context) {
|
|
var descriptor = context.descriptor,
|
|
element = context.element;
|
|
|
|
if (!canHaveRootElementReference(element)) {
|
|
return;
|
|
}
|
|
|
|
var businessObject = getBusinessObject(element),
|
|
rootElement = getRootElement(businessObject);
|
|
|
|
if (rootElement) {
|
|
descriptor.referencedRootElement = rootElement;
|
|
}
|
|
});
|
|
|
|
eventBus.on('copyPaste.pasteElement', LOW_PRIORITY, function(context) {
|
|
var descriptor = context.descriptor,
|
|
businessObject = descriptor.businessObject;
|
|
|
|
if (!canHaveRootElementReference(businessObject)) {
|
|
return;
|
|
}
|
|
|
|
var referencedRootElement = descriptor.referencedRootElement;
|
|
|
|
if (!referencedRootElement) {
|
|
return;
|
|
}
|
|
|
|
if (!hasRootElement(referencedRootElement)) {
|
|
referencedRootElement = moddleCopy.copyElement(
|
|
referencedRootElement,
|
|
bpmnFactory.create(referencedRootElement.$type)
|
|
);
|
|
}
|
|
|
|
setRootElement(businessObject, referencedRootElement);
|
|
});
|
|
}
|
|
|
|
RootElementReferenceBehavior.$inject = [
|
|
'bpmnjs',
|
|
'eventBus',
|
|
'injector',
|
|
'moddleCopy',
|
|
'bpmnFactory'
|
|
];
|
|
|
|
inherits(RootElementReferenceBehavior, CommandInterceptor);
|
|
|
|
// helpers //////////
|
|
|
|
function hasAnyEventDefinition(element, types) {
|
|
if (!isArray(types)) {
|
|
types = [ types ];
|
|
}
|
|
|
|
return some(types, function(type) {
|
|
return hasEventDefinition(element, type);
|
|
});
|
|
} |