bpmn-js 18.22.1 → 18.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/bpmn-modeler.development.js +1040 -323
  2. package/dist/bpmn-modeler.production.min.js +12 -12
  3. package/dist/bpmn-navigated-viewer.development.js +2 -2
  4. package/dist/bpmn-navigated-viewer.production.min.js +1 -1
  5. package/dist/bpmn-viewer.development.js +2 -2
  6. package/dist/bpmn-viewer.production.min.js +1 -1
  7. package/lib/features/modeling/Modeling.d.ts +13 -0
  8. package/lib/features/modeling/Modeling.d.ts.map +1 -1
  9. package/lib/features/modeling/Modeling.js +21 -0
  10. package/lib/features/modeling/behavior/CategoryRootElementReferenceBehavior.d.ts +19 -0
  11. package/lib/features/modeling/behavior/CategoryRootElementReferenceBehavior.d.ts.map +1 -0
  12. package/lib/features/modeling/behavior/CategoryRootElementReferenceBehavior.js +157 -0
  13. package/lib/features/modeling/behavior/GroupBehavior.d.ts +2 -8
  14. package/lib/features/modeling/behavior/GroupBehavior.d.ts.map +1 -1
  15. package/lib/features/modeling/behavior/GroupBehavior.js +65 -134
  16. package/lib/features/modeling/behavior/UpdateCategoryValueRefsBehavior.d.ts +17 -0
  17. package/lib/features/modeling/behavior/UpdateCategoryValueRefsBehavior.d.ts.map +1 -0
  18. package/lib/features/modeling/behavior/UpdateCategoryValueRefsBehavior.js +169 -0
  19. package/lib/features/modeling/behavior/UpdateFlowNodeRefsBehavior.d.ts +1 -1
  20. package/lib/features/modeling/behavior/UpdateFlowNodeRefsBehavior.d.ts.map +1 -1
  21. package/lib/features/modeling/behavior/UpdateFlowNodeRefsBehavior.js +35 -37
  22. package/lib/features/modeling/behavior/index.d.ts +4 -0
  23. package/lib/features/modeling/behavior/index.d.ts.map +1 -1
  24. package/lib/features/modeling/behavior/index.js +6 -0
  25. package/lib/features/modeling/behavior/util/CategoryUtil.d.ts +12 -3
  26. package/lib/features/modeling/behavior/util/CategoryUtil.d.ts.map +1 -1
  27. package/lib/features/modeling/behavior/util/CategoryUtil.js +25 -2
  28. package/lib/features/modeling/cmd/UpdateCategoryValueRefsHandler.d.ts +40 -0
  29. package/lib/features/modeling/cmd/UpdateCategoryValueRefsHandler.d.ts.map +1 -0
  30. package/lib/features/modeling/cmd/UpdateCategoryValueRefsHandler.js +424 -0
  31. package/lib/features/modeling/cmd/UpdateFlowNodeRefsHandler.d.ts +0 -8
  32. package/lib/features/modeling/cmd/UpdateFlowNodeRefsHandler.d.ts.map +1 -1
  33. package/lib/features/modeling/cmd/UpdateFlowNodeRefsHandler.js +1 -9
  34. package/lib/features/rules/BpmnRules.js +38 -0
  35. package/package.json +2 -2
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * bpmn-js - bpmn-modeler v18.22.1
2
+ * bpmn-js - bpmn-modeler v18.23.0
3
3
  *
4
4
  * Copyright (c) 2014-present, camunda Services GmbH
5
5
  *
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * Source Code: https://github.com/bpmn-io/bpmn-js
10
10
  *
11
- * Date: 2026-07-29
11
+ * Date: 2026-08-10
12
12
  */
