| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400 |
- import {
- assign,
- forEach,
- isDefined,
- isObject,
- omit
- } from 'min-dash';
- import inherits from 'inherits-browser';
- import {
- getBusinessObject,
- getDi,
- is
- } from '../../util/ModelUtil';
- import {
- isAny
- } from '../modeling/util/ModelingUtil';
- import {
- isExpanded
- } from '../../util/DiUtil';
- import BaseElementFactory from 'diagram-js/lib/core/ElementFactory';
- import {
- DEFAULT_LABEL_SIZE
- } from '../../util/LabelUtil';
- import {
- ensureCompatDiRef
- } from '../../util/CompatibilityUtil';
- /**
- * @typedef {import('diagram-js/lib/i18n/translate/translate').default} Translate
- *
- * @typedef {import('diagram-js/lib/util/Types').Dimensions} Dimensions
- *
- * @typedef {import('./BpmnFactory').default} BpmnFactory
- *
- * @typedef {import('../../model/Types').BpmnAttributes} BpmnAttributes
- * @typedef {import('../../model/Types').Connection} Connection
- * @typedef {import('../../model/Types').Element} Element
- * @typedef {import('../../model/Types').Label} Label
- * @typedef {import('../../model/Types').Root} Root
- * @typedef {import('../../model/Types').Shape} Shape
- * @typedef {import('../../model/Types').Moddle} Moddle
- * @typedef {import('../../model/Types').ModdleElement} ModdleElement
- */
- /**
- * A BPMN-specific element factory.
- *
- * @template {Connection} [T=Connection]
- * @template {Label} [U=Label]
- * @template {Root} [V=Root]
- * @template {Shape} [W=Shape]
- *
- * @extends {BaseElementFactory<T, U, V, W>}
- *
- * @param {BpmnFactory} bpmnFactory
- * @param {Moddle} moddle
- * @param {Translate} translate
- */
- export default function ElementFactory(bpmnFactory, moddle, translate) {
- BaseElementFactory.call(this);
- this._bpmnFactory = bpmnFactory;
- this._moddle = moddle;
- this._translate = translate;
- }
- inherits(ElementFactory, BaseElementFactory);
- ElementFactory.$inject = [
- 'bpmnFactory',
- 'moddle',
- 'translate'
- ];
- ElementFactory.prototype._baseCreate = BaseElementFactory.prototype.create;
- /**
- * Create a root element.
- *
- * @overlord
- * @param {'root'} elementType
- * @param {Partial<Root> & Partial<BpmnAttributes>} [attrs]
- * @return {V}
- */
- /**
- * Create a shape.
- *
- * @overlord
- * @param {'shape'} elementType
- * @param {Partial<Shape> & Partial<BpmnAttributes>} [attrs]
- * @return {W}
- */
- /**
- * Create a connection.
- *
- * @overlord
- * @param {'connection'} elementType
- * @param {Partial<Connection> & Partial<BpmnAttributes>} [attrs]
- * @return {T}
- */
- /**
- * Create a label.
- *
- * @param {'label'} elementType
- * @param {Partial<Label> & Partial<BpmnAttributes>} [attrs]
- * @return {U}
- */
- ElementFactory.prototype.create = function(elementType, attrs) {
- // no special magic for labels,
- // we assume their businessObjects have already been created
- // and wired via attrs
- if (elementType === 'label') {
- var di = attrs.di || this._bpmnFactory.createDiLabel();
- return this._baseCreate(elementType, assign({ type: 'label', di: di }, DEFAULT_LABEL_SIZE, attrs));
- }
- return this.createElement(elementType, attrs);
- };
- /**
- * Create a BPMN root element.
- *
- * @overlord
- * @param {'root'} elementType
- * @param {Partial<Root> & Partial<BpmnAttributes>} [attrs]
- * @return {V}
- */
- /**
- * Create a BPMN shape.
- *
- * @overlord
- * @param {'shape'} elementType
- * @param {Partial<Shape> & Partial<BpmnAttributes>} [attrs]
- * @return {W}
- */
- /**
- * Create a BPMN connection.
- *
- * @param {'connection'} elementType
- * @param {Partial<Connection> & Partial<BpmnAttributes>} [attrs]
- * @return {T}
- */
- ElementFactory.prototype.createElement = function(elementType, attrs) {
- var size,
- translate = this._translate;
- attrs = assign({}, attrs || {});
- var businessObject = attrs.businessObject,
- di = attrs.di;
- if (!businessObject) {
- if (!attrs.type) {
- throw new Error(translate('no shape type specified'));
- }
- businessObject = this._bpmnFactory.create(attrs.type);
- ensureCompatDiRef(businessObject);
- }
- if (!isModdleDi(di)) {
- var diAttrs = assign(
- {},
- di || {},
- { id: businessObject.id + '_di' }
- );
- if (elementType === 'root') {
- di = this._bpmnFactory.createDiPlane(businessObject, diAttrs);
- } else
- if (elementType === 'connection') {
- di = this._bpmnFactory.createDiEdge(businessObject, diAttrs);
- } else {
- di = this._bpmnFactory.createDiShape(businessObject, diAttrs);
- }
- }
- if (is(businessObject, 'bpmn:Group')) {
- attrs = assign({
- isFrame: true
- }, attrs);
- }
- attrs = applyAttributes(businessObject, attrs, [
- 'processRef',
- 'isInterrupting',
- 'associationDirection',
- 'isForCompensation'
- ]);
- if (attrs.isExpanded) {
- attrs = applyAttribute(di, attrs, 'isExpanded');
- }
- if (is(businessObject, 'bpmn:SubProcess')) {
- attrs.collapsed = !isExpanded(businessObject, di);
- }
- if (is(businessObject, 'bpmn:ExclusiveGateway')) {
- di.isMarkerVisible = true;
- }
- if (isDefined(attrs.triggeredByEvent)) {
- businessObject.triggeredByEvent = attrs.triggeredByEvent;
- delete attrs.triggeredByEvent;
- }
- if (isDefined(attrs.cancelActivity)) {
- businessObject.cancelActivity = attrs.cancelActivity;
- delete attrs.cancelActivity;
- }
- var eventDefinitions,
- newEventDefinition;
- if (attrs.eventDefinitionType) {
- eventDefinitions = businessObject.get('eventDefinitions') || [];
- newEventDefinition = this._bpmnFactory.create(attrs.eventDefinitionType, attrs.eventDefinitionAttrs);
- if (attrs.eventDefinitionType === 'bpmn:ConditionalEventDefinition') {
- newEventDefinition.condition = this._bpmnFactory.create('bpmn:FormalExpression');
- }
- eventDefinitions.push(newEventDefinition);
- newEventDefinition.$parent = businessObject;
- businessObject.eventDefinitions = eventDefinitions;
- delete attrs.eventDefinitionType;
- }
- size = this.getDefaultSize(businessObject, di);
- attrs = assign({
- id: businessObject.id
- }, size, attrs, {
- businessObject: businessObject,
- di: di
- });
- return this._baseCreate(elementType, attrs);
- };
- /**
- * Get the default size of a diagram element.
- *
- * @param {Element} element The element.
- * @param {ModdleElement} di The DI.
- *
- * @return {Dimensions} Default width and height of the element.
- */
- ElementFactory.prototype.getDefaultSize = function(element, di) {
- var bo = getBusinessObject(element);
- di = di || getDi(element);
- if (is(bo, 'bpmn:SubProcess')) {
- if (isExpanded(bo, di)) {
- return { width: 350, height: 200 };
- } else {
- return { width: 100, height: 80 };
- }
- }
- if (is(bo, 'bpmn:Task')) {
- return { width: 100, height: 80 };
- }
- if (is(bo, 'bpmn:Gateway')) {
- return { width: 50, height: 50 };
- }
- if (is(bo, 'bpmn:Event')) {
- return { width: 36, height: 36 };
- }
- if (is(bo, 'bpmn:Participant')) {
- if (isExpanded(bo, di)) {
- return { width: 600, height: 250 };
- } else {
- return { width: 400, height: 60 };
- }
- }
- if (is(bo, 'bpmn:Lane')) {
- return { width: 400, height: 100 };
- }
- if (is(bo, 'bpmn:DataObjectReference')) {
- return { width: 36, height: 50 };
- }
- if (is(bo, 'bpmn:DataStoreReference')) {
- return { width: 50, height: 50 };
- }
- if (is(bo, 'bpmn:TextAnnotation')) {
- return { width: 100, height: 30 };
- }
- if (is(bo, 'bpmn:Group')) {
- return { width: 300, height: 300 };
- }
- return { width: 100, height: 80 };
- };
- /**
- * Create participant.
- *
- * @param {boolean|Partial<Shape> & Partial<BpmnAttributes>} [attrs]
- * Attributes or whether the participant is expanded.
- *
- * @return {W} The created participant.
- */
- ElementFactory.prototype.createParticipantShape = function(attrs) {
- if (!isObject(attrs)) {
- attrs = { isExpanded: attrs };
- }
- attrs = assign({ type: 'bpmn:Participant' }, attrs || {});
- // participants are expanded by default
- if (attrs.isExpanded !== false) {
- attrs.processRef = this._bpmnFactory.create('bpmn:Process');
- }
- return this.createShape(attrs);
- };
- // helpers //////////////////////
- /**
- * Apply attributes from a map to the given element, remove attribute from the
- * map on application.
- *
- * @param {Element} element
- * @param {Object} attrs (in/out map of attributes)
- * @param {string[]} attributeNames name of attributes to apply
- *
- * @return {Object} changed attrs
- */
- function applyAttributes(element, attrs, attributeNames) {
- forEach(attributeNames, function(property) {
- attrs = applyAttribute(element, attrs, property);
- });
- return attrs;
- }
- /**
- * Apply named property to element and drain it from the attrs collection.
- *
- * @param {Element} element
- * @param {Object} attrs (in/out map of attributes)
- * @param {string} attributeName to apply
- *
- * @return {Object} changed attrs
- */
- function applyAttribute(element, attrs, attributeName) {
- if (attrs[attributeName] === undefined) {
- return attrs;
- }
- element[attributeName] = attrs[attributeName];
- return omit(attrs, [ attributeName ]);
- }
- /**
- * @param {Element} element
- *
- * @return {boolean}
- */
- function isModdleDi(element) {
- return isAny(element, [
- 'bpmndi:BPMNShape',
- 'bpmndi:BPMNEdge',
- 'bpmndi:BPMNDiagram',
- 'bpmndi:BPMNPlane',
- ]);
- }
|