Skip to content

Commit df75988

Browse files
marstammnikku
authored andcommitted
feat: decouple DI from businessObject
In the diagram `di` is now accessed via the diagram element, not the business object. This has the benefit that elements in multiple diagrams can easily be represented. Related to #1472 BREAKING CHANGE: * Instead of referencing the `di` from the business object, reference it from the diagram element representing it.
1 parent 03352e8 commit df75988

File tree

7 files changed

+47
-52
lines changed

7 files changed

+47
-52
lines changed

lib/BaseViewer.js

-13
Original file line numberDiff line numberDiff line change
@@ -528,19 +528,6 @@ BaseViewer.prototype.clear = function() {
528528
return;
529529
}
530530

531-
// remove businessObject#di binding
532-
//
533-
// this is necessary, as we establish the bindings
534-
// in the BpmnTreeWalker (and assume none are given
535-
// on reimport)
536-
this.get('elementRegistry').forEach(function(element) {
537-
var bo = element.businessObject;
538-
539-
if (bo && bo.di) {
540-
delete bo.di;
541-
}
542-
});
543-
544531
// remove drawn elements
545532
Diagram.prototype.clear.call(this);
546533
};

lib/draw/BpmnRenderUtil.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export function isCollection(element) {
4343
}
4444

4545
export function getDi(element) {
46-
return element.businessObject.di;
46+
return element.di;
4747
}
4848

