feat(label-editing): improve text annotation editing
Related to camunda/camunda-modeler#564
This commit is contained in:
parent
114da17403
commit
e797d9c142
|
@ -1551,7 +1551,7 @@ function BpmnRenderer(eventBus, styles, pathMap, canvas, priority) {
|
|||
});
|
||||
|
||||
var text = getSemantic(element).text || '';
|
||||
renderLabel(parentGfx, text, { box: element, align: 'left-middle', padding: 5 });
|
||||
renderLabel(parentGfx, text, { box: element, align: 'left-top', padding: 5 });
|
||||
|
||||
return textElement;
|
||||
},
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
var svgAppend = require('tiny-svg/lib/append'),
|
||||
svgAttr = require('tiny-svg/lib/attr'),
|
||||
svgCreate = require('tiny-svg/lib/create'),
|
||||
svgRemove = require('tiny-svg/lib/remove');
|
||||
|
||||
var getBusinessObject = require('../../util/ModelUtil').getBusinessObject,
|
||||
is = require('../../util/ModelUtil').is;
|
||||
|
||||
var translate = require('diagram-js/lib/util/SvgTransformUtil').translate;
|
||||
|
||||
var MARKER_HIDDEN = 'djs-element-hidden',
|
||||
MARKER_LABEL_HIDDEN = 'djs-label-hidden';
|
||||
|
||||
function getStrokeColor(element, defaultColor) {
|
||||
var bo = getBusinessObject(element);
|
||||
|
||||
return bo.di.get('stroke') || defaultColor || 'black';
|
||||
}
|
||||
|
||||
function LabelEditingPreview(eventBus, canvas, elementRegistry, pathMap) {
|
||||
var self = this;
|
||||
|
||||
var defaultLayer = canvas.getDefaultLayer();
|
||||
|
||||
var element, absoluteElementBBox, gfx;
|
||||
|
||||
eventBus.on('directEditing.activate', function(context) {
|
||||
var activeProvider = context.active;
|
||||
|
||||
element = activeProvider.element.label || activeProvider.element;
|
||||
|
||||
// text annotation
|
||||
if (is(element, 'bpmn:TextAnnotation')) {
|
||||
absoluteElementBBox = canvas.getAbsoluteBBox(element);
|
||||
|
||||
gfx = svgCreate('g');
|
||||
|
||||
var textPathData = pathMap.getScaledPath('TEXT_ANNOTATION', {
|
||||
xScaleFactor: 1,
|
||||
yScaleFactor: 1,
|
||||
containerWidth: element.width,
|
||||
containerHeight: element.height,
|
||||
position: {
|
||||
mx: 0.0,
|
||||
my: 0.0
|
||||
}
|
||||
});
|
||||
|
||||
var path = self.path = svgCreate('path');
|
||||
|
||||
svgAttr(path, {
|
||||
d: textPathData,
|
||||
strokeWidth: 2,
|
||||
stroke: getStrokeColor(element)
|
||||
});
|
||||
|
||||
svgAppend(gfx, path);
|
||||
|
||||
svgAppend(defaultLayer, gfx);
|
||||
|
||||
translate(gfx, element.x, element.y);
|
||||
}
|
||||
|
||||
if (is(element, 'bpmn:TextAnnotation') ||
|
||||
element.labelTarget) {
|
||||
canvas.addMarker(element, MARKER_HIDDEN);
|
||||
} else if (is(element, 'bpmn:Task') ||
|
||||
is(element, 'bpmn:CallActivity') ||
|
||||
is(element, 'bpmn:SubProcess') ||
|
||||
is(element, 'bpmn:Participant')) {
|
||||
canvas.addMarker(element, MARKER_LABEL_HIDDEN);
|
||||
}
|
||||
});
|
||||
|
||||
eventBus.on('directEditing.resize', function(context) {
|
||||
|
||||
// text annotation
|
||||
if (is(element, 'bpmn:TextAnnotation')) {
|
||||
var height = context.height,
|
||||
dy = context.dy;
|
||||
|
||||
var newElementHeight = Math.max(element.height / absoluteElementBBox.height * (height + dy), 0);
|
||||
|
||||
var textPathData = pathMap.getScaledPath('TEXT_ANNOTATION', {
|
||||
xScaleFactor: 1,
|
||||
yScaleFactor: 1,
|
||||
containerWidth: element.width,
|
||||
containerHeight: newElementHeight,
|
||||
position: {
|
||||
mx: 0.0,
|
||||
my: 0.0
|
||||
}
|
||||
});
|
||||
|
||||
svgAttr(self.path, {
|
||||
d: textPathData
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
eventBus.on([ 'directEditing.complete', 'directEditing.cancel' ], function(context) {
|
||||
var activeProvider = context.active;
|
||||
|
||||
if (activeProvider) {
|
||||
canvas.removeMarker(activeProvider.element.label || activeProvider.element, MARKER_HIDDEN);
|
||||
canvas.removeMarker(element, MARKER_LABEL_HIDDEN);
|
||||
}
|
||||
|
||||
element = undefined;
|
||||
absoluteElementBBox = undefined;
|
||||
|
||||
if (gfx) {
|
||||
svgRemove(gfx);
|
||||
|
||||
gfx = undefined;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
LabelEditingPreview.$inject = [ 'eventBus', 'canvas', 'elementRegistry', 'pathMap' ];
|
||||
|
||||
module.exports = LabelEditingPreview;
|
|
@ -1,5 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
var assign = require('lodash/object/assign');
|
||||
|
||||
var UpdateLabelHandler = require('./cmd/UpdateLabelHandler');
|
||||
|
||||
var LabelUtil = require('./LabelUtil');
|
||||
|
@ -7,10 +9,12 @@ var LabelUtil = require('./LabelUtil');
|
|||
var is = require('../../util/ModelUtil').is,
|
||||
isExpanded = require('../../util/DiUtil').isExpanded;
|
||||
|
||||
var LINE_HEIGHT = 14,
|
||||
PADDING = 6;
|
||||
var SMALL_FONT_SIZE = 11,
|
||||
SMALL_LINE_HEIGHT = 13,
|
||||
MEDIUM_FONT_SIZE = 12,
|
||||
MEDIUM_LINE_HEIGHT = 14;
|
||||
|
||||
function LabelEditingProvider(eventBus, canvas, directEditing, commandStack) {
|
||||
function LabelEditingProvider(eventBus, canvas, directEditing, commandStack, resizeHandles) {
|
||||
|
||||
this._canvas = canvas;
|
||||
this._commandStack = commandStack;
|
||||
|
@ -22,19 +26,20 @@ function LabelEditingProvider(eventBus, canvas, directEditing, commandStack) {
|
|||
// listen to dblclick on non-root elements
|
||||
eventBus.on('element.dblclick', function(event) {
|
||||
directEditing.activate(event.element);
|
||||
|
||||
resizeHandles.removeResizers();
|
||||
});
|
||||
|
||||
// complete on followup canvas operation
|
||||
eventBus.on([ 'element.mousedown', 'drag.init', 'canvas.viewbox.changed' ], function(event) {
|
||||
eventBus.on([ 'element.mousedown', 'drag.init', 'canvas.viewbox.changing' ], function(event) {
|
||||
directEditing.complete();
|
||||
});
|
||||
|
||||
// cancel on command stack changes
|
||||
eventBus.on([ 'commandStack.changed' ], function() {
|
||||
eventBus.on([ 'commandStack.changed' ], function(e) {
|
||||
directEditing.cancel();
|
||||
});
|
||||
|
||||
|
||||
if ('ontouchstart' in document.documentElement) {
|
||||
// we deactivate automatic label editing on mobile devices
|
||||
// as it breaks the user interaction workflow
|
||||
|
@ -42,10 +47,9 @@ function LabelEditingProvider(eventBus, canvas, directEditing, commandStack) {
|
|||
// TODO(nre): we should temporarily focus the edited element here
|
||||
// and release the focused viewport after the direct edit operation is finished
|
||||
} else {
|
||||
eventBus.on('create.end', 500, function(e) {
|
||||
|
||||
var element = e.shape,
|
||||
canExecute = e.context.canExecute;
|
||||
eventBus.on('create.end', 500, function(event) {
|
||||
var element = event.shape,
|
||||
canExecute = event.context.canExecute;
|
||||
|
||||
if (!canExecute) {
|
||||
return;
|
||||
|
@ -53,14 +57,15 @@ function LabelEditingProvider(eventBus, canvas, directEditing, commandStack) {
|
|||
|
||||
if (is(element, 'bpmn:Task') || is(element, 'bpmn:TextAnnotation') ||
|
||||
(is(element, 'bpmn:SubProcess') && !isExpanded(element))) {
|
||||
|
||||
directEditing.activate(element);
|
||||
|
||||
resizeHandles.removeResizers();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
LabelEditingProvider.$inject = [ 'eventBus', 'canvas', 'directEditing', 'commandStack' ];
|
||||
LabelEditingProvider.$inject = [ 'eventBus', 'canvas', 'directEditing', 'commandStack', 'resizeHandles' ];
|
||||
|
||||
module.exports = LabelEditingProvider;
|
||||
|
||||
|
@ -70,21 +75,62 @@ module.exports = LabelEditingProvider;
|
|||
*
|
||||
* @param {djs.model.Base} element
|
||||
*
|
||||
* @return {Object} an object with properties bounds (position and size) and text
|
||||
* @return {Object} an object with properties bounds (position and size), text and options
|
||||
*/
|
||||
LabelEditingProvider.prototype.activate = function(element) {
|
||||
|
||||
// text
|
||||
var text = LabelUtil.getLabel(element);
|
||||
|
||||
if (text === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
var properties = this.getEditingBBox(element);
|
||||
var context = {
|
||||
text: text
|
||||
};
|
||||
|
||||
properties.text = text;
|
||||
// bounds
|
||||
var bounds = this.getEditingBBox(element);
|
||||
|
||||
return properties;
|
||||
assign(context, bounds);
|
||||
|
||||
// options
|
||||
var target = element.label || element;
|
||||
|
||||
var options = {};
|
||||
|
||||
// tasks
|
||||
if (is(element, 'bpmn:Task') ||
|
||||
is(element, 'bpmn:Participant') ||
|
||||
is(element, 'bpmn:Lane') ||
|
||||
(is(element, 'bpmn:CallActivity') && !isExpanded(element)) ||
|
||||
(is(element, 'bpmn:SubProcess') && !isExpanded(element))) {
|
||||
assign(options, {
|
||||
centerVertically: true
|
||||
});
|
||||
}
|
||||
|
||||
// external labels
|
||||
if (target.labelTarget) {
|
||||
assign(options, {
|
||||
autoResize: true
|
||||
});
|
||||
}
|
||||
|
||||
// text annotations
|
||||
if (is(element, 'bpmn:TextAnnotation')) {
|
||||
assign(options, {
|
||||
resizable: true,
|
||||
autoResize: true
|
||||
});
|
||||
}
|
||||
|
||||
assign(context, {
|
||||
options: options
|
||||
});
|
||||
|
||||
return context;
|
||||
};
|
||||
|
||||
|
||||
|
@ -110,17 +156,36 @@ LabelEditingProvider.prototype.getEditingBBox = function(element) {
|
|||
// default position
|
||||
var bounds = { x: bbox.x, y: bbox.y };
|
||||
|
||||
var style = {},
|
||||
zoom;
|
||||
var zoom = canvas.zoom();
|
||||
|
||||
// take zoom into account
|
||||
var smallFontSize = SMALL_FONT_SIZE * zoom,
|
||||
smallLineHeight = SMALL_LINE_HEIGHT * zoom,
|
||||
mediumFontSize = MEDIUM_FONT_SIZE * zoom,
|
||||
mediumLineHeight = MEDIUM_LINE_HEIGHT * zoom;
|
||||
|
||||
var style = {};
|
||||
|
||||
// adjust for expanded pools AND lanes
|
||||
if ((is(element, 'bpmn:Participant') && isExpanded(element)) || is(element, 'bpmn:Lane')) {
|
||||
if ((is(element, 'bpmn:Participant') && isExpanded(element))
|
||||
|| is(element, 'bpmn:Lane')) {
|
||||
|
||||
bounds.width = 150;
|
||||
bounds.minHeight = LINE_HEIGHT + PADDING;
|
||||
bounds.maxHeight = LINE_HEIGHT * 2 + PADDING;
|
||||
bounds.x = bbox.x - bounds.width / 2;
|
||||
bounds.y = mid.y - bounds.minHeight / 2;
|
||||
assign(bounds, {
|
||||
width: bbox.height,
|
||||
height: 30 * zoom,
|
||||
x: bbox.x - bbox.height / 2 + (15 * zoom),
|
||||
y: mid.y - (30 * zoom) / 2
|
||||
});
|
||||
|
||||
assign(style, {
|
||||
fontSize: mediumFontSize + 'px',
|
||||
lineHeight: mediumLineHeight + 'px',
|
||||
paddingTop: (7 * zoom) + 'px',
|
||||
paddingBottom: (7 * zoom) + 'px',
|
||||
paddingLeft: (5 * zoom) + 'px',
|
||||
paddingRight: (5 * zoom) + 'px',
|
||||
transform: 'rotate(-90deg)'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
@ -131,63 +196,97 @@ LabelEditingProvider.prototype.getEditingBBox = function(element) {
|
|||
(is(element, 'bpmn:SubProcess') && !isExpanded(element)) ||
|
||||
(is(element, 'bpmn:Participant') && !isExpanded(element))
|
||||
) {
|
||||
assign(bounds, {
|
||||
width: bbox.width,
|
||||
height: bbox.height
|
||||
});
|
||||
|
||||
zoom = canvas.zoom();
|
||||
|
||||
// fixed size for internal labels:
|
||||
// on high zoom levels: text box size === bbox size
|
||||
// on low zoom levels: text box size === bbox size at 100% zoom
|
||||
// This ensures minimum bounds at low zoom levels
|
||||
if (zoom > 1) {
|
||||
bounds.width = bbox.width;
|
||||
bounds.height = bbox.height;
|
||||
} else {
|
||||
bounds.width = bbox.width / zoom;
|
||||
bounds.height = bbox.height / zoom;
|
||||
}
|
||||
|
||||
// centering overlapping text box size at low zoom levels
|
||||
if (zoom < 1) {
|
||||
bounds.x = bbox.x - (bounds.width / 2 - bbox.width / 2);
|
||||
bounds.y = bbox.y - (bounds.height / 2 - bbox.height / 2);
|
||||
}
|
||||
|
||||
assign(style, {
|
||||
fontSize: mediumFontSize + 'px',
|
||||
lineHeight: mediumLineHeight + 'px',
|
||||
paddingTop: (7 * zoom) + 'px',
|
||||
paddingBottom: (7 * zoom) + 'px',
|
||||
paddingLeft: (5 * zoom) + 'px',
|
||||
paddingRight: (5 * zoom) + 'px'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// internal labels for expanded sub processes
|
||||
if (is(element, 'bpmn:SubProcess') && isExpanded(element)) {
|
||||
assign(bounds, {
|
||||
width: bbox.width,
|
||||
x: bbox.x
|
||||
});
|
||||
|
||||
bounds.width = element.width;
|
||||
bounds.maxHeight = 3 * LINE_HEIGHT + PADDING; // maximum 3 lines
|
||||
bounds.x = mid.x - element.width / 2;
|
||||
assign(style, {
|
||||
fontSize: mediumFontSize + 'px',
|
||||
lineHeight: mediumLineHeight + 'px',
|
||||
paddingTop: (7 * zoom) + 'px',
|
||||
paddingBottom: (7 * zoom) + 'px',
|
||||
paddingLeft: (5 * zoom) + 'px',
|
||||
paddingRight: (5 * zoom) + 'px'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// external labels for events, data elements, gateways and connections
|
||||
if (target.labelTarget) {
|
||||
var width = 90 * zoom,
|
||||
paddingTop = 7 * zoom,
|
||||
paddingBottom = 4 * zoom;
|
||||
|
||||
bounds.width = 150;
|
||||
bounds.minHeight = LINE_HEIGHT + PADDING; // 1 line
|
||||
bounds.x = mid.x - bounds.width / 2;
|
||||
assign(bounds, {
|
||||
width: width,
|
||||
height: bbox.height + paddingTop + paddingBottom,
|
||||
x: mid.x - width / 2,
|
||||
y: bbox.y - paddingTop
|
||||
});
|
||||
|
||||
assign(style, {
|
||||
fontSize: smallFontSize + 'px',
|
||||
lineHeight: smallLineHeight + 'px',
|
||||
paddingTop: paddingTop + 'px',
|
||||
paddingBottom: paddingBottom + 'px'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// text annotations
|
||||
if (is(element, 'bpmn:TextAnnotation')) {
|
||||
bounds.minWidth = 100;
|
||||
bounds.height = element.height;
|
||||
assign(bounds, {
|
||||
width: bbox.width,
|
||||
height: bbox.height,
|
||||
minWidth: 30 * zoom,
|
||||
minHeight: 10 * zoom
|
||||
});
|
||||
|
||||
style.textAlign = 'left';
|
||||
assign(style, {
|
||||
textAlign: 'left',
|
||||
paddingTop: (7 * zoom) + 'px',
|
||||
paddingBottom: (7 * zoom) + 'px',
|
||||
paddingLeft: (5 * zoom) + 'px',
|
||||
paddingRight: (5 * zoom) + 'px',
|
||||
fontSize: mediumFontSize + 'px',
|
||||
lineHeight: mediumLineHeight + 'px'
|
||||
});
|
||||
}
|
||||
|
||||
return { bounds: bounds, style: style };
|
||||
};
|
||||
|
||||
|
||||
LabelEditingProvider.prototype.update = function(element, newLabel) {
|
||||
LabelEditingProvider.prototype.update = function(element, newLabel, activeContextText, bounds) {
|
||||
var absoluteElementBBox = this._canvas.getAbsoluteBBox(element);
|
||||
|
||||
this._commandStack.execute('element.updateLabel', {
|
||||
element: element,
|
||||
newLabel: newLabel
|
||||
newLabel: newLabel,
|
||||
bounds: {
|
||||
x: element.x,
|
||||
y: element.y,
|
||||
width: element.width / absoluteElementBBox.width * bounds.width,
|
||||
height: element.height / absoluteElementBBox.height * bounds.height
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
@ -6,7 +6,8 @@ var TextUtil = require('diagram-js/lib/util/Text');
|
|||
|
||||
var hasExternalLabel = require('../../../util/LabelUtil').hasExternalLabel;
|
||||
|
||||
var getBusinessObject = require('../../../util/ModelUtil').getBusinessObject;
|
||||
var getBusinessObject = require('../../../util/ModelUtil').getBusinessObject,
|
||||
is = require('../../../util/ModelUtil').is;
|
||||
|
||||
var NULL_DIMENSIONS = {
|
||||
width: 0,
|
||||
|
@ -52,14 +53,17 @@ function UpdateLabelHandler(modeling) {
|
|||
|
||||
function postExecute(ctx) {
|
||||
var element = ctx.element,
|
||||
label = element.label || element;
|
||||
label = element.label || element,
|
||||
bounds = ctx.bounds;
|
||||
|
||||
// ignore internal labels
|
||||
if (!hasExternalLabel(element)) {
|
||||
// ignore internal labels for elements except text annotations
|
||||
if (!hasExternalLabel(element) && !is(element, 'bpmn:TextAnnotation')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var text = getBusinessObject(label).name;
|
||||
var bo = getBusinessObject(label);
|
||||
|
||||
var text = bo.name || bo.text;
|
||||
|
||||
if (!text) {
|
||||
return;
|
||||
|
@ -67,7 +71,7 @@ function UpdateLabelHandler(modeling) {
|
|||
|
||||
// get layouted text bounds and resize external
|
||||
// external label accordingly
|
||||
var newBounds = getLayoutedBounds(label, text, textUtil);
|
||||
var newBounds = is(element, 'bpmn:TextAnnotation') ? bounds : getLayoutedBounds(label, text, textUtil);
|
||||
|
||||
modeling.resizeShape(label, newBounds, NULL_DIMENSIONS);
|
||||
}
|
||||
|
|
|
@ -2,8 +2,13 @@ module.exports = {
|
|||
__depends__: [
|
||||
require('diagram-js/lib/command'),
|
||||
require('diagram-js/lib/features/change-support'),
|
||||
require('diagram-js/lib/features/resize'),
|
||||
require('diagram-js-direct-editing')
|
||||
],
|
||||
__init__: [ 'labelEditingProvider' ],
|
||||
labelEditingProvider: [ 'type', require('./LabelEditingProvider') ]
|
||||
};
|
||||
__init__: [
|
||||
'labelEditingProvider',
|
||||
'labelEditingPreview'
|
||||
],
|
||||
labelEditingProvider: [ 'type', require('./LabelEditingProvider') ],
|
||||
labelEditingPreview: [ 'type', require('./LabelEditingPreview') ]
|
||||
};
|
||||
|
|
|
@ -7,7 +7,7 @@ TestHelper.insertCSS('diagram-js.css', require('diagram-js/assets/diagram-js.css
|
|||
TestHelper.insertCSS('bpmn-embedded.css', require('../assets/bpmn-font/css/bpmn-embedded.css'));
|
||||
|
||||
TestHelper.insertCSS('diagram-js-testing.css',
|
||||
'.test-container .result { height: 500px; }' + '.test-container > div'
|
||||
'.test-container .result { height: 500px; }' + '.test-container { height: 1000px !important }'
|
||||
);
|
||||
|
||||
|
||||
|
|
|
@ -1,248 +1,178 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="_w9Yc0PLSEeOqh_cnoUOA7A" targetNamespace="http://activiti.org/bpmn" exporter="Camunda Modeler" exporterVersion="1.4.0-nightly" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
|
||||
<bpmn2:collaboration id="_Collaboration_2">
|
||||
<bpmn2:participant id="expanded-pool" name="A" processRef="Process_1" />
|
||||
<bpmn2:participant id="collapsed-pool" name="A" />
|
||||
<bpmn2:messageFlow id="message-flow" name="A" sourceRef="task-nested-embedded" targetRef="collapsed-pool" />
|
||||
<bpmn2:messageFlow id="message-flow-unlabeled" name="" sourceRef="collapsed-pool" targetRef="expanded-pool" />
|
||||
<bpmn2:textAnnotation id="text-annotation"> <bpmn2:text>A</bpmn2:text>
|
||||
</bpmn2:textAnnotation>
|
||||
</bpmn2:collaboration>
|
||||
<bpmn2:process id="Process_1" isExecutable="false">
|
||||
<bpmn2:ioSpecification id="InputOutputSpecification_1">
|
||||
<bpmn2:dataInput id="data-input" />
|
||||
<bpmn2:dataOutput id="data-output" />
|
||||
</bpmn2:ioSpecification>
|
||||
<bpmn2:laneSet id="LaneSet_1" name="Lane Set 1">
|
||||
<bpmn2:lane id="lane-1" name="A">
|
||||
<bpmn2:flowNodeRef>intermediate-throw-event</bpmn2:flowNodeRef>
|
||||
<bpmn2:flowNodeRef>empty-task</bpmn2:flowNodeRef>
|
||||
<bpmn2:childLaneSet xsi:type="bpmn2:tLaneSet" id="LaneSet_2">
|
||||
<bpmn2:lane id="nested-lane-1-1" name="A">
|
||||
<bpmn2:flowNodeRef>start-event</bpmn2:flowNodeRef>
|
||||
<bpmn2:flowNodeRef>exclusive-gateway</bpmn2:flowNodeRef>
|
||||
<bpmn2:flowNodeRef>intermediate-throw-event</bpmn2:flowNodeRef>
|
||||
<bpmn2:flowNodeRef>empty-task</bpmn2:flowNodeRef>
|
||||
</bpmn2:lane>
|
||||
<bpmn2:lane id="nested-lane-1-2" name="A">
|
||||
<bpmn2:flowNodeRef>call-activity</bpmn2:flowNodeRef>
|
||||
<bpmn2:flowNodeRef>user-task</bpmn2:flowNodeRef>
|
||||
</bpmn2:lane>
|
||||
</bpmn2:childLaneSet>
|
||||
</bpmn2:lane>
|
||||
<bpmn2:lane id="lane-2" name="A">
|
||||
<bpmn2:childLaneSet xsi:type="bpmn2:tLaneSet" id="LaneSet_3">
|
||||
<bpmn2:lane id="nested-lane-no-label" name="">
|
||||
<bpmn2:flowNodeRef>subprocess-expanded</bpmn2:flowNodeRef>
|
||||
<bpmn2:flowNodeRef>subprocess-collapsed</bpmn2:flowNodeRef>
|
||||
</bpmn2:lane>
|
||||
</bpmn2:childLaneSet>
|
||||
</bpmn2:lane>
|
||||
</bpmn2:laneSet>
|
||||
<bpmn2:subProcess id="subprocess-expanded" name="A">
|
||||
<bpmn2:dataInputAssociation id="DataInputAssociation_1">
|
||||
<bpmn2:sourceRef>data-input</bpmn2:sourceRef>
|
||||
</bpmn2:dataInputAssociation>
|
||||
<bpmn2:dataOutputAssociation id="DataOutputAssociation_1">
|
||||
<bpmn2:targetRef>data-output</bpmn2:targetRef>
|
||||
</bpmn2:dataOutputAssociation>
|
||||
<bpmn2:task id="task-nested-embedded" name="A" />
|
||||
</bpmn2:subProcess>
|
||||
<bpmn2:subProcess id="subprocess-collapsed" name="A" triggeredByEvent="true">
|
||||
<bpmn2:dataInputAssociation id="DataInputAssociation_2">
|
||||
<bpmn2:sourceRef>data-store-reference</bpmn2:sourceRef>
|
||||
</bpmn2:dataInputAssociation>
|
||||
<bpmn2:startEvent id="nested-embedded-start-event" name="start event" isInterrupting="false" />
|
||||
</bpmn2:subProcess>
|
||||
<bpmn2:callActivity id="call-activity" name="A">
|
||||
<bpmn2:incoming>sequence-flow-no</bpmn2:incoming>
|
||||
</bpmn2:callActivity>
|
||||
<bpmn2:userTask id="user-task" name="A" />
|
||||
<bpmn2:boundaryEvent id="boundary-event" name="A" attachedToRef="user-task" />
|
||||
<bpmn2:startEvent id="start-event">
|
||||
<bpmn2:outgoing>sequenceflow-unlabeled</bpmn2:outgoing>
|
||||
</bpmn2:startEvent>
|
||||
<bpmn2:sequenceFlow id="sequenceflow-unlabeled" name="" sourceRef="start-event" targetRef="exclusive-gateway" />
|
||||
<bpmn2:exclusiveGateway id="exclusive-gateway" name="A">
|
||||
<bpmn2:incoming>sequenceflow-unlabeled</bpmn2:incoming>
|
||||
<bpmn2:outgoing>sequence-flow-no</bpmn2:outgoing>
|
||||
<bpmn2:outgoing>sequence-flow-yes</bpmn2:outgoing>
|
||||
</bpmn2:exclusiveGateway>
|
||||
<bpmn2:sequenceFlow id="sequence-flow-no" name="A" sourceRef="exclusive-gateway" targetRef="call-activity" />
|
||||
<bpmn2:sequenceFlow id="sequence-flow-yes" name="A" sourceRef="exclusive-gateway" targetRef="intermediate-throw-event" />
|
||||
<bpmn2:dataStoreReference id="data-store-reference" name="A" dataStoreRef="DataStore_1" />
|
||||
<bpmn2:dataObject id="DataObject_1" name="Data Object 1" />
|
||||
<bpmn2:dataObjectReference id="data-object-reference" name="A" dataObjectRef="DataObject_1" />
|
||||
<bpmn2:intermediateThrowEvent id="intermediate-throw-event" name="A">
|
||||
<bpmn2:incoming>sequence-flow-yes</bpmn2:incoming>
|
||||
<bpmn2:outgoing>SequenceFlow_1r751z0</bpmn2:outgoing>
|
||||
</bpmn2:intermediateThrowEvent>
|
||||
<bpmn2:task id="empty-task">
|
||||
<bpmn2:incoming>SequenceFlow_1r751z0</bpmn2:incoming>
|
||||
</bpmn2:task>
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_1r751z0" sourceRef="intermediate-throw-event" targetRef="empty-task" />
|
||||
<bpmn2:association id="Association_1" sourceRef="text-annotation" targetRef="subprocess-expanded" />
|
||||
</bpmn2:process>
|
||||
<bpmn2:dataStore id="DataStore_1" name="Data Store 1" />
|
||||
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="1.6.0">
|
||||
<bpmn:collaboration id="Collaboration_1o0amh9">
|
||||
<bpmn:participant id="Participant_1" name="FOO BAR" processRef="Process_1" />
|
||||
<bpmn:participant id="Participant_2" />
|
||||
<bpmn:messageFlow id="MessageFlow_1" name="FOO" sourceRef="Task_1fo1fvh" targetRef="Participant_2" />
|
||||
<bpmn:textAnnotation id="TextAnnotation_1"> <bpmn:text>FOO</bpmn:text>
|
||||
</bpmn:textAnnotation>
|
||||
</bpmn:collaboration>
|
||||
<bpmn:process id="Process_1" isExecutable="false">
|
||||
<bpmn:laneSet>
|
||||
<bpmn:lane id="Lane_2">
|
||||
<bpmn:flowNodeRef>StartEvent_1</bpmn:flowNodeRef>
|
||||
<bpmn:flowNodeRef>SubProcess_1</bpmn:flowNodeRef>
|
||||
</bpmn:lane>
|
||||
<bpmn:lane id="Lane_1" name="FOO BAR">
|
||||
<bpmn:flowNodeRef>Task_1</bpmn:flowNodeRef>
|
||||
<bpmn:flowNodeRef>StartEvent_08jn2xd</bpmn:flowNodeRef>
|
||||
<bpmn:flowNodeRef>Task_1fo1fvh</bpmn:flowNodeRef>
|
||||
<bpmn:flowNodeRef>ExclusiveGateway_1</bpmn:flowNodeRef>
|
||||
<bpmn:flowNodeRef>EndEvent_1</bpmn:flowNodeRef>
|
||||
</bpmn:lane>
|
||||
</bpmn:laneSet>
|
||||
<bpmn:startEvent id="StartEvent_1" name="FOO">
|
||||
<bpmn:outgoing>SequenceFlow_2</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:sequenceFlow id="SequenceFlow_2" sourceRef="StartEvent_1" targetRef="SubProcess_1" />
|
||||
<bpmn:subProcess id="SubProcess_1" name="FOO">
|
||||
<bpmn:incoming>SequenceFlow_2</bpmn:incoming>
|
||||
<bpmn:outgoing>SequenceFlow_14kuv1e</bpmn:outgoing>
|
||||
</bpmn:subProcess>
|
||||
<bpmn:startEvent id="StartEvent_08jn2xd" name="FOO BAR">
|
||||
<bpmn:outgoing>SequenceFlow_1</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:task id="Task_1" name="FOO">
|
||||
<bpmn:incoming>SequenceFlow_1</bpmn:incoming>
|
||||
<bpmn:incoming>SequenceFlow_14kuv1e</bpmn:incoming>
|
||||
<bpmn:outgoing>SequenceFlow_13rjp44</bpmn:outgoing>
|
||||
<bpmn:outgoing>SequenceFlow_0kmqqm9</bpmn:outgoing>
|
||||
</bpmn:task>
|
||||
<bpmn:sequenceFlow id="SequenceFlow_1" name="FOO" sourceRef="StartEvent_08jn2xd" targetRef="Task_1" />
|
||||
<bpmn:sequenceFlow id="SequenceFlow_14kuv1e" sourceRef="SubProcess_1" targetRef="Task_1" />
|
||||
<bpmn:task id="Task_1fo1fvh" name="FOO BAR">
|
||||
<bpmn:incoming>SequenceFlow_13rjp44</bpmn:incoming>
|
||||
<bpmn:outgoing>SequenceFlow_1h7vuvi</bpmn:outgoing>
|
||||
</bpmn:task>
|
||||
<bpmn:sequenceFlow id="SequenceFlow_13rjp44" sourceRef="Task_1" targetRef="Task_1fo1fvh" />
|
||||
<bpmn:exclusiveGateway id="ExclusiveGateway_1" name="FOO">
|
||||
<bpmn:incoming>SequenceFlow_1h7vuvi</bpmn:incoming>
|
||||
</bpmn:exclusiveGateway>
|
||||
<bpmn:sequenceFlow id="SequenceFlow_1h7vuvi" sourceRef="Task_1fo1fvh" targetRef="ExclusiveGateway_1" />
|
||||
<bpmn:endEvent id="EndEvent_1">
|
||||
<bpmn:incoming>SequenceFlow_0kmqqm9</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
<bpmn:sequenceFlow id="SequenceFlow_0kmqqm9" sourceRef="Task_1" targetRef="EndEvent_1" />
|
||||
<bpmn:dataObjectReference id="DataObjectReference_1" dataObjectRef="DataObject_1rq8hb8" />
|
||||
<bpmn:dataObject id="DataObject_1rq8hb8" />
|
||||
<bpmn:dataStoreReference id="DataStoreReference_1" />
|
||||
<bpmn:association id="Association_0ckvfj2" sourceRef="SubProcess_1" targetRef="TextAnnotation_1" />
|
||||
</bpmn:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="_Collaboration_2">
|
||||
<bpmndi:BPMNShape id="_BPMNShape_Participant_2" bpmnElement="expanded-pool" isHorizontal="true">
|
||||
<dc:Bounds x="60" y="48" width="540" height="613" />
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration_1o0amh9">
|
||||
<bpmndi:BPMNShape id="Participant_15tkgjw_di" bpmnElement="Participant_1">
|
||||
<dc:Bounds x="160" y="122" width="600" height="477" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_Lane_2" bpmnElement="lane-1" isHorizontal="true">
|
||||
<dc:Bounds x="90" y="48" width="510" height="277" />
|
||||
<bpmndi:BPMNShape id="Lane_00fz5ca_di" bpmnElement="Lane_2">
|
||||
<dc:Bounds x="190" y="122" width="570" height="250" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_Lane_3" bpmnElement="nested-lane-1-1" isHorizontal="true">
|
||||
<dc:Bounds x="120" y="48" width="480" height="133" />
|
||||
<bpmndi:BPMNShape id="Lane_1qi2aws_di" bpmnElement="Lane_1">
|
||||
<dc:Bounds x="190" y="372" width="570" height="227" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_Lane_4" bpmnElement="nested-lane-1-2" isHorizontal="true">
|
||||
<dc:Bounds x="120" y="180" width="480" height="145" />
|
||||
<bpmndi:BPMNShape id="SubProcess_194zznr_di" bpmnElement="SubProcess_1" isExpanded="true">
|
||||
<dc:Bounds x="311" y="147" width="350" height="200" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_Lane_5" bpmnElement="lane-2" isHorizontal="true">
|
||||
<dc:Bounds x="90" y="324" width="510" height="337" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_Lane_6" bpmnElement="nested-lane-no-label" isHorizontal="true">
|
||||
<dc:Bounds x="120" y="324" width="480" height="337" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_SubProcess_2" bpmnElement="subprocess-expanded" isExpanded="true">
|
||||
<dc:Bounds x="359" y="364" width="200" height="150" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_SubProcess_3" bpmnElement="subprocess-collapsed">
|
||||
<dc:Bounds x="156" y="364" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="nested-embedded-start-event">
|
||||
<dc:Bounds x="188" y="386" width="36" height="36" />
|
||||
<bpmndi:BPMNShape id="StartEvent_0909sti_di" bpmnElement="StartEvent_1">
|
||||
<dc:Bounds x="223" y="229" width="36" height="36" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="173" y="427" width="66" height="22" />
|
||||
<dc:Bounds x="228" y="265" width="25" height="12" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_Task_2" bpmnElement="task-nested-embedded">
|
||||
<dc:Bounds x="432" y="408" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_Participant_3" bpmnElement="collapsed-pool" isHorizontal="true">
|
||||
<dc:Bounds x="672" y="336" width="385" height="100" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_TextAnnotation_2" bpmnElement="text-annotation">
|
||||
<dc:Bounds x="60" y="669" width="147" height="98" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="BPMNEdge_Association_1" bpmnElement="Association_1" sourceElement="_BPMNShape_TextAnnotation_2" targetElement="_BPMNShape_SubProcess_2">
|
||||
<di:waypoint xsi:type="dc:Point" x="190" y="669" />
|
||||
<di:waypoint xsi:type="dc:Point" x="371" y="514" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_CallActivity_2" bpmnElement="call-activity">
|
||||
<dc:Bounds x="422" y="202" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_3" bpmnElement="start-event">
|
||||
<dc:Bounds x="168" y="96" width="36" height="36" />
|
||||
<bpmndi:BPMNEdge id="SequenceFlow_140ewlr_di" bpmnElement="SequenceFlow_2">
|
||||
<di:waypoint xsi:type="dc:Point" x="259" y="247" />
|
||||
<di:waypoint xsi:type="dc:Point" x="311" y="247" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="153" y="137" width="66" height="22" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_IntermediateThrowEvent_2" bpmnElement="intermediate-throw-event">
|
||||
<dc:Bounds x="397" y="96" width="36" height="36" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="371" y="137" width="90" height="38" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_UserTask_2" bpmnElement="user-task">
|
||||
<dc:Bounds x="180" y="192" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_BoundaryEvent_2" bpmnElement="boundary-event">
|
||||
<dc:Bounds x="228" y="254" width="36" height="36" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="200" y="295" width="93" height="22" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_ExclusiveGateway_2" bpmnElement="exclusive-gateway" isMarkerVisible="true">
|
||||
<dc:Bounds x="312" y="89" width="50" height="50" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="306" y="48" width="64" height="38" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_1" bpmnElement="sequenceflow-unlabeled" sourceElement="_BPMNShape_StartEvent_3" targetElement="_BPMNShape_ExclusiveGateway_2">
|
||||
<di:waypoint xsi:type="dc:Point" x="204" y="114" />
|
||||
<di:waypoint xsi:type="dc:Point" x="312" y="114" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="243" y="114" width="6" height="6" />
|
||||
<dc:Bounds x="285" y="232" width="0" height="0" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_2" bpmnElement="sequence-flow-no" sourceElement="_BPMNShape_ExclusiveGateway_2" targetElement="_BPMNShape_CallActivity_2">
|
||||
<di:waypoint xsi:type="dc:Point" x="337" y="139" />
|
||||
<di:waypoint xsi:type="dc:Point" x="337" y="242" />
|
||||
<di:waypoint xsi:type="dc:Point" x="422" y="242" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="342" y="204" width="20" height="22" />
|
||||
</bpmndi:BPMNLabel>
|
||||
<bpmndi:BPMNShape id="TextAnnotation_0vwfagl_di" bpmnElement="TextAnnotation_1">
|
||||
<dc:Bounds x="814" y="122" width="100" height="30" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="Association_0ckvfj2_di" bpmnElement="Association_0ckvfj2">
|
||||
<di:waypoint xsi:type="dc:Point" x="661" y="196" />
|
||||
<di:waypoint xsi:type="dc:Point" x="814" y="152" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_3" bpmnElement="sequence-flow-yes" sourceElement="_BPMNShape_ExclusiveGateway_2" targetElement="_BPMNShape_IntermediateThrowEvent_2">
|
||||
<di:waypoint xsi:type="dc:Point" x="362" y="114" />
|
||||
<di:waypoint xsi:type="dc:Point" x="397" y="114" />
|
||||
<bpmndi:BPMNShape id="StartEvent_08jn2xd_di" bpmnElement="StartEvent_08jn2xd">
|
||||
<dc:Bounds x="223" y="416" width="36" height="36" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="335.49989765458423" y="114" width="90" height="22" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="BPMNEdge_MessageFlow_1" bpmnElement="message-flow" sourceElement="_BPMNShape_Task_2" targetElement="_BPMNShape_Participant_3">
|
||||
<di:waypoint xsi:type="dc:Point" x="532" y="448" />
|
||||
<di:waypoint xsi:type="dc:Point" x="632" y="448" />
|
||||
<di:waypoint xsi:type="dc:Point" x="632" y="386" />
|
||||
<di:waypoint xsi:type="dc:Point" x="672" y="386" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="612" y="456" width="91" height="38" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_DataStoreReference_2" bpmnElement="data-store-reference">
|
||||
<dc:Bounds x="156" y="547" width="50" height="50" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="149" y="602" width="64" height="22" />
|
||||
<dc:Bounds x="228" y="452" width="25" height="24" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_DataObjectReference_2" bpmnElement="data-object-reference">
|
||||
<dc:Bounds x="267" y="547" width="36" height="50" />
|
||||
<bpmndi:BPMNShape id="Task_1i068gk_di" bpmnElement="Task_1">
|
||||
<dc:Bounds x="436" y="394" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="SequenceFlow_088kva8_di" bpmnElement="SequenceFlow_1">
|
||||
<di:waypoint xsi:type="dc:Point" x="259" y="434" />
|
||||
<di:waypoint xsi:type="dc:Point" x="436" y="434" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="245" y="602" width="80" height="38" />
|
||||
<dc:Bounds x="335" y="409" width="25" height="12" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="SequenceFlow_14kuv1e_di" bpmnElement="SequenceFlow_14kuv1e">
|
||||
<di:waypoint xsi:type="dc:Point" x="486" y="347" />
|
||||
<di:waypoint xsi:type="dc:Point" x="486" y="394" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="501" y="360.5" width="0" height="0" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="Task_1fo1fvh_di" bpmnElement="Task_1fo1fvh">
|
||||
<dc:Bounds x="436" y="500" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="SequenceFlow_13rjp44_di" bpmnElement="SequenceFlow_13rjp44">
|
||||
<di:waypoint xsi:type="dc:Point" x="486" y="474" />
|
||||
<di:waypoint xsi:type="dc:Point" x="486" y="500" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="501" y="477" width="0" height="0" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="ExclusiveGateway_1dulwbf_di" bpmnElement="ExclusiveGateway_1" isMarkerVisible="true">
|
||||
<dc:Bounds x="578" y="515" width="50" height="50" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="590" y="565" width="25" height="12" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_DataInput_2" bpmnElement="data-input">
|
||||
<dc:Bounds x="372" y="547" width="36" height="50" />
|
||||
<bpmndi:BPMNEdge id="SequenceFlow_1h7vuvi_di" bpmnElement="SequenceFlow_1h7vuvi">
|
||||
<di:waypoint xsi:type="dc:Point" x="536" y="540" />
|
||||
<di:waypoint xsi:type="dc:Point" x="578" y="540" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="390" y="602" width="0" height="0" />
|
||||
<dc:Bounds x="557" y="515" width="0" height="0" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="EndEvent_0c4s9zs_di" bpmnElement="EndEvent_1">
|
||||
<dc:Bounds x="585" y="416" width="36" height="36" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="603" y="452" width="0" height="0" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_DataOutput_2" bpmnElement="data-output">
|
||||
<dc:Bounds x="504" y="547" width="36" height="50" />
|
||||
<bpmndi:BPMNEdge id="SequenceFlow_0kmqqm9_di" bpmnElement="SequenceFlow_0kmqqm9">
|
||||
<di:waypoint xsi:type="dc:Point" x="536" y="434" />
|
||||
<di:waypoint xsi:type="dc:Point" x="585" y="434" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="522" y="602" width="0" height="0" />
|
||||
<dc:Bounds x="561" y="409" width="0" height="0" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="DataObjectReference_024w45b_di" bpmnElement="DataObjectReference_1">
|
||||
<dc:Bounds x="223" y="515" width="36" height="50" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="241" y="565" width="0" height="0" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="BPMNEdge_DataInputAssociation_1" bpmnElement="DataInputAssociation_1" sourceElement="_BPMNShape_DataInput_2" targetElement="_BPMNShape_SubProcess_2">
|
||||
<di:waypoint xsi:type="dc:Point" x="403" y="547" />
|
||||
<di:waypoint xsi:type="dc:Point" x="420" y="514" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="BPMNEdge_DataOutputAssociation_1" bpmnElement="DataOutputAssociation_1" sourceElement="_BPMNShape_SubProcess_2" targetElement="_BPMNShape_DataOutput_2">
|
||||
<di:waypoint xsi:type="dc:Point" x="495" y="514" />
|
||||
<di:waypoint xsi:type="dc:Point" x="510" y="547" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="BPMNEdge_DataInputAssociation_2" bpmnElement="DataInputAssociation_2" sourceElement="_BPMNShape_DataStoreReference_2" targetElement="_BPMNShape_SubProcess_3">
|
||||
<di:waypoint xsi:type="dc:Point" x="185" y="547" />
|
||||
<di:waypoint xsi:type="dc:Point" x="200" y="444" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="BPMNEdge_MessageFlow_2" bpmnElement="message-flow-unlabeled" sourceElement="_BPMNShape_Participant_3" targetElement="_BPMNShape_Participant_2">
|
||||
<di:waypoint xsi:type="dc:Point" x="672" y="386" />
|
||||
<di:waypoint xsi:type="dc:Point" x="600" y="386" />
|
||||
<bpmndi:BPMNShape id="DataStoreReference_0b4jv9b_di" bpmnElement="DataStoreReference_1">
|
||||
<dc:Bounds x="315.54926829268294" y="515" width="50" height="50" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="591" y="368" width="90" height="6" />
|
||||
<dc:Bounds x="341" y="565" width="0" height="0" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="Task_0da8ze1_di" bpmnElement="empty-task">
|
||||
<dc:Bounds x="472" y="74" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="SequenceFlow_1r751z0_di" bpmnElement="SequenceFlow_1r751z0">
|
||||
<di:waypoint xsi:type="dc:Point" x="433" y="114" />
|
||||
<di:waypoint xsi:type="dc:Point" x="472" y="114" />
|
||||
<bpmndi:BPMNEdge id="MessageFlow_0pmpiw7_di" bpmnElement="MessageFlow_1">
|
||||
<di:waypoint xsi:type="dc:Point" x="486" y="580" />
|
||||
<di:waypoint xsi:type="dc:Point" x="486" y="646" />
|
||||
<bpmndi:BPMNLabel>
|
||||
<dc:Bounds x="407.5" y="89" width="90" height="20" />
|
||||
<dc:Bounds x="488" y="603" width="25" height="13" />
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="Participant_0kzj58d_di" bpmnElement="Participant_2">
|
||||
<dc:Bounds x="161" y="646" width="600" height="250" />
|
||||
</bpmndi:BPMNShape>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn2:definitions>
|
||||
</bpmn:definitions>
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
'use strict';
|
||||
|
||||
/* global bootstrapViewer, inject */
|
||||
|
||||
|
||||
var labelEditingModule = require('../../../../lib/features/label-editing'),
|
||||
coreModule = require('../../../../lib/core'),
|
||||
draggingModule = require('diagram-js/lib/features/dragging'),
|
||||
modelingModule = require('diagram-js/lib/features/modeling');
|
||||
|
||||
describe('features - label-editing preview', function() {
|
||||
|
||||
var diagramXML = require('../../../fixtures/bpmn/features/label-editing/labels.bpmn');
|
||||
|
||||
var testModules = [ labelEditingModule, coreModule, draggingModule, modelingModule ];
|
||||
|
||||
beforeEach(bootstrapViewer(diagramXML, { modules: testModules }));
|
||||
|
||||
describe('activate', function() {
|
||||
|
||||
it('[external labels AND text annotations ] should add marker to hide element on activate', inject(function(directEditing, elementRegistry) {
|
||||
|
||||
// given
|
||||
var textAnnotation = elementRegistry.get('TextAnnotation_1');
|
||||
|
||||
// when
|
||||
directEditing.activate(textAnnotation);
|
||||
|
||||
// then
|
||||
var gfx = elementRegistry.getGraphics(textAnnotation);
|
||||
|
||||
expect(gfx.classList.contains('djs-element-hidden')).to.be.true;
|
||||
}));
|
||||
|
||||
|
||||
it('[internal labels] should add marker to hide label on activate', inject(function(directEditing, elementRegistry) {
|
||||
|
||||
// given
|
||||
var task = elementRegistry.get('Task_1');
|
||||
|
||||
// when
|
||||
directEditing.activate(task);
|
||||
|
||||
// then
|
||||
var gfx = elementRegistry.getGraphics(task);
|
||||
|
||||
expect(gfx.classList.contains('djs-label-hidden')).to.be.true;
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('resize', function() {
|
||||
|
||||
it('[text annotations] should resize preview on resize', inject(function(directEditing, elementRegistry, eventBus, labelEditingPreview) {
|
||||
|
||||
// given
|
||||
var textAnnotation = elementRegistry.get('TextAnnotation_1');
|
||||
directEditing.activate(textAnnotation);
|
||||
|
||||
// when
|
||||
eventBus.fire('directEditing.resize', {
|
||||
width: 200,
|
||||
height: 200,
|
||||
dx: 100,
|
||||
dy: 100
|
||||
});
|
||||
|
||||
// then
|
||||
var bounds = labelEditingPreview.path.getBBox();
|
||||
|
||||
expect(bounds).to.eql({ x: 0, y: 0, width: 10, height: 300 });
|
||||
}));
|
||||
|
||||
|
||||
it('[text annotations] should resize preview below 0', inject(function(directEditing, elementRegistry, eventBus, labelEditingPreview) {
|
||||
|
||||
// given
|
||||
var textAnnotation = elementRegistry.get('TextAnnotation_1');
|
||||
directEditing.activate(textAnnotation);
|
||||
|
||||
// when
|
||||
eventBus.fire('directEditing.resize', {
|
||||
width: 200,
|
||||
height: 200,
|
||||
dx: -300,
|
||||
dy: -300
|
||||
});
|
||||
|
||||
// then
|
||||
var bounds = labelEditingPreview.path.getBBox();
|
||||
|
||||
expect(bounds).to.eql({ x: 0, y: 0, width: 10, height: 0 });
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('complete/cancel', function() {
|
||||
|
||||
it('[external labels AND text annotations] should remove marker to hide element on complete', inject(function(directEditing, elementRegistry) {
|
||||
|
||||
// given
|
||||
var textAnnotation = elementRegistry.get('TextAnnotation_1');
|
||||
directEditing.activate(textAnnotation);
|
||||
|
||||
// when
|
||||
directEditing.complete();
|
||||
|
||||
// then
|
||||
var gfx = elementRegistry.getGraphics(textAnnotation);
|
||||
|
||||
expect(gfx.classList.contains('djs-element-hidden')).to.be.false;
|
||||
}));
|
||||
|
||||
|
||||
it('[internal labels] should remove marker to hide label on complete', inject(function(directEditing, elementRegistry) {
|
||||
|
||||
// given
|
||||
var task = elementRegistry.get('Task_1');
|
||||
directEditing.activate(task);
|
||||
|
||||
// when
|
||||
directEditing.complete();
|
||||
|
||||
// then
|
||||
var gfx = elementRegistry.getGraphics(task);
|
||||
|
||||
expect(gfx.classList.contains('djs-label-hidden')).to.be.false;
|
||||
}));
|
||||
|
||||
});
|
||||
});
|
|
@ -1,14 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
var TestHelper = require('../../../TestHelper');
|
||||
|
||||
/* global bootstrapViewer, inject */
|
||||
|
||||
TestHelper.insertCSS('diagram-js-label-editing.css',
|
||||
'div { box-sizing: border-box; }' +
|
||||
'div[contenteditable=true] { line-height: 14px; font-family: Arial; font-size: 12px }'
|
||||
);
|
||||
|
||||
|
||||
var labelEditingModule = require('../../../../lib/features/label-editing'),
|
||||
coreModule = require('../../../../lib/core'),
|
||||
|
@ -17,6 +10,10 @@ var labelEditingModule = require('../../../../lib/features/label-editing'),
|
|||
|
||||
var LabelUtil = require('../../../../lib/features/label-editing/LabelUtil');
|
||||
|
||||
var MEDIUM_LINE_HEIGHT = 14;
|
||||
|
||||
var DELTA = 3;
|
||||
|
||||
function triggerKeyEvent(element, event, code) {
|
||||
var e = document.createEvent('Events');
|
||||
|
||||
|
@ -30,6 +27,13 @@ function triggerKeyEvent(element, event, code) {
|
|||
return element.dispatchEvent(e);
|
||||
}
|
||||
|
||||
function expectBounds(parent, bounds) {
|
||||
expect(parent.offsetLeft).to.be.closeTo(bounds.x, DELTA);
|
||||
expect(parent.offsetTop).to.be.closeTo(bounds.y, DELTA);
|
||||
expect(parent.offsetWidth).to.be.closeTo(bounds.width, DELTA);
|
||||
expect(parent.offsetHeight).to.be.closeTo(bounds.height, DELTA);
|
||||
}
|
||||
|
||||
describe('features - label-editing', function() {
|
||||
|
||||
var diagramXML = require('../../../fixtures/bpmn/features/label-editing/labels.bpmn');
|
||||
|
@ -44,7 +48,7 @@ describe('features - label-editing', function() {
|
|||
it('should register on dblclick', inject(function(elementRegistry, directEditing, eventBus) {
|
||||
|
||||
// given
|
||||
var shape = elementRegistry.get('task-nested-embedded');
|
||||
var shape = elementRegistry.get('Task_1');
|
||||
|
||||
// when
|
||||
eventBus.fire('element.dblclick', { element: shape });
|
||||
|
@ -60,7 +64,7 @@ describe('features - label-editing', function() {
|
|||
it('should cancel on <ESC>', inject(function(elementRegistry, directEditing, eventBus) {
|
||||
|
||||
// given
|
||||
var shape = elementRegistry.get('task-nested-embedded'),
|
||||
var shape = elementRegistry.get('Task_1'),
|
||||
task = shape.businessObject;
|
||||
|
||||
var oldName = task.name;
|
||||
|
@ -84,12 +88,12 @@ describe('features - label-editing', function() {
|
|||
it('should complete on drag start', inject(function(elementRegistry, directEditing, dragging) {
|
||||
|
||||
// given
|
||||
var shape = elementRegistry.get('task-nested-embedded'),
|
||||
var shape = elementRegistry.get('Task_1'),
|
||||
task = shape.businessObject;
|
||||
|
||||
directEditing.activate(shape);
|
||||
|
||||
directEditing._textbox.content.innerText = 'FOO BAR';
|
||||
directEditing._textbox.content.textContent = 'FOO BAR';
|
||||
|
||||
// when
|
||||
dragging.init(null, { x: 0, y: 0 }, 'foo');
|
||||
|
@ -102,7 +106,7 @@ describe('features - label-editing', function() {
|
|||
it('should submit on root element click', inject(function(elementRegistry, directEditing, canvas, eventBus) {
|
||||
|
||||
// given
|
||||
var shape = elementRegistry.get('task-nested-embedded'),
|
||||
var shape = elementRegistry.get('Task_1'),
|
||||
task = shape.businessObject;
|
||||
|
||||
// activate
|
||||
|
@ -174,7 +178,7 @@ describe('features - label-editing', function() {
|
|||
it('should update via command stack', function() {
|
||||
|
||||
// given
|
||||
var diagramElement = elementRegistry.get('user-task');
|
||||
var diagramElement = elementRegistry.get('Task_1');
|
||||
|
||||
var listenerCalled;
|
||||
|
||||
|
@ -194,7 +198,7 @@ describe('features - label-editing', function() {
|
|||
it('should undo via command stack', inject(function(commandStack) {
|
||||
|
||||
// given
|
||||
var diagramElement = elementRegistry.get('user-task');
|
||||
var diagramElement = elementRegistry.get('Task_1');
|
||||
|
||||
var oldLabel = LabelUtil.getLabel(diagramElement);
|
||||
|
||||
|
@ -217,7 +221,7 @@ describe('features - label-editing', function() {
|
|||
it('on shape change', function() {
|
||||
|
||||
// given
|
||||
var diagramElement = elementRegistry.get('user-task');
|
||||
var diagramElement = elementRegistry.get('Task_1');
|
||||
|
||||
var listenerCalled;
|
||||
|
||||
|
@ -239,7 +243,7 @@ describe('features - label-editing', function() {
|
|||
it('on connection on change', function() {
|
||||
|
||||
// given
|
||||
var diagramElement = elementRegistry.get('sequence-flow-no');
|
||||
var diagramElement = elementRegistry.get('SequenceFlow_1');
|
||||
|
||||
var listenerCalled;
|
||||
|
||||
|
@ -300,297 +304,328 @@ describe('features - label-editing', function() {
|
|||
}
|
||||
|
||||
|
||||
it('task', directEdit('user-task'));
|
||||
it('task', directEdit('Task_1'));
|
||||
|
||||
|
||||
it('gateway', directEdit('exclusive-gateway'));
|
||||
it('gateway', directEdit('ExclusiveGateway_1'));
|
||||
|
||||
it('gateway via label', directEdit('exclusive-gateway_label'));
|
||||
it('gateway via label', directEdit('ExclusiveGateway_1_label'));
|
||||
|
||||
|
||||
it('event', directEdit('intermediate-throw-event'));
|
||||
it('event', directEdit('StartEvent_1'));
|
||||
|
||||
it('event via label', directEdit('intermediate-throw-event_label'));
|
||||
it('event via label', directEdit('StartEvent_1_label'));
|
||||
|
||||
it('event without label', directEdit('start-event'));
|
||||
it('event without label', directEdit('EndEvent_1'));
|
||||
|
||||
|
||||
it('data store reference', directEdit('data-store-reference'));
|
||||
it('data store reference', directEdit('DataStoreReference_1'));
|
||||
|
||||
it('data object reference', directEdit('data-object-reference'));
|
||||
it('data object reference', directEdit('DataObjectReference_1'));
|
||||
|
||||
|
||||
it('sequenceflow', directEdit('sequence-flow-yes'));
|
||||
it('sequenceflow', directEdit('SequenceFlow_1'));
|
||||
|
||||
it('sequenceflow without label', directEdit('sequenceflow-unlabeled'));
|
||||
it('sequenceflow via label', directEdit('SequenceFlow_1_label'));
|
||||
|
||||
it('sequenceflow via label', directEdit('sequence-flow-yes_label'));
|
||||
it('sequenceflow without label', directEdit('SequenceFlow_2'));
|
||||
|
||||
|
||||
it('message flow', directEdit('message-flow'));
|
||||
it('message flow', directEdit('MessageFlow_1'));
|
||||
|
||||
it('message flow via label', directEdit('message-flow_label'));
|
||||
it('message flow via label', directEdit('MessageFlow_1_label'));
|
||||
|
||||
|
||||
it('pool', directEdit('expanded-pool'));
|
||||
it('pool', directEdit('Participant_1'));
|
||||
|
||||
it('pool, collapsed', directEdit('collapsed-pool'));
|
||||
it('pool, collapsed', directEdit('Participant_2'));
|
||||
|
||||
|
||||
it('lane with label', directEdit('nested-lane-1-2'));
|
||||
it('lane with label', directEdit('Lane_1'));
|
||||
|
||||
it('lane without label', directEdit('nested-lane-no-label'));
|
||||
it('lane without label', directEdit('Lane_2'));
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('sizing', function() {
|
||||
describe('sizes', function() {
|
||||
|
||||
var testModules = [ labelEditingModule, coreModule, modelingModule ];
|
||||
|
||||
|
||||
|
||||
function testTextboxSizing(elementId, zoom, width, height, content) {
|
||||
return inject(function(canvas, elementRegistry, directEditing) {
|
||||
// zoom in
|
||||
canvas.zoom(zoom);
|
||||
// grab one element
|
||||
var shape = elementRegistry.get(elementId);
|
||||
// activate label editing
|
||||
directEditing.activate(shape);
|
||||
// grab the textarea
|
||||
var textbox = directEditing._textbox;
|
||||
// optionally set content text
|
||||
if (content) {
|
||||
textbox.content.innerText = content;
|
||||
}
|
||||
|
||||
if (width === 'auto') {
|
||||
width = shape.width;
|
||||
}
|
||||
|
||||
if (height === 'auto') {
|
||||
height = shape.height;
|
||||
}
|
||||
|
||||
// then
|
||||
if (typeof width === 'object' && width.min) {
|
||||
expect(textbox.content.offsetWidth).to.be.at.least(width.min);
|
||||
} else {
|
||||
expect(textbox.content.offsetWidth).to.be.equal(width);
|
||||
}
|
||||
|
||||
if (typeof height === 'object' && height.min) {
|
||||
expect(textbox.content.offsetHeight).to.be.at.least(height.min);
|
||||
} else {
|
||||
expect(textbox.content.offsetHeight).to.be.equal(height);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
beforeEach(bootstrapViewer(diagramXML, {
|
||||
modules: testModules,
|
||||
canvas: { deferUpdate: false }
|
||||
}));
|
||||
|
||||
|
||||
describe('height', function() {
|
||||
|
||||
var oneLineText = 'One line',
|
||||
twoLineText = 'Two\nlines',
|
||||
tenLineText = '1\n2\n3\n4\n5\n6\n7\n8\n9\n0';
|
||||
describe('bounds', function() {
|
||||
|
||||
describe('external labels', function() {
|
||||
|
||||
it('[no text] should have min height', testTextboxSizing('start-event', 1, 150, 20));
|
||||
it('[zoom 1] should have fixed width and element height', inject(function(canvas, directEditing, elementRegistry) {
|
||||
var zoom = 1;
|
||||
|
||||
it('[1 line text] should be 1 line high', testTextboxSizing('start-event', 1, 150, 20, oneLineText));
|
||||
canvas.zoom(zoom);
|
||||
|
||||
it('[2 line text] should be 2 line high', testTextboxSizing('start-event', 1, 150, 34, twoLineText));
|
||||
var startEvent = elementRegistry.get('StartEvent_1');
|
||||
|
||||
it('[10 line text] should be 10 line high', testTextboxSizing('start-event', 1, 150, 146, tenLineText));
|
||||
var bounds = canvas.getAbsoluteBBox(startEvent.label);
|
||||
var mid = {
|
||||
x: bounds.x + bounds.width / 2,
|
||||
y: bounds.y + bounds.height / 2
|
||||
};
|
||||
|
||||
directEditing.activate(startEvent);
|
||||
|
||||
expectBounds(directEditing._textbox.parent, {
|
||||
x: mid.x - (45 * zoom),
|
||||
y: bounds.y - (7 * zoom),
|
||||
width: (90 * zoom),
|
||||
height: bounds.height + (5 * zoom) + 7
|
||||
});
|
||||
}));
|
||||
|
||||
|
||||
it('[zoom 1.5] should have fixed width and element height', inject(function(canvas, directEditing, elementRegistry) {
|
||||
var zoom = 1.5;
|
||||
|
||||
canvas.zoom(zoom);
|
||||
|
||||
var startEvent = elementRegistry.get('StartEvent_1');
|
||||
|
||||
var bounds = canvas.getAbsoluteBBox(startEvent.label);
|
||||
var mid = {
|
||||
x: bounds.x + bounds.width / 2,
|
||||
y: bounds.y + bounds.height / 2
|
||||
};
|
||||
|
||||
directEditing.activate(startEvent);
|
||||
|
||||
expectBounds(directEditing._textbox.parent, {
|
||||
x: mid.x - (45 * zoom),
|
||||
y: bounds.y - (7 * zoom),
|
||||
width: (90 * zoom),
|
||||
height: bounds.height + (5 * zoom) + (7 * zoom)
|
||||
});
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('internal labels', function() {
|
||||
|
||||
it('[no text] should have fixed dimensions', testTextboxSizing('empty-task', 1, 'auto', 'auto'));
|
||||
it('[zoom 1] should have element size', inject(function(canvas, directEditing, elementRegistry) {
|
||||
var zoom = 1;
|
||||
|
||||
it('[1 line text] should have fixed dimensions', testTextboxSizing('empty-task', 1, 'auto', 'auto', oneLineText));
|
||||
canvas.zoom(zoom);
|
||||
|
||||
it('[2 line text] should have fixed dimensions', testTextboxSizing('empty-task', 1, 'auto', 'auto', twoLineText));
|
||||
var task = elementRegistry.get('Task_1');
|
||||
|
||||
it('[10 line text] should have fixed dimensions', testTextboxSizing('empty-task', 1, 'auto', 'auto', tenLineText));
|
||||
var bounds = canvas.getAbsoluteBBox(task);
|
||||
|
||||
directEditing.activate(task);
|
||||
|
||||
expectBounds(directEditing._textbox.parent, bounds);
|
||||
}));
|
||||
|
||||
|
||||
it('[zoom 1.5] should have element size', inject(function(canvas, directEditing, elementRegistry) {
|
||||
var zoom = 1.5;
|
||||
|
||||
canvas.zoom(zoom);
|
||||
|
||||
var task = elementRegistry.get('Task_1');
|
||||
|
||||
var bounds = canvas.getAbsoluteBBox(task);
|
||||
|
||||
directEditing.activate(task);
|
||||
|
||||
expectBounds(directEditing._textbox.parent, bounds);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('sequence flows', function() {
|
||||
|
||||
it('[no text] should have min height', testTextboxSizing('sequenceflow-unlabeled', 1, 150, 20));
|
||||
it('[zoom 1] should have fixed width and element height', inject(function(canvas, directEditing, elementRegistry) {
|
||||
var zoom = 1;
|
||||
|
||||
it('[1 line text] should be 1 line high', testTextboxSizing('sequenceflow-unlabeled', 1, 150, 20, oneLineText));
|
||||
canvas.zoom(zoom);
|
||||
|
||||
it('[2 line text] should be 2 line high', testTextboxSizing('sequenceflow-unlabeled', 1, 150, 34, twoLineText));
|
||||
var sequenceFlow = elementRegistry.get('SequenceFlow_1');
|
||||
|
||||
it('[10 line text] should be 10 line high', testTextboxSizing('sequenceflow-unlabeled', 1, 150, 146, tenLineText));
|
||||
var bounds = canvas.getAbsoluteBBox(sequenceFlow.label);
|
||||
var mid = {
|
||||
x: bounds.x + bounds.width / 2,
|
||||
y: bounds.y + bounds.height / 2
|
||||
};
|
||||
|
||||
directEditing.activate(sequenceFlow);
|
||||
|
||||
expectBounds(directEditing._textbox.parent, {
|
||||
x: mid.x - (45 * zoom),
|
||||
y: bounds.y - (7 * zoom),
|
||||
width: (90 * zoom),
|
||||
height: bounds.height + (5 * zoom) + 7
|
||||
});
|
||||
}));
|
||||
|
||||
|
||||
it('[zoom 1.5] should have fixed width and element height', inject(function(canvas, directEditing, elementRegistry) {
|
||||
var zoom = 1.5;
|
||||
|
||||
canvas.zoom(zoom);
|
||||
|
||||
var sequenceflow = elementRegistry.get('SequenceFlow_1');
|
||||
|
||||
var bounds = canvas.getAbsoluteBBox(sequenceflow.label);
|
||||
var mid = {
|
||||
x: bounds.x + bounds.width / 2,
|
||||
y: bounds.y + bounds.height / 2
|
||||
};
|
||||
|
||||
directEditing.activate(sequenceflow);
|
||||
|
||||
expectBounds(directEditing._textbox.parent, {
|
||||
x: mid.x - (45 * zoom),
|
||||
y: bounds.y - (7 * zoom),
|
||||
width: (90 * zoom),
|
||||
height: bounds.height + (5 * zoom) + (7 * zoom)
|
||||
});
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('text annotation', function() {
|
||||
describe('text annotations', function() {
|
||||
|
||||
it('[no text] should have element height', testTextboxSizing('text-annotation', 1, 100, 98));
|
||||
it('[zoom 1] should have element size', inject(function(canvas, directEditing, elementRegistry) {
|
||||
var zoom = 1;
|
||||
|
||||
it('[1 line text] should have element height', testTextboxSizing('text-annotation', 1, 100, 98, oneLineText));
|
||||
canvas.zoom(zoom);
|
||||
|
||||
it('[2 line text] should have element height', testTextboxSizing('text-annotation', 1, 100, 98, twoLineText));
|
||||
var textAnnotation = elementRegistry.get('TextAnnotation_1');
|
||||
|
||||
it('[10 line text] should have element height', testTextboxSizing('text-annotation', 1, { min: 100 }, 98, tenLineText));
|
||||
var bounds = canvas.getAbsoluteBBox(textAnnotation);
|
||||
|
||||
directEditing.activate(textAnnotation);
|
||||
|
||||
expectBounds(directEditing._textbox.parent, bounds);
|
||||
}));
|
||||
|
||||
|
||||
it('[zoom 1.5] should have element size', inject(function(canvas, directEditing, elementRegistry) {
|
||||
var zoom = 1.5;
|
||||
|
||||
canvas.zoom(zoom);
|
||||
|
||||
var textAnnotation = elementRegistry.get('TextAnnotation_1');
|
||||
|
||||
var bounds = canvas.getAbsoluteBBox(textAnnotation);
|
||||
|
||||
directEditing.activate(textAnnotation);
|
||||
|
||||
expectBounds(directEditing._textbox.parent, bounds);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('expanded sub process', function() {
|
||||
describe('expanded sub processes', function() {
|
||||
|
||||
it('[no text] should have min height', testTextboxSizing('subprocess-expanded', 1, 200, 20));
|
||||
it('[zoom 1] should have element width and height to fit text', inject(function(canvas, directEditing, elementRegistry) {
|
||||
var zoom = 1;
|
||||
|
||||
it('[1 line text] should be 1 line high', testTextboxSizing('subprocess-expanded', 1, 200, 20, oneLineText));
|
||||
canvas.zoom(zoom);
|
||||
|
||||
it('[2 line text] should be 2 line high', testTextboxSizing('subprocess-expanded', 1, 200, 34, twoLineText));
|
||||
var subProcess = elementRegistry.get('SubProcess_1');
|
||||
|
||||
it('[10 line text] should be max 3 line high', testTextboxSizing('subprocess-expanded', 1, 200, 48, tenLineText));
|
||||
var bounds = canvas.getAbsoluteBBox(subProcess);
|
||||
|
||||
directEditing.activate(subProcess);
|
||||
|
||||
expectBounds(directEditing._textbox.parent, {
|
||||
x: bounds.x,
|
||||
y: bounds.y,
|
||||
width: bounds.width,
|
||||
height: (MEDIUM_LINE_HEIGHT * zoom) + (7 * 2 * zoom)
|
||||
});
|
||||
}));
|
||||
|
||||
|
||||
it('[zoom 1.5] should have element width and height to fit text', inject(function(canvas, directEditing, elementRegistry) {
|
||||
var zoom = 1.5;
|
||||
|
||||
canvas.zoom(zoom);
|
||||
|
||||
var subProcess = elementRegistry.get('SubProcess_1');
|
||||
|
||||
var bounds = canvas.getAbsoluteBBox(subProcess);
|
||||
|
||||
directEditing.activate(subProcess);
|
||||
|
||||
expectBounds(directEditing._textbox.parent, {
|
||||
x: bounds.x,
|
||||
y: bounds.y,
|
||||
width: bounds.width,
|
||||
height: (MEDIUM_LINE_HEIGHT * zoom) + (7 * 2 * zoom)
|
||||
});
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('pools/lanes', function() {
|
||||
|
||||
it('[no text] should have min height', testTextboxSizing('expanded-pool', 1, 150, 20));
|
||||
it('[zoom 1] should have width of element height, height of 30', inject(function(canvas, directEditing, elementRegistry) {
|
||||
var zoom = 1;
|
||||
|
||||
it('[1 line text] should be 1 line high', testTextboxSizing('expanded-pool', 1, 150, 20, oneLineText));
|
||||
canvas.zoom(zoom);
|
||||
|
||||
it('[2 line text] should be 2 line high', testTextboxSizing('expanded-pool', 1, 150, 34, twoLineText));
|
||||
var pool = elementRegistry.get('Participant_1');
|
||||
|
||||
it('[10 line text] should be max 2 line high', testTextboxSizing('expanded-pool', 1, 150, 34, tenLineText));
|
||||
var bounds = canvas.getAbsoluteBBox(pool);
|
||||
var mid = {
|
||||
x: bounds.x + bounds.width / 2,
|
||||
y: bounds.y + bounds.height / 2
|
||||
};
|
||||
|
||||
});
|
||||
directEditing.activate(pool);
|
||||
|
||||
});
|
||||
|
||||
describe('width', function() {
|
||||
|
||||
var oneWord = 'foobar',
|
||||
fiveWords = 'lorem ipsum dolor foobar foobar',
|
||||
longWord = 'loremipsumdolorfoobar';
|
||||
|
||||
describe('external labels', function() {
|
||||
|
||||
it('[no text] should have fixed width', testTextboxSizing('start-event', 1, 150, 20));
|
||||
|
||||
it('[one word] should have fixed width', testTextboxSizing('start-event', 1, 150, 20, oneWord));
|
||||
|
||||
it('[five words] should have fixed width, line break', testTextboxSizing('start-event', 1, 150, { min: 34 }, fiveWords));
|
||||
|
||||
it('[long word] should have fixed width', testTextboxSizing('start-event', 1, 150, { min: 20 }, longWord));
|
||||
|
||||
});
|
||||
expectBounds(directEditing._textbox.parent, {
|
||||
x: bounds.x - (bounds.height / 2) + (15 * zoom),
|
||||
y: mid.y - (30 * zoom) / 2,
|
||||
width: bounds.height * zoom,
|
||||
height: 30 * zoom
|
||||
});
|
||||
}));
|
||||
|
||||
|
||||
describe('internal labels', function() {
|
||||
it('[zoom 1.5] should have width of element height, height of 30', inject(function(canvas, directEditing, elementRegistry) {
|
||||
var zoom = 1.5;
|
||||
|
||||
it('[no text] should have fixed dimensions (task)', testTextboxSizing('empty-task', 1, 100, 80));
|
||||
canvas.zoom(zoom);
|
||||
|
||||
it('[no text] should have fixed dimensions (call activity)', testTextboxSizing('call-activity', 1, 100, 80));
|
||||
var pool = elementRegistry.get('Participant_1');
|
||||
|
||||
it('[no text] should have fixed dimensions (collapsed sub process)', testTextboxSizing('subprocess-collapsed', 1, 100, 80));
|
||||
var bounds = canvas.getAbsoluteBBox(pool);
|
||||
var mid = {
|
||||
x: bounds.x + bounds.width / 2,
|
||||
y: bounds.y + bounds.height / 2
|
||||
};
|
||||
|
||||
it('[one word] should have fixed dimensions', testTextboxSizing('empty-task', 1, 100, 80, oneWord));
|
||||
directEditing.activate(pool);
|
||||
|
||||
it('[five words] should have fixed dimensions', testTextboxSizing('empty-task', 1, 100, 80, fiveWords));
|
||||
|
||||
it('[long word] should have fixed dimensions', testTextboxSizing('empty-task', 1, 100, 80, longWord));
|
||||
|
||||
describe('zoom', function() {
|
||||
|
||||
it('should have fixed dimensions (low zoom)', testTextboxSizing('empty-task', 0.5, 100, 80, oneWord));
|
||||
|
||||
it('should have fixed dimensions (high zoom)', testTextboxSizing('empty-task', 1.5, 150, 120, oneWord));
|
||||
|
||||
it('should center text box position (low zoom)', inject(function(canvas, elementRegistry, directEditing) {
|
||||
|
||||
// given
|
||||
canvas.zoom(0.5, { x: 0, y: 0 });
|
||||
|
||||
var shape = elementRegistry.get('empty-task');
|
||||
|
||||
// when
|
||||
directEditing.activate(shape);
|
||||
|
||||
// then
|
||||
var textbox = directEditing._textbox;
|
||||
|
||||
expect(textbox.content.offsetLeft).to.equal(211);
|
||||
expect(textbox.content.offsetTop).to.equal(17);
|
||||
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('sequence flows', function() {
|
||||
|
||||
it('[no text] should have fixed width', testTextboxSizing('sequenceflow-unlabeled', 1, 150, 20));
|
||||
|
||||
it('[one word] should have fixed width', testTextboxSizing('sequenceflow-unlabeled', 1, 150, 20, oneWord));
|
||||
|
||||
it('[five words] should have fixed width, line break', testTextboxSizing('sequenceflow-unlabeled', 1, 150, { min: 34 }, fiveWords));
|
||||
|
||||
it('[long word] should have fixed width', testTextboxSizing('sequenceflow-unlabeled', 1, 150, { min: 20 }, longWord));
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('text annotation', function() {
|
||||
|
||||
it('[no text] should have min width', testTextboxSizing('text-annotation', 1, 100, 98));
|
||||
|
||||
it('[one word] should have min width', testTextboxSizing('text-annotation', 1, 100, 98, oneWord));
|
||||
|
||||
it('[five words] should expand width', testTextboxSizing('text-annotation', 1, { min: 176 }, 98, fiveWords));
|
||||
|
||||
it('[long word] should expand width', testTextboxSizing('text-annotation', 1, { min: 129 }, 98, longWord));
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('expanded sub process', function() {
|
||||
|
||||
it('[no text] should have fixed width', testTextboxSizing('subprocess-expanded', 1, 200, 20));
|
||||
|
||||
it('[one word] should have fixed width', testTextboxSizing('subprocess-expanded', 1, 200, 20, oneWord));
|
||||
|
||||
it('[five words] should have fixed width, line break',
|
||||
testTextboxSizing('subprocess-expanded', 1, 200, 34, 'five yreallyreallyreally loooooong woooords'));
|
||||
|
||||
it('[long word] should have fixed width', testTextboxSizing('subprocess-expanded', 1, 200, 20, longWord));
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('pools/lanes', function() {
|
||||
|
||||
it('[no text] should have fixed width', testTextboxSizing('expanded-pool', 1, 150, 20));
|
||||
|
||||
it('[one word] should have fixed width', testTextboxSizing('expanded-pool', 1, 150, 20, oneWord));
|
||||
|
||||
it('[five words] should have fixed width, line break', testTextboxSizing('expanded-pool', 1, 150, 34, fiveWords));
|
||||
|
||||
it('[long word] should have fixed width', testTextboxSizing('expanded-pool', 1, 150, { min: 20 }, longWord));
|
||||
expectBounds(directEditing._textbox.parent, {
|
||||
x: bounds.x - (bounds.height / 2) + (15 * zoom),
|
||||
y: mid.y - (30 * zoom) / 2,
|
||||
width: bounds.height,
|
||||
height: 30 * zoom
|
||||
});
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@ var Modeler = require('../../../../lib/Modeler');
|
|||
|
||||
var TestContainer = require('mocha-test-container-support');
|
||||
|
||||
var DELTA = 2;
|
||||
|
||||
|
||||
describe('label bounds', function() {
|
||||
|
||||
|
@ -126,7 +128,7 @@ describe('label bounds', function() {
|
|||
// then
|
||||
var expectedX = getExpectedX(shape);
|
||||
|
||||
expect(shape.label.x).to.equal(expectedX);
|
||||
expect(shape.label.x).to.be.closeTo(expectedX, DELTA);
|
||||
}));
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue