bpmn-js 0.20.4 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/.travis.yml +2 -0
  2. package/lib/draw/BpmnRenderer.js +4 -3
  3. package/lib/features/copy-paste/BpmnCopyPaste.js +22 -19
  4. package/lib/features/label-editing/LabelEditingPreview.js +122 -0
  5. package/lib/features/label-editing/LabelEditingProvider.js +154 -55
  6. package/lib/features/label-editing/cmd/UpdateLabelHandler.js +10 -6
  7. package/lib/features/label-editing/index.js +8 -3
  8. package/lib/features/modeling/BpmnUpdater.js +17 -13
  9. package/lib/features/modeling/ElementFactory.js +36 -19
  10. package/lib/features/modeling/Modeling.js +5 -1
  11. package/lib/features/modeling/behavior/DropOnFlowBehavior.js +50 -16
  12. package/lib/features/modeling/behavior/ReplaceElementBehaviour.js +4 -2
  13. package/lib/features/modeling/behavior/util/LabelLayoutUtil.js +3 -2
  14. package/lib/features/modeling/behavior/util/LineAttachmentUtil.js +36 -30
  15. package/lib/features/rules/BpmnRules.js +29 -11
  16. package/lib/features/snapping/BpmnSnapping.js +22 -6
  17. package/package.json +22 -22
  18. package/test/TestHelper.js +1 -1
  19. package/test/fixtures/bpmn/features/label-editing/labels.bpmn +132 -202
  20. package/test/integration/CustomElementsSpec.js +2 -5
  21. package/test/spec/features/copy-paste/BpmnCopyPasteSpec.js +38 -0
  22. package/test/spec/features/label-editing/LabelEditingPreviewSpec.js +133 -0
  23. package/test/spec/features/label-editing/LabelEditingProviderSpec.js +207 -172
  24. package/test/spec/features/modeling/LabelBoundsSpec.js +3 -1
  25. package/test/spec/features/modeling/LabelLayoutingSpec.js +211 -232
  26. package/test/spec/features/modeling/behavior/DropOnFlowBehavior.bpmn +5 -1
  27. package/test/spec/features/modeling/behavior/DropOnFlowBehaviorSpec.js +174 -1
  28. package/test/spec/features/modeling/behavior/util/LabelLayoutUtilSpec.js +75 -0
  29. package/test/spec/features/modeling/behavior/util/LineAttachmentUtilSpec.js +55 -7
  30. package/test/spec/features/rules/BpmnRulesSpec.js +108 -64
  31. package/test/spec/features/snapping/BpmnSnapping.sequenceFlow.bpmn +41 -0
  32. package/test/spec/features/snapping/BpmnSnappingSpec.js +66 -0
package/.travis.yml CHANGED
@@ -1,6 +1,8 @@
1
1
  language: node_js
2
2
  node_js: '4.0'
3
3
 
4
+ sudo: false
5
+
4
6
  addons:
5
7
  firefox: "latest-esr"
6
8
 
@@ -1551,7 +1551,7 @@ function BpmnRenderer(eventBus, styles, pathMap, canvas, priority) {
1551
1551
  });
1552
1552
 
1553
1553
  var text = getSemantic(element).text || '';
1554
- renderLabel(parentGfx, text, { box: element, align: 'left-middle', padding: 5 });
1554
+ renderLabel(parentGfx, text, { box: element, align: 'left-top', padding: 5 });
1555
1555
 
1556
1556
  return textElement;
1557
1557
  },
@@ -1827,8 +1827,9 @@ function isThrowEvent(event) {
1827
1827
  }
1828
1828
 
1829
1829
  function isCollection(element) {
1830
- return element.isCollection ||
1831
- (element.elementObjectRef && element.elementObjectRef.isCollection);
1830
+ var dataObject = element.dataObjectRef;
1831
+
1832
+ return element.isCollection || (dataObject && dataObject.isCollection);
1832
1833
  }
1833
1834
 
1834
1835
  function getDi(element) {
@@ -30,22 +30,16 @@ function removeProperties(element, properties) {
30
30
  });
31
31
  }
32
32
 