4949
export function getSemantic(element) {

lib/import/BpmnImporter.js

+20-19
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,18 @@ import {
2626
} from './Util';
2727

2828

29-
function elementData(semantic, attrs) {
29+
function elementData(semantic, di, attrs) {
3030
return assign({
3131
id: semantic.id,
3232
type: semantic.$type,
33-
businessObject: semantic
33+
businessObject: semantic,
34+
di: di
3435
}, attrs);
3536
}
3637

37-
function getWaypoints(bo, source, target) {
38+
function getWaypoints(di, source, target) {
3839

39-
var waypoints = bo.di.waypoint;
40+
var waypoints = di.waypoint;
4041

4142
if (!waypoints || waypoints.length < 2) {
4243
return [ getMid(source), getMid(target) ];
@@ -92,12 +93,12 @@ BpmnImporter.$inject = [
9293
* Add bpmn element (semantic) to the canvas onto the
9394
* specified parent shape.
9495
*/
95-
BpmnImporter.prototype.add = function(semantic, parentElement) {
96-
97-
var di = semantic.di,
98-
element,
96+
BpmnImporter.prototype.add = function(context, parentElement) {
97+
var element,
9998
translate = this._translate,
100-
hidden;
99+
hidden,
100+
semantic = context.element,
101+
di = context.di;
101102

102103
var parentIndex;
103104

@@ -107,21 +108,21 @@ BpmnImporter.prototype.add = function(semantic, parentElement) {
107108
if (is(di, 'bpmndi:BPMNPlane')) {
108109

109110
// add a virtual element (not being drawn)
110-
element = this._elementFactory.createRoot(elementData(semantic));
111+
element = this._elementFactory.createRoot(elementData(semantic, di));
111112

112113
this._canvas.setRootElement(element);
113114
}
114115

115116
// SHAPE
116117
else if (is(di, 'bpmndi:BPMNShape')) {
117118

118-
var collapsed = !isExpanded(semantic),
119+
var collapsed = !isExpanded(semantic, di),
119120
isFrame = isFrameElement(semantic);
120121
hidden = parentElement && (parentElement.hidden || parentElement.collapsed);
121122

122-
var bounds = semantic.di.bounds;
123+
var bounds = di.bounds;
123124

124-
element = this._elementFactory.createShape(elementData(semantic, {
125+
element = this._elementFactory.createShape(elementData(semantic, di, {
125126
collapsed: collapsed,
126127
hidden: hidden,
127128
x: Math.round(bounds.x),
@@ -159,11 +160,11 @@ BpmnImporter.prototype.add = function(semantic, parentElement) {
159160

160161
hidden = parentElement && (parentElement.hidden || parentElement.collapsed);
161162

162-
element = this._elementFactory.createConnection(elementData(semantic, {
163+
element = this._elementFactory.createConnection(elementData(semantic, di, {
163164
hidden: hidden,
164165
source: source,
165166
target: target,
166-
waypoints: getWaypoints(semantic, source, target)
167+
waypoints: getWaypoints(di, source, target)
167168
}));
168169

169170
if (is(semantic, 'bpmn:DataAssociation')) {
@@ -190,7 +191,7 @@ BpmnImporter.prototype.add = function(semantic, parentElement) {
190191

191192
// (optional) LABEL
192193
if (isLabelExternal(semantic) && getLabel(element)) {
193-
this.addLabel(semantic, element);
194+
this.addLabel(semantic, di, element);
194195
}
195196

196197

@@ -239,12 +240,12 @@ BpmnImporter.prototype._attachBoundary = function(boundarySemantic, boundaryElem
239240
/**
240241
* add label for an element
241242
*/
242-
BpmnImporter.prototype.addLabel = function(semantic, element) {
243+
BpmnImporter.prototype.addLabel = function(semantic, di, element) {
243244
var bounds,
244245
text,
245246
label;
246247

247-
bounds = getExternalLabelBounds(semantic, element);
248+
bounds = getExternalLabelBounds(di, element);
248249

249250
text = getLabel(element);
250251

@@ -254,7 +255,7 @@ BpmnImporter.prototype.addLabel = function(semantic, element) {
254255
bounds = this._textRenderer.getExternalLabelBounds(bounds, text);
255256
}
256257

257-
label = this._elementFactory.createLabel(elementData(semantic, {
258+
label = this._elementFactory.createLabel(elementData(semantic, di, {
258259
id: semantic.id + '_label',
259260
labelTarget: element,
260261
type: 'label',

lib/import/BpmnTreeWalker.js

+8-13
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,10 @@ import {
44
forEach
55
} from 'min-dash';
66

7-
import Refs from 'object-refs';
8-
97
import {
108
elementToString
119
} from './Util';
1210

13-
var diRefs = new Refs(
14-
{ name: 'bpmnElement', enumerable: true },
15-
{ name: 'di', configurable: true }
16-
);
17-
1811
/**
1912
* Returns true if an element has the given meta-model type
2013
*
@@ -48,6 +41,8 @@ export default function BpmnTreeWalker(handler, translate) {
4841
// prerequisites are drawn
4942
var deferred = [];
5043

44+
var diMap = {};
45+
5146
// Helpers //////////////////////
5247

5348
function contextual(fn, ctx) {
@@ -76,17 +71,17 @@ export default function BpmnTreeWalker(handler, translate) {
7671
}
7772

7873
// call handler
79-
return handler.element(element, ctx);
74+
return handler.element({ element: element, di: diMap[element.id] }, ctx);
8075
}
8176

8277
function visitRoot(element, diagram) {
83-
return handler.root(element, diagram);
78+
return handler.root({ element: element, di: diMap[element.id] }, diagram);
8479
}
8580

8681
function visitIfDi(element, ctx) {
8782

8883
try {
89-
var gfx = element.di && visit(element, ctx);
84+
var gfx = diMap[element.id] && visit(element, ctx);
9085

9186
handled(element);
9287

@@ -109,16 +104,15 @@ export default function BpmnTreeWalker(handler, translate) {
109104
var bpmnElement = di.bpmnElement;
110105

111106
if (bpmnElement) {
112-
if (bpmnElement.di) {
107+
if (diMap[bpmnElement.id]) {
113108
logError(
114109
translate('multiple DI elements defined for {element}', {
115110
element: elementToString(bpmnElement)
116111
}),
117112
{ element: bpmnElement }
118113
);
119114
} else {
120-
diRefs.bind(bpmnElement, 'di');
121-
bpmnElement.di = di;
115+
diMap[bpmnElement.id] = di;
122116
}
123117
} else {
124118
logError(
@@ -175,6 +169,7 @@ export default function BpmnTreeWalker(handler, translate) {
175169
}
176170

177171
// load DI from selected diagram only
172+
diMap = {};
178173
handleDiagram(diagram);
179174

180175

lib/util/DiUtil.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
11
import {
22
is,
3-
getBusinessObject
3+
getBusinessObject,
4+
getDi
45
} from './ModelUtil';
56

67
import {
78
forEach
89
} from 'min-dash';
910

1011

11-
export function isExpanded(element) {
12+
export function isExpanded(element, di) {
13+
di = di || getDi(element);
1214

1315
if (is(element, 'bpmn:CallActivity')) {
1416
return false;
1517
}
1618

1719
if (is(element, 'bpmn:SubProcess')) {
18-
return getBusinessObject(element).di && !!getBusinessObject(element).di.isExpanded;
20+
return di && !!di.isExpanded;
1921
}
2022

2123
if (is(element, 'bpmn:Participant')) {

lib/util/LabelUtil.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -116,15 +116,14 @@ export function getExternalLabelMid(element) {
116116
* Returns the bounds of an elements label, parsed from the elements DI or
117117
* generated from its bounds.
118118
*
119-
* @param {BpmnElement} semantic
119+
* @param {BpmndDi} di
120120
* @param {djs.model.Base} element
121121
*/
122-
export function getExternalLabelBounds(semantic, element) {
122+
export function getExternalLabelBounds(di, element) {
123123

124124
var mid,
125125
size,
126126
bounds,
127-
di = semantic.di,
128127
label = di.label;
129128

130129
if (label && label.bounds) {

lib/util/ModelUtil.js

+11
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,15 @@ export function is(element, type) {
2222
*/
2323
export function getBusinessObject(element) {
2424
return (element && element.businessObject) || element;
25+
}
26+
27+
/**
28+
* Return the di object for a given element.
29+
*
30+
* @param {djs.model.Base} element
31+
*
32+
* @return {ModdleElement}
33+
*/
34+
export function getDi(element) {
35+
return element && element.di;
2536
}

0 commit comments

Comments
 (0)