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 https://github.com/bpmn-io/bpmn-js/issues/1472 BREAKING CHANGE: * Instead of referencing the `di` from the business object, reference it from the diagram element representing it.
This commit is contained in:
parent
d19c4b0027
commit
2b11d871cd
|
@ -528,19 +528,6 @@ BaseViewer.prototype.clear = function() {
|
|||
return;
|
||||
}
|
||||
|
||||
// remove businessObject#di binding
|
||||
//
|
||||
// this is necessary, as we establish the bindings
|
||||
// in the BpmnTreeWalker (and assume none are given
|
||||
// on reimport)
|
||||
this.get('elementRegistry').forEach(function(element) {
|
||||
var bo = element.businessObject;
|
||||
|
||||
if (bo && bo.di) {
|
||||
delete bo.di;
|
||||
}
|
||||
});
|
||||
|
||||
// remove drawn elements
|
||||
Diagram.prototype.clear.call(this);
|
||||
};
|
||||
|
|
|
@ -43,7 +43,7 @@ export function isCollection(element) {
|
|||
}
|
||||
|
||||
export function getDi(element) {
|
||||
return element.businessObject.di;
|
||||
return element.di;
|
||||
}
|
||||
|
||||
export function getSemantic(element) {
|
||||
|
|
|
@ -26,17 +26,18 @@ import {
|
|||
} from './Util';
|
||||
|
||||
|
||||
function elementData(semantic, attrs) {
|
||||
function elementData(semantic, di, attrs) {
|
||||
return assign({
|
||||
id: semantic.id,
|
||||
type: semantic.$type,
|
||||
businessObject: semantic
|
||||
businessObject: semantic,
|
||||
di: di
|
||||
}, attrs);
|
||||
}
|
||||
|
||||
function getWaypoints(bo, source, target) {
|
||||
function getWaypoints(di, source, target) {
|
||||
|
||||
var waypoints = bo.di.waypoint;
|
||||
var waypoints = di.waypoint;
|
||||
|
||||
if (!waypoints || waypoints.length < 2) {
|
||||
return [ getMid(source), getMid(target) ];
|
||||
|
@ -92,10 +93,8 @@ BpmnImporter.$inject = [
|
|||
* Add bpmn element (semantic) to the canvas onto the
|
||||
* specified parent shape.
|
||||
*/
|
||||
BpmnImporter.prototype.add = function(semantic, parentElement) {
|
||||
|
||||
var di = semantic.di,
|
||||
element,
|
||||
BpmnImporter.prototype.add = function(semantic, di, parentElement) {
|
||||
var element,
|
||||
translate = this._translate,
|
||||
hidden;
|
||||
|
||||
|
@ -107,7 +106,7 @@ BpmnImporter.prototype.add = function(semantic, parentElement) {
|
|||
if (is(di, 'bpmndi:BPMNPlane')) {
|
||||
|
||||
// add a virtual element (not being drawn)
|
||||
element = this._elementFactory.createRoot(elementData(semantic));
|
||||
element = this._elementFactory.createRoot(elementData(semantic, di));
|
||||
|
||||
this._canvas.setRootElement(element);
|
||||
}
|
||||
|
@ -115,13 +114,14 @@ BpmnImporter.prototype.add = function(semantic, parentElement) {
|
|||
// SHAPE
|
||||
else if (is(di, 'bpmndi:BPMNShape')) {
|
||||
|
||||
var collapsed = !isExpanded(semantic),
|
||||
var collapsed = !isExpanded(semantic, di),
|
||||
isFrame = isFrameElement(semantic);
|
||||
|
||||
hidden = parentElement && (parentElement.hidden || parentElement.collapsed);
|
||||
|
||||
var bounds = semantic.di.bounds;
|
||||
var bounds = di.bounds;
|
||||
|
||||
element = this._elementFactory.createShape(elementData(semantic, {
|
||||
element = this._elementFactory.createShape(elementData(semantic, di, {
|
||||
collapsed: collapsed,
|
||||
hidden: hidden,
|
||||
x: Math.round(bounds.x),
|
||||
|
@ -159,11 +159,11 @@ BpmnImporter.prototype.add = function(semantic, parentElement) {
|
|||
|
||||
hidden = parentElement && (parentElement.hidden || parentElement.collapsed);
|
||||
|
||||
element = this._elementFactory.createConnection(elementData(semantic, {
|
||||
element = this._elementFactory.createConnection(elementData(semantic, di, {
|
||||
hidden: hidden,
|
||||
source: source,
|
||||
target: target,
|
||||
waypoints: getWaypoints(semantic, source, target)
|
||||
waypoints: getWaypoints(di, source, target)
|
||||
}));
|
||||
|
||||
if (is(semantic, 'bpmn:DataAssociation')) {
|
||||
|
@ -190,7 +190,7 @@ BpmnImporter.prototype.add = function(semantic, parentElement) {
|
|||
|
||||
// (optional) LABEL
|
||||
if (isLabelExternal(semantic) && getLabel(element)) {
|
||||
this.addLabel(semantic, element);
|
||||
this.addLabel(semantic, di, element);
|
||||
}
|
||||
|
||||
|
||||
|
@ -239,12 +239,12 @@ BpmnImporter.prototype._attachBoundary = function(boundarySemantic, boundaryElem
|
|||
/**
|
||||
* add label for an element
|
||||
*/
|
||||
BpmnImporter.prototype.addLabel = function(semantic, element) {
|
||||
BpmnImporter.prototype.addLabel = function(semantic, di, element) {
|
||||
var bounds,
|
||||
text,
|
||||
label;
|
||||
|
||||
bounds = getExternalLabelBounds(semantic, element);
|
||||
bounds = getExternalLabelBounds(di, element);
|
||||
|
||||
text = getLabel(element);
|
||||
|
||||
|
@ -254,7 +254,7 @@ BpmnImporter.prototype.addLabel = function(semantic, element) {
|
|||
bounds = this._textRenderer.getExternalLabelBounds(bounds, text);
|
||||
}
|
||||
|
||||
label = this._elementFactory.createLabel(elementData(semantic, {
|
||||
label = this._elementFactory.createLabel(elementData(semantic, di, {
|
||||
id: semantic.id + '_label',
|
||||
labelTarget: element,
|
||||
type: 'label',
|
||||
|
|
|
@ -4,17 +4,10 @@ import {
|
|||
forEach
|
||||
} from 'min-dash';
|
||||
|
||||
import Refs from 'object-refs';
|
||||
|
||||
import {
|
||||
elementToString
|
||||
} from './Util';
|
||||
|
||||
var diRefs = new Refs(
|
||||
{ name: 'bpmnElement', enumerable: true },
|
||||
{ name: 'di', configurable: true }
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns true if an element has the given meta-model type
|
||||
*
|
||||
|
@ -48,6 +41,8 @@ export default function BpmnTreeWalker(handler, translate) {
|
|||
// prerequisites are drawn
|
||||
var deferred = [];
|
||||
|
||||
var diMap = {};
|
||||
|
||||
// Helpers //////////////////////
|
||||
|
||||
function contextual(fn, ctx) {
|
||||
|
@ -76,17 +71,17 @@ export default function BpmnTreeWalker(handler, translate) {
|
|||
}
|
||||
|
||||
// call handler
|
||||
return handler.element(element, ctx);
|
||||
return handler.element(element, diMap[element.id], ctx);
|
||||
}
|
||||
|
||||
function visitRoot(element, diagram) {
|
||||
return handler.root(element, diagram);
|
||||
return handler.root(element, diMap[element.id], diagram);
|
||||
}
|
||||
|
||||
function visitIfDi(element, ctx) {
|
||||
|
||||
try {
|
||||
var gfx = element.di && visit(element, ctx);
|
||||
var gfx = diMap[element.id] && visit(element, ctx);
|
||||
|
||||
handled(element);
|
||||
|
||||
|
@ -109,7 +104,7 @@ export default function BpmnTreeWalker(handler, translate) {
|
|||
var bpmnElement = di.bpmnElement;
|
||||
|
||||
if (bpmnElement) {
|
||||
if (bpmnElement.di) {
|
||||
if (diMap[bpmnElement.id]) {
|
||||
logError(
|
||||
translate('multiple DI elements defined for {element}', {
|
||||
element: elementToString(bpmnElement)
|
||||
|
@ -117,8 +112,7 @@ export default function BpmnTreeWalker(handler, translate) {
|
|||
{ element: bpmnElement }
|
||||
);
|
||||
} else {
|
||||
diRefs.bind(bpmnElement, 'di');
|
||||
bpmnElement.di = di;
|
||||
diMap[bpmnElement.id] = di;
|
||||
}
|
||||
} else {
|
||||
logError(
|
||||
|
@ -175,6 +169,7 @@ export default function BpmnTreeWalker(handler, translate) {
|
|||
}
|
||||
|
||||
// load DI from selected diagram only
|
||||
diMap = {};
|
||||
handleDiagram(diagram);
|
||||
|
||||
|
||||
|
|
|
@ -49,12 +49,12 @@ export function importBpmnDiagram(diagram, definitions, bpmnDiagram) {
|
|||
|
||||
var visitor = {
|
||||
|
||||
root: function(element) {
|
||||
return importer.add(element);
|
||||
root: function(element, di) {
|
||||
return importer.add(element, di);
|
||||
},
|
||||
|
||||
element: function(element, parentShape) {
|
||||
return importer.add(element, parentShape);
|
||||
element: function(element, di, parentShape) {
|
||||
return importer.add(element, di, parentShape);
|
||||
},
|
||||
|
||||
error: function(message, context) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import {
|
||||
is,
|
||||
getBusinessObject
|
||||
getBusinessObject,
|
||||
getDi
|
||||
} from './ModelUtil';
|
||||
|
||||
import {
|
||||
|
@ -8,14 +9,16 @@ import {
|
|||
} from 'min-dash';
|
||||
|
||||
|
||||
export function isExpanded(element) {
|
||||
export function isExpanded(element, di) {
|
||||
|
||||
if (is(element, 'bpmn:CallActivity')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is(element, 'bpmn:SubProcess')) {
|
||||
return getBusinessObject(element).di && !!getBusinessObject(element).di.isExpanded;
|
||||
di = di || getDi(element);
|
||||
|
||||
return di && !!di.isExpanded;
|
||||
}
|
||||
|
||||
if (is(element, 'bpmn:Participant')) {
|
||||
|
|
|
@ -116,15 +116,14 @@ export function getExternalLabelMid(element) {
|
|||
* Returns the bounds of an elements label, parsed from the elements DI or
|
||||
* generated from its bounds.
|
||||
*
|
||||
* @param {BpmnElement} semantic
|
||||
* @param {BpmndDi} di
|
||||
* @param {djs.model.Base} element
|
||||
*/
|
||||
export function getExternalLabelBounds(semantic, element) {
|
||||
export function getExternalLabelBounds(di, element) {
|
||||
|
||||
var mid,
|
||||
size,
|
||||
bounds,
|
||||
di = semantic.di,
|
||||
label = di.label;
|
||||
|
||||
if (label && label.bounds) {
|
||||
|
|
|
@ -22,4 +22,15 @@ export function is(element, type) {
|
|||
*/
|
||||
export function getBusinessObject(element) {
|
||||
return (element && element.businessObject) || element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the di object for a given element.
|
||||
*
|
||||
* @param {djs.model.Base} element
|
||||
*
|
||||
* @return {ModdleElement}
|
||||
*/
|
||||
export function getDi(element) {
|
||||
return element && element.di;
|
||||
}
|
Loading…
Reference in New Issue