bpmn-js 9.0.0-subprocesses.3 → 9.0.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 (43) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/dist/assets/bpmn-js.css +38 -4
  3. package/dist/assets/diagram-js.css +1 -1
  4. package/dist/bpmn-modeler.development.js +2411 -1110
  5. package/dist/bpmn-modeler.production.min.js +8 -8
  6. package/dist/bpmn-navigated-viewer.development.js +983 -315
  7. package/dist/bpmn-navigated-viewer.production.min.js +6 -6
  8. package/dist/bpmn-viewer.development.js +983 -315
  9. package/dist/bpmn-viewer.production.min.js +6 -6
  10. package/lib/BaseViewer.js +1 -1
  11. package/lib/draw/BpmnRenderer.js +8 -7
  12. package/lib/features/auto-resize/BpmnAutoResizeProvider.js +6 -0
  13. package/lib/features/copy-paste/BpmnCopyPaste.js +1 -0
  14. package/lib/features/di-ordering/BpmnDiOrdering.js +15 -11
  15. package/lib/features/drilldown/DrilldownBreadcrumbs.js +122 -0
  16. package/lib/features/drilldown/DrilldownCentering.js +87 -10
  17. package/lib/features/drilldown/DrilldownOverlayBehavior.js +181 -0
  18. package/lib/features/drilldown/SubprocessCompatibility.js +9 -6
  19. package/lib/features/drilldown/index.js +7 -4
  20. package/lib/features/label-editing/LabelEditingProvider.js +1 -1
  21. package/lib/features/label-editing/cmd/UpdateLabelHandler.js +29 -2
  22. package/lib/features/modeling/BpmnFactory.js +5 -1
  23. package/lib/features/modeling/BpmnUpdater.js +43 -1
  24. package/lib/features/modeling/ElementFactory.js +4 -0
  25. package/lib/features/modeling/behavior/CreateParticipantBehavior.js +59 -84
  26. package/lib/features/modeling/behavior/DropOnFlowBehavior.js +2 -2
  27. package/lib/features/modeling/behavior/RemoveEmbeddedLabelBoundsBehavior.js +34 -0
  28. package/lib/features/modeling/behavior/SubProcessPlaneBehavior.js +557 -0
  29. package/lib/features/modeling/behavior/ToggleCollapseConnectionBehaviour.js +74 -0
  30. package/lib/features/modeling/behavior/UnclaimIdBehavior.js +3 -1
  31. package/lib/features/modeling/behavior/index.js +27 -18
  32. package/lib/features/modeling/cmd/SetColorHandler.js +23 -6
  33. package/lib/features/modeling/cmd/UpdateCanvasRootHandler.js +4 -2
  34. package/lib/features/modeling/util/ModelingUtil.js +2 -20
  35. package/lib/features/ordering/BpmnOrderingProvider.js +3 -3
  36. package/lib/features/palette/PaletteProvider.js +1 -1
  37. package/lib/features/popup-menu/ReplaceMenuProvider.js +1 -1
  38. package/lib/import/BpmnImporter.js +15 -9
  39. package/lib/import/Importer.js +130 -10
  40. package/lib/util/DrilldownUtil.js +66 -0
  41. package/lib/util/ModelUtil.js +19 -0
  42. package/package.json +2 -2
  43. package/lib/features/drilldown/DrilldownOverlays.js +0 -110
