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