bpmn-js 8.8.0 → 9.0.0-subprocesses.1

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 (53) hide show
  1. package/CHANGELOG.md +15 -1
  2. package/dist/assets/bpmn-js.css +58 -0
  3. package/dist/assets/diagram-js.css +1 -0
  4. package/dist/bpmn-modeler.development.js +1489 -827
  5. package/dist/bpmn-modeler.production.min.js +7 -6
  6. package/dist/bpmn-navigated-viewer.development.js +20890 -19973
  7. package/dist/bpmn-navigated-viewer.production.min.js +22 -20
  8. package/dist/bpmn-viewer.development.js +20091 -19174
  9. package/dist/bpmn-viewer.production.min.js +22 -20
  10. package/lib/BaseViewer.js +0 -13
  11. package/lib/Viewer.js +3 -1
  12. package/lib/draw/BpmnRenderUtil.js +6 -4
  13. package/lib/draw/BpmnRenderer.js +367 -296
  14. package/lib/features/context-pad/ContextPadProvider.js +1 -1
  15. package/lib/features/copy-paste/BpmnCopyPaste.js +13 -13
  16. package/lib/features/copy-paste/ModdleCopy.js +19 -2
  17. package/lib/features/di-ordering/BpmnDiOrdering.js +2 -3
  18. package/lib/features/label-editing/LabelEditingPreview.js +3 -3
  19. package/lib/features/label-editing/cmd/UpdateLabelHandler.js +2 -1
  20. package/lib/features/modeling/BpmnFactory.js +8 -8
  21. package/lib/features/modeling/BpmnUpdater.js +35 -27
  22. package/lib/features/modeling/ElementFactory.js +60 -37
  23. package/lib/features/modeling/behavior/DataStoreBehavior.js +3 -1
  24. package/lib/features/modeling/behavior/IsHorizontalFix.js +7 -4
  25. package/lib/features/modeling/behavior/LabelBehavior.js +8 -7
  26. package/lib/features/modeling/behavior/ResizeBehavior.js +129 -3
  27. package/lib/features/modeling/behavior/ToggleElementCollapseBehaviour.js +6 -6
  28. package/lib/features/modeling/behavior/util/ResizeUtil.js +1 -132
  29. package/lib/features/modeling/cmd/UpdateCanvasRootHandler.js +8 -6
  30. package/lib/features/modeling/cmd/UpdatePropertiesHandler.js +19 -12
  31. package/lib/features/modeling/cmd/UpdateSemanticParentHandler.js +5 -3
  32. package/lib/features/palette/PaletteProvider.js +3 -1
  33. package/lib/features/popup-menu/ReplaceMenuProvider.js +5 -5
  34. package/lib/features/popup-menu/util/TypeUtil.js +1 -1
  35. package/lib/features/replace/BpmnReplace.js +29 -29
  36. package/lib/features/subprocess-navigation/SubprocessCentering.js +55 -0
  37. package/lib/features/subprocess-navigation/SubprocessCompatibility.js +135 -0
  38. package/lib/features/subprocess-navigation/SubprocessElements.js +55 -0
  39. package/lib/features/subprocess-navigation/SubprocessFlows.js +109 -0
  40. package/lib/features/subprocess-navigation/SubprocessOverlays.js +104 -0
  41. package/lib/features/subprocess-navigation/index.js +18 -0
  42. package/lib/import/BpmnImporter.js +76 -22
  43. package/lib/import/BpmnTreeWalker.js +19 -17
  44. package/lib/import/Importer.js +17 -6
  45. package/lib/util/CompatibilityUtil.js +21 -1
  46. package/lib/util/DiUtil.js +10 -3
  47. package/lib/util/LabelUtil.js +2 -3
  48. package/lib/util/ModelUtil.js +11 -0
  49. package/package.json +2 -2
  50. package/test/helper/index.js +6 -1
  51. package/test/matchers/BoundsMatchers.js +10 -10
  52. package/test/matchers/ConnectionMatchers.js +5 -5
  53. package/test/util/MockEvents.js +10 -2
@@ -36,6 +36,7 @@ function copyProperties(source, target, properties) {
36
36
  });
