bpmn-js 9.0.0-subprocesses.1 → 9.0.1

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 (50) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/dist/assets/bpmn-js.css +69 -14
  3. package/dist/assets/diagram-js.css +81 -78
  4. package/dist/bpmn-modeler.development.js +2897 -1810
  5. package/dist/bpmn-modeler.production.min.js +8 -8
  6. package/dist/bpmn-navigated-viewer.development.js +1458 -1101
  7. package/dist/bpmn-navigated-viewer.production.min.js +6 -6
  8. package/dist/bpmn-viewer.development.js +1457 -1100
  9. package/dist/bpmn-viewer.production.min.js +6 -6
  10. package/lib/BaseViewer.js +1 -1
  11. package/lib/Viewer.js +2 -2
  12. package/lib/draw/BpmnRenderer.js +303 -373
  13. package/lib/features/auto-resize/BpmnAutoResizeProvider.js +6 -0
  14. package/lib/features/copy-paste/BpmnCopyPaste.js +1 -0
  15. package/lib/features/di-ordering/BpmnDiOrdering.js +15 -11
  16. package/lib/features/drilldown/DrilldownBreadcrumbs.js +122 -0
  17. package/lib/features/drilldown/DrilldownCentering.js +118 -0
  18. package/lib/features/drilldown/DrilldownOverlayBehavior.js +181 -0
  19. package/lib/features/drilldown/SubprocessCompatibility.js +201 -0
  20. package/lib/features/drilldown/index.js +17 -0
  21. package/lib/features/label-editing/LabelEditingProvider.js +1 -1
  22. package/lib/features/label-editing/cmd/UpdateLabelHandler.js +29 -2
  23. package/lib/features/modeling/BpmnFactory.js +5 -1
  24. package/lib/features/modeling/BpmnUpdater.js +43 -1
  25. package/lib/features/modeling/ElementFactory.js +4 -0
  26. package/lib/features/modeling/behavior/CreateParticipantBehavior.js +59 -84
  27. package/lib/features/modeling/behavior/DropOnFlowBehavior.js +2 -2
  28. package/lib/features/modeling/behavior/RemoveEmbeddedLabelBoundsBehavior.js +34 -0
  29. package/lib/features/modeling/behavior/SubProcessPlaneBehavior.js +557 -0
  30. package/lib/features/modeling/behavior/ToggleCollapseConnectionBehaviour.js +74 -0
  31. package/lib/features/modeling/behavior/UnclaimIdBehavior.js +3 -1
  32. package/lib/features/modeling/behavior/index.js +27 -18
  33. package/lib/features/modeling/cmd/SetColorHandler.js +23 -6
  34. package/lib/features/modeling/cmd/UpdateCanvasRootHandler.js +4 -2
  35. package/lib/features/modeling/util/ModelingUtil.js +2 -20
  36. package/lib/features/ordering/BpmnOrderingProvider.js +3 -3
  37. package/lib/features/palette/PaletteProvider.js +1 -1
  38. package/lib/features/popup-menu/ReplaceMenuProvider.js +1 -1
  39. package/lib/import/BpmnImporter.js +17 -60
  40. package/lib/import/Importer.js +130 -10
  41. package/lib/util/DrilldownUtil.js +66 -0
  42. package/lib/util/ModelUtil.js +19 -0
  43. package/package.json +2 -2
  44. package/test/helper/index.js +1 -6
  45. package/lib/features/subprocess-navigation/SubprocessCentering.js +0 -55
  46. package/lib/features/subprocess-navigation/SubprocessCompatibility.js +0 -135
  47. package/lib/features/subprocess-navigation/SubprocessElements.js +0 -55
  48. package/lib/features/subprocess-navigation/SubprocessFlows.js +0 -109
  49. package/lib/features/subprocess-navigation/SubprocessOverlays.js +0 -104
  50. package/lib/features/subprocess-navigation/index.js +0 -18
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * bpmn-js - bpmn-navigated-viewer v9.0.0-subprocesses.1
2
+ * bpmn-js - bpmn-navigated-viewer v9.0.1
3
3
  *
4
4
  * Copyright (c) 2014-present, camunda Services GmbH
5
5
  *
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * Source Code: https://github.com/bpmn-io/bpmn-js
10
10
  *
11
- * Date: 2021-10-26
11
+ * Date: 2022-02-18
12
12
  */
13
13
  (function (global, factory) {
14
14
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
@@ -207,6 +207,23 @@
207
207
  function some(collection, matcher) {
208
208
  return !!find(collection, matcher);
209
209
  }
210
+ /**
211
+ * Transform a collection into another collection
212
+ * by piping each member through the given fn.
213
+ *
214
+ * @param {Object|Array} collection
215
+ * @param {Function} fn
216
+ *
217
+ * @return {Array} transformed collection
218
+ */
219
+
220
+ function map$1(collection, fn) {
221
+ var result = [];
222
+ forEach(collection, function (val, key) {
223
+ result.push(fn(val, key));
224
+ });
225
+ return result;
226
+ }
210
227
  /**
211
228
  * Create an object pattern matcher.
212
229
  *
@@ -214,7 +231,7 @@
214
231
  *
215
232
  * const matcher = matchPattern({ id: 1 });
216
233
  *
217
- * var element = find(elements, matcher);
234
+ * let element = find(elements, matcher);
218
235
  *
219
236
  * @param {Object} pattern
220
237
  *
@@ -244,8 +261,11 @@
244
261
  }
245
262
 
246
263
  /**
247
- * Debounce fn, calling it only once if
248
- * the given time elapsed between calls.
264
+ * Debounce fn, calling it only once if the given time
265
+ * elapsed between calls.
266
+ *
267
+ * Lodash-style the function exposes methods to `#clear`
268
+ * and `#flush` to control internal behavior.
249
269
  *
250
270
  * @param {Function} fn
251
271
  * @param {Number} timeout
@@ -258,23 +278,39 @@
258
278
  var lastThis;
259
279
  var lastNow;
260
280
 
261
- function fire() {
281
+ function fire(force) {
262
282
  var now = Date.now();
263
- var scheduledDiff = lastNow + timeout - now;
283
+ var scheduledDiff = force ? 0 : lastNow + timeout - now;
264
284
 
265
285
  if (scheduledDiff > 0) {
266
286
  return schedule(scheduledDiff);
267
287
  }
268
288
 
269
289
  fn.apply(lastThis, lastArgs);
270
- timer = lastNow = lastArgs = lastThis = undefined;
290
+ clear();
271
291
  }
272
292
 
273
293
  function schedule(timeout) {
274
294
  timer = setTimeout(fire, timeout);
275
295
  }
276
296
 
277
- return function () {
297
+ function clear() {
298
+ if (timer) {
299
+ clearTimeout(timer);
300
+ }
301
+
302
+ timer = lastNow = lastArgs = lastThis = undefined;
303
+ }
304
+
305
+ function flush() {
306
+ if (timer) {
307
+ fire(true);
308
+ }
309
+
310
+ clear();
311
+ }
312
+
313
+ function callback() {
278
314
  lastNow = Date.now();
279
315
 
280
316
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
@@ -287,7 +323,11 @@
287
323
  if (!timer) {
288
324
  schedule(timeout);
289
325
  }
290
- };
326
+ }
327
+
328
+ callback.flush = flush;
329
+ callback.cancel = clear;
330
+ return callback;
291
331
  }
292
332
  /**
293
333
  * Bind function against target <this>.
@@ -476,7 +516,6 @@
476
516
  return bo && (typeof bo.$instanceOf === 'function') && bo.$instanceOf(type);
477
517
  }
478
518
 
479
-
480
519
  /**
481
520
  * Return the business object for a given element.
482
521
  *
@@ -2530,68 +2569,68 @@
2530
2569
  return drawPath(parentGfx, path, assign({ 'data-marker': type }, attrs));
2531
2570
  }
2532
2571
 
2533
- function as(type) {
2534
- return function(parentGfx, element, attrs) {
2535
- return handlers[type](parentGfx, element, attrs);
2536
- };
2537
- }
2538
-
2539
2572
  function renderer(type) {
2540
2573
  return handlers[type];
2541
2574
  }
2542
2575
 
2543
- function renderEventContent(element, parentGfx, attrs) {
2576
+ function as(type) {
2577
+ return function(parentGfx, element) {
2578
+ return renderer(type)(parentGfx, element);
2579
+ };
2580
+ }
2581
+
2582
+ function renderEventContent(element, parentGfx) {
2544
2583
 
2545
2584
  var event = getSemantic(element);
2546
2585
  var isThrowing = isThrowEvent(event);
2547
2586
 
2548
2587
  if (event.eventDefinitions && event.eventDefinitions.length>1) {
2549
2588
  if (event.parallelMultiple) {
2550
- return renderer('bpmn:ParallelMultipleEventDefinition')(parentGfx, element, attrs, isThrowing);
2589
+ return renderer('bpmn:ParallelMultipleEventDefinition')(parentGfx, element, isThrowing);
2551
2590
  }
2552
2591
  else {
2553
- return renderer('bpmn:MultipleEventDefinition')(parentGfx, element, attrs, isThrowing);
2592
+ return renderer('bpmn:MultipleEventDefinition')(parentGfx, element, isThrowing);
2554
2593
  }
2555
2594
  }
2556
2595
 
2557
2596
  if (isTypedEvent(event, 'bpmn:MessageEventDefinition')) {
2558
- return renderer('bpmn:MessageEventDefinition')(parentGfx, element, attrs, isThrowing);
2597
+ return renderer('bpmn:MessageEventDefinition')(parentGfx, element, isThrowing);
2559
2598
  }
2560
2599
 
2561
2600
  if (isTypedEvent(event, 'bpmn:TimerEventDefinition')) {
2562
- return renderer('bpmn:TimerEventDefinition')(parentGfx, element, attrs, isThrowing);
2601
+ return renderer('bpmn:TimerEventDefinition')(parentGfx, element, isThrowing);
2563
2602
  }
2564
2603
 
2565
2604
  if (isTypedEvent(event, 'bpmn:ConditionalEventDefinition')) {
2566
- return renderer('bpmn:ConditionalEventDefinition')(parentGfx, element, attrs);
2605
+ return renderer('bpmn:ConditionalEventDefinition')(parentGfx, element);
2567
2606
  }
2568
2607
 
2569
2608
  if (isTypedEvent(event, 'bpmn:SignalEventDefinition')) {
2570
- return renderer('bpmn:SignalEventDefinition')(parentGfx, element, attrs, isThrowing);
2609
+ return renderer('bpmn:SignalEventDefinition')(parentGfx, element, isThrowing);
2571
2610
  }
2572
2611
 
2573
2612
  if (isTypedEvent(event, 'bpmn:EscalationEventDefinition')) {
2574
- return renderer('bpmn:EscalationEventDefinition')(parentGfx, element, attrs, isThrowing);
2613
+ return renderer('bpmn:EscalationEventDefinition')(parentGfx, element, isThrowing);
2575
2614
  }
2576
2615
 
2577
2616
  if (isTypedEvent(event, 'bpmn:LinkEventDefinition')) {
2578
- return renderer('bpmn:LinkEventDefinition')(parentGfx, element, attrs, isThrowing);
2617
+ return renderer('bpmn:LinkEventDefinition')(parentGfx, element, isThrowing);
2579
2618
  }
2580
2619
 
2581
2620
  if (isTypedEvent(event, 'bpmn:ErrorEventDefinition')) {
2582
- return renderer('bpmn:ErrorEventDefinition')(parentGfx, element, attrs, isThrowing);
2621
+ return renderer('bpmn:ErrorEventDefinition')(parentGfx, element, isThrowing);
2583
2622
  }
2584
2623
 
2585
2624
  if (isTypedEvent(event, 'bpmn:CancelEventDefinition')) {
2586
- return renderer('bpmn:CancelEventDefinition')(parentGfx, element, attrs, isThrowing);
2625
+ return renderer('bpmn:CancelEventDefinition')(parentGfx, element, isThrowing);
2587
2626
  }
2588
2627
 
2589
2628
  if (isTypedEvent(event, 'bpmn:CompensateEventDefinition')) {
2590
- return renderer('bpmn:CompensateEventDefinition')(parentGfx, element, attrs, isThrowing);
2629
+ return renderer('bpmn:CompensateEventDefinition')(parentGfx, element, isThrowing);
2591
2630
  }
2592
2631
 
2593
2632
  if (isTypedEvent(event, 'bpmn:TerminateEventDefinition')) {
2594
- return renderer('bpmn:TerminateEventDefinition')(parentGfx, element, attrs, isThrowing);
2633
+ return renderer('bpmn:TerminateEventDefinition')(parentGfx, element, isThrowing);
2595
2634
  }
2596
2635
 
2597
2636
  return null;
@@ -2614,20 +2653,20 @@
2614
2653
  return text;
2615
2654
  }
2616
2655
 
2617
- function renderEmbeddedLabel(parentGfx, element, align, attrs) {
2656
+ function renderEmbeddedLabel(parentGfx, element, align) {
2618
2657
  var semantic = getSemantic(element);
2619
2658
 
2620
2659
  return renderLabel(parentGfx, semantic.name, {
2621
2660
  box: element,
2622
2661
  align: align,
2623
2662
  padding: 5,
2624
- style: assign({
2663
+ style: {
2625
2664
  fill: getLabelColor(element, defaultLabelColor, defaultStrokeColor)
2626
- }, attrs)
2665
+ }
2627
2666
  });
2628
2667
  }
2629
2668
 
2630
- function renderExternalLabel(parentGfx, element, attrs) {
2669
+ function renderExternalLabel(parentGfx, element) {
2631
2670
 
2632
2671
  var box = {
2633
2672
  width: 90,
@@ -2644,22 +2683,21 @@
2644
2683
  textRenderer.getExternalStyle(),
2645
2684
  {
2646
2685
  fill: getLabelColor(element, defaultLabelColor, defaultStrokeColor)
2647
- },
2648
- attrs
2686
+ }
2649
2687
  )
2650
2688
  });
2651
2689
  }
2652
2690
 
2653
- function renderLaneLabel(parentGfx, text, element, attrs) {
2691
+ function renderLaneLabel(parentGfx, text, element) {
2654
2692
  var textBox = renderLabel(parentGfx, text, {
2655
2693
  box: {
2656
2694
  height: 30,
2657
2695
  width: element.height
2658
2696
  },
2659
2697
  align: 'center-middle',
2660
- style: assign({
2698
+ style: {
2661
2699
  fill: getLabelColor(element, defaultLabelColor, defaultStrokeColor)
2662
- }, attrs)
2700
+ }
2663
2701
  });
2664
2702
 
2665
2703
  var top = -1 * element.height;
@@ -2686,11 +2724,11 @@
2686
2724
 
2687
2725
  return drawCircle(parentGfx, element.width, element.height, attrs);
2688
2726
  },
2689
- 'bpmn:StartEvent': function(parentGfx, element, attrs) {
2690
- attrs = assign({
2727
+ 'bpmn:StartEvent': function(parentGfx, element) {
2728
+ var attrs = {
2691
2729
  fill: getFillColor(element, defaultFillColor),
2692
2730
  stroke: getStrokeColor(element, defaultStrokeColor)
2693
- }, attrs);
2731
+ };
2694
2732
 
2695
2733
  var semantic = getSemantic(element);
2696
2734
 
@@ -2709,7 +2747,7 @@
2709
2747
 
2710
2748
  return circle;
2711
2749
  },
2712
- 'bpmn:MessageEventDefinition': function(parentGfx, element, attrs, isThrowing) {
2750
+ 'bpmn:MessageEventDefinition': function(parentGfx, element, isThrowing) {
2713
2751
  var pathData = pathMap.getScaledPath('EVENT_MESSAGE', {
2714
2752
  xScaleFactor: 0.9,
2715
2753
  yScaleFactor: 0.9,
@@ -2724,24 +2762,20 @@
2724
2762
  var fill = isThrowing ? getStrokeColor(element, defaultStrokeColor) : getFillColor(element, defaultFillColor);
2725
2763
  var stroke = isThrowing ? getFillColor(element, defaultFillColor) : getStrokeColor(element, defaultStrokeColor);
2726
2764
 
2727
- attrs = assign({
2765
+ var messagePath = drawPath(parentGfx, pathData, {
2728
2766
  strokeWidth: 1,
2729
2767
  fill: fill,
2730
2768
  stroke: stroke
2731
- }, attrs);
2732
-
2733
- var messagePath = drawPath(parentGfx, pathData, attrs);
2769
+ });
2734
2770
 
2735
2771
  return messagePath;
2736
2772
  },
2737
- 'bpmn:TimerEventDefinition': function(parentGfx, element, attrs) {
2738
- var outerAttrs = assign({
2773
+ 'bpmn:TimerEventDefinition': function(parentGfx, element) {
2774
+ var circle = drawCircle(parentGfx, element.width, element.height, 0.2 * element.height, {
2739
2775
  strokeWidth: 2,
2740
2776
  fill: getFillColor(element, defaultFillColor),
2741
2777
  stroke: getStrokeColor(element, defaultStrokeColor)
2742
- }, attrs);
2743
-
2744
- var circle = drawCircle(parentGfx, element.width, element.height, 0.2 * element.height, outerAttrs);
2778
+ });
2745
2779
 
2746
2780
  var pathData = pathMap.getScaledPath('EVENT_TIMER_WH', {
2747
2781
  xScaleFactor: 0.75,
@@ -2754,13 +2788,11 @@
2754
2788
  }
2755
2789
  });
2756
2790
 
2757
- var innerAttrs = assign({
2791
+ drawPath(parentGfx, pathData, {
2758
2792
  strokeWidth: 2,
2759
2793
  strokeLinecap: 'square',
2760
2794
  stroke: getStrokeColor(element, defaultStrokeColor)
2761
- }, attrs);
2762
-
2763
- drawPath(parentGfx, pathData, innerAttrs);
2795
+ });
2764
2796
 
2765
2797
  for (var i = 0;i < 12; i++) {
2766
2798
 
@@ -2778,25 +2810,17 @@
2778
2810
  var width = element.width / 2;
2779
2811
  var height = element.height / 2;
2780
2812
 
2781
- var lineAttrs = assign({
2813
+ drawPath(parentGfx, linePathData, {
2782
2814
  strokeWidth: 1,
2783
2815
  strokeLinecap: 'square',
2784
2816
  transform: 'rotate(' + (i * 30) + ',' + height + ',' + width + ')',
2785
2817
  stroke: getStrokeColor(element, defaultStrokeColor)
2786
- }, attrs);
2787
-
2788
- drawPath(parentGfx, linePathData, lineAttrs);
2818
+ });
2789
2819
  }
2790
2820
 
2791
2821
  return circle;
2792
2822
  },
2793
- 'bpmn:EscalationEventDefinition': function(parentGfx, event, attrs, isThrowing) {
2794
- attrs = assign({
2795
- strokeWidth: 1,
2796
- fill: fill,
2797
- stroke: getStrokeColor(event, defaultStrokeColor)
2798
- }, attrs);
2799
-
2823
+ 'bpmn:EscalationEventDefinition': function(parentGfx, event, isThrowing) {
2800
2824
  var pathData = pathMap.getScaledPath('EVENT_ESCALATION', {
2801
2825
  xScaleFactor: 1,
2802
2826
  yScaleFactor: 1,
@@ -2810,14 +2834,13 @@
2810
2834
 
2811
2835
  var fill = isThrowing ? getStrokeColor(event, defaultStrokeColor) : 'none';
2812
2836
 
2813
- return drawPath(parentGfx, pathData, attrs);
2814
- },
2815
- 'bpmn:ConditionalEventDefinition': function(parentGfx, event, attrs) {
2816
- attrs = assign({
2837
+ return drawPath(parentGfx, pathData, {
2817
2838
  strokeWidth: 1,
2839
+ fill: fill,
2818
2840
  stroke: getStrokeColor(event, defaultStrokeColor)
2819
- }, attrs);
2820
-
2841
+ });
2842
+ },
2843
+ 'bpmn:ConditionalEventDefinition': function(parentGfx, event) {
2821
2844
  var pathData = pathMap.getScaledPath('EVENT_CONDITIONAL', {
2822
2845
  xScaleFactor: 1,
2823
2846
  yScaleFactor: 1,
@@ -2829,9 +2852,12 @@
2829
2852
  }
2830
2853
  });
2831
2854
 
2832
- return drawPath(parentGfx, pathData, attrs);
2855
+ return drawPath(parentGfx, pathData, {
2856
+ strokeWidth: 1,
2857
+ stroke: getStrokeColor(event, defaultStrokeColor)
2858
+ });
2833
2859
  },
2834
- 'bpmn:LinkEventDefinition': function(parentGfx, event, attrs, isThrowing) {
2860
+ 'bpmn:LinkEventDefinition': function(parentGfx, event, isThrowing) {
2835
2861
  var pathData = pathMap.getScaledPath('EVENT_LINK', {
2836
2862
  xScaleFactor: 1,
2837
2863
  yScaleFactor: 1,
@@ -2845,15 +2871,13 @@
2845
2871
 
2846
2872
  var fill = isThrowing ? getStrokeColor(event, defaultStrokeColor) : 'none';
2847
2873
 
2848
- attrs = assign({
2874
+ return drawPath(parentGfx, pathData, {
2849
2875
  strokeWidth: 1,
2850
2876
  fill: fill,
2851
2877
  stroke: getStrokeColor(event, defaultStrokeColor)
2852
- }, attrs);
2853
-
2854
- return drawPath(parentGfx, pathData, attrs);
2878
+ });
2855
2879
  },
2856
- 'bpmn:ErrorEventDefinition': function(parentGfx, event, attrs, isThrowing) {
2880
+ 'bpmn:ErrorEventDefinition': function(parentGfx, event, isThrowing) {
2857
2881
  var pathData = pathMap.getScaledPath('EVENT_ERROR', {
2858
2882
  xScaleFactor: 1.1,
2859
2883
  yScaleFactor: 1.1,
@@ -2867,15 +2891,13 @@
2867
2891
 
2868
2892
  var fill = isThrowing ? getStrokeColor(event, defaultStrokeColor) : 'none';
2869
2893
 
2870
- attrs = assign({
2894
+ return drawPath(parentGfx, pathData, {
2871
2895
  strokeWidth: 1,
2872
2896
  fill: fill,
2873
2897
  stroke: getStrokeColor(event, defaultStrokeColor)
2874
- }, attrs);
2875
-
2876
- return drawPath(parentGfx, pathData, attrs);
2898
+ });
2877
2899
  },
2878
- 'bpmn:CancelEventDefinition': function(parentGfx, event, attrs, isThrowing) {
2900
+ 'bpmn:CancelEventDefinition': function(parentGfx, event, isThrowing) {
2879
2901
  var pathData = pathMap.getScaledPath('EVENT_CANCEL_45', {
2880
2902
  xScaleFactor: 1.0,
2881
2903
  yScaleFactor: 1.0,
@@ -2889,19 +2911,17 @@
2889
2911
 
2890
2912
  var fill = isThrowing ? getStrokeColor(event, defaultStrokeColor) : 'none';
2891
2913
 
2892
- attrs = assign({
2914
+ var path = drawPath(parentGfx, pathData, {
2893
2915
  strokeWidth: 1,
2894
2916
  fill: fill,
2895
2917
  stroke: getStrokeColor(event, defaultStrokeColor)
2896
- }, attrs);
2897
-
2898
- var path = drawPath(parentGfx, pathData, attrs);
2918
+ });
2899
2919
 
2900
2920
  rotate(path, 45);
2901
2921
 
2902
2922
  return path;
2903
2923
  },
2904
- 'bpmn:CompensateEventDefinition': function(parentGfx, event, attrs, isThrowing) {
2924
+ 'bpmn:CompensateEventDefinition': function(parentGfx, event, isThrowing) {
2905
2925
  var pathData = pathMap.getScaledPath('EVENT_COMPENSATION', {
2906
2926
  xScaleFactor: 1,
2907
2927
  yScaleFactor: 1,
@@ -2915,15 +2935,13 @@
2915
2935
 
2916
2936
  var fill = isThrowing ? getStrokeColor(event, defaultStrokeColor) : 'none';
2917
2937
 
2918
- attrs = assign({
2938
+ return drawPath(parentGfx, pathData, {
2919
2939
  strokeWidth: 1,
2920
2940
  fill: fill,
2921
2941
  stroke: getStrokeColor(event, defaultStrokeColor)
2922
- }, attrs);
2923
-
2924
- return drawPath(parentGfx, pathData, attrs);
2942
+ });
2925
2943
  },
2926
- 'bpmn:SignalEventDefinition': function(parentGfx, event, attrs, isThrowing) {
2944
+ 'bpmn:SignalEventDefinition': function(parentGfx, event, isThrowing) {
2927
2945
  var pathData = pathMap.getScaledPath('EVENT_SIGNAL', {
2928
2946
  xScaleFactor: 0.9,
2929
2947
  yScaleFactor: 0.9,
@@ -2937,15 +2955,13 @@
2937
2955
 
2938
2956
  var fill = isThrowing ? getStrokeColor(event, defaultStrokeColor) : 'none';
2939
2957
 
2940
- attrs = assign({
2958
+ return drawPath(parentGfx, pathData, {
2941
2959
  strokeWidth: 1,
2942
2960
  fill: fill,
2943
2961
  stroke: getStrokeColor(event, defaultStrokeColor)
2944
- }, attrs);
2945
-
2946
- return drawPath(parentGfx, pathData, attrs);
2962
+ });
2947
2963
  },
2948
- 'bpmn:MultipleEventDefinition': function(parentGfx, event, attrs, isThrowing) {
2964
+ 'bpmn:MultipleEventDefinition': function(parentGfx, event, isThrowing) {
2949
2965
  var pathData = pathMap.getScaledPath('EVENT_MULTIPLE', {
2950
2966
  xScaleFactor: 1.1,
2951
2967
  yScaleFactor: 1.1,
@@ -2959,14 +2975,12 @@
2959
2975
 
2960
2976
  var fill = isThrowing ? getStrokeColor(event, defaultStrokeColor) : 'none';
2961
2977
 
2962
- attrs = assign({
2978
+ return drawPath(parentGfx, pathData, {
2963
2979
  strokeWidth: 1,
2964
2980
  fill: fill
2965
- }, attrs);
2966
-
2967
- return drawPath(parentGfx, pathData, attrs);
2981
+ });
2968
2982
  },
2969
- 'bpmn:ParallelMultipleEventDefinition': function(parentGfx, event, attrs) {
2983
+ 'bpmn:ParallelMultipleEventDefinition': function(parentGfx, event) {
2970
2984
  var pathData = pathMap.getScaledPath('EVENT_PARALLEL_MULTIPLE', {
2971
2985
  xScaleFactor: 1.2,
2972
2986
  yScaleFactor: 1.2,
@@ -2978,54 +2992,47 @@
2978
2992
  }
2979
2993
  });
2980
2994
 
2981
- attrs = assign({
2995
+ return drawPath(parentGfx, pathData, {
2982
2996
  strokeWidth: 1,
2983
2997
  fill: getStrokeColor(event, defaultStrokeColor),
2984
2998
  stroke: getStrokeColor(event, defaultStrokeColor)
2985
- }, attrs);
2986
-
2987
-
2988
- return drawPath(parentGfx, pathData, attrs);
2999
+ });
2989
3000
  },
2990
- 'bpmn:EndEvent': function(parentGfx, element, attrs) {
2991
- var outerAttrs = assign({
3001
+ 'bpmn:EndEvent': function(parentGfx, element) {
3002
+ var circle = renderer('bpmn:Event')(parentGfx, element, {
2992
3003
  strokeWidth: 4,
2993
3004
  fill: getFillColor(element, defaultFillColor),
2994
- stroke: getStrokeColor(element, defaultStrokeColor),
2995
- }, attrs);
2996
-
2997
- var circle = renderer('bpmn:Event')(parentGfx, element, outerAttrs);
3005
+ stroke: getStrokeColor(element, defaultStrokeColor)
3006
+ });
2998
3007
 
2999
- renderEventContent(element, parentGfx, attrs);
3008
+ renderEventContent(element, parentGfx);
3000
3009
 
3001
3010
  return circle;
3002
3011
  },
3003
- 'bpmn:TerminateEventDefinition': function(parentGfx, element, attrs) {
3004
- attrs = assign({
3005
- fill: getFillColor(element, defaultFillColor),
3006
- stroke: getStrokeColor(element, defaultStrokeColor),
3007
- strokeWidth: 4
3008
- }, attrs);
3009
-
3010
- var circle = drawCircle(parentGfx, element.width, element.height, 8, attrs);
3012
+ 'bpmn:TerminateEventDefinition': function(parentGfx, element) {
3013
+ var circle = drawCircle(parentGfx, element.width, element.height, 8, {
3014
+ strokeWidth: 4,
3015
+ fill: getStrokeColor(element, defaultStrokeColor),
3016
+ stroke: getStrokeColor(element, defaultStrokeColor)
3017
+ });
3011
3018
 
3012
3019
  return circle;
3013
3020
  },
3014
- 'bpmn:IntermediateEvent': function(parentGfx, element, attrs) {
3015
- var outerAttrs = assign({
3021
+ 'bpmn:IntermediateEvent': function(parentGfx, element) {
3022
+ var outer = renderer('bpmn:Event')(parentGfx, element, {
3016
3023
  strokeWidth: 1,
3017
3024
  fill: getFillColor(element, defaultFillColor),
3018
3025
  stroke: getStrokeColor(element, defaultStrokeColor)
3019
- }, attrs);
3020
-
3021
- var outer = renderer('bpmn:Event')(parentGfx, element, outerAttrs);
3026
+ });
3022
3027
 
3023
3028
  /* inner */
3024
- drawCircle(parentGfx, element.width, element.height, INNER_OUTER_DIST, assign({}, outerAttrs, {
3029
+ drawCircle(parentGfx, element.width, element.height, INNER_OUTER_DIST, {
3030
+ strokeWidth: 1,
3025
3031
  fill: getFillColor(element, 'none'),
3026
- }));
3032
+ stroke: getStrokeColor(element, defaultStrokeColor)
3033
+ });
3027
3034
 
3028
- renderEventContent(element, parentGfx, attrs);
3035
+ renderEventContent(element, parentGfx);
3029
3036
 
3030
3037
  return outer;
3031
3038
  },
@@ -3043,21 +3050,21 @@
3043
3050
  return drawRect(parentGfx, element.width, element.height, TASK_BORDER_RADIUS, attrs);
3044
3051
  },
