BpmnCopyPaste.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. import {
  2. getBusinessObject,
  3. getDi,
  4. is
  5. } from '../../util/ModelUtil';
  6. import {
  7. forEach,
  8. isArray,
  9. isUndefined,
  10. omit,
  11. reduce
  12. } from 'min-dash';
  13. import { isLabel } from '../../util/LabelUtil';
  14. /**
  15. * @typedef {import('../modeling/BpmnFactory').default} BpmnFactory
  16. * @typedef {import('diagram-js/lib/core/EventBus').default} EventBus
  17. * @typedef {import('./ModdleCopy').default} ModdleCopy
  18. */
  19. function copyProperties(source, target, properties) {
  20. if (!isArray(properties)) {
  21. properties = [ properties ];
  22. }
  23. forEach(properties, function(property) {
  24. if (!isUndefined(source[property])) {
  25. target[property] = source[property];
  26. }
  27. });
  28. }
  29. var LOW_PRIORITY = 750;
  30. /**
  31. * BPMN-specific copy & paste.
  32. *
  33. * @param {BpmnFactory} bpmnFactory
  34. * @param {EventBus} eventBus
  35. * @param {ModdleCopy} moddleCopy
  36. */
  37. export default function BpmnCopyPaste(bpmnFactory, eventBus, moddleCopy) {
  38. function copy(bo, clone) {
  39. var targetBo = bpmnFactory.create(bo.$type);
  40. return moddleCopy.copyElement(bo, targetBo, null, clone);
  41. }
  42. eventBus.on('copyPaste.copyElement', LOW_PRIORITY, function(context) {
  43. var descriptor = context.descriptor,
  44. element = context.element,
  45. businessObject = getBusinessObject(element);
  46. // do not copy business object + di for labels;
  47. // will be pulled from the referenced label target
  48. if (isLabel(element)) {
  49. return descriptor;
  50. }
  51. var businessObjectCopy = descriptor.businessObject = copy(businessObject, true);
  52. var diCopy = descriptor.di = copy(getDi(element), true);
  53. diCopy.bpmnElement = businessObjectCopy;
  54. copyProperties(businessObjectCopy, descriptor, 'name');
  55. copyProperties(diCopy, descriptor, 'isExpanded');
  56. // default sequence flow
  57. if (businessObject.default) {
  58. descriptor.default = businessObject.default.id;
  59. }
  60. });
  61. var referencesKey = '-bpmn-js-refs';
  62. function getReferences(cache) {
  63. return (cache[referencesKey] = cache[referencesKey] || {});
  64. }
  65. function setReferences(cache, references) {
  66. cache[referencesKey] = references;
  67. }
  68. function resolveReferences(descriptor, cache, references) {
  69. var businessObject = getBusinessObject(descriptor);
  70. // default sequence flows
  71. if (descriptor.default) {
  72. // relationship cannot be resolved immediately
  73. references[ descriptor.default ] = {
  74. element: businessObject,
  75. property: 'default'
  76. };
  77. }
  78. // boundary events
  79. if (descriptor.host) {
  80. // relationship can be resolved immediately
  81. getBusinessObject(descriptor).attachedToRef = getBusinessObject(cache[ descriptor.host ]);
  82. }
  83. return omit(references, reduce(references, function(array, reference, key) {
  84. var element = reference.element,
  85. property = reference.property;
  86. if (key === descriptor.id) {
  87. element.set(property, businessObject);
  88. array.push(descriptor.id);
  89. }
  90. return array;
  91. }, []));
  92. }
  93. eventBus.on('copyPaste.pasteElement', function(context) {
  94. var cache = context.cache,
  95. descriptor = context.descriptor,
  96. businessObject = descriptor.businessObject,
  97. di = descriptor.di;
  98. // wire existing di + businessObject for external label
  99. if (isLabel(descriptor)) {
  100. descriptor.businessObject = getBusinessObject(cache[ descriptor.labelTarget ]);
  101. descriptor.di = getDi(cache[ descriptor.labelTarget ]);
  102. return;
  103. }
  104. businessObject = descriptor.businessObject = copy(businessObject);
  105. di = descriptor.di = copy(di);
  106. di.bpmnElement = businessObject;
  107. copyProperties(descriptor, businessObject, [
  108. 'isExpanded',
  109. 'name'
  110. ]);
  111. descriptor.type = businessObject.$type;
  112. });
  113. // copy + paste processRef with participant
  114. eventBus.on('copyPaste.copyElement', LOW_PRIORITY, function(context) {
  115. var descriptor = context.descriptor,
  116. element = context.element;
  117. if (!is(element, 'bpmn:Participant')) {
  118. return;
  119. }
  120. var participantBo = getBusinessObject(element);
  121. if (participantBo.processRef) {
  122. descriptor.processRef = copy(participantBo.processRef, true);
  123. }
  124. });
  125. eventBus.on('copyPaste.pasteElement', function(context) {
  126. var descriptor = context.descriptor,
  127. processRef = descriptor.processRef;
  128. if (processRef) {
  129. descriptor.processRef = copy(processRef);
  130. }
  131. });
  132. // resolve references
  133. eventBus.on('copyPaste.pasteElement', LOW_PRIORITY, function(context) {
  134. var cache = context.cache,
  135. descriptor = context.descriptor;
  136. // resolve references e.g. default sequence flow
  137. setReferences(
  138. cache,
  139. resolveReferences(descriptor, cache, getReferences(cache))
  140. );
  141. });
  142. }
  143. BpmnCopyPaste.$inject = [
  144. 'bpmnFactory',
  145. 'eventBus',
  146. 'moddleCopy'
  147. ];