@jylups/cmmn-js 0.0.0-stage → 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 (103) hide show
  1. package/.babelrc +3 -0
  2. package/CHANGELOG.md +119 -0
  3. package/LICENSE +23 -0
  4. package/README.md +107 -2
  5. package/dist/assets/cmmn-font/css/cmmn-codes.css +41 -0
  6. package/dist/assets/cmmn-font/css/cmmn-embedded.css +94 -0
  7. package/dist/assets/cmmn-font/css/cmmn.css +97 -0
  8. package/dist/assets/cmmn-font/font/cmmn.eot +0 -0
  9. package/dist/assets/cmmn-font/font/cmmn.svg +90 -0
  10. package/dist/assets/cmmn-font/font/cmmn.ttf +0 -0
  11. package/dist/assets/cmmn-font/font/cmmn.woff +0 -0
  12. package/dist/assets/cmmn-font/font/cmmn.woff2 +0 -0
  13. package/dist/assets/diagram-js.css +713 -0
  14. package/dist/cmmn-modeler.development.js +44817 -0
  15. package/dist/cmmn-modeler.production.min.js +2 -0
  16. package/dist/cmmn-navigated-viewer.development.js +18131 -0
  17. package/dist/cmmn-navigated-viewer.production.min.js +2 -0
  18. package/dist/cmmn-viewer.development.js +17599 -0
  19. package/dist/cmmn-viewer.production.min.js +2 -0
  20. package/index.js +1 -0
  21. package/lib/Modeler.js +222 -0
  22. package/lib/NavigatedViewer.js +28 -0
  23. package/lib/Viewer.js +489 -0
  24. package/lib/core/ItemRegistry.js +316 -0
  25. package/lib/core/index.js +7 -0
  26. package/lib/draw/CmmnRenderer.js +1235 -0
  27. package/lib/draw/PathMap.js +335 -0
  28. package/lib/draw/index.js +5 -0
  29. package/lib/features/auto-resize/CmmnAutoResizeProvider.js +57 -0
  30. package/lib/features/auto-resize/index.js +7 -0
  31. package/lib/features/context-pad/ContextPadProvider.js +240 -0
  32. package/lib/features/context-pad/index.js +11 -0
  33. package/lib/features/editor-actions/CmmnEditorActions.js +105 -0
  34. package/lib/features/editor-actions/index.js +10 -0
  35. package/lib/features/keyboard/CmmnKeyboardBindings.js +159 -0
  36. package/lib/features/keyboard/index.js +7 -0
  37. package/lib/features/label-editing/LabelEditingProvider.js +221 -0
  38. package/lib/features/label-editing/LabelUtil.js +95 -0
  39. package/lib/features/label-editing/cmd/UpdateLabelHandler.js +63 -0
  40. package/lib/features/label-editing/index.js +9 -0
  41. package/lib/features/modeling/CmmnFactory.js +166 -0
  42. package/lib/features/modeling/CmmnLayouter.js +49 -0
  43. package/lib/features/modeling/CmmnUpdater.js +511 -0
  44. package/lib/features/modeling/ElementFactory.js +215 -0
  45. package/lib/features/modeling/Modeling.js +185 -0
  46. package/lib/features/modeling/behavior/AttachCriterionBehavior.js +58 -0
  47. package/lib/features/modeling/behavior/CaseFileItemUpdater.js +324 -0
  48. package/lib/features/modeling/behavior/LabelBehavior.js +139 -0
  49. package/lib/features/modeling/behavior/PlanItemDefinitionUpdater.js +449 -0
  50. package/lib/features/modeling/behavior/PlanningTableUpdater.js +620 -0
  51. package/lib/features/modeling/behavior/ReplaceConnectionBehavior.js +320 -0
  52. package/lib/features/modeling/behavior/ReplaceElementBehavior.js +395 -0
  53. package/lib/features/modeling/behavior/ResizeCasePlanModelBehavior.js +108 -0
  54. package/lib/features/modeling/behavior/SentryUpdater.js +678 -0
  55. package/lib/features/modeling/behavior/UnclaimIdBehavior.js +28 -0
  56. package/lib/features/modeling/behavior/index.js +24 -0
  57. package/lib/features/modeling/cmd/AppendShapeHandler.js +52 -0
  58. package/lib/features/modeling/cmd/IdClaimHandler.js +38 -0
  59. package/lib/features/modeling/cmd/ReconnectConnectionHandler.js +57 -0
  60. package/lib/features/modeling/cmd/ReplaceShapeHandler.js +46 -0
  61. package/lib/features/modeling/cmd/UpdateControlsHandler.js +221 -0
  62. package/lib/features/modeling/cmd/UpdatePropertiesHandler.js +240 -0
  63. package/lib/features/modeling/cmd/UpdateSemanticParentHandler.js +94 -0
  64. package/lib/features/modeling/index.js +20 -0
  65. package/lib/features/modeling/util/ModelingUtil.js +138 -0
  66. package/lib/features/modeling/util/PlanItemDefinitionUtil.js +183 -0
  67. package/lib/features/ordering/CmmnOrderingProvider.js +146 -0
  68. package/lib/features/ordering/index.js +4 -0
  69. package/lib/features/outline/Outline.js +47 -0
  70. package/lib/features/outline/index.js +6 -0
  71. package/lib/features/palette/PaletteProvider.js +171 -0
  72. package/lib/features/palette/index.js +12 -0
  73. package/lib/features/popup-menu/ReplaceMenuProvider.js +448 -0
  74. package/lib/features/popup-menu/index.js +4 -0
  75. package/lib/features/replace/CmmnReplace.js +355 -0
  76. package/lib/features/replace/ReplaceOptions.js +241 -0
  77. package/lib/features/replace/index.js +8 -0
  78. package/lib/features/replace-preview/CmmnReplacePreview.js +247 -0
  79. package/lib/features/replace-preview/index.js +7 -0
  80. package/lib/features/rules/CmmnRules.js +1040 -0
  81. package/lib/features/rules/index.js +7 -0
  82. package/lib/features/search/CmmnSearchProvider.js +129 -0
  83. package/lib/features/search/index.js +7 -0
  84. package/lib/features/snapping/CmmnConnectSnapping.js +110 -0
  85. package/lib/features/snapping/CmmnCreateMoveSnapping.js +148 -0
  86. package/lib/features/snapping/CmmnResizeSnapping.js +42 -0
  87. package/lib/features/snapping/CmmnSnappingUtil.js +76 -0
  88. package/lib/features/snapping/index.js +17 -0
  89. package/lib/import/CmmnImporter.js +251 -0
  90. package/lib/import/CmmnTreeWalker.js +410 -0
  91. package/lib/import/Importer.js +73 -0
  92. package/lib/import/Util.js +9 -0
  93. package/lib/import/index.js +3 -0
  94. package/lib/util/DiUtil.js +39 -0
  95. package/lib/util/LabelUtil.js +124 -0
  96. package/lib/util/ModelUtil.js +257 -0
  97. package/lib/util/PoweredByUtil.js +91 -0
  98. package/package.json +88 -4
  99. package/test/helper/index.js +231 -0
  100. package/test/util/KeyEvents.js +23 -0
  101. package/test/util/MockEvents.js +55 -0
  102. package/test/util/custom-rules/CustomRules.js +19 -0
  103. package/test/util/custom-rules/index.js +4 -0