3045
3052
 
3046
- 'bpmn:Task': function(parentGfx, element, attrs) {
3047
- attrs = assign({
3053
+ 'bpmn:Task': function(parentGfx, element) {
3054
+ var attrs = {
3048
3055
  fill: getFillColor(element, defaultFillColor),
3049
3056
  stroke: getStrokeColor(element, defaultStrokeColor)
3050
- }, attrs);
3057
+ };
3051
3058
 
3052
3059
  var rect = renderer('bpmn:Activity')(parentGfx, element, attrs);
3053
3060
 
3054
3061
  renderEmbeddedLabel(parentGfx, element, 'center-middle');
3055
- attachTaskMarkers(parentGfx, element, attrs);
3062
+ attachTaskMarkers(parentGfx, element);
3056
3063
 
3057
3064
  return rect;
3058
3065
  },
3059
- 'bpmn:ServiceTask': function(parentGfx, element, attrs) {
3060
- var task = renderer('bpmn:Task')(parentGfx, element, attrs);
3066
+ 'bpmn:ServiceTask': function(parentGfx, element) {
3067
+ var task = renderer('bpmn:Task')(parentGfx, element);
3061
3068
 
3062
3069
  var pathDataBG = pathMap.getScaledPath('TASK_TYPE_SERVICE', {
3063
3070
  abspos: {
@@ -3066,12 +3073,11 @@
3066
3073
  }
3067
3074
  });
3068
3075
 
3069
- var serviceAttrs = assign({
3076
+ /* service bg */ drawPath(parentGfx, pathDataBG, {
3070
3077
  strokeWidth: 1,
3071
3078
  fill: getFillColor(element, defaultFillColor),
3072
3079
  stroke: getStrokeColor(element, defaultStrokeColor)
3073
- }, attrs);
3074
- /* service bg */ drawPath(parentGfx, pathDataBG, serviceAttrs);
3080
+ });
3075
3081
 
3076
3082
  var fillPathData = pathMap.getScaledPath('TASK_TYPE_SERVICE_FILL', {
3077
3083
  abspos: {
@@ -3080,11 +3086,10 @@
3080
3086
  }
3081
3087
  });
3082
3088
 
3083
- var fillAttrs = assign({
3089
+ /* service fill */ drawPath(parentGfx, fillPathData, {
3084
3090
  strokeWidth: 0,
3085
3091
  fill: getFillColor(element, defaultFillColor)
3086
- }, attrs);
3087
- /* service fill */ drawPath(parentGfx, fillPathData, fillAttrs);
3092
+ });
3088
3093
 
3089
3094
  var pathData = pathMap.getScaledPath('TASK_TYPE_SERVICE', {
3090
3095
  abspos: {
@@ -3093,12 +3098,16 @@
3093
3098
  }
3094
3099
  });
3095
3100
 
3096
- /* service */ drawPath(parentGfx, pathData, serviceAttrs);
3101
+ /* service */ drawPath(parentGfx, pathData, {
3102
+ strokeWidth: 1,
3103
+ fill: getFillColor(element, defaultFillColor),
3104
+ stroke: getStrokeColor(element, defaultStrokeColor)
3105
+ });
3097
3106
 
3098
3107
  return task;
3099
3108
  },
3100
- 'bpmn:UserTask': function(parentGfx, element, attrs) {
3101
- var task = renderer('bpmn:Task')(parentGfx, element, attrs);
3109
+ 'bpmn:UserTask': function(parentGfx, element) {
3110
+ var task = renderer('bpmn:Task')(parentGfx, element);
3102
3111
 
3103
3112
  var x = 15;
3104
3113
  var y = 12;
@@ -3110,12 +3119,11 @@
3110
3119
  }
3111
3120
  });
3112
3121
 
3113
- var userAttrs = assign({
3122
+ /* user path */ drawPath(parentGfx, pathData, {
3114
3123
  strokeWidth: 0.5,
3115
3124
  fill: getFillColor(element, defaultFillColor),
3116
3125
  stroke: getStrokeColor(element, defaultStrokeColor)
3117
- }, attrs);
3118
- /* user path */ drawPath(parentGfx, pathData, userAttrs);
3126
+ });
3119
3127
 
3120
3128
  var pathData2 = pathMap.getScaledPath('TASK_TYPE_USER_2', {
3121
3129
  abspos: {
@@ -3124,7 +3132,11 @@
3124
3132
  }
3125
3133
  });
3126
3134
 
3127
- /* user2 path */ drawPath(parentGfx, pathData2, userAttrs);
3135
+ /* user2 path */ drawPath(parentGfx, pathData2, {
3136
+ strokeWidth: 0.5,
3137
+ fill: getFillColor(element, defaultFillColor),
3138
+ stroke: getStrokeColor(element, defaultStrokeColor)
3139
+ });
3128
3140
 
3129
3141
  var pathData3 = pathMap.getScaledPath('TASK_TYPE_USER_3', {
3130
3142
  abspos: {
@@ -3133,12 +3145,16 @@
3133
3145
  }
3134
3146
  });
3135
3147
 
3136
- /* user3 path */ drawPath(parentGfx, pathData3, userAttrs);
3148
+ /* user3 path */ drawPath(parentGfx, pathData3, {
3149
+ strokeWidth: 0.5,
3150
+ fill: getStrokeColor(element, defaultStrokeColor),
3151
+ stroke: getStrokeColor(element, defaultStrokeColor)
3152
+ });
3137
3153
 
3138
3154
  return task;
3139
3155
  },
