@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,251 @@
1
+ 'use strict';
2
+
3
+ var assign = require('min-dash').assign,
4
+ map = require('min-dash').map;
5
+
6
+ var LabelUtil = require('../util/LabelUtil');
7
+
8
+ var is = require('../util/ModelUtil').is;
9
+
10
+ var hasExternalLabel = LabelUtil.hasExternalLabel,
11
+ getExternalLabelBounds = LabelUtil.getExternalLabelBounds,
12
+ isCollapsed = require('../util/DiUtil').isCollapsed,
13
+ elementToString = require('./Util').elementToString;
14
+
15
+
16
+ function elementData(semantic, attrs) {
17
+ return assign({
18
+ id: semantic.id,
19
+ type: semantic.$type,
20
+ businessObject: semantic
21
+ }, attrs);
22
+ }
23
+
24
+ function collectWaypoints(waypoints) {
25
+ return map(waypoints, function(p) {
26
+ return { x: p.x, y: p.y };
27
+ });
28
+ }
29
+
30
+ function notYetDrawn(semantic, refSemantic, property) {
31
+ return new Error(
32
+ 'element ' + elementToString(refSemantic) + ' referenced by ' +
33
+ elementToString(semantic) + '#' + property + ' not yet drawn');
34
+ }
35
+
36
+ /**
37
+ * An importer that adds cmmn elements to the canvas
38
+ *
39
+ * @param {EventBus} eventBus
40
+ * @param {Canvas} canvas
41
+ * @param {ElementFactory} elementFactory
42
+ * @param {ElementRegistry} elementRegistry
43
+ */
44
+ function CmmnImporter(eventBus, canvas, elementFactory, elementRegistry) {
45
+ this._eventBus = eventBus;
46
+ this._canvas = canvas;
47
+
48
+ this._elementFactory = elementFactory;
49
+ this._elementRegistry = elementRegistry;
50
+ }
51
+
52
+ CmmnImporter.$inject = [ 'eventBus', 'canvas', 'elementFactory', 'elementRegistry' ];
53
+
54
+ module.exports = CmmnImporter;
55
+
56
+
57
+ /**
58
+ * Set the diagram as root element
59
+ */
60
+ CmmnImporter.prototype.root = function(diagram) {
61
+ var element = this._elementFactory.createRoot(elementData(diagram));
62
+
63
+ this._canvas.setRootElement(element);
64
+
65
+ return element;
66
+ };
67
+
68
+
69
+ /**
70
+ * Add cmmn element (semantic) to the canvas onto the
71
+ * specified parent shape.
72
+ */
73
+ CmmnImporter.prototype.add = function(semantic, parentElement) {
74
+
75
+ var di = semantic.di,
76
+ element,
77
+ hidden;
78
+
79
+ // SHAPE
80
+ if (di && is(di, 'cmmndi:CMMNShape') && !this._getElement(semantic)) {
81
+
82
+ var collapsed = isCollapsed(semantic);
83
+
84
+ hidden = parentElement && (parentElement.hidden || parentElement.collapsed);
85
+
86
+ var bounds = semantic.di.bounds;
87
+
88
+ element = this._elementFactory.createShape(elementData(semantic, {
89
+ collapsed: collapsed,
90
+ hidden: hidden,
91
+ x: Math.round(bounds.x),
92
+ y: Math.round(bounds.y),
93
+ width: Math.round(bounds.width),
94
+ height: Math.round(bounds.height)
95
+ }));
96
+
97
+ if (is(semantic, 'cmmn:Criterion')) {
98
+ this._attachCriterion(semantic, element);
99
+ }
100
+
101
+ this._canvas.addShape(element, parentElement);
102
+ }
103
+
104
+ // CONNECTION
105
+ else if ((di && is(di, 'cmmndi:CMMNEdge')) || is(semantic, 'cmmndi:CMMNEdge')) {
106
+
107
+ var source = this._getSource(semantic),
108
+ target = this._getTarget(semantic);
109
+
110
+ hidden = (parentElement && (parentElement.hidden || parentElement.collapsed)) ||
111
+ (source && source.hidden) ||
112
+ (target && target.hidden) ;
113
+
114
+ var waypoint = (semantic.di || {}).waypoint || semantic.waypoint;
115
+
116
+ element = this._elementFactory.createConnection(elementData(semantic, {
117
+ hidden: hidden,
118
+ source: source,
119
+ target: target,
120
+ waypoints: collectWaypoints(waypoint)
121
+ }));
122
+
123
+ this._canvas.addConnection(element, parentElement);
124
+ } else {
125
+ throw new Error('unknown di ' + elementToString(di) + ' for element ' + elementToString(semantic));
126
+ }
127
+
128
+ // (optional) LABEL
129
+ if (hasExternalLabel(semantic)) {
130
+ this.addLabel(semantic, element);
131
+ }
132
+
133
+ this._eventBus.fire('cmmnElement.added', { element: element });
134
+
135
+ return element;
136
+ };
137
+
138
+
139
+ /**
140
+ * Attach the criterion element to the given host
141
+ *
142
+ * @param {ModdleElement} criterionSemantic
143
+ * @param {djs.model.Base} criterionElement
144
+ */
145
+ CmmnImporter.prototype._attachCriterion = function(criterionSemantic, criterionElement) {
146
+ var hostSemantic = criterionSemantic.$parent;
147
+
148
+ if (!hostSemantic) {
149
+ throw new Error('missing ' + elementToString(criterionSemantic) + '$parent');
150
+ }
151
+
152
+ var host = this._elementRegistry.get(hostSemantic.id),
153
+ attachers = host && host.attachers;
154
+
155
+ if (!host) {
156
+ throw notYetDrawn(criterionSemantic, hostSemantic, 'criterion');
157
+ }
158
+
159
+ // wire element.host <> host.attachers
160
+ criterionElement.host = host;
161
+
162
+ if (!attachers) {
163
+ host.attachers = attachers = [];
164
+ }
165
+
166
+ if (attachers.indexOf(criterionElement) === -1) {
167
+ attachers.push(criterionElement);
168
+ }
169
+ };
170
+
171
+
172
+ /**
173
+ * add label for an element
174
+ */
175
+ CmmnImporter.prototype.addLabel = function(semantic, element) {
176
+ var bounds = getExternalLabelBounds(semantic, element);
177
+
178
+ var label = this._elementFactory.createLabel(elementData(semantic, {
179
+ id: semantic.id + '_label',
180
+ labelTarget: element,
181
+ type: 'label',
182
+ hidden: element.hidden,
183
+ x: Math.round(bounds.x),
184
+ y: Math.round(bounds.y),
185
+ width: Math.round(bounds.width),
186
+ height: Math.round(bounds.height)
187
+ }));
188
+
189
+ return this._canvas.addShape(label, element.parent);
190
+ };
191
+
192
+ CmmnImporter.prototype._getSource = function(semantic) {
193
+ var cmmnElement = semantic.cmmnElementRef;
194
+
195
+ if (cmmnElement) {
196
+
197
+ if (is(cmmnElement, 'cmmn:OnPart')) {
198
+
199
+ if (cmmnElement.exitCriterionRef) {
200
+ return this._getEnd(cmmnElement, 'exitCriterionRef');
201
+ }
202
+
203
+ return this._getEnd(cmmnElement, 'sourceRef');
204
+
205
+ }
206
+
207
+ if (is(cmmnElement, 'cmmn:Association')) {
208
+ return this._getEnd(cmmnElement, 'sourceRef');
209
+ }
210
+
211
+ }
212
+
213
+ if (is(semantic, 'cmmndi:CMMNEdge')) {
214
+ return this._getEnd(semantic, 'sourceCMMNElementRef');
215
+ }
216
+
217
+ };
218
+
219
+ CmmnImporter.prototype._getTarget = function(semantic) {
220
+ var cmmnElement = semantic.cmmnElementRef;
221
+
222
+ if (cmmnElement) {
223
+
224
+ if (is(cmmnElement, 'cmmn:Association')) {
225
+ return this._getEnd(cmmnElement, 'targetRef');
226
+ }
227
+
228
+ }
229
+
230
+ return this._getEnd(semantic, 'targetCMMNElementRef');
231
+ };
232
+
233
+ CmmnImporter.prototype._getEnd = function(semantic, side) {
234
+ var refSemantic = semantic[side];
235
+ var element = refSemantic && this._getElement(refSemantic);
236
+
237
+ if (element) {
238
+ return element;
239
+ }
240
+
241
+ if (refSemantic) {
242
+ throw notYetDrawn(semantic, refSemantic, side);
243
+ } else {
244
+ throw new Error(elementToString(semantic) + '#' + side + 'Ref not specified');
245
+ }
246
+
247
+ };
248
+
249
+ CmmnImporter.prototype._getElement = function(semantic) {
250
+ return this._elementRegistry.get(semantic.id);
251
+ };
@@ -0,0 +1,410 @@
1
+ 'use strict';
2
+
3
+ var forEach = require('min-dash').forEach,
4
+ filter = require('min-dash').filter;
5
+
6
+ var Refs = require('object-refs');
7
+
8
+ var elementToString = require('./Util').elementToString;
9
+ var is = require('../util/ModelUtil').is;
10
+
11
+ var Collections = require('diagram-js/lib/util/Collections');
12
+
13
+ var diRefs = new Refs({ name: 'cmmnElement', enumerable: true }, { name: 'di' });
14
+
15
+
16
+ function CmmnTreeWalker(handler) {
17
+
18
+ // list of elements to handle deferred to ensure
19
+ // prerequisites are drawn
20
+ var deferred = [];
21
+
22
+ // list of CMMNEdges which cmmnElementRef is equals null:
23
+ // - it is a connection which does not have a representation
24
+ // in case plan model
25
+ // - it is a connection between a human (plan item) task and a
26
+ // discretionary item
27
+ var connections = [];
28
+
29
+ var discretionaryConnections = {};
30
+
31
+ // list of cases to draw
32
+ var cases = [];
33
+
34
+ var handledDiscretionaryItems = {};
35
+
36
+ // list of elements (textAnnotations and caseFileItems)
37
+ var elementsWithoutParent = [];
38
+
39
+ var associations = [];
40
+
41
+ // Helpers /////////////////
42
+
43
+ function isDiscretionaryItemHandled(item) {
44
+ return !!handledDiscretionaryItems[item.id];
45
+ }
46
+
47
+ function handledDiscretionaryItem(item) {
48
+ handledDiscretionaryItems[item.id] = item;
49
+ }
50
+
51
+ /**
52
+ * Returns the surrounding 'cmmn:Case' element
53
+ *
54
+ * @param {ModdleElement} element
55
+ *
56
+ * @return {ModdleElement} the surrounding case
57
+ */
58
+ function getCase(element) {
59
+ while (element && !is(element, 'cmmn:Case')) {
60
+ element = element.$parent;
61
+ }
62
+ return element;
63
+ }
64
+
65
+ function visit(element, ctx) {
66
+ // call handler
67
+ return handler.element(element, ctx);
68
+ }
69
+
70
+ function visitRoot(element, diagram) {
71
+ return handler.root(element, diagram);
72
+ }
73
+
74
+ function visitIfDi(element, ctx) {
75
+ try {
76
+ handler.addItem(element);
77
+ return element.di && visit(element, ctx);
78
+ } catch (e) {
79
+ logError(e.message, { element: element, error: e });
80
+
81
+ console.error('failed to import ' + elementToString(element));
82
+ console.error(e);
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Visit an edge (connection, association or discretionary connection).
88
+ *
89
+ * Errors, for example an edge that references an element which is not
90
+ * drawn, are reported as import warnings so that a single broken edge
91
+ * does not stop the import of the rest of the diagram.
92
+ */
93
+ function visitEdge(edge, ctx) {
94
+ try {
95
+ return visit(edge, ctx);
96
+ } catch (e) {
97
+ logError(e.message, { element: edge, error: e });
98
+
99
+ console.error('failed to import ' + elementToString(edge));
100
+ console.error(e);
101
+ }
102
+ }
103
+
104
+ function logError(message, context) {
105
+ handler.error(message, context);
106
+ }
107
+
108
+
109
+ function contextual(fn, ctx) {
110
+ return function(e) {
111
+ fn(e, ctx);
112
+ };
113
+ }
114
+
115
+ // DI handling /////////////////
116
+
117
+ function registerDi(di) {
118
+
119
+ var cmmnElement = di.cmmnElementRef;
120
+
121
+ if (cmmnElement && !is(di, 'cmmndi:CMMNEdge')) {
122
+
123
+ if (cmmnElement.di) {
124
+ logError('multiple DI elements defined for ' + elementToString(cmmnElement), { element: cmmnElement });
125
+ }
126
+ else {
127
+
128
+ var _case = getCase(cmmnElement);
129
+ if (_case && cases.indexOf(_case) === -1) {
130
+ // add _case to the list of cases
131
+ // that should be drawn
132
+ cases.push(_case);
133
+ }
134
+
135
+ if (is(cmmnElement, 'cmmn:TextAnnotation') || is(cmmnElement, 'cmmn:CaseFileItem')) {
136
+ elementsWithoutParent.push(cmmnElement);
137
+ }
138
+
139
+ diRefs.bind(cmmnElement, 'di');
140
+ cmmnElement.di = di;
141
+ }
142
+
143
+ }
144
+ else if (is(di, 'cmmndi:CMMNEdge')) {
145
+ var shouldHandle = true;
146
+
147
+ if (!isReferencingTarget(di)) {
148
+ shouldHandle = false;
149
+ logError('no target referenced in ' + elementToString(di), { element: di });
150
+ }
151
+
152
+ if (!isReferencingSource(di)) {
153
+ shouldHandle = false;
154
+ logError('no source referenced in ' + elementToString(di), { element: di });
155
+ }
156
+
157
+ if (shouldHandle) {
158
+
159
+ if (is(cmmnElement, 'cmmn:Association')) {
160
+ associations.push(di);
161
+ }
162
+ else if (!cmmnElement) {
163
+ var source = di.sourceCMMNElementRef;
164
+ discretionaryConnections[source.id] = discretionaryConnections[source.id] || [];
165
+ discretionaryConnections[source.id].push(di);
166
+ }
167
+ else {
168
+ connections.push(function(ctx) {
169
+ handleConnection(di, ctx);
170
+ });
171
+ }
172
+ }
173
+
174
+ }
175
+ else {
176
+ logError('no cmmnElement referenced in ' + elementToString(di), { element: di });
177
+ }
178
+ }
179
+
180
+ function isReferencingTarget(edge) {
181
+ if (is(edge.cmmnElementRef, 'cmmn:Association')) {
182
+ return !!edge.cmmnElementRef.targetRef;
183
+ }
184
+
185
+ return !!edge.targetCMMNElementRef;
186
+ }
187
+
188
+ function isReferencingSource(edge) {
189
+ if (is(edge.cmmnElementRef, 'cmmn:OnPart')) {
190
+ return !!(edge.cmmnElementRef.exitCriterionRef || edge.cmmnElementRef.sourceRef);
191
+ }
192
+
193
+ if (is(edge.cmmnElementRef, 'cmmn:Association')) {
194
+ return !!edge.cmmnElementRef.sourceRef;
195
+ }
196
+
197
+ return !!edge.sourceCMMNElementRef;
198
+ }
199
+
200
+ function handleConnection(connection, context) {
201
+ visitEdge(connection, context);
202
+ }
203
+
204
+ function handleDiagram(diagram) {
205
+ handleDiagramElements(diagram.diagramElements);
206
+ }
207
+
208
+ function handleDiagramElements(diagramElements) {
209
+ forEach(diagramElements, handleDiagramElement);
210
+ }
211
+
212
+ function handleDiagramElement(diagramElement) {
213
+ registerDi(diagramElement);
214
+ }
215
+
216
+ // Semantic handling /////////////////
217
+
218
+ function handleDefinitions(definitions, diagram) {
219
+ // make sure we walk the correct cmmnElement
220
+
221
+ var cmmndi = definitions.CMMNDI;
222
+
223
+ // no di -> nothing to import
224
+ if (!cmmndi) {
225
+ return;
226
+ }
227
+
228
+ var diagrams = cmmndi.diagrams;
229
+
230
+ if (diagram && diagrams.indexOf(diagram) === -1) {
231
+ throw new Error('diagram not part of cmmn:Definitions');
232
+ }
233
+
234
+ if (!diagram && diagrams && diagrams.length) {
235
+ diagram = diagrams[0];
236
+ }
237
+
238
+ // handle only the first diagram and ignore others
239
+ handleDiagram(diagram);
240
+
241
+ var context = visitRoot(diagram, diagram);
242
+
243
+ handleCases(cases, context);
244
+
245
+ forEach(elementsWithoutParent, contextual(handleElementWithoutParent));
246
+ forEach(associations, contextual(handleAssociation));
247
+ }
248
+
249
+ function handleCases(cases, context) {
250
+ forEach(cases, function(_case) {
251
+ handleCase(_case, context);
252
+
253
+ // clear collections for the next iteration
254
+ deferred = [];
255
+ connections = [];
256
+ });
257
+ }
258
+
259
+ function handleCase(_case, context) {
260
+ var casePlanModel = _case.casePlanModel;
261
+
262
+ var casePlanModelContext;
263
+ if (casePlanModel) {
264
+ casePlanModelContext = handleCasePlanModel(casePlanModel, context);
265
+ }
266
+
267
+ handleDeferred(deferred);
268
+
269
+ forEach(connections, function(d) { d(casePlanModelContext); });
270
+
271
+ }
272
+
273
+ function handleCasePlanModel(casePlanModel, context) {
274
+ var newCtx = visitIfDi(casePlanModel, context);
275
+
276
+ forEach(casePlanModel.exitCriteria, contextual(handleCriterion, newCtx));
277
+
278
+ handlePlanFragment(casePlanModel, newCtx);
279
+ handleElementsWithoutParent(casePlanModel, newCtx);
280
+
281
+ return newCtx;
282
+ }
283
+
284
+ function handleDeferred(deferred) {
285
+ forEach(deferred, function(d) { d(); });
286
+ }
287
+
288
+ function handlePlanFragment(planFragment, context) {
289
+ handlePlanItems(planFragment.planItems, context);
290
+
291
+ if (is(planFragment, 'cmmn:Stage')) {
292
+ handleStage(planFragment, context);
293
+ }
294
+ }
295
+
296
+ function handleStage(stage, context) {
297
+ handlePlanningTable(stage.planningTable, context);
298
+ }
299
+
300
+ function handlePlanningTable(planningTable, context) {
301
+ if (planningTable) {
302
+ forEach(planningTable.tableItems, function(tableItem) {
303
+ if (is(tableItem, 'cmmn:DiscretionaryItem')) {
304
+ handleDiscretionaryItem(tableItem, context);
305
+ }
306
+ else if (is(tableItem, 'cmmn:PlanningTable')) {
307
+ handlePlanningTable(tableItem, context);
308
+ }
309
+ });
310
+ }
311
+ }
312
+
313
+ function handleDiscretionaryItem(discretionayItem, context) {
314
+ if (isDiscretionaryItemHandled(discretionayItem)) {
315
+ return;
316
+ }
317
+
318
+ handledDiscretionaryItem(discretionayItem);
319
+ handleItem(discretionayItem, context);
320
+ }
321
+
322
+ function handlePlanItems(planItems, context) {
323
+ forEach(planItems, contextual(handleItem, context));
324
+ }
325
+
326
+ function handleItem(item, context) {
327
+ var newCtx = visitIfDi(item, context);
328
+
329
+ forEach(item.exitCriteria, contextual(handleCriterion, context));
330
+ forEach(item.entryCriteria, contextual(handleCriterion, context));
331
+
332
+ var definitionRef = item.definitionRef;
333
+ if (is(definitionRef, 'cmmn:PlanFragment')) {
334
+ handlePlanFragment(definitionRef, newCtx);
335
+ handleElementsWithoutParent(item, newCtx);
336
+ }
337
+ else if (is(definitionRef, 'cmmn:HumanTask')) {
338
+ handlePlanningTable(definitionRef.planningTable, context);
339
+
340
+ var edges = discretionaryConnections[item.id];
341
+ forEach(edges, contextual(handleDiscretionaryConnection, context));
342
+ delete discretionaryConnections[item.id];
343
+
344
+ }
345
+ }
346
+
347
+ function handleCriterion(criterion, context) {
348
+ deferred.unshift(function() {
349
+ visitIfDi(criterion, context);
350
+ });
351
+ }
352
+
353
+ function handleElementsWithoutParent(container, context) {
354
+
355
+ if (container.di && container.di.bounds) {
356
+ var elements = getEnclosedElements(elementsWithoutParent, container);
357
+
358
+ forEach(elements, function(e) {
359
+ Collections.remove(elementsWithoutParent, e);
360
+ handleElementWithoutParent(e, context);
361
+ });
362
+ }
363
+
364
+ }
365
+
366
+ function handleElementWithoutParent(element, context) {
367
+ if (is(element, 'cmmn:TextAnnotation')) {
368
+ handleTextAnnotation(element, context);
369
+ }
370
+ else if (is(element, 'cmmn:CaseFileItem')) {
371
+ handleCaseFileItem(element, context);
372
+ }
373
+ }
374
+
375
+ function handleCaseFileItem(caseFileItem, context) {
376
+ visitIfDi(caseFileItem, context);
377
+ }
378
+
379
+ function handleTextAnnotation(annotation, context) {
380
+ visitIfDi(annotation, context);
381
+ }
382
+
383
+ function handleAssociation(association, context) {
384
+ visitEdge(association, context);
385
+ }
386
+
387
+ function handleDiscretionaryConnection(connection, context) {
388
+ deferred.push(function() {
389
+ visitEdge(connection, context);
390
+ });
391
+ }
392
+
393
+ function getEnclosedElements(elements, container) {
394
+ var bounds = container.di.bounds;
395
+ return filter(elements, function(e) {
396
+ return e.di.bounds.x > bounds.x &&
397
+ e.di.bounds.x < (bounds.x + bounds.width) &&
398
+ e.di.bounds.y > bounds.y &&
399
+ e.di.bounds.y < (bounds.y + bounds.height);
400
+ });
401
+ }
402
+
403
+ // API /////////////////
404
+
405
+ return {
406
+ handleDefinitions: handleDefinitions
407
+ };
408
+ }
409
+
410
+ module.exports = CmmnTreeWalker;