bpmn-js 9.0.0-subprocesses.1 → 9.0.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 (50) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/dist/assets/bpmn-js.css +69 -14
  3. package/dist/assets/diagram-js.css +81 -78
  4. package/dist/bpmn-modeler.development.js +2897 -1810
  5. package/dist/bpmn-modeler.production.min.js +8 -8
  6. package/dist/bpmn-navigated-viewer.development.js +1458 -1101
  7. package/dist/bpmn-navigated-viewer.production.min.js +6 -6
  8. package/dist/bpmn-viewer.development.js +1457 -1100
  9. package/dist/bpmn-viewer.production.min.js +6 -6
  10. package/lib/BaseViewer.js +1 -1
  11. package/lib/Viewer.js +2 -2
  12. package/lib/draw/BpmnRenderer.js +303 -373
  13. package/lib/features/auto-resize/BpmnAutoResizeProvider.js +6 -0
  14. package/lib/features/copy-paste/BpmnCopyPaste.js +1 -0
  15. package/lib/features/di-ordering/BpmnDiOrdering.js +15 -11
  16. package/lib/features/drilldown/DrilldownBreadcrumbs.js +122 -0
  17. package/lib/features/drilldown/DrilldownCentering.js +118 -0
  18. package/lib/features/drilldown/DrilldownOverlayBehavior.js +181 -0
  19. package/lib/features/drilldown/SubprocessCompatibility.js +201 -0
  20. package/lib/features/drilldown/index.js +17 -0
  21. package/lib/features/label-editing/LabelEditingProvider.js +1 -1
  22. package/lib/features/label-editing/cmd/UpdateLabelHandler.js +29 -2
  23. package/lib/features/modeling/BpmnFactory.js +5 -1
  24. package/lib/features/modeling/BpmnUpdater.js +43 -1
  25. package/lib/features/modeling/ElementFactory.js +4 -0
  26. package/lib/features/modeling/behavior/CreateParticipantBehavior.js +59 -84
  27. package/lib/features/modeling/behavior/DropOnFlowBehavior.js +2 -2
  28. package/lib/features/modeling/behavior/RemoveEmbeddedLabelBoundsBehavior.js +34 -0
  29. package/lib/features/modeling/behavior/SubProcessPlaneBehavior.js +557 -0
  30. package/lib/features/modeling/behavior/ToggleCollapseConnectionBehaviour.js +74 -0
  31. package/lib/features/modeling/behavior/UnclaimIdBehavior.js +3 -1
  32. package/lib/features/modeling/behavior/index.js +27 -18
  33. package/lib/features/modeling/cmd/SetColorHandler.js +23 -6
  34. package/lib/features/modeling/cmd/UpdateCanvasRootHandler.js +4 -2
  35. package/lib/features/modeling/util/ModelingUtil.js +2 -20
  36. package/lib/features/ordering/BpmnOrderingProvider.js +3 -3
  37. package/lib/features/palette/PaletteProvider.js +1 -1
  38. package/lib/features/popup-menu/ReplaceMenuProvider.js +1 -1
  39. package/lib/import/BpmnImporter.js +17 -60
  40. package/lib/import/Importer.js +130 -10
  41. package/lib/util/DrilldownUtil.js +66 -0
  42. package/lib/util/ModelUtil.js +19 -0
  43. package/package.json +2 -2
  44. package/test/helper/index.js +1 -6
  45. package/lib/features/subprocess-navigation/SubprocessCentering.js +0 -55
  46. package/lib/features/subprocess-navigation/SubprocessCompatibility.js +0 -135
  47. package/lib/features/subprocess-navigation/SubprocessElements.js +0 -55
  48. package/lib/features/subprocess-navigation/SubprocessFlows.js +0 -109
  49. package/lib/features/subprocess-navigation/SubprocessOverlays.js +0 -104
  50. package/lib/features/subprocess-navigation/index.js +0 -18