3140
- 'bpmn:ManualTask': function(parentGfx, element, attrs) {
3141
- var task = renderer('bpmn:Task')(parentGfx, element, attrs);
3156
+ 'bpmn:ManualTask': function(parentGfx, element) {
3157
+ var task = renderer('bpmn:Task')(parentGfx, element);
3142
3158
 
3143
3159
  var pathData = pathMap.getScaledPath('TASK_TYPE_MANUAL', {
3144
3160
  abspos: {
@@ -3147,17 +3163,16 @@
3147
3163
  }
3148
3164
  });
3149
3165
 
3150
- var manualAttrs = assign({
3166
+ /* manual path */ drawPath(parentGfx, pathData, {
3151
3167
  strokeWidth: 0.5, // 0.25,
3152
3168
  fill: getFillColor(element, defaultFillColor),
3153
3169
  stroke: getStrokeColor(element, defaultStrokeColor)
3154
- }, attrs);
3155
- /* manual path */ drawPath(parentGfx, pathData, manualAttrs);
3170
+ });
3156
3171
 
3157
3172
  return task;
3158
3173
  },
3159
- 'bpmn:SendTask': function(parentGfx, element, attrs) {
3160
- var task = renderer('bpmn:Task')(parentGfx, element, attrs);
3174
+ 'bpmn:SendTask': function(parentGfx, element) {
3175
+ var task = renderer('bpmn:Task')(parentGfx, element);
3161
3176
 
3162
3177
  var pathData = pathMap.getScaledPath('TASK_TYPE_SEND', {
3163
3178
  xScaleFactor: 1,
@@ -3170,25 +3185,22 @@
3170
3185
  }
3171
3186
  });
3172
3187
 
3173
- /* send path */
3174
- var pathAttrs = assign({
3188
+ /* send path */ drawPath(parentGfx, pathData, {
3175
3189
  strokeWidth: 1,
3176
3190
  fill: getStrokeColor(element, defaultStrokeColor),
3177
3191
  stroke: getFillColor(element, defaultFillColor)
3178
- }, attrs);
3179
-
3180
- drawPath(parentGfx, pathData, pathAttrs);
3192
+ });
3181
3193
 
3182
3194
  return task;
3183
3195
  },
3184
- 'bpmn:ReceiveTask' : function(parentGfx, element, attrs) {
3196
+ 'bpmn:ReceiveTask' : function(parentGfx, element) {
3185
3197
  var semantic = getSemantic(element);
3186
3198
 
3187
- var task = renderer('bpmn:Task')(parentGfx, element, attrs);
3199
+ var task = renderer('bpmn:Task')(parentGfx, element);
3188
3200
  var pathData;
3189
3201
 
3190
3202
  if (semantic.instantiate) {
3191
- drawCircle(parentGfx, 28, 28, 20 * 0.22, assign({ strokeWidth: 1 }, attrs));
3203
+ drawCircle(parentGfx, 28, 28, 20 * 0.22, { strokeWidth: 1 });
3192
3204
 
3193
3205
  pathData = pathMap.getScaledPath('TASK_TYPE_INSTANTIATING_SEND', {
3194
3206
  abspos: {
@@ -3210,18 +3222,16 @@
3210
3222
  });
3211
3223
  }
3212
3224
 
3213
- var receiveAttrs = assign({
3225
+ /* receive path */ drawPath(parentGfx, pathData, {
3214
3226
  strokeWidth: 1,
3215
3227
  fill: getFillColor(element, defaultFillColor),
3216
3228
  stroke: getStrokeColor(element, defaultStrokeColor)
3217
- }, attrs);
3218
-
3219
- /* receive path */ drawPath(parentGfx, pathData, receiveAttrs);
3229
+ });
3220
3230
 
3221
3231
  return task;
3222
3232
  },
3223
- 'bpmn:ScriptTask': function(parentGfx, element, attrs) {
3224
- var task = renderer('bpmn:Task')(parentGfx, element, attrs);
3233
+ 'bpmn:ScriptTask': function(parentGfx, element) {
3234
+ var task = renderer('bpmn:Task')(parentGfx, element);
3225
3235
 
3226
3236
  var pathData = pathMap.getScaledPath('TASK_TYPE_SCRIPT', {
3227
3237
  abspos: {
@@ -3230,16 +3240,15 @@
3230
3240
  }
3231
3241
  });
3232
3242
 
3233
- var scriptAttrs = assign({
3243
+ /* script path */ drawPath(parentGfx, pathData, {
3234
3244
  strokeWidth: 1,
3235
3245
  stroke: getStrokeColor(element, defaultStrokeColor)
3236
- }, attrs);
3237
- /* script path */ drawPath(parentGfx, pathData, scriptAttrs);
3246
+ });
3238
3247
 
3239
3248
  return task;
3240
3249
  },
3241
- 'bpmn:BusinessRuleTask': function(parentGfx, element, attrs) {
3242
- var task = renderer('bpmn:Task')(parentGfx, element, attrs);
3250
+ 'bpmn:BusinessRuleTask': function(parentGfx, element) {
3251
+ var task = renderer('bpmn:Task')(parentGfx, element);
3243
3252
 
3244
3253
  var headerPathData = pathMap.getScaledPath('TASK_TYPE_BUSINESS_RULE_HEADER', {
3245
3254
  abspos: {
@@ -3248,12 +3257,12 @@
3248
3257
  }
3249
3258
  });
3250
3259
 
3251
- var headerAttrs = assign({
3260
+ var businessHeaderPath = drawPath(parentGfx, headerPathData);
3261
+ attr$1(businessHeaderPath, {
3252
3262
  strokeWidth: 1,
3253
3263
  fill: getFillColor(element, '#aaaaaa'),
3254
3264
  stroke: getStrokeColor(element, defaultStrokeColor)
3255
- }, attrs);
3256
- drawPath(parentGfx, headerPathData, headerAttrs);
3265
+ });
3257
3266
 
3258
3267
  var headerData = pathMap.getScaledPath('TASK_TYPE_BUSINESS_RULE_MAIN', {
3259
3268
  abspos: {
@@ -3262,11 +3271,11 @@
3262
3271
  }
3263
3272
  });
3264
3273
 
3265
- var businessAttrs = assign({
3274
+ var businessPath = drawPath(parentGfx, headerData);
3275
+ attr$1(businessPath, {
3266
3276
  strokeWidth: 1,
3267
3277
  stroke: getStrokeColor(element, defaultStrokeColor)
3268
- }, attrs);
3269
- drawPath(parentGfx, headerData, businessAttrs);
3278
+ });
3270
3279
 
3271
3280
  return task;
3272
3281
  },
@@ -3289,42 +3298,41 @@
3289
3298
  renderEmbeddedLabel(parentGfx, element, expanded ? 'center-top' : 'center-middle');
3290
3299
 
3291
3300
  if (expanded) {
3292
- attachTaskMarkers(parentGfx, element, attrs);
3301
+ attachTaskMarkers(parentGfx, element);
3293
3302
  } else {
3294
- attachTaskMarkers(parentGfx, element, attrs, ['SubProcessMarker']);
3303
+ attachTaskMarkers(parentGfx, element, ['SubProcessMarker']);
3295
3304
  }
3296
3305
 
3297
3306
  return rect;
3298
3307
  },
3299
- 'bpmn:AdHocSubProcess': function(parentGfx, element, attrs) {
3300
- return renderer('bpmn:SubProcess')(parentGfx, element, attrs);
3308
+ 'bpmn:AdHocSubProcess': function(parentGfx, element) {
3309
+ return renderer('bpmn:SubProcess')(parentGfx, element);
3301
3310
  },
3302
- 'bpmn:Transaction': function(parentGfx, element, attrs) {
3303
- var outer = renderer('bpmn:SubProcess')(parentGfx, element, attrs);
3311
+ 'bpmn:Transaction': function(parentGfx, element) {
3312
+ var outer = renderer('bpmn:SubProcess')(parentGfx, element);
3304
3313
 
3305
3314
  var innerAttrs = styles.style([ 'no-fill', 'no-events' ], {
3306
3315
  stroke: getStrokeColor(element, defaultStrokeColor)
3307
3316
  });
3308
3317
 
3309
- /* inner path */ drawRect(parentGfx, element.width, element.height, TASK_BORDER_RADIUS - 2, INNER_OUTER_DIST, assign(innerAttrs, attrs));
3318
+ /* inner path */ drawRect(parentGfx, element.width, element.height, TASK_BORDER_RADIUS - 2, INNER_OUTER_DIST, innerAttrs);
3310
3319
 
3311
3320
  return outer;
3312
3321
  },
3313
- 'bpmn:CallActivity': function(parentGfx, element, attrs) {
3314
- attrs = assign({
3322
+ 'bpmn:CallActivity': function(parentGfx, element) {
3323
+ return renderer('bpmn:SubProcess')(parentGfx, element, {
3315
3324
  strokeWidth: 5
3316
- }, attrs);
3317
-
3318
- return renderer('bpmn:SubProcess')(parentGfx, element, attrs);
3325
+ });
3319
3326
  },
3320
- 'bpmn:Participant': function(parentGfx, element, attrs) {
3321
- var outerAttrs = assign({
3327
+ 'bpmn:Participant': function(parentGfx, element) {
3328
+
3329
+ var attrs = {
3322
3330
  fillOpacity: DEFAULT_FILL_OPACITY,
3323
3331
  fill: getFillColor(element, defaultFillColor),
3324
3332
  stroke: getStrokeColor(element, defaultStrokeColor)
3325
- }, attrs);
3333
+ };
3326
3334
 
3327
- var lane = renderer('bpmn:Lane')(parentGfx, element, outerAttrs);
3335
+ var lane = renderer('bpmn:Lane')(parentGfx, element, attrs);
3328
3336
 
3329
3337
  var expandedPool = isExpanded(element);
3330
3338
 
@@ -3332,9 +3340,9 @@
3332
3340
  drawLine(parentGfx, [
3333
3341
  { x: 30, y: 0 },
3334
3342
  { x: 30, y: element.height }
3335
- ], assign({
3343
+ ], {
3336
3344
  stroke: getStrokeColor(element, defaultStrokeColor)
3337
- }, attrs));
3345
+ });
3338
3346
  var text = getSemantic(element).name;
3339
3347
  renderLaneLabel(parentGfx, text, element);
3340
3348
  } else {
@@ -3352,7 +3360,7 @@
3352
3360
  var participantMultiplicity = !!(getSemantic(element).participantMultiplicity);
3353
3361
 
3354
3362
  if (participantMultiplicity) {
3355
- renderer('ParticipantMultiplicityMarker')(parentGfx, element, attrs);
3363
+ renderer('ParticipantMultiplicityMarker')(parentGfx, element);
3356
3364
  }
3357
3365
 
3358
3366
  return lane;
@@ -3373,23 +3381,20 @@
3373
3381
 
3374
3382
  return rect;
3375
3383
  },
3376
- 'bpmn:InclusiveGateway': function(parentGfx, element, attrs) {
3377
- var diamond = renderer('bpmn:Gateway')(parentGfx, element, attrs);
3384
+ 'bpmn:InclusiveGateway': function(parentGfx, element) {
3385
+ var diamond = renderer('bpmn:Gateway')(parentGfx, element);
3378
3386
 
3379
-
3380
- var circleAttrs = assign({
3387
+ /* circle path */
3388
+ drawCircle(parentGfx, element.width, element.height, element.height * 0.24, {
3381
3389
  strokeWidth: 2.5,
3382
3390
  fill: getFillColor(element, defaultFillColor),
3383
3391
  stroke: getStrokeColor(element, defaultStrokeColor)
3384
- }, attrs);
3385
-
3386
- /* circle path */
3387
- drawCircle(parentGfx, element.width, element.height, element.height * 0.24, circleAttrs);
3392
+ });
3388
3393
 
3389
3394
  return diamond;
3390
3395
  },
3391
- 'bpmn:ExclusiveGateway': function(parentGfx, element, attrs) {
3392
- var diamond = renderer('bpmn:Gateway')(parentGfx, element, attrs);
3396
+ 'bpmn:ExclusiveGateway': function(parentGfx, element) {
3397
+ var diamond = renderer('bpmn:Gateway')(parentGfx, element);
3393
3398
 
3394
3399
  var pathData = pathMap.getScaledPath('GATEWAY_EXCLUSIVE', {
3395
3400
  xScaleFactor: 0.4,
@@ -3403,17 +3408,17 @@
3403
3408
  });
3404
3409
 
3405
3410
  if ((getDi(element).isMarkerVisible)) {
3406
- drawPath(parentGfx, pathData, assign({
3411
+ drawPath(parentGfx, pathData, {
3407
3412
  strokeWidth: 1,
3408
3413
  fill: getStrokeColor(element, defaultStrokeColor),
3409
3414
  stroke: getStrokeColor(element, defaultStrokeColor)
3410
- }, attrs));
3415
+ });
3411
3416
  }
3412
3417
 
3413
3418
  return diamond;
3414
3419
  },
3415
- 'bpmn:ComplexGateway': function(parentGfx, element, attrs) {
3416
- var diamond = renderer('bpmn:Gateway')(parentGfx, element, attrs);
3420
+ 'bpmn:ComplexGateway': function(parentGfx, element) {
3421
+ var diamond = renderer('bpmn:Gateway')(parentGfx, element);
3417
3422
 
3418
3423
  var pathData = pathMap.getScaledPath('GATEWAY_COMPLEX', {
3419
3424
  xScaleFactor: 0.5,
@@ -3426,17 +3431,16 @@
3426
3431
  }
3427
3432
  });
3428
3433
 
3429
- var innerAttrs = assign({
3434
+ /* complex path */ drawPath(parentGfx, pathData, {
3430
3435
  strokeWidth: 1,
3431
3436
  fill: getStrokeColor(element, defaultStrokeColor),
3432
3437
  stroke: getStrokeColor(element, defaultStrokeColor)
3433
- }, attrs);
3434
- /* complex path */ drawPath(parentGfx, pathData, innerAttrs);
3438
+ });
3435
3439
 
3436
3440
  return diamond;
3437
3441
  },
3438
- 'bpmn:ParallelGateway': function(parentGfx, element, attrs) {
3439
- var diamond = renderer('bpmn:Gateway')(parentGfx, element, attrs);
3442
+ 'bpmn:ParallelGateway': function(parentGfx, element) {
3443
+ var diamond = renderer('bpmn:Gateway')(parentGfx, element);
3440
3444
 
3441
3445
  var pathData = pathMap.getScaledPath('GATEWAY_PARALLEL', {
3442
3446
  xScaleFactor: 0.6,
@@ -3449,27 +3453,25 @@
3449
3453
  }
3450
3454
  });
3451
3455
 
3452
- var innerAttrs = assign({
3456
+ /* parallel path */ drawPath(parentGfx, pathData, {
3453
3457
  strokeWidth: 1,
3454
3458
  fill: getStrokeColor(element, defaultStrokeColor),
3455
3459
  stroke: getStrokeColor(element, defaultStrokeColor)
3456
- }, attrs);
3457
- /* parallel path */ drawPath(parentGfx, pathData, innerAttrs);
3460
+ });
3458
3461
 
3459
3462
  return diamond;
3460
3463
  },
3461
- 'bpmn:EventBasedGateway': function(parentGfx, element, attrs) {
3464
+ 'bpmn:EventBasedGateway': function(parentGfx, element) {
3462
3465
 
3463
3466
  var semantic = getSemantic(element);
3464
3467
 
3465
- var diamond = renderer('bpmn:Gateway')(parentGfx, element, attrs);
3468
+ var diamond = renderer('bpmn:Gateway')(parentGfx, element);
3466
3469
 
3467
- var outerAttrs = assign({
3470
+ /* outer circle path */ drawCircle(parentGfx, element.width, element.height, element.height * 0.20, {
3468
3471
  strokeWidth: 1,
3469
3472
  fill: 'none',
3470
3473
  stroke: getStrokeColor(element, defaultStrokeColor)
3471
- }, attrs);
3472
- /* outer circle path */ drawCircle(parentGfx, element.width, element.height, element.height * 0.20, outerAttrs);
3474
+ });
3473
3475
 
3474
3476
  var type = semantic.eventGatewayType;
3475
3477
  var instantiate = !!semantic.instantiate;
@@ -3487,12 +3489,13 @@
3487
3489
  }
3488
3490
  });
3489
3491
 
3490
- var innerAttrs = assign({
3492
+ var attrs = {
3491
3493
  strokeWidth: 2,
3492
3494
  fill: getFillColor(element, 'none'),
3493
3495
  stroke: getStrokeColor(element, defaultStrokeColor)
3494
- }, attrs);
3495
- /* event path */ drawPath(parentGfx, pathData, innerAttrs);
3496
+ };
3497
+
3498
+ /* event path */ drawPath(parentGfx, pathData, attrs);
3496
3499
  }
3497
3500
 
3498
3501
  if (type === 'Parallel') {
@@ -3508,7 +3511,7 @@
3508
3511
  }
3509
3512
  });
3510
3513
 
3511
- var parallelPath = drawPath(parentGfx, pathData, attrs);
3514
+ var parallelPath = drawPath(parentGfx, pathData);
3512
3515
  attr$1(parallelPath, {
3513
3516
  strokeWidth: 1,
3514
3517
  fill: 'none'
@@ -3516,12 +3519,12 @@
3516
3519
  } else if (type === 'Exclusive') {
3517
3520
 
3518
3521
  if (!instantiate) {
3519
- var innerCircleAttrs = assign({
3522
+ var innerCircle = drawCircle(parentGfx, element.width, element.height, element.height * 0.26);
3523
+ attr$1(innerCircle, {
3520
3524
  strokeWidth: 1,
3521
3525
  fill: 'none',
3522
3526
  stroke: getStrokeColor(element, defaultStrokeColor)
3523
- }, attrs);
3524
- drawCircle(parentGfx, element.width, element.height, element.height * 0.26, innerCircleAttrs);
3527
+ });
3525
3528
  }
3526
3529
 
3527
3530
  drawEvent();
@@ -3530,28 +3533,26 @@
3530
3533
 
3531
3534
  return diamond;
3532
3535
  },
3533
- 'bpmn:Gateway': function(parentGfx, element, attrs) {
3534
- attrs = assign({
3536
+ 'bpmn:Gateway': function(parentGfx, element) {
3537
+ var attrs = {
3535
3538
  fill: getFillColor(element, defaultFillColor),
3536
3539
  fillOpacity: DEFAULT_FILL_OPACITY,
3537
3540
  stroke: getStrokeColor(element, defaultStrokeColor)
3538
- }, attrs);
3541
+ };
3539
3542
 
3540
3543
  return drawDiamond(parentGfx, element.width, element.height, attrs);
3541
3544
  },
3542
- 'bpmn:SequenceFlow': function(parentGfx, element, attrs) {
3543
- attrs = attrs || {};
3544
-
3545
+ 'bpmn:SequenceFlow': function(parentGfx, element) {
3545
3546
  var pathData = createPathFromConnection(element);
3546
3547
 
3547
- var fill = attrs.fill || getFillColor(element, defaultFillColor),
3548
- stroke = attrs.stroke || getStrokeColor(element, defaultStrokeColor);
3548
+ var fill = getFillColor(element, defaultFillColor),
3549
+ stroke = getStrokeColor(element, defaultStrokeColor);
3549
3550
 
3550
- attrs = assign({
3551
+ var attrs = {
3551
3552
  strokeLinejoin: 'round',
3552
3553
  markerEnd: marker('sequenceflow-end', fill, stroke),
3553
3554
  stroke: getStrokeColor(element, defaultStrokeColor)
3554
- }, attrs || {});
3555
+ };
3555
3556
 
3556
3557
  var path = drawPath(parentGfx, pathData, attrs);
3557
3558
 
@@ -3605,56 +3606,41 @@
3605
3606
 
3606
3607
  return drawLine(parentGfx, element.waypoints, attrs);
3607
3608
  },
3608
- 'bpmn:DataInputAssociation': function(parentGfx, element, attrs) {
3609
- attrs = attrs || {};
3610
-
3611
- var fill = attrs.fill || getFillColor(element, defaultFillColor),
3612
- stroke = attrs.stroke || getStrokeColor(element, defaultStrokeColor);
3609
+ 'bpmn:DataInputAssociation': function(parentGfx, element) {
3610
+ var fill = getFillColor(element, defaultFillColor),
3611
+ stroke = getStrokeColor(element, defaultStrokeColor);
3613
3612
 
3614
- attrs = assign({
3615
- fill: fill,
3616
- stroke: stroke,
3613
+ return renderer('bpmn:Association')(parentGfx, element, {
3617
3614
  markerEnd: marker('association-end', fill, stroke)
3618
- }, attrs);
3619
-
3620
- return renderer('bpmn:Association')(parentGfx, element, attrs);
3615
+ });
3621
3616
  },
3622
- 'bpmn:DataOutputAssociation': function(parentGfx, element, attrs) {
3623
- attrs = attrs || {};
3624
-
3625
- var fill = attrs.fill || getFillColor(element, defaultFillColor),
3626
- stroke = attrs.stroke || getStrokeColor(element, defaultStrokeColor);
3627
-
3617
+ 'bpmn:DataOutputAssociation': function(parentGfx, element) {
3618
+ var fill = getFillColor(element, defaultFillColor),
3619
+ stroke = getStrokeColor(element, defaultStrokeColor);
3628
3620
 
3629
- attrs = assign({
3630
- fill: fill,
3631
- stroke: stroke,
3621
+ return renderer('bpmn:Association')(parentGfx, element, {
3632
3622
  markerEnd: marker('association-end', fill, stroke)
3633
- }, attrs);
3634
-
3635
- return renderer('bpmn:Association')(parentGfx, element, attrs);
3623
+ });
3636
3624
  },
3637
- 'bpmn:MessageFlow': function(parentGfx, element, attrs) {
3638
- attrs = attrs || {};
3625
+ 'bpmn:MessageFlow': function(parentGfx, element) {
3639
3626
 
3640
3627
  var semantic = getSemantic(element),
3641
3628
  di = getDi(element);
3642
3629
 
3643
- var fill = attrs.fill || getFillColor(element, defaultFillColor),
3644
- stroke = attrs.stroke || getStrokeColor(element, defaultStrokeColor);
3630
+ var fill = getFillColor(element, defaultFillColor),
3631
+ stroke = getStrokeColor(element, defaultStrokeColor);
3645
3632
 
3646
3633
  var pathData = createPathFromConnection(element);
3647
3634
 
3648
-
3649
- attrs = assign({
3635
+ var attrs = {
3650
3636
  markerEnd: marker('messageflow-end', fill, stroke),
3651
3637
  markerStart: marker('messageflow-start', fill, stroke),
3652
3638
  strokeDasharray: '10, 12',
3653
3639
  strokeLinecap: 'round',
3654
3640
  strokeLinejoin: 'round',
3655
3641
  strokeWidth: '1.5px',
3656
- stroke: stroke
3657
- }, attrs);
3642
+ stroke: getStrokeColor(element, defaultStrokeColor)
3643
+ };
3658
3644
 
3659
3645
  var path = drawPath(parentGfx, pathData, attrs);
3660
3646
 
@@ -3701,7 +3687,7 @@
3701
3687
 
3702
3688
  return path;
3703
3689
  },
3704
- 'bpmn:DataObject': function(parentGfx, element, attrs) {
3690
+ 'bpmn:DataObject': function(parentGfx, element) {
3705
3691
  var pathData = pathMap.getScaledPath('DATA_OBJECT_PATH', {
3706
3692
  xScaleFactor: 1,
3707
3693
  yScaleFactor: 1,
@@ -3713,56 +3699,46 @@
3713
3699
  }
3714
3700
  });
3715
3701
 
3716
- var outerAttrs = assign({
3702
+ var elementObject = drawPath(parentGfx, pathData, {
3717
3703
  fill: getFillColor(element, defaultFillColor),
3718
3704
  fillOpacity: DEFAULT_FILL_OPACITY,
3719
3705
  stroke: getStrokeColor(element, defaultStrokeColor)
3720
- }, attrs);
3721
- var elementObject = drawPath(parentGfx, pathData, outerAttrs);
3706
+ });
3722
3707
 
3723
3708
  var semantic = getSemantic(element);
3724
3709
 
3725
3710
  if (isCollection(semantic)) {
3726
- renderDataItemCollection(parentGfx, element, attrs);
3711
+ renderDataItemCollection(parentGfx, element);
3727
3712
  }
3728
3713
 
3729
3714
  return elementObject;
3730
3715
  },
3731
3716
  'bpmn:DataObjectReference': as('bpmn:DataObject'),
3732
- 'bpmn:DataInput': function(parentGfx, element, attrs) {
3717
+ 'bpmn:DataInput': function(parentGfx, element) {
3733
3718
 
3734
3719
  var arrowPathData = pathMap.getRawPath('DATA_ARROW');
3735
3720
 
3736
3721
  // page
3737
- var elementObject = renderer('bpmn:DataObject')(parentGfx, element, attrs);
3722
+ var elementObject = renderer('bpmn:DataObject')(parentGfx, element);
3738
3723
 
3739
- var innerAttrs = assign({ strokeWidth: 1 }, attrs);
3740
- /* input arrow path */ drawPath(parentGfx, arrowPathData, innerAttrs);
3724
+ /* input arrow path */ drawPath(parentGfx, arrowPathData, { strokeWidth: 1 });
3741
3725
 
3742
3726
  return elementObject;
3743
3727
  },
3744
- 'bpmn:DataOutput': function(parentGfx, element, attrs) {
3728
+ 'bpmn:DataOutput': function(parentGfx, element) {
3745
3729
  var arrowPathData = pathMap.getRawPath('DATA_ARROW');
3746
3730
 
3747
3731
  // page
3748
- var elementObject = renderer('bpmn:DataObject')(parentGfx, element, attrs);
3732
+ var elementObject = renderer('bpmn:DataObject')(parentGfx, element);
3749
3733
 
3750
- var arrowAttrs = assign({
3734
+ /* output arrow path */ drawPath(parentGfx, arrowPathData, {
3751
3735
  strokeWidth: 1,
3752
3736
  fill: 'black'
3753
- }, attrs);
3754
- /* output arrow path */ drawPath(parentGfx, arrowPathData, arrowAttrs);
3737
+ });
3755
3738
 
3756
3739
  return elementObject;
3757
3740
  },
3758
- 'bpmn:DataStoreReference': function(parentGfx, element, attrs) {
3759
- attrs = assign({
3760
- strokeWidth: 2,
3761
- fill: getFillColor(element, defaultFillColor),
3762
- fillOpacity: DEFAULT_FILL_OPACITY,
3763
- stroke: getStrokeColor(element, defaultStrokeColor)
3764
- }, attrs);
3765
-
3741
+ 'bpmn:DataStoreReference': function(parentGfx, element) {
3766
3742
  var DATA_STORE_PATH = pathMap.getScaledPath('DATA_STORE', {
3767
3743
  xScaleFactor: 1,
3768
3744
  yScaleFactor: 1,
@@ -3774,20 +3750,25 @@
3774
3750
  }
3775
3751
  });
3776
3752
 
3777
- var elementStore = drawPath(parentGfx, DATA_STORE_PATH, attrs);
3753
+ var elementStore = drawPath(parentGfx, DATA_STORE_PATH, {
3754
+ strokeWidth: 2,
3755
+ fill: getFillColor(element, defaultFillColor),
3756
+ fillOpacity: DEFAULT_FILL_OPACITY,
3757
+ stroke: getStrokeColor(element, defaultStrokeColor)
3758
+ });
3778
3759
 
3779
3760
  return elementStore;
3780
3761
  },
3781
- 'bpmn:BoundaryEvent': function(parentGfx, element, attrs) {
3762
+ 'bpmn:BoundaryEvent': function(parentGfx, element) {
3782
3763
 
3783
3764
  var semantic = getSemantic(element),
3784
3765
  cancel = semantic.cancelActivity;
3785
3766
 
3786
- attrs = assign({
3767
+ var attrs = {
3787
3768
  strokeWidth: 1,
3788
3769
  fill: getFillColor(element, defaultFillColor),
3789
3770
  stroke: getStrokeColor(element, defaultStrokeColor)
3790
- }, attrs);
3771
+ };
3791
3772
 
3792
3773
  if (!cancel) {
3793
3774
  attrs.strokeDasharray = '6';
@@ -3808,32 +3789,30 @@
3808
3789
 
3809
3790
  /* inner path */ drawCircle(parentGfx, element.width, element.height, INNER_OUTER_DIST, innerAttrs);
3810
3791
 
3811
- renderEventContent(element, parentGfx, attrs);
3792
+ renderEventContent(element, parentGfx);
3812
3793
 
3813
3794
  return outer;
3814
3795
  },
3815
- 'bpmn:Group': function(parentGfx, element, attrs) {
3796
+ 'bpmn:Group': function(parentGfx, element) {
3816
3797
 
3817
- attrs = assign({
3798
+ var group = drawRect(parentGfx, element.width, element.height, TASK_BORDER_RADIUS, {
3818
3799
  stroke: getStrokeColor(element, defaultStrokeColor),
3819
3800
  strokeWidth: 1,
3820
3801
  strokeDasharray: '8,3,1,3',
3821
3802
  fill: 'none',
3822
3803
  pointerEvents: 'none'
3823
- }, attrs);
3824
-
3825
- var group = drawRect(parentGfx, element.width, element.height, TASK_BORDER_RADIUS, attrs);
3804
+ });
3826
3805
 
3827
3806
  return group;
3828
3807
  },
3829
3808
  'label': function(parentGfx, element) {
3830
3809
  return renderExternalLabel(parentGfx, element);
3831
3810
  },
3832
- 'bpmn:TextAnnotation': function(parentGfx, element, attrs) {
3833
- var style = assign({}, attrs, {
3811
+ 'bpmn:TextAnnotation': function(parentGfx, element) {
3812
+ var style = {
3834
3813
  'fill': 'none',
3835
3814
  'stroke': 'none'
3836
- });
3815
+ };
3837
3816
 
3838
3817
  var textElement = drawRect(parentGfx, element.width, element.height, 0, 0, style);
3839
3818
 
@@ -3848,10 +3827,9 @@
3848
3827
  }
3849
3828
  });
3850
3829
 
3851
- var pathAttrs = assign({
3830
+ drawPath(parentGfx, textPathData, {
3852
3831
  stroke: getStrokeColor(element, defaultStrokeColor)
3853
- }, attrs);
3854
- drawPath(parentGfx, textPathData, pathAttrs);
3832
+ });
3855
3833
 
3856
3834
  var text = getSemantic(element).text || '';
3857
3835
  renderLabel(parentGfx, text, {
@@ -3865,13 +3843,7 @@
3865
3843
 
3866
3844
  return textElement;
3867
3845
  },
3868
- 'ParticipantMultiplicityMarker': function(parentGfx, element, attrs) {
3869
- attrs = assign({
3870
- strokeWidth: 2,
3871
- fill: getFillColor(element, defaultFillColor),
3872
- stroke: getStrokeColor(element, defaultStrokeColor)
3873
- }, attrs);
3874
-
3846
+ 'ParticipantMultiplicityMarker': function(parentGfx, element) {
3875
3847
  var markerPath = pathMap.getScaledPath('MARKER_PARALLEL', {
3876
3848
  xScaleFactor: 1,
3877
3849
  yScaleFactor: 1,
@@ -3883,15 +3855,18 @@
3883
3855
  }
3884
3856
  });
3885
3857
 
3886
- drawMarker('participant-multiplicity', parentGfx, markerPath, attrs);
3858
+ drawMarker('participant-multiplicity', parentGfx, markerPath, {
3859
+ strokeWidth: 2,
3860
+ fill: getFillColor(element, defaultFillColor),
3861
+ stroke: getStrokeColor(element, defaultStrokeColor)
3862
+ });
3887
3863
  },
3888
- 'SubProcessMarker': function(parentGfx, element, attrs) {
3889
- attrs = assign({
3864
+ 'SubProcessMarker': function(parentGfx, element) {
3865
+ var markerRect = drawRect(parentGfx, 14, 14, 0, {
3866
+ strokeWidth: 1,
3890
3867
  fill: getFillColor(element, defaultFillColor),
3891
3868
  stroke: getStrokeColor(element, defaultStrokeColor)
3892
- }, attrs);
3893
-
3894
- var markerRect = drawRect(parentGfx, 14, 14, 0, assign({ strokeWidth: 1 }, attrs));
3869
+ });
3895
3870
 
3896
3871
  // Process marker is placed in the middle of the box
3897
3872
  // therefore fixed values can be used here
@@ -3908,14 +3883,12 @@
3908
3883
  }
3909
3884
  });
3910
3885
 
3911
- drawMarker('sub-process', parentGfx, markerPath, attrs);
3912
- },
3913
- 'ParallelMarker': function(parentGfx, element, attrs, position) {
3914
- attrs = assign({
3886
+ drawMarker('sub-process', parentGfx, markerPath, {
3915
3887
  fill: getFillColor(element, defaultFillColor),
3916
3888
  stroke: getStrokeColor(element, defaultStrokeColor)
3917
- }, attrs);
3918
-
3889
+ });
3890
+ },
3891
+ 'ParallelMarker': function(parentGfx, element, position) {
3919
3892
  var markerPath = pathMap.getScaledPath('MARKER_PARALLEL', {
3920
3893
  xScaleFactor: 1,
3921
3894
  yScaleFactor: 1,
@@ -3927,13 +3900,12 @@
3927
3900
  }
3928
3901
  });
3929
3902
 
3930
- drawMarker('parallel', parentGfx, markerPath, attrs);
3931
- },
3932
- 'SequentialMarker': function(parentGfx, element, attrs, position) {
3933
- attrs = assign({
3903
+ drawMarker('parallel', parentGfx, markerPath, {
3934
3904
  fill: getFillColor(element, defaultFillColor),
3935
3905
  stroke: getStrokeColor(element, defaultStrokeColor)
3936
- }, attrs);
3906
+ });
3907
+ },
3908
+ 'SequentialMarker': function(parentGfx, element, position) {
3937
3909
  var markerPath = pathMap.getScaledPath('MARKER_SEQUENTIAL', {
3938
3910
  xScaleFactor: 1,
3939
3911
  yScaleFactor: 1,
@@ -3945,15 +3917,12 @@
3945
3917
  }
3946
3918
  });
3947
3919
 
3948
- drawMarker('sequential', parentGfx, markerPath, attrs);
3949
- },
3950
- 'CompensationMarker': function(parentGfx, element, attrs, position) {
3951
- attrs = assign({
3952
- strokeWidth: 1,
3920
+ drawMarker('sequential', parentGfx, markerPath, {
3953
3921
  fill: getFillColor(element, defaultFillColor),
3954
3922
  stroke: getStrokeColor(element, defaultStrokeColor)
3955
- }, attrs);
3956
-
3923
+ });
3924
+ },
3925
+ 'CompensationMarker': function(parentGfx, element, position) {
3957
3926
  var markerMath = pathMap.getScaledPath('MARKER_COMPENSATION', {
3958
3927
  xScaleFactor: 1,
3959
3928
  yScaleFactor: 1,
@@ -3965,17 +3934,13 @@
3965
3934
  }
3966
3935
  });
3967
3936
 
3968
- drawMarker('compensation', parentGfx, markerMath, attrs);
3969
- },
3970
- 'LoopMarker': function(parentGfx, element, attrs, position) {
3971
- attrs = assign({
3937
+ drawMarker('compensation', parentGfx, markerMath, {
3972
3938
  strokeWidth: 1,
3973
3939
  fill: getFillColor(element, defaultFillColor),
3974
- stroke: getStrokeColor(element, defaultStrokeColor),
3975
- strokeLinecap: 'round',
3976
- strokeMiterlimit: 0.5
3977
- }, attrs);
3978
-
3940
+ stroke: getStrokeColor(element, defaultStrokeColor)
3941
+ });
3942
+ },
3943
+ 'LoopMarker': function(parentGfx, element, position) {
3979
3944
  var markerPath = pathMap.getScaledPath('MARKER_LOOP', {
3980
3945
  xScaleFactor: 1,
3981
3946
  yScaleFactor: 1,
@@ -3987,15 +3952,15 @@
3987
3952
  }
3988
3953
  });
3989
3954
 
3990
- drawMarker('loop', parentGfx, markerPath, attrs);
3991
- },
3992
- 'AdhocMarker': function(parentGfx, element, attrs, position) {
3993
- attrs = assign({
3955
+ drawMarker('loop', parentGfx, markerPath, {
3994
3956
  strokeWidth: 1,
3995
- fill: getStrokeColor(element, defaultStrokeColor),
3996
- stroke: getStrokeColor(element, defaultStrokeColor)
3997
- }, attrs);
3998
-
3957
+ fill: getFillColor(element, defaultFillColor),
3958
+ stroke: getStrokeColor(element, defaultStrokeColor),
3959
+ strokeLinecap: 'round',
3960
+ strokeMiterlimit: 0.5
3961
+ });
3962
+ },
3963
+ 'AdhocMarker': function(parentGfx, element, position) {
3999
3964
  var markerPath = pathMap.getScaledPath('MARKER_ADHOC', {
4000
3965
  xScaleFactor: 1,
4001
3966
  yScaleFactor: 1,
@@ -4007,11 +3972,15 @@
4007
3972
  }
4008
3973
  });
4009
3974
 
4010
- drawMarker('adhoc', parentGfx, markerPath, attrs);
3975
+ drawMarker('adhoc', parentGfx, markerPath, {
3976
+ strokeWidth: 1,
3977
+ fill: getStrokeColor(element, defaultStrokeColor),
3978
+ stroke: getStrokeColor(element, defaultStrokeColor)
3979
+ });
4011
3980
  }
4012
3981
  };
4013
3982
 
4014
- function attachTaskMarkers(parentGfx, element, attrs, taskMarkers) {
3983
+ function attachTaskMarkers(parentGfx, element, taskMarkers) {
4015
3984
  var obj = getSemantic(element);
4016
3985
 
4017
3986
  var subprocess = taskMarkers && taskMarkers.indexOf('SubProcessMarker') !== -1;
@@ -4036,15 +4005,15 @@
4036
4005
  }
4037
4006
 
4038
4007
  forEach(taskMarkers, function(marker) {
4039
- renderer(marker)(parentGfx, element, attrs, position);
4008
+ renderer(marker)(parentGfx, element, position);
4040
4009
  });
4041
4010
 
4042
4011
  if (obj.isForCompensation) {
4043
- renderer('CompensationMarker')(parentGfx, element, attrs, position);
4012
+ renderer('CompensationMarker')(parentGfx, element, position);
4044
4013
  }
4045
4014
 
4046
4015
  if (obj.$type === 'bpmn:AdHocSubProcess') {
4047
- renderer('AdhocMarker')(parentGfx, element, attrs, position);
4016
+ renderer('AdhocMarker')(parentGfx, element, position);
4048
4017
  }
4049
4018
 
4050
4019
  var loopCharacteristics = obj.loopCharacteristics,
@@ -4053,23 +4022,20 @@
4053
4022
  if (loopCharacteristics) {
4054
4023
 
4055
4024
  if (isSequential === undefined) {
4056
- renderer('LoopMarker')(parentGfx, element, attrs, position);
4025
+ renderer('LoopMarker')(parentGfx, element, position);
4057
4026
  }
4058
4027
 
4059
4028
  if (isSequential === false) {
4060
- renderer('ParallelMarker')(parentGfx, element, attrs, position);
4029
+ renderer('ParallelMarker')(parentGfx, element, position);
4061
4030
  }
4062
4031
 
4063
4032
  if (isSequential === true) {
4064
- renderer('SequentialMarker')(parentGfx, element, attrs, position);
4033
+ renderer('SequentialMarker')(parentGfx, element, position);
4065
4034
  }
4066
4035
  }
4067
4036
  }
4068
4037
 
4069
- function renderDataItemCollection(parentGfx, element, attrs) {
4070
- attrs = assign({
4071
- strokeWidth: 2
4072
- }, attrs);
4038
+ function renderDataItemCollection(parentGfx, element) {
4073
4039
 
4074
4040
  var yPosition = (element.height - 18) / element.height;
4075
4041
 
@@ -4084,13 +4050,16 @@
4084
4050
  }
4085
4051
  });
4086
4052
 
4087
- /* collection path */ drawPath(parentGfx, pathData, attrs);
4053
+ /* collection path */ drawPath(parentGfx, pathData, {
4054
+ strokeWidth: 2
4055
+ });
4088
4056
  }
4089
4057
 
4090
4058
 
4091
4059
  // extension API, use at your own risk
4092
4060
  this._drawPath = drawPath;
4093
4061
 
4062
+ this._renderer = renderer;
4094
4063
  }
4095
4064
 
4096
4065
 
@@ -4110,20 +4079,20 @@
4110
4079
  return is$1(element, 'bpmn:BaseElement');
4111
4080
  };
4112
4081
 
4113
- BpmnRenderer.prototype.drawShape = function(parentGfx, element, attrs) {
4082
+ BpmnRenderer.prototype.drawShape = function(parentGfx, element) {
4114
4083
  var type = element.type;
4115
- var h = this.handlers[type];
4084
+ var h = this._renderer(type);
4116
4085
 
4117
4086
  /* jshint -W040 */
4118
- return h(parentGfx, element, attrs);
4087
+ return h(parentGfx, element);
4119
4088
  };
4120
4089
 
4121
- BpmnRenderer.prototype.drawConnection = function(parentGfx, element, attrs) {
4090
+ BpmnRenderer.prototype.drawConnection = function(parentGfx, element) {
4122
4091
  var type = element.type;
4123
- var h = this.handlers[type];
4092
+ var h = this._renderer(type);
4124
4093
 
4125
4094
  /* jshint -W040 */
4126
- return h(parentGfx, element, attrs);
4095
+ return h(parentGfx, element);
4127
4096
  };
4128
4097
 
4129
4098
  BpmnRenderer.prototype.getShapePath = function(element) {
@@ -5330,6 +5299,13 @@
5330
5299
  return '<' + e.$type + (e.id ? ' id="' + e.id : '') + '" />';
5331
5300
  }
5332
5301
 
5302
+ /**
5303
+ * @param {ModdleElement} semantic
5304
+ * @param {ModdleElement} di
5305
+ * @param {Object} [attrs=null]
5306
+ *
5307
+ * @return {Object}
5308
+ */
5333
5309
  function elementData(semantic, di, attrs) {
5334
5310
  return assign({
5335
5311
  id: semantic.id,
@@ -5352,32 +5328,6 @@
5352
5328
  });
5353
5329
  }
5354
5330
 
5355
- var PLANE_PADDING = 50;
5356
-
5357
- function getPlaneBounds(plane) {
5358
- var planeTrbl = {
5359
- top: Infinity,
5360
- right: -Infinity,
5361
- bottom: -Infinity,
5362
- left: Infinity
5363
- };
5364
-
5365
- plane.planeElement.forEach(function(element) {
5366
- if (!element.bounds) {
5367
- return;
5368
- }
5369
-
5370
- var trbl = asTRBL(element.bounds);
5371
-
5372
- planeTrbl.top = Math.min(trbl.top, planeTrbl.top);
5373
- planeTrbl.left = Math.min(trbl.left, planeTrbl.left);
5374
- planeTrbl.right = Math.max(trbl.right, planeTrbl.right);
5375
- planeTrbl.bottom = Math.max(trbl.bottom, planeTrbl.bottom);
5376
- });
5377
-
5378
- return asBounds(planeTrbl);
5379
- }
5380
-
5381
5331
  function notYetDrawn(translate, semantic, refSemantic, property) {
5382
5332
  return new Error(translate('element {element} referenced by {referenced}#{property} not yet drawn', {
5383
5333
  element: elementToString(refSemantic),
@@ -5432,39 +5382,17 @@
5432
5382
 
5433
5383
  // ROOT ELEMENT
5434
5384
  // handle the special case that we deal with a
5435
- // invisible root element (process or collaboration)
5385
+ // invisible root element (process, subprocess or collaboration)
5436
5386
  if (is$1(di, 'bpmndi:BPMNPlane')) {
5437
5387
 
5438
- if (is$1(semantic, 'bpmn:SubProcess')) {
5439
- var plane = this._canvas.createPlane(semantic.id, element);
5440
-
5441
- // Get size of expanded element
5442
- var bounds = getPlaneBounds(di);
5443
-
5444
- var primary = this._elementRegistry.get(semantic.id);
5445
- element = this._elementFactory.createShape(elementData(semantic, di, {
5446
- collapsed: false,
5447
- hidden: false,
5448
- x: bounds.x - PLANE_PADDING,
5449
- y: bounds.y - PLANE_PADDING,
5450
- width: bounds.width + PLANE_PADDING * 2,
5451
- height: bounds.height + PLANE_PADDING * 2,
5452
- isFrame: true
5453
- }));
5454
-
5455
- element.id = element.id + '_secondary';
5456
- element.isSecondary = true;
5457
- element.primaryShape = primary;
5388
+ var attrs = is$1(semantic, 'bpmn:SubProcess')
5389
+ ? { id: semantic.id + '_plane' }
5390
+ : {};
5458
5391
 
5459
- this._canvas.addShape(element, plane.rootElement);
5460
- }
5461
- else {
5462
-
5463
- // add a virtual element (not being drawn)
5464
- element = this._elementFactory.createRoot(elementData(semantic, di));
5392
+ // add a virtual element (not being drawn)
5393
+ element = this._elementFactory.createRoot(elementData(semantic, di, attrs));
5465
5394
 
5466
- this._canvas.createPlane(semantic.id, element);
5467
- }
5395
+ this._canvas.addRootElement(element);
5468
5396
  }
5469
5397
 
5470
5398
  // SHAPE
@@ -5475,7 +5403,7 @@
5475
5403
 
5476
5404
  hidden = parentElement && (parentElement.hidden || parentElement.collapsed);
5477
5405
 
5478
- bounds = di.bounds;
5406
+ var bounds = di.bounds;
5479
5407
 
5480
5408
  element = this._elementFactory.createShape(elementData(semantic, di, {
5481
5409
  collapsed: collapsed,
@@ -5500,7 +5428,7 @@
5500
5428
 
5501
5429
  // check whether data store is inside our outside of its semantic parent
5502
5430
  if (!isPointInsideBBox(parentElement, getMid(bounds))) {
5503
- parentElement = this._canvas.findPlane(parentElement).rootElement;
5431
+ parentElement = this._canvas.findRoot(parentElement);
5504
5432
  }
5505
5433
  }
5506
5434
 
@@ -5528,7 +5456,7 @@
5528
5456
  // are rendered correctly across different "hacks" people
5529
5457
  // love to model such as cross participant / sub process
5530
5458
  // associations
5531
- parentElement = this._canvas.findPlane(parentElement).rootElement;
5459
+ parentElement = this._canvas.findRoot(parentElement);
5532
5460
  }
5533
5461
 
5534
5462
  // insert sequence flows behind other flow nodes (cf. #727)
@@ -5779,7 +5707,7 @@
5779
5707
  return isPrimaryButton(event) || isAuxiliaryButton(event);
5780
5708
  }
5781
5709
 
5782
- var LOW_PRIORITY$3 = 500;
5710
+ var LOW_PRIORITY$4 = 500;
5783
5711
 
5784
5712
 
5785
5713
  /**
@@ -5974,7 +5902,7 @@
5974
5902
  eventBus.on([
5975
5903
  'shape.changed',
5976
5904
  'connection.changed'
5977
- ], LOW_PRIORITY$3, function(event) {
5905
+ ], LOW_PRIORITY$4, function(event) {
5978
5906
 
5979
5907
  var element = event.element,
5980
5908
  gfx = event.gfx;
@@ -5982,7 +5910,7 @@
5982
5910
  eventBus.fire('interactionEvents.updateHit', { element: element, gfx: gfx });
5983
5911
  });
5984
5912
 
5985
- eventBus.on('interactionEvents.createHit', LOW_PRIORITY$3, function(event) {
5913
+ eventBus.on('interactionEvents.createHit', LOW_PRIORITY$4, function(event) {
5986
5914
  var element = event.element,
5987
5915
  gfx = event.gfx;
5988
5916
 
@@ -6256,97 +6184,6 @@
6256
6184
  interactionEvents: [ 'type', InteractionEvents ]
6257
6185
  };
6258
6186
 
6259
- /**
6260
- * Adds an element to a collection and returns true if the
6261
- * element was added.
6262
- *
6263
- * @param {Array<Object>} elements
6264
- * @param {Object} e
6265
- * @param {boolean} unique
6266
- */
6267
- function add$1(elements, e, unique) {
6268
- var canAdd = !unique || elements.indexOf(e) === -1;
6269
-
6270
- if (canAdd) {
6271
- elements.push(e);
6272
- }
6273
-
6274
- return canAdd;
6275
- }
6276
-
6277
-
6278
- /**
6279
- * Iterate over each element in a collection, calling the iterator function `fn`
6280
- * with (element, index, recursionDepth).
6281
- *
6282
- * Recurse into all elements that are returned by `fn`.
6283
- *
6284
- * @param {Object|Array<Object>} elements
6285
- * @param {Function} fn iterator function called with (element, index, recursionDepth)
6286
- * @param {number} [depth] maximum recursion depth
6287
- */
6288
- function eachElement(elements, fn, depth) {
6289
-
6290
- depth = depth || 0;
6291
-
6292
- if (!isArray$1(elements)) {
6293
- elements = [ elements ];
6294
- }
6295
-
6296
- forEach(elements, function(s, i) {
6297
- var filter = fn(s, i, depth);
6298
-
6299
- if (isArray$1(filter) && filter.length) {
6300
- eachElement(filter, fn, depth + 1);
6301
- }
6302
- });
6303
- }
6304
-
6305
-
6306
- /**
6307
- * Collects self + child elements up to a given depth from a list of elements.
6308
- *
6309
- * @param {djs.model.Base|Array<djs.model.Base>} elements the elements to select the children from
6310
- * @param {boolean} unique whether to return a unique result set (no duplicates)
6311
- * @param {number} maxDepth the depth to search through or -1 for infinite
6312
- *
6313
- * @return {Array<djs.model.Base>} found elements
6314
- */
6315
- function selfAndChildren(elements, unique, maxDepth) {
6316
- var result = [],
6317
- processedChildren = [];
6318
-
6319
- eachElement(elements, function(element, i, depth) {
6320
- add$1(result, element, unique);
6321
-
6322
- var children = element.children;
6323
-
6324
- // max traversal depth not reached yet
6325
- if (maxDepth === -1 || depth < maxDepth) {
6326
-
6327
- // children exist && children not yet processed
6328
- if (children && add$1(processedChildren, children, unique)) {
6329
- return children;
6330
- }
6331
- }
6332
- });
6333
-
6334
- return result;
6335
- }
6336
-
6337
-
6338
- /**
6339
- * Return self + ALL children for a number of elements
6340
- *
6341
- * @param {Array<djs.model.Base>} elements to query
6342
- * @param {boolean} allowDuplicates to allow duplicates in the result set
6343
- *
6344
- * @return {Array<djs.model.Base>} the collected elements
6345
- */
6346
- function selfAndAllChildren(elements, allowDuplicates) {
6347
- return selfAndChildren(elements, !allowDuplicates, -1);
6348
- }
6349
-
6350
6187
  /**
6351
6188
  * Returns the surrounding bbox for all elements in
6352
6189
  * the array or the element primitive.
@@ -6421,7 +6258,7 @@
6421
6258
  return !!(element && element.isFrame);
6422
6259
  }
6423
6260
 
6424
- var LOW_PRIORITY$2 = 500;
6261
+ var LOW_PRIORITY$3 = 500;
6425
6262
 
6426
6263
 
6427
6264
  /**
@@ -6459,7 +6296,7 @@
6459
6296
 
6460
6297
  // A low priortity is necessary, because outlines of labels have to be updated
6461
6298
  // after the label bounds have been updated in the renderer.
6462
- eventBus.on([ 'shape.added', 'shape.changed' ], LOW_PRIORITY$2, function(event) {
6299
+ eventBus.on([ 'shape.added', 'shape.changed' ], LOW_PRIORITY$3, function(event) {
6463
6300
  var element = event.element,
6464
6301
  gfx = event.gfx;
6465
6302
 
@@ -6556,7 +6393,7 @@
6556
6393
  self.deselect(element);
6557
6394
  });
6558
6395
 
6559
- eventBus.on([ 'diagram.clear', 'plane.set' ], function(e) {
6396
+ eventBus.on([ 'diagram.clear', 'root.set' ], function(e) {
6560
6397
  self.select(null);
6561
6398
  });
6562
6399
  }
@@ -6609,10 +6446,12 @@
6609
6446
 
6610
6447
  var canvas = this._canvas;
6611
6448
 
6449
+ var rootElement = canvas.getRootElement();
6450
+
6612
6451
  elements = elements.filter(function(element) {
6613
- var plane = canvas.findPlane(element);
6452
+ var elementRoot = canvas.findRoot(element);
6614
6453
 
6615
- return plane === canvas.getActivePlane();
6454
+ return rootElement === elementRoot;
6616
6455
  });
6617
6456
 
6618
6457
  // selection may be cleared by passing an empty array or null
@@ -6853,7 +6692,7 @@
6853
6692
  // document wide unique overlay ids
6854
6693
  var ids = new IdGenerator('ov');
6855
6694
 
6856
- var LOW_PRIORITY$1 = 500;
6695
+ var LOW_PRIORITY$2 = 500;
6857
6696
 
6858
6697
 
6859
6698
  /**
@@ -7083,8 +6922,7 @@
7083
6922
  *
7084
6923
  * @see Overlays#get for filter options.
7085
6924
  *
7086
- * @param {string} [id]
7087
- * @param {Object} [filter]
6925
+ * @param {string|object} [filter]
7088
6926
  */
7089
6927
  Overlays.prototype.remove = function(filter) {
7090
6928
 
@@ -7200,6 +7038,7 @@
7200
7038
  }
7201
7039
 
7202
7040
  setPosition(htmlContainer, left || 0, top || 0);
7041
+ this._updateOverlayVisibilty(overlay, this._canvas.viewbox());
7203
7042
  };
7204
7043
 
7205
7044
 
@@ -7283,12 +7122,10 @@
7283
7122
  classes(htmlContainer).add('djs-overlay-' + overlay.type);
7284
7123
  }
7285
7124
 
7286
- var plane = this._canvas.findPlane(element);
7287
- var activePlane = this._canvas.getActivePlane();
7288
- overlay.plane = plane;
7289
- if (plane !== activePlane) {
7290
- setVisible(htmlContainer, false);
7291
- }
7125
+ var elementRoot = this._canvas.findRoot(element);
7126
+ var activeRoot = this._canvas.getRootElement();
7127
+
7128
+ setVisible(htmlContainer, elementRoot === activeRoot);
7292
7129
 
7293
7130
  overlay.htmlContainer = htmlContainer;
7294
7131
 
@@ -7304,14 +7141,14 @@
7304
7141
 
7305
7142
  Overlays.prototype._updateOverlayVisibilty = function(overlay, viewbox) {
7306
7143
  var show = overlay.show,
7307
- plane = overlay.plane,
7144
+ rootElement = this._canvas.findRoot(overlay.element),
7308
7145
  minZoom = show && show.minZoom,
7309
7146
  maxZoom = show && show.maxZoom,
7310
7147
  htmlContainer = overlay.htmlContainer,
7311
- activePlane = this._canvas.getActivePlane(),
7148
+ activeRootElement = this._canvas.getRootElement(),
7312
7149
  visible = true;
7313
7150
 
7314
- if (plane !== activePlane) {
7151
+ if (rootElement !== activeRootElement) {
7315
7152
  visible = false;
7316
7153
  } else if (show) {
7317
7154
  if (
@@ -7422,7 +7259,7 @@
7422
7259
 
7423
7260
  // move integration
7424
7261
 
7425
- eventBus.on('element.changed', LOW_PRIORITY$1, function(e) {
7262
+ eventBus.on('element.changed', LOW_PRIORITY$2, function(e) {
7426
7263
  var element = e.element;
7427
7264
 
7428
7265
  var container = self._getOverlayContainer(element, true);
@@ -7447,10 +7284,8 @@
7447
7284
  });
7448
7285
 
7449
7286
 
7450
- eventBus.on('plane.set', function(e) {
7451
- forEach(self._overlays, function(el) {
7452
- setVisible(el.htmlContainer, el.plane === e.plane);
7453
- });
7287
+ eventBus.on('root.set', function() {
7288
+ self._updateOverlaysVisibilty(self._canvas.viewbox());
7454
7289
  });
7455
7290
 
7456
7291
  // clear overlays with diagram
@@ -7563,250 +7398,184 @@
7563
7398
  changeSupport: [ 'type', ChangeSupport ]
7564
7399
  };
7565
7400
 
7566
- function SubprocessElements(eventBus, elementRegistry, canvas, elementFactory) {
7567
- var attachBoundaries = function() {
7568
- var secondaryShapes = elementRegistry.filter(function(el) {
7569
- return is$1(el, 'bpmn:SubProcess') && el.isSecondary;
7570
- });
7571
-
7572
- secondaryShapes.forEach(function(process) {
7573
-
7574
- // Add Boundary events
7575
- if (process.primaryShape && process.primaryShape.attachers) {
7576
- process.primaryShape.attachers.forEach(function(boundary) {
7577
- var bo = getBusinessObject(boundary);
7578
-
7579
- var primary = process.primaryShape;
7580
-
7581
- var relativeXPos = (boundary.x + 15 - primary.x) / primary.width;
7582
- var relativeYPos = (boundary.y + 15 - primary.y) / primary.height;
7583
-
7584
- var dx = process.x + (process.width * relativeXPos) - 15;
7585
- var dy = process.y + (process.height * relativeYPos) - 15;
7586
-
7587
- var boundaryShape = elementFactory.createShape({
7588
- id: bo.id + '_secondary',
7589
- businessObject: bo,
7590
- type: 'bpmn:BoundaryEvent',
7591
- hidden: false,
7592
- x: dx,
7593
- y: dy,
7594
- width: 30,
7595
- height: 30,
7596
- isFrame: false,
7597
- isSecondary: true,
7598
- primaryShape: boundary,
7599
- di: boundary.di
7600
- });
7401
+ var DEFAULT_PRIORITY$2 = 1000;
7601
7402
 
7602
- canvas.addShape(boundaryShape, process.parent);
7403
+ /**
7404
+ * A utility that can be used to plug-in into the command execution for
7405
+ * extension and/or validation.
7406
+ *
7407
+ * @param {EventBus} eventBus
7408
+ *
7409
+ * @example
7410
+ *
7411
+ * import inherits from 'inherits';
7412
+ *
7413
+ * import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
7414
+ *
7415
+ * function CommandLogger(eventBus) {
7416
+ * CommandInterceptor.call(this, eventBus);
7417
+ *
7418
+ * this.preExecute(function(event) {
7419
+ * console.log('command pre-execute', event);
7420
+ * });
7421
+ * }
7422
+ *
7423
+ * inherits(CommandLogger, CommandInterceptor);
7424
+ *
7425
+ */
7426
+ function CommandInterceptor(eventBus) {
7427
+ this._eventBus = eventBus;
7428
+ }
7603
7429
 
7604
- if (!process.attachers) {
7605
- process.attachers = [];
7606
- }
7430
+ CommandInterceptor.$inject = [ 'eventBus' ];
7607
7431
 
7608
- process.attachers.push(boundaryShape);
7609
- });
7610
- }
7611
- });
7432
+ function unwrapEvent(fn, that) {
7433
+ return function(event) {
7434
+ return fn.call(that || null, event.context, event.command, event);
7612
7435
  };
7613
-
7614
- eventBus.on('import.done', attachBoundaries);
7615
7436
  }
7616
7437
 
7438
+ /**
7439
+ * Register an interceptor for a command execution
7440
+ *
7441
+ * @param {string|Array<string>} [events] list of commands to register on
7442
+ * @param {string} [hook] command hook, i.e. preExecute, executed to listen on
7443
+ * @param {number} [priority] the priority on which to hook into the execution
7444
+ * @param {Function} handlerFn interceptor to be invoked with (event)
7445
+ * @param {boolean} unwrap if true, unwrap the event and pass (context, command, event) to the
7446
+ * listener instead
7447
+ * @param {Object} [that] Pass context (`this`) to the handler function
7448
+ */
7449
+ CommandInterceptor.prototype.on = function(events, hook, priority, handlerFn, unwrap, that) {
7617
7450
 
7618
- SubprocessElements.$inject = [ 'eventBus', 'elementRegistry', 'canvas', 'elementFactory' ];
7619
-
7620
- var defaultPosition = { x: 100, y: 50 };
7621
-
7622
- function SubprocessCentering(eventBus, canvas) {
7623
- var currentPlane = 'base';
7624
- var positionMap = {};
7451
+ if (isFunction(hook) || isNumber(hook)) {
7452
+ that = unwrap;
7453
+ unwrap = handlerFn;
7454
+ handlerFn = priority;
7455
+ priority = hook;
7456
+ hook = null;
7457
+ }
7625
7458
 
7626
- eventBus.on('plane.set', function(event) {
7459
+ if (isFunction(priority)) {
7460
+ that = unwrap;
7461
+ unwrap = handlerFn;
7462
+ handlerFn = priority;
7463
+ priority = DEFAULT_PRIORITY$2;
7464
+ }
7627
7465
 
7628
- var currentViewbox = canvas.viewbox();
7629
- positionMap[currentPlane] = {
7630
- x: currentViewbox.x,
7631
- y: currentViewbox.y,
7632
- zoom: currentViewbox.scale
7633
- };
7466
+ if (isObject(unwrap)) {
7467
+ that = unwrap;
7468
+ unwrap = false;
7469
+ }
7634
7470
 
7635
- var planeId = event.plane.name;
7636
- var storedViewbox = positionMap[planeId];
7471
+ if (!isFunction(handlerFn)) {
7472
+ throw new Error('handlerFn must be a function');
7473
+ }
7637
7474
 
7638
- if (!storedViewbox) {
7639
- if (!event.plane.rootElement.isImplicit) {
7640
- storedViewbox = {
7641
- x: 0,
7642
- y: 0,
7643
- zoom: 1
7644
- };
7645
- }
7646
- else {
7647
- var currentBoundingBox = canvas.getActiveLayer().getBBox();
7648
- storedViewbox = {
7649
- x: currentBoundingBox.x - defaultPosition.x,
7650
- y: currentBoundingBox.y - defaultPosition.y,
7651
- zoom: 1
7652
- };
7653
- }
7654
- }
7475
+ if (!isArray$1(events)) {
7476
+ events = [ events ];
7477
+ }
7655
7478
 
7656
- var dx = (currentViewbox.x - storedViewbox.x) * currentViewbox.scale,
7657
- dy = (currentViewbox.y - storedViewbox.y) * currentViewbox.scale;
7479
+ var eventBus = this._eventBus;
7658
7480
 
7659
- if (dx !== 0 || dy !== 0) {
7660
- canvas.scroll({
7661
- dx: dx,
7662
- dy: dy
7663
- });
7664
- }
7481
+ forEach(events, function(event) {
7665
7482
 
7666
- if (storedViewbox.zoom !== currentViewbox.scale) {
7667
- canvas.zoom(storedViewbox.zoom, { x: 0, y: 0 });
7668
- }
7483
+ // concat commandStack(.event)?(.hook)?
7484
+ var fullEvent = [ 'commandStack', event, hook ].filter(function(e) { return e; }).join('.');
7669
7485
 
7670
- currentPlane = planeId;
7486
+ eventBus.on(fullEvent, priority, unwrap ? unwrapEvent(handlerFn, that) : handlerFn, that);
7671
7487
  });
7672
- }
7673
-
7674
- SubprocessCentering.$inject = [ 'eventBus', 'canvas' ];
7675
-
7676
- function SubprocessCompatibility(eventBus, elementRegistry, canvas, moddle, elementFactory, bpmnjs) {
7677
- this._eventBus = eventBus;
7678
- this._elementRegistry = elementRegistry;
7679
- this._canvas = canvas;
7680
- this._bpmnjs = bpmnjs;
7681
- this._moddle = moddle;
7682
- this._elementFactory = elementFactory;
7683
-
7684
- var self = this;
7488
+ };
7685
7489
 
7686
- eventBus.on('import.done', 1500, function() {
7687
- self._handleImport();
7688
- });
7689
- }
7690
7490
 
7691
- SubprocessCompatibility.prototype._handleImport = function() {
7692
- var elementRegistry = this._elementRegistry;
7693
- var canvas = this._canvas;
7694
- var elementFactory = this._elementFactory;
7695
- var self = this;
7696
- var legacyProcesses = elementRegistry.filter(function(element) {
7697
- return is$1(element, 'bpmn:SubProcess') && !isExpanded(element) && element.children && element.children.length;
7698
- });
7491
+ var hooks = [
7492
+ 'canExecute',
7493
+ 'preExecute',
7494
+ 'preExecuted',
7495
+ 'execute',
7496
+ 'executed',
7497
+ 'postExecute',
7498
+ 'postExecuted',
7499
+ 'revert',
7500
+ 'reverted'
7501
+ ];
7699
7502
 
7700
- legacyProcesses.forEach(function(oldParent) {
7701
- var bo = getBusinessObject(oldParent);
7503
+ /*
7504
+ * Install hook shortcuts
7505
+ *
7506
+ * This will generate the CommandInterceptor#(preExecute|...|reverted) methods
7507
+ * which will in term forward to CommandInterceptor#on.
7508
+ */
7509
+ forEach(hooks, function(hook) {
7702
7510
 
7703
- var newDiagram = self.createDiagram(bo);
7511
+ /**
7512
+ * {canExecute|preExecute|preExecuted|execute|executed|postExecute|postExecuted|revert|reverted}
7513
+ *
7514
+ * A named hook for plugging into the command execution
7515
+ *
7516
+ * @param {string|Array<string>} [events] list of commands to register on
7517
+ * @param {number} [priority] the priority on which to hook into the execution
7518
+ * @param {Function} handlerFn interceptor to be invoked with (event)
7519
+ * @param {boolean} [unwrap=false] if true, unwrap the event and pass (context, command, event) to the
7520
+ * listener instead
7521
+ * @param {Object} [that] Pass context (`this`) to the handler function
7522
+ */
7523
+ CommandInterceptor.prototype[hook] = function(events, priority, handlerFn, unwrap, that) {
7704
7524
 
7705
- var newParent = elementFactory.createRoot(
7706
- {
7707
- id: bo.id,
7708
- type: bo.$type,
7709
- businessObject: bo,
7710
- di: newDiagram.plane
7711
- }
7712
- );
7525
+ if (isFunction(events) || isNumber(events)) {
7526
+ that = unwrap;
7527
+ unwrap = handlerFn;
7528
+ handlerFn = priority;
7529
+ priority = events;
7530
+ events = null;
7531
+ }
7713
7532
 
7714
- newParent.id = newParent.id + '_plane';
7533
+ this.on(events, hook, priority, handlerFn, unwrap, that);
7534
+ };
7535
+ });
7715
7536
 
7716
- canvas.createPlane(bo.id, newParent);
7537
+ /**
7538
+ * A modeling behavior that ensures we set the correct root element
7539
+ * as we undo and redo commands.
7540
+ *
7541
+ * @param {Canvas} canvas
7542
+ * @param {didi.Injector} injector
7543
+ */
7544
+ function RootElementsBehavior(canvas, injector) {
7717
7545
 
7718
- var elementsToChange = selfAndAllChildren(oldParent).filter(function(el) {
7719
- return el !== oldParent;
7720
- });
7546
+ injector.invoke(CommandInterceptor, this);
7721
7547
 
7722
- self.moveElementsToRoot(elementsToChange);
7548
+ this.executed(function(event) {
7549
+ var context = event.context;
7723
7550
 
7724
- elementsToChange.forEach(function(el) {
7725
- if (el.parent === oldParent) {
7726
- el.parent = newParent;
7727
- }
7728
- el.hidden = el.parent && (el.parent.hidden || el.parent.collapsed);
7551
+ if (context.rootElement) {
7552
+ canvas.setRootElement(context.rootElement);
7553
+ } else {
7554
+ context.rootElement = canvas.getRootElement();
7555
+ }
7556
+ });
7729
7557
 
7730
- self.moveToDiPlane(el, newDiagram.plane);
7558
+ this.revert(function(event) {
7559
+ var context = event.context;
7731
7560
 
7732
- self._eventBus.fire('elements.changed', { elements: [el] });
7733
- });
7561
+ if (context.rootElement) {
7562
+ canvas.setRootElement(context.rootElement);
7563
+ }
7734
7564
  });
7565
+ }
7735
7566
 
7736
- };
7567
+ inherits$1(RootElementsBehavior, CommandInterceptor);
7737
7568
 
7738
- SubprocessCompatibility.prototype.moveToDiPlane = function(element, newPlane) {
7739
- var di = getDi(element);
7740
- var containingDiagram = findRootDiagram(di);
7569
+ RootElementsBehavior.$inject = [ 'canvas', 'injector'];
7741
7570
 
7742
- // Remove DI from old Plane and add it to the new one
7743
- var parentPlaneElement = containingDiagram.plane.get('planeElement');
7744
- parentPlaneElement.splice(parentPlaneElement.indexOf(di), 1);
7745
- newPlane.get('planeElement').push(di);
7571
+ var RootElementsModule = {
7572
+ __init__: [ 'rootElementsBehavior' ],
7573
+ rootElementsBehavior: [ 'type', RootElementsBehavior ]
7746
7574
  };
7747
7575
 
7748
- SubprocessCompatibility.prototype.moveElementsToRoot = function(elements) {
7749
- var defaultPosition = { x: 180, y: 160 },
7750
- minX = Infinity,
7751
- minY = Infinity;
7752
-
7753
- elements.forEach(function(el) {
7754
- minX = Math.min(minX, el.x || Infinity);
7755
- minY = Math.min(minY, el.y || Infinity);
7756
- });
7576
+ var css_escape = {exports: {}};
7757
7577
 
7758
- var xOffset = defaultPosition.x - minX;
7759
- var yOffset = defaultPosition.y - minY;
7760
-
7761
- elements.forEach(function(el) {
7762
- if (el.waypoints) {
7763
- el.waypoints.forEach(function(waypoint) {
7764
- waypoint.x = waypoint.x + xOffset;
7765
- waypoint.y = waypoint.y + yOffset;
7766
- });
7767
- } else {
7768
- el.x = el.x + xOffset;
7769
- el.y = el.y + yOffset;
7770
- }
7771
- });
7772
- };
7773
-
7774
- SubprocessCompatibility.prototype.getDefinitions = function() {
7775
- return this._bpmnjs._definitions || [];
7776
- };
7777
-
7778
- SubprocessCompatibility.prototype.getDiagrams = function() {
7779
- return this.getDefinitions().diagrams || [];
7780
- };
7781
-
7782
- SubprocessCompatibility.prototype.createDiagram = function(bo) {
7783
- var plane = this._moddle.create('bpmndi:BPMNPlane', { bpmnElement: bo });
7784
- var diagram = this._moddle.create('bpmndi:BPMNDiagram', {
7785
- plane: plane
7786
- });
7787
- plane.$parent = diagram;
7788
- plane.bpmnElement = bo;
7789
- diagram.$parent = this.getDefinitions();
7790
- this.getDiagrams().push(diagram);
7791
- return diagram;
7792
- };
7793
-
7794
- SubprocessCompatibility.$inject = [ 'eventBus', 'elementRegistry', 'canvas', 'moddle', 'elementFactory', 'bpmnjs' ];
7795
-
7796
-
7797
- // Util
7798
-
7799
- var findRootDiagram = function(element) {
7800
- if (is$1(element, 'bpmndi:BPMNDiagram')) {
7801
- return element;
7802
- } else {
7803
- return findRootDiagram(element.$parent);
7804
- }
7805
- };
7806
-
7807
- var css_escape = {exports: {}};
7808
-
7809
- /*! https://mths.be/cssescape v1.5.1 by @mathias | MIT license */
7578
+ /*! https://mths.be/cssescape v1.5.1 by @mathias | MIT license */
7810
7579
 
7811
7580
  (function (module, exports) {
7812
7581
  (function(root, factory) {
@@ -7926,224 +7695,640 @@
7926
7695
  });
7927
7696
  }
7928
7697
 
7929
- var ARROW_DOWN_SVG = '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4.81801948,3.50735931 L10.4996894,9.1896894 L10.5,4 L12,4 L12,12 L4,12 L4,10.5 L9.6896894,10.4996894 L3.75735931,4.56801948 C3.46446609,4.27512627 3.46446609,3.80025253 3.75735931,3.50735931 C4.05025253,3.21446609 4.52512627,3.21446609 4.81801948,3.50735931 Z"/></svg>';
7930
- var ARROW_UP_SVG = '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M11.1819805,12.4926407 L5.5003106,6.8103106 L5.5,12 L4,12 L4,4 L12,4 L12,5.5 L6.3103106,5.5003106 L12.2426407,11.4319805 C12.5355339,11.7248737 12.5355339,12.1997475 12.2426407,12.4926407 C11.9497475,12.7855339 11.4748737,12.7855339 11.1819805,12.4926407 Z"/></svg>';
7698
+ var planeSuffix = '_plane';
7931
7699
 
7932
- function SubprocessOverlays(eventBus, elementRegistry, overlays, canvas) {
7700
+ /**
7701
+ * Get plane ID for a primary shape.
7702
+ *
7703
+ * @param {djs.model.Base|ModdleElement} element
7704
+ *
7705
+ * @returns {String}
7706
+ */
7707
+ function getPlaneIdFromShape(element) {
7708
+ var id = element.id;
7709
+
7710
+ if (is$1(element, 'bpmn:SubProcess')) {
7711
+ return addPlaneSuffix(id);
7712
+ }
7933
7713
 
7934
- function createBreadcrumbs(subProcess) {
7935
- var breadcrumbs = domify('<ul class="bjs-breadcrumbs"></ul>');
7936
- var drillUp = domify('<button class="bjs-drilldown">' + ARROW_UP_SVG + '</button>');
7937
- drillUp.addEventListener('click', function() {
7938
- var plane = canvas.findPlane(getBusinessObject(subProcess).id);
7939
- canvas.setActivePlane(plane);
7714
+ return id;
7715
+ }
7716
+
7717
+ function addPlaneSuffix(id) {
7718
+ return id + planeSuffix;
7719
+ }
7720
+
7721
+ var OPEN_CLASS = 'bjs-breadcrumbs-shown';
7722
+
7723
+
7724
+ /**
7725
+ * Adds overlays that allow switching planes on collapsed subprocesses.
7726
+ *
7727
+ * @param {eventBus} eventBus
7728
+ * @param {elementRegistry} elementRegistry
7729
+ * @param {overlays} overlays
7730
+ * @param {canvas} canvas
7731
+ */
7732
+ function DrilldownBreadcrumbs(eventBus, elementRegistry, overlays, canvas) {
7733
+ var breadcrumbs = domify('<ul class="bjs-breadcrumbs"></ul>');
7734
+ var container = canvas.getContainer();
7735
+ var containerClasses = classes(container);
7736
+ container.appendChild(breadcrumbs);
7737
+
7738
+ var boParents = [];
7739
+
7740
+ // update breadcrumbs if name or ID of the primary shape changes
7741
+ eventBus.on('element.changed', function(e) {
7742
+ var shape = e.element,
7743
+ bo = getBusinessObject(shape);
7744
+
7745
+ var isPresent = find(boParents, function(el) {
7746
+ return el === bo;
7940
7747
  });
7941
7748
 
7942
- breadcrumbs.appendChild(drillUp);
7749
+ if (!isPresent) {
7750
+ return;
7751
+ }
7943
7752
 
7944
- var parents = getParentChain(subProcess);
7753
+ updateBreadcrumbs();
7754
+ });
7945
7755
 
7946
- var path = parents.map(function(el) {
7947
- var title = escapeHTML(el.name) || el.id;
7756
+ /**
7757
+ * Updates the displayed breadcrumbs. If no element is provided, only the
7758
+ * labels are updated.
7759
+ *
7760
+ * @param {djs.model.Base} [element]
7761
+ */
7762
+ function updateBreadcrumbs(element) {
7763
+ if (element) {
7764
+ boParents = getBoParentChain(element);
7765
+ }
7766
+
7767
+ var path = boParents.map(function(parent) {
7768
+ var title = escapeHTML(parent.name || parent.id);
7948
7769
  var link = domify('<li><span class="bjs-crumb"><a title="' + title + '">' + title + '</a></span></li>');
7949
7770
 
7771
+ var parentPlane = canvas.findRoot(getPlaneIdFromShape(parent)) || canvas.findRoot(parent.id);
7772
+
7773
+ // when the root is a collaboration, the process does not have a corresponding
7774
+ // element in the elementRegisty. Instead, we search for the corresponding participant
7775
+ if (!parentPlane && is$1(parent, 'bpmn:Process')) {
7776
+ var participant = elementRegistry.find(function(element) {
7777
+ var bo = getBusinessObject(element);
7778
+ return bo && bo.processRef && bo.processRef === parent;
7779
+ });
7780
+
7781
+ parentPlane = canvas.findRoot(participant.id);
7782
+ }
7783
+
7950
7784
  link.addEventListener('click', function() {
7951
- if (canvas.getPlane(el.id)) {
7952
- canvas.setActivePlane(el.id);
7953
- } else {
7954
- var plane = canvas.findPlane(el.id);
7955
- canvas.setActivePlane(plane);
7956
- }
7785
+ canvas.setRootElement(parentPlane);
7957
7786
  });
7958
7787
 
7959
7788
  return link;
7960
7789
  });
7961
7790
 
7791
+ breadcrumbs.innerHTML = '';
7792
+
7793
+ // show breadcrumbs and expose state to .djs-container
7794
+ var visible = path.length > 1;
7795
+ containerClasses.toggle(OPEN_CLASS, visible);
7796
+
7962
7797
  path.forEach(function(el) {
7963
7798
  breadcrumbs.appendChild(el);
7964
7799
  });
7800
+ }
7965
7801
 
7966
- overlays.add(subProcess, {
7967
- position: {
7968
- top: -30,
7969
- left: -10
7970
- },
7971
- html: breadcrumbs
7972
- });
7802
+ eventBus.on('root.set', function(event) {
7803
+ updateBreadcrumbs(event.element);
7804
+ });
7805
+
7806
+ }
7807
+
7808
+ DrilldownBreadcrumbs.$inject = [ 'eventBus', 'elementRegistry', 'overlays', 'canvas' ];
7809
+
7810
+
7811
+ // helpers //////////
7812
+
7813
+ /**
7814
+ * Returns the parents for the element using the business object chain,
7815
+ * starting with the root element.
7816
+ *
7817
+ * @param {djs.model.Shape} child
7818
+ *
7819
+ * @returns {Array<djs.model.Shape>} parents
7820
+ */
7821
+ function getBoParentChain(child) {
7822
+ var bo = getBusinessObject(child);
7823
+
7824
+ var parents = [];
7825
+
7826
+ for (var element = bo; element; element = element.$parent) {
7827
+ if (is$1(element, 'bpmn:SubProcess') || is$1(element, 'bpmn:Process')) {
7828
+ parents.push(element);
7829
+ }
7973
7830
  }
7974
7831
 
7975
- var createDrilldown = function(element) {
7976
- var html = domify('<button class="bjs-drilldown">' + ARROW_DOWN_SVG + '</button>');
7832
+ return parents.reverse();
7833
+ }
7977
7834
 
7978
- html.addEventListener('click', function() {
7979
- canvas.setActivePlane(element.id);
7980
- });
7835
+ /**
7836
+ * Move collapsed subprocesses into view when drilling down.
7837
+ *
7838
+ * Zoom and scroll are saved in a session.
7839
+ *
7840
+ * @param {eventBus} eventBus
7841
+ * @param {canvas} canvas
7842
+ */
7843
+ function DrilldownCentering(eventBus, canvas) {
7981
7844
 
7982
- overlays.add(element, {
7983
- position: {
7984
- bottom: -7,
7985
- right: -8
7986
- },
7987
- html: html
7845
+ var currentRoot = null;
7846
+ var positionMap = new Map();
7847
+
7848
+ eventBus.on('root.set', function(event) {
7849
+ var newRoot = event.element;
7850
+ var currentViewbox = canvas.viewbox();
7851
+ var storedViewbox = positionMap.get(newRoot);
7852
+
7853
+ positionMap.set(currentRoot, {
7854
+ x: currentViewbox.x,
7855
+ y: currentViewbox.y,
7856
+ zoom: currentViewbox.scale
7988
7857
  });
7858
+
7859
+ currentRoot = newRoot;
7860
+
7861
+ // current root was replaced with a collaboration, we don't update the viewbox
7862
+ if (is$1(newRoot, 'bpmn:Collaboration') && !storedViewbox) {
7863
+ return;
7864
+ }
7865
+
7866
+ storedViewbox = storedViewbox || { x: 0, y: 0, zoom: 1 };
7867
+
7868
+ var dx = (currentViewbox.x - storedViewbox.x) * currentViewbox.scale,
7869
+ dy = (currentViewbox.y - storedViewbox.y) * currentViewbox.scale;
7870
+
7871
+ if (dx !== 0 || dy !== 0) {
7872
+ canvas.scroll({
7873
+ dx: dx,
7874
+ dy: dy
7875
+ });
7876
+ }
7877
+
7878
+ if (storedViewbox.zoom !== currentViewbox.scale) {
7879
+ canvas.zoom(storedViewbox.zoom, { x: 0, y: 0 });
7880
+ }
7881
+ });
7882
+
7883
+ eventBus.on('diagram.clear', function() {
7884
+ positionMap.clear();
7885
+ currentRoot = null;
7886
+ });
7887
+
7888
+ }
7889
+
7890
+ DrilldownCentering.$inject = [ 'eventBus', 'canvas' ];
7891
+
7892
+
7893
+ /**
7894
+ * ES5 Map implementation. Works.
7895
+ */
7896
+ function Map() {
7897
+
7898
+ this._entries = [];
7899
+
7900
+ this.set = function(key, value) {
7901
+
7902
+ var found = false;
7903
+
7904
+ for (var k in this._entries) {
7905
+ if (this._entries[k][0] === key) {
7906
+ this._entries[k][1] = value;
7907
+
7908
+ found = true;
7909
+
7910
+ break;
7911
+ }
7912
+ }
7913
+
7914
+ if (!found) {
7915
+ this._entries.push([ key, value ]);
7916
+ }
7989
7917
  };
7990
7918
 
7991
- var addOverlays = function(elements) {
7992
- elements.forEach(function(element) {
7993
- if (is$1(element, 'bpmn:SubProcess')
7994
- && element.collapsed
7995
- && canvas.getPlane(element.id)) {
7996
- createDrilldown(element);
7919
+ this.get = function(key) {
7920
+
7921
+ for (var k in this._entries) {
7922
+ if (this._entries[k][0] === key) {
7923
+ return this._entries[k][1];
7997
7924
  }
7925
+ }
7926
+
7927
+ return null;
7928
+ };
7929
+
7930
+ this.clear = function() {
7931
+ this._entries.length = 0;
7932
+ };
7933
+
7934
+ this.remove = function(key) {
7935
+
7936
+ var idx = -1;
7937
+
7938
+ for (var k in this._entries) {
7939
+ if (this._entries[k][0] === key) {
7940
+ idx = k;
7998
7941
 
7999
- if (is$1(element, 'bpmn:SubProcess') && element.isSecondary) {
8000
- createBreadcrumbs(element);
7942
+ break;
8001
7943
  }
8002
- });
7944
+ }
7945
+
7946
+ if (idx !== -1) {
7947
+ this._entries.splice(idx, 1);
7948
+ }
8003
7949
  };
7950
+ }
8004
7951
 
8005
- eventBus.on('import.done', function() {
8006
- addOverlays(elementRegistry.filter(function(el) {
8007
- return is$1(el, 'bpmn:SubProcess');
8008
- }));
7952
+ var DEFAULT_POSITION = {
7953
+ x: 180,
7954
+ y: 160
7955
+ };
7956
+
7957
+ /**
7958
+ * Hook into `import.render.start` and create new planes for diagrams with
7959
+ * collapsed subprocesses and all dis on the same plane.
7960
+ *
7961
+ * @param {eventBus} eventBus
7962
+ * @param {moddle} moddle
7963
+ */
7964
+ function SubprocessCompatibility(eventBus, moddle) {
7965
+ this._eventBus = eventBus;
7966
+ this._moddle = moddle;
7967
+
7968
+ var self = this;
7969
+
7970
+ eventBus.on('import.render.start', 1500, function(e, context) {
7971
+ self.handleImport(context.definitions);
8009
7972
  });
8010
7973
  }
8011
7974
 
8012
- SubprocessOverlays.$inject = [ 'eventBus', 'elementRegistry', 'overlays', 'canvas' ];
7975
+ SubprocessCompatibility.prototype.handleImport = function(definitions) {
7976
+ if (!definitions.diagrams) {
7977
+ return;
7978
+ }
8013
7979
 
7980
+ var self = this;
7981
+ this._definitions = definitions;
7982
+ this._processToDiagramMap = {};
8014
7983
 
8015
- var getParentChain = function(child) {
8016
- var bo = getBusinessObject(child);
7984
+ definitions.diagrams.forEach(function(diagram) {
7985
+ if (!diagram.plane || !diagram.plane.bpmnElement) {
7986
+ return;
7987
+ }
8017
7988
 
8018
- var parents = [];
7989
+ self._processToDiagramMap[diagram.plane.bpmnElement.id] = diagram;
7990
+ });
8019
7991
 
8020
- for (var element = bo; element; element = element.$parent) {
8021
- if (is$1(element, 'bpmn:SubProcess') || is$1(element, 'bpmn:Process')) {
8022
- parents.push(element);
8023
- }
8024
- }
7992
+ var newDiagrams = [];
7993
+ definitions.diagrams.forEach(function(diagram) {
7994
+ var createdDiagrams = self.createNewDiagrams(diagram.plane);
7995
+ Array.prototype.push.apply(newDiagrams, createdDiagrams);
7996
+ });
8025
7997
 
8026
- return parents.reverse();
7998
+ newDiagrams.forEach(function(diagram) {
7999
+ self.movePlaneElementsToOrigin(diagram.plane);
8000
+ });
8027
8001
  };
8028
8002
 
8029
- var FLOW_LENGTH = 50;
8030
- var HIGH_RENDER_PRIORITY = 2000;
8031
8003
 
8032
- function SubprocessFlows(eventBus, config) {
8004
+ /**
8005
+ * Moves all DI elements from collapsed subprocesses to a new plane.
8006
+ *
8007
+ * @param {Object} plane
8008
+ * @return {Array} new diagrams created for the collapsed subprocesses
8009
+ */
8010
+ SubprocessCompatibility.prototype.createNewDiagrams = function(plane) {
8011
+ var self = this;
8033
8012
 
8034
- var mutedStrokeColor = (config && config.mutedStrokeColor) || '#dddddd';
8013
+ var collapsedElements = [];
8014
+ var elementsToMove = [];
8035
8015
 
8036
- function drawFakeFlows(element, parentGfx) {
8037
- var primary = element.primaryShape;
8016
+ plane.get('planeElement').forEach(function(diElement) {
8017
+ var bo = diElement.bpmnElement;
8038
8018
 
8039
- var drawFakeConnection = function(connection, isOutgoing) {
8019
+ if (!bo) {
8020
+ return;
8021
+ }
8040
8022
 
8041
- var segment;
8042
- if (isOutgoing) {
8043
- segment = connection.waypoints.slice(0, 2);
8023
+ var parent = bo.$parent;
8044
8024
 
8045
- // Reverse order for normalizing
8046
- segment = segment.reverse();
8047
- } else {
8048
- segment = connection.waypoints.slice(connection.waypoints.length - 2);
8049
- }
8025
+ if (is$1(bo, 'bpmn:SubProcess') && !diElement.isExpanded) {
8026
+ collapsedElements.push(bo);
8027
+ }
8050
8028
 
8051
- var endpoint = segment[1];
8029
+ if (is$1(parent, 'bpmn:SubProcess') && parent !== plane.bpmnElement) {
8052
8030
 
8053
- var relativePosition = {
8054
- x: (endpoint.x - primary.x) / primary.width,
8055
- y: (endpoint.y - primary.y) / primary.height
8056
- };
8031
+ // don't change the array while we iterate over it
8032
+ elementsToMove.push({ diElement: diElement, parent: parent });
8033
+ }
8034
+ });
8057
8035
 
8058
- var anchorPoint = {
8059
- x: endpoint.x - (element.width * relativePosition.x),
8060
- y: endpoint.y - (element.height * relativePosition.y)
8061
- };
8036
+ var newDiagrams = [];
8037
+
8038
+ // create new planes for all collapsed subprocesses, even when they are empty
8039
+ collapsedElements.forEach(function(element) {
8040
+ if (!self._processToDiagramMap[element.id]) {
8041
+ var diagram = self.createDiagram(element);
8042
+ self._processToDiagramMap[element.id] = diagram;
8043
+ newDiagrams.push(diagram);
8044
+ }
8045
+ });
8046
+
8047
+ elementsToMove.forEach(function(element) {
8048
+ var diElement = element.diElement;
8049
+ var parent = element.parent;
8050
+
8051
+ // parent is expanded, get nearest collapsed parent
8052
+ while (parent && collapsedElements.indexOf(parent) === -1) {
8053
+ parent = parent.$parent;
8054
+ }
8055
+
8056
+ // false positive, all parents are expanded
8057
+ if (!parent) {
8058
+ return;
8059
+ }
8060
+
8061
+ var diagram = self._processToDiagramMap[parent.id];
8062
+ self.moveToDiPlane(diElement, diagram.plane);
8063
+ });
8064
+
8065
+ return newDiagrams;
8066
+ };
8067
+
8068
+ SubprocessCompatibility.prototype.movePlaneElementsToOrigin = function(plane) {
8069
+ var elements = plane.get('planeElement');
8070
+
8071
+ // get bounding box of all elements
8072
+ var planeBounds = getPlaneBounds(plane);
8073
+
8074
+ var offset = {
8075
+ x: planeBounds.x - DEFAULT_POSITION.x,
8076
+ y: planeBounds.y - DEFAULT_POSITION.y
8077
+ };
8062
8078
 
8063
- var newWaypoints = segment.map(function(el) {
8064
- return { x: el.x - anchorPoint.x, y: el.y - anchorPoint.y };
8079
+ elements.forEach(function(diElement) {
8080
+ if (diElement.waypoint) {
8081
+ diElement.waypoint.forEach(function(waypoint) {
8082
+ waypoint.x = waypoint.x - offset.x;
8083
+ waypoint.y = waypoint.y - offset.y;
8065
8084
  });
8085
+ } else if (diElement.bounds) {
8086
+ diElement.bounds.x = diElement.bounds.x - offset.x;
8087
+ diElement.bounds.y = diElement.bounds.y - offset.y;
8088
+ }
8089
+ });
8090
+ };
8066
8091
 
8067
- newWaypoints[0] = normalizeLength(newWaypoints[1], newWaypoints[0], FLOW_LENGTH);
8068
8092
 
8069
- var attrs = {
8070
- stroke: mutedStrokeColor
8071
- };
8093
+ SubprocessCompatibility.prototype.moveToDiPlane = function(diElement, newPlane) {
8094
+ var containingDiagram = findRootDiagram(diElement);
8072
8095
 
8073
- if (isOutgoing) {
8096
+ // remove DI from old Plane and add it to the new one
8097
+ var parentPlaneElement = containingDiagram.plane.get('planeElement');
8098
+ parentPlaneElement.splice(parentPlaneElement.indexOf(diElement), 1);
8099
+ newPlane.get('planeElement').push(diElement);
8100
+ };
8101
+
8102
+
8103
+ SubprocessCompatibility.prototype.createDiagram = function(bo) {
8104
+ var plane = this._moddle.create('bpmndi:BPMNPlane', { bpmnElement: bo });
8105
+ var diagram = this._moddle.create('bpmndi:BPMNDiagram', {
8106
+ plane: plane
8107
+ });
8108
+ plane.$parent = diagram;
8109
+ plane.bpmnElement = bo;
8110
+ diagram.$parent = this._definitions;
8111
+ this._definitions.diagrams.push(diagram);
8112
+ return diagram;
8113
+ };
8114
+
8115
+ SubprocessCompatibility.$inject = [ 'eventBus', 'moddle' ];
8116
+
8117
+
8118
+ // helpers
8119
+
8120
+ function findRootDiagram(element) {
8121
+ if (is$1(element, 'bpmndi:BPMNDiagram')) {
8122
+ return element;
8123
+ } else {
8124
+ return findRootDiagram(element.$parent);
8125
+ }
8126
+ }
8127
+
8128
+ function getPlaneBounds(plane) {
8129
+ var planeTrbl = {
8130
+ top: Infinity,
8131
+ right: -Infinity,
8132
+ bottom: -Infinity,
8133
+ left: Infinity
8134
+ };
8135
+
8136
+ plane.planeElement.forEach(function(element) {
8137
+ if (!element.bounds) {
8138
+ return;
8139
+ }
8140
+
8141
+ var trbl = asTRBL(element.bounds);
8142
+
8143
+ planeTrbl.top = Math.min(trbl.top, planeTrbl.top);
8144
+ planeTrbl.left = Math.min(trbl.left, planeTrbl.left);
8145
+ });
8146
+
8147
+ return asBounds(planeTrbl);
8148
+ }
8149
+
8150
+ var LOW_PRIORITY$1 = 250;
8151
+ var ARROW_DOWN_SVG = '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4.81801948,3.50735931 L10.4996894,9.1896894 L10.5,4 L12,4 L12,12 L4,12 L4,10.5 L9.6896894,10.4996894 L3.75735931,4.56801948 C3.46446609,4.27512627 3.46446609,3.80025253 3.75735931,3.50735931 C4.05025253,3.21446609 4.52512627,3.21446609 4.81801948,3.50735931 Z"/></svg>';
8152
+
8153
+ var EMPTY_MARKER = 'bjs-drilldown-empty';
8154
+
8155
+ function DrilldownOverlayBehavior(
8156
+ canvas, eventBus, elementRegistry, overlays
8157
+ ) {
8158
+ CommandInterceptor.call(this, eventBus);
8159
+
8160
+ this._canvas = canvas;
8161
+ this._eventBus = eventBus;
8162
+ this._elementRegistry = elementRegistry;
8163
+ this._overlays = overlays;
8164
+
8165
+ var self = this;
8166
+
8167
+ this.executed('shape.toggleCollapse', LOW_PRIORITY$1, function(context) {
8168
+ var shape = context.shape;
8169
+
8170
+ // Add overlay to the collapsed shape
8171
+ if (self.canDrillDown(shape)) {
8172
+ self.addOverlay(shape);
8173
+ } else {
8174
+ self.removeOverlay(shape);
8175
+ }
8176
+ }, true);
8177
+
8178
+
8179
+ this.reverted('shape.toggleCollapse', LOW_PRIORITY$1, function(context) {
8180
+ var shape = context.shape;
8181
+
8182
+ // Add overlay to the collapsed shape
8183
+ if (self.canDrillDown(shape)) {
8184
+ self.addOverlay(shape);
8185
+ } else {
8186
+ self.removeOverlay(shape);
8187
+ }
8188
+ }, true);
8074
8189
 
8075
- // Reverse order again for correct end marker position
8076
- newWaypoints = newWaypoints.reverse();
8077
- } else {
8078
8190
 
8079
- // Remove start marker for incoming flows
8080
- attrs.markerStart = undefined;
8191
+ this.executed(['shape.create', 'shape.move', 'shape.delete'], LOW_PRIORITY$1,
8192
+ function(context) {
8193
+ var oldParent = context.oldParent,
8194
+ newParent = context.newParent || context.parent,
8195
+ shape = context.shape;
8196
+
8197
+ // Add overlay to the collapsed shape
8198
+ if (self.canDrillDown(shape)) {
8199
+ self.addOverlay(shape);
8081
8200
  }
8082
8201
 
8083
- eventBus.fire('render.connection', {
8084
- type: connection.type,
8085
- gfx: parentGfx,
8086
- element: {
8087
- type: connection.type,
8088
- waypoints: newWaypoints,
8089
- di: connection.di,
8090
- businessObject: connection.businessObject
8091
- },
8092
- attrs: attrs
8093
- });
8094
- };
8202
+ self.updateDrilldownOverlay(oldParent);
8203
+ self.updateDrilldownOverlay(newParent);
8204
+ self.updateDrilldownOverlay(shape);
8205
+ }, true);
8206
+
8207
+
8208
+ this.reverted(['shape.create', 'shape.move', 'shape.delete'], LOW_PRIORITY$1,
8209
+ function(context) {
8210
+ var oldParent = context.oldParent,
8211
+ newParent = context.newParent || context.parent,
8212
+ shape = context.shape;
8095
8213
 
8096
- primary.incoming && primary.incoming.forEach(function(connection) {
8097
- drawFakeConnection(connection, false);
8214
+ // Add overlay to the collapsed shape
8215
+ if (self.canDrillDown(shape)) {
8216
+ self.addOverlay(shape);
8217
+ }
8218
+
8219
+ self.updateDrilldownOverlay(oldParent);
8220
+ self.updateDrilldownOverlay(newParent);
8221
+ self.updateDrilldownOverlay(shape);
8222
+ }, true);
8223
+
8224
+
8225
+ eventBus.on('import.done', function() {
8226
+ elementRegistry.filter(function(e) {
8227
+ return self.canDrillDown(e);
8228
+ }).map(function(el) {
8229
+ self.addOverlay(el);
8098
8230
  });
8231
+ });
8232
+
8233
+ }
8234
+
8235
+ inherits$1(DrilldownOverlayBehavior, CommandInterceptor);
8236
+
8237
+ DrilldownOverlayBehavior.prototype.updateDrilldownOverlay = function(shape) {
8238
+ var canvas = this._canvas;
8239
+
8240
+ if (!shape) {
8241
+ return;
8242
+ }
8243
+
8244
+ var root = canvas.findRoot(shape);
8245
+ if (root) {
8246
+ this.updateOverlayVisibility(root);
8247
+ }
8248
+ };
8249
+
8250
+
8251
+ DrilldownOverlayBehavior.prototype.canDrillDown = function(element) {
8252
+ var canvas = this._canvas;
8253
+ return is$1(element, 'bpmn:SubProcess') && canvas.findRoot(getPlaneIdFromShape(element));
8254
+ };
8255
+
8256
+ /**
8257
+ * Updates visibility of the drilldown overlay. If the plane has no elements,
8258
+ * the drilldown will be only shown when the element is selected.
8259
+ *
8260
+ * @param {djs.model.Shape|djs.model.Root} element collapsed shape or root element
8261
+ */
8262
+ DrilldownOverlayBehavior.prototype.updateOverlayVisibility = function(element) {
8263
+ var overlays = this._overlays;
8264
+
8265
+ var bo = element.businessObject;
8266
+
8267
+ var overlay = overlays.get({ element: bo.id, type: 'drilldown' })[0];
8268
+
8269
+ if (!overlay) {
8270
+ return;
8271
+ }
8272
+
8273
+ var hasContent = bo && bo.flowElements && bo.flowElements.length;
8274
+ classes(overlay.html).toggle(EMPTY_MARKER, !hasContent);
8275
+ };
8276
+
8277
+ /**
8278
+ * Attaches a drilldown button to the given element. We assume that the plane has
8279
+ * the same id as the element.
8280
+ *
8281
+ * @param {djs.model.Shape} element collapsed shape
8282
+ */
8283
+ DrilldownOverlayBehavior.prototype.addOverlay = function(element) {
8284
+ var canvas = this._canvas;
8285
+ var overlays = this._overlays;
8099
8286
 
8100
- primary.outgoing && primary.outgoing.forEach(function(connection) {
8101
- drawFakeConnection(connection, true);
8102
- });
8287
+ var existingOverlays = overlays.get({ element: element, type: 'drilldown' });
8288
+ if (existingOverlays.length) {
8289
+ this.removeOverlay(element);
8103
8290
  }
8104
8291
 
8105
- eventBus.on([ 'render.shape' ], HIGH_RENDER_PRIORITY, function(evt, context) {
8106
- var element = context.element,
8107
- visuals = context.gfx;
8108
-
8109
- if (element.isSecondary && element.primaryShape) {
8110
- drawFakeFlows(element, visuals);
8111
- }
8292
+ var button = domify('<button class="bjs-drilldown">' + ARROW_DOWN_SVG + '</button>');
8112
8293
 
8294
+ button.addEventListener('click', function() {
8295
+ canvas.setRootElement(canvas.findRoot(getPlaneIdFromShape(element)));
8113
8296
  });
8114
8297
 
8115
- }
8116
-
8117
- SubprocessFlows.$inject = [ 'eventBus', 'config' ];
8118
-
8119
-
8120
- // helpers
8298
+ overlays.add(element, 'drilldown', {
8299
+ position: {
8300
+ bottom: -7,
8301
+ right: -8
8302
+ },
8303
+ html: button
8304
+ });
8121
8305
 
8122
- function normalizeLength(fixedPoint, variablePoint, length) {
8123
- var dx = fixedPoint.x - variablePoint.x,
8124
- dy = fixedPoint.y - variablePoint.y,
8125
- totalDistance = Math.abs(dx) + Math.abs(dy);
8306
+ this.updateOverlayVisibility(element);
8307
+ };
8126
8308
 
8127
- dx = dx / totalDistance;
8128
- dy = dy / totalDistance;
8309
+ DrilldownOverlayBehavior.prototype.removeOverlay = function(element) {
8310
+ var overlays = this._overlays;
8129
8311
 
8130
- dx *= length;
8131
- dy *= length;
8312
+ overlays.remove({
8313
+ element: element,
8314
+ type: 'drilldown'
8315
+ });
8316
+ };
8132
8317
 
8133
- return {
8134
- x: fixedPoint.x - dx,
8135
- y: fixedPoint.y - dy
8136
- };
8137
- }
8318
+ DrilldownOverlayBehavior.$inject = [
8319
+ 'canvas',
8320
+ 'eventBus',
8321
+ 'elementRegistry',
8322
+ 'overlays'
8323
+ ];
8138
8324
 
8139
- var SubprocessNavigationModule = {
8140
- __depends__: [ OverlaysModule, ChangeSupportModule ],
8141
- __init__: [ 'subprocessElements', 'subprocessOverlays', 'subprocessCompatibility', 'subprocessCentering', 'subprocessFlows' ],
8142
- subprocessElements: [ 'type', SubprocessElements ],
8143
- subprocessOverlays: [ 'type', SubprocessOverlays ],
8144
- subprocessCompatibility: [ 'type', SubprocessCompatibility ],
8145
- subprocessCentering: [ 'type', SubprocessCentering ],
8146
- subprocessFlows: ['type', SubprocessFlows]
8325
+ var DrilldownModdule = {
8326
+ __depends__: [ OverlaysModule, ChangeSupportModule, RootElementsModule ],
8327
+ __init__: [ 'drilldownBreadcrumbs', 'drilldownOverlayBehavior', 'drilldownCentering', 'subprocessCompatibility'],
8328
+ drilldownBreadcrumbs: [ 'type', DrilldownBreadcrumbs ],
8329
+ drilldownCentering: [ 'type', DrilldownCentering ],
8330
+ drilldownOverlayBehavior: [ 'type', DrilldownOverlayBehavior ],
8331
+ subprocessCompatibility: [ 'type', SubprocessCompatibility ]
8147
8332
  };
8148
8333
 
8149
8334
  var CLASS_PATTERN = /^class /;
@@ -8783,7 +8968,10 @@
8783
8968
  }
8784
8969
 
8785
8970
  var BASE_LAYER = 'base';
8786
- var HIDDEN_MARKER = 'djs-element-hidden';
8971
+
8972
+ // render plane contents behind utility layers
8973
+ var PLANE_LAYER_INDEX = 0;
8974
+ var UTILITY_LAYER_INDEX = 1;
8787
8975
 
8788
8976
 
8789
8977
  var REQUIRED_MODEL_ATTRS = {
@@ -8810,6 +8998,12 @@
8810
8998
  this._elementRegistry = elementRegistry;
8811
8999
  this._graphicsFactory = graphicsFactory;
8812
9000
 
9001
+ this._rootsIdx = 0;
9002
+
9003
+ this._layers = {};
9004
+ this._planes = [];
9005
+ this._rootElement = null;
9006
+
8813
9007
  this._init(config || {});
8814
9008
  }
8815
9009
 
@@ -8847,9 +9041,6 @@
8847
9041
 
8848
9042
  var viewport = this._viewport = createGroup(svg, 'viewport');
8849
9043
 
8850
- this._layers = {};
8851
- this._planes = {};
8852
-
8853
9044
  // debounce canvas.viewbox.changed events
8854
9045
  // for smoother diagram interaction
8855
9046
  if (config.deferUpdate !== false) {
@@ -8883,7 +9074,8 @@
8883
9074
  'connection.added',
8884
9075
  'shape.removed',
8885
9076
  'connection.removed',
8886
- 'elements.changed'
9077
+ 'elements.changed',
9078
+ 'root.set'
8887
9079
  ], function() {
8888
9080
  delete this._cachedViewbox;
8889
9081
  }, this);
@@ -8908,7 +9100,7 @@
8908
9100
  delete this._container;
8909
9101
  delete this._layers;
8910
9102
  delete this._planes;
8911
- delete this._activePlane;
9103
+ delete this._rootElement;
8912
9104
  delete this._viewport;
8913
9105
  };
8914
9106
 
@@ -8923,15 +9115,15 @@
8923
9115
  var type = getType(element);
8924
9116
 
8925
9117
  if (type === 'root') {
8926
- self.setRootElementForPlane(null, self.findPlane(element), true);
9118
+ self.removeRootElement(element);
8927
9119
  } else {
8928
9120
  self._removeElement(element, type);
8929
9121
  }
8930
9122
  });
8931
9123
 
8932
9124
  // remove all planes
8933
- this._activePlane = null;
8934
- this._planes = {};
9125
+ this._planes = [];
9126
+ this._rootElement = null;
8935
9127
 
8936
9128
  // force recomputation of view box
8937
9129
  delete this._cachedViewbox;
@@ -8944,7 +9136,7 @@
8944
9136
  * @returns {SVGElement}
8945
9137
  */
8946
9138
  Canvas.prototype.getDefaultLayer = function() {
8947
- return this.getLayer(BASE_LAYER);
9139
+ return this.getLayer(BASE_LAYER, PLANE_LAYER_INDEX);
8948
9140
  };
8949
9141
 
8950
9142
  /**
@@ -8993,8 +9185,8 @@
8993
9185
  */
8994
9186
  Canvas.prototype._createLayer = function(name, index) {
8995
9187
 
8996
- if (!index) {
8997
- index = 0;
9188
+ if (typeof index === 'undefined') {
9189
+ index = UTILITY_LAYER_INDEX;
8998
9190
  }
8999
9191
 
9000
9192
  var childIndex = reduce(this._layers, function(childIndex, layer) {
@@ -9012,142 +9204,75 @@
9012
9204
 
9013
9205
  };
9014
9206
 
9015
- /**
9016
- * Returns a plane that is used to draw elements on it.
9017
- *
9018
- * @param {string} name
9019
- *
9020
- * @return {Object} plane descriptor with { layer, rootElement, name }
9021
- */
9022
- Canvas.prototype.getPlane = function(name) {
9023
- if (!name) {
9024
- throw new Error('must specify a name');
9025
- }
9026
-
9027
- var plane = this._planes[name];
9028
-
9029
- return plane;
9030
- };
9031
-
9032
- /**
9033
- * Creates a plane that is used to draw elements on it. If no
9034
- * root element is provided, an implicit root will be used.
9035
- *
9036
- * @param {string} name
9037
- * @param {Object|djs.model.Root} [rootElement] optional root element
9038
- *
9039
- * @return {Object} plane descriptor with { layer, rootElement, name }
9040
- */
9041
- Canvas.prototype.createPlane = function(name, rootElement) {
9042
- if (!name) {
9043
- throw new Error('must specify a name');
9044
- }
9045
-
9046
- if (this._planes[name]) {
9047
- throw new Error('plane ' + name + ' already exists');
9048
- }
9049
-
9050
- if (!rootElement) {
9051
- rootElement = {
9052
- id: '__implicitroot' + name,
9053
- children: [],
9054
- isImplicit: true
9055
- };
9056
- }
9057
-
9058
- var svgLayer = this.getLayer(name);
9059
- classes$1(svgLayer).add(HIDDEN_MARKER);
9060
-
9061
- var plane = this._planes[name] = {
9062
- layer: svgLayer,
9063
- name: name,
9064
- rootElement: null
9065
- };
9066
-
9067
- this.setRootElementForPlane(rootElement, plane);
9068
-
9069
- return plane;
9070
- };
9071
-
9072
- /**
9073
- * Sets the active plane and hides the previously active plane.
9074
- *
9075
- * @param {string|Object} plane
9076
- *
9077
- * @return {Object} plane descriptor with { layer, rootElement, name }
9078
- */
9079
- Canvas.prototype.setActivePlane = function(plane) {
9080
- if (!plane) {
9081
- throw new Error('must specify a plane');
9082
- }
9083
-
9084
- if (typeof plane === 'string') {
9085
- plane = this.getPlane(plane);
9086
- }
9087
9207
 
9088
- // hide previous Plane
9089
- if (this._activePlane) {
9090
- classes$1(this._activePlane.layer).add(HIDDEN_MARKER);
9091
- }
9208
+ Canvas.prototype._removeLayer = function(name) {
9092
9209
 
9093
- this._activePlane = plane;
9210
+ var layer = this._layers[name];
9094
9211
 
9095
- // show current Plane
9096
- classes$1(plane.layer).remove(HIDDEN_MARKER);
9212
+ if (layer) {
9213
+ delete this._layers[name];
9097
9214
 
9098
- if (plane.rootElement) {
9099
- this._elementRegistry.updateGraphics(plane.rootElement, this._svg, true);
9215
+ remove$2(layer.group);
9100
9216
  }
9101
-
9102
- this._eventBus.fire('plane.set', { plane: plane });
9103
-
9104
- return plane;
9105
9217
  };
9106
9218
 
9107
9219
  /**
9108
- * Returns the currently active layer
9220
+ * Returns the currently active layer. Can be null.
9109
9221
  *
9110
- * @returns {SVGElement}
9222
+ * @returns {SVGElement|null}
9111
9223
  */
9112
-
9113
9224
  Canvas.prototype.getActiveLayer = function() {
9114
- return this.getActivePlane().layer;
9115
- };
9225
+ var plane = this._findPlaneForRoot(this.getRootElement());
9116
9226
 
9117
- /**
9118
- * Returns the currently active plane.
9119
- *
9120
- * @return {Object} plane descriptor with { layer, rootElement, name }
9121
- */
9122
- Canvas.prototype.getActivePlane = function() {
9123
- var plane = this._activePlane;
9124
9227
  if (!plane) {
9125
- plane = this.createPlane(BASE_LAYER);
9126
- this.setActivePlane(BASE_LAYER);
9228
+ return null;
9127
9229
  }
9128
9230
 
9129
- return plane;
9231
+ return plane.layer;
9130
9232
  };
9131
9233
 
9234
+
9132
9235
  /**
9133
9236
  * Returns the plane which contains the given element.
9134
9237
  *
9135
9238
  * @param {string|djs.model.Base} element
9136
9239
  *
9137
- * @return {Object} plane descriptor with { layer, rootElement, name }
9240
+ * @return {djs.model.Base} root for element
9138
9241
  */
9139
- Canvas.prototype.findPlane = function(element) {
9242
+ Canvas.prototype.findRoot = function(element) {
9140
9243
  if (typeof element === 'string') {
9141
9244
  element = this._elementRegistry.get(element);
9142
9245
  }
9143
9246
 
9144
- var root = findRoot(element);
9247
+ if (!element) {
9248
+ return;
9249
+ }
9250
+
9251
+ var plane = this._findPlaneForRoot(
9252
+ findRoot(element)
9253
+ ) || {};
9254
+
9255
+ return plane.rootElement;
9256
+ };
9257
+
9258
+ /**
9259
+ * Return a list of all root elements on the diagram.
9260
+ *
9261
+ * @return {djs.model.Root[]}
9262
+ */
9263
+ Canvas.prototype.getRootElements = function() {
9264
+ return this._planes.map(function(plane) {
9265
+ return plane.rootElement;
9266
+ });
9267
+ };
9145
9268
 
9269
+ Canvas.prototype._findPlaneForRoot = function(rootElement) {
9146
9270
  return find(this._planes, function(plane) {
9147
- return plane.rootElement === root;
9271
+ return plane.rootElement === rootElement;
9148
9272
  });
9149
9273
  };
9150
9274
 
9275
+
9151
9276
  /**
9152
9277
  * Returns the html element that encloses the
9153
9278
  * drawing canvas.
@@ -9268,95 +9393,205 @@
9268
9393
  }
9269
9394
  };
9270
9395
 
9396
+ /**
9397
+ * Returns the current root element.
9398
+ *
9399
+ * Supports two different modes for handling root elements:
9400
+ *
9401
+ * 1. if no root element has been added before, an implicit root will be added
9402
+ * and returned. This is used in applications that don't require explicit
9403
+ * root elements.
9404
+ *
9405
+ * 2. when root elements have been added before calling `getRootElement`,
9406
+ * root elements can be null. This is used for applications that want to manage
9407
+ * root elements themselves.
9408
+ *
9409
+ * @returns {Object|djs.model.Root|null} rootElement.
9410
+ */
9271
9411
  Canvas.prototype.getRootElement = function() {
9272
- var plane = this.getActivePlane();
9412
+ var rootElement = this._rootElement;
9273
9413
 
9274
- return plane.rootElement;
9414
+ // can return null if root elements are present but none was set yet
9415
+ if (rootElement || this._planes.length) {
9416
+ return rootElement;
9417
+ }
9418
+
9419
+ return this.setRootElement(this.addRootElement(null));
9275
9420
  };
9276
9421
 
9422
+ /**
9423
+ * Adds a given root element and returns it.
9424
+ *
9425
+ * @param {Object|djs.model.Root} rootElement
9426
+ *
9427
+ * @return {Object|djs.model.Root} rootElement
9428
+ */
9277
9429
 
9430
+ Canvas.prototype.addRootElement = function(rootElement) {
9431
+ var idx = this._rootsIdx++;
9278
9432
 
9279
- // root element handling //////////////////////
9433
+ if (!rootElement) {
9434
+ rootElement = {
9435
+ id: '__implicitroot_' + idx,
9436
+ children: [],
9437
+ isImplicit: true
9438
+ };
9439
+ }
9440
+
9441
+ var layerName = rootElement.layer = 'root-' + idx;
9442
+
9443
+ this._ensureValid('root', rootElement);
9444
+
9445
+ var layer = this.getLayer(layerName, PLANE_LAYER_INDEX);
9446
+
9447
+ attr$1(layer, 'display', 'none');
9448
+
9449
+ this._addRoot(rootElement, layer);
9450
+
9451
+ this._planes.push({
9452
+ rootElement: rootElement,
9453
+ layer: layer
9454
+ });
9455
+
9456
+ return rootElement;
9457
+ };
9280
9458
 
9281
9459
  /**
9282
- * Sets a given element as the new root element for the canvas
9283
- * and returns the new root element.
9460
+ * Removes a given rootElement and returns it.
9284
9461
  *
9285
- * @param {Object|djs.model.Root} element
9286
- * @param {boolean} [override] whether to override the current root element, if any
9462
+ * @param {djs.model.Root|String} rootElement
9287
9463
  *
9288
- * @return {Object|djs.model.Root} new root element
9464
+ * @return {Object|djs.model.Root} rootElement
9289
9465
  */
9290
- Canvas.prototype.setRootElement = function(element, override) {
9291
- var activePlane = this._activePlane;
9466
+ Canvas.prototype.removeRootElement = function(rootElement) {
9292
9467
 
9293
- if (activePlane) {
9294
- return this.setRootElementForPlane(element, activePlane, override);
9295
- } else {
9296
- var basePlane = this.createPlane(BASE_LAYER, element);
9468
+ if (typeof rootElement === 'string') {
9469
+ rootElement = this._elementRegistry.get(rootElement);
9470
+ }
9471
+
9472
+ var plane = this._findPlaneForRoot(rootElement);
9473
+
9474
+ if (!plane) {
9475
+ return;
9476
+ }
9477
+
9478
+ // hook up life-cycle events
9479
+ this._removeRoot(rootElement);
9297
9480
 
9298
- this.setActivePlane(basePlane);
9481
+ // clean up layer
9482
+ this._removeLayer(rootElement.layer);
9483
+
9484
+ // clean up plane
9485
+ this._planes = this._planes.filter(function(plane) {
9486
+ return plane.rootElement !== rootElement;
9487
+ });
9299
9488
 
9300
- return basePlane.rootElement;
9489
+ // clean up active root
9490
+ if (this._rootElement === rootElement) {
9491
+ this._rootElement = null;
9301
9492
  }
9493
+
9494
+ return rootElement;
9302
9495
  };
9303
9496
 
9304
9497
 
9498
+ // root element handling //////////////////////
9499
+
9305
9500
  /**
9306
9501
  * Sets a given element as the new root element for the canvas
9307
9502
  * and returns the new root element.
9308
9503
  *
9309
- * @param {Object|djs.model.Root} element
9310
- * @param {Object|djs.model.Root} plane
9311
- * @param {boolean} [override] whether to override the current root element, if any
9504
+ * @param {Object|djs.model.Root} rootElement
9312
9505
  *
9313
9506
  * @return {Object|djs.model.Root} new root element
9314
9507
  */
9315
- Canvas.prototype.setRootElementForPlane = function(element, plane, override) {
9508
+ Canvas.prototype.setRootElement = function(rootElement, override) {
9316
9509
 
9317
- if (typeof plane === 'string') {
9318
- plane = this.getPlane(plane);
9510
+ if (isDefined(override)) {
9511
+ throw new Error('override not supported');
9319
9512
  }
9320
9513
 
9321
- if (element) {
9322
- this._ensureValid('root', element);
9514
+ if (rootElement === this._rootElement) {
9515
+ return;
9323
9516
  }
9324
9517
 
9325
- var currentRoot = plane.rootElement,
9326
- elementRegistry = this._elementRegistry,
9327
- eventBus = this._eventBus;
9518
+ var plane;
9328
9519
 
9329
- if (currentRoot) {
9330
- if (!override) {
9331
- throw new Error('rootElement already set, need to specify override');
9332
- }
9520
+ if (!rootElement) {
9521
+ throw new Error('rootElement required');
9522
+ }
9333
9523
 
9334
- // simulate element remove event sequence
9335
- eventBus.fire('root.remove', { element: currentRoot });
9336
- eventBus.fire('root.removed', { element: currentRoot });
9524
+ plane = this._findPlaneForRoot(rootElement);
9337
9525
 
9338
- elementRegistry.remove(currentRoot);
9526
+ // give set add semantics for backwards compatibility
9527
+ if (!plane) {
9528
+ rootElement = this.addRootElement(rootElement);
9339
9529
  }
9340
9530
 
9341
- if (element) {
9342
- var gfx = plane.layer;
9531
+ this._setRoot(rootElement);
9532
+
9533
+ return rootElement;
9534
+ };
9535
+
9536
+
9537
+ Canvas.prototype._removeRoot = function(element) {
9538
+ var elementRegistry = this._elementRegistry,
9539
+ eventBus = this._eventBus;
9540
+
9541
+ // simulate element remove event sequence
9542
+ eventBus.fire('root.remove', { element: element });
9543
+ eventBus.fire('root.removed', { element: element });
9343
9544
 
9344
- // resemble element add event sequence
9345
- eventBus.fire('root.add', { element: element });
9545
+ elementRegistry.remove(element);
9546
+ };
9547
+
9548
+
9549
+ Canvas.prototype._addRoot = function(element, gfx) {
9550
+ var elementRegistry = this._elementRegistry,
9551
+ eventBus = this._eventBus;
9552
+
9553
+ // resemble element add event sequence
9554
+ eventBus.fire('root.add', { element: element });
9555
+
9556
+ elementRegistry.add(element, gfx);
9557
+
9558
+ eventBus.fire('root.added', { element: element, gfx: gfx });
9559
+ };
9560
+
9561
+
9562
+ Canvas.prototype._setRoot = function(rootElement, layer) {
9563
+
9564
+ var currentRoot = this._rootElement;
9565
+
9566
+ var currentLayer;
9567
+
9568
+ if (currentRoot) {
9346
9569
 
9347
- elementRegistry.add(element, gfx);
9570
+ // un-associate previous root element <svg>
9571
+ this._elementRegistry.updateGraphics(currentRoot, null, true);
9348
9572
 
9349
- eventBus.fire('root.added', { element: element, gfx: gfx });
9573
+ // hide previous layer
9574
+ currentLayer = this._findPlaneForRoot(currentRoot).layer;
9350
9575
 
9351
- // associate SVG with root element when active
9352
- if (plane === this._activePlane) {
9353
- this._elementRegistry.updateGraphics(element, this._svg, true);
9576
+ attr$1(currentLayer, 'display', 'none');
9577
+ }
9578
+
9579
+ if (rootElement) {
9580
+
9581
+ if (!layer) {
9582
+ layer = this._findPlaneForRoot(rootElement).layer;
9354
9583
  }
9584
+
9585
+ // associate element with <svg>
9586
+ this._elementRegistry.updateGraphics(rootElement, this._svg, true);
9587
+
9588
+ // show root layer
9589
+ attr$1(layer, 'display', null);
9355
9590
  }
9356
9591
 
9357
- plane.rootElement = element;
9592
+ this._rootElement = rootElement;
9358
9593
 
9359
- return element;
9594
+ this._eventBus.fire('root.set', { element: rootElement });
9360
9595
  };
9361
9596
 
9362
9597
  // add functionality //////////////////////
@@ -9367,7 +9602,7 @@
9367
9602
  }
9368
9603
 
9369
9604
  if (this._elementRegistry.get(element.id)) {
9370
- throw new Error('element with id ' + element.id + ' already exists');
9605
+ throw new Error('element <' + element.id + '> already exists');
9371
9606
  }
9372
9607
 
9373
9608
  var requiredAttrs = REQUIRED_MODEL_ATTRS[type];
@@ -9657,6 +9892,7 @@
9657
9892
  innerBox,
9658
9893
  outerBox = this.getSize(),
9659
9894
  matrix,
9895
+ activeLayer,
9660
9896
  transform,
9661
9897
  scale,
9662
9898
  x, y;
@@ -9664,9 +9900,11 @@
9664
9900
  if (!box) {
9665
9901
 
9666
9902
  // compute the inner box based on the
9667
- // diagrams default layer. This allows us to exclude
9903
+ // diagrams active layer. This allows us to exclude
9668
9904
  // external components, such as overlays
9669
- innerBox = this.getDefaultLayer().getBBox();
9905
+
9906
+ activeLayer = this._rootElement ? this.getActiveLayer() : null;
9907
+ innerBox = activeLayer && activeLayer.getBBox() || {};
9670
9908
 
9671
9909
  transform = transform$1(viewport);
9672
9910
  matrix = transform ? transform.matrix : createMatrix();
@@ -9682,10 +9920,10 @@
9682
9920
  height: outerBox.height / scale,
9683
9921
  scale: scale,
9684
9922
  inner: {
9685
- width: innerBox.width,
9686
- height: innerBox.height,
9687
- x: innerBox.x,
9688
- y: innerBox.y
9923
+ width: innerBox.width || 0,
9924
+ height: innerBox.height || 0,
9925
+ x: innerBox.x || 0,
9926
+ y: innerBox.y || 0
9689
9927
  },
9690
9928
  outer: outerBox
9691
9929
  };
@@ -9738,17 +9976,22 @@
9738
9976
  * Scrolls the viewbox to contain the given element.
9739
9977
  * Optionally specify a padding to be applied to the edges.
9740
9978
  *
9741
- * @param {Object} [element] the element to scroll to.
9979
+ * @param {Object|String} [element] the element to scroll to.
9742
9980
  * @param {Object|Number} [padding=100] the padding to be applied. Can also specify top, bottom, left and right.
9743
9981
  *
9744
9982
  */
9745
9983
  Canvas.prototype.scrollToElement = function(element, padding) {
9746
9984
  var defaultPadding = 100;
9747
9985
 
9748
- // switch to correct Plane
9749
- var targetPlane = this.findPlane(element);
9750
- if (targetPlane !== this._activePlane) {
9751
- this.setActivePlane(targetPlane);
9986
+ if (typeof element === 'string') {
9987
+ element = this._elementRegistry.get(element);
9988
+ }
9989
+
9990
+ // set to correct rootElement
9991
+ var rootElement = this.findRoot(element);
9992
+
9993
+ if (rootElement !== this.getRootElement()) {
9994
+ this.setRootElement(rootElement);
9752
9995
  }
9753
9996
 
9754
9997
  if (!padding) {
@@ -10111,7 +10354,9 @@
10111
10354
  container.gfx = gfx;
10112
10355
  }
10113
10356
 
10114
- attr$1(gfx, ELEMENT_ID, id);
10357
+ if (gfx) {
10358
+ attr$1(gfx, ELEMENT_ID, id);
10359
+ }
10115
10360
 
10116
10361
  return gfx;
10117
10362
  };
@@ -19888,18 +20133,29 @@
19888
20133
 
19889
20134
  var walker = new BpmnTreeWalker(visitor, translate);
19890
20135
 
20136
+
20137
+ bpmnDiagram = bpmnDiagram || (definitions.diagrams && definitions.diagrams[0]);
20138
+
20139
+ var diagramsToImport = getDiagramsToImport(definitions, bpmnDiagram);
20140
+
20141
+ if (!diagramsToImport) {
20142
+ throw new Error(translate('no diagram to display'));
20143
+ }
20144
+
19891
20145
  // traverse BPMN 2.0 document model,
19892
20146
  // starting at definitions
19893
- if (!bpmnDiagram && definitions.diagrams) {
19894
- for (var i = 0; i < definitions.diagrams.length; i++) {
19895
- walker.handleDefinitions(definitions, definitions.diagrams[i]);
19896
- }
19897
- } else {
19898
- walker.handleDefinitions(definitions, bpmnDiagram);
19899
- }
20147
+ forEach(diagramsToImport, function(diagram) {
20148
+ walker.handleDefinitions(definitions, diagram);
20149
+ });
19900
20150
 
19901
- var mainDiagram = bpmnDiagram || definitions.diagrams[0];
19902
- canvas.setActivePlane(mainDiagram.plane.bpmnElement.id);
20151
+ var rootId = bpmnDiagram.plane.bpmnElement.id;
20152
+
20153
+ // we do need to account for different ways we create root elements
20154
+ // each nested imported <root> do have the `_plane` suffix, while
20155
+ // the root <root> is found under the business object ID
20156
+ canvas.setRootElement(
20157
+ canvas.findRoot(rootId + '_plane') || canvas.findRoot(rootId)
20158
+ );
19903
20159
  }
19904
20160
 
19905
20161
  return new Promise(function(resolve, reject) {
@@ -19927,6 +20183,107 @@
19927
20183
  });
19928
20184
  }
19929
20185
 
20186
+ /**
20187
+ * Returns all diagrams in the same hirarchy as the requested diagram.
20188
+ * Includes all parent and sub process diagrams.
20189
+ *
20190
+ * @param {Array} definitions
20191
+ * @param {Object} bpmnDiagram
20192
+ *
20193
+ * @returns {Array<Object>}
20194
+ */
20195
+ function getDiagramsToImport(definitions, bpmnDiagram) {
20196
+ if (!bpmnDiagram) {
20197
+ return;
20198
+ }
20199
+
20200
+ var bpmnElement = bpmnDiagram.plane.bpmnElement,
20201
+ rootElement = bpmnElement;
20202
+
20203
+ if (!is$1(bpmnElement, 'bpmn:Process') && !is$1(bpmnElement, 'bpmn:Collaboration')) {
20204
+ rootElement = findRootProcess(bpmnElement);
20205
+ }
20206
+
20207
+ // in case the process is part of a collaboration, the plane references the
20208
+ // collaboration, not the process
20209
+ var collaboration;
20210
+
20211
+ if (is$1(rootElement, 'bpmn:Collaboration')) {
20212
+ collaboration = rootElement;
20213
+ } else {
20214
+ collaboration = find(definitions.rootElements, function(element) {
20215
+ if (!is$1(element, 'bpmn:Collaboration')) {
20216
+ return;
20217
+ }
20218
+
20219
+ return find(element.participants, function(participant) {
20220
+ return participant.processRef === rootElement;
20221
+ });
20222
+ });
20223
+ }
20224
+
20225
+ var rootElements = [ rootElement ];
20226
+
20227
+ // all collaboration processes can contain sub-diagrams
20228
+ if (collaboration) {
20229
+ rootElements = map$1(collaboration.participants, function(participant) {
20230
+ return participant.processRef;
20231
+ });
20232
+
20233
+ rootElements.push(collaboration);
20234
+ }
20235
+
20236
+ var allChildren = selfAndAllFlowElements(rootElements);
20237
+
20238
+ // if we have multiple diagrams referencing the same element, we
20239
+ // use the first in the file
20240
+ var diagramsToImport = [ bpmnDiagram ];
20241
+ var handledElements = [ bpmnElement ];
20242
+
20243
+ forEach(definitions.diagrams, function(diagram) {
20244
+ var businessObject = diagram.plane.bpmnElement;
20245
+
20246
+ if (
20247
+ allChildren.indexOf(businessObject) !== -1 &&
20248
+ handledElements.indexOf(businessObject) === -1
20249
+ ) {
20250
+ diagramsToImport.push(diagram);
20251
+ handledElements.push(businessObject);
20252
+ }
20253
+ });
20254
+
20255
+
20256
+ return diagramsToImport;
20257
+ }
20258
+
20259
+ function selfAndAllFlowElements(elements) {
20260
+ var result = [];
20261
+
20262
+ forEach(elements, function(element) {
20263
+ if (!element) {
20264
+ return;
20265
+ }
20266
+
20267
+ result.push(element);
20268
+
20269
+ result = result.concat(selfAndAllFlowElements(element.flowElements));
20270
+ });
20271
+
20272
+ return result;
20273
+ }
20274
+
20275
+ function findRootProcess(element) {
20276
+ var parent = element;
20277
+
20278
+ while (parent) {
20279
+ if (is$1(parent, 'bpmn:Process')) {
20280
+ return parent;
20281
+ }
20282
+
20283
+ parent = parent.$parent;
20284
+ }
20285
+ }
20286
+
19930
20287
  /**
19931
20288
  * This file must not be changed or exchanged.
19932
20289
  *
@@ -20417,7 +20774,7 @@
20417
20774
  try {
20418
20775
  var canvas = self.get('canvas');
20419
20776
 
20420
- var contentNode = canvas.getDefaultLayer(),
20777
+ var contentNode = canvas.getActiveLayer(),
20421
20778
  defsNode = query('defs', canvas._svg);
20422
20779
 
20423
20780
  var contents = innerSVG(contentNode),
@@ -20799,7 +21156,7 @@
20799
21156
  TranslateModule,
20800
21157
  SelectionModule,
20801
21158
  OverlaysModule,
20802
- SubprocessNavigationModule
21159
+ DrilldownModdule
20803
21160
  ];
20804
21161
 
20805
21162
  // default moddle extensions the viewer is composed of
@@ -20949,7 +21306,7 @@
20949
21306
  }
20950
21307
 
20951
21308
  var allowedModifiers = this._getAllowedModifiers(event.target);
20952
- return !allowedModifiers.includes(event.key);
21309
+ return allowedModifiers.indexOf(event.key) === -1;
20953
21310
  };
20954
21311
 
20955
21312
  Keyboard.prototype._getAllowedModifiers = function(element) {