123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- import inherits from 'inherits';
- import OrderingProvider from 'diagram-js/lib/features/ordering/OrderingProvider';
- import {
- isAny
- } from '../modeling/util/ModelingUtil';
- import {
- findIndex,
- find
- } from 'min-dash';
- /**
- * a simple ordering provider that makes sure:
- *
- * (0) labels and groups are rendered always on top
- * (1) elements are ordered by a {level} property
- */
- export default function BpmnOrderingProvider(eventBus, canvas, translate) {
- OrderingProvider.call(this, eventBus);
- var orders = [
- { type: 'bpmn:SubProcess', order: { level: 6 } },
- {
- type: 'bpmn:SequenceFlow',
- order: {
- level: 3,
- containers: [
- 'bpmn:Participant',
- 'bpmn:FlowElementsContainer'
- ]
- }
- },
- // handle DataAssociation(s) like message flows and render them always on top
- {
- type: 'bpmn:DataAssociation',
- order: {
- level: 9,
- containers: [
- 'bpmn:Collaboration',
- 'bpmn:Process'
- ]
- }
- },
- {
- type: 'bpmn:MessageFlow', order: {
- level: 9,
- containers: [ 'bpmn:Collaboration' ]
- }
- },
- {
- type: 'bpmn:Association',
- order: {
- level: 6,
- containers: [
- 'bpmn:Participant',
- 'bpmn:FlowElementsContainer',
- 'bpmn:Collaboration'
- ]
- }
- },
- { type: 'bpmn:BoundaryEvent', order: { level: 8 } },
- {
- type: 'bpmn:Group',
- order: {
- level: 10,
- containers: [
- 'bpmn:Collaboration',
- 'bpmn:Process'
- ]
- }
- },
- { type: 'bpmn:FlowElement', order: { level: 5 } },
- { type: 'bpmn:Participant', order: { level: -2 } },
- { type: 'bpmn:Lane', order: { level: -1 } }
- ];
- function computeOrder(element) {
- if (element.labelTarget) {
- return { level: 10 };
- }
- var entry = find(orders, function(o) {
- return isAny(element, [ o.type ]);
- });
- return entry && entry.order || { level: 1 };
- }
- function getOrder(element) {
- var order = element.order;
- if (!order) {
- element.order = order = computeOrder(element);
- }
- return order;
- }
- function findActualParent(element, newParent, containers) {
- var actualParent = newParent;
- while (actualParent) {
- if (isAny(actualParent, containers)) {
- break;
- }
- actualParent = actualParent.parent;
- }
- if (!actualParent) {
- throw new Error(translate('no parent for {element} in {parent}', {
- element: element.id,
- parent: newParent.id
- }));
- }
- return actualParent;
- }
- this.getOrdering = function(element, newParent) {
- // render labels always on top
- if (element.labelTarget) {
- return {
- parent: canvas.getRootElement(),
- index: -1
- };
- }
- var elementOrder = getOrder(element);
- if (elementOrder.containers) {
- newParent = findActualParent(element, newParent, elementOrder.containers);
- }
- var currentIndex = newParent.children.indexOf(element);
- var insertIndex = findIndex(newParent.children, function(child) {
- // do not compare with labels, they are created
- // in the wrong order (right after elements) during import and
- // mess up the positioning.
- if (!element.labelTarget && child.labelTarget) {
- return false;
- }
- return elementOrder.level < getOrder(child).level;
- });
- // if the element is already in the child list at
- // a smaller index, we need to adjust the insert index.
- // this takes into account that the element is being removed
- // before being re-inserted
- if (insertIndex !== -1) {
- if (currentIndex !== -1 && currentIndex < insertIndex) {
- insertIndex -= 1;
- }
- }
- return {
- index: insertIndex,
- parent: newParent
- };
- };
- }
- BpmnOrderingProvider.$inject = [ 'eventBus', 'canvas', 'translate' ];
- inherits(BpmnOrderingProvider, OrderingProvider);
|