@@ -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
+ }
@@ -0,0 +1,118 @@
1
+ import { is } from '../../util/ModelUtil';
2
+
3
+ /**
4
+ * Move collapsed subprocesses into view when drilling down.
5
+ *
6
+ * Zoom and scroll are saved in a session.
7
+ *
8
+ * @param {eventBus} eventBus
9
+ * @param {canvas} canvas
10
+ */
11
+ export default function DrilldownCentering(eventBus, canvas) {
12
+
13
+ var currentRoot = null;
14
+ var positionMap = new Map();
15
+
16
+ eventBus.on('root.set', function(event) {
17
+ var newRoot = event.element;
18
+ var currentViewbox = canvas.viewbox();
19
+ var storedViewbox = positionMap.get(newRoot);
20
+
21
+ positionMap.set(currentRoot, {
22
+ x: currentViewbox.x,
23
+ y: currentViewbox.y,
24
+ zoom: currentViewbox.scale
25
+ });
26
+
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 };
35
+
36
+ var dx = (currentViewbox.x - storedViewbox.x) * currentViewbox.scale,
37
+ dy = (currentViewbox.y - storedViewbox.y) * currentViewbox.scale;
38
+
39
+ if (dx !== 0 || dy !== 0) {
40
+ canvas.scroll({
41
+ dx: dx,
42
+ dy: dy
43
+ });
44
+ }
45
+
46
+ if (storedViewbox.zoom !== currentViewbox.scale) {
47
+ canvas.zoom(storedViewbox.zoom, { x: 0, y: 0 });
48
+ }
49
+ });
50
+
51
+ eventBus.on('diagram.clear', function() {
52
+ positionMap.clear();
53
+ currentRoot = null;
54
+ });
55
+
56
+ }
57
+
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
+ ];
@@ -0,0 +1,201 @@
1
+
2
+ import { asBounds, asTRBL } from 'diagram-js/lib/layout/LayoutUtil';
3
+ import { is } from '../../util/ModelUtil';
4
+
5
+ var DEFAULT_POSITION = {
6
+ x: 180,
7
+ y: 160
8
+ };
9
+
10
+ /**
11
+ * Hook into `import.render.start` and create new planes for diagrams with
12
+ * collapsed subprocesses and all dis on the same plane.
13
+ *
14
+ * @param {eventBus} eventBus
15
+ * @param {moddle} moddle
16
+ */
17
+ export default function SubprocessCompatibility(eventBus, moddle) {
18
+ this._eventBus = eventBus;
19
+ this._moddle = moddle;
20
+
21
+ var self = this;
22
+
23
+ eventBus.on('import.render.start', 1500, function(e, context) {
24
+ self.handleImport(context.definitions);
25
+ });
26
+ }
27
+
28
+ SubprocessCompatibility.prototype.handleImport = function(definitions) {
29
+ if (!definitions.diagrams) {
30
+ return;
31
+ }
32
+
33
+ var self = this;
34
+ this._definitions = definitions;
35
+ this._processToDiagramMap = {};
36
+
37
+ definitions.diagrams.forEach(function(diagram) {
38
+ if (!diagram.plane || !diagram.plane.bpmnElement) {
39
+ return;
40
+ }
41
+
42
+ self._processToDiagramMap[diagram.plane.bpmnElement.id] = diagram;
43
+ });
44
+
45
+ var newDiagrams = [];
46
+ definitions.diagrams.forEach(function(diagram) {
47
+ var createdDiagrams = self.createNewDiagrams(diagram.plane);
48
+ Array.prototype.push.apply(newDiagrams, createdDiagrams);
49
+ });
50
+
51
+ newDiagrams.forEach(function(diagram) {
52
+ self.movePlaneElementsToOrigin(diagram.plane);
53
+ });
54
+ };
55
+
56
+
57
+ /**
58
+ * Moves all DI elements from collapsed subprocesses to a new plane.
59
+ *
60
+ * @param {Object} plane
61
+ * @return {Array} new diagrams created for the collapsed subprocesses
62
+ */
63
+ SubprocessCompatibility.prototype.createNewDiagrams = function(plane) {
64
+ var self = this;
65
+
66
+ var collapsedElements = [];
67
+ var elementsToMove = [];
68
+
69
+ plane.get('planeElement').forEach(function(diElement) {
70
+ var bo = diElement.bpmnElement;
71
+
72
+ if (!bo) {
73
+ return;
74
+ }
75
+
76
+ var parent = bo.$parent;
77
+
78
+ if (is(bo, 'bpmn:SubProcess') && !diElement.isExpanded) {
79
+ collapsedElements.push(bo);
80
+ }
81
+
82
+ if (is(parent, 'bpmn:SubProcess') && parent !== plane.bpmnElement) {
83
+
84
+ // don't change the array while we iterate over it
85
+ elementsToMove.push({ diElement: diElement, parent: parent });
86
+ }
87
+ });
88
+
89
+ var newDiagrams = [];
90
+
91
+ // create new planes for all collapsed subprocesses, even when they are empty
92
+ collapsedElements.forEach(function(element) {
93
+ if (!self._processToDiagramMap[element.id]) {
94
+ var diagram = self.createDiagram(element);
95
+ self._processToDiagramMap[element.id] = diagram;
96
+ newDiagrams.push(diagram);
97
+ }
98
+ });
99
+
100
+ elementsToMove.forEach(function(element) {
101
+ var diElement = element.diElement;
102
+ var parent = element.parent;
103
+
104
+ // parent is expanded, get nearest collapsed parent
105
+ while (parent && collapsedElements.indexOf(parent) === -1) {
106
+ parent = parent.$parent;
107
+ }
108
+
109
+ // false positive, all parents are expanded
110
+ if (!parent) {
111
+ return;
112
+ }
113
+
114
+ var diagram = self._processToDiagramMap[parent.id];
115
+ self.moveToDiPlane(diElement, diagram.plane);
116
+ });
117
+
118
+ return newDiagrams;
119
+ };
120
+
121
+ SubprocessCompatibility.prototype.movePlaneElementsToOrigin = function(plane) {
122
+ var elements = plane.get('planeElement');
123
+
124
+ // get bounding box of all elements
125
+ var planeBounds = getPlaneBounds(plane);
126
+
127
+ var offset = {
128
+ x: planeBounds.x - DEFAULT_POSITION.x,
129
+ y: planeBounds.y - DEFAULT_POSITION.y
130
+ };
131
+
132
+ elements.forEach(function(diElement) {
133
+ if (diElement.waypoint) {
134
+ diElement.waypoint.forEach(function(waypoint) {
135
+ waypoint.x = waypoint.x - offset.x;
136
+ waypoint.y = waypoint.y - offset.y;
137
+ });
138
+ } else if (diElement.bounds) {
139
+ diElement.bounds.x = diElement.bounds.x - offset.x;
140
+ diElement.bounds.y = diElement.bounds.y - offset.y;
141
+ }
142
+ });
143
+ };
144
+
145
+
146
+ SubprocessCompatibility.prototype.moveToDiPlane = function(diElement, newPlane) {
147
+ var containingDiagram = findRootDiagram(diElement);
148
+
149
+ // remove DI from old Plane and add it to the new one
150
+ var parentPlaneElement = containingDiagram.plane.get('planeElement');
151
+ parentPlaneElement.splice(parentPlaneElement.indexOf(diElement), 1);
152
+ newPlane.get('planeElement').push(diElement);
153
+ };
154
+
155
+
156
+ SubprocessCompatibility.prototype.createDiagram = function(bo) {
157
+ var plane = this._moddle.create('bpmndi:BPMNPlane', { bpmnElement: bo });
158
+ var diagram = this._moddle.create('bpmndi:BPMNDiagram', {
159
+ plane: plane
160
+ });
161
+ plane.$parent = diagram;
162
+ plane.bpmnElement = bo;
163
+ diagram.$parent = this._definitions;
164
+ this._definitions.diagrams.push(diagram);
165
+ return diagram;
166
+ };
167
+
168
+ SubprocessCompatibility.$inject = [ 'eventBus', 'moddle' ];
169
+
170
+
171
+ // helpers
172
+
173
+ function findRootDiagram(element) {
174
+ if (is(element, 'bpmndi:BPMNDiagram')) {
175
+ return element;
176
+ } else {
177
+ return findRootDiagram(element.$parent);
178
+ }
179
+ }
180
+
181
+ function getPlaneBounds(plane) {
182
+ var planeTrbl = {
183
+ top: Infinity,
184
+ right: -Infinity,
185
+ bottom: -Infinity,
186
+ left: Infinity
187
+ };
188
+
189
+ plane.planeElement.forEach(function(element) {
190
+ if (!element.bounds) {
191
+ return;
192
+ }
193
+
194
+ var trbl = asTRBL(element.bounds);
195
+
196
+ planeTrbl.top = Math.min(trbl.top, planeTrbl.top);
197
+ planeTrbl.left = Math.min(trbl.left, planeTrbl.left);
198
+ });
199
+
200
+ return asBounds(planeTrbl);
201
+ }
@@ -0,0 +1,17 @@
1
+ import OverlaysModule from 'diagram-js/lib/features/overlays';
2
+ import ChangeSupportModule from 'diagram-js/lib/features/change-support';
3
+ import RootElementsModule from 'diagram-js/lib/features/root-elements';
4
+
5
+ import DrilldownBreadcrumbs from './DrilldownBreadcrumbs';
6
+ import DrilldownCentering from './DrilldownCentering';
7
+ import SubprocessCompatibility from './SubprocessCompatibility';
8
+ import DrilldownOverlayBehavior from './DrilldownOverlayBehavior';
9
+
10
+ export default {
11
+ __depends__: [ OverlaysModule, ChangeSupportModule, RootElementsModule ],
12
+ __init__: [ 'drilldownBreadcrumbs', 'drilldownOverlayBehavior', 'drilldownCentering', 'subprocessCompatibility'],
13
+ drilldownBreadcrumbs: [ 'type', DrilldownBreadcrumbs ],
14
+ drilldownCentering: [ 'type', DrilldownCentering ],
15
+ drilldownOverlayBehavior: [ 'type', DrilldownOverlayBehavior ],
16
+ subprocessCompatibility: [ 'type', SubprocessCompatibility ]
17
+ };