37
37
  }
38
38
 
39
+
39
40
  var CUSTOM_PROPERTIES = [
40
41
  'cancelActivity',
41
42
  'instantiate',
@@ -44,8 +45,10 @@ var CUSTOM_PROPERTIES = [
44
45
  'isInterrupting'
45
46
  ];
46
47
 
47
-
48
- function toggeling(element, target) {
48
+ /**
49
+ * Check if element should be collapsed or expanded.
50
+ */
51
+ function shouldToggleCollapsed(element, targetElement) {
49
52
 
50
53
  var oldCollapsed = (
51
54
  element && has(element, 'collapsed') ? element.collapsed : !isExpanded(element)
@@ -53,11 +56,11 @@ function toggeling(element, target) {
53
56
 
54
57
  var targetCollapsed;
55
58
 
56
- if (target && (has(target, 'collapsed') || has(target, 'isExpanded'))) {
59
+ if (targetElement && (has(targetElement, 'collapsed') || has(targetElement, 'isExpanded'))) {
57
60
 
58
61
  // property is explicitly set so use it
59
62
  targetCollapsed = (
60
- has(target, 'collapsed') ? target.collapsed : !target.isExpanded
63
+ has(targetElement, 'collapsed') ? targetElement.collapsed : !targetElement.isExpanded
61
64
  );
62
65
  } else {
63
66
 
@@ -66,7 +69,6 @@ function toggeling(element, target) {
66
69
  }
67
70
 
68
71
  if (oldCollapsed !== targetCollapsed) {
69
- element.collapsed = oldCollapsed;
70
72
  return true;
71
73
  }
72
74
 
@@ -74,7 +76,6 @@ function toggeling(element, target) {
74
76
  }
75
77
 
76
78
 
77
-
78
79
  /**
79
80
  * This module takes care of replacing BPMN elements
80
81
  */
@@ -105,15 +106,13 @@ export default function BpmnReplace(
105
106
  var type = target.type,
106
107
  oldBusinessObject = element.businessObject;
107
108
 
108
- if (isSubProcess(oldBusinessObject)) {
109
- if (type === 'bpmn:SubProcess') {
110
- if (toggeling(element, target)) {
109
+ if (isSubProcess(oldBusinessObject) && type === 'bpmn:SubProcess') {
110
+ if (shouldToggleCollapsed(element, target)) {
111
111
 
112
- // expanding or collapsing process
113
- modeling.toggleCollapse(element);
112
+ // expanding or collapsing process
113
+ modeling.toggleCollapse(element);
114
114
 
115
- return element;
116
- }
115
+ return element;
117
116
  }
118
117
  }
119
118
 
@@ -121,9 +120,20 @@ export default function BpmnReplace(
121
120
 
122
121
  var newElement = {
123
122
  type: type,
124
- businessObject: newBusinessObject
123
+ businessObject: newBusinessObject,
125
124
  };
126
125
 
126
+ newElement.di = {};
127
+
128
+ // colors will be set to DI
129
+ copyProperties(element.di, newElement.di, [
130
+ 'fill',
131
+ 'stroke',
132
+ 'background-color',
133
+ 'border-color',
134
+ 'color'
135
+ ]);
136
+
127
137
  var elementProps = getPropertyNames(oldBusinessObject.$descriptor),
128
138
  newElementProps = getPropertyNames(newBusinessObject.$descriptor, true),
129
139
  copyProps = intersection(elementProps, newElementProps);
@@ -183,7 +193,7 @@ export default function BpmnReplace(
183
193
  if (isSubProcess(oldBusinessObject)) {
184
194
 
185
195
  // no toggeling, so keep old state
186
- newElement.isExpanded = isExpanded(oldBusinessObject);
196
+ newElement.isExpanded = isExpanded(element);
187
197
  }
188
198
 
189
199
  // else if property is explicitly set, use it
@@ -194,7 +204,7 @@ export default function BpmnReplace(
194
204
  // TODO: need also to respect min/max Size
195
205
  // copy size, from an expanded subprocess to an expanded alternative subprocess
196
206
  // except bpmn:Task, because Task is always expanded
197
- if ((isExpanded(oldBusinessObject) && !is(oldBusinessObject, 'bpmn:Task')) && newElement.isExpanded) {
207
+ if ((isExpanded(element) && !is(oldBusinessObject, 'bpmn:Task')) && newElement.isExpanded) {
198
208
  newElement.width = element.width;
199
209
  newElement.height = element.height;
200
210
  }
@@ -219,12 +229,12 @@ export default function BpmnReplace(
219
229
 
220
230
  // apply same width and default height
221
231
  newElement.width = element.width;
222
- newElement.height = elementFactory._getDefaultSize(newBusinessObject).height;
232
+ newElement.height = elementFactory.getDefaultSize(newElement).height;
223
233
  }
224
234
 
225
235
  if (!rules.allowed('shape.resize', { shape: newBusinessObject })) {
226
- newElement.height = elementFactory._getDefaultSize(newBusinessObject).height;
227
- newElement.width = elementFactory._getDefaultSize(newBusinessObject).width;
236
+ newElement.height = elementFactory.getDefaultSize(newElement).height;
237
+ newElement.width = elementFactory.getDefaultSize(newElement).width;
228
238
  }
229
239
 
230
240
  newBusinessObject.name = oldBusinessObject.name;
@@ -262,16 +272,6 @@ export default function BpmnReplace(
262
272
  newElement.x = element.x + (element.width - newElement.width) / 2;
263
273
  }
264
274
 
265
- newElement.di = {};
266
-
267
- // colors will be set to DI
268
- copyProperties(oldBusinessObject.di, newElement.di, [
269
- 'fill',
270
- 'stroke',
271
- 'background-color',
272
- 'border-color',
273
- 'color'
274
- ]);
275
275
 
276
276
  newElement = replace.replaceElement(element, newElement, hints);
277
277
 
@@ -0,0 +1,55 @@
1
+ var defaultPosition = { x: 100, y: 50 };
2
+
3
+ export default function SubprocessCentering(eventBus, canvas) {
4
+ var currentPlane = 'base';
5
+ var positionMap = {};
6
+
7
+ eventBus.on('plane.set', function(event) {
8
+
9
+ var currentViewbox = canvas.viewbox();
10
+ positionMap[currentPlane] = {
11
+ x: currentViewbox.x,
12
+ y: currentViewbox.y,
13
+ zoom: currentViewbox.scale
14
+ };
15
+
16
+ var planeId = event.plane.name;
17
+ var storedViewbox = positionMap[planeId];
18
+
19
+ if (!storedViewbox) {
20
+ if (!event.plane.rootElement.isImplicit) {
21
+ storedViewbox = {
22
+ x: 0,
23
+ y: 0,
24
+ zoom: 1
25
+ };
26
+ }
27
+ else {
28
+ var currentBoundingBox = canvas.getActiveLayer().getBBox();
29
+ storedViewbox = {
30
+ x: currentBoundingBox.x - defaultPosition.x,
31
+ y: currentBoundingBox.y - defaultPosition.y,
32
+ zoom: 1
33
+ };
34
+ }
35
+ }
36
+
37
+ var dx = (currentViewbox.x - storedViewbox.x) * currentViewbox.scale,
38
+ dy = (currentViewbox.y - storedViewbox.y) * currentViewbox.scale;
39
+
40
+ if (dx !== 0 || dy !== 0) {
41
+ canvas.scroll({
42
+ dx: dx,
43
+ dy: dy
44
+ });
45
+ }
46
+
47
+ if (storedViewbox.zoom !== currentViewbox.scale) {
48
+ canvas.zoom(storedViewbox.zoom, { x: 0, y: 0 });
49
+ }
50
+
51
+ currentPlane = planeId;
52
+ });
53
+ }
54
+
55
+ SubprocessCentering.$inject = [ 'eventBus', 'canvas' ];
@@ -0,0 +1,135 @@
1
+
2
+ import { selfAndAllChildren } from 'diagram-js/lib/util/Elements';
3
+ import { isExpanded } from '../../util/DiUtil';
4
+ import { getBusinessObject, getDi, is } from '../../util/ModelUtil';
5
+
6
+ export default function SubprocessCompatibility(eventBus, elementRegistry, canvas, moddle, elementFactory, bpmnjs) {
7
+ this._eventBus = eventBus;
8
+ this._elementRegistry = elementRegistry;
9
+ this._canvas = canvas;
10
+ this._bpmnjs = bpmnjs;
11
+ this._moddle = moddle;
12
+ this._elementFactory = elementFactory;
13
+
14
+ var self = this;
15
+
16
+ eventBus.on('import.done', 1500, function() {
17
+ self._handleImport();
18
+ });
19
+ }
20
+
21
+ SubprocessCompatibility.prototype._handleImport = function() {
22
+ var elementRegistry = this._elementRegistry;
23
+ var canvas = this._canvas;
24
+ var elementFactory = this._elementFactory;
25
+ var self = this;
26
+ var legacyProcesses = elementRegistry.filter(function(element) {
27
+ return is(element, 'bpmn:SubProcess') && !isExpanded(element) && element.children && element.children.length;
28
+ });
29
+
30
+ legacyProcesses.forEach(function(oldParent) {
31
+ var bo = getBusinessObject(oldParent);
32
+
33
+ var newDiagram = self.createDiagram(bo);
34
+
35
+ var newParent = elementFactory.createRoot(
36
+ {
37
+ id: bo.id,
38
+ type: bo.$type,
39
+ businessObject: bo,
40
+ di: newDiagram.plane
41
+ }
42
+ );
43
+
44
+ newParent.id = newParent.id + '_plane';
45
+
46
+ canvas.createPlane(bo.id, newParent);
47
+
48
+ var elementsToChange = selfAndAllChildren(oldParent).filter(function(el) {
49
+ return el !== oldParent;
50
+ });
51
+
52
+ self.moveElementsToRoot(elementsToChange);
53
+
54
+ elementsToChange.forEach(function(el) {
55
+ if (el.parent === oldParent) {
56
+ el.parent = newParent;
57
+ }
58
+ el.hidden = el.parent && (el.parent.hidden || el.parent.collapsed);
59
+
60
+ self.moveToDiPlane(el, newDiagram.plane);
61
+
62
+ self._eventBus.fire('elements.changed', { elements: [el] });
63
+ });
64
+ });
65
+
66
+ };
67
+
68
+ SubprocessCompatibility.prototype.moveToDiPlane = function(element, newPlane) {
69
+ var di = getDi(element);
70
+ var containingDiagram = findRootDiagram(di);
71
+
72
+ // Remove DI from old Plane and add it to the new one
73
+ var parentPlaneElement = containingDiagram.plane.get('planeElement');
74
+ parentPlaneElement.splice(parentPlaneElement.indexOf(di), 1);
75
+ newPlane.get('planeElement').push(di);
76
+ };
77
+
78
+ SubprocessCompatibility.prototype.moveElementsToRoot = function(elements) {
79
+ var defaultPosition = { x: 180, y: 160 },
80
+ minX = Infinity,
81
+ minY = Infinity;
82
+
83
+ elements.forEach(function(el) {
84
+ minX = Math.min(minX, el.x || Infinity);
85
+ minY = Math.min(minY, el.y || Infinity);
86
+ });
87
+
88
+ var xOffset = defaultPosition.x - minX;
89
+ var yOffset = defaultPosition.y - minY;
90
+
91
+ elements.forEach(function(el) {
92
+ if (el.waypoints) {
93
+ el.waypoints.forEach(function(waypoint) {
94
+ waypoint.x = waypoint.x + xOffset;
95
+ waypoint.y = waypoint.y + yOffset;
96
+ });
97
+ } else {
98
+ el.x = el.x + xOffset;
99
+ el.y = el.y + yOffset;
100
+ }
101
+ });
102
+ };
103
+
104
+ SubprocessCompatibility.prototype.getDefinitions = function() {
105
+ return this._bpmnjs._definitions || [];
106
+ };
107
+
108
+ SubprocessCompatibility.prototype.getDiagrams = function() {
109
+ return this.getDefinitions().diagrams || [];
110
+ };
111
+
112
+ SubprocessCompatibility.prototype.createDiagram = function(bo) {
113
+ var plane = this._moddle.create('bpmndi:BPMNPlane', { bpmnElement: bo });
114
+ var diagram = this._moddle.create('bpmndi:BPMNDiagram', {
115
+ plane: plane
116
+ });
117
+ plane.$parent = diagram;
118
+ plane.bpmnElement = bo;
119
+ diagram.$parent = this.getDefinitions();
120
+ this.getDiagrams().push(diagram);
121
+ return diagram;
122
+ };
123
+
124
+ SubprocessCompatibility.$inject = [ 'eventBus', 'elementRegistry', 'canvas', 'moddle', 'elementFactory', 'bpmnjs' ];
125
+
126
+
127
+ // Util
128
+
129
+ var findRootDiagram = function(element) {
130
+ if (is(element, 'bpmndi:BPMNDiagram')) {
131
+ return element;
132
+ } else {
133
+ return findRootDiagram(element.$parent);
134
+ }
135
+ };
@@ -0,0 +1,55 @@
1
+ import { getBusinessObject, is } from '../../util/ModelUtil';
2
+
3
+ export default function SubprocessElements(eventBus, elementRegistry, canvas, elementFactory) {
4
+ var attachBoundaries = function() {
5
+ var secondaryShapes = elementRegistry.filter(function(el) {
6
+ return is(el, 'bpmn:SubProcess') && el.isSecondary;
7
+ });
8
+
9
+ secondaryShapes.forEach(function(process) {
10
+
11
+ // Add Boundary events
12
+ if (process.primaryShape && process.primaryShape.attachers) {
13
+ process.primaryShape.attachers.forEach(function(boundary) {
14
+ var bo = getBusinessObject(boundary);
15
+
16
+ var primary = process.primaryShape;
17
+
18
+ var relativeXPos = (boundary.x + 15 - primary.x) / primary.width;
19
+ var relativeYPos = (boundary.y + 15 - primary.y) / primary.height;
20
+
21
+ var dx = process.x + (process.width * relativeXPos) - 15;
22
+ var dy = process.y + (process.height * relativeYPos) - 15;
23
+
24
+ var boundaryShape = elementFactory.createShape({
25
+ id: bo.id + '_secondary',
26
+ businessObject: bo,
27
+ type: 'bpmn:BoundaryEvent',
28
+ hidden: false,
29
+ x: dx,
30
+ y: dy,
31
+ width: 30,
32
+ height: 30,
33
+ isFrame: false,
34
+ isSecondary: true,
35
+ primaryShape: boundary,
36
+ di: boundary.di
37
+ });
38
+
39
+ canvas.addShape(boundaryShape, process.parent);
40
+
41
+ if (!process.attachers) {
42
+ process.attachers = [];
43
+ }
44
+
45
+ process.attachers.push(boundaryShape);
46
+ });
47
+ }
48
+ });
49
+ };
50
+
51
+ eventBus.on('import.done', attachBoundaries);
52
+ }
53
+
54
+
55
+ SubprocessElements.$inject = [ 'eventBus', 'elementRegistry', 'canvas', 'elementFactory' ];
@@ -0,0 +1,109 @@
1
+ var FLOW_LENGTH = 50;
2
+ var HIGH_RENDER_PRIORITY = 2000;
3
+
4
+ export default function SubprocessFlows(eventBus, config) {
5
+
6
+ var mutedStrokeColor = (config && config.mutedStrokeColor) || '#dddddd';
7
+
8
+ function drawFakeFlows(element, parentGfx) {
9
+ var primary = element.primaryShape;
10
+
11
+ var drawFakeConnection = function(connection, isOutgoing) {
12
+
13
+ var segment;
14
+ if (isOutgoing) {
15
+ segment = connection.waypoints.slice(0, 2);
16
+
17
+ // Reverse order for normalizing
18
+ segment = segment.reverse();
19
+ } else {
20
+ segment = connection.waypoints.slice(connection.waypoints.length - 2);
21
+ }
22
+
23
+ var endpoint = segment[1];
24
+
25
+ var relativePosition = {
26
+ x: (endpoint.x - primary.x) / primary.width,
27
+ y: (endpoint.y - primary.y) / primary.height
28
+ };
29
+
30
+ var anchorPoint = {
31
+ x: endpoint.x - (element.width * relativePosition.x),
32
+ y: endpoint.y - (element.height * relativePosition.y)
33
+ };
34
+
35
+ var newWaypoints = segment.map(function(el) {
36
+ return { x: el.x - anchorPoint.x, y: el.y - anchorPoint.y };
37
+ });
38
+
39
+ newWaypoints[0] = normalizeLength(newWaypoints[1], newWaypoints[0], FLOW_LENGTH);
40
+
41
+ var attrs = {
42
+ stroke: mutedStrokeColor
43
+ };
44
+
45
+ if (isOutgoing) {
46
+
47
+ // Reverse order again for correct end marker position
48
+ newWaypoints = newWaypoints.reverse();
49
+ } else {
50
+
51
+ // Remove start marker for incoming flows
52
+ attrs.markerStart = undefined;
53
+ }
54
+
55
+ eventBus.fire('render.connection', {
56
+ type: connection.type,
57
+ gfx: parentGfx,
58
+ element: {
59
+ type: connection.type,
60
+ waypoints: newWaypoints,
61
+ di: connection.di,
62
+ businessObject: connection.businessObject
63
+ },
64
+ attrs: attrs
65
+ });
66
+ };
67
+
68
+ primary.incoming && primary.incoming.forEach(function(connection) {
69
+ drawFakeConnection(connection, false);
70
+ });
71
+
72
+ primary.outgoing && primary.outgoing.forEach(function(connection) {
73
+ drawFakeConnection(connection, true);
74
+ });
75
+ }
76
+
77
+ eventBus.on([ 'render.shape' ], HIGH_RENDER_PRIORITY, function(evt, context) {
78
+ var element = context.element,
79
+ visuals = context.gfx;
80
+
81
+ if (element.isSecondary && element.primaryShape) {
82
+ drawFakeFlows(element, visuals);
83
+ }
84
+
85
+ });
86
+
87
+ }
88
+
89
+ SubprocessFlows.$inject = [ 'eventBus', 'config' ];
90
+
91
+
92
+ // helpers
93
+
94
+ function normalizeLength(fixedPoint, variablePoint, length) {
95
+ var dx = fixedPoint.x - variablePoint.x,
96
+ dy = fixedPoint.y - variablePoint.y,
97
+ totalDistance = Math.abs(dx) + Math.abs(dy);
98
+
99
+ dx = dx / totalDistance;
100
+ dy = dy / totalDistance;
101
+
102
+ dx *= length;
103
+ dy *= length;
104
+
105
+ return {
106
+ x: fixedPoint.x - dx,
107
+ y: fixedPoint.y - dy
108
+ };
109
+ }
@@ -0,0 +1,104 @@
1
+ import { domify } from 'min-dom';
2
+
3
+ import { escapeHTML } from 'diagram-js/lib/util/EscapeUtil';
4
+ import { getBusinessObject, is } from '../../util/ModelUtil';
5
+
6
+ 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>';
7
+ var ARROW_UP_SVG = '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M11.1819805,12.4926407 L5.5003106,6.8103106 L5.5,12 L4,12 L4,4 L12,4 L12,5.5 L6.3103106,5.5003106 L12.2426407,11.4319805 C12.5355339,11.7248737 12.5355339,12.1997475 12.2426407,12.4926407 C11.9497475,12.7855339 11.4748737,12.7855339 11.1819805,12.4926407 Z"/></svg>';
8
+
9
+ export default function SubprocessOverlays(eventBus, elementRegistry, overlays, canvas) {
10
+
11
+ function createBreadcrumbs(subProcess) {
12
+ var breadcrumbs = domify('<ul class="bjs-breadcrumbs"></ul>');
13
+ var drillUp = domify('<button class="bjs-drilldown">' + ARROW_UP_SVG + '</button>');
14
+ drillUp.addEventListener('click', function() {
15
+ var plane = canvas.findPlane(getBusinessObject(subProcess).id);
16
+ canvas.setActivePlane(plane);
17
+ });
18
+
19
+ breadcrumbs.appendChild(drillUp);
20
+
21
+ var parents = getParentChain(subProcess);
22
+
23
+ var path = parents.map(function(el) {
24
+ var title = escapeHTML(el.name) || el.id;
25
+ var link = domify('<li><span class="bjs-crumb"><a title="' + title + '">' + title + '</a></span></li>');
26
+
27
+ link.addEventListener('click', function() {
28
+ if (canvas.getPlane(el.id)) {
29
+ canvas.setActivePlane(el.id);
30
+ } else {
31
+ var plane = canvas.findPlane(el.id);
32
+ canvas.setActivePlane(plane);
33
+ }
34
+ });
35
+
36
+ return link;
37
+ });
38
+
39
+ path.forEach(function(el) {
40
+ breadcrumbs.appendChild(el);
41
+ });
42
+
43
+ overlays.add(subProcess, {
44
+ position: {
45
+ top: -30,
46
+ left: -10
47
+ },
48
+ html: breadcrumbs
49
+ });
50
+ }
51
+
52
+ var createDrilldown = function(element) {
53
+ var html = domify('<button class="bjs-drilldown">' + ARROW_DOWN_SVG + '</button>');
54
+
55
+ html.addEventListener('click', function() {
56
+ canvas.setActivePlane(element.id);
57
+ });
58
+
59
+ overlays.add(element, {
60
+ position: {
61
+ bottom: -7,
62
+ right: -8
63
+ },
64
+ html: html
65
+ });
66
+ };
67
+
68
+ var addOverlays = function(elements) {
69
+ elements.forEach(function(element) {
70
+ if (is(element, 'bpmn:SubProcess')
71
+ && element.collapsed
72
+ && canvas.getPlane(element.id)) {
73
+ createDrilldown(element);
74
+ }
75
+
76
+ if (is(element, 'bpmn:SubProcess') && element.isSecondary) {
77
+ createBreadcrumbs(element);
78
+ }
79
+ });
80
+ };
81
+
82
+ eventBus.on('import.done', function() {
83
+ addOverlays(elementRegistry.filter(function(el) {
84
+ return is(el, 'bpmn:SubProcess');
85
+ }));
86
+ });
87
+ }
88
+
89
+ SubprocessOverlays.$inject = [ 'eventBus', 'elementRegistry', 'overlays', 'canvas' ];
90
+
91
+
92
+ var getParentChain = function(child) {
93
+ var bo = getBusinessObject(child);
94
+
95
+ var parents = [];
96
+
97
+ for (var element = bo; element; element = element.$parent) {
98
+ if (is(element, 'bpmn:SubProcess') || is(element, 'bpmn:Process')) {
99
+ parents.push(element);
100
+ }
101
+ }
102
+
103
+ return parents.reverse();
104
+ };
@@ -0,0 +1,18 @@
1
+ import OverlaysModule from 'diagram-js/lib/features/overlays';
2
+ import ChangeSupportModule from 'diagram-js/lib/features/change-support';
3
+
4
+ import SubprocessElements from './SubprocessElements';
5
+ import SubprocessCentering from './SubprocessCentering';
6
+ import SubprocessCompatibility from './SubprocessCompatibility';
7
+ import SubprocessOverlays from './SubprocessOverlays';
8
+ import SubprocessFlows from './SubprocessFlows';
9
+
10
+ export default {
11
+ __depends__: [ OverlaysModule, ChangeSupportModule ],
12
+ __init__: [ 'subprocessElements', 'subprocessOverlays', 'subprocessCompatibility', 'subprocessCentering', 'subprocessFlows' ],
13
+ subprocessElements: [ 'type', SubprocessElements ],
14
+ subprocessOverlays: [ 'type', SubprocessOverlays ],
15
+ subprocessCompatibility: [ 'type', SubprocessCompatibility ],
16
+ subprocessCentering: [ 'type', SubprocessCentering ],
17
+ subprocessFlows: ['type', SubprocessFlows]
18
+ };