@metadev/daga 5.0.2 → 5.0.4

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.
package/index.esm.js CHANGED
@@ -210,7 +210,7 @@ const distanceBetweenPoints = (point1, point2) => {
210
210
  return Math.pow(Math.pow(point1[0] - point2[0], 2) + Math.pow(point1[1] - point2[1], 2), 0.5);
211
211
  };
212
212
  /**
213
- * Checks whether the two given reactangles share at least one point.
213
+ * Checks whether the two given rectangles share at least one point.
214
214
  * @public
215
215
  * @param rectangle1 A rectangle.
216
216
  * @param rectangle2 A rectangle.
@@ -1170,6 +1170,9 @@ const numberOfRows = s => {
1170
1170
  * @private
1171
1171
  */
1172
1172
  const clone = o => {
1173
+ if (o === null) {
1174
+ return o;
1175
+ }
1173
1176
  if (typeof o !== 'object') {
1174
1177
  return o;
1175
1178
  }
@@ -2424,7 +2427,7 @@ class DiagramConnection extends DiagramElement {
2424
2427
  */
2425
2428
  this.endLabel = '';
2426
2429
  /**
2427
- * Points that this connection passes through.
2430
+ * Points that this connection must pass through in its route from its start point to its end point, in order.
2428
2431
  * @public
2429
2432
  */
2430
2433
  this.points = [];
@@ -2442,8 +2445,10 @@ class DiagramConnection extends DiagramElement {
2442
2445
  (_a = this.model.canvas) === null || _a === void 0 ? void 0 : _a.updateConnectionsInView(this.id);
2443
2446
  }
2444
2447
  raise() {
2445
- var _a;
2448
+ var _a, _b, _c;
2446
2449
  (_a = this.select()) === null || _a === void 0 ? void 0 : _a.raise();
2450
+ (_b = this.start) === null || _b === void 0 ? void 0 : _b.raise(false);
2451
+ (_c = this.end) === null || _c === void 0 ? void 0 : _c.raise(false);
2447
2452
  }
2448
2453
  /**
2449
2454
  * Set the start of this connection to the given port or reset this connection's starting port if `undefined`.
@@ -2497,11 +2502,12 @@ class DiagramConnection extends DiagramElement {
2497
2502
  * @public
2498
2503
  */
2499
2504
  tighten() {
2500
- var _a, _b, _c, _d, _e;
2505
+ var _a, _b, _c, _d, _e, _f;
2501
2506
  const allowConnectionLoops = ((_a = this.model.canvas) === null || _a === void 0 ? void 0 : _a.allowConnectionLoops) || false;
2502
2507
  const allowSharingPorts = ((_b = this.model.canvas) === null || _b === void 0 ? void 0 : _b.allowSharingPorts) !== false;
2503
2508
  const allowSharingBothPorts = ((_c = this.model.canvas) === null || _c === void 0 ? void 0 : _c.allowSharingBothPorts) || false;
2504
- if (((_d = this.start) === null || _d === void 0 ? void 0 : _d.rootElement) && this.end) {
2509
+ const tightenConnectionsAcrossPortTypes = ((_d = this.model.canvas) === null || _d === void 0 ? void 0 : _d.tightenConnectionsAcrossPortTypes) || false;
2510
+ if (((_e = this.start) === null || _e === void 0 ? void 0 : _e.rootElement) && this.end) {
2505
2511
  const alternativeStartPortsSortedByDistanceAscending = this.start.rootElement.ports.map(p => [p, p.distanceTo(this.end.coords)]).sort((a, b) => a[1] - b[1]).map(a => a[0]);
2506
2512
  checkAlternativeStartPorts: for (const alternativeStartPort of alternativeStartPortsSortedByDistanceAscending) {
2507
2513
  if (!allowConnectionLoops && alternativeStartPort === this.end) {
@@ -2512,6 +2518,10 @@ class DiagramConnection extends DiagramElement {
2512
2518
  // alternative start port not valid, it doesn't allow outgoing connections
2513
2519
  continue checkAlternativeStartPorts;
2514
2520
  }
2521
+ if (!tightenConnectionsAcrossPortTypes && alternativeStartPort.type !== this.start.type) {
2522
+ // alternative start port not valid, the port type is different
2523
+ continue checkAlternativeStartPorts;
2524
+ }
2515
2525
  if (!allowSharingPorts && (alternativeStartPort.incomingConnections.filter(c => !c.removed && c !== this).length > 0 || alternativeStartPort.outgoingConnections.filter(c => !c.removed && c !== this).length > 0)) {
2516
2526
  // alternative start port not valid, it already has other connections
2517
2527
  continue checkAlternativeStartPorts;
@@ -2539,7 +2549,7 @@ class DiagramConnection extends DiagramElement {
2539
2549
  }
2540
2550
  }
2541
2551
  }
2542
- if (((_e = this.end) === null || _e === void 0 ? void 0 : _e.rootElement) && this.start) {
2552
+ if (((_f = this.end) === null || _f === void 0 ? void 0 : _f.rootElement) && this.start) {
2543
2553
  const alternativeEndPortsSortedByDistanceAscending = this.end.rootElement.ports.map(p => [p, p.distanceTo(this.start.coords)]).sort((a, b) => a[1] - b[1]).map(a => a[0]);
2544
2554
  checkAlternativeEndPorts: for (const alternativeEndPort of alternativeEndPortsSortedByDistanceAscending) {
2545
2555
  if (!allowConnectionLoops && alternativeEndPort === this.start) {
@@ -2550,6 +2560,10 @@ class DiagramConnection extends DiagramElement {
2550
2560
  // alternative end port not valid, it doesn't allow incoming connections
2551
2561
  continue checkAlternativeEndPorts;
2552
2562
  }
2563
+ if (!tightenConnectionsAcrossPortTypes && alternativeEndPort.type !== this.end.type) {
2564
+ // alternative end port not valid, the port type is different
2565
+ continue checkAlternativeEndPorts;
2566
+ }
2553
2567
  if (!allowSharingPorts && (alternativeEndPort.incomingConnections.filter(c => !c.removed && c !== this).length > 0 || alternativeEndPort.outgoingConnections.filter(c => !c.removed && c !== this).length > 0)) {
2554
2568
  // alternative end port not valid, it already has other connections
2555
2569
  continue checkAlternativeEndPorts;
@@ -2618,6 +2632,7 @@ class DiagramConnectionSet extends DiagramElementSet {
2618
2632
  * @returns The instanced connection.
2619
2633
  */
2620
2634
  new(type, start, end, id) {
2635
+ var _a, _b;
2621
2636
  let connectionType;
2622
2637
  if (type instanceof DiagramConnectionType) {
2623
2638
  connectionType = type;
@@ -2632,6 +2647,8 @@ class DiagramConnectionSet extends DiagramElementSet {
2632
2647
  super.add(connection);
2633
2648
  connection.updateInView();
2634
2649
  connection.valueSet.resetValues();
2650
+ (_a = connection.start) === null || _a === void 0 ? void 0 : _a.raise(false);
2651
+ (_b = connection.end) === null || _b === void 0 ? void 0 : _b.raise(false);
2635
2652
  return connection;
2636
2653
  }
2637
2654
  remove(id) {
@@ -2666,6 +2683,7 @@ const DIAGRAM_FIELD_DEFAULTS = {
2666
2683
  horizontalAlign: HorizontalAlign.Center,
2667
2684
  verticalAlign: VerticalAlign.Center,
2668
2685
  orientation: Side.Top,
2686
+ multiline: false,
2669
2687
  fit: false,
2670
2688
  shrink: true
2671
2689
  };
@@ -2695,7 +2713,7 @@ class DiagramField extends DiagramElement {
2695
2713
  (_a = this.model.canvas) === null || _a === void 0 ? void 0 : _a.fitFieldRootInView(this.id, this.shrink);
2696
2714
  }
2697
2715
  }
2698
- constructor(model, rootElement, coords, width, height, fontSize, fontFamily, color, selectedColor, horizontalAlign, verticalAlign, orientation, text, editable, fit, shrink) {
2716
+ constructor(model, rootElement, coords, width, height, fontSize, fontFamily, color, selectedColor, horizontalAlign, verticalAlign, orientation, multiline, text, editable, fit, shrink) {
2699
2717
  const id = `${rootElement === null || rootElement === void 0 ? void 0 : rootElement.id}_field`;
2700
2718
  if (model.fields.get(id) !== undefined) {
2701
2719
  throw new Error('DiagramField for rootElement already exists');
@@ -2736,6 +2754,7 @@ class DiagramField extends DiagramElement {
2736
2754
  this.orientation = 0;
2737
2755
  }
2738
2756
  }
2757
+ this.multiline = multiline;
2739
2758
  this.defaultText = text;
2740
2759
  this._text = text;
2741
2760
  this.editable = editable;
@@ -2780,8 +2799,8 @@ class DiagramFieldSet extends DiagramElementSet {
2780
2799
  * Instance a new field and add it to this set. This method is normally called when instancing an element with a field and it is rarely called by itself.
2781
2800
  * @private
2782
2801
  */
2783
- new(rootElement, coords, fontSize, fontFamily, color, selectedColor, width, height, horizontalAlign, verticalAlign, orientation, text, editable, fit, shrink) {
2784
- const field = new DiagramField(this.model, rootElement, coords, width, height, fontSize, fontFamily, color, selectedColor, horizontalAlign, verticalAlign, orientation, text, editable, fit, shrink);
2802
+ new(rootElement, coords, fontSize, fontFamily, color, selectedColor, width, height, horizontalAlign, verticalAlign, orientation, multiline, text, editable, fit, shrink) {
2803
+ const field = new DiagramField(this.model, rootElement, coords, width, height, fontSize, fontFamily, color, selectedColor, horizontalAlign, verticalAlign, orientation, multiline, text, editable, fit, shrink);
2785
2804
  super.add(field);
2786
2805
  field.updateInView();
2787
2806
  // add this field to its root element
@@ -2960,6 +2979,11 @@ const getTopPadding$1 = config => {
2960
2979
  }
2961
2980
  };
2962
2981
 
2982
+ var ResizableMode;
2983
+ (function (ResizableMode) {
2984
+ ResizableMode[ResizableMode["OnlyWhenSelected"] = 0] = "OnlyWhenSelected";
2985
+ })(ResizableMode || (ResizableMode = {}));
2986
+
2963
2987
  /**
2964
2988
  * Default value of the default width of a diagram section.
2965
2989
  * @private
@@ -3164,12 +3188,15 @@ class DiagramSection extends DiagramElement {
3164
3188
  * @public
3165
3189
  */
3166
3190
  getResizableX() {
3167
- var _a, _b;
3191
+ var _a;
3168
3192
  const sectionType = this.type;
3169
3193
  if ((sectionType === null || sectionType === void 0 ? void 0 : sectionType.resizableX) !== undefined) {
3194
+ if (sectionType.resizableX === ResizableMode.OnlyWhenSelected) {
3195
+ return this.selected;
3196
+ }
3170
3197
  return sectionType.resizableX;
3171
3198
  }
3172
- return ((_b = (_a = this.node) === null || _a === void 0 ? void 0 : _a.type) === null || _b === void 0 ? void 0 : _b.resizableX) || false;
3199
+ return ((_a = this.node) === null || _a === void 0 ? void 0 : _a.getResizableX()) || false;
3173
3200
  }
3174
3201
  /**
3175
3202
  * Returns whether this section can be resized vertically.
@@ -3178,12 +3205,15 @@ class DiagramSection extends DiagramElement {
3178
3205
  * @public
3179
3206
  */
3180
3207
  getResizableY() {
3181
- var _a, _b;
3208
+ var _a;
3182
3209
  const sectionType = this.type;
3183
3210
  if ((sectionType === null || sectionType === void 0 ? void 0 : sectionType.resizableY) !== undefined) {
3211
+ if (sectionType.resizableY === ResizableMode.OnlyWhenSelected) {
3212
+ return this.selected;
3213
+ }
3184
3214
  return sectionType.resizableY;
3185
3215
  }
3186
- return ((_b = (_a = this.node) === null || _a === void 0 ? void 0 : _a.type) === null || _b === void 0 ? void 0 : _b.resizableY) || false;
3216
+ return ((_a = this.node) === null || _a === void 0 ? void 0 : _a.getResizableY()) || false;
3187
3217
  }
3188
3218
  /**
3189
3219
  * Get the port of this section which is closest to the given coordinates.
@@ -3409,7 +3439,7 @@ class DiagramSectionSet extends DiagramElementSet {
3409
3439
  default:
3410
3440
  labelCoords = port.coords;
3411
3441
  }
3412
- this.model.fields.new(port, labelCoords, labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelWidth, labelHeight, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, labelConfiguration.orientation, '', labelConfiguration.editable, labelConfiguration.fit, labelConfiguration.shrink);
3442
+ this.model.fields.new(port, labelCoords, labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelWidth, labelHeight, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, labelConfiguration.orientation, labelConfiguration.multiline, '', labelConfiguration.editable, labelConfiguration.fit, labelConfiguration.shrink);
3413
3443
  }
3414
3444
  }
3415
3445
  }
@@ -3417,7 +3447,7 @@ class DiagramSectionSet extends DiagramElementSet {
3417
3447
  const sectionLabel = (_k = (_j = (_h = (_g = node.type.sectionGrid) === null || _g === void 0 ? void 0 : _g.sections) === null || _h === void 0 ? void 0 : _h[indexYInNode]) === null || _j === void 0 ? void 0 : _j[indexXInNode]) === null || _k === void 0 ? void 0 : _k.label;
3418
3448
  if (sectionLabel) {
3419
3449
  const labelConfiguration = Object.assign(Object.assign({}, DIAGRAM_FIELD_DEFAULTS), sectionLabel);
3420
- this.model.fields.new(section, [section.coords[0] + getLeftMargin(labelConfiguration), section.coords[1] + getTopMargin(labelConfiguration)], labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, section.width - getLeftMargin(labelConfiguration) - getRightMargin(labelConfiguration), section.height - getTopMargin(labelConfiguration) - getBottomMargin(labelConfiguration), labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, labelConfiguration.orientation, '', labelConfiguration.editable, labelConfiguration.fit, labelConfiguration.shrink);
3450
+ this.model.fields.new(section, [section.coords[0] + getLeftMargin(labelConfiguration), section.coords[1] + getTopMargin(labelConfiguration)], labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, section.width - getLeftMargin(labelConfiguration) - getRightMargin(labelConfiguration), section.height - getTopMargin(labelConfiguration) - getBottomMargin(labelConfiguration), labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, labelConfiguration.orientation, labelConfiguration.multiline, '', labelConfiguration.editable, labelConfiguration.fit, labelConfiguration.shrink);
3421
3451
  }
3422
3452
  return section;
3423
3453
  }
@@ -3694,6 +3724,28 @@ class DiagramNode extends DiagramElement {
3694
3724
  getPriority() {
3695
3725
  return this.type.priority;
3696
3726
  }
3727
+ /**
3728
+ * Returns whether this node can be resized horizontally.
3729
+ * @public
3730
+ */
3731
+ getResizableX() {
3732
+ const resizableX = this.type.resizableX;
3733
+ if (resizableX === ResizableMode.OnlyWhenSelected) {
3734
+ return this.selected;
3735
+ }
3736
+ return resizableX;
3737
+ }
3738
+ /**
3739
+ * Returns whether this node can be resized vertically.
3740
+ * @public
3741
+ */
3742
+ getResizableY() {
3743
+ const resizableY = this.type.resizableY;
3744
+ if (resizableY === ResizableMode.OnlyWhenSelected) {
3745
+ return this.selected;
3746
+ }
3747
+ return resizableY;
3748
+ }
3697
3749
  /**
3698
3750
  * Get the port of this node which is closest to the given coordinates.
3699
3751
  * @param coords A point in the diagram.
@@ -4315,14 +4367,14 @@ class DiagramNodeSet extends DiagramElementSet {
4315
4367
  default:
4316
4368
  labelCoords = port.coords;
4317
4369
  }
4318
- this.model.fields.new(port, labelCoords, labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelWidth, labelHeight, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, labelConfiguration.orientation, '', labelConfiguration.editable, labelConfiguration.fit, labelConfiguration.shrink);
4370
+ this.model.fields.new(port, labelCoords, labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelWidth, labelHeight, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, labelConfiguration.orientation, labelConfiguration.multiline, '', labelConfiguration.editable, labelConfiguration.fit, labelConfiguration.shrink);
4319
4371
  }
4320
4372
  }
4321
4373
  }
4322
4374
  // add node label
4323
4375
  if (nodeType.label) {
4324
4376
  const labelConfiguration = Object.assign(Object.assign({}, DIAGRAM_FIELD_DEFAULTS), nodeType.label);
4325
- this.model.fields.new(node, [node.coords[0] + getLeftMargin(labelConfiguration), node.coords[1] + getTopMargin(labelConfiguration)], labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, node.width - getLeftMargin(labelConfiguration) - getRightMargin(labelConfiguration), node.height - getTopMargin(labelConfiguration) - getBottomMargin(labelConfiguration), labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, labelConfiguration.orientation, '', labelConfiguration.editable, labelConfiguration.fit, labelConfiguration.shrink);
4377
+ this.model.fields.new(node, [node.coords[0] + getLeftMargin(labelConfiguration), node.coords[1] + getTopMargin(labelConfiguration)], labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, node.width - getLeftMargin(labelConfiguration) - getRightMargin(labelConfiguration), node.height - getTopMargin(labelConfiguration) - getBottomMargin(labelConfiguration), labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, labelConfiguration.orientation, labelConfiguration.multiline, '', labelConfiguration.editable, labelConfiguration.fit, labelConfiguration.shrink);
4326
4378
  }
4327
4379
  // add node decorators
4328
4380
  if (nodeType.decorators.length > 0) {
@@ -4716,17 +4768,19 @@ class DiagramPort extends DiagramElement {
4716
4768
  var _a;
4717
4769
  (_a = this.model.canvas) === null || _a === void 0 ? void 0 : _a.updatePortsInView(this.id);
4718
4770
  }
4719
- raise() {
4771
+ raise(raiseConnections = true) {
4720
4772
  var _a;
4721
4773
  (_a = this.select()) === null || _a === void 0 ? void 0 : _a.raise();
4722
4774
  if (this.label) {
4723
4775
  this.label.raise();
4724
4776
  }
4725
- for (const connection of this.incomingConnections) {
4726
- connection.raise();
4727
- }
4728
- for (const connection of this.outgoingConnections) {
4729
- connection.raise();
4777
+ if (raiseConnections) {
4778
+ for (const connection of this.incomingConnections) {
4779
+ connection.raise();
4780
+ }
4781
+ for (const connection of this.outgoingConnections) {
4782
+ connection.raise();
4783
+ }
4730
4784
  }
4731
4785
  }
4732
4786
  /**
@@ -4880,23 +4934,21 @@ class DagaImporter {
4880
4934
  model.nodes.add(newNode);
4881
4935
  newNode.width = node.width;
4882
4936
  newNode.height = node.height;
4883
- if (node.label) {
4884
- // add node decorators
4885
- if (newNodeType.decorators) {
4886
- for (let i = 0; i < newNodeType.decorators.length; ++i) {
4887
- const decoratorConfig = newNodeType.decorators[i];
4888
- model.decorators.new(newNode, [newNode.coords[0] + decoratorConfig.coords[0], newNode.coords[1] + decoratorConfig.coords[1]], decoratorConfig.width, decoratorConfig.height, newNode.getPriority(), decoratorConfig.html, `${newNode.id}_decorator_${i}`);
4889
- }
4890
- }
4891
- // add node label
4892
- if (newNodeType.label) {
4893
- const labelConfiguration = Object.assign(Object.assign({}, DIAGRAM_FIELD_DEFAULTS), newNodeType.label);
4894
- const newField = new DiagramField(model, newNode, [newNode.coords[0] + getLeftMargin(labelConfiguration), newNode.coords[1] + getTopMargin(labelConfiguration)], newNode.width - getLeftMargin(labelConfiguration) - getRightMargin(labelConfiguration), newNode.height - getTopMargin(labelConfiguration) - getBottomMargin(labelConfiguration), labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, labelConfiguration.orientation, '', labelConfiguration.editable, labelConfiguration.fit, labelConfiguration.shrink);
4895
- newField.text = node.label;
4896
- newNode.label = newField;
4897
- model.fields.add(newField);
4898
- newField.updateInView();
4899
- }
4937
+ // add node decorators
4938
+ if (newNodeType.decorators) {
4939
+ for (let i = 0; i < newNodeType.decorators.length; ++i) {
4940
+ const decoratorConfig = newNodeType.decorators[i];
4941
+ model.decorators.new(newNode, [newNode.coords[0] + decoratorConfig.coords[0], newNode.coords[1] + decoratorConfig.coords[1]], decoratorConfig.width, decoratorConfig.height, newNode.getPriority(), decoratorConfig.html, `${newNode.id}_decorator_${i}`);
4942
+ }
4943
+ }
4944
+ // add node label
4945
+ if (newNodeType.label) {
4946
+ const labelConfiguration = Object.assign(Object.assign({}, DIAGRAM_FIELD_DEFAULTS), newNodeType.label);
4947
+ const newField = new DiagramField(model, newNode, [newNode.coords[0] + getLeftMargin(labelConfiguration), newNode.coords[1] + getTopMargin(labelConfiguration)], newNode.width - getLeftMargin(labelConfiguration) - getRightMargin(labelConfiguration), newNode.height - getTopMargin(labelConfiguration) - getBottomMargin(labelConfiguration), labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, labelConfiguration.orientation, labelConfiguration.multiline, '', labelConfiguration.editable, labelConfiguration.fit, labelConfiguration.shrink);
4948
+ newField.text = node.label;
4949
+ newNode.label = newField;
4950
+ model.fields.add(newField);
4951
+ newField.updateInView();
4900
4952
  }
4901
4953
  for (const child of node.children || []) {
4902
4954
  const newChild = this.importNode(model, child);
@@ -4909,16 +4961,14 @@ class DagaImporter {
4909
4961
  const newSection = new DiagramSection(model, newNode, section.indexXInNode, section.indexYInNode, section.coords, section.width, section.height, section.id);
4910
4962
  (_b = newNode.sections) === null || _b === void 0 ? void 0 : _b.push(newSection);
4911
4963
  model.sections.add(newSection);
4912
- if (section.label) {
4913
- // add section label
4914
- if ((_f = (_e = (_d = (_c = newNodeType.sectionGrid) === null || _c === void 0 ? void 0 : _c.sections) === null || _d === void 0 ? void 0 : _d[section.indexYInNode]) === null || _e === void 0 ? void 0 : _e[section.indexXInNode]) === null || _f === void 0 ? void 0 : _f.label) {
4915
- const labelConfiguration = Object.assign(Object.assign({}, DIAGRAM_FIELD_DEFAULTS), (_k = (_j = (_h = (_g = newNodeType.sectionGrid) === null || _g === void 0 ? void 0 : _g.sections) === null || _h === void 0 ? void 0 : _h[section.indexYInNode]) === null || _j === void 0 ? void 0 : _j[section.indexXInNode]) === null || _k === void 0 ? void 0 : _k.label);
4916
- const newField = new DiagramField(model, newSection, [newSection.coords[0] + getLeftMargin(labelConfiguration), newSection.coords[1] + getTopMargin(labelConfiguration)], newSection.width - getLeftMargin(labelConfiguration) - getRightMargin(labelConfiguration), newSection.height - getTopMargin(labelConfiguration) - getBottomMargin(labelConfiguration), labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, labelConfiguration.orientation, '', labelConfiguration.editable, labelConfiguration.fit, labelConfiguration.shrink);
4917
- newField.text = section.label;
4918
- newSection.label = newField;
4919
- model.fields.add(newField);
4920
- newField.updateInView();
4921
- }
4964
+ // add section label
4965
+ if ((_f = (_e = (_d = (_c = newNodeType.sectionGrid) === null || _c === void 0 ? void 0 : _c.sections) === null || _d === void 0 ? void 0 : _d[section.indexYInNode]) === null || _e === void 0 ? void 0 : _e[section.indexXInNode]) === null || _f === void 0 ? void 0 : _f.label) {
4966
+ const labelConfiguration = Object.assign(Object.assign({}, DIAGRAM_FIELD_DEFAULTS), (_k = (_j = (_h = (_g = newNodeType.sectionGrid) === null || _g === void 0 ? void 0 : _g.sections) === null || _h === void 0 ? void 0 : _h[section.indexYInNode]) === null || _j === void 0 ? void 0 : _j[section.indexXInNode]) === null || _k === void 0 ? void 0 : _k.label);
4967
+ const newField = new DiagramField(model, newSection, [newSection.coords[0] + getLeftMargin(labelConfiguration), newSection.coords[1] + getTopMargin(labelConfiguration)], newSection.width - getLeftMargin(labelConfiguration) - getRightMargin(labelConfiguration), newSection.height - getTopMargin(labelConfiguration) - getBottomMargin(labelConfiguration), labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, labelConfiguration.orientation, labelConfiguration.multiline, '', labelConfiguration.editable, labelConfiguration.fit, labelConfiguration.shrink);
4968
+ newField.text = section.label;
4969
+ newSection.label = newField;
4970
+ model.fields.add(newField);
4971
+ newField.updateInView();
4922
4972
  }
4923
4973
  let portCounter = 0;
4924
4974
  for (const port of section.ports || []) {
@@ -4945,7 +4995,7 @@ class DagaImporter {
4945
4995
  default:
4946
4996
  labelCoords = newPort.coords;
4947
4997
  }
4948
- const newField = new DiagramField(model, newPort, labelCoords, labelConfiguration.fontSize, labelConfiguration.fontSize, labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, labelConfiguration.orientation, '', labelConfiguration.editable, labelConfiguration.fit, labelConfiguration.shrink);
4998
+ const newField = new DiagramField(model, newPort, labelCoords, labelConfiguration.fontSize, labelConfiguration.fontSize, labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, labelConfiguration.orientation, labelConfiguration.multiline, '', labelConfiguration.editable, labelConfiguration.fit, labelConfiguration.shrink);
4949
4999
  newField.text = port.label;
4950
5000
  newPort.label = newField;
4951
5001
  model.fields.add(newField);
@@ -4992,7 +5042,7 @@ class DagaImporter {
4992
5042
  default:
4993
5043
  labelCoords = newPort.coords;
4994
5044
  }
4995
- const newField = new DiagramField(model, newPort, labelCoords, labelConfiguration.fontSize, labelConfiguration.fontSize, labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, labelConfiguration.orientation, '', labelConfiguration.editable, labelConfiguration.fit, labelConfiguration.shrink);
5045
+ const newField = new DiagramField(model, newPort, labelCoords, labelConfiguration.fontSize, labelConfiguration.fontSize, labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, labelConfiguration.orientation, labelConfiguration.multiline, '', labelConfiguration.editable, labelConfiguration.fit, labelConfiguration.shrink);
4996
5046
  newField.text = port.label;
4997
5047
  newPort.label = newField;
4998
5048
  model.fields.add(newField);
@@ -6289,6 +6339,7 @@ var DiagramEvents;
6289
6339
  DiagramEvents[DiagramEvents["SecondaryClick"] = 2] = "SecondaryClick";
6290
6340
  DiagramEvents[DiagramEvents["Selection"] = 3] = "Selection";
6291
6341
  DiagramEvents[DiagramEvents["Highlight"] = 4] = "Highlight";
6342
+ DiagramEvents[DiagramEvents["DraggingNode"] = 5] = "DraggingNode";
6292
6343
  })(DiagramEvents || (DiagramEvents = {}));
6293
6344
  /**
6294
6345
  * Diagram event which consists of the user zooming or panning.
@@ -6372,6 +6423,20 @@ class DiagramHighlightedEvent extends DiagramEvent {
6372
6423
  this.target = target;
6373
6424
  }
6374
6425
  }
6426
+ /**
6427
+ * Diagram event which consists of the user dragging a diagram node.
6428
+ */
6429
+ class DiagramDraggingNodeEvent extends DiagramEvent {
6430
+ /**
6431
+ * Create a diagram dragging node event.
6432
+ *
6433
+ * @param target Diagram node which is targeted by the event.
6434
+ */
6435
+ constructor(target) {
6436
+ super(DiagramEvents.DraggingNode);
6437
+ this.target = target;
6438
+ }
6439
+ }
6375
6440
 
6376
6441
  /**
6377
6442
  * A foreign object which is inserted with arbitrary html into a diagram.
@@ -6648,8 +6713,8 @@ const isSecondaryButton = event => {
6648
6713
  * @private
6649
6714
  * @see linePath
6650
6715
  */
6651
- const getConnectionPath = (shape, startCoords, endCoords, startDirection, endDirection, width, startMarkerWidth, endMarkerWidth) => {
6652
- return linePath(shape, [startCoords, endCoords], startDirection, endDirection, Math.max(
6716
+ const getConnectionPath = (shape, startCoords, endCoords, startDirection, endDirection, points, width, startMarkerWidth, endMarkerWidth) => {
6717
+ return linePath(shape, [startCoords, ...points, endCoords], startDirection, endDirection, Math.max(
6653
6718
  // reasonable value for the minimumDistanceBeforeTurn relative to the line width
6654
6719
  10, startMarkerWidth || 0, endMarkerWidth || 0) * width);
6655
6720
  };
@@ -6669,6 +6734,34 @@ const getRelatedNodeOrItself = element => {
6669
6734
  }
6670
6735
  return element.rootElement instanceof DiagramNode || element.rootElement instanceof DiagramSection || element.rootElement instanceof DiagramPort ? getRelatedNodeOrItself(element.rootElement) : element;
6671
6736
  };
6737
+ const needsResizerX = element => {
6738
+ if (element instanceof DiagramNode) {
6739
+ return element.type.resizableX !== false;
6740
+ }
6741
+ if (element instanceof DiagramSection) {
6742
+ if (element.type !== undefined) {
6743
+ return element.type.resizableX !== false;
6744
+ }
6745
+ if (element.node !== undefined) {
6746
+ return needsResizerX(element.node);
6747
+ }
6748
+ }
6749
+ return false;
6750
+ };
6751
+ const needsResizerY = element => {
6752
+ if (element instanceof DiagramNode) {
6753
+ return element.type.resizableY !== false;
6754
+ }
6755
+ if (element instanceof DiagramSection) {
6756
+ if (element.type !== undefined) {
6757
+ return element.type.resizableY !== false;
6758
+ }
6759
+ if (element.node !== undefined) {
6760
+ return needsResizerY(element.node);
6761
+ }
6762
+ }
6763
+ return false;
6764
+ };
6672
6765
  const initializeLook = selection => {
6673
6766
  selection.filter('.shaped-look').append('path');
6674
6767
  selection.filter('.image-look').append('image').attr('preserveAspectRatio', 'none');
@@ -7143,10 +7236,10 @@ class DiagramUserSelection extends DiagramElementSet {
7143
7236
  constructor(canvas, diagramPropertiesText) {
7144
7237
  super();
7145
7238
  this.canvas = canvas;
7239
+ // TODO: would be a good idea to be able to configure how often this fires, or whether at all
7146
7240
  this.canvas.propertyEditorChanges$.pipe(debounceTime(2000)).subscribe(() => {
7147
7241
  this.makeUpdateValuesAction();
7148
7242
  });
7149
- //console.log(diagramPropertiesText);
7150
7243
  this.diagramPropertiesText = diagramPropertiesText !== undefined ? diagramPropertiesText : DIAGRAM_PROPERTIES_DEFAULT_TEXT;
7151
7244
  }
7152
7245
  add(element) {
@@ -7378,26 +7471,6 @@ class DiagramUserSelection extends DiagramElementSet {
7378
7471
  }
7379
7472
  }
7380
7473
 
7381
- const degreesToRadians = theta => theta * Math.PI / 180;
7382
- /**
7383
- * Calculates the original size of the a rectangle that has been rotated by the given number of degrees resulting in a bounding box of the given size.
7384
- *
7385
- * @param width The width of a bounding box.
7386
- * @param height The height of a bounding box.
7387
- * @param orientation A rotation in degrees.
7388
- * @returns The size of the original rectangle.
7389
- */
7390
- const unrotate = (width, height, orientation) => {
7391
- // TODO: this method fails under certain edge cases
7392
- // like for example, when angle is 45 degrees so sin(theta) == cos(theta)
7393
- const theta = degreesToRadians(orientation);
7394
- const orientationSine = Math.sin(theta);
7395
- const orientationCosine = Math.cos(theta);
7396
- const oldWidth = (Math.abs(width * orientationCosine) - Math.abs(height * orientationSine)) / (orientationCosine * orientationCosine - orientationSine * orientationSine);
7397
- const oldHeight = (Math.abs(width * orientationSine) - Math.abs(height * orientationCosine)) / (orientationSine * orientationSine - orientationCosine * orientationCosine);
7398
- return [oldWidth, oldHeight];
7399
- };
7400
-
7401
7474
  /**
7402
7475
  * Thickness of the invisible path around a connection used to make it easier to click on, in diagram units.
7403
7476
  * @private
@@ -7432,7 +7505,7 @@ class DiagramCanvas {
7432
7505
  * @param config The configuration object used to set the parameters of this canvas.
7433
7506
  */
7434
7507
  constructor(parentComponent, config) {
7435
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7;
7508
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8;
7436
7509
  this.backgroundPatternId = `daga-background-pattern-id-${DiagramCanvas.canvasCount++}`;
7437
7510
  this.zoomTransform = d3.zoomIdentity;
7438
7511
  // used to distinguish drags from clicks when dragging elements and during multiple selection
@@ -7460,12 +7533,13 @@ class DiagramCanvas {
7460
7533
  this.panRate = ((_z = config.canvas) === null || _z === void 0 ? void 0 : _z.panRate) || 100;
7461
7534
  this.inferConnectionType = ((_0 = config.connectionSettings) === null || _0 === void 0 ? void 0 : _0.inferConnectionType) || false;
7462
7535
  this.autoTightenConnections = ((_1 = config.connectionSettings) === null || _1 === void 0 ? void 0 : _1.autoTighten) !== false;
7463
- this.allowConnectionLoops = ((_2 = config.connectionSettings) === null || _2 === void 0 ? void 0 : _2.allowLoops) || false;
7464
- this.allowSharingPorts = ((_3 = config.connectionSettings) === null || _3 === void 0 ? void 0 : _3.sharePorts) !== false;
7465
- this.allowSharingBothPorts = ((_4 = config.connectionSettings) === null || _4 === void 0 ? void 0 : _4.shareBothPorts) || false;
7466
- this.portHighlightRadius = ((_5 = config.connectionSettings) === null || _5 === void 0 ? void 0 : _5.portHighlightRadius) || 100;
7536
+ this.tightenConnectionsAcrossPortTypes = ((_2 = config.connectionSettings) === null || _2 === void 0 ? void 0 : _2.tightenAcrossPortTypes) || false;
7537
+ this.allowConnectionLoops = ((_3 = config.connectionSettings) === null || _3 === void 0 ? void 0 : _3.allowLoops) || false;
7538
+ this.allowSharingPorts = ((_4 = config.connectionSettings) === null || _4 === void 0 ? void 0 : _4.sharePorts) !== false;
7539
+ this.allowSharingBothPorts = ((_5 = config.connectionSettings) === null || _5 === void 0 ? void 0 : _5.shareBothPorts) || false;
7540
+ this.portHighlightRadius = ((_6 = config.connectionSettings) === null || _6 === void 0 ? void 0 : _6.portHighlightRadius) || 100;
7467
7541
  this.multipleSelectionOn = false;
7468
- this.priorityThresholds = ((_6 = config.canvas) === null || _6 === void 0 ? void 0 : _6.priorityThresholds) || [];
7542
+ this.priorityThresholds = ((_7 = config.canvas) === null || _7 === void 0 ? void 0 : _7.priorityThresholds) || [];
7469
7543
  this.priorityThreshold = this.priorityThresholds ? this.priorityThresholds[0] : undefined;
7470
7544
  this.layoutFormat = config.layoutFormat;
7471
7545
  this.userActions = config.userActions || {};
@@ -7492,7 +7566,7 @@ class DiagramCanvas {
7492
7566
  const connectionType = new DiagramConnectionType(Object.assign(Object.assign({}, config.connectionTypeDefaults), connectionTypeConfig));
7493
7567
  this.model.connections.types.add(connectionType);
7494
7568
  }
7495
- this._connectionType = ((_7 = config === null || config === void 0 ? void 0 : config.connectionSettings) === null || _7 === void 0 ? void 0 : _7.defaultConnection) !== undefined ? this.model.connections.types.get(config.connectionSettings.defaultConnection) : undefined;
7569
+ this._connectionType = ((_8 = config === null || config === void 0 ? void 0 : config.connectionSettings) === null || _8 === void 0 ? void 0 : _8.defaultConnection) !== undefined ? this.model.connections.types.get(config.connectionSettings.defaultConnection) : undefined;
7496
7570
  }
7497
7571
  }
7498
7572
  addValidator(validator) {
@@ -7748,7 +7822,14 @@ class DiagramCanvas {
7748
7822
  }
7749
7823
  }
7750
7824
  getViewCoordinates() {
7751
- return [this.zoomTransform.x, this.zoomTransform.y];
7825
+ var _a, _b, _c;
7826
+ const canvasViewBoundingBox = (_c = (_b = (_a = this.selectCanvasView()) === null || _a === void 0 ? void 0 : _a.select('rect')) === null || _b === void 0 ? void 0 : _b.node()) === null || _c === void 0 ? void 0 : _c.getBBox();
7827
+ /*
7828
+ transform the coordinates of the zoomTransform to the coordinates
7829
+ needed to point the zoomTransfrom to the center of the screen to
7830
+ ensure that canvas.translateTo(getViewCoordinates()) has no effect
7831
+ */
7832
+ return [((canvasViewBoundingBox.width + canvasViewBoundingBox.x) / 2 - this.zoomTransform.x) / this.zoomTransform.k, ((canvasViewBoundingBox.height + canvasViewBoundingBox.y) / 2 - this.zoomTransform.y) / this.zoomTransform.k];
7752
7833
  }
7753
7834
  translateBy(x, y) {
7754
7835
  if (!isNaN(x) && !isNaN(y)) {
@@ -7760,12 +7841,42 @@ class DiagramCanvas {
7760
7841
  this.zoomBehavior.translateTo(this.selectCanvasView(), x, y);
7761
7842
  }
7762
7843
  }
7763
- center() {
7844
+ zoomAndPanTo(x, y, z, duration) {
7845
+ if (!duration || duration <= 0) {
7846
+ this.zoomBehavior.scaleTo(this.selectCanvasView(), z);
7847
+ this.zoomBehavior.translateTo(this.selectCanvasView(), x, y);
7848
+ return;
7849
+ }
7850
+ this.zoomBehavior.interpolate(d3.interpolate);
7851
+ const [startingX, startingY] = this.getViewCoordinates();
7852
+ const startingZoom = this.getZoomLevel();
7853
+ const targetX = x,
7854
+ targetY = y,
7855
+ targetZoom = z;
7856
+ this.selectCanvasElements().transition().duration(duration).ease(d3.easeCubicInOut).tween('progress', () => {
7857
+ let animationInterrupted = false;
7858
+ return value => {
7859
+ try {
7860
+ if (!animationInterrupted) {
7861
+ const currentX = value * (targetX - startingX) + startingX;
7862
+ const currentY = value * (targetY - startingY) + startingY;
7863
+ const currentZoom = value * (targetZoom - startingZoom) + startingZoom;
7864
+ this.zoomBehavior.scaleTo(this.selectCanvasView(), currentZoom);
7865
+ this.zoomBehavior.translateTo(this.selectCanvasView(), currentX, currentY);
7866
+ }
7867
+ } catch (e) {
7868
+ console.warn('Animation has been interrupted');
7869
+ animationInterrupted = true;
7870
+ }
7871
+ };
7872
+ });
7873
+ }
7874
+ center(nodeIds, maxZoomLevel, duration) {
7764
7875
  var _a;
7765
7876
  // if there are no nodes, we have nothing to do here
7766
7877
  if (this.model.nodes.length > 0) {
7767
7878
  const canvasViewBoundingBox = (_a = this.selectCanvasView().select('rect').node()) === null || _a === void 0 ? void 0 : _a.getBBox();
7768
- const nonRemovedNodes = this.model.nodes.all();
7879
+ const nonRemovedNodes = (nodeIds === null || nodeIds === void 0 ? void 0 : nodeIds.map(i => this.model.nodes.get(i)).filter(n => !!n)) || this.model.nodes.all();
7769
7880
  const minimumX = Math.min(...nonRemovedNodes.map(n => n.coords[0]));
7770
7881
  const maximumX = Math.max(...nonRemovedNodes.map(n => n.coords[0] + n.width));
7771
7882
  const averageX = (minimumX + maximumX) / 2;
@@ -7780,12 +7891,12 @@ class DiagramCanvas {
7780
7891
  * (windowRangeX / rangeX) is the zoom level to fit everything horizontally
7781
7892
  * (windowRangeY / rangeY) is the zoom level to fit everything vertically
7782
7893
  * the minimum between them is the zoom to fit everything in the screen both horizontally and vertically
7783
- * we also add 1 to the list so that if the zoom exceeds 1 it is set to 1
7894
+ * we also add maxZoomLevel to the list so that if the zoom exceeds maxZoomLevel it is set to maxZoomLevel
7895
+ * or 1 if maxZoomLevel is undefined
7784
7896
  * a zoom bigger than 1 means zooming in instead of out, and we don't want to zoom in if it's not necessary
7785
7897
  */
7786
- const zoom = Math.min(windowRangeX / rangeX, windowRangeY / rangeY, 1);
7787
- this.translateTo(averageX, averageY);
7788
- this.zoomTo(zoom);
7898
+ const zoom = Math.min(windowRangeX / rangeX, windowRangeY / rangeY, maxZoomLevel !== undefined ? maxZoomLevel : 1);
7899
+ this.zoomAndPanTo(averageX, averageY, zoom, duration);
7789
7900
  }
7790
7901
  }
7791
7902
  getClosestGridPoint(point) {
@@ -7841,7 +7952,7 @@ class DiagramCanvas {
7841
7952
  updateNodesInView(...ids) {
7842
7953
  let updateSelection = this.selectCanvasElements().selectAll('g.diagram-node').data(this.model.nodes.filter(e => this.priorityThreshold !== undefined ? e.getPriority() >= this.priorityThreshold : true), d => d.id);
7843
7954
  const exitSelection = updateSelection.exit();
7844
- const enterSelection = updateSelection.enter().append('g').attr('id', d => d.id).attr('class', d => `diagram-node${d.type.resizableX ? ' resizable-x' : ''}${d.type.resizableY ? ' resizable-y' : ''} ${d.type.defaultLook.lookType}`);
7955
+ const enterSelection = updateSelection.enter().append('g').attr('id', d => d.id).attr('class', d => `diagram-node${needsResizerX(d) ? ' resizable-x' : ''}${needsResizerY(d) ? ' resizable-y' : ''} ${d.type.defaultLook.lookType}`);
7845
7956
  if (ids && ids.length > 0) {
7846
7957
  updateSelection = updateSelection.filter(d => ids.includes(d.id));
7847
7958
  }
@@ -7904,28 +8015,28 @@ class DiagramCanvas {
7904
8015
  this.secondaryButton = false;
7905
8016
  }));
7906
8017
  initializeLook(enterSelection);
7907
- enterSelection.filter('.resizable-x').append('line').attr('class', 'left-resizer').attr('stroke', 'transparent').attr('stroke-width', `${RESIZER_THICKNESS}px`).on(Events.MouseOver, (_event, d) => {
7908
- if (this.canUserPerformAction(DiagramActions.StretchNode) && d.type.resizableX && !d.removed) {
8018
+ enterSelection.filter('.resizable-x').append('line').attr('class', 'left-resizer').attr('stroke', 'transparent').attr('stroke-width', RESIZER_THICKNESS).on(Events.MouseOver, (_event, d) => {
8019
+ if (this.canUserPerformAction(DiagramActions.StretchNode) && d.getResizableX() && !d.removed) {
7909
8020
  setCursorStyle(CursorStyle.EWResize);
7910
8021
  }
7911
8022
  }).on(Events.MouseOut, (_event, d) => {
7912
- if (this.canUserPerformAction(DiagramActions.StretchNode) && d.type.resizableX && !d.removed) {
8023
+ if (this.canUserPerformAction(DiagramActions.StretchNode) && d.getResizableX() && !d.removed) {
7913
8024
  setCursorStyle();
7914
8025
  }
7915
8026
  }).call(d3.drag().on(DragEvents.Start, (_event, d) => {
7916
- if (this.canUserPerformAction(DiagramActions.StretchNode) && d.type.resizableX && !d.removed) {
8027
+ if (this.canUserPerformAction(DiagramActions.StretchNode) && d.getResizableX() && !d.removed) {
7917
8028
  setCursorStyle(CursorStyle.EWResize);
7918
8029
  this.currentAction = new SetGeometryAction(this, DiagramActions.StretchNode, d.id, d.getGeometry(), d.getGeometry());
7919
8030
  } else {
7920
8031
  setCursorStyle(CursorStyle.NotAllowed);
7921
8032
  }
7922
8033
  }).on(DragEvents.Drag, (event, d) => {
7923
- if (this.canUserPerformAction(DiagramActions.StretchNode) && d.type.resizableX && !d.removed) {
8034
+ if (this.canUserPerformAction(DiagramActions.StretchNode) && d.getResizableX() && !d.removed) {
7924
8035
  const pointerCoords = this.getPointerLocationRelativeToCanvas(event);
7925
8036
  d.stretch(Side.Left, d.coords[0] - pointerCoords[0]);
7926
8037
  }
7927
8038
  }).on(DragEvents.End, (event, d) => {
7928
- if (this.canUserPerformAction(DiagramActions.StretchNode) && d.type.resizableX && !d.removed && this.currentAction instanceof SetGeometryAction && this.currentAction.intent === DiagramActions.StretchNode) {
8039
+ if (this.canUserPerformAction(DiagramActions.StretchNode) && d.getResizableX() && !d.removed && this.currentAction instanceof SetGeometryAction && this.currentAction.intent === DiagramActions.StretchNode) {
7929
8040
  let pointerCoords = this.getPointerLocationRelativeToCanvas(event);
7930
8041
  if (this.snapToGrid) {
7931
8042
  pointerCoords = this.getClosestGridPoint([pointerCoords[0] - d.type.snapToGridOffset[0], pointerCoords[1] - d.type.snapToGridOffset[1]]);
@@ -7940,28 +8051,28 @@ class DiagramCanvas {
7940
8051
  }
7941
8052
  setCursorStyle();
7942
8053
  }));
7943
- enterSelection.filter('.resizable-y').append('line').attr('class', 'top-resizer').attr('stroke', 'transparent').attr('stroke-width', `${RESIZER_THICKNESS}px`).on(Events.MouseOver, (_event, d) => {
7944
- if (this.canUserPerformAction(DiagramActions.StretchNode) && d.type.resizableY && !d.removed) {
8054
+ enterSelection.filter('.resizable-y').append('line').attr('class', 'top-resizer').attr('stroke', 'transparent').attr('stroke-width', RESIZER_THICKNESS).on(Events.MouseOver, (_event, d) => {
8055
+ if (this.canUserPerformAction(DiagramActions.StretchNode) && d.getResizableY() && !d.removed) {
7945
8056
  setCursorStyle(CursorStyle.NSResize);
7946
8057
  }
7947
8058
  }).on(Events.MouseOut, (_event, d) => {
7948
- if (this.canUserPerformAction(DiagramActions.StretchNode) && d.type.resizableY && !d.removed) {
8059
+ if (this.canUserPerformAction(DiagramActions.StretchNode) && d.getResizableY() && !d.removed) {
7949
8060
  setCursorStyle();
7950
8061
  }
7951
8062
  }).call(d3.drag().on(DragEvents.Start, (_event, d) => {
7952
- if (this.canUserPerformAction(DiagramActions.StretchNode) && d.type.resizableY && !d.removed) {
8063
+ if (this.canUserPerformAction(DiagramActions.StretchNode) && d.getResizableY() && !d.removed) {
7953
8064
  setCursorStyle(CursorStyle.NSResize);
7954
8065
  this.currentAction = new SetGeometryAction(this, DiagramActions.StretchNode, d.id, d.getGeometry(), d.getGeometry());
7955
8066
  } else {
7956
8067
  setCursorStyle(CursorStyle.NotAllowed);
7957
8068
  }
7958
8069
  }).on(DragEvents.Drag, (event, d) => {
7959
- if (this.canUserPerformAction(DiagramActions.StretchNode) && d.type.resizableY && !d.removed) {
8070
+ if (this.canUserPerformAction(DiagramActions.StretchNode) && d.getResizableY() && !d.removed) {
7960
8071
  const pointerCoords = this.getPointerLocationRelativeToCanvas(event);
7961
8072
  d.stretch(Side.Top, d.coords[1] - pointerCoords[1]);
7962
8073
  }
7963
8074
  }).on(DragEvents.End, (event, d) => {
7964
- if (this.canUserPerformAction(DiagramActions.StretchNode) && d.type.resizableY && !d.removed && this.currentAction instanceof SetGeometryAction && this.currentAction.intent === DiagramActions.StretchNode) {
8075
+ if (this.canUserPerformAction(DiagramActions.StretchNode) && d.getResizableY() && !d.removed && this.currentAction instanceof SetGeometryAction && this.currentAction.intent === DiagramActions.StretchNode) {
7965
8076
  let pointerCoords = this.getPointerLocationRelativeToCanvas(event);
7966
8077
  if (this.snapToGrid) {
7967
8078
  pointerCoords = this.getClosestGridPoint([pointerCoords[0] - d.type.snapToGridOffset[0], pointerCoords[1] - d.type.snapToGridOffset[1]]);
@@ -7976,28 +8087,28 @@ class DiagramCanvas {
7976
8087
  }
7977
8088
  setCursorStyle();
7978
8089
  }));
7979
- enterSelection.filter('.resizable-x').append('line').attr('class', 'right-resizer').attr('stroke', 'transparent').attr('stroke-width', `${RESIZER_THICKNESS}px`).on(Events.MouseOver, (_event, d) => {
7980
- if (this.canUserPerformAction(DiagramActions.StretchNode) && d.type.resizableX && !d.removed) {
8090
+ enterSelection.filter('.resizable-x').append('line').attr('class', 'right-resizer').attr('stroke', 'transparent').attr('stroke-width', RESIZER_THICKNESS).on(Events.MouseOver, (_event, d) => {
8091
+ if (this.canUserPerformAction(DiagramActions.StretchNode) && d.getResizableX() && !d.removed) {
7981
8092
  setCursorStyle(CursorStyle.EWResize);
7982
8093
  }
7983
8094
  }).on(Events.MouseOut, (_event, d) => {
7984
- if (this.canUserPerformAction(DiagramActions.StretchNode) && d.type.resizableX && !d.removed) {
8095
+ if (this.canUserPerformAction(DiagramActions.StretchNode) && d.getResizableX() && !d.removed) {
7985
8096
  setCursorStyle();
7986
8097
  }
7987
8098
  }).call(d3.drag().on(DragEvents.Start, (_event, d) => {
7988
- if (this.canUserPerformAction(DiagramActions.StretchNode) && d.type.resizableX && !d.removed) {
8099
+ if (this.canUserPerformAction(DiagramActions.StretchNode) && d.getResizableX() && !d.removed) {
7989
8100
  setCursorStyle(CursorStyle.EWResize);
7990
8101
  this.currentAction = new SetGeometryAction(this, DiagramActions.StretchNode, d.id, d.getGeometry(), d.getGeometry());
7991
8102
  } else {
7992
8103
  setCursorStyle(CursorStyle.NotAllowed);
7993
8104
  }
7994
8105
  }).on(DragEvents.Drag, (event, d) => {
7995
- if (this.canUserPerformAction(DiagramActions.StretchNode) && d.type.resizableX && !d.removed) {
8106
+ if (this.canUserPerformAction(DiagramActions.StretchNode) && d.getResizableX() && !d.removed) {
7996
8107
  const pointerCoords = this.getPointerLocationRelativeToCanvas(event);
7997
8108
  d.stretch(Side.Right, pointerCoords[0] - (d.coords[0] + d.width));
7998
8109
  }
7999
8110
  }).on(DragEvents.End, (event, d) => {
8000
- if (this.canUserPerformAction(DiagramActions.StretchNode) && d.type.resizableX && !d.removed && this.currentAction instanceof SetGeometryAction && this.currentAction.intent === DiagramActions.StretchNode) {
8111
+ if (this.canUserPerformAction(DiagramActions.StretchNode) && d.getResizableX() && !d.removed && this.currentAction instanceof SetGeometryAction && this.currentAction.intent === DiagramActions.StretchNode) {
8001
8112
  let pointerCoords = this.getPointerLocationRelativeToCanvas(event);
8002
8113
  if (this.snapToGrid) {
8003
8114
  pointerCoords = this.getClosestGridPoint([pointerCoords[0] - d.type.snapToGridOffset[2], pointerCoords[1] - d.type.snapToGridOffset[3]]);
@@ -8012,28 +8123,28 @@ class DiagramCanvas {
8012
8123
  }
8013
8124
  setCursorStyle();
8014
8125
  }));
8015
- enterSelection.filter('.resizable-y').append('line').attr('class', 'bottom-resizer').attr('stroke', 'transparent').attr('stroke-width', `${RESIZER_THICKNESS}px`).on(Events.MouseOver, (_event, d) => {
8016
- if (this.canUserPerformAction(DiagramActions.StretchNode) && d.type.resizableY && !d.removed) {
8126
+ enterSelection.filter('.resizable-y').append('line').attr('class', 'bottom-resizer').attr('stroke', 'transparent').attr('stroke-width', RESIZER_THICKNESS).on(Events.MouseOver, (_event, d) => {
8127
+ if (this.canUserPerformAction(DiagramActions.StretchNode) && d.getResizableY() && !d.removed) {
8017
8128
  setCursorStyle(CursorStyle.NSResize);
8018
8129
  }
8019
8130
  }).on(Events.MouseOut, (_event, d) => {
8020
- if (this.canUserPerformAction(DiagramActions.StretchNode) && d.type.resizableY && !d.removed) {
8131
+ if (this.canUserPerformAction(DiagramActions.StretchNode) && d.getResizableY() && !d.removed) {
8021
8132
  setCursorStyle();
8022
8133
  }
8023
8134
  }).call(d3.drag().on(DragEvents.Start, (_event, d) => {
8024
- if (this.canUserPerformAction(DiagramActions.StretchNode) && d.type.resizableY && !d.removed) {
8135
+ if (this.canUserPerformAction(DiagramActions.StretchNode) && d.getResizableY() && !d.removed) {
8025
8136
  setCursorStyle(CursorStyle.NSResize);
8026
8137
  this.currentAction = new SetGeometryAction(this, DiagramActions.StretchNode, d.id, d.getGeometry(), d.getGeometry());
8027
8138
  } else {
8028
8139
  setCursorStyle(CursorStyle.NotAllowed);
8029
8140
  }
8030
8141
  }).on(DragEvents.Drag, (event, d) => {
8031
- if (this.canUserPerformAction(DiagramActions.StretchNode) && d.type.resizableY && !d.removed) {
8142
+ if (this.canUserPerformAction(DiagramActions.StretchNode) && d.getResizableY() && !d.removed) {
8032
8143
  const pointerCoords = this.getPointerLocationRelativeToCanvas(event);
8033
8144
  d.stretch(Side.Bottom, pointerCoords[1] - (d.coords[1] + d.height));
8034
8145
  }
8035
8146
  }).on(DragEvents.End, (event, d) => {
8036
- if (this.canUserPerformAction(DiagramActions.StretchNode) && d.type.resizableY && !d.removed && this.currentAction instanceof SetGeometryAction && this.currentAction.intent === DiagramActions.StretchNode) {
8147
+ if (this.canUserPerformAction(DiagramActions.StretchNode) && d.getResizableY() && !d.removed && this.currentAction instanceof SetGeometryAction && this.currentAction.intent === DiagramActions.StretchNode) {
8037
8148
  let pointerCoords = this.getPointerLocationRelativeToCanvas(event);
8038
8149
  if (this.snapToGrid) {
8039
8150
  if (this.snapToGrid) {
@@ -8052,17 +8163,17 @@ class DiagramCanvas {
8052
8163
  }));
8053
8164
  mergeSelection.attr('transform', d => `translate(${d.coords[0]},${d.coords[1]})`).attr('opacity', d => d.removed ? 0.5 : 1);
8054
8165
  updateLook(mergeSelection);
8055
- mergeSelection.filter('.resizable-x').select('line.left-resizer').attr('x1', RESIZER_THICKNESS / 2).attr('x2', RESIZER_THICKNESS / 2).attr('y1', 0).attr('y2', d => d.height);
8056
- mergeSelection.filter('.resizable-y').select('line.top-resizer').attr('x1', 0).attr('x2', d => d.width).attr('y1', RESIZER_THICKNESS / 2).attr('y2', RESIZER_THICKNESS / 2);
8057
- mergeSelection.filter('.resizable-x').select('line.right-resizer').attr('x1', d => d.width - RESIZER_THICKNESS / 2).attr('x2', d => d.width - RESIZER_THICKNESS / 2).attr('y1', 0).attr('y2', d => d.height);
8058
- mergeSelection.filter('.resizable-y').select('line.bottom-resizer').attr('x1', 0).attr('x2', d => d.width).attr('y1', d => d.height - RESIZER_THICKNESS / 2).attr('y2', d => d.height - RESIZER_THICKNESS / 2);
8166
+ mergeSelection.filter('.resizable-x').select('line.left-resizer').style('pointer-events', d => d.getResizableX() ? 'initial' : 'none').attr('x1', RESIZER_THICKNESS / 2).attr('x2', RESIZER_THICKNESS / 2).attr('y1', 0).attr('y2', d => d.height);
8167
+ mergeSelection.filter('.resizable-y').select('line.top-resizer').style('pointer-events', d => d.getResizableY() ? 'initial' : 'none').attr('x1', 0).attr('x2', d => d.width).attr('y1', RESIZER_THICKNESS / 2).attr('y2', RESIZER_THICKNESS / 2);
8168
+ mergeSelection.filter('.resizable-x').select('line.right-resizer').style('pointer-events', d => d.getResizableX() ? 'initial' : 'none').attr('x1', d => d.width - RESIZER_THICKNESS / 2).attr('x2', d => d.width - RESIZER_THICKNESS / 2).attr('y1', 0).attr('y2', d => d.height);
8169
+ mergeSelection.filter('.resizable-y').select('line.bottom-resizer').style('pointer-events', d => d.getResizableY() ? 'initial' : 'none').attr('x1', 0).attr('x2', d => d.width).attr('y1', d => d.height - RESIZER_THICKNESS / 2).attr('y2', d => d.height - RESIZER_THICKNESS / 2);
8059
8170
  }
8060
8171
  updateSectionsInView(...ids) {
8061
8172
  let updateSelection = this.selectCanvasElements().selectAll('g.diagram-section').data(this.model.sections.filter(e => this.priorityThreshold !== undefined ? e.getPriority() >= this.priorityThreshold : true), d => d.id);
8062
8173
  const exitSelection = updateSelection.exit();
8063
8174
  const enterSelection = updateSelection.enter().append('g').attr('id', d => d.id).attr('class', d => {
8064
8175
  var _a;
8065
- return `diagram-section${d.getResizableX() ? ' resizable-x' : ''}${d.getResizableY() ? ' resizable-y' : ''} ${(_a = d.look) === null || _a === void 0 ? void 0 : _a.lookType}`;
8176
+ return `diagram-section${needsResizerX(d) ? ' resizable-x' : ''}${needsResizerY(d) ? ' resizable-y' : ''} ${(_a = d.look) === null || _a === void 0 ? void 0 : _a.lookType}`;
8066
8177
  });
8067
8178
  if (ids && ids.length > 0) {
8068
8179
  updateSelection = updateSelection.filter(d => ids.includes(d.id));
@@ -8143,7 +8254,7 @@ class DiagramCanvas {
8143
8254
  this.secondaryButton = false;
8144
8255
  }));
8145
8256
  initializeLook(enterSelection);
8146
- enterSelection.filter('.resizable-x').append('line').attr('class', 'left-resizer').attr('stroke', 'transparent').attr('stroke-width', `${RESIZER_THICKNESS}px`).on(Events.MouseOver, (_event, d) => {
8257
+ enterSelection.filter('.resizable-x').append('line').attr('class', 'left-resizer').attr('stroke', 'transparent').attr('stroke-width', RESIZER_THICKNESS).on(Events.MouseOver, (_event, d) => {
8147
8258
  if (this.canUserPerformAction(DiagramActions.StretchSection) && d.getResizableX() && !d.removed) {
8148
8259
  setCursorStyle(CursorStyle.EWResize);
8149
8260
  }
@@ -8177,7 +8288,7 @@ class DiagramCanvas {
8177
8288
  }
8178
8289
  setCursorStyle();
8179
8290
  }));
8180
- enterSelection.filter('.resizable-y').append('line').attr('class', 'top-resizer').attr('stroke', 'transparent').attr('stroke-width', `${RESIZER_THICKNESS}px`).on(Events.MouseOver, (_event, d) => {
8291
+ enterSelection.filter('.resizable-y').append('line').attr('class', 'top-resizer').attr('stroke', 'transparent').attr('stroke-width', RESIZER_THICKNESS).on(Events.MouseOver, (_event, d) => {
8181
8292
  if (this.canUserPerformAction(DiagramActions.StretchSection) && d.getResizableY() && !d.removed) {
8182
8293
  setCursorStyle(CursorStyle.NSResize);
8183
8294
  }
@@ -8211,7 +8322,7 @@ class DiagramCanvas {
8211
8322
  }
8212
8323
  setCursorStyle();
8213
8324
  }));
8214
- enterSelection.filter('.resizable-x').append('line').attr('class', 'right-resizer').attr('stroke', 'transparent').attr('stroke-width', `${RESIZER_THICKNESS}px`).on(Events.MouseOver, (_event, d) => {
8325
+ enterSelection.filter('.resizable-x').append('line').attr('class', 'right-resizer').attr('stroke', 'transparent').attr('stroke-width', RESIZER_THICKNESS).on(Events.MouseOver, (_event, d) => {
8215
8326
  if (this.canUserPerformAction(DiagramActions.StretchSection) && d.getResizableX() && !d.removed) {
8216
8327
  setCursorStyle(CursorStyle.EWResize);
8217
8328
  }
@@ -8245,7 +8356,7 @@ class DiagramCanvas {
8245
8356
  }
8246
8357
  setCursorStyle();
8247
8358
  }));
8248
- enterSelection.filter('.resizable-y').append('line').attr('class', 'bottom-resizer').attr('stroke', 'transparent').attr('stroke-width', `${RESIZER_THICKNESS}px`).on(Events.MouseOver, (_event, d) => {
8359
+ enterSelection.filter('.resizable-y').append('line').attr('class', 'bottom-resizer').attr('stroke', 'transparent').attr('stroke-width', RESIZER_THICKNESS).on(Events.MouseOver, (_event, d) => {
8249
8360
  if (this.canUserPerformAction(DiagramActions.StretchSection) && d.getResizableY() && !d.removed) {
8250
8361
  setCursorStyle(CursorStyle.NSResize);
8251
8362
  }
@@ -8281,10 +8392,10 @@ class DiagramCanvas {
8281
8392
  }));
8282
8393
  mergeSelection.attr('transform', d => `translate(${d.coords[0]},${d.coords[1]})`).attr('opacity', d => d.removed ? 0.5 : 1);
8283
8394
  updateLook(mergeSelection);
8284
- mergeSelection.filter('.resizable-x').select('line.left-resizer').attr('x1', RESIZER_THICKNESS / 2).attr('x2', RESIZER_THICKNESS / 2).attr('y1', 0).attr('y2', d => d.height);
8285
- mergeSelection.filter('.resizable-y').select('line.top-resizer').attr('x1', 0).attr('x2', d => d.width).attr('y1', RESIZER_THICKNESS / 2).attr('y2', RESIZER_THICKNESS / 2);
8286
- mergeSelection.filter('.resizable-x').select('line.right-resizer').attr('x1', d => d.width - RESIZER_THICKNESS / 2).attr('x2', d => d.width - RESIZER_THICKNESS / 2).attr('y1', 0).attr('y2', d => d.height);
8287
- mergeSelection.filter('.resizable-y').select('line.bottom-resizer').attr('x1', 0).attr('x2', d => d.width).attr('y1', d => d.height - RESIZER_THICKNESS / 2).attr('y2', d => d.height - RESIZER_THICKNESS / 2);
8395
+ mergeSelection.filter('.resizable-x').select('line.left-resizer').style('pointer-events', d => d.getResizableX() ? 'initial' : 'none').attr('x1', RESIZER_THICKNESS / 2).attr('x2', RESIZER_THICKNESS / 2).attr('y1', 0).attr('y2', d => d.height);
8396
+ mergeSelection.filter('.resizable-y').select('line.top-resizer').style('pointer-events', d => d.getResizableY() ? 'initial' : 'none').attr('x1', 0).attr('x2', d => d.width).attr('y1', RESIZER_THICKNESS / 2).attr('y2', RESIZER_THICKNESS / 2);
8397
+ mergeSelection.filter('.resizable-x').select('line.right-resizer').style('pointer-events', d => d.getResizableX() ? 'initial' : 'none').attr('x1', d => d.width - RESIZER_THICKNESS / 2).attr('x2', d => d.width - RESIZER_THICKNESS / 2).attr('y1', 0).attr('y2', d => d.height);
8398
+ mergeSelection.filter('.resizable-y').select('line.bottom-resizer').style('pointer-events', d => d.getResizableY() ? 'initial' : 'none').attr('x1', 0).attr('x2', d => d.width).attr('y1', d => d.height - RESIZER_THICKNESS / 2).attr('y2', d => d.height - RESIZER_THICKNESS / 2);
8288
8399
  }
8289
8400
  updatePortsInView(...ids) {
8290
8401
  let updateSelection = this.selectCanvasElements().selectAll('g.diagram-port').data(this.model.ports.filter(e => this.priorityThreshold !== undefined ? e.getPriority() >= this.priorityThreshold : true), d => d.id);
@@ -8369,14 +8480,14 @@ class DiagramCanvas {
8369
8480
  }
8370
8481
  }
8371
8482
  }).on(DragEvents.Drag, (event, d) => {
8372
- var _a, _b, _c, _d;
8483
+ var _a, _b, _c, _d, _e;
8373
8484
  if (this.multipleSelectionOn || this.secondaryButton) {
8374
8485
  this.continueMultipleSelection(event);
8375
8486
  } else {
8376
8487
  if (this.canUserPerformAction(DiagramActions.AddConnection) && !d.removed) {
8377
8488
  if (this.unfinishedConnection !== undefined) {
8378
8489
  const endCoords = [event.x, event.y];
8379
- (_a = this.unfinishedConnectionTracer) === null || _a === void 0 ? void 0 : _a.attr('d', getConnectionPath(this.unfinishedConnection.look.shape || DIAGRAM_CONNECTION_TYPE_DEFAULTS.look.shape, this.unfinishedConnection.startCoords, endCoords, this.unfinishedConnection.startDirection, this.unfinishedConnection.endDirection, this.unfinishedConnection.type.defaultLook.thickness || DIAGRAM_CONNECTION_TYPE_DEFAULTS.look.thickness, (_b = this.unfinishedConnection.type.defaultStartMarkerLook) === null || _b === void 0 ? void 0 : _b.width, (_c = this.unfinishedConnection.type.defaultEndMarkerLook) === null || _c === void 0 ? void 0 : _c.width));
8490
+ (_a = this.unfinishedConnectionTracer) === null || _a === void 0 ? void 0 : _a.attr('d', getConnectionPath(this.unfinishedConnection.look.shape || DIAGRAM_CONNECTION_TYPE_DEFAULTS.look.shape, this.unfinishedConnection.startCoords, endCoords, this.unfinishedConnection.startDirection, this.unfinishedConnection.endDirection, this.unfinishedConnection.points, this.unfinishedConnection.type.defaultLook.thickness || DIAGRAM_CONNECTION_TYPE_DEFAULTS.look.thickness, (_b = this.unfinishedConnection.type.defaultStartMarkerLook) === null || _b === void 0 ? void 0 : _b.width, (_c = this.unfinishedConnection.type.defaultEndMarkerLook) === null || _c === void 0 ? void 0 : _c.width));
8380
8491
  const unfinishedConnectionGhostNode = (_d = this.unfinishedConnectionTracer) === null || _d === void 0 ? void 0 : _d.node();
8381
8492
  if (unfinishedConnectionGhostNode) {
8382
8493
  let margin = 2;
@@ -8391,6 +8502,7 @@ class DiagramCanvas {
8391
8502
  this.unfinishedConnection.endCoords = endCoords;
8392
8503
  }
8393
8504
  this.updateConnectionsInView(UNFINISHED_CONNECTION_ID);
8505
+ (_e = this.unfinishedConnectionPort) === null || _e === void 0 ? void 0 : _e.raise(false);
8394
8506
  // highlight closest target port
8395
8507
  if (this.model.ports.length > 0) {
8396
8508
  const pointerCoords = this.getPointerLocationRelativeToCanvas(event);
@@ -8524,29 +8636,29 @@ class DiagramCanvas {
8524
8636
  enterSelection.select('g.diagram-connection-end-label').append('text').style('user-select', 'none');
8525
8637
  mergeSelection.attr('opacity', d => d.removed ? 0.5 : 1).select('path.diagram-connection-path').attr('d', d => {
8526
8638
  var _a, _b;
8527
- return getConnectionPath(d.look.shape || DIAGRAM_CONNECTION_TYPE_DEFAULTS.look.shape, d.startCoords, d.endCoords, d.startDirection, d.endDirection, d.type.defaultLook.thickness || DIAGRAM_CONNECTION_TYPE_DEFAULTS.look.thickness, (_a = d.type.defaultStartMarkerLook) === null || _a === void 0 ? void 0 : _a.width, (_b = d.type.defaultEndMarkerLook) === null || _b === void 0 ? void 0 : _b.width);
8528
- }).attr('marker-start', d => `url(#${d.id}-start-marker)`).attr('marker-end', d => `url(#${d.id}-end-marker)`).attr('stroke', d => d.look.color || DIAGRAM_CONNECTION_TYPE_DEFAULTS.look.color).attr('stroke-width', d => `${d.look.thickness}px`).attr('stroke-dasharray', d => lineStyleDasharray(d.look.style || DIAGRAM_CONNECTION_TYPE_DEFAULTS.look.style, d.type.defaultLook.thickness || DIAGRAM_CONNECTION_TYPE_DEFAULTS.look.thickness)).attr('fill', 'none');
8639
+ return getConnectionPath(d.look.shape || DIAGRAM_CONNECTION_TYPE_DEFAULTS.look.shape, d.startCoords, d.endCoords, d.startDirection, d.endDirection, d.points, d.type.defaultLook.thickness || DIAGRAM_CONNECTION_TYPE_DEFAULTS.look.thickness, (_a = d.type.defaultStartMarkerLook) === null || _a === void 0 ? void 0 : _a.width, (_b = d.type.defaultEndMarkerLook) === null || _b === void 0 ? void 0 : _b.width);
8640
+ }).attr('marker-start', d => `url(#${d.id}-start-marker)`).attr('marker-end', d => `url(#${d.id}-end-marker)`).attr('stroke', d => d.look.color || DIAGRAM_CONNECTION_TYPE_DEFAULTS.look.color).attr('stroke-width', d => d.look.thickness || DIAGRAM_CONNECTION_TYPE_DEFAULTS.look.thickness).attr('stroke-dasharray', d => lineStyleDasharray(d.look.style || DIAGRAM_CONNECTION_TYPE_DEFAULTS.look.style, d.type.defaultLook.thickness || DIAGRAM_CONNECTION_TYPE_DEFAULTS.look.thickness)).attr('fill', 'none');
8529
8641
  mergeSelection.select('path.diagram-connection-path-box').attr('d', d => {
8530
8642
  var _a, _b;
8531
- return getConnectionPath(d.look.shape || DIAGRAM_CONNECTION_TYPE_DEFAULTS.look.shape, d.startCoords, d.endCoords, d.startDirection, d.endDirection, d.type.defaultLook.thickness || DIAGRAM_CONNECTION_TYPE_DEFAULTS.look.thickness, (_a = d.type.defaultStartMarkerLook) === null || _a === void 0 ? void 0 : _a.width, (_b = d.type.defaultEndMarkerLook) === null || _b === void 0 ? void 0 : _b.width);
8643
+ return getConnectionPath(d.look.shape || DIAGRAM_CONNECTION_TYPE_DEFAULTS.look.shape, d.startCoords, d.endCoords, d.startDirection, d.endDirection, d.points, d.type.defaultLook.thickness || DIAGRAM_CONNECTION_TYPE_DEFAULTS.look.thickness, (_a = d.type.defaultStartMarkerLook) === null || _a === void 0 ? void 0 : _a.width, (_b = d.type.defaultEndMarkerLook) === null || _b === void 0 ? void 0 : _b.width);
8532
8644
  }).attr('stroke', 'transparent')
8533
8645
  // allow generating pointer events even when it is transparent
8534
- .attr('pointer-events', 'stroke').attr('stroke-width', d => `${(d.look.thickness || DIAGRAM_CONNECTION_TYPE_DEFAULTS.look.thickness) + CONNECTION_PATH_BOX_THICKNESS}px`).attr('stroke-dasharray', d => lineStyleDasharray(d.look.style || DIAGRAM_CONNECTION_TYPE_DEFAULTS.look.style, d.type.defaultLook.thickness || DIAGRAM_CONNECTION_TYPE_DEFAULTS.look.thickness)).attr('fill', 'none');
8646
+ .attr('pointer-events', 'stroke').attr('stroke-width', d => (d.look.thickness || DIAGRAM_CONNECTION_TYPE_DEFAULTS.look.thickness) + CONNECTION_PATH_BOX_THICKNESS).attr('stroke-dasharray', d => lineStyleDasharray(d.look.style || DIAGRAM_CONNECTION_TYPE_DEFAULTS.look.style, d.type.defaultLook.thickness || DIAGRAM_CONNECTION_TYPE_DEFAULTS.look.thickness)).attr('fill', 'none');
8535
8647
  mergeSelection.data().forEach(connection => {
8536
8648
  this.updateConnectionLabelsInView(connection);
8537
8649
  this.updateConnectionMarkersInView(connection);
8538
8650
  });
8539
8651
  }
8540
8652
  updateFieldsInView(...ids) {
8541
- let updateSelection = this.selectCanvasElements().selectAll('foreignObject.diagram-field').data(this.model.fields.filter(e => this.priorityThreshold !== undefined ? e.getPriority() >= this.priorityThreshold : true), d => d.id);
8653
+ let updateSelection = this.selectCanvasElements().selectAll('g.diagram-field').data(this.model.fields.filter(e => this.priorityThreshold !== undefined ? e.getPriority() >= this.priorityThreshold : true), d => d.id);
8542
8654
  const exitSelection = updateSelection.exit();
8543
- const enterSelection = updateSelection.enter().append('foreignObject').attr('id', d => d.id).attr('class', 'diagram-field');
8655
+ const enterSelection = updateSelection.enter().append('g').attr('id', d => d.id).attr('class', 'diagram-field');
8544
8656
  if (ids && ids.length > 0) {
8545
8657
  updateSelection = updateSelection.filter(d => ids.includes(d.id));
8546
8658
  }
8547
8659
  const mergeSelection = enterSelection.merge(updateSelection);
8548
8660
  exitSelection.remove();
8549
- enterSelection.style('box-sizing', 'border-box').on(Events.MouseOver, (_event, d) => {
8661
+ enterSelection.on(Events.MouseOver, (_event, d) => {
8550
8662
  if (!this.dragging) {
8551
8663
  this.userHighlight.focusOn(d);
8552
8664
  this.diagramEvent$.next(new DiagramHighlightedEvent(d));
@@ -8583,22 +8695,7 @@ class DiagramCanvas {
8583
8695
  this.diagramEvent$.next(diagramEvent);
8584
8696
  if (!diagramEvent.defaultPrevented && this.canUserPerformAction(DiagramActions.EditField) && d.editable && !d.removed) {
8585
8697
  this.currentAction = new EditFieldAction(this, d.id, d.text, '');
8586
- this.createInputField(d.text, d.coords, d.width, d.height, d.fontSize, d.fontFamily || DIAGRAM_FIELD_DEFAULTS.fontFamily, d.orientation, () => {
8587
- // (_text)
8588
- /*
8589
- Empty for now
8590
- We should create a better function to stretch the root element as the text expands
8591
- Bear in mind that DiagramNode.setGeometry() calls DiagramNode.raise(), which breaks the input field
8592
- */
8593
- }, text => {
8594
- d.text = text;
8595
- if (this.currentAction instanceof EditFieldAction) {
8596
- this.currentAction.to = text;
8597
- this.currentAction.do();
8598
- this.actionStack.add(this.currentAction);
8599
- this.currentAction = undefined;
8600
- }
8601
- });
8698
+ this.openTextInput(d.id);
8602
8699
  }
8603
8700
  }).call(d3.drag().filter(event => {
8604
8701
  this.secondaryButton = isSecondaryButton(event);
@@ -8652,18 +8749,25 @@ class DiagramCanvas {
8652
8749
  }
8653
8750
  }
8654
8751
  this.secondaryButton = false;
8655
- })).append('xhtml:div').style('width', '100%').style('height', '100%').style('display', 'flex').append('xhtml:p').style('box-sizing', 'border-box').style('outline', 0).style('margin', 0).style('border', 0).style('padding', 0).style('user-select', 'none').style('font-kerning', 'none').style('white-space', 'nowrap');
8656
- mergeSelection.attr('x', 0).attr('y', 0).attr('width', d => `${d.width}px`).attr('height', d => `${d.height}px`).attr('transform', d => `translate(${d.coords[0]},${d.coords[1]})`).attr('opacity', d => d.removed ? 0.5 : 1).select('div').style('justify-content', d => d.horizontalAlign === HorizontalAlign.Center ? 'center' : d.horizontalAlign === HorizontalAlign.Right ? 'flex-end' : 'flex-start').style('align-items', d => d.verticalAlign === VerticalAlign.Center ? 'center' : d.verticalAlign === VerticalAlign.Bottom ? 'end' : 'start').select('p').style('max-width', d => d.fit ? 'default' : `${unrotate(d.width, d.height, d.orientation)[0]}px`).style('max-height', d => d.fit ? 'default' : `${unrotate(d.width, d.height, d.orientation)[1]}px`).style('overflow', d => d.fit ? 'default' : 'clip').style('text-overflow', d => d.fit ? 'default' : 'ellipsis').style('text-align', d => d.horizontalAlign === HorizontalAlign.Center ? 'center' : d.horizontalAlign === HorizontalAlign.Right ? 'end' : 'start').style('transform', d => `rotate(${d.orientation}deg)`).style('font-size', d => `${d.fontSize}px`).style('font-family', d => d.fontFamily || "'Wonder Unit Sans', sans-serif").style('font-weight', d => d.highlighted ? 600 : 400).style('color', d => d.selected ? d.selectedColor || '#000000' : d.color || '#000000').html(d => d.text.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\n/g, '<br/>'));
8752
+ }));
8753
+ enterSelection.append('text');
8754
+ enterSelection.append('rect');
8755
+ mergeSelection.attr('x', 0).attr('y', 0).attr('width', d => d.width).attr('height', d => d.height).attr('transform', d => `translate(${d.coords[0]},${d.coords[1]}) rotate(${d.orientation} ${d.width / 2} ${d.height / 2})`).attr('opacity', d => d.removed ? 0.5 : 1).select('text').attr('x', d => d.horizontalAlign === HorizontalAlign.Center ? d.width / 2 : d.horizontalAlign === HorizontalAlign.Right ? d.width : 0).attr('text-anchor', d => d.horizontalAlign === HorizontalAlign.Center ? 'middle' : d.horizontalAlign === HorizontalAlign.Right ? 'end' : 'start').attr('y', d => d.verticalAlign === VerticalAlign.Center ? d.height / 2 : d.verticalAlign === VerticalAlign.Bottom ? d.height : 0).attr('dominant-baseline', d => d.verticalAlign === VerticalAlign.Center ? 'middle' : d.verticalAlign === VerticalAlign.Bottom ? 'auto' : 'hanging').attr('font-size', d => d.fontSize).attr('font-family', d => d.fontFamily || "'Wonder Unit Sans', sans-serif").attr('font-weight', d => d.highlighted ? 600 : 400).attr('fill', d => d.selected ? d.selectedColor || '#000000' : d.color || '#000000').each(d => {
8756
+ this.setFieldTextAndWrap(d);
8757
+ });
8758
+ mergeSelection
8759
+ // add a transparent rectangle to capture pointer events on the text
8760
+ .select('rect').attr('x', 0).attr('y', 0).attr('width', d => d.width).attr('height', d => d.height).attr('fill', 'transparent');
8657
8761
  }
8658
8762
  updateObjectsInView(...ids) {
8659
- let updateSelection = this.selectCanvasElements().selectAll('foreignObject.diagram-object').data(this.model.objects.filter(e => this.priorityThreshold !== undefined ? e.getPriority() >= this.priorityThreshold : true), d => d.id);
8763
+ let updateSelection = this.selectCanvasElements().selectAll('g.diagram-object').data(this.model.objects.filter(e => this.priorityThreshold !== undefined ? e.getPriority() >= this.priorityThreshold : true), d => d.id);
8660
8764
  const exitSelection = updateSelection.exit();
8661
- const enterSelection = updateSelection.enter().append('foreignObject').attr('id', d => d.id).attr('class', 'diagram-object');
8765
+ const enterSelection = updateSelection.enter().append('g').attr('id', d => d.id).attr('class', 'diagram-object');
8662
8766
  if (ids && ids.length > 0) {
8663
8767
  updateSelection = updateSelection.filter(d => ids.includes(d.id));
8664
8768
  }
8665
8769
  const mergeSelection = enterSelection.merge(updateSelection);
8666
- mergeSelection.attr('width', d => `${d.width}px`).attr('height', d => `${d.height}px`).attr('transform', d => `translate(${d.coords[0]},${d.coords[1]})`).html(d => d.html);
8770
+ mergeSelection.attr('width', d => d.width).attr('height', d => d.height).attr('transform', d => `translate(${d.coords[0]},${d.coords[1]})`).html(d => d.html);
8667
8771
  exitSelection.remove();
8668
8772
  enterSelection.on(Events.ContextMenu, (event, d) => {
8669
8773
  if (this.dragging) {
@@ -8699,14 +8803,14 @@ class DiagramCanvas {
8699
8803
  }));
8700
8804
  }
8701
8805
  updateDecoratorsInView(...ids) {
8702
- let updateSelection = this.selectCanvasElements().selectAll('foreignObject.diagram-decorator').data(this.model.decorators.filter(e => this.priorityThreshold !== undefined ? e.getPriority() >= this.priorityThreshold : true), d => d.id);
8806
+ let updateSelection = this.selectCanvasElements().selectAll('g.diagram-decorator').data(this.model.decorators.filter(e => this.priorityThreshold !== undefined ? e.getPriority() >= this.priorityThreshold : true), d => d.id);
8703
8807
  const exitSelection = updateSelection.exit();
8704
- const enterSelection = updateSelection.enter().append('foreignObject').attr('id', d => d.id).attr('class', 'diagram-decorator');
8808
+ const enterSelection = updateSelection.enter().append('g').attr('id', d => d.id).attr('class', 'diagram-decorator');
8705
8809
  if (ids && ids.length > 0) {
8706
8810
  updateSelection = updateSelection.filter(d => ids.includes(d.id));
8707
8811
  }
8708
8812
  const mergeSelection = enterSelection.merge(updateSelection);
8709
- mergeSelection.attr('width', d => `${d.width}px`).attr('height', d => `${d.height}px`).attr('transform', d => `translate(${d.coords[0]},${d.coords[1]})`).html(d => d.html);
8813
+ mergeSelection.attr('width', d => d.width).attr('height', d => d.height).attr('transform', d => `translate(${d.coords[0]},${d.coords[1]})`).html(d => d.html);
8710
8814
  exitSelection.remove();
8711
8815
  enterSelection.on(Events.MouseOver, (_event, d) => {
8712
8816
  if (!this.dragging) {
@@ -8885,10 +8989,10 @@ class DiagramCanvas {
8885
8989
  pathStartLabelPoint = pathNode.getPointAtLength(getLeftMargin(labelConfiguration) + boundingWidth / 2);
8886
8990
  break;
8887
8991
  case Side.Top:
8888
- pathStartLabelPoint = pathNode.getPointAtLength(getBottomMargin(labelConfiguration) + boundingWidth / 2);
8992
+ pathStartLabelPoint = pathNode.getPointAtLength(getBottomMargin(labelConfiguration) + boundingHeight / 2);
8889
8993
  break;
8890
8994
  case Side.Bottom:
8891
- pathStartLabelPoint = pathNode.getPointAtLength(getTopMargin(labelConfiguration) + boundingWidth / 2);
8995
+ pathStartLabelPoint = pathNode.getPointAtLength(getTopMargin(labelConfiguration) + boundingHeight / 2);
8892
8996
  break;
8893
8997
  default:
8894
8998
  pathStartLabelPoint = pathNode.getPointAtLength(Math.max(getLeftMargin(labelConfiguration) + boundingWidth / 2, getRightMargin(labelConfiguration) + boundingWidth / 2, getTopMargin(labelConfiguration) + boundingHeight / 2, getBottomMargin(labelConfiguration) + boundingHeight / 2));
@@ -8923,10 +9027,10 @@ class DiagramCanvas {
8923
9027
  pathEndLabelPoint = pathNode.getPointAtLength(pathLength - (getLeftMargin(labelConfiguration) + boundingWidth / 2));
8924
9028
  break;
8925
9029
  case Side.Top:
8926
- pathEndLabelPoint = pathNode.getPointAtLength(pathLength - (getBottomMargin(labelConfiguration) + boundingWidth / 2));
9030
+ pathEndLabelPoint = pathNode.getPointAtLength(pathLength - (getBottomMargin(labelConfiguration) + boundingHeight / 2));
8927
9031
  break;
8928
9032
  case Side.Bottom:
8929
- pathEndLabelPoint = pathNode.getPointAtLength(pathLength - (getTopMargin(labelConfiguration) + boundingWidth / 2));
9033
+ pathEndLabelPoint = pathNode.getPointAtLength(pathLength - (getTopMargin(labelConfiguration) + boundingHeight / 2));
8930
9034
  break;
8931
9035
  default:
8932
9036
  pathEndLabelPoint = pathNode.getPointAtLength(pathLength - Math.max(getLeftMargin(labelConfiguration) + boundingWidth / 2, getRightMargin(labelConfiguration) + boundingWidth / 2, getTopMargin(labelConfiguration) + boundingHeight / 2, getBottomMargin(labelConfiguration) + boundingHeight / 2));
@@ -9081,6 +9185,7 @@ class DiagramCanvas {
9081
9185
  if (port.allowsOutgoing || port.allowsIncoming) {
9082
9186
  if (this.connectionType && (this.connectionType.canStartFromType(((_b = (_a = port.getNode()) === null || _a === void 0 ? void 0 : _a.type) === null || _b === void 0 ? void 0 : _b.id) || '') && port.allowsOutgoing || this.connectionType.canFinishOnType(((_d = (_c = port.getNode()) === null || _c === void 0 ? void 0 : _c.type) === null || _d === void 0 ? void 0 : _d.id) || '') && port.allowsIncoming)) {
9083
9187
  this.unfinishedConnection = new DiagramConnection(this.model, this.connectionType, port, undefined, UNFINISHED_CONNECTION_ID);
9188
+ this.unfinishedConnectionPort = port;
9084
9189
  } else {
9085
9190
  if (this.inferConnectionType) {
9086
9191
  let differentConnectionType = this.model.connections.types.all().find(t => {
@@ -9095,6 +9200,7 @@ class DiagramCanvas {
9095
9200
  }
9096
9201
  if (differentConnectionType !== undefined) {
9097
9202
  this.unfinishedConnection = new DiagramConnection(this.model, differentConnectionType, port, undefined, UNFINISHED_CONNECTION_ID);
9203
+ this.unfinishedConnectionPort = port;
9098
9204
  }
9099
9205
  }
9100
9206
  }
@@ -9168,6 +9274,7 @@ class DiagramCanvas {
9168
9274
  (_b = this.unfinishedConnection) === null || _b === void 0 ? void 0 : _b.setEnd(undefined);
9169
9275
  (_d = (_c = this.unfinishedConnection) === null || _c === void 0 ? void 0 : _c.select()) === null || _d === void 0 ? void 0 : _d.remove();
9170
9276
  this.unfinishedConnection = undefined;
9277
+ this.unfinishedConnectionPort = undefined;
9171
9278
  }
9172
9279
  cancelAllUserActions() {
9173
9280
  this.currentAction = undefined;
@@ -9179,7 +9286,28 @@ class DiagramCanvas {
9179
9286
  canUserPerformAction(action) {
9180
9287
  return this.userActions[action] !== false;
9181
9288
  }
9182
- createInputField(text, coords, width, height, fontSize, fontFamily, orientation, changeCallback, finishCallback) {
9289
+ openTextInput(id) {
9290
+ const field = this.model.fields.get(id);
9291
+ if (field) {
9292
+ this.createInputField(field.text, field.coords, field.width, field.height, field.fontSize, field.fontFamily || DIAGRAM_FIELD_DEFAULTS.fontFamily, field.orientation, field.multiline, () => {
9293
+ // (_text)
9294
+ /*
9295
+ Empty for now
9296
+ We should create a better function to stretch the root element as the text expands
9297
+ Bear in mind that DiagramNode.setGeometry() calls DiagramNode.raise(), which breaks the input field
9298
+ */
9299
+ }, text => {
9300
+ field.text = text;
9301
+ if (this.currentAction instanceof EditFieldAction) {
9302
+ this.currentAction.to = text;
9303
+ this.currentAction.do();
9304
+ this.actionStack.add(this.currentAction);
9305
+ this.currentAction = undefined;
9306
+ }
9307
+ });
9308
+ }
9309
+ }
9310
+ createInputField(text, coords, width, height, fontSize, fontFamily, orientation, multiline, changeCallback, finishCallback) {
9183
9311
  // if we have a text input open, close it before creating a new one
9184
9312
  this.removeInputField();
9185
9313
  const inputFieldContainer = this.selectCanvasElements().append('foreignObject').attr('x', `${coords[0]}px`).attr('y', `${coords[1]}px`).attr('width', `${width}px`).attr('height', `${height}px`).style('box-sizing', 'border-box').style('border', '1px solid');
@@ -9189,16 +9317,16 @@ class DiagramCanvas {
9189
9317
  let inputFieldHeight;
9190
9318
  inputField.text(text).style('box-sizing', 'border-box').style('width', `${width}px`).style('height', `${height}px`).style('font-size', `${fontSize}px`).style('font-family', fontFamily).style('resize', 'none').style('outline', 0).style('border', 0).style('margin', 0).style('padding', 0).on(Events.KeyDown, event => {
9191
9319
  event.stopPropagation();
9192
- }).on(Events.KeyUp, event => {
9193
- event.stopPropagation();
9194
- if (event.key === Keys.Escape) {
9195
- const value = inputField.property('value');
9320
+ if (event.key === Keys.Escape || event.key === Keys.Enter && !multiline) {
9321
+ const value = inputField.property('value') || '';
9196
9322
  this.removeInputField();
9197
9323
  if (finishCallback) {
9198
9324
  finishCallback(value);
9199
9325
  }
9200
9326
  }
9201
- }).on(Events.Input, () => {
9327
+ }).on(Events.KeyUp, event => {
9328
+ event.stopPropagation();
9329
+ }).on(Events.Input, event => {
9202
9330
  const value = inputField.property('value');
9203
9331
  inputField.attr('cols', numberOfColumns(value) + 1);
9204
9332
  inputField.attr('rows', numberOfRows(value) + 1);
@@ -9241,13 +9369,54 @@ class DiagramCanvas {
9241
9369
  }
9242
9370
  minimumSizeOfField(field) {
9243
9371
  var _a, _b;
9244
- const pNode = (_b = (_a = field.select()) === null || _a === void 0 ? void 0 : _a.select('p')) === null || _b === void 0 ? void 0 : _b.node();
9245
- if (!pNode) {
9372
+ const textNode = (_b = (_a = field.select()) === null || _a === void 0 ? void 0 : _a.select('text')) === null || _b === void 0 ? void 0 : _b.node();
9373
+ if (!textNode) {
9246
9374
  // happens when a field has been created but not updated in view yet
9247
9375
  return [0, 0];
9248
9376
  }
9249
- const pBoundingBox = pNode.getBoundingClientRect();
9250
- return [pBoundingBox.width / this.zoomTransform.k, pBoundingBox.height / this.zoomTransform.k];
9377
+ const textBoundingBox = textNode.getBoundingClientRect();
9378
+ return [textBoundingBox.width / this.zoomTransform.k, textBoundingBox.height / this.zoomTransform.k];
9379
+ }
9380
+ setFieldTextAndWrap(field) {
9381
+ var _a, _b, _c, _d;
9382
+ const textSelection = (_a = field.select()) === null || _a === void 0 ? void 0 : _a.select('text');
9383
+ const textNode = textSelection === null || textSelection === void 0 ? void 0 : textSelection.node();
9384
+ if (textSelection && textNode) {
9385
+ this.setFieldText(field, textSelection, field.text);
9386
+ } else {
9387
+ // can happen if a field has been created but not updated in view yet
9388
+ // not sure if this still happens but should check just in case
9389
+ return;
9390
+ }
9391
+ if (field.fit) {
9392
+ // no need to wrap
9393
+ return;
9394
+ }
9395
+ let minimumSize = this.minimumSizeOfField(field);
9396
+ while (minimumSize[0] > field.width || minimumSize[1] > field.height) {
9397
+ const textString = ((_d = (_c = (_b = textSelection === null || textSelection === void 0 ? void 0 : textSelection.html()) === null || _b === void 0 ? void 0 : _b.replace(/<\/tspan>/g, '\n')) === null || _c === void 0 ? void 0 : _c.replace(/<tspan[^>]*>/g, '')) === null || _d === void 0 ? void 0 : _d.slice(0, -1)) || '';
9398
+ let newTextString = '...';
9399
+ if (textString.endsWith('...')) {
9400
+ newTextString = textString.slice(0, -4) + '...';
9401
+ } else {
9402
+ newTextString = textString.slice(0, -1) + '...';
9403
+ }
9404
+ if (textSelection) {
9405
+ this.setFieldText(field, textSelection, newTextString);
9406
+ }
9407
+ if (newTextString === '...') {
9408
+ // if no more characters can be removed and the new text is a bare ellipsis, stop the execution
9409
+ return;
9410
+ }
9411
+ minimumSize = this.minimumSizeOfField(field);
9412
+ }
9413
+ }
9414
+ setFieldText(field, textSelection, text) {
9415
+ const lines = text.split('\n');
9416
+ textSelection.html('');
9417
+ for (let i = 0; i < lines.length; ++i) {
9418
+ textSelection.append('tspan').attr('x', field.horizontalAlign === HorizontalAlign.Center ? field.width / 2 : field.horizontalAlign === HorizontalAlign.Right ? field.width : 0).attr('y', field.verticalAlign === VerticalAlign.Center ? (i + 0.5 - lines.length / 2) * field.fontSize + field.height / 2 : field.verticalAlign === VerticalAlign.Bottom ? field.height - (lines.length - i - 1) * field.fontSize : i * field.fontSize).text(lines[i]);
9419
+ }
9251
9420
  }
9252
9421
  /**
9253
9422
  * Method to call to start the moving of a node triggered by a user drag event.
@@ -9279,6 +9448,7 @@ class DiagramCanvas {
9279
9448
  }
9280
9449
  this.userHighlight.clear();
9281
9450
  this.dragging = true;
9451
+ this.diagramEvent$.next(new DiagramDraggingNodeEvent(d));
9282
9452
  }
9283
9453
  }
9284
9454
  /**
@@ -10284,4 +10454,4 @@ const getLocationsOfNodes = model => {
10284
10454
  return locations;
10285
10455
  };
10286
10456
 
10287
- export { ACTION_STACK_SIZE, ActionStack, AddConnectionAction, AddNodeAction, AdjacencyLayout, ApplyLayoutAction, BreadthAdjacencyLayout, BreadthLayout, ClosedShape, CollabClient, Corner, CursorStyle, DIAGRAM_FIELD_DEFAULTS, DagaExporter, DagaImporter, DiagramActionMethod, DiagramActions, DiagramCanvas, DiagramConnection, DiagramConnectionSet, DiagramConnectionType, DiagramContextMenu, DiagramDecorator, DiagramDecoratorSet, DiagramDoubleClickEvent, DiagramElement, DiagramElementSet, DiagramEntitySet, DiagramEvent, DiagramEvents, DiagramField, DiagramFieldSet, DiagramHighlightedEvent, DiagramModel, DiagramNode, DiagramNodeSet, DiagramNodeType, DiagramObject, DiagramObjectSet, DiagramPort, DiagramPortSet, DiagramPortType, DiagramSecondaryClickEvent, DiagramSection, DiagramSectionSet, DiagramSelectionEvent, DiagramUserHighlight, DiagramUserSelection, DiagramZoomEvent, DragEvents, EditFieldAction, Events, ForceLayout, HorizontalAlign, HorizontalLayout, Keys, LineShape, LineStyle, MoveAction, PasteAction, PriorityLayout, Property, PropertySet, RemoveAction, SetGeometryAction, SetParentAction, Side, TreeLayout, Type, UpdateValuesAction, ValueSet, VerticalAlign, VerticalLayout, ZoomEvents, addIfNotExists, diff, equals, filterByOnlyAncestors, filterByOnlyDescendants, generalClosedPath, getBottomMargin, getBottomPadding$1 as getBottomPadding, getLeftMargin, getLeftPadding$1 as getLeftPadding, getLocationsOfNodes, getRightMargin, getRightPadding$1 as getRightPadding, getTopMargin, getTopPadding$1 as getTopPadding, isObject, layouts, linePath, lineStyleDasharray, removeIfExists, setCursorStyle };
10457
+ export { ACTION_STACK_SIZE, ActionStack, AddConnectionAction, AddNodeAction, AdjacencyLayout, ApplyLayoutAction, BreadthAdjacencyLayout, BreadthLayout, ClosedShape, CollabClient, Corner, CursorStyle, DIAGRAM_FIELD_DEFAULTS, DagaExporter, DagaImporter, DiagramActionMethod, DiagramActions, DiagramCanvas, DiagramConnection, DiagramConnectionSet, DiagramConnectionType, DiagramContextMenu, DiagramDecorator, DiagramDecoratorSet, DiagramDoubleClickEvent, DiagramDraggingNodeEvent, DiagramElement, DiagramElementSet, DiagramEntitySet, DiagramEvent, DiagramEvents, DiagramField, DiagramFieldSet, DiagramHighlightedEvent, DiagramModel, DiagramNode, DiagramNodeSet, DiagramNodeType, DiagramObject, DiagramObjectSet, DiagramPort, DiagramPortSet, DiagramPortType, DiagramSecondaryClickEvent, DiagramSection, DiagramSectionSet, DiagramSelectionEvent, DiagramUserHighlight, DiagramUserSelection, DiagramZoomEvent, DragEvents, EditFieldAction, Events, ForceLayout, HorizontalAlign, HorizontalLayout, Keys, LineShape, LineStyle, MoveAction, PasteAction, PriorityLayout, Property, PropertySet, RemoveAction, ResizableMode, SetGeometryAction, SetParentAction, Side, TreeLayout, Type, UpdateValuesAction, ValueSet, VerticalAlign, VerticalLayout, ZoomEvents, addIfNotExists, diff, equals, filterByOnlyAncestors, filterByOnlyDescendants, generalClosedPath, getBottomMargin, getBottomPadding$1 as getBottomPadding, getLeftMargin, getLeftPadding$1 as getLeftPadding, getLocationsOfNodes, getRightMargin, getRightPadding$1 as getRightPadding, getTopMargin, getTopPadding$1 as getTopPadding, isObject, layouts, linePath, lineStyleDasharray, removeIfExists, setCursorStyle };