@@ -0,0 +1,320 @@
1
+ 'use strict';
2
+
3
+ var forEach = require('min-dash').forEach,
4
+ inherits = require('inherits'),
5
+ assign = require('min-dash').assign;
6
+
7
+ var isArray = require('min-dash').isArray;
8
+
9
+ var CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor').default;
10
+
11
+ var is = require('../../../util/ModelUtil').is;
12
+
13
+ var LOW_PRIORITY = 200,
14
+ HIGH_PRIORITY = 5000;
15
+
16
+ function ReplaceConnectionBehavior(eventBus, modeling, cmmnRules, selection, rules) {
17
+
18
+ CommandInterceptor.call(this, eventBus);
19
+
20
+
21
+ function canConnectPlanItemOnPartConnection(source, target) {
22
+ return cmmnRules.canConnectPlanItemOnPartConnection(source, target);
23
+ }
24
+
25
+
26
+ function canConnectCaseFileItemOnPartConnection(source, target) {
27
+ return cmmnRules.canConnectCaseFileItemOnPartConnection(source, target);
28
+ }
29
+
30
+
31
+ function canConnectDiscretionaryConnection(source, target, connection) {
32
+ return cmmnRules.canConnectDiscretionaryConnection(source, target, connection);
33
+ }
34
+
35
+
36
+ function canConnectAssociation(source, target) {
37
+ return cmmnRules.canConnectAssociation(source, target);
38
+ }
39
+
40
+
41
+ function canReconnect(type, attrs) {
42
+ return rules.allowed(type, attrs);
43
+ }
44
+
45
+ function fixConnection(connection, source, target, hints) {
46
+
47
+ var parent = connection.parent;
48
+
49
+ hints = hints || {};
50
+ source = source || connection.source;
51
+ target = target || connection.target;
52
+
53
+ if (!parent) {
54
+ return;
55
+ }
56
+
57
+ var remove,
58
+ replacement,
59
+ cmmnElement = getCmmnElement(connection);
60
+
61
+ /**
62
+ * Check if incoming or outgoing connections can stay and/or replaced.
63
+ */
64
+
65
+ if (cmmnElement) {
66
+
67
+ if (is(cmmnElement, 'cmmn:PlanItemOnPart')) {
68
+
69
+ if (!canConnectPlanItemOnPartConnection(source, target)) {
70
+ remove = true;
71
+ }
72
+
73
+ if (canConnectCaseFileItemOnPartConnection(source, target)) {
74
+ replacement = {
75
+ type: 'cmmn:CaseFileItemOnPart',
76
+ name: cmmnElement.name,
77
+ isStandardEventVisible: isStandardEventVisible(connection)
78
+ };
79
+ }
80
+
81
+ if (canConnectDiscretionaryConnection(source, target, connection)) {
82
+ replacement = {
83
+ type: 'cmmndi:CMMNEdge'
84
+ };
85
+ }
86
+
87
+ }
88
+
89
+
90
+ if (is(cmmnElement, 'cmmn:CaseFileItemOnPart')) {
91
+
92
+ if (!canConnectCaseFileItemOnPartConnection(source, target)) {
93
+ remove = true;
94
+ }
95
+
96
+ if (canConnectPlanItemOnPartConnection(source, target)) {
97
+ replacement = {
98
+ type: 'cmmn:PlanItemOnPart',
99
+ name: cmmnElement.name,
100
+ isStandardEventVisible: isStandardEventVisible(connection)
101
+ };
102
+ }
103
+
104
+ }
105
+
106
+ if (is(cmmnElement, 'cmmn:Association') && !canConnectAssociation(source, target)) {
107
+ remove = true;
108
+ }
109
+
110
+ }
111
+ else {
112
+
113
+ if (!canConnectDiscretionaryConnection(source, target, connection)) {
114
+ remove = true;
115
+ }
116
+
117
+ if (canConnectPlanItemOnPartConnection(source, target)) {
118
+ replacement = {
119
+ type: 'cmmn:PlanItemOnPart',
120
+ isStandardEventVisible: true
121
+ };
122
+ }
123
+
124
+ }
125
+
126
+ if (remove) {
127
+
128
+ if (!replacement && (isTextAnnotation(source) || isTextAnnotation(target))) {
129
+
130
+ replacement = {
131
+ type: 'cmmn:Association'
132
+ };
133
+ }
134
+
135
+ modeling.removeConnection(connection);
136
+ }
137
+
138
+ if (replacement) {
139
+
140
+ var attrs = assign({
141
+ waypoints: connection.waypoints.slice()
142
+ }, replacement);
143
+
144
+ var newConnection = modeling.connect(source, target, attrs);
145
+
146
+ if (hints.select !== false) {
147
+ selection.select(newConnection);
148
+ }
149
+
150
+ return newConnection;
151
+
152
+ }
153
+
154
+ }
155
+
156
+
157
+ this.postExecuted('elements.move', LOW_PRIORITY, function(context) {
158
+
159
+ var closure = context.closure,
160
+ allConnections = closure.allConnections;
161
+
162
+ forEach(allConnections, function(connection) {
163
+ fixConnection(connection, null, null, {
164
+ select: false
165
+ });
166
+ });
167
+
168
+ }, true);
169
+
170
+
171
+ this.preExecute([
172
+ 'connection.reconnectEnd',
173
+ 'connection.reconnectStart'
174
+ ], HIGH_PRIORITY + LOW_PRIORITY, function(event) {
175
+
176
+ var type = event.command,
177
+ isReconnectStart = (type === 'connection.reconnectStart'),
178
+ context = event.context,
179
+ connection = context.connection,
180
+ source = context.newSource || connection.source,
181
+ target = context.newTarget || connection.target,
182
+ dockingOrPoints = context.dockingOrPoints,
183
+ canExecute = context.canExecute;
184
+
185
+ if (context.hints && context.hints.nested) {
186
+ return;
187
+ }
188
+
189
+ if (canExecute === undefined) {
190
+
191
+ var attrs = {
192
+ connection: connection
193
+ };
194
+
195
+ attrs[ isReconnectStart ? 'hover' : 'source' ] = source;
196
+ attrs[ !isReconnectStart ? 'hover' : 'target' ] = target;
197
+
198
+ canExecute = canReconnect(type, attrs);
199
+
200
+ }
201
+
202
+ if (canExecute && canExecute.reverse) {
203
+
204
+ if (!isArray(dockingOrPoints)) {
205
+ var waypoints = connection.waypoints.slice();
206
+ waypoints.splice(isReconnectStart ? 0 : -1, 1, dockingOrPoints);
207
+ dockingOrPoints = waypoints;
208
+ }
209
+
210
+ context.newSource = target;
211
+ context.newTarget = source;
212
+ context.dockingOrPoints = dockingOrPoints.reverse();
213
+
214
+ }
215
+
216
+ });
217
+
218
+
219
+ this.preExecute([
220
+ 'connection.reconnectStart',
221
+ 'connection.reconnectEnd'
222
+ ], HIGH_PRIORITY, function(context) {
223
+
224
+ var connection = context.connection,
225
+ source = context.newSource || connection.source,
226
+ target = context.newTarget || connection.target,
227
+ hints = context.hints || {};
228
+
229
+ context.connection = fixConnection(connection, source, target, {
230
+ select: !hints.nested
231
+ }) || connection;
232
+
233
+ }, true);
234
+
235
+
236
+ this.postExecuted('shape.replace', function(context) {
237
+
238
+ var shape = context.newShape,
239
+ bo = shape.businessObject,
240
+ connections = getAttachersOutgoingConnections(shape);
241
+
242
+ forEach(connections, function(connection) {
243
+
244
+ var source = connection.source,
245
+ target = connection.target,
246
+ cmmnElement = getCmmnElement(connection);
247
+
248
+ if (is(cmmnElement, 'cmmn:PlanItemOnPart')) {
249
+
250
+ if (canConnectPlanItemOnPartConnection(source, target)) {
251
+ modeling.updateProperties(cmmnElement, { sourceRef: bo }, connection);
252
+ }
253
+ else {
254
+ modeling.removeConnection(connection);
255
+ }
256
+
257
+ }
258
+
259
+ });
260
+
261
+ }, true);
262
+
263
+
264
+ this.postExecuted('element.updateProperties', function(context) {
265
+
266
+ var properties = context.properties,
267
+ changed = context.changed;
268
+
269
+ if (properties && properties.isBlocking === false) {
270
+
271
+ forEach(changed, function(shape) {
272
+
273
+ var connections = shape.outgoing;
274
+
275
+ forEach(connections, function(connection) {
276
+ fixConnection(connection, null, null, {
277
+ select: false
278
+ });
279
+ });
280
+
281
+ });
282
+
283
+ }
284
+
285
+ }, true);
286
+
287
+ }
288
+
289
+ inherits(ReplaceConnectionBehavior, CommandInterceptor);
290
+
291
+ ReplaceConnectionBehavior.$inject = [ 'eventBus', 'modeling', 'cmmnRules', 'selection', 'rules' ];
292
+
293
+ module.exports = ReplaceConnectionBehavior;
294
+
295
+
296
+ function isStandardEventVisible(connection) {
297
+ return connection.businessObject.isStandardEventVisible;
298
+ }
299
+
300
+ function getCmmnElement(connection) {
301
+ return connection.businessObject && connection.businessObject.cmmnElementRef;
302
+ }
303
+
304
+ function getAttachersOutgoingConnections(shape) {
305
+
306
+ var attachers = shape.attachers,
307
+ connections = [];
308
+
309
+ forEach(attachers, function(attacher) {
310
+ forEach(attacher.outgoing, function(connection) {
311
+ connections.push(connection);
312
+ });
313
+ });
314
+
315
+ return connections;
316
+ }
317
+
318
+ function isTextAnnotation(element) {
319
+ return is(element, 'cmmn:TextAnnotation');
320
+ }
@@ -0,0 +1,395 @@
1
+ 'use strict';
2
+
3
+ var inherits = require('inherits');
4
+
5
+ var CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor').default;
6
+
7
+ var saveClear = require('diagram-js/lib/util/Removal').saveClear;
8
+
9
+ var ModelUtil = require('../../../util/ModelUtil'),
10
+ is = ModelUtil.is,
11
+ getDefinition = ModelUtil.getDefinition,
12
+ getSentry = ModelUtil.getSentry;
13
+
14
+ var forEach = require('min-dash').forEach,
15
+ filter = require('min-dash').filter,
16
+ assign = require('min-dash').assign;
17
+
18
+ var HIGH_PRIORITY = 6000,
19
+ LOW_PRIORITY = 500,
20
+ VERY_LOW_PRIORITY = 100;
21
+
22
+
23
+ function ReplaceElementBehavior(
24
+ cmmnReplace,
25
+ cmmnRules,
26
+ elementFactory,
27
+ elementRegistry,
28
+ eventBus,
29
+ modeling,
30
+ selection,
31
+ rules
32
+ ) {
33
+
34
+ CommandInterceptor.call(this, eventBus);
35
+
36
+ this._cmmnReplace = cmmnReplace;
37
+ this._cmmnRules = cmmnRules;
38
+ this._elementFactory = elementFactory;
39
+ this._elementRegistry = elementRegistry;
40
+ this._modeling = modeling;
41
+ this._selection = selection;
42
+ this._rules = rules;
43
+
44
+ var self = this;
45
+
46
+
47
+ function canConnect(source, target) {
48
+
49
+ return rules.allowed('connection.create', {
50
+ source: source,
51
+ target: target
52
+ });
53
+
54
+ }
55
+
56
+ function canReconnect(type, attrs) {
57
+ return rules.allowed(type, attrs);
58
+ }
59
+
60
+
61
+ // SHAPES //////////////////////////////////////////////////////////////////
62
+
63
+ this.preExecute([ 'shape.create', 'shape.append' ], HIGH_PRIORITY, function(context) {
64
+
65
+ var shape = context.shape,
66
+ source = context.source,
67
+ target = context.parent || context.target || (source && source.parent),
68
+ host = context.host,
69
+ position = context.position,
70
+ hints = context.hints || {};
71
+
72
+ if (hints.nested) {
73
+ return;
74
+ }
75
+
76
+ if (host && isCriterion(shape)) {
77
+ target = host;
78
+ }
79
+
80
+ if (!cmmnRules.canCreate(shape, target, source, position)) {
81
+
82
+ var canReplace = cmmnRules.canReplace([ shape ], target, position, source);
83
+
84
+ if (canReplace && canReplace.replacements) {
85
+
86
+ var replacement = canReplace.replacements[0],
87
+ definition = getDefinition(shape),
88
+ sentry = getSentry(shape),
89
+ elementType = replacement.newElementType,
90
+ definitionType = replacement.newDefinitionType || (definition && definition.$type);
91
+
92
+ var attrs = assign({}, {
93
+ type: elementType
94
+ });
95
+
96
+ if (definitionType) {
97
+ assign(attrs, {
98
+ definitionType: definitionType
99
+ });
100
+ }
101
+
102
+ if (sentry) {
103
+ assign(attrs, {
104
+ sentryRef: sentry
105
+ });
106
+ }
107
+
108
+ context.shape = elementFactory.createShape(attrs);
109
+
110
+ }
111
+
112
+ }
113
+
114
+ }, true);
115
+
116
+
117
+ this.postExecuted('elements.move', LOW_PRIORITY, function(context) {
118
+
119
+ var target = context.newParent,
120
+ newHost = context.newHost,
121
+ elements = context.shapes.slice();
122
+
123
+ if (elements.length === 1 && newHost) {
124
+ target = newHost;
125
+ }
126
+ else {
127
+ elements = filter(elements, function(elem) {
128
+ return !isCriterion(elem);
129
+ });
130
+ }
131
+
132
+ if (target && !cmmnRules.canMove(elements, target)) {
133
+
134
+ var canReplace = cmmnRules.canReplace(elements, target);
135
+
136
+ if (canReplace && canReplace.replacements) {
137
+ self.replaceElements(elements, canReplace.replacements);
138
+ }
139
+
140
+ }
141
+
142
+ }, true);
143
+
144
+
145
+ this.postExecuted([ 'shape.replace' ], 1500, function(e) {
146
+ var context = e.context,
147
+ oldShape = context.oldShape,
148
+ newShape = context.newShape;
149
+
150
+ modeling.unclaimId(oldShape.businessObject.id, oldShape.businessObject);
151
+ modeling.updateProperties(newShape, { id: oldShape.id });
152
+ });
153
+
154
+
155
+ // CONNECTIONS /////////////////////////////////////////////////////////////////////
156
+
157
+ this.preExecute('connection.create', HIGH_PRIORITY, function(context) {
158
+
159
+ var source = context.source,
160
+ target = context.target,
161
+ canReplace = context.canExecute || canConnect(source, target);
162
+
163
+ if (canReplace && canReplace.replacements) {
164
+
165
+ var replacements = self.replaceElements([ source, target ], canReplace.replacements, {
166
+ select: false
167
+ });
168
+
169
+ context.source = replacements[source.id] || context.source;
170
+ context.target = replacements[target.id] || context.target;
171
+
172
+ // remember replaced by element in canReplace object (see 'connect.end')
173
+ assign(canReplace, {
174
+ replacedBy: !canReplace.reverse ? context.target : context.source
175
+ });
176
+
177
+ }
178
+
179
+ }, true);
180
+
181
+
182
+ eventBus.on('connect.end', LOW_PRIORITY + VERY_LOW_PRIORITY, function(e) {
183
+
184
+ var canExecute = e.context.canExecute,
185
+ replacedBy = canExecute && canExecute.replacedBy;
186
+
187
+ // if target shape has been replaced, then select the
188
+ // new element and not the old target.
189
+ if (replacedBy) {
190
+ e.context.target = replacedBy;
191
+ }
192
+
193
+ });
194
+
195
+
196
+ this.preExecute([
197
+ 'connection.reconnectStart',
198
+ 'connection.reconnectEnd'
199
+ ], HIGH_PRIORITY, function(event) {
200
+
201
+ var type = event.command,
202
+ isReconnectStart = (type === 'connection.reconnectStart'),
203
+ context = event.context,
204
+ connection = context.connection,
205
+ source = context.newSource || connection.source,
206
+ target = context.newTarget || connection.target,
207
+ attrs = { connection: connection },
208
+ canReplace;
209
+
210
+ if (context.hints && context.hints.nested) {
211
+ return;
212
+ }
213
+
214
+ attrs[ isReconnectStart ? 'hover' : 'source' ] = source;
215
+ attrs[ !isReconnectStart ? 'hover' : 'target' ] = target;
216
+
217
+ canReplace = canReconnect(type, attrs);
218
+
219
+ if (canReplace && canReplace.replacements) {
220
+ var replacements = self.replaceElements([ source, target ], canReplace.replacements, {
221
+ select: false
222
+ });
223
+
224
+ context.newSource = replacements[source.id] || context.newSource;
225
+ context.newTarget = replacements[target.id] || context.newTarget;
226
+ }
227
+
228
+ // remember result in context, so that this can be re-used
229
+ context.canExecute = canReplace;
230
+
231
+ });
232
+
233
+
234
+ this.preExecute('shape.delete', HIGH_PRIORITY, function(context) {
235
+
236
+ var shape = context.shape,
237
+ parent = isCriterion(shape) ? shape.host : shape.parent,
238
+ definition = getDefinition(parent);
239
+
240
+ // if the shape to delete is contained by a plan fragment (and not stage)
241
+ // then remove incoming connections. Thereby an additional hint is provided
242
+ // to the context, so that shape delete is not replaced when the connection
243
+ // is deleted.
244
+
245
+ if (is(definition, 'cmmn:Stage')) {
246
+ return;
247
+ }
248
+
249
+ saveClear(shape.incoming, function(connection) {
250
+ modeling.removeConnection(connection, { nested: true, endChanged: true });
251
+ });
252
+
253
+ }, true);
254
+
255
+
256
+ this.postExecuted([
257
+ 'connection.delete',
258
+ 'connection.reconnectEnd'
259
+ ], LOW_PRIORITY, function(context) {
260
+
261
+ var shape = context.target || context.oldTarget,
262
+ elements = [ shape ],
263
+ target = isCriterion(shape) ? shape.host : shape.parent,
264
+ hints = context.hints || {};
265
+
266
+ if (hints.endChanged) {
267
+ return;
268
+ }
269
+
270
+ if (target && !cmmnRules.canMove(elements, target)) {
271
+
272
+ var canReplace = cmmnRules.canReplace(elements, target);
273
+
274
+ if (canReplace && canReplace.replacements) {
275
+ self.replaceElements(elements, canReplace.replacements, { select: false });
276
+ }
277
+
278
+ }
279
+
280
+ }, true);
281
+
282
+
283
+ // PROPERTIES /////////////////////////////////////////////////////////////////////
284
+
285
+ this.postExecuted('element.updateProperties', function(context) {
286
+
287
+ var properties = context.properties,
288
+ changed = context.changed;
289
+
290
+ if (properties && properties.isBlocking === false) {
291
+
292
+ forEach(changed, function(shape) {
293
+
294
+ var attachers = shape.attachers,
295
+ canReplace = cmmnRules.canReplace(attachers, shape);
296
+
297
+ if (canReplace) {
298
+ self.replaceElements(attachers, canReplace.replacements, { select: false });
299
+ }
300
+ });
301
+
302
+ }
303
+
304
+ }, true);
305
+
306
+
307
+ // API ///////////////////////////////////////////////////////////////////////////
308
+
309
+ this.replaceElements = function(elements, newElements, hints) {
310
+
311
+ var self = this;
312
+
313
+ var elementRegistry = this._elementRegistry,
314
+ selection = this._selection;
315
+
316
+ var executedReplacements = {};
317
+
318
+ hints = hints || {};
319
+
320
+ forEach(newElements, function(replacement) {
321
+
322
+ var oldElement = elementRegistry.get(replacement.oldElementId),
323
+ idx = elements.indexOf(oldElement),
324
+ replacedBy;
325
+
326
+ if (!oldElement) {
327
+ return;
328
+ }
329
+
330
+ replacedBy = self.replaceElement(oldElement, replacement);
331
+
332
+ if (idx !== -1) {
333
+ elements[idx] = replacedBy;
334
+ }
335
+
336
+ executedReplacements[oldElement.id] = replacedBy;
337
+
338
+ });
339
+
340
+ if (newElements && hints.select !== false) {
341
+ selection.select(elements);
342
+ }
343
+
344
+ return executedReplacements;
345
+
346
+ };
347
+
348
+
349
+ this.replaceElement = function(element, replacement) {
350
+
351
+ var cmmnReplace = this._cmmnReplace;
352
+
353
+ var definition = getDefinition(element),
354
+ definitionType = replacement.newDefinitionType || (definition && definition.$type);
355
+
356
+ if (!element) {
357
+ return;
358
+ }
359
+
360
+ var newElement = {
361
+ type: replacement.newElementType
362
+ };
363
+
364
+ if (definitionType) {
365
+ assign(newElement, {
366
+ definitionType: definitionType
367
+ });
368
+ }
369
+
370
+ return cmmnReplace.replaceElement(element, newElement, { select: false });
371
+
372
+ };
373
+
374
+ }
375
+
376
+
377
+ ReplaceElementBehavior.$inject = [
378
+ 'cmmnReplace',
379
+ 'cmmnRules',
380
+ 'elementFactory',
381
+ 'elementRegistry',
382
+ 'eventBus',
383
+ 'modeling',
384
+ 'selection',
385
+ 'rules'
386
+ ];
387
+
388
+ inherits(ReplaceElementBehavior, CommandInterceptor);
389
+
390
+ module.exports = ReplaceElementBehavior;
391
+
392
+
393
+ function isCriterion(element) {
394
+ return is(element, 'cmmn:Criterion');
395
+ }