package/lib/BaseViewer.js CHANGED
@@ -439,7 +439,7 @@ BaseViewer.prototype.saveSVG = wrapForCompatibility(function saveSVG(options) {
439
439
  try {
440
440
  var canvas = self.get('canvas');
441
441
 
442
- var contentNode = canvas.getDefaultLayer(),
442
+ var contentNode = canvas.getActiveLayer(),
443
443
  defsNode = domQuery('defs', canvas._svg);
444
444
 
445
445
  var contents = innerSVG(contentNode),
@@ -382,16 +382,16 @@ export default function BpmnRenderer(
382
382
  return drawPath(parentGfx, path, assign({ 'data-marker': type }, attrs));
383
383
  }
384
384
 
385
+ function renderer(type) {
386
+ return handlers[type];
387
+ }
388
+
385
389
  function as(type) {
386
390
  return function(parentGfx, element) {
387
- return handlers[type](parentGfx, element);
391
+ return renderer(type)(parentGfx, element);
388
392
  };
389
393
  }
390
394
 
391
- function renderer(type) {
392
- return handlers[type];
393
- }
394
-
395
395
  function renderEventContent(element, parentGfx) {
396
396
 
397
397
  var event = getSemantic(element);
@@ -1872,6 +1872,7 @@ export default function BpmnRenderer(
1872
1872
  // extension API, use at your own risk
1873
1873
  this._drawPath = drawPath;
1874
1874
 
1875
+ this._renderer = renderer;
1875
1876
  }
1876
1877
 
1877
1878
 
@@ -1893,7 +1894,7 @@ BpmnRenderer.prototype.canRender = function(element) {
1893
1894
 
1894
1895
  BpmnRenderer.prototype.drawShape = function(parentGfx, element) {
1895
1896
  var type = element.type;
1896
- var h = this.handlers[type];
1897
+ var h = this._renderer(type);
1897
1898
 
1898
1899
  /* jshint -W040 */
1899
1900
  return h(parentGfx, element);
@@ -1901,7 +1902,7 @@ BpmnRenderer.prototype.drawShape = function(parentGfx, element) {
1901
1902
 
1902
1903
  BpmnRenderer.prototype.drawConnection = function(parentGfx, element) {
1903
1904
  var type = element.type;
1904
- var h = this.handlers[type];
1905
+ var h = this._renderer(type);
1905
1906
 
1906
1907
  /* jshint -W040 */
1907
1908
  return h(parentGfx, element);
@@ -33,6 +33,12 @@ BpmnAutoResizeProvider.$inject = [
33
33
  */
34
34
  BpmnAutoResizeProvider.prototype.canResize = function(elements, target) {
35
35
 
36
+ // do not resize plane elements:
37
+ // root elements, collapsed sub-processes
38
+ if (is(target.di, 'bpmndi:BPMNPlane')) {
39
+ return false;
40
+ }
41
+
36
42
  if (!is(target, 'bpmn:Participant') && !is(target, 'bpmn:Lane') && !(is(target, 'bpmn:SubProcess'))) {
37
43
  return false;
38
44
  }
@@ -145,6 +145,7 @@ export default function BpmnCopyPaste(bpmnFactory, eventBus, moddleCopy) {
145
145
  );
146
146
 
147
147
  newDi = bpmnFactory.create(oldDi.$type);
148
+ newDi.bpmnElement = newBusinessObject;
148
149
 
149
150
  descriptor.di = moddleCopy.copyElement(
150
151
  oldDi,
@@ -2,6 +2,7 @@ import { getDi } from '../../util/ModelUtil';
2
2
 
3
3
  import {
4
4
  filter,
5
+ forEach,
5
6
  map
6
7
  } from 'min-dash';
7
8
 
@@ -15,21 +16,24 @@ export default function BpmnDiOrdering(eventBus, canvas) {
15
16
  eventBus.on('saveXML.start', HIGH_PRIORITY, orderDi);
16
17
 
17
18
  function orderDi() {
18
- var root = canvas.getRootElement(),
19
- rootDi = getDi(root),
20
- elements,
21
- diElements;
19
+ var rootElements = canvas.getRootElements();
22
20
 
23
- elements = selfAndAllChildren([ root ], false);
21
+ forEach(rootElements, function(root) {
22
+ var rootDi = getDi(root),
23
+ elements,
24
+ diElements;
24
25
 
25
- // only bpmndi:Shape and bpmndi:Edge can be direct children of bpmndi:Plane
26
- elements = filter(elements, function(element) {
27
- return element !== root && !element.labelTarget;
28
- });
26
+ elements = selfAndAllChildren([ root ], false);
27
+
28
+ // only bpmndi:Shape and bpmndi:Edge can be direct children of bpmndi:Plane
29
+ elements = filter(elements, function(element) {
30
+ return element !== root && !element.labelTarget;
31
+ });
29
32
 
30
- diElements = map(elements, getDi);
33
+ diElements = map(elements, getDi);
31
34
 
32
- rootDi.set('planeElement', diElements);
35
+ rootDi.set('planeElement', diElements);
36
+ });
33
37
  }
34
38
  }
35
39
 
@@ -0,0 +1,122 @@
1
+ import { domify, classes } from 'min-dom';
2
+ import { find } from 'min-dash';
3
+
4
+ import { escapeHTML } from 'diagram-js/lib/util/EscapeUtil';
5
+ import { getBusinessObject, is } from '../../util/ModelUtil';
6
+ import {
7
+ getPlaneIdFromShape
8
+ } from '../../util/DrilldownUtil';
9
+
10
+ var OPEN_CLASS = 'bjs-breadcrumbs-shown';
11
+
12
+
13
+ /**
14
+ * Adds overlays that allow switching planes on collapsed subprocesses.
15
+ *
16
+ * @param {eventBus} eventBus
17
+ * @param {elementRegistry} elementRegistry
18
+ * @param {overlays} overlays
19
+ * @param {canvas} canvas
20
+ */
21
+ export default function DrilldownBreadcrumbs(eventBus, elementRegistry, overlays, canvas) {
22
+ var breadcrumbs = domify('<ul class="bjs-breadcrumbs"></ul>');
23
+ var container = canvas.getContainer();
24
+ var containerClasses = classes(container);
25
+ container.appendChild(breadcrumbs);
26
+
27
+ var boParents = [];
28
+
29
+ // update breadcrumbs if name or ID of the primary shape changes
30
+ eventBus.on('element.changed', function(e) {
31
+ var shape = e.element,
32
+ bo = getBusinessObject(shape);
33
+
34
+ var isPresent = find(boParents, function(el) {
35
+ return el === bo;
36
+ });
37
+
38
+ if (!isPresent) {
39
+ return;
40
+ }
41
+
42
+ updateBreadcrumbs();
43
+ });
44
+
45
+ /**
46
+ * Updates the displayed breadcrumbs. If no element is provided, only the
47
+ * labels are updated.
48
+ *
49
+ * @param {djs.model.Base} [element]
50
+ */
51
+ function updateBreadcrumbs(element) {
52
+ if (element) {
53
+ boParents = getBoParentChain(element);
54
+ }
55
+
56
+ var path = boParents.map(function(parent) {
57
+ var title = escapeHTML(parent.name || parent.id);
58
+ var link = domify('<li><span class="bjs-crumb"><a title="' + title + '">' + title + '</a></span></li>');
59
+
60
+ var parentPlane = canvas.findRoot(getPlaneIdFromShape(parent)) || canvas.findRoot(parent.id);
61
+
62
+ // when the root is a collaboration, the process does not have a corresponding
63
+ // element in the elementRegisty. Instead, we search for the corresponding participant
64
+ if (!parentPlane && is(parent, 'bpmn:Process')) {
65
+ var participant = elementRegistry.find(function(element) {
66
+ var bo = getBusinessObject(element);
67
+ return bo && bo.processRef && bo.processRef === parent;
68
+ });
69
+
70
+ parentPlane = canvas.findRoot(participant.id);
71
+ }
72
+
73
+ link.addEventListener('click', function() {
74
+ canvas.setRootElement(parentPlane);
75
+ });
76
+
77
+ return link;
78
+ });
79
+
80
+ breadcrumbs.innerHTML = '';
81
+
82
+ // show breadcrumbs and expose state to .djs-container
83
+ var visible = path.length > 1;
84
+ containerClasses.toggle(OPEN_CLASS, visible);
85
+
86
+ path.forEach(function(el) {
87
+ breadcrumbs.appendChild(el);
88
+ });
89
+ }
90
+
91
+ eventBus.on('root.set', function(event) {
92
+ updateBreadcrumbs(event.element);
93
+ });
94
+
95
+ }
96
+
97
+ DrilldownBreadcrumbs.$inject = [ 'eventBus', 'elementRegistry', 'overlays', 'canvas' ];
98
+
99
+
100
+ // helpers //////////
101
+
102
+ /**
103
+ * Returns the parents for the element using the business object chain,
104
+ * starting with the root element.
105
+ *
106
+ * @param {djs.model.Shape} child
107
+ *
108
+ * @returns {Array<djs.model.Shape>} parents
109
+ */
110
+ function getBoParentChain(child) {
111
+ var bo = getBusinessObject(child);
112
+
113
+ var parents = [];
114
+
115
+ for (var element = bo; element; element = element.$parent) {
116
+ if (is(element, 'bpmn:SubProcess') || is(element, 'bpmn:Process')) {
117
+ parents.push(element);
118
+ }
119
+ }
120
+
121
+ return parents.reverse();
122
+ }
@@ -1,24 +1,37 @@
1
+ import { is } from '../../util/ModelUtil';
2
+
1
3
  /**
2
- * Move collapsed subprocesses into view when drilling down. Zoom and scroll
3
- * are saved in a session.
4
+ * Move collapsed subprocesses into view when drilling down.
5
+ *
6
+ * Zoom and scroll are saved in a session.
4
7
  *
5
8
  * @param {eventBus} eventBus
6
9
  * @param {canvas} canvas
7
10
  */
8
11
  export default function DrilldownCentering(eventBus, canvas) {
9
- var currentPlane = 'base';
10
- var positionMap = {};
11
12
 
12
- eventBus.on('plane.set', function(event) {
13
+ var currentRoot = null;
14
+ var positionMap = new Map();
15
+
16
+ eventBus.on('root.set', function(event) {
17
+ var newRoot = event.element;
13
18
  var currentViewbox = canvas.viewbox();
14
- positionMap[currentPlane] = {
19
+ var storedViewbox = positionMap.get(newRoot);
20
+
21
+ positionMap.set(currentRoot, {
15
22
  x: currentViewbox.x,
16
23
  y: currentViewbox.y,
17
24
  zoom: currentViewbox.scale
18
- };
25
+ });
19
26
 
20
- var planeId = event.plane.name;
21
- var storedViewbox = positionMap[planeId] || { x: 0, y: 0, zoom: 1 };
27
+ currentRoot = newRoot;
28
+
29
+ // current root was replaced with a collaboration, we don't update the viewbox
30
+ if (is(newRoot, 'bpmn:Collaboration') && !storedViewbox) {
31
+ return;
32
+ }
33
+
34
+ storedViewbox = storedViewbox || { x: 0, y: 0, zoom: 1 };
22
35
 
23
36
  var dx = (currentViewbox.x - storedViewbox.x) * currentViewbox.scale,
24
37
  dy = (currentViewbox.y - storedViewbox.y) * currentViewbox.scale;
@@ -33,9 +46,73 @@ export default function DrilldownCentering(eventBus, canvas) {
33
46
  if (storedViewbox.zoom !== currentViewbox.scale) {
34
47
  canvas.zoom(storedViewbox.zoom, { x: 0, y: 0 });
35
48
  }
49
+ });
36
50
 
37
- currentPlane = planeId;
51
+ eventBus.on('diagram.clear', function() {
52
+ positionMap.clear();
53
+ currentRoot = null;
38
54
  });
55
+
39
56
  }
40
57
 
41
58
  DrilldownCentering.$inject = [ 'eventBus', 'canvas' ];
59
+
60
+
61
+ /**
62
+ * ES5 Map implementation. Works.
63
+ */
64
+ function Map() {
65
+
66
+ this._entries = [];
67
+
68
+ this.set = function(key, value) {
69
+
70
+ var found = false;
71
+
72
+ for (var k in this._entries) {
73
+ if (this._entries[k][0] === key) {
74
+ this._entries[k][1] = value;
75
+
76
+ found = true;
77
+
78
+ break;
79
+ }
80
+ }
81
+
82
+ if (!found) {
83
+ this._entries.push([ key, value ]);
84
+ }
85
+ };
86
+
87
+ this.get = function(key) {
88
+
89
+ for (var k in this._entries) {
90
+ if (this._entries[k][0] === key) {
91
+ return this._entries[k][1];
92
+ }
93
+ }
94
+
95
+ return null;
96
+ };
97
+
98
+ this.clear = function() {
99
+ this._entries.length = 0;
100
+ };
101
+
102
+ this.remove = function(key) {
103
+
104
+ var idx = -1;
105
+
106
+ for (var k in this._entries) {
107
+ if (this._entries[k][0] === key) {
108
+ idx = k;
109
+
110
+ break;
111
+ }
112
+ }
113
+
114
+ if (idx !== -1) {
115
+ this._entries.splice(idx, 1);
116
+ }
117
+ };
118
+ }
@@ -0,0 +1,181 @@
1
+ import inherits from 'inherits';
2
+
3
+ import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
4
+ import { is } from '../../util/ModelUtil';
5
+ import { classes, domify } from 'min-dom';
6
+ import { getPlaneIdFromShape } from '../../util/DrilldownUtil';
7
+
8
+ var LOW_PRIORITY = 250;
9
+ 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>';
10
+
11
+ var EMPTY_MARKER = 'bjs-drilldown-empty';
12
+
13
+ export default function DrilldownOverlayBehavior(
14
+ canvas, eventBus, elementRegistry, overlays
15
+ ) {
16
+ CommandInterceptor.call(this, eventBus);
17
+
18
+ this._canvas = canvas;
19
+ this._eventBus = eventBus;
20
+ this._elementRegistry = elementRegistry;
21
+ this._overlays = overlays;
22
+
23
+ var self = this;
24
+
25
+ this.executed('shape.toggleCollapse', LOW_PRIORITY, function(context) {
26
+ var shape = context.shape;
27
+
28
+ // Add overlay to the collapsed shape
29
+ if (self.canDrillDown(shape)) {
30
+ self.addOverlay(shape);
31
+ } else {
32
+ self.removeOverlay(shape);
33
+ }
34
+ }, true);
35
+
36
+
37
+ this.reverted('shape.toggleCollapse', LOW_PRIORITY, function(context) {
38
+ var shape = context.shape;
39
+
40
+ // Add overlay to the collapsed shape
41
+ if (self.canDrillDown(shape)) {
42
+ self.addOverlay(shape);
43
+ } else {
44
+ self.removeOverlay(shape);
45
+ }
46
+ }, true);
47
+
48
+
49
+ this.executed(['shape.create', 'shape.move', 'shape.delete'], LOW_PRIORITY,
50
+ function(context) {
51
+ var oldParent = context.oldParent,
52
+ newParent = context.newParent || context.parent,
53
+ shape = context.shape;
54
+
55
+ // Add overlay to the collapsed shape
56
+ if (self.canDrillDown(shape)) {
57
+ self.addOverlay(shape);
58
+ }
59
+
60
+ self.updateDrilldownOverlay(oldParent);
61
+ self.updateDrilldownOverlay(newParent);
62
+ self.updateDrilldownOverlay(shape);
63
+ }, true);
64
+
65
+
66
+ this.reverted(['shape.create', 'shape.move', 'shape.delete'], LOW_PRIORITY,
67
+ function(context) {
68
+ var oldParent = context.oldParent,
69
+ newParent = context.newParent || context.parent,
70
+ shape = context.shape;
71
+
72
+ // Add overlay to the collapsed shape
73
+ if (self.canDrillDown(shape)) {
74
+ self.addOverlay(shape);
75
+ }
76
+
77
+ self.updateDrilldownOverlay(oldParent);
78
+ self.updateDrilldownOverlay(newParent);
79
+ self.updateDrilldownOverlay(shape);
80
+ }, true);
81
+
82
+
83
+ eventBus.on('import.done', function() {
84
+ elementRegistry.filter(function(e) {
85
+ return self.canDrillDown(e);
86
+ }).map(function(el) {
87
+ self.addOverlay(el);
88
+ });
89
+ });
90
+
91
+ }
92
+
93
+ inherits(DrilldownOverlayBehavior, CommandInterceptor);
94
+
95
+ DrilldownOverlayBehavior.prototype.updateDrilldownOverlay = function(shape) {
96
+ var canvas = this._canvas;
97
+
98
+ if (!shape) {
99
+ return;
100
+ }
101
+
102
+ var root = canvas.findRoot(shape);
103
+ if (root) {
104
+ this.updateOverlayVisibility(root);
105
+ }
106
+ };
107
+
108
+
109
+ DrilldownOverlayBehavior.prototype.canDrillDown = function(element) {
110
+ var canvas = this._canvas;
111
+ return is(element, 'bpmn:SubProcess') && canvas.findRoot(getPlaneIdFromShape(element));
112
+ };
113
+
114
+ /**
115
+ * Updates visibility of the drilldown overlay. If the plane has no elements,
116
+ * the drilldown will be only shown when the element is selected.
117
+ *
118
+ * @param {djs.model.Shape|djs.model.Root} element collapsed shape or root element
119
+ */
120
+ DrilldownOverlayBehavior.prototype.updateOverlayVisibility = function(element) {
121
+ var overlays = this._overlays;
122
+
123
+ var bo = element.businessObject;
124
+
125
+ var overlay = overlays.get({ element: bo.id, type: 'drilldown' })[0];
126
+
127
+ if (!overlay) {
128
+ return;
129
+ }
130
+
131
+ var hasContent = bo && bo.flowElements && bo.flowElements.length;
132
+ classes(overlay.html).toggle(EMPTY_MARKER, !hasContent);
133
+ };
134
+
135
+ /**
136
+ * Attaches a drilldown button to the given element. We assume that the plane has
137
+ * the same id as the element.
138
+ *
139
+ * @param {djs.model.Shape} element collapsed shape
140
+ */
141
+ DrilldownOverlayBehavior.prototype.addOverlay = function(element) {
142
+ var canvas = this._canvas;
143
+ var overlays = this._overlays;
144
+
145
+ var existingOverlays = overlays.get({ element: element, type: 'drilldown' });
146
+ if (existingOverlays.length) {
147
+ this.removeOverlay(element);
148
+ }
149
+
150
+ var button = domify('<button class="bjs-drilldown">' + ARROW_DOWN_SVG + '</button>');
151
+
152
+ button.addEventListener('click', function() {
153
+ canvas.setRootElement(canvas.findRoot(getPlaneIdFromShape(element)));
154
+ });
155
+
156
+ overlays.add(element, 'drilldown', {
157
+ position: {
158
+ bottom: -7,
159
+ right: -8
160
+ },
161
+ html: button
162
+ });
163
+
164
+ this.updateOverlayVisibility(element);
165
+ };
166
+
167
+ DrilldownOverlayBehavior.prototype.removeOverlay = function(element) {
168
+ var overlays = this._overlays;
169
+
170
+ overlays.remove({
171
+ element: element,
172
+ type: 'drilldown'
173
+ });
174
+ };
175
+
176
+ DrilldownOverlayBehavior.$inject = [
177
+ 'canvas',
178
+ 'eventBus',
179
+ 'elementRegistry',
180
+ 'overlays'
181
+ ];
@@ -83,6 +83,15 @@ SubprocessCompatibility.prototype.createNewDiagrams = function(plane) {
83
83
 
84
84
  var newDiagrams = [];
85
85
 
86
+ // create new planes for all collapsed subprocesses, even when they are empty
87
+ collapsedElements.forEach(function(element) {
88
+ if (!self._processToDiagramMap[element.id]) {
89
+ var diagram = self.createDiagram(element);
90
+ self._processToDiagramMap[element.id] = diagram;
91
+ newDiagrams.push(diagram);
92
+ }
93
+ });
94
+
86
95
  elementsToMove.forEach(function(element) {
87
96
  var diElement = element.diElement;
88
97
  var parent = element.parent;
@@ -98,12 +107,6 @@ SubprocessCompatibility.prototype.createNewDiagrams = function(plane) {
98
107
  }
99
108
 
100
109
  var diagram = self._processToDiagramMap[parent.id];
101
- if (!diagram) {
102
- diagram = self.createDiagram(parent);
103
- self._processToDiagramMap[parent.id] = diagram;
104
- newDiagrams.push(diagram);
105
- }
106
-
107
110
  self.moveToDiPlane(diElement, diagram.plane);
108
111
  });
109
112
 
@@ -1,14 +1,17 @@
1
1
  import OverlaysModule from 'diagram-js/lib/features/overlays';
2
2
  import ChangeSupportModule from 'diagram-js/lib/features/change-support';
3
+ import RootElementsModule from 'diagram-js/lib/features/root-elements';
3
4
 
4
- import DrilldownOverlays from './DrilldownOverlays';
5
+ import DrilldownBreadcrumbs from './DrilldownBreadcrumbs';
5
6
  import DrilldownCentering from './DrilldownCentering';
6
7
  import SubprocessCompatibility from './SubprocessCompatibility';
8
+ import DrilldownOverlayBehavior from './DrilldownOverlayBehavior';
7
9
 
8
10
  export default {
9
- __depends__: [ OverlaysModule, ChangeSupportModule ],
10
- __init__: [ 'drilldownOverlays', 'drilldownCentering', 'subprocessCompatibility'],
11
- drilldownOverlays: [ 'type', DrilldownOverlays ],
11
+ __depends__: [ OverlaysModule, ChangeSupportModule, RootElementsModule ],
12
+ __init__: [ 'drilldownBreadcrumbs', 'drilldownOverlayBehavior', 'drilldownCentering', 'subprocessCompatibility'],
13
+ drilldownBreadcrumbs: [ 'type', DrilldownBreadcrumbs ],
12
14
  drilldownCentering: [ 'type', DrilldownCentering ],
15
+ drilldownOverlayBehavior: [ 'type', DrilldownOverlayBehavior ],
13
16
  subprocessCompatibility: [ 'type', SubprocessCompatibility ]
14
17
  };
@@ -105,7 +105,7 @@ export default function LabelEditingProvider(
105
105
 
106
106
  function activateDirectEdit(element, force) {
107
107
  if (force ||
108
- isAny(element, [ 'bpmn:Task', 'bpmn:TextAnnotation', 'bpmn:Group' ]) ||
108
+ isAny(element, [ 'bpmn:Task', 'bpmn:TextAnnotation' ]) ||
109
109
  isCollapsedSubProcess(element)) {
110
110
 
111
111
  directEditing.activate(element);
@@ -11,6 +11,7 @@ import {
11
11
  } from '../../../util/LabelUtil';
12
12
 
13
13
  import {
14
+ getDi,
14
15
  is
15
16
  } from '../../../util/ModelUtil';
16
17
 
@@ -23,7 +24,30 @@ var NULL_DIMENSIONS = {
23
24
  /**
24
25
  * A handler that updates the text of a BPMN element.
25
26
  */
26
- export default function UpdateLabelHandler(modeling, textRenderer) {
27
+ export default function UpdateLabelHandler(modeling, textRenderer, bpmnFactory) {
28
+
29
+ /**
30
+ * Creates an empty `diLabel` attribute for embedded labels.
31
+ *
32
+ * @param {djs.model.Base} element
33
+ * @param {string} text
34
+ */
35
+ function ensureInternalLabelDi(element, text) {
36
+ if (isLabelExternal(element)) {
37
+ return;
38
+ }
39
+
40
+ var di = getDi(element);
41
+
42
+ if (text && !di.label) {
43
+ di.label = bpmnFactory.create('bpmndi:BPMNLabel');
44
+ }
45
+
46
+ if (!text && di.label) {
47
+ di.label = null;
48
+ }
49
+ }
50
+
27
51
 
28
52
  /**
29
53
  * Set the label and return the changed elements.
@@ -42,6 +66,8 @@ export default function UpdateLabelHandler(modeling, textRenderer) {
42
66
 
43
67
  setLabel(label, text, labelTarget !== label);
44
68
 
69
+ ensureInternalLabelDi(element, text);
70
+
45
71
  return [ label, labelTarget ];
46
72
  }
47
73
 
@@ -127,7 +153,8 @@ export default function UpdateLabelHandler(modeling, textRenderer) {
127
153
 
128
154
  UpdateLabelHandler.$inject = [
129
155
  'modeling',
130
- 'textRenderer'
156
+ 'textRenderer',
157
+ 'bpmnFactory'
131
158
  ];
132
159
 
133
160
 
@@ -42,6 +42,10 @@ BpmnFactory.prototype._needsId = function(element) {
42
42
  };
43
43
 
44
44
  BpmnFactory.prototype._ensureId = function(element) {
45
+ if (element.id) {
46
+ this._model.ids.claim(element.id, element);
47
+ return;
48
+ }
45
49
 
46
50
  // generate semantic ids for elements
47
51
  // bpmn:SequenceFlow -> SequenceFlow_ID
@@ -112,7 +116,7 @@ BpmnFactory.prototype.createDiWaypoint = function(point) {
112
116
  BpmnFactory.prototype.createDiEdge = function(semantic, attrs) {
113
117
  return this.create('bpmndi:BPMNEdge', assign({
114
118
  bpmnElement: semantic,
115
- waypoints: this.createDiWaypoints([])
119
+ waypoint: this.createDiWaypoints([])
116
120
  }, attrs));
117
121
  };
118
122