33
- function BpmnCopyPaste(bpmnFactory, eventBus, copyPaste, clipboard, moddle, canvas, bpmnRules) {
33
+ function BpmnCopyPaste(
34
+ bpmnFactory, eventBus, copyPaste,
35
+ clipboard, canvas, bpmnRules) {
34
36
 
35
37
  var helper = new ModelCloneHelper(eventBus);
36
38
 
37
39
  copyPaste.registerDescriptor(function(element, descriptor) {
38
- var businessObject = getBusinessObject(element),
39
- newBusinessObject = bpmnFactory.create(businessObject.$type);
40
+ var businessObject = descriptor.oldBusinessObject = getBusinessObject(element);
40
41
 
41
- var properties = getProperties(businessObject.$descriptor),
42
- colors = {};
43
-
44
- properties = filter(properties, function(property) {
45
- return IGNORED_PROPERTIES.indexOf(property.replace(/bpmn:/, '')) === -1;
46
- });
47
-
48
- descriptor.businessObject = helper.clone(businessObject, newBusinessObject, properties);
42
+ var colors = {};
49
43
 
50
44
  descriptor.type = element.type;
51
45
 
@@ -77,11 +71,22 @@ function BpmnCopyPaste(bpmnFactory, eventBus, copyPaste, clipboard, moddle, canv
77
71
  createdElements = context.createdElements,
78
72
  parent = descriptor.parent,
79
73
  rootElement = canvas.getRootElement(),
80
- businessObject,
74
+ oldBusinessObject = descriptor.oldBusinessObject,
75
+ newBusinessObject,
81
76
  source,
82
77
  target,
83
78
  canConnect;
84
79
 
80
+ newBusinessObject = bpmnFactory.create(oldBusinessObject.$type);
81
+
82
+ var properties = getProperties(oldBusinessObject.$descriptor);
83
+
84
+ properties = filter(properties, function(property) {
85
+ return IGNORED_PROPERTIES.indexOf(property.replace(/bpmn:/, '')) === -1;
86
+ });
87
+
88
+ descriptor.businessObject = helper.clone(oldBusinessObject, newBusinessObject, properties);
89
+
85
90
  if (descriptor.type === 'label') {
86
91
  return;
87
92
  }
@@ -117,19 +122,17 @@ function BpmnCopyPaste(bpmnFactory, eventBus, copyPaste, clipboard, moddle, canv
117
122
  }
118
123
  }
119
124
 
120
- businessObject = descriptor.businessObject;
121
-
122
125
  // remove the id or else we cannot paste multiple times
123
- delete businessObject.id;
126
+ delete newBusinessObject.id;
124
127
 
125
128
  // assign an ID
126
- bpmnFactory._ensureId(businessObject);
129
+ bpmnFactory._ensureId(newBusinessObject);
127
130
 
128
131
  if (descriptor.type === 'bpmn:Participant' && descriptor.processRef) {
129
- descriptor.processRef = businessObject.processRef = bpmnFactory.create('bpmn:Process');
132
+ descriptor.processRef = newBusinessObject.processRef = bpmnFactory.create('bpmn:Process');
130
133
  }
131
134
 
132
- setProperties(businessObject, descriptor, [
135
+ setProperties(newBusinessObject, descriptor, [
133
136
  'isExpanded',
134
137
  'triggeredByEvent'
135
138
  ]);
@@ -138,6 +141,7 @@ function BpmnCopyPaste(bpmnFactory, eventBus, copyPaste, clipboard, moddle, canv
138
141
  'triggeredByEvent'
139
142
  ]);
140
143
  });
144
+
141
145
  }
142
146
 
143
147
 
@@ -146,7 +150,6 @@ BpmnCopyPaste.$inject = [
146
150
  'eventBus',
147
151
  'copyPaste',
148
152
  'clipboard',
149
- 'moddle',
150
153
  'canvas',
151
154
  'bpmnRules'
152
155
  ];
@@ -0,0 +1,122 @@
1
+ var svgAppend = require('tiny-svg/lib/append'),
2
+ svgAttr = require('tiny-svg/lib/attr'),
3
+ svgCreate = require('tiny-svg/lib/create'),
4
+ svgRemove = require('tiny-svg/lib/remove');
5
+
6
+ var getBusinessObject = require('../../util/ModelUtil').getBusinessObject,
7
+ is = require('../../util/ModelUtil').is;
8
+
9
+ var translate = require('diagram-js/lib/util/SvgTransformUtil').translate;
10
+
11
+ var MARKER_HIDDEN = 'djs-element-hidden',
12
+ MARKER_LABEL_HIDDEN = 'djs-label-hidden';
13
+
14
+ function getStrokeColor(element, defaultColor) {
15
+ var bo = getBusinessObject(element);
16
+
17
+ return bo.di.get('stroke') || defaultColor || 'black';
18
+ }
19
+
20
+ function LabelEditingPreview(eventBus, canvas, elementRegistry, pathMap) {
21
+ var self = this;
22
+
23
+ var defaultLayer = canvas.getDefaultLayer();
24
+
25
+ var element, absoluteElementBBox, gfx;
26
+
27
+ eventBus.on('directEditing.activate', function(context) {
28
+ var activeProvider = context.active;
29
+
30
+ element = activeProvider.element.label || activeProvider.element;
31
+
32
+ // text annotation
33
+ if (is(element, 'bpmn:TextAnnotation')) {
34
+ absoluteElementBBox = canvas.getAbsoluteBBox(element);
35
+
36
+ gfx = svgCreate('g');
37
+
38
+ var textPathData = pathMap.getScaledPath('TEXT_ANNOTATION', {
39
+ xScaleFactor: 1,
40
+ yScaleFactor: 1,
41
+ containerWidth: element.width,
42
+ containerHeight: element.height,
43
+ position: {
44
+ mx: 0.0,
45
+ my: 0.0
46
+ }
47
+ });
48
+
49
+ var path = self.path = svgCreate('path');
50
+
51
+ svgAttr(path, {
52
+ d: textPathData,
53
+ strokeWidth: 2,
54
+ stroke: getStrokeColor(element)
55
+ });
56
+
57
+ svgAppend(gfx, path);
58
+
59
+ svgAppend(defaultLayer, gfx);
60
+
61
+ translate(gfx, element.x, element.y);
62
+ }
63
+
64
+ if (is(element, 'bpmn:TextAnnotation') ||
65
+ element.labelTarget) {
66
+ canvas.addMarker(element, MARKER_HIDDEN);
67
+ } else if (is(element, 'bpmn:Task') ||
68
+ is(element, 'bpmn:CallActivity') ||
69
+ is(element, 'bpmn:SubProcess') ||
70
+ is(element, 'bpmn:Participant')) {
71
+ canvas.addMarker(element, MARKER_LABEL_HIDDEN);
72
+ }
73
+ });
74
+
75
+ eventBus.on('directEditing.resize', function(context) {
76
+
77
+ // text annotation
78
+ if (is(element, 'bpmn:TextAnnotation')) {
79
+ var height = context.height,
80
+ dy = context.dy;
81
+
82
+ var newElementHeight = Math.max(element.height / absoluteElementBBox.height * (height + dy), 0);
83
+
84
+ var textPathData = pathMap.getScaledPath('TEXT_ANNOTATION', {
85
+ xScaleFactor: 1,
86
+ yScaleFactor: 1,
87
+ containerWidth: element.width,
88
+ containerHeight: newElementHeight,
89
+ position: {
90
+ mx: 0.0,
91
+ my: 0.0
92
+ }
93
+ });
94
+
95
+ svgAttr(self.path, {
96
+ d: textPathData
97
+ });
98
+ }
99
+ });
100
+
101
+ eventBus.on([ 'directEditing.complete', 'directEditing.cancel' ], function(context) {
102
+ var activeProvider = context.active;
103
+
104
+ if (activeProvider) {
105
+ canvas.removeMarker(activeProvider.element.label || activeProvider.element, MARKER_HIDDEN);
106
+ canvas.removeMarker(element, MARKER_LABEL_HIDDEN);
107
+ }
108
+
109
+ element = undefined;
110
+ absoluteElementBBox = undefined;
111
+
112
+ if (gfx) {
113
+ svgRemove(gfx);
114
+
115
+ gfx = undefined;
116
+ }
117
+ });
118
+ }
119
+
120
+ LabelEditingPreview.$inject = [ 'eventBus', 'canvas', 'elementRegistry', 'pathMap' ];
121
+
122
+ module.exports = LabelEditingPreview;
@@ -1,5 +1,7 @@
1
1
  'use strict';
2
2
 
3
+ var assign = require('lodash/object/assign');
4
+
3
5
  var UpdateLabelHandler = require('./cmd/UpdateLabelHandler');
4
6
 
5
7
  var LabelUtil = require('./LabelUtil');
@@ -7,10 +9,12 @@ var LabelUtil = require('./LabelUtil');
7
9
  var is = require('../../util/ModelUtil').is,
8
10
  isExpanded = require('../../util/DiUtil').isExpanded;
9
11
 
10
- var LINE_HEIGHT = 14,
11
- PADDING = 6;
12
+ var SMALL_FONT_SIZE = 11,
13
+ SMALL_LINE_HEIGHT = 13,
14
+ MEDIUM_FONT_SIZE = 12,
15
+ MEDIUM_LINE_HEIGHT = 14;
12
16
 
13
- function LabelEditingProvider(eventBus, canvas, directEditing, commandStack) {
17
+ function LabelEditingProvider(eventBus, canvas, directEditing, commandStack, resizeHandles) {
14
18
 
15
19
  this._canvas = canvas;
16
20
  this._commandStack = commandStack;
@@ -22,19 +26,20 @@ function LabelEditingProvider(eventBus, canvas, directEditing, commandStack) {
22
26
  // listen to dblclick on non-root elements
23
27
  eventBus.on('element.dblclick', function(event) {
24
28
  directEditing.activate(event.element);
29
+
30
+ resizeHandles.removeResizers();
25
31
  });
26
32
 
27
33
  // complete on followup canvas operation
28
- eventBus.on([ 'element.mousedown', 'drag.init', 'canvas.viewbox.changed' ], function(event) {
34
+ eventBus.on([ 'element.mousedown', 'drag.init', 'canvas.viewbox.changing' ], function(event) {
29
35
  directEditing.complete();
30
36
  });
31
37
 
32
38
  // cancel on command stack changes
33
- eventBus.on([ 'commandStack.changed' ], function() {
39
+ eventBus.on([ 'commandStack.changed' ], function(e) {
34
40
  directEditing.cancel();
35
41
  });
36
42
 
37
-
38
43
  if ('ontouchstart' in document.documentElement) {
39
44
  // we deactivate automatic label editing on mobile devices
40
45
  // as it breaks the user interaction workflow
@@ -42,10 +47,9 @@ function LabelEditingProvider(eventBus, canvas, directEditing, commandStack) {
42
47
  // TODO(nre): we should temporarily focus the edited element here
43
48
  // and release the focused viewport after the direct edit operation is finished
44
49
  } else {
45
- eventBus.on('create.end', 500, function(e) {
46
-
47
- var element = e.shape,
48
- canExecute = e.context.canExecute;
50
+ eventBus.on('create.end', 500, function(event) {
51
+ var element = event.shape,
52
+ canExecute = event.context.canExecute;
49
53
 
50
54
  if (!canExecute) {
51
55
  return;
@@ -53,14 +57,15 @@ function LabelEditingProvider(eventBus, canvas, directEditing, commandStack) {
53
57
 
54
58
  if (is(element, 'bpmn:Task') || is(element, 'bpmn:TextAnnotation') ||
55
59
  (is(element, 'bpmn:SubProcess') && !isExpanded(element))) {
56
-
57
60
  directEditing.activate(element);
61
+
62
+ resizeHandles.removeResizers();
58
63
  }
59
64
  });
60
65
  }
61
66
  }
62
67
 
63
- LabelEditingProvider.$inject = [ 'eventBus', 'canvas', 'directEditing', 'commandStack' ];
68
+ LabelEditingProvider.$inject = [ 'eventBus', 'canvas', 'directEditing', 'commandStack', 'resizeHandles' ];
64
69
 
65
70
  module.exports = LabelEditingProvider;
66
71
 
@@ -70,21 +75,62 @@ module.exports = LabelEditingProvider;
70
75
  *
71
76
  * @param {djs.model.Base} element
72
77
  *
73
- * @return {Object} an object with properties bounds (position and size) and text
78
+ * @return {Object} an object with properties bounds (position and size), text and options
74
79
  */
75
80
  LabelEditingProvider.prototype.activate = function(element) {
76
81
 
82
+ // text
77
83
  var text = LabelUtil.getLabel(element);
78
84
 
79
85
  if (text === undefined) {
80
86
  return;
81
87
  }
82
88
 
83
- var properties = this.getEditingBBox(element);
89
+ var context = {
90
+ text: text
91
+ };
92
+
93
+ // bounds
94
+ var bounds = this.getEditingBBox(element);
95
+
96
+ assign(context, bounds);
97
+
98
+ // options
99
+ var target = element.label || element;
100
+
101
+ var options = {};
84
102
 
85
- properties.text = text;
103
+ // tasks
104
+ if (is(element, 'bpmn:Task') ||
105
+ is(element, 'bpmn:Participant') ||
106
+ is(element, 'bpmn:Lane') ||
107
+ (is(element, 'bpmn:CallActivity') && !isExpanded(element)) ||
108
+ (is(element, 'bpmn:SubProcess') && !isExpanded(element))) {
109
+ assign(options, {
110
+ centerVertically: true
111
+ });
112
+ }
86
113
 
87
- return properties;
114
+ // external labels
115
+ if (target.labelTarget) {
116
+ assign(options, {
117
+ autoResize: true
118
+ });
119
+ }
120
+
121
+ // text annotations
122
+ if (is(element, 'bpmn:TextAnnotation')) {
123
+ assign(options, {
124
+ resizable: true,
125
+ autoResize: true
126
+ });
127
+ }
128
+
129
+ assign(context, {
130
+ options: options
131
+ });
132
+
133
+ return context;
88
134
  };
89
135
 
90
136
 
@@ -110,17 +156,36 @@ LabelEditingProvider.prototype.getEditingBBox = function(element) {
110
156
  // default position
111
157
  var bounds = { x: bbox.x, y: bbox.y };
112
158
 
113
- var style = {},
114
- zoom;
159
+ var zoom = canvas.zoom();
160
+
161
+ // take zoom into account
162
+ var smallFontSize = SMALL_FONT_SIZE * zoom,
163
+ smallLineHeight = SMALL_LINE_HEIGHT * zoom,
164
+ mediumFontSize = MEDIUM_FONT_SIZE * zoom,
165
+ mediumLineHeight = MEDIUM_LINE_HEIGHT * zoom;
166
+
167
+ var style = {};
115
168
 
116
169
  // adjust for expanded pools AND lanes
117
- if ((is(element, 'bpmn:Participant') && isExpanded(element)) || is(element, 'bpmn:Lane')) {
170
+ if ((is(element, 'bpmn:Participant') && isExpanded(element))
171
+ || is(element, 'bpmn:Lane')) {
172
+
173
+ assign(bounds, {
174
+ width: bbox.height,
175
+ height: 30 * zoom,
176
+ x: bbox.x - bbox.height / 2 + (15 * zoom),
177
+ y: mid.y - (30 * zoom) / 2
178
+ });
118
179
 
119
- bounds.width = 150;
120
- bounds.minHeight = LINE_HEIGHT + PADDING;
121
- bounds.maxHeight = LINE_HEIGHT * 2 + PADDING;
122
- bounds.x = bbox.x - bounds.width / 2;
123
- bounds.y = mid.y - bounds.minHeight / 2;
180
+ assign(style, {
181
+ fontSize: mediumFontSize + 'px',
182
+ lineHeight: mediumLineHeight + 'px',
183
+ paddingTop: (7 * zoom) + 'px',
184
+ paddingBottom: (7 * zoom) + 'px',
185
+ paddingLeft: (5 * zoom) + 'px',
186
+ paddingRight: (5 * zoom) + 'px',
187
+ transform: 'rotate(-90deg)'
188
+ });
124
189
  }
125
190
 
126
191
 
@@ -131,63 +196,97 @@ LabelEditingProvider.prototype.getEditingBBox = function(element) {
131
196
  (is(element, 'bpmn:SubProcess') && !isExpanded(element)) ||
132
197
  (is(element, 'bpmn:Participant') && !isExpanded(element))
133
198
  ) {
199
+ assign(bounds, {
200
+ width: bbox.width,
201
+ height: bbox.height
202
+ });
134
203
 
135
- zoom = canvas.zoom();
136
-
137
- // fixed size for internal labels:
138
- // on high zoom levels: text box size === bbox size
139
- // on low zoom levels: text box size === bbox size at 100% zoom
140
- // This ensures minimum bounds at low zoom levels
141
- if (zoom > 1) {
142
- bounds.width = bbox.width;
143
- bounds.height = bbox.height;
144
- } else {
145
- bounds.width = bbox.width / zoom;
146
- bounds.height = bbox.height / zoom;
147
- }
148
-
149
- // centering overlapping text box size at low zoom levels
150
- if (zoom < 1) {
151
- bounds.x = bbox.x - (bounds.width / 2 - bbox.width / 2);
152
- bounds.y = bbox.y - (bounds.height / 2 - bbox.height / 2);
153
- }
154
-
204
+ assign(style, {
205
+ fontSize: mediumFontSize + 'px',
206
+ lineHeight: mediumLineHeight + 'px',
207
+ paddingTop: (7 * zoom) + 'px',
208
+ paddingBottom: (7 * zoom) + 'px',
209
+ paddingLeft: (5 * zoom) + 'px',
210
+ paddingRight: (5 * zoom) + 'px'
211
+ });
155
212
  }
156
213
 
157
214
 
158
215
  // internal labels for expanded sub processes
159
216
  if (is(element, 'bpmn:SubProcess') && isExpanded(element)) {
217
+ assign(bounds, {
218
+ width: bbox.width,
219
+ x: bbox.x
220
+ });
160
221
 
161
- bounds.width = element.width;
162
- bounds.maxHeight = 3 * LINE_HEIGHT + PADDING; // maximum 3 lines
163
- bounds.x = mid.x - element.width / 2;
222
+ assign(style, {
223
+ fontSize: mediumFontSize + 'px',
224
+ lineHeight: mediumLineHeight + 'px',
225
+ paddingTop: (7 * zoom) + 'px',
226
+ paddingBottom: (7 * zoom) + 'px',
227
+ paddingLeft: (5 * zoom) + 'px',
228
+ paddingRight: (5 * zoom) + 'px'
229
+ });
164
230
  }
165
231
 
166
232
 
167
233
  // external labels for events, data elements, gateways and connections
168
234
  if (target.labelTarget) {
235
+ var width = 90 * zoom,
236
+ paddingTop = 7 * zoom,
237
+ paddingBottom = 4 * zoom;
238
+
239
+ assign(bounds, {
240
+ width: width,
241
+ height: bbox.height + paddingTop + paddingBottom,
242
+ x: mid.x - width / 2,
243
+ y: bbox.y - paddingTop
244
+ });
169
245
 
170
- bounds.width = 150;
171
- bounds.minHeight = LINE_HEIGHT + PADDING; // 1 line
172
- bounds.x = mid.x - bounds.width / 2;
246
+ assign(style, {
247
+ fontSize: smallFontSize + 'px',
248
+ lineHeight: smallLineHeight + 'px',
249
+ paddingTop: paddingTop + 'px',
250
+ paddingBottom: paddingBottom + 'px'
251
+ });
173
252
  }
174
253
 
175
254
 
176
255
  // text annotations
177
256
  if (is(element, 'bpmn:TextAnnotation')) {
178
- bounds.minWidth = 100;
179
- bounds.height = element.height;
257
+ assign(bounds, {
258
+ width: bbox.width,
259
+ height: bbox.height,
260
+ minWidth: 30 * zoom,
261
+ minHeight: 10 * zoom
262
+ });
180
263
 
181
- style.textAlign = 'left';
264
+ assign(style, {
265
+ textAlign: 'left',
266
+ paddingTop: (7 * zoom) + 'px',
267
+ paddingBottom: (7 * zoom) + 'px',
268
+ paddingLeft: (5 * zoom) + 'px',
269
+ paddingRight: (5 * zoom) + 'px',
270
+ fontSize: mediumFontSize + 'px',
271
+ lineHeight: mediumLineHeight + 'px'
272
+ });
182
273
  }
183
274
 
184
275
  return { bounds: bounds, style: style };
185
276
  };
186
277
 
187
278
 
188
- LabelEditingProvider.prototype.update = function(element, newLabel) {
279
+ LabelEditingProvider.prototype.update = function(element, newLabel, activeContextText, bounds) {
280
+ var absoluteElementBBox = this._canvas.getAbsoluteBBox(element);
281
+
189
282
  this._commandStack.execute('element.updateLabel', {
190
283
  element: element,
191
- newLabel: newLabel
284
+ newLabel: newLabel,
285
+ bounds: {
286
+ x: element.x,
287
+ y: element.y,
288
+ width: element.width / absoluteElementBBox.width * bounds.width,
289
+ height: element.height / absoluteElementBBox.height * bounds.height
290
+ }
192
291
  });
193
292
  };
@@ -6,7 +6,8 @@ var TextUtil = require('diagram-js/lib/util/Text');
6
6
 
7
7
  var hasExternalLabel = require('../../../util/LabelUtil').hasExternalLabel;
8
8
 
9
- var getBusinessObject = require('../../../util/ModelUtil').getBusinessObject;
9
+ var getBusinessObject = require('../../../util/ModelUtil').getBusinessObject,
10
+ is = require('../../../util/ModelUtil').is;
10
11
 
11
12
  var NULL_DIMENSIONS = {
12
13
  width: 0,
@@ -52,14 +53,17 @@ function UpdateLabelHandler(modeling) {
52
53
 
53
54
  function postExecute(ctx) {
54
55
  var element = ctx.element,
55
- label = element.label || element;
56
+ label = element.label || element,
57
+ bounds = ctx.bounds;
56
58
 
57
- // ignore internal labels
58
- if (!hasExternalLabel(element)) {
59
+ // ignore internal labels for elements except text annotations
60
+ if (!hasExternalLabel(element) && !is(element, 'bpmn:TextAnnotation')) {
59
61
  return;
60
62
  }
61
63
 
62
- var text = getBusinessObject(label).name;
64
+ var bo = getBusinessObject(label);
65
+
66
+ var text = bo.name || bo.text;
63
67
 
64
68
  if (!text) {
65
69
  return;
@@ -67,7 +71,7 @@ function UpdateLabelHandler(modeling) {
67
71
 
68
72
  // get layouted text bounds and resize external
69
73
  // external label accordingly
70
- var newBounds = getLayoutedBounds(label, text, textUtil);
74
+ var newBounds = is(element, 'bpmn:TextAnnotation') ? bounds : getLayoutedBounds(label, text, textUtil);
71
75
 
72
76
  modeling.resizeShape(label, newBounds, NULL_DIMENSIONS);
73
77
  }
@@ -2,8 +2,13 @@ module.exports = {
2
2
  __depends__: [
3
3
  require('diagram-js/lib/command'),
4
4
  require('diagram-js/lib/features/change-support'),
5
+ require('diagram-js/lib/features/resize'),
5
6
  require('diagram-js-direct-editing')
6
7
  ],
7
- __init__: [ 'labelEditingProvider' ],
8
- labelEditingProvider: [ 'type', require('./LabelEditingProvider') ]
9
- };
8
+ __init__: [
9
+ 'labelEditingProvider',
10
+ 'labelEditingPreview'
11
+ ],
12
+ labelEditingProvider: [ 'type', require('./LabelEditingProvider') ],
13
+ labelEditingPreview: [ 'type', require('./LabelEditingPreview') ]
14
+ };
@@ -74,19 +74,23 @@ function BpmnUpdater(eventBus, bpmnFactory, connectionDocking, translate) {
74
74
  self.updateParent(element, oldParent);
75
75
  }
76
76
 
77
- this.executed([ 'shape.move',
78
- 'shape.create',
79
- 'shape.delete',
80
- 'connection.create',
81
- 'connection.move',
82
- 'connection.delete' ], ifBpmn(updateParent));
83
-
84
- this.reverted([ 'shape.move',
85
- 'shape.create',
86
- 'shape.delete',
87
- 'connection.create',
88
- 'connection.move',
89
- 'connection.delete' ], ifBpmn(reverseUpdateParent));
77
+ this.executed([
78
+ 'shape.move',
79
+ 'shape.create',
80
+ 'shape.delete',
81
+ 'connection.create',
82
+ 'connection.move',
83
+ 'connection.delete'
84
+ ], ifBpmn(updateParent));
85
+
86
+ this.reverted([
87
+ 'shape.move',
88
+ 'shape.create',
89
+ 'shape.delete',
90
+ 'connection.create',
91
+ 'connection.move',
92
+ 'connection.delete'
93
+ ], ifBpmn(reverseUpdateParent));
90
94
 
91
95
  /*
92
96
  * ## Updating Parent