diff --git a/lib/Viewer.js b/lib/Viewer.js
index cc996adfcd..27a81bde38 100644
--- a/lib/Viewer.js
+++ b/lib/Viewer.js
@@ -4,7 +4,7 @@ import CoreModule from './core';
import TranslateModule from 'diagram-js/lib/i18n/translate';
import SelectionModule from 'diagram-js/lib/features/selection';
import OverlaysModule from 'diagram-js/lib/features/overlays';
-import SubprocessNavigationModule from './features/subprocess-navigation';
+import DrilldownModdule from './features/drilldown';
import BaseViewer from './BaseViewer';
@@ -68,7 +68,7 @@ Viewer.prototype._modules = [
TranslateModule,
SelectionModule,
OverlaysModule,
- SubprocessNavigationModule
+ DrilldownModdule
];
// default moddle extensions the viewer is composed of
diff --git a/lib/features/subprocess-navigation/SubprocessCentering.js b/lib/features/drilldown/DrilldownCentering.js
similarity index 88%
rename from lib/features/subprocess-navigation/SubprocessCentering.js
rename to lib/features/drilldown/DrilldownCentering.js
index 13f4dd4643..41aada469a 100644
--- a/lib/features/subprocess-navigation/SubprocessCentering.js
+++ b/lib/features/drilldown/DrilldownCentering.js
@@ -1,11 +1,17 @@
var defaultPosition = { x: 100, y: 50 };
+/**
+ * Move collapsed subprocesses into view when drilling down. Zoom and scroll
+ * are saved in a session.
+ *
+ * @param {eventBus} eventBus
+ * @param {canvas} canvas
+ */
export default function SubprocessCentering(eventBus, canvas) {
var currentPlane = 'base';
var positionMap = {};
eventBus.on('plane.set', function(event) {
-
var currentViewbox = canvas.viewbox();
positionMap[currentPlane] = {
x: currentViewbox.x,
diff --git a/lib/features/subprocess-navigation/SubprocessOverlays.js b/lib/features/drilldown/DrilldownOverlays.js
similarity index 87%
rename from lib/features/subprocess-navigation/SubprocessOverlays.js
rename to lib/features/drilldown/DrilldownOverlays.js
index f3bde102dc..247526cbe6 100644
--- a/lib/features/subprocess-navigation/SubprocessOverlays.js
+++ b/lib/features/drilldown/DrilldownOverlays.js
@@ -6,7 +6,15 @@ import { getBusinessObject, is } from '../../util/ModelUtil';
var ARROW_DOWN_SVG = ' ';
var ARROW_UP_SVG = ' ';
-export default function SubprocessOverlays(eventBus, elementRegistry, overlays, canvas) {
+/**
+ * Adds Overlays that allow switching planes on collapsed subprocesses.
+ *
+ * @param {eventBus} eventBus
+ * @param {elementRegistry} elementRegistry
+ * @param {overlays} overlays
+ * @param {canvas} canvas
+ */
+export default function DrilldownOverlays(eventBus, elementRegistry, overlays, canvas) {
function createBreadcrumbs(subProcess) {
var breadcrumbs = domify('
');
@@ -21,7 +29,7 @@ export default function SubprocessOverlays(eventBus, elementRegistry, overlays,
var parents = getParentChain(subProcess);
var path = parents.map(function(el) {
- var title = escapeHTML(el.name) || el.id;
+ var title = escapeHTML(el.name || el.id);
var link = domify('' + title + ' ');
link.addEventListener('click', function() {
@@ -86,9 +94,10 @@ export default function SubprocessOverlays(eventBus, elementRegistry, overlays,
});
}
-SubprocessOverlays.$inject = [ 'eventBus', 'elementRegistry', 'overlays', 'canvas' ];
+DrilldownOverlays.$inject = [ 'eventBus', 'elementRegistry', 'overlays', 'canvas' ];
+// helpers
var getParentChain = function(child) {
var bo = getBusinessObject(child);
diff --git a/lib/features/subprocess-navigation/SubprocessCompatibility.js b/lib/features/drilldown/SubprocessCompatibility.js
similarity index 92%
rename from lib/features/subprocess-navigation/SubprocessCompatibility.js
rename to lib/features/drilldown/SubprocessCompatibility.js
index 1619f213d4..3bf0fe7a62 100644
--- a/lib/features/subprocess-navigation/SubprocessCompatibility.js
+++ b/lib/features/drilldown/SubprocessCompatibility.js
@@ -2,8 +2,8 @@
import { is } from '../../util/ModelUtil';
/**
- * Hooks into `import.render.start` and creates new planes for collapsed
- * subprocesses with elements on the parent diPlane.
+ * Hook into `import.render.start` and create new planes for diagrams with
+ * collapsed subprocesses and all dis on the same plane.
*
* @param {eventBus} eventBus
* @param {moddle} moddle
@@ -19,6 +19,7 @@ export default function SubprocessCompatibility(eventBus, moddle) {
});
}
+
SubprocessCompatibility.prototype.handleImport = function(definitions) {
if (!definitions.diagrams) {
return;
@@ -60,12 +61,12 @@ SubprocessCompatibility.prototype.fixPlaneDi = function(plane) {
if (is(parent, 'bpmn:SubProcess') && parent !== plane.bpmnElement) {
// don't change the array while we iterate over it
- elementsToMove.push({ element: diElement, parent: parent });
+ elementsToMove.push({ diElement: diElement, parent: parent });
}
});
elementsToMove.forEach(function(element) {
- var diElement = element.element;
+ var diElement = element.diElement;
var parent = element.parent;
// parent is expanded, get nearest collapsed parent
diff --git a/lib/features/drilldown/SubprocessFakeBoundaries.js b/lib/features/drilldown/SubprocessFakeBoundaries.js
new file mode 100644
index 0000000000..2e833dac24
--- /dev/null
+++ b/lib/features/drilldown/SubprocessFakeBoundaries.js
@@ -0,0 +1,73 @@
+import { getBusinessObject, is } from '../../util/ModelUtil';
+
+/**
+ * Add secondary shape for boundary events on expanded subprocess views.
+ * The position is determined relative to the primary element.
+ *
+ * @param {eventBus} eventBus
+ * @param {elementRegistry} elementRegistry
+ * @param {canvas} canvas
+ * @param {elementFactory} elementFactory
+ */
+export default function SubprocessFakeBoundaries(
+ eventBus, elementRegistry,
+ canvas, elementFactory) {
+
+ var attachBoundaries = function() {
+ var secondaryShapes = elementRegistry.filter(function(el) {
+ return is(el, 'bpmn:SubProcess') && el.isSecondary;
+ });
+
+ secondaryShapes.forEach(function(process) {
+ if (!process.primaryShape || !process.primaryShape.attachers) {
+ return;
+ }
+
+ process.primaryShape.attachers.forEach(function(boundary) {
+ var bo = getBusinessObject(boundary);
+
+ var primary = process.primaryShape;
+
+ var relativeXPos = (boundary.x + 15 - primary.x) / primary.width;
+ var relativeYPos = (boundary.y + 15 - primary.y) / primary.height;
+
+ var dx = process.x + (process.width * relativeXPos) - 15;
+ var dy = process.y + (process.height * relativeYPos) - 15;
+
+ var boundaryShape = elementFactory.createShape({
+ id: bo.id + '_secondary',
+ businessObject: bo,
+ type: 'bpmn:BoundaryEvent',
+ hidden: false,
+ x: dx,
+ y: dy,
+ width: 30,
+ height: 30,
+ isFrame: false,
+ isSecondary: true,
+ primaryShape: boundary,
+ di: boundary.di
+ });
+
+ canvas.addShape(boundaryShape, process.parent);
+
+ if (!process.attachers) {
+ process.attachers = [];
+ }
+
+ process.attachers.push(boundaryShape);
+ });
+
+ });
+ };
+
+ eventBus.on('import.done', attachBoundaries);
+}
+
+
+SubprocessFakeBoundaries.$inject = [
+ 'eventBus',
+ 'elementRegistry',
+ 'canvas',
+ 'elementFactory'
+];
diff --git a/lib/features/subprocess-navigation/SubprocessFlows.js b/lib/features/drilldown/SubprocessFakeFlows.js
similarity index 88%
rename from lib/features/subprocess-navigation/SubprocessFlows.js
rename to lib/features/drilldown/SubprocessFakeFlows.js
index 90b7863393..e2c62c1026 100644
--- a/lib/features/subprocess-navigation/SubprocessFlows.js
+++ b/lib/features/drilldown/SubprocessFakeFlows.js
@@ -1,7 +1,14 @@
var FLOW_LENGTH = 50;
var HIGH_RENDER_PRIORITY = 2000;
-export default function SubprocessFlows(eventBus, config) {
+/**
+ * Draw representations of flows on expanded shape of subprocesses. The position
+ * is determined relative to the primary element.
+ *
+ * @param {eventBus} eventBus
+ * @param {config.subprocessFlows} config
+ */
+export default function SubprocessFakeFlows(eventBus, config) {
var mutedStrokeColor = (config && config.mutedStrokeColor) || '#dddddd';
@@ -86,7 +93,7 @@ export default function SubprocessFlows(eventBus, config) {
}
-SubprocessFlows.$inject = [ 'eventBus', 'config.subprocessFlows' ];
+SubprocessFakeFlows.$inject = [ 'eventBus', 'config.subprocessFlows' ];
// helpers
diff --git a/lib/features/drilldown/index.js b/lib/features/drilldown/index.js
new file mode 100644
index 0000000000..3437d6bd50
--- /dev/null
+++ b/lib/features/drilldown/index.js
@@ -0,0 +1,18 @@
+import OverlaysModule from 'diagram-js/lib/features/overlays';
+import ChangeSupportModule from 'diagram-js/lib/features/change-support';
+
+import DrilldownOverlays from './DrilldownOverlays';
+import DrilldownCentering from './DrilldownCentering';
+import SubprocessCompatibility from './SubprocessCompatibility';
+import SubprocessFakeBoundaries from './SubprocessFakeBoundaries';
+import SubprocessFakeFlows from './SubprocessFakeFlows';
+
+export default {
+ __depends__: [ OverlaysModule, ChangeSupportModule ],
+ __init__: [ 'drilldownOverlays', 'drilldownCentering', 'subprocessCompatibility', 'subprocessFakeBoundaries', 'subprocessFakeFlows' ],
+ drilldownOverlays: [ 'type', DrilldownOverlays ],
+ drilldownCentering: [ 'type', DrilldownCentering ],
+ subprocessCompatibility: [ 'type', SubprocessCompatibility ],
+ subprocessFakeBoundaries: [ 'type', SubprocessFakeBoundaries ],
+ subprocessFakeFlows: [ 'type', SubprocessFakeFlows ]
+};
\ No newline at end of file
diff --git a/lib/features/subprocess-navigation/SubprocessElements.js b/lib/features/subprocess-navigation/SubprocessElements.js
deleted file mode 100644
index 14a1e4adce..0000000000
--- a/lib/features/subprocess-navigation/SubprocessElements.js
+++ /dev/null
@@ -1,55 +0,0 @@
-import { getBusinessObject, is } from '../../util/ModelUtil';
-
-export default function SubprocessElements(eventBus, elementRegistry, canvas, elementFactory) {
- var attachBoundaries = function() {
- var secondaryShapes = elementRegistry.filter(function(el) {
- return is(el, 'bpmn:SubProcess') && el.isSecondary;
- });
-
- secondaryShapes.forEach(function(process) {
-
- // Add Boundary events
- if (process.primaryShape && process.primaryShape.attachers) {
- process.primaryShape.attachers.forEach(function(boundary) {
- var bo = getBusinessObject(boundary);
-
- var primary = process.primaryShape;
-
- var relativeXPos = (boundary.x + 15 - primary.x) / primary.width;
- var relativeYPos = (boundary.y + 15 - primary.y) / primary.height;
-
- var dx = process.x + (process.width * relativeXPos) - 15;
- var dy = process.y + (process.height * relativeYPos) - 15;
-
- var boundaryShape = elementFactory.createShape({
- id: bo.id + '_secondary',
- businessObject: bo,
- type: 'bpmn:BoundaryEvent',
- hidden: false,
- x: dx,
- y: dy,
- width: 30,
- height: 30,
- isFrame: false,
- isSecondary: true,
- primaryShape: boundary,
- di: boundary.di
- });
-
- canvas.addShape(boundaryShape, process.parent);
-
- if (!process.attachers) {
- process.attachers = [];
- }
-
- process.attachers.push(boundaryShape);
- });
- }
- });
- };
-
- eventBus.on('import.done', attachBoundaries);
-}
-
-
-SubprocessElements.$inject = [ 'eventBus', 'elementRegistry', 'canvas', 'elementFactory' ];
diff --git a/lib/features/subprocess-navigation/index.js b/lib/features/subprocess-navigation/index.js
deleted file mode 100644
index 70f1f7d5f7..0000000000
--- a/lib/features/subprocess-navigation/index.js
+++ /dev/null
@@ -1,18 +0,0 @@
-import OverlaysModule from 'diagram-js/lib/features/overlays';
-import ChangeSupportModule from 'diagram-js/lib/features/change-support';
-
-import SubprocessElements from './SubprocessElements';
-import SubprocessCentering from './SubprocessCentering';
-import SubprocessCompatibility from './SubprocessCompatibility';
-import SubprocessOverlays from './SubprocessOverlays';
-import SubprocessFlows from './SubprocessFlows';
-
-export default {
- __depends__: [ OverlaysModule, ChangeSupportModule ],
- __init__: [ 'subprocessElements', 'subprocessOverlays', 'subprocessCompatibility', 'subprocessCentering', 'subprocessFlows' ],
- subprocessElements: [ 'type', SubprocessElements ],
- subprocessOverlays: [ 'type', SubprocessOverlays ],
- subprocessCompatibility: [ 'type', SubprocessCompatibility ],
- subprocessCentering: [ 'type', SubprocessCentering ],
- subprocessFlows: ['type', SubprocessFlows]
-};
\ No newline at end of file
diff --git a/lib/import/BpmnImporter.js b/lib/import/BpmnImporter.js
index fce4673487..ca87f4f570 100644
--- a/lib/import/BpmnImporter.js
+++ b/lib/import/BpmnImporter.js
@@ -130,15 +130,17 @@ BpmnImporter.prototype.add = function(semantic, di, parentElement) {
// ROOT ELEMENT
// handle the special case that we deal with a
- // invisible root element (process or collaboration)
+ // invisible root element (process, subprocess or collaboration)
if (is(di, 'bpmndi:BPMNPlane')) {
+ // create a new plane with implicit root for subprocesses. The only child
+ // is the expanded subprocess shape, which contains all further children
+ // TODO(marstamm): ideally, the importer would be plugable and we can move this into a behaviour
if (is(semantic, 'bpmn:SubProcess')) {
var plane = this._canvas.createPlane(semantic.id, element);
// Get size of expanded element
var bounds = getPlaneBounds(di);
-
var primary = this._elementRegistry.get(semantic.id);
element = this._elementFactory.createShape(elementData(semantic, di, {
collapsed: false,
diff --git a/test/spec/features/subprocess-navigation/SubprocessNavigationSpec.js b/test/spec/features/drilldown/DrilldownSpec.js
similarity index 98%
rename from test/spec/features/subprocess-navigation/SubprocessNavigationSpec.js
rename to test/spec/features/drilldown/DrilldownSpec.js
index 47613eafe2..36707cd027 100644
--- a/test/spec/features/subprocess-navigation/SubprocessNavigationSpec.js
+++ b/test/spec/features/drilldown/DrilldownSpec.js
@@ -3,14 +3,14 @@ import {
} from 'test/TestHelper';
import coreModule from 'lib/core';
-import subprocessNavigationModule from 'lib/features/subprocess-navigation';
+import DrilldownModule from 'lib/features/drilldown';
import { bootstrapViewer } from '../../../helper';
describe('features - subprocess-navigation', function() {
var testModules = [
coreModule,
- subprocessNavigationModule
+ DrilldownModule
];
var multiLayerXML = require('./nested-subprocesses.bpmn');
diff --git a/test/spec/features/subprocess-navigation/legacy-subprocesses.bpmn b/test/spec/features/drilldown/legacy-subprocesses.bpmn
similarity index 100%
rename from test/spec/features/subprocess-navigation/legacy-subprocesses.bpmn
rename to test/spec/features/drilldown/legacy-subprocesses.bpmn
diff --git a/test/spec/features/subprocess-navigation/nested-subprocesses.bpmn b/test/spec/features/drilldown/nested-subprocesses.bpmn
similarity index 100%
rename from test/spec/features/subprocess-navigation/nested-subprocesses.bpmn
rename to test/spec/features/drilldown/nested-subprocesses.bpmn