ReplaceElementBehaviour.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. import inherits from 'inherits-browser';
  2. import { forEach, reduce } from 'min-dash';
  3. import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
  4. import { isEventSubProcess } from '../../../util/DiUtil';
  5. /**
  6. * @typedef {import('../../replace/BpmnReplace').default} BpmnReplace
  7. * @typedef {import('../../rules/BpmnRules').default} BpmnRules
  8. * @typedef {import('diagram-js/lib/core/ElementRegistry').default} ElementRegistry
  9. * @typedef {import('didi').Injector} Injector
  10. * @typedef {import('../Modeling').default} Modeling
  11. * @typedef {import('diagram-js/lib/features/selection/Selection').default} Selection
  12. */
  13. /**
  14. * BPMN-specific replace behavior.
  15. *
  16. * @param {BpmnReplace} bpmnReplace
  17. * @param {BpmnRules} bpmnRules
  18. * @param {ElementRegistry} elementRegistry
  19. * @param {Injector} injector
  20. * @param {Modeling} modeling
  21. * @param {Selection} selection
  22. */
  23. export default function ReplaceElementBehaviour(
  24. bpmnReplace,
  25. bpmnRules,
  26. elementRegistry,
  27. injector,
  28. modeling,
  29. selection
  30. ) {
  31. injector.invoke(CommandInterceptor, this);
  32. this._bpmnReplace = bpmnReplace;
  33. this._elementRegistry = elementRegistry;
  34. this._selection = selection;
  35. // replace elements on create, e.g. during copy-paste
  36. this.postExecuted([ 'elements.create' ], 500, function(event) {
  37. var context = event.context,
  38. target = context.parent,
  39. elements = context.elements;
  40. var elementReplacements = reduce(elements, function(replacements, element) {
  41. var canReplace = bpmnRules.canReplace([ element ], element.host || element.parent || target);
  42. return canReplace ? replacements.concat(canReplace.replacements) : replacements;
  43. }, []);
  44. if (elementReplacements.length) {
  45. this._replaceElements(elements, elementReplacements);
  46. }
  47. }, this);
  48. // replace elements on move
  49. this.postExecuted([ 'elements.move' ], 500, function(event) {
  50. var context = event.context,
  51. target = context.newParent,
  52. newHost = context.newHost,
  53. elements = [];
  54. forEach(context.closure.topLevel, function(topLevelElements) {
  55. if (isEventSubProcess(topLevelElements)) {
  56. elements = elements.concat(topLevelElements.children);
  57. } else {
  58. elements = elements.concat(topLevelElements);
  59. }
  60. });
  61. // set target to host if attaching
  62. if (elements.length === 1 && newHost) {
  63. target = newHost;
  64. }
  65. var canReplace = bpmnRules.canReplace(elements, target);
  66. if (canReplace) {
  67. this._replaceElements(elements, canReplace.replacements, newHost);
  68. }
  69. }, this);
  70. // update attachments on host replace
  71. this.postExecute([ 'shape.replace' ], 1500, function(e) {
  72. var context = e.context,
  73. oldShape = context.oldShape,
  74. newShape = context.newShape,
  75. attachers = oldShape.attachers,
  76. canReplace;
  77. if (attachers && attachers.length) {
  78. canReplace = bpmnRules.canReplace(attachers, newShape);
  79. this._replaceElements(attachers, canReplace.replacements);
  80. }
  81. }, this);
  82. // keep ID on shape replace
  83. this.postExecuted([ 'shape.replace' ], 1500, function(e) {
  84. var context = e.context,
  85. oldShape = context.oldShape,
  86. newShape = context.newShape;
  87. modeling.unclaimId(oldShape.businessObject.id, oldShape.businessObject);
  88. modeling.updateProperties(newShape, { id: oldShape.id });
  89. });
  90. }
  91. inherits(ReplaceElementBehaviour, CommandInterceptor);
  92. ReplaceElementBehaviour.prototype._replaceElements = function(elements, newElements) {
  93. var elementRegistry = this._elementRegistry,
  94. bpmnReplace = this._bpmnReplace,
  95. selection = this._selection;
  96. forEach(newElements, function(replacement) {
  97. var newElement = {
  98. type: replacement.newElementType
  99. };
  100. var oldElement = elementRegistry.get(replacement.oldElementId);
  101. var idx = elements.indexOf(oldElement);
  102. elements[idx] = bpmnReplace.replaceElement(oldElement, newElement, { select: false });
  103. });
  104. if (newElements) {
  105. selection.select(elements);
  106. }
  107. };
  108. ReplaceElementBehaviour.$inject = [
  109. 'bpmnReplace',
  110. 'bpmnRules',
  111. 'elementRegistry',
  112. 'injector',
  113. 'modeling',
  114. 'selection'
  115. ];