13
13
  (function (global, factory) {
14
14
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
@@ -22571,7 +22571,7 @@
22571
22571
  // document wide unique overlay ids
22572
22572
  var ids$2 = new IdGenerator('ov');
22573
22573
 
22574
- var LOW_PRIORITY$q = 500;
22574
+ var LOW_PRIORITY$s = 500;
22575
22575
 
22576
22576
  /**
22577
22577
  * @typedef {import('../../core/Canvas.js').default} Canvas
@@ -23201,7 +23201,7 @@
23201
23201
 
23202
23202
  // move integration
23203
23203
 
23204
- eventBus.on('element.changed', LOW_PRIORITY$q, function(e) {
23204
+ eventBus.on('element.changed', LOW_PRIORITY$s, function(e) {
23205
23205
  var element = e.element;
23206
23206
 
23207
23207
  var container = self._getOverlayContainer(element, true);
@@ -24283,7 +24283,7 @@
24283
24283
  * @typedef {import('../../model/Types').Shape} Shape
24284
24284
  */
24285
24285
 
24286
- var LOW_PRIORITY$p = 250;
24286
+ var LOW_PRIORITY$r = 250;
24287
24287
  var ARROW_DOWN_SVG = '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4.81801948,3.50735931 L10.4996894,9.1896894 L10.5,4 L12,4 L12,12 L4,12 L4,10.5 L9.6896894,10.4996894 L3.75735931,4.56801948 C3.46446609,4.27512627 3.46446609,3.80025253 3.75735931,3.50735931 C4.05025253,3.21446609 4.52512627,3.21446609 4.81801948,3.50735931 Z"/></svg>';
24288
24288
 
24289
24289
  var EMPTY_MARKER = 'bjs-drilldown-empty';
@@ -24308,7 +24308,7 @@
24308
24308
 
24309
24309
  var self = this;
24310
24310
 
24311
- this.executed('shape.toggleCollapse', LOW_PRIORITY$p, function(context) {
24311
+ this.executed('shape.toggleCollapse', LOW_PRIORITY$r, function(context) {
24312
24312
  var shape = context.shape;
24313
24313
 
24314
24314
  // Add overlay to the collapsed shape
@@ -24320,7 +24320,7 @@
24320
24320
  }, true);
24321
24321
 
24322
24322
 
24323
- this.reverted('shape.toggleCollapse', LOW_PRIORITY$p, function(context) {
24323
+ this.reverted('shape.toggleCollapse', LOW_PRIORITY$r, function(context) {
24324
24324
  var shape = context.shape;
24325
24325
 
24326
24326
  // Add overlay to the collapsed shape
@@ -24332,7 +24332,7 @@
24332
24332
  }, true);
24333
24333
 
24334
24334
 
24335
- this.executed([ 'shape.create', 'shape.move', 'shape.delete' ], LOW_PRIORITY$p,
24335
+ this.executed([ 'shape.create', 'shape.move', 'shape.delete' ], LOW_PRIORITY$r,
24336
24336
  function(context) {
24337
24337
  var oldParent = context.oldParent,
24338
24338
  newParent = context.newParent || context.parent,
@@ -24349,7 +24349,7 @@
24349
24349
  }, true);
24350
24350
 
24351
24351
 
24352
- this.reverted([ 'shape.create', 'shape.move', 'shape.delete' ], LOW_PRIORITY$p,
24352
+ this.reverted([ 'shape.create', 'shape.move', 'shape.delete' ], LOW_PRIORITY$r,
24353
24353
  function(context) {
24354
24354
  var oldParent = context.oldParent,
24355
24355
  newParent = context.newParent || context.parent,
@@ -24626,7 +24626,7 @@
24626
24626
  return isPrimaryButton(event) || isAuxiliaryButton(event);
24627
24627
  }
24628
24628
 
24629
- var LOW_PRIORITY$o = 500;
24629
+ var LOW_PRIORITY$q = 500;
24630
24630
 
24631
24631
 
24632
24632
  /**
@@ -24823,7 +24823,7 @@
24823
24823
  eventBus.on([
24824
24824
  'shape.changed',
24825
24825
  'connection.changed'
24826
- ], LOW_PRIORITY$o, function(event) {
24826
+ ], LOW_PRIORITY$q, function(event) {
24827
24827
 
24828
24828
  var element = event.element,
24829
24829
  gfx = event.gfx;
@@ -24831,7 +24831,7 @@
24831
24831
  eventBus.fire('interactionEvents.updateHit', { element: element, gfx: gfx });
24832
24832
  });
24833
24833
 
24834
- eventBus.on('interactionEvents.createHit', LOW_PRIORITY$o, function(event) {
24834
+ eventBus.on('interactionEvents.createHit', LOW_PRIORITY$q, function(event) {
24835
24835
  var element = event.element,
24836
24836
  gfx = event.gfx;
24837
24837
 
@@ -25794,7 +25794,7 @@
25794
25794
  Keyboard.prototype.isShift = isShift;
25795
25795
  Keyboard.prototype.isKey = isKey;
25796
25796
 
25797
- var LOW_PRIORITY$n = 500;
25797
+ var LOW_PRIORITY$p = 500;
25798
25798
 
25799
25799
 
25800
25800
  /**
@@ -25810,7 +25810,7 @@
25810
25810
 
25811
25811
  var self = this;
25812
25812
 
25813
- eventBus.on('editorActions.init', LOW_PRIORITY$n, function(event) {
25813
+ eventBus.on('editorActions.init', LOW_PRIORITY$p, function(event) {
25814
25814
 
25815
25815
  var editorActions = event.editorActions;
25816
25816
 
@@ -29804,7 +29804,7 @@
29804
29804
  * @typedef {import('diagram-js/lib/features/context-pad/ContextPadProvider').default<Element>} ContextPadProvider
29805
29805
  */
29806
29806
 
29807
- var LOW_PRIORITY$m = 900;
29807
+ var LOW_PRIORITY$o = 900;
29808
29808
 
29809
29809
  /**
29810
29810
  * A provider for the `Align elements` context pad entry.
@@ -29818,7 +29818,7 @@
29818
29818
  */
29819
29819
  function AlignElementsContextPadProvider(contextPad, popupMenu, translate, canvas) {
29820
29820
 
29821
- contextPad.registerProvider(LOW_PRIORITY$m, this);
29821
+ contextPad.registerProvider(LOW_PRIORITY$o, this);
29822
29822
 
29823
29823
  this._contextPad = contextPad;
29824
29824
  this._popupMenu = popupMenu;
@@ -30448,7 +30448,7 @@
30448
30448
  * @typedef {import('../modeling/Modeling.js').default} Modeling
30449
30449
  */
30450
30450
 
30451
- var LOW_PRIORITY$l = 100;
30451
+ var LOW_PRIORITY$n = 100;
30452
30452
 
30453
30453
 
30454
30454
  /**
@@ -30461,7 +30461,7 @@
30461
30461
  */
30462
30462
  function AutoPlace$1(eventBus, modeling, canvas) {
30463
30463
 
30464
- eventBus.on('autoPlace', LOW_PRIORITY$l, function(context) {
30464
+ eventBus.on('autoPlace', LOW_PRIORITY$n, function(context) {
30465
30465
  var shape = context.shape,
30466
30466
  source = context.source;
30467
30467
 
@@ -31324,7 +31324,7 @@
31324
31324
  * @typedef {import('../../core/EventBus.js').default} EventBus
31325
31325
  */
31326
31326
 
31327
- var HIGH_PRIORITY$l = 1500;
31327
+ var HIGH_PRIORITY$m = 1500;
31328
31328
 
31329
31329
 
31330
31330
  /**
@@ -31392,7 +31392,7 @@
31392
31392
  */
31393
31393
  eventBus.on('drag.start', function(event) {
31394
31394
 
31395
- eventBus.once('drag.move', HIGH_PRIORITY$l, function(event) {
31395
+ eventBus.once('drag.move', HIGH_PRIORITY$m, function(event) {
31396
31396
 
31397
31397
  ensureHover(event);
31398
31398
 
@@ -31423,7 +31423,7 @@
31423
31423
  hover = event.element;
31424
31424
  });
31425
31425
 
31426
- eventBus.on('element.hover', HIGH_PRIORITY$l, function(event) {
31426
+ eventBus.on('element.hover', HIGH_PRIORITY$m, function(event) {
31427
31427
 
31428
31428
  // (3) am I on an element still?
31429
31429
  if (hover) {
@@ -33402,7 +33402,7 @@
33402
33402
  MARKER_CONNECT_UPDATING$1 = 'djs-updating',
33403
33403
  MARKER_DRAGGER = 'djs-dragging';
33404
33404
 
33405
- var HIGH_PRIORITY$k = 1100;
33405
+ var HIGH_PRIORITY$l = 1100;
33406
33406
 
33407
33407
  /**
33408
33408
  * Preview connection while moving bendpoints.
@@ -33470,7 +33470,7 @@
33470
33470
  eventBus.on([
33471
33471
  'bendpoint.move.out',
33472
33472
  'bendpoint.move.cleanup'
33473
- ], HIGH_PRIORITY$k, function(event) {
33473
+ ], HIGH_PRIORITY$l, function(event) {
33474
33474
  var context = event.context,
33475
33475
  hover = context.hover,
33476
33476
  target = context.target;
@@ -33556,7 +33556,7 @@
33556
33556
  eventBus.on([
33557
33557
  'bendpoint.move.end',
33558
33558
  'bendpoint.move.cancel'
33559
- ], HIGH_PRIORITY$k, function(event) {
33559
+ ], HIGH_PRIORITY$l, function(event) {
33560
33560
  var context = event.context,
33561
33561
  connection = context.connection,
33562
33562
  draggerGfx = context.draggerGfx,
@@ -34572,8 +34572,8 @@
34572
34572
  * @typedef {import('../../core/EventBus.js').default} EventBus
34573
34573
  */
34574
34574
 
34575
- var HIGH_PRIORITY$j = 1100,
34576
- LOW_PRIORITY$k = 900;
34575
+ var HIGH_PRIORITY$k = 1100,
34576
+ LOW_PRIORITY$m = 900;
34577
34577
 
34578
34578
  var MARKER_OK$3 = 'connect-ok',
34579
34579
  MARKER_NOT_OK$3 = 'connect-not-ok';
@@ -34617,7 +34617,7 @@
34617
34617
  });
34618
34618
  });
34619
34619
 
34620
- eventBus.on('connect.hover', LOW_PRIORITY$k, function(event) {
34620
+ eventBus.on('connect.hover', LOW_PRIORITY$m, function(event) {
34621
34621
  var context = event.context,
34622
34622
  hover = event.hover,
34623
34623
  canExecute = context.canExecute;
@@ -34633,7 +34633,7 @@
34633
34633
  eventBus.on([
34634
34634
  'connect.out',
34635
34635
  'connect.cleanup'
34636
- ], HIGH_PRIORITY$j, function(event) {
34636
+ ], HIGH_PRIORITY$k, function(event) {
34637
34637
  var hover = event.hover;
34638
34638
 
34639
34639
  if (hover) {
@@ -35685,7 +35685,7 @@
35685
35685
  * @typedef {import('../../../model/Types').Element} Element
35686
35686
  */
35687
35687
 
35688
- var HIGH_PRIORITY$i = 1500;
35688
+ var HIGH_PRIORITY$j = 1500;
35689
35689
 
35690
35690
  /**
35691
35691
  * A behavior that ensures that visually enclosed artifacts are affected
@@ -35706,7 +35706,7 @@
35706
35706
  injector.invoke(CommandInterceptor, this);
35707
35707
 
35708
35708
  // enclosed artifacts are deleted with a container element
35709
- this.preExecute('elements.delete', HIGH_PRIORITY$i, function(event) {
35709
+ this.preExecute('elements.delete', HIGH_PRIORITY$j, function(event) {
35710
35710
  var context = event.context,
35711
35711
  elements = context.elements;
35712
35712
 
@@ -35819,7 +35819,7 @@
35819
35819
  * @typedef {import('didi').Injector} Injector
35820
35820
  */
35821
35821
 
35822
- var LOW_PRIORITY$j = 500;
35822
+ var LOW_PRIORITY$l = 500;
35823
35823
 
35824
35824
 
35825
35825
  /**
@@ -35835,7 +35835,7 @@
35835
35835
 
35836
35836
  var self = this;
35837
35837
 
35838
- this.postExecuted('elements.create', LOW_PRIORITY$j, function(context) {
35838
+ this.postExecuted('elements.create', LOW_PRIORITY$l, function(context) {
35839
35839
  var elements = context.elements;
35840
35840
 
35841
35841
  elements = elements.filter(function(shape) {
@@ -35858,7 +35858,7 @@
35858
35858
  }, true);
35859
35859
 
35860
35860
 
35861
- this.preExecute('elements.move', LOW_PRIORITY$j, function(context) {
35861
+ this.preExecute('elements.move', LOW_PRIORITY$l, function(context) {
35862
35862
  var shapes = context.shapes,
35863
35863
  host = context.newHost;
35864
35864
 
@@ -35976,6 +35976,255 @@
35976
35976
 
35977
35977
  e$3(BoundaryEventBehavior, CommandInterceptor);
35978
35978
 
35979
+ /**
35980
+ * @typedef {import('../../BpmnFactory').default} BpmnFactory
35981
+ *
35982
+ * @typedef {import('../../../../model/Types').ModdleElement} ModdleElement
35983
+ */
35984
+
35985
+ /**
35986
+ * Creates a new bpmn:CategoryValue inside a new bpmn:Category
35987
+ *
35988
+ * @param {BpmnFactory} bpmnFactory
35989
+ *
35990
+ * @return {ModdleElement}
35991
+ */
35992
+ function createCategory(bpmnFactory) {
35993
+ return bpmnFactory.create('bpmn:Category');
35994
+ }
35995
+
35996
+ /**
35997
+ * Creates a new bpmn:CategoryValue inside a new bpmn:Category
35998
+ *
35999
+ * @param {BpmnFactory} bpmnFactory
36000
+ *
36001
+ * @return {ModdleElement}
36002
+ */
36003
+ function createCategoryValue(bpmnFactory) {
36004
+ return bpmnFactory.create('bpmn:CategoryValue');
36005
+ }
36006
+
36007
+ /**
36008
+ * Returns a group's category value, creating one (including a
36009
+ * category) if needed.
36010
+ *
36011
+ * @param {BpmnFactory} bpmnFactory
36012
+ * @param {ModdleElement} groupBo
36013
+ *
36014
+ * @return {ModdleElement}
36015
+ */
36016
+ function getOrCreateCategoryValueForGroup(bpmnFactory, groupBo) {
36017
+ var categoryValue = groupBo.get('categoryValueRef');
36018
+
36019
+ if (!categoryValue) {
36020
+ categoryValue = groupBo.categoryValueRef = createCategoryValue(bpmnFactory);
36021
+ }
36022
+
36023
+ if (!categoryValue.$parent) {
36024
+ categoryValue.$parent = createCategory(bpmnFactory);
36025
+ }
36026
+
36027
+ return categoryValue;
36028
+ }
36029
+
36030
+ /**
36031
+ * Adds category value to definitions
36032
+ *
36033
+ * @param {ModdleElement} categoryValue
36034
+ * @param {ModdleElement} category
36035
+ * @param {ModdleElement} definitions
36036
+ *
36037
+ * @return {ModdleElement}
36038
+ */
36039
+ function linkCategoryValue(categoryValue, category, definitions) {
36040
+ add(category.get('categoryValue'), categoryValue);
36041
+ categoryValue.$parent = category;
36042
+
36043
+ add(definitions.get('rootElements'), category);
36044
+ category.$parent = definitions;
36045
+
36046
+ return categoryValue;
36047
+ }
36048
+
36049
+ /**
36050
+ * Unlink category value from parent
36051
+ *
36052
+ * @param {ModdleElement} categoryValue
36053
+ *
36054
+ * @return {ModdleElement}
36055
+ */
36056
+ function unlinkCategoryValue(categoryValue) {
36057
+ var category = categoryValue.$parent;
36058
+
36059
+ if (category) {
36060
+ remove(category.get('categoryValue'), categoryValue);
36061
+ categoryValue.$parent = null;
36062
+ }
36063
+
36064
+ return categoryValue;
36065
+ }
36066
+
36067
+ /**
36068
+ * Unlink category from parent
36069
+ *
36070
+ * @param {ModdleElement} category
36071
+ *
36072
+ * @return {ModdleElement}
36073
+ */
36074
+ function unlinkCategory(category) {
36075
+ var definitions = category.$parent;
36076
+
36077
+ if (definitions) {
36078
+ remove(definitions.get('rootElements'), category);
36079
+ category.$parent = null;
36080
+ }
36081
+
36082
+ return category;
36083
+ }
36084
+
36085
+ var LOW_PRIORITY$k = 500;
36086
+
36087
+ /**
36088
+ * @typedef {import('../../../Modeler').default} Modeler
36089
+ * @typedef {import('diagram-js/lib/core/ElementRegistry').default} ElementRegistry
36090
+ * @typedef {import('didi').Injector} Injector
36091
+ */
36092
+
36093
+ /**
36094
+ * Maintains a group's category (value) inside definitions#rootElements.
36095
+ *
36096
+ * @param {Modeler} bpmnjs
36097
+ * @param {ElementRegistry} elementRegistry
36098
+ * @param {Injector} injector
36099
+ */
36100
+ function CategoryRootElementReferenceBehavior(
36101
+ bpmnjs, elementRegistry, injector
36102
+ ) {
36103
+ injector.invoke(CommandInterceptor, this);
36104
+
36105
+ function getGroupBusinessObjects(ignoredBusinessObject) {
36106
+ return elementRegistry.filter(function(element) {
36107
+ return is(element, 'bpmn:Group') && !element.labelTarget;
36108
+ }).map(getBusinessObject).filter(function(businessObject) {
36109
+ return businessObject !== ignoredBusinessObject;
36110
+ });
36111
+ }
36112
+
36113
+ function isCategoryValueReferenced(categoryValue, ignoredBusinessObject) {
36114
+ return getGroupBusinessObjects(ignoredBusinessObject).some(function(businessObject) {
36115
+ return businessObject.get('categoryValueRef') === categoryValue;
36116
+ });
36117
+ }
36118
+
36119
+ function isCategoryReferenced(category, ignoredBusinessObject) {
36120
+ return getGroupBusinessObjects(ignoredBusinessObject).some(function(businessObject) {
36121
+ var categoryValue = businessObject.get('categoryValueRef');
36122
+
36123
+ return categoryValue && categoryValue.$parent === category;
36124
+ });
36125
+ }
36126
+
36127
+ function link(categoryValue, category) {
36128
+ if (categoryValue && category) {
36129
+ linkCategoryValue(categoryValue, category, bpmnjs.getDefinitions());
36130
+ }
36131
+ }
36132
+
36133
+ function unlink(categoryValue, category, ignoredBusinessObject) {
36134
+ if (category && !isCategoryReferenced(category, ignoredBusinessObject)) {
36135
+ unlinkCategory(category);
36136
+ }
36137
+
36138
+ if (categoryValue && !isCategoryValueReferenced(categoryValue, ignoredBusinessObject)) {
36139
+ unlinkCategoryValue(categoryValue);
36140
+ }
36141
+ }
36142
+
36143
+
36144
+ this.executed([ 'shape.create', 'label.create' ], function(context) {
36145
+ var shape = context.labelTarget || context.shape;
36146
+
36147
+ if (!is(shape, 'bpmn:Group') || shape.labelTarget) {
36148
+ return;
36149
+ }
36150
+
36151
+ link(context.categoryValue, context.category);
36152
+ }, true);
36153
+
36154
+ this.reverted([ 'shape.create', 'label.create' ], function(context) {
36155
+ var shape = context.labelTarget || context.shape;
36156
+
36157
+ if (!is(shape, 'bpmn:Group') || shape.labelTarget) {
36158
+ return;
36159
+ }
36160
+
36161
+ unlink(context.categoryValue, context.category, getBusinessObject(shape));
36162
+ }, true);
36163
+
36164
+ this.executed([ 'shape.move', 'shape.resize' ], LOW_PRIORITY$k, function(context) {
36165
+ link(context.categoryValue, context.category);
36166
+ }, true);
36167
+
36168
+ this.reverted([ 'shape.move', 'shape.resize' ], function(context) {
36169
+ var shape = context.shape;
36170
+
36171
+ if (context.categoryValue) {
36172
+ unlink(context.categoryValue, context.category, getBusinessObject(shape));
36173
+ }
36174
+ }, true);
36175
+
36176
+ this.executed('group.updateRefs', function(context) {
36177
+ getGroupUpdates(context).forEach(function(update) {
36178
+ link(update.categoryValue, update.category);
36179
+ });
36180
+ }, true);
36181
+
36182
+ this.reverted('group.updateRefs', function(context) {
36183
+ getGroupUpdates(context).forEach(function(update) {
36184
+ unlink(
36185
+ update.categoryValue,
36186
+ update.category,
36187
+ getBusinessObject(update.groupShape)
36188
+ );
36189
+ });
36190
+ }, true);
36191
+
36192
+ this.executed('shape.delete', function(context) {
36193
+ var shape = context.shape;
36194
+
36195
+ if (!is(shape, 'bpmn:Group') || shape.labelTarget) {
36196
+ return;
36197
+ }
36198
+
36199
+ unlink(context.categoryValue, context.category, getBusinessObject(shape));
36200
+ }, true);
36201
+
36202
+ this.reverted('shape.delete', function(context) {
36203
+ var shape = context.shape;
36204
+
36205
+ if (!is(shape, 'bpmn:Group') || shape.labelTarget) {
36206
+ return;
36207
+ }
36208
+
36209
+ link(context.categoryValue, context.category);
36210
+ }, true);
36211
+ }
36212
+
36213
+ CategoryRootElementReferenceBehavior.$inject = [
36214
+ 'bpmnjs',
36215
+ 'elementRegistry',
36216
+ 'injector'
36217
+ ];
36218
+
36219
+ e$3(CategoryRootElementReferenceBehavior, CommandInterceptor);
36220
+
36221
+
36222
+ // helpers //////////
36223
+
36224
+ function getGroupUpdates(context) {
36225
+ return context.updates?.groups || [];
36226
+ }
36227
+
35979
36228
  /**
35980
36229
  * @typedef {import('diagram-js/lib/core/EventBus').default} EventBus
35981
36230
  * @typedef {import('../lib/features/modeling/Modeling').default} Modeling
@@ -36272,7 +36521,7 @@
36272
36521
 
36273
36522
  var PARTICIPANT_BORDER_WIDTH = 30;
36274
36523
 
36275
- var HIGH_PRIORITY$h = 2000;
36524
+ var HIGH_PRIORITY$i = 2000;
36276
36525
 
36277
36526
 
36278
36527
  /**
@@ -36289,7 +36538,7 @@
36289
36538
  eventBus.on([
36290
36539
  'create.start',
36291
36540
  'shape.move.start'
36292
- ], HIGH_PRIORITY$h, function(event) {
36541
+ ], HIGH_PRIORITY$i, function(event) {
36293
36542
  var context = event.context,
36294
36543
  shape = context.shape,
36295
36544
  rootElement = canvas.getRootElement();
@@ -36324,7 +36573,7 @@
36324
36573
  });
36325
36574
 
36326
36575
  // force hovering process when creating first participant
36327
- eventBus.on('create.start', HIGH_PRIORITY$h, function(event) {
36576
+ eventBus.on('create.start', HIGH_PRIORITY$i, function(event) {
36328
36577
  var context = event.context,
36329
36578
  shape = context.shape,
36330
36579
  rootElement = canvas.getRootElement(),
@@ -36336,7 +36585,7 @@
36336
36585
  }
36337
36586
 
36338
36587
  if (is(shape, 'bpmn:Participant') && is(rootElement, 'bpmn:Process')) {
36339
- eventBus.on('element.hover', HIGH_PRIORITY$h, ensureHoveringProcess);
36588
+ eventBus.on('element.hover', HIGH_PRIORITY$i, ensureHoveringProcess);
36340
36589
 
36341
36590
  eventBus.once('create.cleanup', function() {
36342
36591
  eventBus.off('element.hover', ensureHoveringProcess);
@@ -36357,7 +36606,7 @@
36357
36606
 
36358
36607
  // when creating mutliple elements through `elements.create` parent must be set to collaboration
36359
36608
  // and passed to `shape.create` as hint
36360
- this.preExecute('elements.create', HIGH_PRIORITY$h, function(context) {
36609
+ this.preExecute('elements.create', HIGH_PRIORITY$i, function(context) {
36361
36610
  var elements = context.elements,
36362
36611
  parent = context.parent,
36363
36612
  participant = findParticipant(elements),
@@ -37293,7 +37542,7 @@
37293
37542
  * @typedef {import('../../space-tool/BpmnSpaceTool').default} SpaceTool
37294
37543
  */
37295
37544
 
37296
- var LOW_PRIORITY$i = 500;
37545
+ var LOW_PRIORITY$j = 500;
37297
37546
 
37298
37547
 
37299
37548
  /**
@@ -37406,7 +37655,7 @@
37406
37655
  /**
37407
37656
  * Adjust sizes of other lanes after lane deletion
37408
37657
  */
37409
- this.postExecuted('shape.delete', LOW_PRIORITY$i, function(event) {
37658
+ this.postExecuted('shape.delete', LOW_PRIORITY$j, function(event) {
37410
37659
 
37411
37660
  var context = event.context,
37412
37661
  hints = context.hints,
@@ -37439,7 +37688,7 @@
37439
37688
  * @typedef {import('didi').Injector} Injector
37440
37689
  */
37441
37690
 
37442
- var LOW_PRIORITY$h = 500;
37691
+ var LOW_PRIORITY$i = 500;
37443
37692
 
37444
37693
 
37445
37694
  /**
@@ -37455,7 +37704,7 @@
37455
37704
 
37456
37705
  var self = this;
37457
37706
 
37458
- this.postExecuted('elements.create', LOW_PRIORITY$h, function(context) {
37707
+ this.postExecuted('elements.create', LOW_PRIORITY$i, function(context) {
37459
37708
  var elements = context.elements;
37460
37709
 
37461
37710
  elements.filter(function(shape) {
@@ -37469,7 +37718,7 @@
37469
37718
  });
37470
37719
  }, true);
37471
37720
 
37472
- this.preExecute('elements.move', LOW_PRIORITY$h, function(context) {
37721
+ this.preExecute('elements.move', LOW_PRIORITY$i, function(context) {
37473
37722
  var shapes = context.shapes,
37474
37723
  newHost = context.newHost;
37475
37724
 
@@ -37842,7 +38091,7 @@
37842
38091
  * @typedef {import('diagram-js/lib/core/Canvas').default} Canvas
37843
38092
  */
37844
38093
 
37845
- var HIGH_PRIORITY$g = 1500;
38094
+ var HIGH_PRIORITY$h = 1500;
37846
38095
  var HIGHEST_PRIORITY = 2000;
37847
38096
 
37848
38097
 
@@ -37864,7 +38113,7 @@
37864
38113
  'shape.move.move',
37865
38114
  'shape.move.out',
37866
38115
  'shape.move.end'
37867
- ], HIGH_PRIORITY$g, function(event) {
38116
+ ], HIGH_PRIORITY$h, function(event) {
37868
38117
  var context = event.context,
37869
38118
  shape = context.shape || event.shape,
37870
38119
  hover = event.hover;
@@ -37896,7 +38145,7 @@
37896
38145
  'global-connect.out',
37897
38146
  'global-connect.end',
37898
38147
  'global-connect.cleanup'
37899
- ], HIGH_PRIORITY$g, function(event) {
38148
+ ], HIGH_PRIORITY$h, function(event) {
37900
38149
  var hover = event.hover;
37901
38150
 
37902
38151
  // ensure connections start/end on bpmn:Participant,
@@ -37910,7 +38159,7 @@
37910
38159
 
37911
38160
  eventBus.on([
37912
38161
  'bendpoint.move.hover'
37913
- ], HIGH_PRIORITY$g, function(event) {
38162
+ ], HIGH_PRIORITY$h, function(event) {
37914
38163
  var context = event.context,
37915
38164
  hover = event.hover,
37916
38165
  type = context.type;
@@ -37926,7 +38175,7 @@
37926
38175
 
37927
38176
  eventBus.on([
37928
38177
  'connect.start'
37929
- ], HIGH_PRIORITY$g, function(event) {
38178
+ ], HIGH_PRIORITY$h, function(event) {
37930
38179
  var context = event.context,
37931
38180
  start = context.start;
37932
38181
 
@@ -37965,101 +38214,12 @@
37965
38214
  'canvas'
37966
38215
  ];
37967
38216
 
37968
- /**
37969
- * @typedef {import('../../BpmnFactory').default} BpmnFactory
37970
- *
37971
- * @typedef {import('../../../model/Types').ModdleElement} ModdleElement
37972
- */
37973
-
37974
- /**
37975
- * Creates a new bpmn:CategoryValue inside a new bpmn:Category
37976
- *
37977
- * @param {BpmnFactory} bpmnFactory
37978
- *
37979
- * @return {ModdleElement}
37980
- */
37981
- function createCategory(bpmnFactory) {
37982
- return bpmnFactory.create('bpmn:Category');
37983
- }
37984
-
37985
- /**
37986
- * Creates a new bpmn:CategoryValue inside a new bpmn:Category
37987
- *
37988
- * @param {BpmnFactory} bpmnFactory
37989
- *
37990
- * @return {ModdleElement}
37991
- */
37992
- function createCategoryValue(bpmnFactory) {
37993
- return bpmnFactory.create('bpmn:CategoryValue');
37994
- }
37995
-
37996
- /**
37997
- * Adds category value to definitions
37998
- *
37999
- * @param {ModdleElement} categoryValue
38000
- * @param {ModdleElement} category
38001
- * @param {ModdleElement} definitions
38002
- *
38003
- * @return {ModdleElement}
38004
- */
38005
- function linkCategoryValue(categoryValue, category, definitions) {
38006
- add(category.get('categoryValue'), categoryValue);
38007
- categoryValue.$parent = category;
38008
-
38009
- add(definitions.get('rootElements'), category);
38010
- category.$parent = definitions;
38011
-
38012
- return categoryValue;
38013
- }
38014
-
38015
- /**
38016
- * Unlink category value from parent
38017
- *
38018
- * @param {ModdleElement} categoryValue
38019
- *
38020
- * @return {ModdleElement}
38021
- */
38022
- function unlinkCategoryValue(categoryValue) {
38023
- var category = categoryValue.$parent;
38024
-
38025
- if (category) {
38026
- remove(category.get('categoryValue'), categoryValue);
38027
- categoryValue.$parent = null;
38028
- }
38029
-
38030
- return categoryValue;
38031
- }
38032
-
38033
- /**
38034
- * Unlink category from parent
38035
- *
38036
- * @param {ModdleElement} category
38037
- *
38038
- * @return {ModdleElement}
38039
- */
38040
- function unlinkCategory(category) {
38041
- var definitions = category.$parent;
38042
-
38043
- if (definitions) {
38044
- remove(definitions.get('rootElements'), category);
38045
- category.$parent = null;
38046
- }
38047
-
38048
- return category;
38049
- }
38050
-
38051
38217
  /**
38052
38218
  * @typedef {import('../BpmnFactory').default} BpmnFactory
38053
- * @typedef {import('../../../Modeler').default} Modeler
38054
- * @typedef {import('diagram-js/lib/core/ElementRegistry').default} ElementRegistry
38055
38219
  * @typedef {import('diagram-js/lib/core/EventBus').default} EventBus
38220
+ * @typedef {import('diagram-js/lib/core/ElementRegistry').default} ElementRegistry
38056
38221
  * @typedef {import('didi').Injector} Injector
38057
38222
  * @typedef {import('../../copy-paste/ModdleCopy').default} ModdleCopy
38058
- *
38059
- * @typedef {import('../../../model/Types').Element} Element
38060
- * @typedef {import('../../../model/Types').Shape} Shape
38061
- *
38062
- * @typedef {import('diagram-js/lib/util/Types').DirectionTRBL} DirectionTRBL
38063
38223
  */
38064
38224
 
38065
38225
  var LOWER_PRIORITY$1 = 770;
@@ -38069,137 +38229,45 @@
38069
38229
  * BPMN specific group behavior.
38070
38230
  *
38071
38231
  * @param {BpmnFactory} bpmnFactory
38072
- * @param {Modeler} bpmnjs
38073
- * @param {ElementRegistry} elementRegistry
38074
38232
  * @param {EventBus} eventBus
38075
38233
  * @param {Injector} injector
38076
38234
  * @param {ModdleCopy} moddleCopy
38077
38235
  */
38078
38236
  function GroupBehavior(
38079
38237
  bpmnFactory,
38080
- bpmnjs,
38081
- elementRegistry,
38082
38238
  eventBus,
38083
38239
  injector,
38084
38240
  moddleCopy
38085
38241
  ) {
38086
38242
  injector.invoke(CommandInterceptor, this);
38087
38243
 
38088
- /**
38089
- * Returns all group element in the current registry.
38090
- *
38091
- * @return {Shape[]}
38092
- */
38093
- function getGroupElements() {
38094
- return elementRegistry.filter(function(e) {
38095
- return is(e, 'bpmn:Group');
38096
- });
38097
- }
38098
-
38099
- /**
38100
- * Returns true if given category is referenced in one of the given elements.
38101
- *
38102
- * @param {Element[]} elements
38103
- * @param {ModdleElement} category
38104
- *
38105
- * @return {boolean}
38106
- */
38107
- function isReferencedCategory(elements, category) {
38108
- return elements.some(function(element) {
38109
- var businessObject = getBusinessObject(element);
38110
-
38111
- var _category = businessObject.categoryValueRef && businessObject.categoryValueRef.$parent;
38112
-
38113
- return _category === category;
38114
- });
38115
- }
38116
-
38117
- /**
38118
- * Returns true if given categoryValue is referenced in one of the given elements.
38119
- *
38120
- * @param {Element[]} elements
38121
- * @param {ModdleElement} categoryValue
38122
- *
38123
- * @return {boolean}
38124
- */
38125
- function isReferencedCategoryValue(elements, categoryValue) {
38126
- return elements.some(function(element) {
38127
- var businessObject = getBusinessObject(element);
38128
-
38129
- return businessObject.categoryValueRef === categoryValue;
38130
- });
38131
- }
38132
-
38133
- /**
38134
- * Remove category value unless it is still referenced.
38135
- *
38136
- * @param {ModdleElement} categoryValue
38137
- * @param {ModdleElement} category
38138
- * @param {ModdleElement} businessObject
38139
- */
38140
- function removeCategoryValue(categoryValue, category, businessObject) {
38141
-
38142
- var groups = getGroupElements().filter(function(element) {
38143
- return element.businessObject !== businessObject;
38144
- });
38145
-
38146
- if (category && !isReferencedCategory(groups, category)) {
38147
- unlinkCategory(category);
38148
- }
38149
-
38150
- if (categoryValue && !isReferencedCategoryValue(groups, categoryValue)) {
38151
- unlinkCategoryValue(categoryValue);
38152
- }
38153
- }
38154
-
38155
- /**
38156
- * Add category value.
38157
- *
38158
- * @param {ModdleElement} categoryValue
38159
- * @param {ModdleElement} category
38160
- *
38161
- * @return {ModdleElement}
38162
- */
38163
- function addCategoryValue(categoryValue, category) {
38164
- return linkCategoryValue(categoryValue, category, bpmnjs.getDefinitions());
38165
- }
38166
-
38167
38244
  function setCategoryValue(element, context) {
38168
38245
  var businessObject = getBusinessObject(element),
38169
- categoryValue = businessObject.categoryValueRef;
38246
+ categoryValue = context.categoryValue || businessObject.categoryValueRef;
38170
38247
 
38171
38248
  if (!categoryValue) {
38172
- categoryValue =
38173
- businessObject.categoryValueRef =
38174
- context.categoryValue = (
38175
- context.categoryValue || createCategoryValue(bpmnFactory)
38176
- );
38249
+ categoryValue = getOrCreateCategoryValueForGroup(bpmnFactory, businessObject);
38177
38250
  }
38178
38251
 
38179
- var category = categoryValue.$parent;
38252
+ var category = context.category || categoryValue.$parent || createCategory(bpmnFactory);
38180
38253
 
38181
- if (!category) {
38182
- category =
38183
- categoryValue.$parent =
38184
- context.category = (
38185
- context.category || createCategory(bpmnFactory)
38186
- );
38187
- }
38254
+ businessObject.categoryValueRef = categoryValue;
38255
+ categoryValue.$parent = category;
38188
38256
 
38189
- addCategoryValue(categoryValue, category, bpmnjs.getDefinitions());
38257
+ context.categoryValue = categoryValue;
38258
+ context.category = category;
38190
38259
  }
38191
38260
 
38192
38261
  function unsetCategoryValue(element, context) {
38193
- var category = context.category,
38194
- categoryValue = context.categoryValue,
38195
- businessObject = getBusinessObject(element);
38262
+ var businessObject = getBusinessObject(element),
38263
+ categoryValue = context.categoryValue || businessObject.categoryValueRef,
38264
+ category = context.category || (categoryValue && categoryValue.$parent);
38196
38265
 
38197
38266
  if (categoryValue) {
38198
- businessObject.categoryValueRef = null;
38267
+ context.categoryValue = categoryValue;
38268
+ context.category = category;
38199
38269
 
38200
- removeCategoryValue(categoryValue, category, businessObject);
38201
- } else {
38202
- removeCategoryValue(null, businessObject.categoryValueRef.$parent, businessObject);
38270
+ businessObject.categoryValueRef = null;
38203
38271
  }
38204
38272
  }
38205
38273
 
@@ -38241,14 +38309,10 @@
38241
38309
  return;
38242
38310
  }
38243
38311
 
38244
- var categoryValue = context.categoryValue = businessObject.categoryValueRef,
38245
- category;
38312
+ var categoryValue = context.categoryValue = businessObject.categoryValueRef;
38246
38313
 
38247
38314
  if (categoryValue) {
38248
- category = context.category = categoryValue.$parent;
38249
-
38250
- removeCategoryValue(categoryValue, category, businessObject);
38251
-
38315
+ context.category = categoryValue.$parent;
38252
38316
  businessObject.categoryValueRef = null;
38253
38317
  }
38254
38318
  });
@@ -38268,39 +38332,77 @@
38268
38332
 
38269
38333
  if (categoryValue) {
38270
38334
  businessObject.categoryValueRef = categoryValue;
38271
-
38272
- addCategoryValue(categoryValue, category);
38335
+ categoryValue.$parent = category;
38273
38336
  }
38274
38337
  });
38275
38338
 
38276
38339
 
38277
- // create new category + value when group was created
38340
+ // create new category + value when group was created so that visually
38341
+ // enclosed elements can be categorized against it, even if it is unlabeled
38278
38342
 
38279
38343
  this.execute('shape.create', function(event) {
38280
38344
  var context = event.context,
38281
- shape = context.shape;
38345
+ shape = context.shape,
38346
+ hints = context.hints || {};
38282
38347
 
38283
38348
  if (!is(shape, 'bpmn:Group') || shape.labelTarget) {
38284
38349
  return;
38285
38350
  }
38286
38351
 
38287
- if (getBusinessObject(shape).categoryValueRef) {
38288
- setCategoryValue(shape, context);
38352
+ // during paste the category value (if any) is carried over from the
38353
+ // source; only fabricate one for genuinely new groups
38354
+ if (hints.createElementsBehavior === false &&
38355
+ !getBusinessObject(shape).categoryValueRef &&
38356
+ !context.categoryValue) {
38357
+ return;
38289
38358
  }
38359
+
38360
+ setCategoryValue(shape, context);
38290
38361
  });
38291
38362
 
38292
38363
  this.reverted('shape.create', function(event) {
38293
38364
 
38294
38365
  var context = event.context,
38295
- shape = context.shape;
38366
+ shape = context.shape,
38367
+ hints = context.hints || {};
38296
38368
 
38297
38369
  if (!is(shape, 'bpmn:Group') || shape.labelTarget) {
38298
38370
  return;
38299
38371
  }
38300
38372
 
38301
- if (getBusinessObject(shape).categoryValueRef) {
38302
- unsetCategoryValue(shape, context);
38373
+ if (hints.createElementsBehavior === false &&
38374
+ !getBusinessObject(shape).categoryValueRef &&
38375
+ !context.categoryValue) {
38376
+ return;
38377
+ }
38378
+
38379
+ unsetCategoryValue(shape, context);
38380
+ });
38381
+
38382
+
38383
+ // add category -> categoryValue for groups when they change
38384
+
38385
+ this.executed([ 'shape.move', 'shape.resize' ], function(event) {
38386
+ var context = event.context,
38387
+ shape = context.shape;
38388
+
38389
+ if (!is(shape, 'bpmn:Group') || shape.labelTarget ||
38390
+ getBusinessObject(shape).categoryValueRef) {
38391
+ return;
38392
+ }
38393
+
38394
+ setCategoryValue(shape, context);
38395
+ });
38396
+
38397
+ this.reverted([ 'shape.move', 'shape.resize' ], function(event) {
38398
+ var context = event.context,
38399
+ shape = context.shape;
38400
+
38401
+ if (!is(shape, 'bpmn:Group') || shape.labelTarget || !context.categoryValue) {
38402
+ return;
38303
38403
  }
38404
+
38405
+ unsetCategoryValue(shape, context);
38304
38406
  });
38305
38407
 
38306
38408
 
@@ -38356,8 +38458,6 @@
38356
38458
 
38357
38459
  GroupBehavior.$inject = [
38358
38460
  'bpmnFactory',
38359
- 'bpmnjs',
38360
- 'elementRegistry',
38361
38461
  'eventBus',
38362
38462
  'injector',
38363
38463
  'moddleCopy'
@@ -40412,7 +40512,7 @@
40412
40512
  'selection'
40413
40513
  ];
40414
40514
 
40415
- var HIGH_PRIORITY$f = 1500;
40515
+ var HIGH_PRIORITY$g = 1500;
40416
40516
 
40417
40517
  /**
40418
40518
  * @typedef {import('diagram-js/lib/core/EventBus').default} EventBus
@@ -40465,7 +40565,7 @@
40465
40565
  * @param {EventBus} eventBus
40466
40566
  */
40467
40567
  function ResizeBehavior$1(eventBus) {
40468
- eventBus.on('resize.start', HIGH_PRIORITY$f, function(event) {
40568
+ eventBus.on('resize.start', HIGH_PRIORITY$g, function(event) {
40469
40569
  var context = event.context,
40470
40570
  shape = context.shape,
40471
40571
  direction = context.direction,
@@ -40737,7 +40837,7 @@
40737
40837
  * @typedef {import('diagram-js/lib/util/Types').DirectionTRBL} DirectionTRBL
40738
40838
  */
40739
40839
 
40740
- var LOW_PRIORITY$g = 500;
40840
+ var LOW_PRIORITY$h = 500;
40741
40841
 
40742
40842
 
40743
40843
  /**
@@ -40867,7 +40967,7 @@
40867
40967
  }
40868
40968
  });
40869
40969
 
40870
- eventBus.on('copyPaste.pasteElement', LOW_PRIORITY$g, function(context) {
40970
+ eventBus.on('copyPaste.pasteElement', LOW_PRIORITY$h, function(context) {
40871
40971
  var descriptor = context.descriptor,
40872
40972
  businessObject = descriptor.businessObject,
40873
40973
  referencedRootElement = descriptor.referencedRootElement;
@@ -41112,8 +41212,8 @@
41112
41212
  * @typedef {import('../../../model/Types').ModdleElement} ModdleElement
41113
41213
  */
41114
41214
 
41115
- var LOW_PRIORITY$f = 400;
41116
- var HIGH_PRIORITY$e = 600;
41215
+ var LOW_PRIORITY$g = 400;
41216
+ var HIGH_PRIORITY$f = 600;
41117
41217
 
41118
41218
  var DEFAULT_POSITION = {
41119
41219
  x: 180,
@@ -41387,7 +41487,7 @@
41387
41487
 
41388
41488
 
41389
41489
  // create/remove plane for the subprocess
41390
- this.executed('shape.toggleCollapse', LOW_PRIORITY$f, function(context) {
41490
+ this.executed('shape.toggleCollapse', LOW_PRIORITY$g, function(context) {
41391
41491
  var shape = context.shape;
41392
41492
 
41393
41493
  if (!is(shape, 'bpmn:SubProcess')) {
@@ -41405,7 +41505,7 @@
41405
41505
 
41406
41506
 
41407
41507
  // create/remove plane for the subprocess
41408
- this.reverted('shape.toggleCollapse', LOW_PRIORITY$f, function(context) {
41508
+ this.reverted('shape.toggleCollapse', LOW_PRIORITY$g, function(context) {
41409
41509
  var shape = context.shape;
41410
41510
 
41411
41511
  if (!is(shape, 'bpmn:SubProcess')) {
@@ -41422,7 +41522,7 @@
41422
41522
  }, true);
41423
41523
 
41424
41524
  // move elements between planes
41425
- this.postExecuted('shape.toggleCollapse', HIGH_PRIORITY$e, function(context) {
41525
+ this.postExecuted('shape.toggleCollapse', HIGH_PRIORITY$f, function(context) {
41426
41526
  var shape = context.shape;
41427
41527
 
41428
41528
  if (!is(shape, 'bpmn:SubProcess')) {
@@ -41969,7 +42069,7 @@
41969
42069
  * @typedef {import('../Modeling').default} Modeling
41970
42070
  */
41971
42071
 
41972
- var LOW_PRIORITY$e = 500;
42072
+ var LOW_PRIORITY$f = 500;
41973
42073
 
41974
42074
  /**
41975
42075
  * @param {EventBus} eventBus
@@ -42030,7 +42130,7 @@
42030
42130
  };
42031
42131
  }
42032
42132
 
42033
- this.executed([ 'shape.toggleCollapse' ], LOW_PRIORITY$e, function(e) {
42133
+ this.executed([ 'shape.toggleCollapse' ], LOW_PRIORITY$f, function(e) {
42034
42134
 
42035
42135
  var context = e.context,
42036
42136
  shape = context.shape;
@@ -42053,7 +42153,7 @@
42053
42153
  }
42054
42154
  });
42055
42155
 
42056
- this.reverted([ 'shape.toggleCollapse' ], LOW_PRIORITY$e, function(e) {
42156
+ this.reverted([ 'shape.toggleCollapse' ], LOW_PRIORITY$f, function(e) {
42057
42157
 
42058
42158
  var context = e.context;
42059
42159
  var shape = context.shape;
@@ -42068,7 +42168,7 @@
42068
42168
  }
42069
42169
  });
42070
42170
 
42071
- this.postExecuted([ 'shape.toggleCollapse' ], LOW_PRIORITY$e, function(e) {
42171
+ this.postExecuted([ 'shape.toggleCollapse' ], LOW_PRIORITY$f, function(e) {
42072
42172
  var shape = e.context.shape,
42073
42173
  defaultSize = elementFactory.getDefaultSize(shape),
42074
42174
  newBounds;
@@ -42223,12 +42323,31 @@
42223
42323
  * @typedef {import('../Modeling').default} Modeling
42224
42324
  */
42225
42325
 
42226
- var LOW_PRIORITY$d = 500,
42227
- HIGH_PRIORITY$d = 5000;
42326
+ var LOW_PRIORITY$e = 500,
42327
+ HIGH_PRIORITY$e = 5000;
42228
42328
 
42329
+ // Commands that provide a shape whose lane references must be updated.
42330
+ var laneRefShapeEvents = [
42331
+ 'shape.create',
42332
+ 'shape.delete',
42333
+ 'shape.move',
42334
+ 'shape.resize'
42335
+ ];
42336
+
42337
+ // Commands that bracket a complete lane reference update, including nested commands.
42338
+ var laneRefUpdateEvents = [
42339
+ ...laneRefShapeEvents,
42340
+ 'spaceTool',
42341
+ 'lane.add',
42342
+ 'lane.resize',
42343
+ 'lane.split',
42344
+ 'elements.create',
42345
+ 'elements.delete',
42346
+ 'elements.move'
42347
+ ];
42229
42348
 
42230
42349
  /**
42231
- * BPMN specific delete lane behavior.
42350
+ * Synchronizes lane flow node references after geometry changes.
42232
42351
  *
42233
42352
  * @param {EventBus} eventBus
42234
42353
  * @param {Modeling} modeling
@@ -42237,18 +42356,11 @@
42237
42356
 
42238
42357
  CommandInterceptor.call(this, eventBus);
42239
42358
 
42240
- /**
42241
- * Update Lane#flowNodeRefs and FlowNode#lanes with every flow node
42242
- * move/resize and lane move/resize. Groups elements to recompute containments
42243
- * as efficient as possible.
42244
- */
42245
-
42246
- // the update context
42247
42359
  var context;
42248
42360
 
42249
42361
 
42250
42362
  function initContext() {
42251
- context = context || new UpdateContext();
42363
+ context = context || new UpdateContext$1();
42252
42364
  context.enter();
42253
42365
 
42254
42366
  return context;
@@ -42280,40 +42392,26 @@
42280
42392
  }
42281
42393
 
42282
42394
 
42283
- var laneRefUpdateEvents = [
42284
- 'spaceTool',
42285
- 'lane.add',
42286
- 'lane.resize',
42287
- 'lane.split',
42288
- 'elements.create',
42289
- 'elements.delete',
42290
- 'elements.move',
42291
- 'shape.create',
42292
- 'shape.delete',
42293
- 'shape.move',
42294
- 'shape.resize'
42295
- ];
42296
-
42297
-
42298
- // listen to a lot of stuff to group lane updates
42299
-
42300
- this.preExecute(laneRefUpdateEvents, HIGH_PRIORITY$d, function(event) {
42395
+ /**
42396
+ * Sets up the context for lane reference updates before executing commands
42397
+ * that may affect them.
42398
+ */
42399
+ this.preExecute(laneRefUpdateEvents, HIGH_PRIORITY$e, function() {
42301
42400
  initContext();
42302
42401
  });
42303
42402
 
42304
- this.postExecuted(laneRefUpdateEvents, LOW_PRIORITY$d, function(event) {
42403
+ /**
42404
+ * Releases the context for lane reference updates after executing commands
42405
+ * that may affect them.
42406
+ */
42407
+ this.postExecuted(laneRefUpdateEvents, LOW_PRIORITY$e, function() {
42305
42408
  releaseContext();
42306
42409
  });
42307
42410
 
42308
-
42309
- // Mark flow nodes + lanes that need an update
42310
-
42311
- this.preExecute([
42312
- 'shape.create',
42313
- 'shape.move',
42314
- 'shape.delete',
42315
- 'shape.resize'
42316
- ], function(event) {
42411
+ /**
42412
+ * Handles updates to lane references for shapes.
42413
+ */
42414
+ this.preExecute(laneRefShapeEvents, function(event) {
42317
42415
 
42318
42416
  var context = event.context,
42319
42417
  shape = context.shape;
@@ -42321,7 +42419,7 @@
42321
42419
  var updateContext = getContext();
42322
42420
 
42323
42421
  // no need to update labels
42324
- if (shape.labelTarget) {
42422
+ if (!shape || shape.labelTarget) {
42325
42423
  return;
42326
42424
  }
42327
42425
 
@@ -42343,7 +42441,7 @@
42343
42441
  e$3(UpdateFlowNodeRefsBehavior, CommandInterceptor);
42344
42442
 
42345
42443
 
42346
- function UpdateContext() {
42444
+ function UpdateContext$1() {
42347
42445
 
42348
42446
  this.flowNodes = [];
42349
42447
  this.lanes = [];
@@ -42369,6 +42467,168 @@
42369
42467
  };
42370
42468
  }
42371
42469
 
42470
+ /**
42471
+ * @typedef {import('diagram-js/lib/core/EventBus').default} EventBus
42472
+ * @typedef {import('../Modeling').default} Modeling
42473
+ */
42474
+
42475
+ var LOW_PRIORITY$d = 500,
42476
+ HIGH_PRIORITY$d = 5000;
42477
+
42478
+ // Commands that provide a shape or connection whose references must be updated.
42479
+ var categoryValueRefShapeAndConnectionEvents = [
42480
+ 'connection.create',
42481
+ 'connection.delete',
42482
+ 'connection.layout',
42483
+ 'connection.move',
42484
+ 'connection.reconnect',
42485
+ 'connection.updateWaypoints',
42486
+ 'shape.create',
42487
+ 'shape.delete',
42488
+ 'shape.move',
42489
+ 'shape.resize'
42490
+ ];
42491
+
42492
+ // Commands that bracket a complete reference update, including nested commands.
42493
+ var categoryValueRefUpdateEvents = [
42494
+ ...categoryValueRefShapeAndConnectionEvents,
42495
+ 'elements.create',
42496
+ 'elements.delete',
42497
+ 'elements.move',
42498
+ 'label.create',
42499
+ 'spaceTool'
42500
+ ];
42501
+
42502
+ /**
42503
+ * Synchronizes group category references after geometry changes.
42504
+ *
42505
+ * @param {EventBus} eventBus
42506
+ * @param {Modeling} modeling
42507
+ */
42508
+ function UpdateCategoryValueRefsBehavior(eventBus, modeling) {
42509
+
42510
+ CommandInterceptor.call(this, eventBus);
42511
+
42512
+ var context;
42513
+
42514
+ function initContext() {
42515
+ context = context || new UpdateContext();
42516
+ context.enter();
42517
+
42518
+ return context;
42519
+ }
42520
+
42521
+ function getContext() {
42522
+ if (!context) {
42523
+ throw new Error('out of bounds release');
42524
+ }
42525
+
42526
+ return context;
42527
+ }
42528
+
42529
+ function releaseContext() {
42530
+ if (!context) {
42531
+ throw new Error('out of bounds release');
42532
+ }
42533
+
42534
+ var triggerUpdate = context.leave();
42535
+
42536
+ if (triggerUpdate) {
42537
+ modeling.updateCategoryValueRefs(
42538
+ Array.from(context.affectedFlowElements),
42539
+ Array.from(context.affectedGroupEntries.values())
42540
+ );
42541
+
42542
+ context = null;
42543
+ }
42544
+
42545
+ return triggerUpdate;
42546
+ }
42547
+
42548
+ /**
42549
+ * Sets up the context for category value reference updates before executing
42550
+ * commands that may affect them.
42551
+ */
42552
+ this.preExecute(categoryValueRefUpdateEvents, HIGH_PRIORITY$d, function() {
42553
+ initContext();
42554
+ });
42555
+
42556
+ /**
42557
+ * Releases the context for category value reference updates after executing
42558
+ * commands that may affect them.
42559
+ */
42560
+ this.postExecuted(categoryValueRefUpdateEvents, LOW_PRIORITY$d, function() {
42561
+ releaseContext();
42562
+ });
42563
+
42564
+ /**
42565
+ * Handles updates to category value references for shapes and connections.
42566
+ */
42567
+ this.preExecute(categoryValueRefShapeAndConnectionEvents, function(event) {
42568
+ var shape = event.context.connection || event.context.shape,
42569
+ updateContext = getContext();
42570
+
42571
+ if (!shape || shape.labelTarget) {
42572
+ return;
42573
+ }
42574
+
42575
+ if (is(shape, 'bpmn:FlowElement')) {
42576
+ updateContext.addFlowElement(shape);
42577
+ }
42578
+
42579
+ if (is(shape, 'bpmn:Group')) {
42580
+ updateContext.addGroup(shape);
42581
+ }
42582
+ });
42583
+
42584
+ this.preExecute('label.create', function(event) {
42585
+ var labelTarget = event.context.labelTarget;
42586
+
42587
+ if (is(labelTarget, 'bpmn:Group')) {
42588
+ getContext().addGroup(labelTarget);
42589
+ }
42590
+ });
42591
+ }
42592
+
42593
+ UpdateCategoryValueRefsBehavior.$inject = [
42594
+ 'eventBus',
42595
+ 'modeling'
42596
+ ];
42597
+
42598
+ e$3(UpdateCategoryValueRefsBehavior, CommandInterceptor);
42599
+
42600
+
42601
+ function UpdateContext() {
42602
+
42603
+ this.affectedFlowElements = new Set();
42604
+ this.affectedGroupEntries = new Map();
42605
+
42606
+ this.counter = 0;
42607
+
42608
+ this.addFlowElement = function(flowElement) {
42609
+ this.affectedFlowElements.add(flowElement);
42610
+ };
42611
+
42612
+ this.addGroup = function(group) {
42613
+ if (!this.affectedGroupEntries.has(group)) {
42614
+ this.affectedGroupEntries.set(group, {
42615
+ categoryValue: group.businessObject.categoryValueRef,
42616
+ groupShape: group
42617
+ });
42618
+ }
42619
+ };
42620
+
42621
+ this.enter = function() {
42622
+ this.counter++;
42623
+ };
42624
+
42625
+ this.leave = function() {
42626
+ this.counter--;
42627
+
42628
+ return !this.counter;
42629
+ };
42630
+ }
42631
+
42372
42632
  /**
42373
42633
  * @typedef {import('diagram-js/lib/core/EventBus').default} EventBus
42374
42634
  * @typedef {import('../../rules/BpmnRules').default} BpmnRules
@@ -42440,6 +42700,7 @@
42440
42700
  'associationBehavior',
42441
42701
  'attachEventBehavior',
42442
42702
  'boundaryEventBehavior',
42703
+ 'categoryRootElementReferenceBehavior',
42443
42704
  'compensateBoundaryEventBehaviour',
42444
42705
  'createBehavior',
42445
42706
  'createDataObjectBehavior',
@@ -42474,6 +42735,7 @@
42474
42735
  'toggleElementCollapseBehaviour',
42475
42736
  'unclaimIdBehavior',
42476
42737
  'updateFlowNodeRefsBehavior',
42738
+ 'updateCategoryValueRefsBehavior',
42477
42739
  'unsetDefaultFlowBehavior',
42478
42740
  'setCompensationActivityAfterPasteBehavior'
42479
42741
  ],
@@ -42483,6 +42745,7 @@
42483
42745
  attachEventBehavior: [ 'type', AttachEventBehavior ],
42484
42746
  artifactBehavior: [ 'type', ArtifactBehavior ],
42485
42747
  boundaryEventBehavior: [ 'type', BoundaryEventBehavior ],
42748
+ categoryRootElementReferenceBehavior: [ 'type', CategoryRootElementReferenceBehavior ],
42486
42749
  compensateBoundaryEventBehaviour: [ 'type', CompensateBoundaryEventBehavior ],
42487
42750
  createBehavior: [ 'type', CreateBehavior ],
42488
42751
  createDataObjectBehavior: [ 'type', CreateDataObjectBehavior ],
@@ -42518,6 +42781,7 @@
42518
42781
  unclaimIdBehavior: [ 'type', UnclaimIdBehavior ],
42519
42782
  unsetDefaultFlowBehavior: [ 'type', DeleteSequenceFlowBehavior ],
42520
42783
  updateFlowNodeRefsBehavior: [ 'type', UpdateFlowNodeRefsBehavior ],
42784
+ updateCategoryValueRefsBehavior: [ 'type', UpdateCategoryValueRefsBehavior ],
42521
42785
  setCompensationActivityAfterPasteBehavior: [ 'type', SetCompensationActivityAfterPasteBehavior ]
42522
42786
  };
42523
42787
 
@@ -43696,9 +43960,47 @@
43696
43960
  return false;
43697
43961
  }
43698
43962
 
43963
+ // do not copy message flows unless both connected participants are copied,
43964
+ // too; otherwise they would end up in an invalid organizational context
43965
+ if (is(element, 'bpmn:MessageFlow') && !canCopyMessageFlow(elements, element)) {
43966
+ return false;
43967
+ }
43968
+
43699
43969
  return true;
43700
43970
  }
43701
43971
 
43972
+ /**
43973
+ * A message flow may only be copied if both of its participants are copied,
43974
+ * too. Otherwise it would be pasted into an invalid organizational context,
43975
+ * e.g. a plain process.
43976
+ *
43977
+ * @param {Element[]} elements
43978
+ * @param {Connection} connection
43979
+ *
43980
+ * @return {boolean}
43981
+ */
43982
+ function canCopyMessageFlow(elements, connection) {
43983
+ var sourceParticipant = getParticipant(connection.source),
43984
+ targetParticipant = getParticipant(connection.target);
43985
+
43986
+ return includes$2(elements, sourceParticipant) && includes$2(elements, targetParticipant);
43987
+ }
43988
+
43989
+ /**
43990
+ * @param {Element} element
43991
+ *
43992
+ * @return {Element|null}
43993
+ */
43994
+ function getParticipant(element) {
43995
+ for (; element; element = element.parent) {
43996
+ if (is(element, 'bpmn:Participant')) {
43997
+ return element;
43998
+ }
43999
+ }
44000
+
44001
+ return null;
44002
+ }
44003
+
43702
44004
  /**
43703
44005
  * @param {Element} element
43704
44006
  *
@@ -53603,8 +53905,6 @@
53603
53905
  /**
53604
53906
  * @typedef {import('diagram-js/lib/command/CommandHandler').default} CommandHandler
53605
53907
  *
53606
- * @typedef {import('diagram-js/lib/core/ElementRegistry').default} ElementRegistry
53607
- *
53608
53908
  * @typedef {import('../../../model/Types').Shape} Shape
53609
53909
  */
53610
53910
 
@@ -53617,15 +53917,9 @@
53617
53917
  *
53618
53918
  * @implements {CommandHandler}
53619
53919
  *
53620
- * @param {ElementRegistry} elementRegistry
53621
53920
  */
53622
- function UpdateFlowNodeRefsHandler(elementRegistry) {
53623
- this._elementRegistry = elementRegistry;
53624
- }
53921
+ function UpdateFlowNodeRefsHandler() {}
53625
53922
 
53626
- UpdateFlowNodeRefsHandler.$inject = [
53627
- 'elementRegistry'
53628
- ];
53629
53923
 
53630
53924
  /**
53631
53925
  * @param {Shape} flowNodeShapes
@@ -53801,6 +54095,409 @@
53801
54095
  return [];
53802
54096
  };
53803
54097
 
54098
+ /**
54099
+ * @typedef {import('diagram-js/lib/command/CommandHandler').default} CommandHandler
54100
+ * @typedef {import('diagram-js/lib/core/ElementRegistry').default} ElementRegistry
54101
+ * @typedef {import('../BpmnFactory').default} BpmnFactory
54102
+ *
54103
+ * @typedef {import('../../../model/Types').Element} Element
54104
+ * @typedef {import('../../../model/Types').ModdleElement} ModdleElement
54105
+ *
54106
+ * @typedef { {
54107
+ * categoryValue: ModdleElement;
54108
+ * root?: Element;
54109
+ * } } CategoryGroupEntry
54110
+ */
54111
+
54112
+ var CATEGORY_VALUE_REFS_ATTR = 'categoryValueRef';
54113
+
54114
+
54115
+ /**
54116
+ * Updates category value references for flow elements visually enclosed by groups.
54117
+ *
54118
+ * A flow element is grouped only when it shares the group's diagram root and
54119
+ * is geometrically enclosed by the group. Consequently, visible children of an
54120
+ * expanded subprocess are grouped, while children of a collapsed subprocess
54121
+ * are not.
54122
+ *
54123
+ * Groups without a category value are auto-healed: if such a group visually
54124
+ * encloses an affected flow element a category value is created for it on the
54125
+ * fly, so that legacy diagrams (groups modeled without a category value) start
54126
+ * to categorize their contents as soon as they are interacted with.
54127
+ *
54128
+ * @implements {CommandHandler}
54129
+ *
54130
+ * @param {BpmnFactory} bpmnFactory
54131
+ * @param {ElementRegistry} elementRegistry
54132
+ */
54133
+ function UpdateCategoryValueRefsHandler(bpmnFactory, elementRegistry) {
54134
+ this._bpmnFactory = bpmnFactory;
54135
+ this._elementRegistry = elementRegistry;
54136
+ }
54137
+
54138
+ UpdateCategoryValueRefsHandler.$inject = [
54139
+ 'bpmnFactory',
54140
+ 'elementRegistry'
54141
+ ];
54142
+
54143
+
54144
+ /**
54145
+ * @param { Element[] } affectedFlowElements
54146
+ * @param { {
54147
+ * categoryValue: ModdleElement;
54148
+ * groupShape: Element;
54149
+ * }[] } affectedGroupEntries
54150
+ *
54151
+ * @return { {
54152
+ * flowElements: {
54153
+ * businessObject: ModdleElement;
54154
+ * categoryValuesToAdd: ModdleElement[];
54155
+ * categoryValuesToRemove: ModdleElement[];
54156
+ * }[];
54157
+ * groups: {
54158
+ * groupShape: Element;
54159
+ * categoryValue: ModdleElement;
54160
+ * category: ModdleElement;
54161
+ * }[];
54162
+ * } }
54163
+ */
54164
+ UpdateCategoryValueRefsHandler.prototype._computeUpdates = function(affectedFlowElements, affectedGroupEntries) {
54165
+ var elementRegistry = this._elementRegistry,
54166
+ bpmnFactory = this._bpmnFactory;
54167
+
54168
+ /** @type {Map<Element, ModdleElement>} */
54169
+ var flowElementBusinessObjects = new Map();
54170
+
54171
+ var groupUpdates = [];
54172
+
54173
+ /**
54174
+ * @type {Map<Element, {
54175
+ * present?: CategoryGroupEntry;
54176
+ * past?: CategoryGroupEntry;
54177
+ * }>}
54178
+ */
54179
+ var categoryGroups = new Map();
54180
+
54181
+ /**
54182
+ * Adds a group to the list of groups to consider for category value updates.
54183
+ *
54184
+ * @param {Element} groupShape
54185
+ * @param {ModdleElement} categoryValue
54186
+ * @param {boolean} isPresent
54187
+ */
54188
+ function addGroup(groupShape, categoryValue, isPresent) {
54189
+ if (!categoryValue) {
54190
+ return;
54191
+ }
54192
+
54193
+ var categoryGroup = categoryGroups.get(groupShape);
54194
+
54195
+ if (!categoryGroup) {
54196
+ categoryGroup = {};
54197
+ categoryGroups.set(groupShape, categoryGroup);
54198
+ }
54199
+
54200
+ if (isPresent && categoryGroup.present) {
54201
+ return;
54202
+ }
54203
+
54204
+ if (!isPresent && categoryGroup.past) {
54205
+ return;
54206
+ }
54207
+
54208
+ if (isPresent) {
54209
+ categoryGroup.present = {
54210
+ categoryValue: categoryValue,
54211
+ root: getRoot(groupShape)
54212
+ };
54213
+ } else {
54214
+ categoryGroup.past = {
54215
+ categoryValue: categoryValue
54216
+ };
54217
+ }
54218
+ }
54219
+
54220
+ /**
54221
+ * Adds a flow element to the list of flow elements to consider for category
54222
+ * value updates.
54223
+ *
54224
+ * @param {Element} flowElement
54225
+ */
54226
+ function addFlowElement(flowElement) {
54227
+ flowElementBusinessObjects.set(
54228
+ flowElement,
54229
+ getBusinessObject(flowElement)
54230
+ );
54231
+ }
54232
+
54233
+ /**
54234
+ * Adds all flow elements on the diagram to the list of flow elements to
54235
+ * consider; skips root elements (e.g. sub process planes) which share a
54236
+ * business object with their collapsed shape but carry no diagram position.
54237
+ */
54238
+ function addAllFlowElements() {
54239
+ elementRegistry.filter(function(element) {
54240
+ return is(element, 'bpmn:FlowElement') && !isLabel(element) && element.parent;
54241
+ }).forEach(addFlowElement);
54242
+ }
54243
+
54244
+ /**
54245
+ * Returns a group's category value, creating one on the fly for
54246
+ * legacy groups modeled without one. Retrieving the value in order to
54247
+ * reference it materializes it; the fresh value is recorded as a heal so
54248
+ * CategoryRootElementReferenceBehavior can maintain its root element.
54249
+ *
54250
+ * @param {Element} groupShape
54251
+ *
54252
+ * @return {ModdleElement}
54253
+ */
54254
+ function getCategoryValue(groupShape) {
54255
+ var groupBo = getBusinessObject(groupShape),
54256
+ categoryValue = groupBo.get('categoryValueRef');
54257
+
54258
+ if (!categoryValue) {
54259
+ categoryValue = getOrCreateCategoryValueForGroup(bpmnFactory, groupBo);
54260
+
54261
+ groupUpdates.push(createGroupUpdate(groupShape, categoryValue));
54262
+ }
54263
+
54264
+ return categoryValue;
54265
+ }
54266
+
54267
+ function getElementsByRoot(elements) {
54268
+ return elements.reduce(function(elementsByRoot, element) {
54269
+ var root = getRoot(element),
54270
+ elementsInRoot = elementsByRoot.get(root);
54271
+
54272
+ if (!elementsInRoot) {
54273
+ elementsInRoot = [];
54274
+ elementsByRoot.set(root, elementsInRoot);
54275
+ }
54276
+
54277
+ elementsInRoot.push(element);
54278
+
54279
+ return elementsByRoot;
54280
+ }, new Map());
54281
+ }
54282
+
54283
+ affectedFlowElements = Array.from(affectedFlowElements || []);
54284
+
54285
+ var affectedFlowElementsByRoot = getElementsByRoot(affectedFlowElements);
54286
+
54287
+ // when a group is moved, resized, added or removed, the category value
54288
+ // references of all flow elements must be rechecked
54289
+ if (affectedGroupEntries.length) {
54290
+ addAllFlowElements();
54291
+ }
54292
+
54293
+ // flow elements that were genuinely moved or created; unrelated groups
54294
+ // will not be touched
54295
+ affectedFlowElements.forEach(addFlowElement);
54296
+
54297
+ // add all present groups to the list of groups to consider for category
54298
+ // value updates, auto-healing legacy groups only when an affected flow
54299
+ // element moves into them
54300
+ elementRegistry.filter(function(element) {
54301
+ return is(element, 'bpmn:Group') && !isLabel(element) && element.parent;
54302
+ }).forEach(function(groupShape) {
54303
+ var categoryValue = getBusinessObject(groupShape).get('categoryValueRef');
54304
+
54305
+ if (!categoryValue) {
54306
+ var groupRoot = getRoot(groupShape),
54307
+ affectedFlowElementsInRoot = affectedFlowElementsByRoot.get(groupRoot) || [],
54308
+ enclosedAffectedFlowElements = getEnclosedElements(
54309
+ affectedFlowElementsInRoot,
54310
+ groupShape
54311
+ ),
54312
+ enclosesAffectedFlowElement = Object.keys(enclosedAffectedFlowElements).length > 0;
54313
+
54314
+ if (enclosesAffectedFlowElement) {
54315
+ categoryValue = getCategoryValue(groupShape);
54316
+ }
54317
+ }
54318
+
54319
+ addGroup(groupShape, categoryValue, true);
54320
+ });
54321
+
54322
+ affectedGroupEntries.forEach(function(groupEntry) {
54323
+ addGroup(groupEntry.groupShape, groupEntry.categoryValue, false);
54324
+ });
54325
+
54326
+ // a healed group receives a fresh category value; recheck all flow elements
54327
+ // so that everything it visually encloses is tagged consistently, not just
54328
+ // the flow element that triggered the healing
54329
+ if (groupUpdates.length) {
54330
+ addAllFlowElements();
54331
+ }
54332
+
54333
+ var flowElements = Array.from(flowElementBusinessObjects.keys());
54334
+
54335
+ var managedCategoryValues = Array.from(categoryGroups.values()).reduce(function(set, group) {
54336
+ if (group.present) {
54337
+ set.add(group.present.categoryValue);
54338
+ }
54339
+
54340
+ if (group.past) {
54341
+ set.add(group.past.categoryValue);
54342
+ }
54343
+
54344
+ return set;
54345
+ }, new Set());
54346
+
54347
+ var categoryValuesByFlowElement = new Map(),
54348
+ flowElementsByRoot = getElementsByRoot(flowElements);
54349
+
54350
+ // Containment is calculated once per group and diagram root. This avoids
54351
+ // allocating an enclosure result for every flow element / group pair.
54352
+ categoryGroups.forEach(function(categoryGroup, groupShape) {
54353
+ var presentGroup = categoryGroup.present;
54354
+
54355
+ if (!presentGroup) {
54356
+ return;
54357
+ }
54358
+
54359
+ var flowElementsInRoot = flowElementsByRoot.get(presentGroup.root) || [],
54360
+ enclosedFlowElements = getEnclosedElements(flowElementsInRoot, groupShape);
54361
+
54362
+ flowElementsInRoot.forEach(function(flowElement) {
54363
+ if (!enclosedFlowElements[flowElement.id]) {
54364
+ return;
54365
+ }
54366
+
54367
+ var categoryValues = categoryValuesByFlowElement.get(flowElement);
54368
+
54369
+ if (!categoryValues) {
54370
+ categoryValues = new Set();
54371
+ categoryValuesByFlowElement.set(flowElement, categoryValues);
54372
+ }
54373
+
54374
+ categoryValues.add(presentGroup.categoryValue);
54375
+ });
54376
+ });
54377
+
54378
+ // compute updates for all flow elements based on the groups they are inside
54379
+ var flowElementUpdates = flowElements.reduce(function(flowElementUpdates, flowElement) {
54380
+ var flowElementBo = flowElementBusinessObjects.get(flowElement),
54381
+ categoryValueRefs = flowElementBo.get(CATEGORY_VALUE_REFS_ATTR),
54382
+ categoryValueRefSet = new Set(categoryValueRefs),
54383
+ enclosingCategoryValues = categoryValuesByFlowElement.get(flowElement) || new Set(),
54384
+ categoryValuesToAdd = Array.from(enclosingCategoryValues).filter(function(categoryValue) {
54385
+ return !categoryValueRefSet.has(categoryValue);
54386
+ }),
54387
+ categoryValuesToRemove = categoryValueRefs.filter(function(categoryValue) {
54388
+ return managedCategoryValues.has(categoryValue) &&
54389
+ !enclosingCategoryValues.has(categoryValue);
54390
+ });
54391
+
54392
+ if (categoryValuesToAdd.length || categoryValuesToRemove.length) {
54393
+ flowElementUpdates.push({
54394
+ businessObject: flowElementBo,
54395
+ categoryValuesToAdd,
54396
+ categoryValuesToRemove
54397
+ });
54398
+ }
54399
+
54400
+ return flowElementUpdates;
54401
+ }, []);
54402
+
54403
+ return {
54404
+ flowElements: flowElementUpdates,
54405
+ groups: groupUpdates
54406
+ };
54407
+ };
54408
+
54409
+
54410
+ UpdateCategoryValueRefsHandler.prototype.execute = function(context) {
54411
+ var updates = context.updates;
54412
+
54413
+ if (!updates) {
54414
+ updates = context.updates = this._computeUpdates(
54415
+ context.affectedFlowElements,
54416
+ context.affectedGroupEntries
54417
+ );
54418
+ }
54419
+
54420
+ // set auto-healed category values first so that flow element updates can
54421
+ // reference them; root element linking is handled by
54422
+ // CategoryRootElementReferenceBehavior
54423
+ applyGroupUpdates(updates.groups);
54424
+
54425
+ applyFlowElementUpdates(updates.flowElements);
54426
+
54427
+ return [];
54428
+ };
54429
+
54430
+
54431
+ UpdateCategoryValueRefsHandler.prototype.revert = function(context) {
54432
+ var updates = context.updates;
54433
+
54434
+ revertFlowElementUpdates(updates.flowElements);
54435
+
54436
+ revertGroupUpdates(updates.groups);
54437
+
54438
+ return [];
54439
+ };
54440
+
54441
+
54442
+ function createGroupUpdate(groupShape, categoryValue) {
54443
+ return {
54444
+ groupShape: groupShape,
54445
+ categoryValue: categoryValue,
54446
+ category: categoryValue.$parent
54447
+ };
54448
+ }
54449
+
54450
+ function applyGroupUpdates(groupUpdates) {
54451
+ groupUpdates.forEach(function(groupUpdate) {
54452
+ getBusinessObject(groupUpdate.groupShape).categoryValueRef = groupUpdate.categoryValue;
54453
+ groupUpdate.categoryValue.$parent = groupUpdate.category;
54454
+ });
54455
+ }
54456
+
54457
+ function revertGroupUpdates(groupUpdates) {
54458
+ groupUpdates.forEach(function(groupUpdate) {
54459
+ getBusinessObject(groupUpdate.groupShape).categoryValueRef = null;
54460
+ });
54461
+ }
54462
+
54463
+ function applyFlowElementUpdates(flowElementUpdates) {
54464
+ flowElementUpdates.forEach(function(flowElementUpdate) {
54465
+ var businessObject = flowElementUpdate.businessObject,
54466
+ categoryValueRefs = businessObject.get(CATEGORY_VALUE_REFS_ATTR);
54467
+
54468
+ flowElementUpdate.categoryValuesToRemove.forEach(function(categoryValue) {
54469
+ remove(categoryValueRefs, categoryValue);
54470
+ });
54471
+
54472
+ flowElementUpdate.categoryValuesToAdd.forEach(function(categoryValue) {
54473
+ add(categoryValueRefs, categoryValue, true);
54474
+ });
54475
+ });
54476
+ }
54477
+
54478
+ function revertFlowElementUpdates(flowElementUpdates) {
54479
+ flowElementUpdates.forEach(function(flowElementUpdate) {
54480
+ var businessObject = flowElementUpdate.businessObject,
54481
+ categoryValueRefs = businessObject.get(CATEGORY_VALUE_REFS_ATTR);
54482
+
54483
+ flowElementUpdate.categoryValuesToAdd.forEach(function(categoryValue) {
54484
+ remove(categoryValueRefs, categoryValue);
54485
+ });
54486
+
54487
+ flowElementUpdate.categoryValuesToRemove.forEach(function(categoryValue) {
54488
+ add(categoryValueRefs, categoryValue, true);
54489
+ });
54490
+ });
54491
+ }
54492
+
54493
+ function getRoot(element) {
54494
+ while (element.parent) {
54495
+ element = element.parent;
54496
+ }
54497
+
54498
+ return element;
54499
+ }
54500
+
53804
54501
  /**
53805
54502
  * @typedef {import('diagram-js/lib/command/CommandHandler').default} CommandHandler
53806
54503
  *
@@ -54161,6 +54858,11 @@
54161
54858
  * @typedef { {
54162
54859
  * removeShape?: boolean;
54163
54860
  * } } UpdateLabelHints
54861
+ *
54862
+ * @typedef { {
54863
+ * categoryValue?: ModdleElement;
54864
+ * groupShape: Shape;
54865
+ * } } GroupEntry
54164
54866
  */
54165
54867
 
54166
54868
  /**
@@ -54211,6 +54913,7 @@
54211
54913
  handlers['lane.resize'] = ResizeLaneHandler;
54212
54914
  handlers['lane.split'] = SplitLaneHandler;
54213
54915
  handlers['lane.updateRefs'] = UpdateFlowNodeRefsHandler;
54916
+ handlers['group.updateRefs'] = UpdateCategoryValueRefsHandler;
54214
54917
  handlers['id.updateClaim'] = IdClaimHandler;
54215
54918
  handlers['element.setColor'] = SetColorHandler;
54216
54919
  handlers['element.updateLabel'] = UpdateLabelHandler;
@@ -54388,6 +55091,20 @@
54388
55091
  });
54389
55092
  };
54390
55093
 
55094
+ /**
55095
+ * Update the referenced category values of each flow element.
55096
+ *
55097
+ * @param {Element[]} affectedFlowElements The flow elements to update.
55098
+ * @param {GroupEntry[]} affectedGroupEntries The groups to update.
55099
+ */
55100
+ Modeling.prototype.updateCategoryValueRefs = function(affectedFlowElements, affectedGroupEntries) {
55101
+
55102
+ this._commandStack.execute('group.updateRefs', {
55103
+ affectedFlowElements: affectedFlowElements,
55104
+ affectedGroupEntries: affectedGroupEntries
55105
+ });
55106
+ };
55107
+
54391
55108
  /**
54392
55109
  * Claim an ID.
54393
55110
  *