@metadev/daga 3.1.5 → 4.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.
package/index.esm.js CHANGED
@@ -807,6 +807,64 @@ const numberOfRows = s => {
807
807
  return ((_a = s.match(/\n/g)) === null || _a === undefined ? undefined : _a.length) || 0;
808
808
  };
809
809
 
810
+ /******************************************************************************
811
+ Copyright (c) Microsoft Corporation.
812
+
813
+ Permission to use, copy, modify, and/or distribute this software for any
814
+ purpose with or without fee is hereby granted.
815
+
816
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
817
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
818
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
819
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
820
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
821
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
822
+ PERFORMANCE OF THIS SOFTWARE.
823
+ ***************************************************************************** */
824
+ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
825
+
826
+
827
+ function __rest(s, e) {
828
+ var t = {};
829
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
830
+ t[p] = s[p];
831
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
832
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
833
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
834
+ t[p[i]] = s[p[i]];
835
+ }
836
+ return t;
837
+ }
838
+
839
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
840
+ var e = new Error(message);
841
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
842
+ };
843
+
844
+ /**
845
+ * Converts a configuration for a look into an easier to consult object of fully qualified looks for each case.
846
+ *
847
+ * @param lookConfig A look configuration object
848
+ * @returns An object with four keys for a look with each possible state of being selected or not and being highlighted or not.
849
+ */
850
+ const extractLooksFromConfig = lookConfig => {
851
+ const {
852
+ selected,
853
+ highlighted
854
+ } = lookConfig,
855
+ rest = __rest(lookConfig, ["selected", "highlighted"]);
856
+ const defaultLook = rest;
857
+ const selectedLook = Object.assign(Object.assign({}, defaultLook), selected);
858
+ const highlightedLook = Object.assign(Object.assign({}, defaultLook), highlighted);
859
+ const selectedAndHighlightedLook = Object.assign(Object.assign(Object.assign({}, defaultLook), highlighted), selected);
860
+ return {
861
+ defaultLook,
862
+ selectedLook,
863
+ highlightedLook,
864
+ selectedAndHighlightedLook
865
+ };
866
+ };
867
+
810
868
  /**
811
869
  * Represents a collection of diagram entities of a type that exists as part of a diagram model.
812
870
  * @public
@@ -943,6 +1001,10 @@ class DiagramEntitySet {
943
1001
  }
944
1002
  }
945
1003
 
1004
+ const escapeSelector = selector => {
1005
+ return selector.replace(/([!"#$%&'()*+,\-./:;<=>?@[\\\]^`{|}])/g, '\\$1');
1006
+ };
1007
+
946
1008
  /**
947
1009
  * Default priority value for diagram elements.
948
1010
  * @private
@@ -955,6 +1017,10 @@ const DEFAULT_PRIORITY = 0;
955
1017
  * @see DiagramCanvas
956
1018
  */
957
1019
  class DiagramElement {
1020
+ /**
1021
+ * Identifier that uniquely identifies this element within its diagram model. Cannot be an empty string.
1022
+ * @public
1023
+ */
958
1024
  get id() {
959
1025
  return this._id;
960
1026
  }
@@ -1000,7 +1066,7 @@ class DiagramElement {
1000
1066
  */
1001
1067
  select() {
1002
1068
  var _a, _b;
1003
- return (_b = (_a = this.model.canvas) === null || _a === undefined ? undefined : _a.selectCanvasView()) === null || _b === undefined ? undefined : _b.select(`g#${this.id}`);
1069
+ return (_b = (_a = this.model.canvas) === null || _a === undefined ? undefined : _a.selectCanvasView()) === null || _b === undefined ? undefined : _b.select(`[id='${escapeSelector(this.id)}']`);
1004
1070
  }
1005
1071
  }
1006
1072
  class DiagramElementSet extends DiagramEntitySet {
@@ -1223,7 +1289,6 @@ class ValueSet {
1223
1289
  constructor(propertySet, rootElement) {
1224
1290
  this.displayedProperties = [];
1225
1291
  this.hiddenProperties = [];
1226
- // TODO JC: make this private after reviewing how it's used from React
1227
1292
  this.values = {};
1228
1293
  this.valueSets = {};
1229
1294
  /**
@@ -1508,7 +1573,7 @@ class ValueSet {
1508
1573
  this.values[key] = structuredClone(property.defaultValue);
1509
1574
  }
1510
1575
  if (rootAttribute !== undefined && rootAttribute !== null) {
1511
- if (property.defaultValue !== undefined) {
1576
+ if (property.defaultValue !== undefined && !equals(this.values[key], property.defaultValue)) {
1512
1577
  this.setRootElementValue(rootAttribute, this.values[key]);
1513
1578
  } else {
1514
1579
  this.values[key] = this.getRootElementValue(rootAttribute);
@@ -1626,6 +1691,34 @@ const diff = (a, b) => {
1626
1691
  }
1627
1692
  return [aDiff, bDiff];
1628
1693
  };
1694
+ /**
1695
+ * Calculates the differences between the two given values of a valueset and returns two objects containing the differences in each relative to the other.
1696
+ *
1697
+ * @param a An object.
1698
+ * @param b An object.
1699
+ * @param valueSet A ValueSet to use as reference for the keys and types of each property.
1700
+ * @returns A tuple of two objects with each containing the keys that have a different value in the corresponding argument compared to the other argument.
1701
+ */
1702
+ const diffProperties = (a, b, valueSet) => {
1703
+ const aDiff = {};
1704
+ const bDiff = {};
1705
+ for (const key in valueSet.propertySet.propertyMap) {
1706
+ if (valueSet.propertySet.propertyMap[key].type === Type.Object) {
1707
+ const diffAB = diffProperties(a[key], b[key], valueSet.getSubValueSet(key));
1708
+ // only add the key if differences are detected
1709
+ if (Object.keys(diffAB[0]).length > 0 && Object.keys(diffAB[1]).length > 0) {
1710
+ aDiff[key] = diffAB[0];
1711
+ bDiff[key] = diffAB[1];
1712
+ }
1713
+ } else {
1714
+ if (!equals(a[key], b[key])) {
1715
+ aDiff[key] = a[key];
1716
+ bDiff[key] = b[key];
1717
+ }
1718
+ }
1719
+ }
1720
+ return [aDiff, bDiff];
1721
+ };
1629
1722
  /**
1630
1723
  * Checks if the given value is an object.
1631
1724
  * @public
@@ -1641,16 +1734,24 @@ const isObject = x => x !== undefined && x !== null && x.constructor === Object;
1641
1734
  */
1642
1735
  const DIAGRAM_CONNECTION_TYPE_DEFAULTS = {
1643
1736
  name: '',
1644
- width: 1,
1645
- shape: LineShape.Straight,
1646
- style: LineStyle.Solid,
1647
1737
  label: null,
1648
- defaultStartMarkerLook: null,
1649
- defaultEndMarkerLook: null,
1738
+ look: {
1739
+ lookType: 'connection-look',
1740
+ color: '#000000',
1741
+ thickness: 1,
1742
+ shape: LineShape.Straight,
1743
+ style: LineStyle.Solid,
1744
+ selected: {
1745
+ color: '#AA00AA'
1746
+ },
1747
+ highlighted: {
1748
+ thickness: 2
1749
+ }
1750
+ },
1751
+ startMarkerLook: undefined,
1752
+ endMarkerLook: undefined,
1650
1753
  startTypes: [],
1651
1754
  endTypes: [],
1652
- color: '#000000',
1653
- selectedColor: '#000000',
1654
1755
  properties: []
1655
1756
  };
1656
1757
  /**
@@ -1663,16 +1764,38 @@ class DiagramConnectionType {
1663
1764
  const values = Object.assign(Object.assign({}, DIAGRAM_CONNECTION_TYPE_DEFAULTS), options);
1664
1765
  this.id = values.id;
1665
1766
  this.name = values.name;
1666
- this.width = values.width;
1667
- this.shape = values.shape;
1668
- this.style = values.style;
1669
1767
  this.label = values.label;
1670
- this.defaultStartMarkerLook = values.defaultStartMarkerLook;
1671
- this.defaultEndMarkerLook = values.defaultEndMarkerLook;
1768
+ const looks = extractLooksFromConfig(values.look);
1769
+ this.defaultLook = looks.defaultLook;
1770
+ this.selectedLook = looks.selectedLook;
1771
+ this.highlightedLook = looks.highlightedLook;
1772
+ this.selectedAndHighlightedLook = looks.selectedAndHighlightedLook;
1773
+ if (values.startMarkerLook !== undefined) {
1774
+ const startMarkerLooks = extractLooksFromConfig(values.startMarkerLook);
1775
+ this.defaultStartMarkerLook = startMarkerLooks.defaultLook;
1776
+ this.selectedStartMarkerLook = startMarkerLooks.selectedLook;
1777
+ this.highlightedStartMarkerLook = startMarkerLooks.highlightedLook;
1778
+ this.selectedAndHighlightedStartMarkerLook = startMarkerLooks.selectedAndHighlightedLook;
1779
+ } else {
1780
+ this.defaultStartMarkerLook = null;
1781
+ this.selectedStartMarkerLook = null;
1782
+ this.highlightedStartMarkerLook = null;
1783
+ this.selectedAndHighlightedStartMarkerLook = null;
1784
+ }
1785
+ if (values.endMarkerLook !== undefined) {
1786
+ const endMarkerLooks = extractLooksFromConfig(values.endMarkerLook);
1787
+ this.defaultEndMarkerLook = endMarkerLooks.defaultLook;
1788
+ this.selectedEndMarkerLook = endMarkerLooks.selectedLook;
1789
+ this.highlightedEndMarkerLook = endMarkerLooks.highlightedLook;
1790
+ this.selectedAndHighlightedEndMarkerLook = endMarkerLooks.selectedAndHighlightedLook;
1791
+ } else {
1792
+ this.defaultEndMarkerLook = null;
1793
+ this.selectedEndMarkerLook = null;
1794
+ this.highlightedEndMarkerLook = null;
1795
+ this.selectedAndHighlightedEndMarkerLook = null;
1796
+ }
1672
1797
  this.startTypes = values.startTypes;
1673
1798
  this.endTypes = values.endTypes;
1674
- this.color = values.color;
1675
- this.selectedColor = values.selectedColor;
1676
1799
  this.propertySet = new PropertySet(values.properties);
1677
1800
  }
1678
1801
  canStartFromType(type) {
@@ -1688,6 +1811,27 @@ class DiagramConnectionType {
1688
1811
  * @see DiagramPort
1689
1812
  */
1690
1813
  class DiagramConnection extends DiagramElement {
1814
+ get type() {
1815
+ return this._type;
1816
+ }
1817
+ set type(type) {
1818
+ var _a, _b;
1819
+ (_b = (_a = this.model.canvas) === null || _a === undefined ? undefined : _a.userSelection) === null || _b === undefined ? undefined : _b.openInPropertyEditor(undefined);
1820
+ this._type = type;
1821
+ if (this.valueSet) {
1822
+ this.valueSet = new ValueSet(type.propertySet, this);
1823
+ }
1824
+ this.updateInView();
1825
+ }
1826
+ get typeString() {
1827
+ return this.type.id;
1828
+ }
1829
+ set typeString(typeString) {
1830
+ const type = this.model.connections.types.get(typeString);
1831
+ if (type) {
1832
+ this.type = type;
1833
+ }
1834
+ }
1691
1835
  /**
1692
1836
  * Name of this connection. Alias for this connection's middle label.
1693
1837
  * @public
@@ -1698,10 +1842,127 @@ class DiagramConnection extends DiagramElement {
1698
1842
  set name(name) {
1699
1843
  this.middleLabel = name;
1700
1844
  }
1845
+ /**
1846
+ * Current look of the connection.
1847
+ * @private
1848
+ */
1849
+ get look() {
1850
+ if (this.selected) {
1851
+ if (this.highlighted) {
1852
+ return this._selectedAndHighlightedLook !== undefined ? this._selectedAndHighlightedLook : this.type.selectedAndHighlightedLook;
1853
+ } else {
1854
+ return this._selectedLook !== undefined ? this._selectedLook : this.type.selectedLook;
1855
+ }
1856
+ } else {
1857
+ if (this.highlighted) {
1858
+ return this._highlightedLook !== undefined ? this._highlightedLook : this.type.highlightedLook;
1859
+ } else {
1860
+ return this._defaultLook !== undefined ? this._defaultLook : this.type.defaultLook;
1861
+ }
1862
+ }
1863
+ }
1864
+ /**
1865
+ * Sets the look configuration of the connection to override the one determined by the type.
1866
+ * `undefined` resets it to the one determined by the type.
1867
+ * @private
1868
+ */
1869
+ set look(look) {
1870
+ if (look) {
1871
+ const looks = extractLooksFromConfig(look);
1872
+ this._defaultLook = Object.assign(Object.assign({}, this._defaultLook), looks.defaultLook);
1873
+ this._selectedLook = Object.assign(Object.assign({}, this._selectedLook), looks.selectedLook);
1874
+ this._highlightedLook = Object.assign(Object.assign({}, this._highlightedLook), looks.highlightedLook);
1875
+ this._selectedAndHighlightedLook = Object.assign(Object.assign({}, this._selectedAndHighlightedLook), looks.selectedAndHighlightedLook);
1876
+ } else {
1877
+ this._defaultLook = look;
1878
+ this._selectedLook = look;
1879
+ this._highlightedLook = look;
1880
+ this._selectedAndHighlightedLook = look;
1881
+ }
1882
+ }
1883
+ /**
1884
+ * Current look of the start marker.
1885
+ * @private
1886
+ */
1887
+ get startMarkerLook() {
1888
+ if (this.selected) {
1889
+ if (this.highlighted) {
1890
+ return this._selectedAndHighlightedStartMarkerLook !== undefined ? this._selectedAndHighlightedStartMarkerLook : this.type.selectedAndHighlightedStartMarkerLook;
1891
+ } else {
1892
+ return this._selectedStartMarkerLook !== undefined ? this._selectedStartMarkerLook : this.type.selectedStartMarkerLook;
1893
+ }
1894
+ } else {
1895
+ if (this.highlighted) {
1896
+ return this._highlightedStartMarkerLook !== undefined ? this._highlightedStartMarkerLook : this.type.highlightedStartMarkerLook;
1897
+ } else {
1898
+ return this._defaultStartMarkerLook !== undefined ? this._defaultStartMarkerLook : this.type.defaultStartMarkerLook;
1899
+ }
1900
+ }
1901
+ }
1902
+ /**
1903
+ * Sets the look configuration of the start marker to override the one determined by the type.
1904
+ * `null` stands for no marker and `undefined` resets it to the one determined by the type.
1905
+ * @private
1906
+ */
1907
+ set startMarkerLook(startMarkerLook) {
1908
+ if (startMarkerLook) {
1909
+ const looks = extractLooksFromConfig(startMarkerLook);
1910
+ this._defaultStartMarkerLook = Object.assign(Object.assign({}, this._defaultStartMarkerLook), looks.defaultLook);
1911
+ this._selectedStartMarkerLook = Object.assign(Object.assign({}, this._selectedStartMarkerLook), looks.selectedLook);
1912
+ this._highlightedStartMarkerLook = Object.assign(Object.assign({}, this._highlightedStartMarkerLook), looks.highlightedLook);
1913
+ this._selectedAndHighlightedStartMarkerLook = Object.assign(Object.assign({}, this._selectedAndHighlightedStartMarkerLook), looks.selectedAndHighlightedLook);
1914
+ } else {
1915
+ this._defaultStartMarkerLook = startMarkerLook;
1916
+ this._selectedStartMarkerLook = startMarkerLook;
1917
+ this._highlightedStartMarkerLook = startMarkerLook;
1918
+ this._selectedAndHighlightedStartMarkerLook = startMarkerLook;
1919
+ }
1920
+ }
1921
+ /**
1922
+ * Current look of the end marker.
1923
+ * @private
1924
+ */
1925
+ get endMarkerLook() {
1926
+ if (this.selected) {
1927
+ if (this.highlighted) {
1928
+ return this._selectedAndHighlightedEndMarkerLook !== undefined ? this._selectedAndHighlightedEndMarkerLook : this.type.selectedAndHighlightedEndMarkerLook;
1929
+ } else {
1930
+ return this._selectedEndMarkerLook !== undefined ? this._selectedEndMarkerLook : this.type.selectedEndMarkerLook;
1931
+ }
1932
+ } else {
1933
+ if (this.highlighted) {
1934
+ return this._highlightedEndMarkerLook !== undefined ? this._highlightedEndMarkerLook : this.type.highlightedEndMarkerLook;
1935
+ } else {
1936
+ return this._defaultEndMarkerLook !== undefined ? this._defaultEndMarkerLook : this.type.defaultEndMarkerLook;
1937
+ }
1938
+ }
1939
+ }
1940
+ /**
1941
+ * Sets the look configuration of the end marker to override the one determined by the type.
1942
+ * `null` stands for no marker and `undefined` resets it to the one determined by the type.
1943
+ * @private
1944
+ */
1945
+ set endMarkerLook(endMarkerLook) {
1946
+ if (endMarkerLook) {
1947
+ const looks = extractLooksFromConfig(endMarkerLook);
1948
+ this._defaultEndMarkerLook = Object.assign(Object.assign({}, this._defaultEndMarkerLook), looks.defaultLook);
1949
+ this._selectedEndMarkerLook = Object.assign(Object.assign({}, this._selectedEndMarkerLook), looks.selectedLook);
1950
+ this._highlightedEndMarkerLook = Object.assign(Object.assign({}, this._highlightedEndMarkerLook), looks.highlightedLook);
1951
+ this._selectedAndHighlightedEndMarkerLook = Object.assign(Object.assign({}, this._selectedAndHighlightedEndMarkerLook), looks.selectedAndHighlightedLook);
1952
+ } else {
1953
+ this._defaultEndMarkerLook = endMarkerLook;
1954
+ this._selectedEndMarkerLook = endMarkerLook;
1955
+ this._highlightedEndMarkerLook = endMarkerLook;
1956
+ this._selectedAndHighlightedEndMarkerLook = endMarkerLook;
1957
+ }
1958
+ }
1701
1959
  constructor(model, type, start, end, id) {
1702
1960
  if (model.connections.get(id) !== undefined) {
1703
1961
  throw new Error(`DiagramConnection with id "${id}" already exists`);
1704
1962
  }
1963
+ if (!id) {
1964
+ throw new Error(`DiagramConnection cannot have an empty or null id`);
1965
+ }
1705
1966
  super(model, id);
1706
1967
  /**
1707
1968
  * Coordinates of the start point of this connection.
@@ -1733,11 +1994,9 @@ class DiagramConnection extends DiagramElement {
1733
1994
  * @public
1734
1995
  */
1735
1996
  this.points = [];
1736
- this.type = type;
1997
+ this._type = type;
1737
1998
  this.valueSet = new ValueSet(type.propertySet, this);
1738
1999
  this.originalData = {};
1739
- this.startMarkerLook = type.defaultStartMarkerLook;
1740
- this.endMarkerLook = type.defaultEndMarkerLook;
1741
2000
  this.setStart(start);
1742
2001
  this.setEnd(end);
1743
2002
  }
@@ -1910,7 +2169,7 @@ class DiagramConnectionSet extends DiagramElementSet {
1910
2169
  * @param type The type of the connection given as either the type itself or the id of the type.
1911
2170
  * @param start The start port of the connection.
1912
2171
  * @param end The end port of the connection.
1913
- * @param id The id of the connection.
2172
+ * @param id The id of the connection. Cannot be an empty string.
1914
2173
  * @returns The instanced connection.
1915
2174
  */
1916
2175
  new(type, start, end, id) {
@@ -2014,10 +2273,6 @@ class DiagramField extends DiagramElement {
2014
2273
  this.editable = editable;
2015
2274
  this.fit = fit;
2016
2275
  }
2017
- select() {
2018
- var _a, _b;
2019
- return (_b = (_a = this.model.canvas) === null || _a === undefined ? undefined : _a.selectCanvasView()) === null || _b === undefined ? undefined : _b.select(`foreignObject#${this.id}`);
2020
- }
2021
2276
  get removed() {
2022
2277
  return this.selfRemoved || this.rootElement !== undefined && this.rootElement.removed;
2023
2278
  }
@@ -2236,30 +2491,6 @@ const getTopPadding$1 = config => {
2236
2491
  }
2237
2492
  };
2238
2493
 
2239
- /**
2240
- * Default values of the look of a diagram section.
2241
- * @private
2242
- * @see DIAGRAM_SECTION_DEFAULTS
2243
- */
2244
- const DIAGRAM_SECTION_LOOK_DEFAULTS = {
2245
- lookType: 'shaped-look',
2246
- shape: ClosedShape.Rectangle,
2247
- fillColor: '#FFFFFF',
2248
- borderColor: '#000000',
2249
- selectedFillColor: '#FFFFFF',
2250
- selectedBorderColor: '#000000'
2251
- };
2252
- /**
2253
- * Default values of the parameters of a diagram section.
2254
- * @private
2255
- * @see DiagramSection
2256
- */
2257
- const DIAGRAM_SECTION_DEFAULTS = {
2258
- label: null,
2259
- ports: [],
2260
- look: DIAGRAM_SECTION_LOOK_DEFAULTS,
2261
- priority: DEFAULT_PRIORITY
2262
- };
2263
2494
  /**
2264
2495
  * Default value of the default width of a diagram section.
2265
2496
  * @private
@@ -2284,6 +2515,41 @@ const DIAGRAM_SECTION_MIN_WIDTH = 1;
2284
2515
  * @see DiagramSection
2285
2516
  */
2286
2517
  const DIAGRAM_SECTION_MIN_HEIGHT = 1;
2518
+ /**
2519
+ * A grid of sections which a node has.
2520
+ * @public
2521
+ * @see DiagramNode
2522
+ * @see SectionGridConfig
2523
+ */
2524
+ class DiagramSectionGrid {
2525
+ constructor(options) {
2526
+ this.margin = options.margin || 0;
2527
+ this.defaultWidths = options.defaultWidths || null;
2528
+ this.defaultHeights = options.defaultHeights || null;
2529
+ this.minWidths = options.minWidths || null;
2530
+ this.minHeights = options.minHeights || null;
2531
+ this.sections = [];
2532
+ for (const sectionRow of options.sections) {
2533
+ const sectionList = [];
2534
+ this.sections.push(sectionList);
2535
+ for (const section of sectionRow) {
2536
+ sectionList.push(new DiagramSectionType(section));
2537
+ }
2538
+ }
2539
+ }
2540
+ }
2541
+ class DiagramSectionType {
2542
+ constructor(options) {
2543
+ this.label = options.label || null;
2544
+ this.ports = options.ports || [];
2545
+ this.priority = options.priority || DEFAULT_PRIORITY;
2546
+ const looks = extractLooksFromConfig(options.look || DIAGRAM_NODE_LOOK_DEFAULTS);
2547
+ this.defaultLook = looks.defaultLook;
2548
+ this.selectedLook = looks.selectedLook;
2549
+ this.highlightedLook = looks.highlightedLook;
2550
+ this.selectedAndHighlightedLook = looks.selectedAndHighlightedLook;
2551
+ }
2552
+ }
2287
2553
  /**
2288
2554
  * A section of a node which can have connections and display a property of the node.
2289
2555
  * @public
@@ -2305,10 +2571,52 @@ class DiagramSection extends DiagramElement {
2305
2571
  this.label.text = name;
2306
2572
  }
2307
2573
  }
2574
+ /**
2575
+ * Current look of this port.
2576
+ * @private
2577
+ */
2578
+ get look() {
2579
+ var _a, _b, _c, _d, _e, _f, _g, _h;
2580
+ if (this.selected) {
2581
+ if (this.highlighted) {
2582
+ return this._selectedAndHighlightedLook !== undefined ? this._selectedAndHighlightedLook : ((_a = this.type) === null || _a === undefined ? undefined : _a.selectedAndHighlightedLook) || ((_b = this.node) === null || _b === undefined ? undefined : _b.look);
2583
+ } else {
2584
+ return this._selectedLook !== undefined ? this._selectedLook : ((_c = this.type) === null || _c === undefined ? undefined : _c.selectedLook) || ((_d = this.node) === null || _d === undefined ? undefined : _d.look);
2585
+ }
2586
+ } else {
2587
+ if (this.highlighted) {
2588
+ return this._highlightedLook !== undefined ? this._highlightedLook : ((_e = this.type) === null || _e === undefined ? undefined : _e.highlightedLook) || ((_f = this.node) === null || _f === undefined ? undefined : _f.look);
2589
+ } else {
2590
+ return this._defaultLook !== undefined ? this._defaultLook : ((_g = this.type) === null || _g === undefined ? undefined : _g.defaultLook) || ((_h = this.node) === null || _h === undefined ? undefined : _h.look);
2591
+ }
2592
+ }
2593
+ }
2594
+ /**
2595
+ * Sets the look configuration of the look to override the one determined by the type.
2596
+ * `undefined` resets it to the one determined by the type.
2597
+ * @private
2598
+ */
2599
+ set look(look) {
2600
+ if (look) {
2601
+ const looks = extractLooksFromConfig(look);
2602
+ this._defaultLook = Object.assign(Object.assign({}, this._defaultLook), looks.defaultLook);
2603
+ this._selectedLook = Object.assign(Object.assign({}, this._selectedLook), looks.selectedLook);
2604
+ this._highlightedLook = Object.assign(Object.assign({}, this._highlightedLook), looks.highlightedLook);
2605
+ this._selectedAndHighlightedLook = Object.assign(Object.assign({}, this._selectedAndHighlightedLook), looks.selectedAndHighlightedLook);
2606
+ } else {
2607
+ this._defaultLook = look;
2608
+ this._selectedLook = look;
2609
+ this._highlightedLook = look;
2610
+ this._selectedAndHighlightedLook = look;
2611
+ }
2612
+ }
2308
2613
  constructor(model, node, indexXInNode, indexYInNode, coords, width, height, id) {
2309
2614
  if (model.sections.get(id) !== undefined) {
2310
2615
  throw new Error(`DiagramSection with id "${id}" already exists`);
2311
2616
  }
2617
+ if (!id) {
2618
+ throw new Error(`DiagramSection cannot have an empty or null id`);
2619
+ }
2312
2620
  super(model, id);
2313
2621
  /**
2314
2622
  * Ports of this section.
@@ -2347,7 +2655,7 @@ class DiagramSection extends DiagramElement {
2347
2655
  decorator.raise();
2348
2656
  }
2349
2657
  }
2350
- getConfig() {
2658
+ get type() {
2351
2659
  var _a, _b, _c, _d, _e;
2352
2660
  return (_e = (_d = (_c = (_b = (_a = this.node) === null || _a === undefined ? undefined : _a.type) === null || _b === undefined ? undefined : _b.sectionGrid) === null || _c === undefined ? undefined : _c.sections) === null || _d === undefined ? undefined : _d[this.indexYInNode]) === null || _e === undefined ? undefined : _e[this.indexXInNode];
2353
2661
  }
@@ -2361,7 +2669,7 @@ class DiagramSection extends DiagramElement {
2361
2669
  }
2362
2670
  getPriority() {
2363
2671
  var _a, _b, _c, _d, _e, _f;
2364
- return ((_f = (_e = (_d = (_c = (_b = (_a = this.node) === null || _a === undefined ? undefined : _a.type) === null || _b === undefined ? undefined : _b.sectionGrid) === null || _c === undefined ? undefined : _c.sections) === null || _d === undefined ? undefined : _d[this.indexYInNode]) === null || _e === undefined ? undefined : _e[this.indexXInNode]) === null || _f === undefined ? undefined : _f.priority) || DIAGRAM_SECTION_DEFAULTS.priority;
2672
+ return ((_f = (_e = (_d = (_c = (_b = (_a = this.node) === null || _a === undefined ? undefined : _a.type) === null || _b === undefined ? undefined : _b.sectionGrid) === null || _c === undefined ? undefined : _c.sections) === null || _d === undefined ? undefined : _d[this.indexYInNode]) === null || _e === undefined ? undefined : _e[this.indexXInNode]) === null || _f === undefined ? undefined : _f.priority) || DEFAULT_PRIORITY;
2365
2673
  }
2366
2674
  /**
2367
2675
  * Get the port of this section which is closest to the given coordinates.
@@ -2512,7 +2820,6 @@ class DiagramSection extends DiagramElement {
2512
2820
  * @public
2513
2821
  */
2514
2822
  setGeometry(geometry) {
2515
- var _a, _b, _c, _d, _e, _f;
2516
2823
  const oldCoordsX = [this.coords[0], this.coords[0] + this.width];
2517
2824
  const oldCoordsY = [this.coords[1], this.coords[1] + this.height];
2518
2825
  this.coords = [...geometry.coords];
@@ -2525,10 +2832,11 @@ class DiagramSection extends DiagramElement {
2525
2832
  port.move(translatePoint(port.coords, oldCoordsX, oldCoordsY, newCoordsX, newCoordsY));
2526
2833
  }
2527
2834
  // Set label's dimensions as a function of ours.
2835
+ const type = this.type;
2528
2836
  if (this.label) {
2529
- this.label.coords = [this.coords[0] + getLeftMargin((_a = this.getConfig()) === null || _a === undefined ? undefined : _a.label), this.coords[1] + getTopMargin((_b = this.getConfig()) === null || _b === undefined ? undefined : _b.label)];
2530
- this.label.width = this.width - getLeftMargin((_c = this.getConfig()) === null || _c === undefined ? undefined : _c.label) - getRightMargin((_d = this.getConfig()) === null || _d === undefined ? undefined : _d.label);
2531
- this.label.height = this.height - getTopMargin((_e = this.getConfig()) === null || _e === undefined ? undefined : _e.label) - getBottomMargin((_f = this.getConfig()) === null || _f === undefined ? undefined : _f.label);
2837
+ this.label.coords = [this.coords[0] + getLeftMargin(type === null || type === undefined ? undefined : type.label), this.coords[1] + getTopMargin(type === null || type === undefined ? undefined : type.label)];
2838
+ this.label.width = this.width - getLeftMargin(type === null || type === undefined ? undefined : type.label) - getRightMargin(type === null || type === undefined ? undefined : type.label);
2839
+ this.label.height = this.height - getTopMargin(type === null || type === undefined ? undefined : type.label) - getBottomMargin(type === null || type === undefined ? undefined : type.label);
2532
2840
  this.label.updateInView();
2533
2841
  }
2534
2842
  // Move decorators to match the new coords.
@@ -2629,8 +2937,14 @@ const DIAGRAM_NODE_LOOK_DEFAULTS = {
2629
2937
  shape: ClosedShape.Rectangle,
2630
2938
  fillColor: '#FFFFFF',
2631
2939
  borderColor: '#000000',
2632
- selectedFillColor: '#FFFFFF',
2633
- selectedBorderColor: '#000000'
2940
+ borderThickness: 1,
2941
+ selected: {
2942
+ fillColor: '#FFAAFF',
2943
+ borderColor: '#AA00AA'
2944
+ },
2945
+ highlighted: {
2946
+ borderThickness: 3
2947
+ }
2634
2948
  };
2635
2949
  /**
2636
2950
  * Default values of the parameters of a diagram node.
@@ -2678,8 +2992,12 @@ class DiagramNodeType {
2678
2992
  this.topPadding = getTopPadding(values);
2679
2993
  this.label = values.label;
2680
2994
  this.ports = values.ports;
2681
- this.sectionGrid = values.sectionGrid;
2682
- this.look = values.look;
2995
+ this.sectionGrid = values.sectionGrid ? new DiagramSectionGrid(values.sectionGrid) : null;
2996
+ const looks = extractLooksFromConfig(values.look);
2997
+ this.defaultLook = looks.defaultLook;
2998
+ this.selectedLook = looks.selectedLook;
2999
+ this.highlightedLook = looks.highlightedLook;
3000
+ this.selectedAndHighlightedLook = looks.selectedAndHighlightedLook;
2683
3001
  this.isUnique = values.isUnique;
2684
3002
  this.canBeParentless = values.canBeParentless;
2685
3003
  this.childrenTypes = values.childrenTypes;
@@ -2695,6 +3013,27 @@ class DiagramNodeType {
2695
3013
  * @see DiagramSection
2696
3014
  */
2697
3015
  class DiagramNode extends DiagramElement {
3016
+ get type() {
3017
+ return this._type;
3018
+ }
3019
+ set type(type) {
3020
+ var _a, _b;
3021
+ (_b = (_a = this.model.canvas) === null || _a === undefined ? undefined : _a.userSelection) === null || _b === undefined ? undefined : _b.openInPropertyEditor(undefined);
3022
+ this._type = type;
3023
+ if (this.valueSet) {
3024
+ this.valueSet = new ValueSet(type.propertySet, this);
3025
+ }
3026
+ this.updateInView();
3027
+ }
3028
+ get typeString() {
3029
+ return this.type.id;
3030
+ }
3031
+ set typeString(typeString) {
3032
+ const type = this.model.nodes.types.get(typeString);
3033
+ if (type) {
3034
+ this.type = type;
3035
+ }
3036
+ }
2698
3037
  /**
2699
3038
  * Name of this node. Alias for this node's label's text.
2700
3039
  * @public
@@ -2708,10 +3047,51 @@ class DiagramNode extends DiagramElement {
2708
3047
  this.label.text = name;
2709
3048
  }
2710
3049
  }
3050
+ /**
3051
+ * Current look of this port.
3052
+ * @private
3053
+ */
3054
+ get look() {
3055
+ if (this.selected) {
3056
+ if (this.highlighted) {
3057
+ return this._selectedAndHighlightedLook !== undefined ? this._selectedAndHighlightedLook : this.type.selectedAndHighlightedLook;
3058
+ } else {
3059
+ return this._selectedLook !== undefined ? this._selectedLook : this.type.selectedLook;
3060
+ }
3061
+ } else {
3062
+ if (this.highlighted) {
3063
+ return this._highlightedLook !== undefined ? this._highlightedLook : this.type.highlightedLook;
3064
+ } else {
3065
+ return this._defaultLook !== undefined ? this._defaultLook : this.type.defaultLook;
3066
+ }
3067
+ }
3068
+ }
3069
+ /**
3070
+ * Sets the look configuration of the look to override the one determined by the type.
3071
+ * `undefined` resets it to the one determined by the type.
3072
+ * @private
3073
+ */
3074
+ set look(look) {
3075
+ if (look) {
3076
+ const looks = extractLooksFromConfig(look);
3077
+ this._defaultLook = Object.assign(Object.assign({}, this._defaultLook), looks.defaultLook);
3078
+ this._selectedLook = Object.assign(Object.assign({}, this._selectedLook), looks.selectedLook);
3079
+ this._highlightedLook = Object.assign(Object.assign({}, this._highlightedLook), looks.highlightedLook);
3080
+ this._selectedAndHighlightedLook = Object.assign(Object.assign({}, this._selectedAndHighlightedLook), looks.selectedAndHighlightedLook);
3081
+ } else {
3082
+ this._defaultLook = look;
3083
+ this._selectedLook = look;
3084
+ this._highlightedLook = look;
3085
+ this._selectedAndHighlightedLook = look;
3086
+ }
3087
+ }
2711
3088
  constructor(model, type, coords = [0, 0], id) {
2712
3089
  if (model.nodes.get(id) !== undefined) {
2713
3090
  throw new Error(`DiagramNode with id "${id}" already exists`);
2714
3091
  }
3092
+ if (!id) {
3093
+ throw new Error(`DiagramNode cannot have an empty or null id`);
3094
+ }
2715
3095
  super(model, id);
2716
3096
  /**
2717
3097
  * Nodes contained within this node.
@@ -2738,7 +3118,7 @@ class DiagramNode extends DiagramElement {
2738
3118
  * @public
2739
3119
  */
2740
3120
  this.geometryTimestamp = null;
2741
- this.type = type;
3121
+ this._type = type;
2742
3122
  this.valueSet = new ValueSet(type.propertySet, this);
2743
3123
  this.originalData = {};
2744
3124
  this.coords = coords;
@@ -3217,7 +3597,7 @@ class DiagramNodeSet extends DiagramElementSet {
3217
3597
  * @public
3218
3598
  * @param type The type of the node given as either the type itself or the id of the type.
3219
3599
  * @param coords The coordinates of the top left corner of the node in the diagram.
3220
- * @param id The id of the node.
3600
+ * @param id The id of the node. Cannot be an empty string.
3221
3601
  * @returns The instanced node.
3222
3602
  */
3223
3603
  new(type, coords, id) {
@@ -3252,7 +3632,8 @@ class DiagramNodeSet extends DiagramElementSet {
3252
3632
  if (nodeType.ports.length > 0) {
3253
3633
  for (let i = 0; i < nodeType.ports.length; ++i) {
3254
3634
  const portConfig = nodeType.ports[i];
3255
- const port = this.model.ports.new(portConfig.type !== undefined ? this.model.ports.types.get(portConfig.type) : undefined, node, [node.coords[0] + portConfig.coords[0], node.coords[1] + portConfig.coords[1]], portConfig.connectionPoint !== undefined ? [node.coords[0] + (portConfig.connectionPoint[0] || 0), node.coords[1] + (portConfig.connectionPoint[1] || 0)] : undefined, portConfig.direction, `${node.id}_${i}`);
3635
+ const portType = portConfig.type !== undefined ? this.model.ports.types.get(portConfig.type) : undefined;
3636
+ const port = this.model.ports.new(portType, node, [node.coords[0] + portConfig.coords[0], node.coords[1] + portConfig.coords[1]], portConfig.connectionPoint !== undefined ? [node.coords[0] + (portConfig.connectionPoint[0] || 0), node.coords[1] + (portConfig.connectionPoint[1] || 0)] : undefined, portConfig.direction, `${node.id}_${i}`);
3256
3637
  if ((_e = port.type) === null || _e === undefined ? undefined : _e.label) {
3257
3638
  const labelConfiguration = Object.assign(Object.assign({}, DIAGRAM_FIELD_DEFAULTS), (_f = port.type) === null || _f === undefined ? undefined : _f.label);
3258
3639
  const labelWidth = 6 * labelConfiguration.fontSize + getLeftPadding$1(labelConfiguration) + getRightPadding$1(labelConfiguration);
@@ -3449,14 +3830,24 @@ const getTopPadding = config => {
3449
3830
  };
3450
3831
 
3451
3832
  /**
3452
- * Default values of the parameters of a diagram port.
3833
+ * Default values of the look of a diagram port.
3453
3834
  * @private
3454
- * @see DiagramPort
3835
+ * @see DIAGRAM_NODE_TYPE_DEFAULTS
3455
3836
  */
3456
- const DIAGRAM_PORT_DEFAULTS = {
3457
- highlightedColor: 'cyan',
3458
- selectedColor: 'violet'
3837
+ const DIAGRAM_PORT_LOOK_DEFAULTS = {
3838
+ lookType: 'shaped-look',
3839
+ shape: ClosedShape.Ellipse,
3840
+ fillColor: 'transparent',
3841
+ borderColor: 'transparent',
3842
+ borderThickness: 0,
3843
+ selected: {
3844
+ fillColor: 'rgba(255, 0, 255, 0.5)'
3845
+ },
3846
+ highlighted: {
3847
+ fillColor: 'rgba(0, 255, 255, 0.5)'
3848
+ }
3459
3849
  };
3850
+ const DIAGRAM_PORT_LOOKS = extractLooksFromConfig(DIAGRAM_PORT_LOOK_DEFAULTS);
3460
3851
  /**
3461
3852
  * Default values of the parameters of a diagram port.
3462
3853
  * @private
@@ -3467,7 +3858,8 @@ const DIAGRAM_PORT_TYPE_DEFAULTS = {
3467
3858
  label: null,
3468
3859
  allowsOutgoing: true,
3469
3860
  allowsIncoming: true,
3470
- width: 24
3861
+ width: 24,
3862
+ look: DIAGRAM_PORT_LOOK_DEFAULTS
3471
3863
  };
3472
3864
  /**
3473
3865
  * A port type, which holds properties that ports of this type share in common.
@@ -3483,7 +3875,11 @@ class DiagramPortType {
3483
3875
  this.allowsOutgoing = values.allowsOutgoing;
3484
3876
  this.allowsIncoming = values.allowsIncoming;
3485
3877
  this.width = values.width;
3486
- this.look = values.look;
3878
+ const looks = extractLooksFromConfig(values.look);
3879
+ this.defaultLook = looks.defaultLook;
3880
+ this.selectedLook = looks.selectedLook;
3881
+ this.highlightedLook = looks.highlightedLook;
3882
+ this.selectedAndHighlightedLook = looks.selectedAndHighlightedLook;
3487
3883
  }
3488
3884
  }
3489
3885
  /**
@@ -3494,6 +3890,27 @@ class DiagramPortType {
3494
3890
  * @see DiagramSection
3495
3891
  */
3496
3892
  class DiagramPort extends DiagramElement {
3893
+ get type() {
3894
+ return this._type;
3895
+ }
3896
+ set type(type) {
3897
+ this._type = type;
3898
+ this.updateInView();
3899
+ }
3900
+ get typeString() {
3901
+ var _a;
3902
+ return (_a = this.type) === null || _a === undefined ? undefined : _a.id;
3903
+ }
3904
+ set typeString(typeString) {
3905
+ if (typeString === undefined) {
3906
+ this.type = undefined;
3907
+ } else {
3908
+ const type = this.model.ports.types.get(typeString);
3909
+ if (type) {
3910
+ this.type = type;
3911
+ }
3912
+ }
3913
+ }
3497
3914
  /**
3498
3915
  * Whether this port can be used as a connection start point.
3499
3916
  */
@@ -3521,10 +3938,67 @@ class DiagramPort extends DiagramElement {
3521
3938
  this.label.text = name;
3522
3939
  }
3523
3940
  }
3941
+ /**
3942
+ * Current look of this port.
3943
+ * @private
3944
+ */
3945
+ get look() {
3946
+ var _a, _b, _c, _d;
3947
+ if (this.selected) {
3948
+ if (this.highlighted) {
3949
+ return this._selectedAndHighlightedLook !== undefined ? this._selectedAndHighlightedLook : (_a = this.type || DIAGRAM_PORT_LOOKS) === null || _a === undefined ? undefined : _a.selectedAndHighlightedLook;
3950
+ } else {
3951
+ return this._selectedLook !== undefined ? this._selectedLook : (_b = this.type || DIAGRAM_PORT_LOOKS) === null || _b === undefined ? undefined : _b.selectedLook;
3952
+ }
3953
+ } else {
3954
+ if (this.highlighted) {
3955
+ return this._highlightedLook !== undefined ? this._highlightedLook : (_c = this.type || DIAGRAM_PORT_LOOKS) === null || _c === undefined ? undefined : _c.highlightedLook;
3956
+ } else {
3957
+ return this._defaultLook !== undefined ? this._defaultLook : (_d = this.type || DIAGRAM_PORT_LOOKS) === null || _d === undefined ? undefined : _d.defaultLook;
3958
+ }
3959
+ }
3960
+ }
3961
+ /**
3962
+ * Sets the look configuration of the look to override the one determined by the type.
3963
+ * `undefined` resets it to the one determined by the type.
3964
+ * @private
3965
+ */
3966
+ set look(look) {
3967
+ if (look) {
3968
+ const looks = extractLooksFromConfig(look);
3969
+ this._defaultLook = Object.assign(Object.assign({}, this._defaultLook), looks.defaultLook);
3970
+ this._selectedLook = Object.assign(Object.assign({}, this._selectedLook), looks.selectedLook);
3971
+ this._highlightedLook = Object.assign(Object.assign({}, this._highlightedLook), looks.highlightedLook);
3972
+ this._selectedAndHighlightedLook = Object.assign(Object.assign({}, this._selectedAndHighlightedLook), looks.selectedAndHighlightedLook);
3973
+ } else {
3974
+ this._defaultLook = look;
3975
+ this._selectedLook = look;
3976
+ this._highlightedLook = look;
3977
+ this._selectedAndHighlightedLook = look;
3978
+ }
3979
+ }
3980
+ /**
3981
+ * Current width of this port.
3982
+ * @private
3983
+ */
3984
+ get width() {
3985
+ var _a;
3986
+ return ((_a = this.type) === null || _a === undefined ? undefined : _a.width) || DIAGRAM_PORT_TYPE_DEFAULTS.width;
3987
+ }
3988
+ /**
3989
+ * Current height of this port. Same as the width.
3990
+ * @private
3991
+ */
3992
+ get height() {
3993
+ return this.width;
3994
+ }
3524
3995
  constructor(model, type, rootElement, coords, connectionPoint, direction, id) {
3525
3996
  if (model.ports.get(id) !== undefined) {
3526
3997
  throw new Error(`DiagramPort with id "${id}" already exists`);
3527
3998
  }
3999
+ if (!id) {
4000
+ throw new Error(`DiagramPort cannot have an empty or null id`);
4001
+ }
3528
4002
  super(model, id);
3529
4003
  /**
3530
4004
  * Connections that start at this port.
@@ -3536,7 +4010,7 @@ class DiagramPort extends DiagramElement {
3536
4010
  * @public
3537
4011
  */
3538
4012
  this.incomingConnections = [];
3539
- this.type = type;
4013
+ this._type = type;
3540
4014
  this.rootElement = rootElement;
3541
4015
  this.coords = coords;
3542
4016
  this.connectionPoint = connectionPoint || coords;
@@ -5127,7 +5601,10 @@ class DiagramHighlightedEvent extends DiagramEvent {
5127
5601
  class DiagramDecorator extends DiagramElement {
5128
5602
  constructor(model, rootElement, coords, width, height, priority, html, id) {
5129
5603
  if (model.objects.get(id) !== undefined) {
5130
- throw new Error(`DiagramObject with id "${id}" already exists`);
5604
+ throw new Error(`DiagramDecorator with id "${id}" already exists`);
5605
+ }
5606
+ if (!id) {
5607
+ throw new Error(`DiagramDecorator cannot have an empty or null id`);
5131
5608
  }
5132
5609
  super(model, id);
5133
5610
  this.rootElement = rootElement;
@@ -5137,10 +5614,6 @@ class DiagramDecorator extends DiagramElement {
5137
5614
  this.priority = priority;
5138
5615
  this.html = html;
5139
5616
  }
5140
- select() {
5141
- var _a, _b;
5142
- return (_b = (_a = this.model.canvas) === null || _a === undefined ? undefined : _a.selectCanvasView()) === null || _b === undefined ? undefined : _b.select(`foreignObject#${this.id}`);
5143
- }
5144
5617
  get removed() {
5145
5618
  return this.selfRemoved || this.rootElement !== undefined && this.rootElement.removed;
5146
5619
  }
@@ -5176,7 +5649,14 @@ class DiagramDecoratorSet extends DiagramElementSet {
5176
5649
  }
5177
5650
  /**
5178
5651
  * Instance a new decorator and add it to this set.
5179
- * @private
5652
+ * @public
5653
+ * @param coords The coordinates of the top left corner of the decorator in the diagram.
5654
+ * @param width The dimension of the decorator along the x axis.
5655
+ * @param height The dimension of the decorator along the y axis.
5656
+ * @param priority The priority of the decorator. Used when filtering by priority.
5657
+ * @param html The html contents of the decorator.
5658
+ * @param id The id of the decorator. Cannot be an empty string.
5659
+ * @returns The instanced decorator.
5180
5660
  */
5181
5661
  new(rootElement, coords, width, height, priority, html, id) {
5182
5662
  const decorator = new DiagramDecorator(this.model, rootElement, coords, width, height, priority, html, id);
@@ -5213,6 +5693,9 @@ class DiagramObject extends DiagramElement {
5213
5693
  if (model.objects.get(id) !== undefined) {
5214
5694
  throw new Error(`DiagramObject with id "${id}" already exists`);
5215
5695
  }
5696
+ if (!id) {
5697
+ throw new Error(`DiagramObject cannot have an empty or null id`);
5698
+ }
5216
5699
  super(model, id);
5217
5700
  this.coords = coords;
5218
5701
  this.width = width;
@@ -5220,10 +5703,6 @@ class DiagramObject extends DiagramElement {
5220
5703
  this.priority = priority;
5221
5704
  this.html = html;
5222
5705
  }
5223
- select() {
5224
- var _a, _b;
5225
- return (_b = (_a = this.model.canvas) === null || _a === undefined ? undefined : _a.selectCanvasView()) === null || _b === undefined ? undefined : _b.select(`foreignObject#${this.id}`);
5226
- }
5227
5706
  get removed() {
5228
5707
  return this.selfRemoved;
5229
5708
  }
@@ -5259,7 +5738,14 @@ class DiagramObjectSet extends DiagramElementSet {
5259
5738
  }
5260
5739
  /**
5261
5740
  * Instance a new object and add it to this set.
5262
- * @private
5741
+ * @public
5742
+ * @param coords The coordinates of the top left corner of the object in the diagram.
5743
+ * @param width The dimension of the object along the x axis.
5744
+ * @param height The dimension of the object along the y axis.
5745
+ * @param priority The priority of the object. Used when filtering by priority.
5746
+ * @param html The html contents of the object.
5747
+ * @param id The id of the object. Cannot be an empty string.
5748
+ * @returns The instanced object.
5263
5749
  */
5264
5750
  new(coords, width, height, priority, html, id) {
5265
5751
  const object = new DiagramObject(this.model, coords, width, height, priority, html, id);
@@ -5362,11 +5848,76 @@ class DiagramModel {
5362
5848
  }
5363
5849
  }
5364
5850
 
5851
+ /**
5852
+ * Checks if the given mouse event was produced with a secondary button press.
5853
+ * @private
5854
+ * @param event A mouse event.
5855
+ * @returns `true` if the given mouse event was produced with a secondary button press, `false` otherwise.
5856
+ */
5857
+ const isSecondaryButton = event => {
5858
+ return !!event.button;
5859
+ };
5860
+ /**
5861
+ * Get the SVG path of a diagram connection.
5862
+ * @private
5863
+ * @see linePath
5864
+ */
5865
+ const getConnectionPath = (shape, startCoords, endCoords, startDirection, endDirection, width, startMarkerWidth, endMarkerWidth) => {
5866
+ return linePath(shape, [startCoords, endCoords], startDirection, endDirection, Math.max(
5867
+ // reasonable value for the minimumDistanceBeforeTurn relative to the line width
5868
+ 10, startMarkerWidth || 0, endMarkerWidth || 0) * width);
5869
+ };
5870
+ const setCursorStyle = style => {
5871
+ if (!style) {
5872
+ d3.select('body').style('cursor', CursorStyle.Auto);
5873
+ } else {
5874
+ d3.select('body').style('cursor', style);
5875
+ }
5876
+ };
5877
+ const getRelatedNodeOrItself = element => {
5878
+ if (element instanceof DiagramNode) {
5879
+ return element;
5880
+ }
5881
+ if (element instanceof DiagramSection) {
5882
+ return element.node || element;
5883
+ }
5884
+ return element.rootElement instanceof DiagramNode || element.rootElement instanceof DiagramSection || element.rootElement instanceof DiagramPort ? getRelatedNodeOrItself(element.rootElement) : element;
5885
+ };
5886
+ const initializeLook = selection => {
5887
+ selection.filter('.shaped-look').append('path');
5888
+ selection.filter('.image-look').append('image').attr('preserveAspectRatio', 'none');
5889
+ selection.filter('.stretchable-image-look').append('image').attr('class', 'top-left-image').attr('preserveAspectRatio', 'none');
5890
+ selection.filter('.stretchable-image-look').append('image').attr('class', 'top-image').attr('preserveAspectRatio', 'none');
5891
+ selection.filter('.stretchable-image-look').append('image').attr('class', 'top-right-image').attr('preserveAspectRatio', 'none');
5892
+ selection.filter('.stretchable-image-look').append('image').attr('class', 'left-image').attr('preserveAspectRatio', 'none');
5893
+ selection.filter('.stretchable-image-look').append('image').attr('class', 'center-image').attr('preserveAspectRatio', 'none');
5894
+ selection.filter('.stretchable-image-look').append('image').attr('class', 'right-image').attr('preserveAspectRatio', 'none');
5895
+ selection.filter('.stretchable-image-look').append('image').attr('class', 'bottom-left-image').attr('preserveAspectRatio', 'none');
5896
+ selection.filter('.stretchable-image-look').append('image').attr('class', 'bottom-image').attr('preserveAspectRatio', 'none');
5897
+ selection.filter('.stretchable-image-look').append('image').attr('class', 'bottom-right-image').attr('preserveAspectRatio', 'none');
5898
+ };
5899
+ const updateLook = selection => {
5900
+ selection.filter('.shaped-look').select('path').attr('d', d => generalClosedPath(d.look.shape, 0, 0, d.width, d.height)).attr('fill', d => d.look.fillColor).attr('stroke', d => d.look.borderColor).attr('stroke-width', d => `${d.look.borderThickness}px`);
5901
+ selection.filter('.image-look').select('image').attr('x', 0).attr('y', 0).attr('width', d => d.width).attr('height', d => d.height).attr('href', d => d.look.backgroundImage);
5902
+ selection.filter('.stretchable-image-look').select('image.top-left-image').attr('x', 0).attr('y', 0).attr('width', d => d.look.leftMargin).attr('height', d => d.look.topMargin).attr('href', d => d.look.backgroundImageTopLeft);
5903
+ selection.filter('.stretchable-image-look').select('image.top-image').attr('x', d => d.look.leftMargin).attr('y', 0).attr('width', d => d.width - d.look.rightMargin - d.look.leftMargin).attr('height', d => d.look.topMargin).attr('href', d => d.look.backgroundImageTop);
5904
+ selection.filter('.stretchable-image-look').select('image.top-right-image').attr('x', d => d.width - d.look.rightMargin).attr('y', 0).attr('width', d => d.look.rightMargin).attr('height', d => d.look.topMargin).attr('href', d => d.look.backgroundImageTopRight);
5905
+ selection.filter('.stretchable-image-look').select('image.left-image').attr('x', 0).attr('y', d => d.look.topMargin).attr('width', d => d.look.leftMargin).attr('height', d => d.height - d.look.bottomMargin - d.look.topMargin).attr('href', d => d.look.backgroundImageLeft);
5906
+ selection.filter('.stretchable-image-look').select('image.center-image').attr('x', d => d.look.leftMargin).attr('y', d => d.look.topMargin).attr('width', d => d.width - d.look.rightMargin - d.look.leftMargin).attr('height', d => d.height - d.look.bottomMargin - d.look.topMargin).attr('href', d => d.look.backgroundImageCenter);
5907
+ selection.filter('.stretchable-image-look').select('image.right-image').attr('x', d => d.width - d.look.rightMargin).attr('y', d => d.look.topMargin).attr('width', d => d.look.rightMargin).attr('height', d => d.height - d.look.bottomMargin - d.look.topMargin).attr('href', d => d.look.backgroundImageRight);
5908
+ selection.filter('.stretchable-image-look').select('image.bottom-left-image').attr('x', 0).attr('y', d => d.height - d.look.bottomMargin).attr('width', d => d.look.leftMargin).attr('height', d => d.look.bottomMargin).attr('href', d => d.look.backgroundImageBottomLeft);
5909
+ selection.filter('.stretchable-image-look').select('image.bottom-image').attr('x', d => d.look.leftMargin).attr('y', d => d.height - d.look.bottomMargin).attr('width', d => d.width - d.look.rightMargin - d.look.leftMargin).attr('height', d => d.look.bottomMargin).attr('href', d => d.look.backgroundImageBottom);
5910
+ selection.filter('.stretchable-image-look').select('image.bottom-right-image').attr('x', d => d.width - d.look.rightMargin).attr('y', d => d.height - d.look.bottomMargin).attr('width', d => d.look.rightMargin).attr('height', d => d.look.bottomMargin).attr('href', d => d.look.backgroundImageBottomRight);
5911
+ };
5912
+
5365
5913
  const CONTEXT_MENU_MENU_RADIUS = 96;
5366
5914
  const CONTEXT_MENU_BUTTON_RADIUS = 32;
5367
5915
  const CONTEXT_MENU_TOTAL_RADIUS = CONTEXT_MENU_MENU_RADIUS + CONTEXT_MENU_BUTTON_RADIUS;
5368
5916
  const CONTEXT_MENU_BUTTON_PADDING_RADIANS = Math.PI / 4;
5369
5917
  const CONTEXT_MENU_ANIMATION_DURATION_MS = 100;
5918
+ const CONTEXT_MENU_DEFAULTS = {
5919
+ customButtons: []
5920
+ };
5370
5921
  /**
5371
5922
  * Stores the functionality regarding the context menu of a diagram canvas.
5372
5923
  * @public
@@ -5378,8 +5929,9 @@ class DiagramContextMenu {
5378
5929
  * @public
5379
5930
  * @param canvas A canvas.
5380
5931
  */
5381
- constructor(canvas) {
5932
+ constructor(canvas, config) {
5382
5933
  this.canvas = canvas;
5934
+ this.config = config || CONTEXT_MENU_DEFAULTS;
5383
5935
  }
5384
5936
  /**
5385
5937
  * Opens the context menu at the location determined by the given mouse event.
@@ -5406,10 +5958,9 @@ class DiagramContextMenu {
5406
5958
  buttons.push({
5407
5959
  name: 'CUT',
5408
5960
  imageClass: 'daga-cut',
5409
- onPress: buttonPressEvent => {
5410
- buttonPressEvent.preventDefault();
5411
- this.canvas.userSelection.cutToClipboard();
5412
- this.canvas.cancelAllUserActions();
5961
+ onPress: canvas => {
5962
+ canvas.userSelection.cutToClipboard();
5963
+ canvas.cancelAllUserActions();
5413
5964
  }
5414
5965
  });
5415
5966
  }
@@ -5417,10 +5968,9 @@ class DiagramContextMenu {
5417
5968
  buttons.push({
5418
5969
  name: 'COPY',
5419
5970
  imageClass: 'daga-copy',
5420
- onPress: buttonPressEvent => {
5421
- buttonPressEvent.preventDefault();
5422
- this.canvas.userSelection.copyToClipboard();
5423
- this.canvas.cancelAllUserActions();
5971
+ onPress: canvas => {
5972
+ canvas.userSelection.copyToClipboard();
5973
+ canvas.cancelAllUserActions();
5424
5974
  }
5425
5975
  });
5426
5976
  }
@@ -5428,10 +5978,9 @@ class DiagramContextMenu {
5428
5978
  buttons.push({
5429
5979
  name: 'PASTE',
5430
5980
  imageClass: 'daga-paste',
5431
- onPress: buttonPressEvent => {
5432
- buttonPressEvent.preventDefault();
5433
- this.canvas.userSelection.pasteFromClipboard(this.canvas.getClosestGridPoint(coordsRelativeToCanvas));
5434
- this.canvas.cancelAllUserActions();
5981
+ onPress: canvas => {
5982
+ canvas.userSelection.pasteFromClipboard(canvas.getClosestGridPoint(coordsRelativeToCanvas));
5983
+ canvas.cancelAllUserActions();
5435
5984
  }
5436
5985
  });
5437
5986
  }
@@ -5439,13 +5988,17 @@ class DiagramContextMenu {
5439
5988
  buttons.push({
5440
5989
  name: 'DELETE',
5441
5990
  imageClass: 'daga-delete',
5442
- onPress: buttonPressEvent => {
5443
- buttonPressEvent.preventDefault();
5444
- this.canvas.userSelection.removeFromModel();
5445
- this.canvas.cancelAllUserActions();
5991
+ onPress: canvas => {
5992
+ canvas.userSelection.removeFromModel();
5993
+ canvas.cancelAllUserActions();
5446
5994
  }
5447
5995
  });
5448
5996
  }
5997
+ for (const customButton of this.config.customButtons || CONTEXT_MENU_DEFAULTS.customButtons) {
5998
+ if (customButton.condition !== undefined ? customButton.condition(this.canvas) : true) {
5999
+ buttons.push(customButton);
6000
+ }
6001
+ }
5449
6002
  // show something if there are no options available
5450
6003
  if (buttons.length === 0) {
5451
6004
  buttons.push({
@@ -5458,20 +6011,22 @@ class DiagramContextMenu {
5458
6011
  const button = buttons[i];
5459
6012
  const buttonOnPress = button.onPress;
5460
6013
  const angle = (i + 0.5 - buttons.length / 2) * CONTEXT_MENU_BUTTON_PADDING_RADIANS;
5461
- const buttonContainer = contextMenuContainer.append('xhtml:div').attr('class', `daga-context-menu-button ${button.imageClass}-button${button.onPress != undefined ? ' daga-clickable' : ''}`).attr('tabindex', 0).style('position', 'absolute').style('box-sizing', 'border-box').style('width', `${2 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('height', `${2 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('border-radius', `${CONTEXT_MENU_BUTTON_RADIUS}px`).style('pointer-events', 'auto')
5462
- // eslint-disable-next-line @typescript-eslint/no-empty-function
5463
- .on(Events.Click, event => {
6014
+ const buttonContainer = contextMenuContainer.append('xhtml:div').attr('class', `daga-context-menu-button ${button.onPress !== undefined ? ' daga-clickable' : ''}`).attr('tabindex', 0).style('position', 'absolute').style('box-sizing', 'border-box').style('width', `${2 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('height', `${2 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('border-radius', `${CONTEXT_MENU_BUTTON_RADIUS}px`).style('pointer-events', 'auto').on(Events.Click, event => {
5464
6015
  if (buttonOnPress) {
5465
- buttonOnPress(event);
6016
+ event.preventDefault();
6017
+ buttonOnPress(this.canvas);
5466
6018
  }
5467
- })
5468
- // eslint-disable-next-line @typescript-eslint/no-empty-function
5469
- .on(Events.KeyDown, event => {
6019
+ }).on(Events.KeyDown, event => {
5470
6020
  if (buttonOnPress && event.key === Keys.Enter) {
5471
- buttonOnPress(event);
6021
+ event.preventDefault();
6022
+ buttonOnPress(this.canvas);
5472
6023
  }
5473
6024
  });
5474
- buttonContainer.append('xhtml:div').style('position', 'absolute').style('left', `${0.75 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('top', `${0.5 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('width', `${0.5 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('height', `${0.5 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('background-size', 'contain').style('background-repeat', 'no-repeat').attr('class', button.imageClass);
6025
+ if (button.imageClass !== undefined) {
6026
+ buttonContainer.append('xhtml:div').style('position', 'absolute').style('left', `${0.75 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('top', `${0.5 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('width', `${0.5 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('height', `${0.5 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('background-size', 'contain').style('background-repeat', 'no-repeat').attr('class', button.imageClass);
6027
+ } else if (button.image !== undefined) {
6028
+ buttonContainer.append('xhtml:img').style('position', 'absolute').style('left', `${0.75 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('top', `${0.5 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('width', `${0.5 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('height', `${0.5 * CONTEXT_MENU_BUTTON_RADIUS}px`).attr('src', button.image);
6029
+ }
5475
6030
  buttonContainer.append('xhtml:span').style('position', 'absolute').style('left', `${0.2 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('top', `${1.1 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('text-align', 'center').style('width', `${1.6 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('height', `${0.35 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('margin', '0').style('font-size', `${0.35 * CONTEXT_MENU_BUTTON_RADIUS}px`).style('font-weight', '700').style('user-select', 'none').text(button.name);
5476
6031
  buttonContainer.transition().ease(d3.easeLinear).duration(CONTEXT_MENU_ANIMATION_DURATION_MS).tween('progress', () => {
5477
6032
  return value => {
@@ -5956,7 +6511,7 @@ class DiagramUserSelection extends DiagramElementSet {
5956
6511
  }
5957
6512
  }
5958
6513
  makeUpdateValuesAction() {
5959
- var _a, _b;
6514
+ var _a, _b, _c;
5960
6515
  if (this.propertyEditorSelection === undefined || this.propertyEditorValues === undefined) {
5961
6516
  return;
5962
6517
  }
@@ -5968,7 +6523,7 @@ class DiagramUserSelection extends DiagramElementSet {
5968
6523
  }
5969
6524
  const from = this.propertyEditorValues;
5970
6525
  const to = structuredClone((_b = this.propertyEditorSelection) === null || _b === undefined ? undefined : _b.valueSet.getValues());
5971
- const [fromDiff, toDiff] = diff(from, to);
6526
+ const [fromDiff, toDiff] = diffProperties(from, to, (_c = this.propertyEditorSelection) === null || _c === undefined ? undefined : _c.valueSet);
5972
6527
  const currentAction = new UpdateValuesAction(this.canvas, previousSelectionId, fromDiff, toDiff);
5973
6528
  currentAction.do();
5974
6529
  this.canvas.actionStack.add(currentAction);
@@ -6011,7 +6566,7 @@ class DiagramCanvas {
6011
6566
  * @param config The configuration object used to set the parameters of this canvas.
6012
6567
  */
6013
6568
  constructor(parentComponent, config) {
6014
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
6569
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
6015
6570
  this.backgroundPatternId = `daga-background-pattern-id-${DiagramCanvas.canvasCount++}`;
6016
6571
  this.zoomTransform = d3.zoomIdentity;
6017
6572
  // used to distinguish drags from clicks when dragging elements and during multiple selection
@@ -6028,17 +6583,17 @@ class DiagramCanvas {
6028
6583
  this.model = new DiagramModel(this, undefined, config.name || 'unnamed', '', config.type || '', config.properties || []);
6029
6584
  this.userSelection = new DiagramUserSelection(this);
6030
6585
  this.userHighlight = new DiagramUserHighlight(this);
6031
- this.contextMenu = new DiagramContextMenu(this);
6032
- this.backgroundColor = ((_a = config.canvas) === null || _a === undefined ? undefined : _a.backgroundColor) || '#FFFFFF';
6033
- this.gridSize = ((_c = (_b = config.canvas) === null || _b === undefined ? undefined : _b.grid) === null || _c === undefined ? undefined : _c.enabled) === false || ((_d = config.canvas) === null || _d === undefined ? undefined : _d.grid) === undefined ? 0 : Math.abs(((_f = (_e = config.canvas) === null || _e === undefined ? undefined : _e.grid) === null || _f === undefined ? undefined : _f.spacing) || 10);
6034
- this.gridThickness = Math.abs(((_h = (_g = config.canvas) === null || _g === undefined ? undefined : _g.grid) === null || _h === undefined ? undefined : _h.thickness) || 0.05);
6035
- this.gridColor = ((_k = (_j = config.canvas) === null || _j === undefined ? undefined : _j.grid) === null || _k === undefined ? undefined : _k.color) || 'rgba(0, 0, 0, 0.1)';
6036
- this.snapToGrid = ((_m = (_l = config.canvas) === null || _l === undefined ? undefined : _l.grid) === null || _m === undefined ? undefined : _m.enabled) === false || ((_o = config.canvas) === null || _o === undefined ? undefined : _o.grid) === undefined ? false : ((_q = (_p = config.canvas) === null || _p === undefined ? undefined : _p.grid) === null || _q === undefined ? undefined : _q.snap) || false;
6037
- this.zoomFactor = ((_r = config.canvas) === null || _r === undefined ? undefined : _r.zoomFactor) || 2;
6038
- this.panRate = ((_s = config.canvas) === null || _s === undefined ? undefined : _s.panRate) || 100;
6586
+ this.contextMenu = new DiagramContextMenu(this, (_a = config.canvas) === null || _a === undefined ? undefined : _a.contextMenu);
6587
+ this.backgroundColor = ((_b = config.canvas) === null || _b === undefined ? undefined : _b.backgroundColor) || '#FFFFFF';
6588
+ this.gridSize = ((_d = (_c = config.canvas) === null || _c === undefined ? undefined : _c.grid) === null || _d === undefined ? undefined : _d.enabled) === false || ((_e = config.canvas) === null || _e === undefined ? undefined : _e.grid) === undefined ? 0 : Math.abs(((_g = (_f = config.canvas) === null || _f === undefined ? undefined : _f.grid) === null || _g === undefined ? undefined : _g.spacing) || 10);
6589
+ this.gridThickness = Math.abs(((_j = (_h = config.canvas) === null || _h === undefined ? undefined : _h.grid) === null || _j === undefined ? undefined : _j.thickness) || 0.05);
6590
+ this.gridColor = ((_l = (_k = config.canvas) === null || _k === undefined ? undefined : _k.grid) === null || _l === undefined ? undefined : _l.color) || 'rgba(0, 0, 0, 0.1)';
6591
+ this.snapToGrid = ((_o = (_m = config.canvas) === null || _m === undefined ? undefined : _m.grid) === null || _o === undefined ? undefined : _o.enabled) === false || ((_p = config.canvas) === null || _p === undefined ? undefined : _p.grid) === undefined ? false : ((_r = (_q = config.canvas) === null || _q === undefined ? undefined : _q.grid) === null || _r === undefined ? undefined : _r.snap) || false;
6592
+ this.zoomFactor = ((_s = config.canvas) === null || _s === undefined ? undefined : _s.zoomFactor) || 2;
6593
+ this.panRate = ((_t = config.canvas) === null || _t === undefined ? undefined : _t.panRate) || 100;
6039
6594
  this.inferConnectionType = config.inferConnectionType || false;
6040
6595
  this.multipleSelectionOn = false;
6041
- this.priorityThresholds = ((_t = config.canvas) === null || _t === undefined ? undefined : _t.priorityThresholds) || [];
6596
+ this.priorityThresholds = ((_u = config.canvas) === null || _u === undefined ? undefined : _u.priorityThresholds) || [];
6042
6597
  this.priorityThreshold = this.priorityThresholds ? this.priorityThresholds[0] : undefined;
6043
6598
  this.layoutFormat = config.layoutFormat;
6044
6599
  this.userActions = config.userActions || {};
@@ -6391,7 +6946,7 @@ class DiagramCanvas {
6391
6946
  updateNodesInView(...ids) {
6392
6947
  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);
6393
6948
  const exitSelection = updateSelection.exit();
6394
- 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.look.lookType}`);
6949
+ 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}`);
6395
6950
  if (ids && ids.length > 0) {
6396
6951
  updateSelection = updateSelection.filter(d => ids.includes(d.id));
6397
6952
  }
@@ -6453,17 +7008,7 @@ class DiagramCanvas {
6453
7008
  }
6454
7009
  this.secondaryButton = false;
6455
7010
  }));
6456
- enterSelection.filter('.shaped-look').append('path');
6457
- enterSelection.filter('.image-look').append('image').attr('preserveAspectRatio', 'none');
6458
- enterSelection.filter('.stretchable-image-look').append('image').attr('class', 'top-left-image').attr('preserveAspectRatio', 'none');
6459
- enterSelection.filter('.stretchable-image-look').append('image').attr('class', 'top-image').attr('preserveAspectRatio', 'none');
6460
- enterSelection.filter('.stretchable-image-look').append('image').attr('class', 'top-right-image').attr('preserveAspectRatio', 'none');
6461
- enterSelection.filter('.stretchable-image-look').append('image').attr('class', 'left-image').attr('preserveAspectRatio', 'none');
6462
- enterSelection.filter('.stretchable-image-look').append('image').attr('class', 'center-image').attr('preserveAspectRatio', 'none');
6463
- enterSelection.filter('.stretchable-image-look').append('image').attr('class', 'right-image').attr('preserveAspectRatio', 'none');
6464
- enterSelection.filter('.stretchable-image-look').append('image').attr('class', 'bottom-left-image').attr('preserveAspectRatio', 'none');
6465
- enterSelection.filter('.stretchable-image-look').append('image').attr('class', 'bottom-image').attr('preserveAspectRatio', 'none');
6466
- enterSelection.filter('.stretchable-image-look').append('image').attr('class', 'bottom-right-image').attr('preserveAspectRatio', 'none');
7011
+ initializeLook(enterSelection);
6467
7012
  enterSelection.filter('.resizable-x').append('line').attr('class', 'left-resizer').attr('stroke', 'transparent').attr('stroke-width', `${RESIZER_THICKNESS}px`).on(Events.MouseOver, (_event, d) => {
6468
7013
  if (this.canUserPerformAction(DiagramActions.StretchNode) && d.type.resizableX && !d.removed) {
6469
7014
  setCursorStyle(CursorStyle.EWResize);
@@ -6601,17 +7146,7 @@ class DiagramCanvas {
6601
7146
  setCursorStyle();
6602
7147
  }));
6603
7148
  mergeSelection.attr('transform', d => `translate(${d.coords[0]},${d.coords[1]})`).attr('opacity', d => d.removed ? 0.5 : 1);
6604
- mergeSelection.filter('.shaped-look').select('path').attr('d', d => generalClosedPath(d.type.look.shape, 0, 0, d.width, d.height)).attr('fill', d => d.selected ? d.type.look.selectedFillColor : d.type.look.fillColor).attr('stroke', d => d.selected ? d.type.look.selectedBorderColor : d.type.look.borderColor).attr('stroke-width', d => `${d.highlighted ? 3 : 1}px`);
6605
- mergeSelection.filter('.image-look').select('image').attr('x', 0).attr('y', 0).attr('width', d => d.width).attr('height', d => d.height).attr('href', d => d.selected ? d.type.look.selectedBackgroundImage : d.type.look.backgroundImage);
6606
- mergeSelection.filter('.stretchable-image-look').select('image.top-left-image').attr('x', 0).attr('y', 0).attr('width', d => d.type.look.leftMargin).attr('height', d => d.type.look.topMargin).attr('href', d => d.selected ? d.type.look.selectedBackgroundImageTopLeft : d.type.look.backgroundImageTopLeft);
6607
- mergeSelection.filter('.stretchable-image-look').select('image.top-image').attr('x', d => d.type.look.leftMargin).attr('y', 0).attr('width', d => d.width - d.type.look.rightMargin - d.type.look.leftMargin).attr('height', d => d.type.look.topMargin).attr('href', d => d.selected ? d.type.look.selectedBackgroundImageTop : d.type.look.backgroundImageTop);
6608
- mergeSelection.filter('.stretchable-image-look').select('image.top-right-image').attr('x', d => d.width - d.type.look.rightMargin).attr('y', 0).attr('width', d => d.type.look.rightMargin).attr('height', d => d.type.look.topMargin).attr('href', d => d.selected ? d.type.look.selectedBackgroundImageTopRight : d.type.look.backgroundImageTopRight);
6609
- mergeSelection.filter('.stretchable-image-look').select('image.left-image').attr('x', 0).attr('y', d => d.type.look.topMargin).attr('width', d => d.type.look.leftMargin).attr('height', d => d.height - d.type.look.bottomMargin - d.type.look.topMargin).attr('href', d => d.selected ? d.type.look.selectedBackgroundImageLeft : d.type.look.backgroundImageLeft);
6610
- mergeSelection.filter('.stretchable-image-look').select('image.center-image').attr('x', d => d.type.look.leftMargin).attr('y', d => d.type.look.topMargin).attr('width', d => d.width - d.type.look.rightMargin - d.type.look.leftMargin).attr('height', d => d.height - d.type.look.bottomMargin - d.type.look.topMargin).attr('href', d => d.selected ? d.type.look.selectedBackgroundImageCenter : d.type.look.backgroundImageCenter);
6611
- mergeSelection.filter('.stretchable-image-look').select('image.right-image').attr('x', d => d.width - d.type.look.rightMargin).attr('y', d => d.type.look.topMargin).attr('width', d => d.type.look.rightMargin).attr('height', d => d.height - d.type.look.bottomMargin - d.type.look.topMargin).attr('href', d => d.selected ? d.type.look.selectedBackgroundImageRight : d.type.look.backgroundImageRight);
6612
- mergeSelection.filter('.stretchable-image-look').select('image.bottom-left-image').attr('x', 0).attr('y', d => d.height - d.type.look.bottomMargin).attr('width', d => d.type.look.leftMargin).attr('height', d => d.type.look.bottomMargin).attr('href', d => d.selected ? d.type.look.selectedBackgroundImageBottomLeft : d.type.look.backgroundImageBottomLeft);
6613
- mergeSelection.filter('.stretchable-image-look').select('image.bottom-image').attr('x', d => d.type.look.leftMargin).attr('y', d => d.height - d.type.look.bottomMargin).attr('width', d => d.width - d.type.look.rightMargin - d.type.look.leftMargin).attr('height', d => d.type.look.bottomMargin).attr('href', d => d.selected ? d.type.look.selectedBackgroundImageBottom : d.type.look.backgroundImageBottom);
6614
- mergeSelection.filter('.stretchable-image-look').select('image.bottom-right-image').attr('x', d => d.width - d.type.look.rightMargin).attr('y', d => d.height - d.type.look.bottomMargin).attr('width', d => d.type.look.rightMargin).attr('height', d => d.type.look.bottomMargin).attr('href', d => d.selected ? d.type.look.selectedBackgroundImageBottomRight : d.type.look.backgroundImageBottomRight);
7149
+ updateLook(mergeSelection);
6615
7150
  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);
6616
7151
  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);
6617
7152
  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);
@@ -6621,8 +7156,8 @@ class DiagramCanvas {
6621
7156
  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);
6622
7157
  const exitSelection = updateSelection.exit();
6623
7158
  const enterSelection = updateSelection.enter().append('g').attr('id', d => d.id).attr('class', d => {
6624
- var _a, _b, _c, _d, _e, _f;
6625
- return `diagram-section${((_b = (_a = d.node) === null || _a === undefined ? undefined : _a.type) === null || _b === undefined ? undefined : _b.resizableX) ? ' resizable-x' : ''}${((_d = (_c = d.node) === null || _c === undefined ? undefined : _c.type) === null || _d === undefined ? undefined : _d.resizableY) ? ' resizable-y' : ''} ${(_f = (_e = d.getConfig()) === null || _e === undefined ? undefined : _e.look) === null || _f === undefined ? undefined : _f.lookType}`;
7159
+ var _a, _b, _c, _d, _e;
7160
+ return `diagram-section${((_b = (_a = d.node) === null || _a === undefined ? undefined : _a.type) === null || _b === undefined ? undefined : _b.resizableX) ? ' resizable-x' : ''}${((_d = (_c = d.node) === null || _c === undefined ? undefined : _c.type) === null || _d === undefined ? undefined : _d.resizableY) ? ' resizable-y' : ''} ${(_e = d.look) === null || _e === undefined ? undefined : _e.lookType}`;
6626
7161
  });
6627
7162
  if (ids && ids.length > 0) {
6628
7163
  updateSelection = updateSelection.filter(d => ids.includes(d.id));
@@ -6702,17 +7237,7 @@ class DiagramCanvas {
6702
7237
  }
6703
7238
  this.secondaryButton = false;
6704
7239
  }));
6705
- enterSelection.filter('.shaped-look').append('path');
6706
- enterSelection.filter('.image-look').append('image').attr('preserveAspectRatio', 'none');
6707
- enterSelection.filter('.stretchable-image-look').append('image').attr('class', 'top-left-image').attr('preserveAspectRatio', 'none');
6708
- enterSelection.filter('.stretchable-image-look').append('image').attr('class', 'top-image').attr('preserveAspectRatio', 'none');
6709
- enterSelection.filter('.stretchable-image-look').append('image').attr('class', 'top-right-image').attr('preserveAspectRatio', 'none');
6710
- enterSelection.filter('.stretchable-image-look').append('image').attr('class', 'left-image').attr('preserveAspectRatio', 'none');
6711
- enterSelection.filter('.stretchable-image-look').append('image').attr('class', 'center-image').attr('preserveAspectRatio', 'none');
6712
- enterSelection.filter('.stretchable-image-look').append('image').attr('class', 'right-image').attr('preserveAspectRatio', 'none');
6713
- enterSelection.filter('.stretchable-image-look').append('image').attr('class', 'bottom-left-image').attr('preserveAspectRatio', 'none');
6714
- enterSelection.filter('.stretchable-image-look').append('image').attr('class', 'bottom-image').attr('preserveAspectRatio', 'none');
6715
- enterSelection.filter('.stretchable-image-look').append('image').attr('class', 'bottom-right-image').attr('preserveAspectRatio', 'none');
7240
+ initializeLook(enterSelection);
6716
7241
  enterSelection.filter('.resizable-x').append('line').attr('class', 'left-resizer').attr('stroke', 'transparent').attr('stroke-width', `${RESIZER_THICKNESS}px`).on(Events.MouseOver, (_event, d) => {
6717
7242
  var _a, _b;
6718
7243
  if (this.canUserPerformAction(DiagramActions.StretchSection) && ((_b = (_a = d.node) === null || _a === undefined ? undefined : _a.type) === null || _b === undefined ? undefined : _b.resizableX) && !d.removed) {
@@ -6870,146 +7395,7 @@ class DiagramCanvas {
6870
7395
  setCursorStyle();
6871
7396
  }));
6872
7397
  mergeSelection.attr('transform', d => `translate(${d.coords[0]},${d.coords[1]})`).attr('opacity', d => d.removed ? 0.5 : 1);
6873
- mergeSelection.filter('.shaped-look').select('path').attr('d', d => {
6874
- var _a;
6875
- return generalClosedPath(((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).shape, 0, 0, d.width, d.height);
6876
- }).attr('fill', d => {
6877
- var _a, _b;
6878
- return d.selected ? ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).selectedFillColor : ((_b = d.getConfig()) === null || _b === undefined ? undefined : _b.look).fillColor;
6879
- }).attr('stroke', d => {
6880
- var _a, _b;
6881
- return d.selected ? ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).selectedBorderColor : ((_b = d.getConfig()) === null || _b === undefined ? undefined : _b.look).borderColor;
6882
- }).attr('stroke-width', d => `${d.highlighted ? 3 : 1}px`);
6883
- mergeSelection.filter('.image-look').select('image').attr('x', 0).attr('y', 0).attr('width', d => d.width).attr('height', d => d.height).attr('href', d => {
6884
- var _a, _b;
6885
- return d.selected ? ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).selectedBackgroundImage : ((_b = d.getConfig()) === null || _b === undefined ? undefined : _b.look).backgroundImage;
6886
- });
6887
- mergeSelection.filter('.stretchable-image-look').select('image.top-left-image').attr('x', 0).attr('y', 0).attr('width', d => {
6888
- var _a;
6889
- return ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).leftMargin;
6890
- }).attr('height', d => {
6891
- var _a;
6892
- return ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).topMargin;
6893
- }).attr('href', d => {
6894
- var _a, _b;
6895
- return d.selected ? ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).selectedBackgroundImageTopLeft : ((_b = d.getConfig()) === null || _b === undefined ? undefined : _b.look).backgroundImageTopLeft;
6896
- });
6897
- mergeSelection.filter('.stretchable-image-look').select('image.top-image').attr('x', d => {
6898
- var _a;
6899
- return ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).leftMargin;
6900
- }).attr('y', 0).attr('width', d => {
6901
- var _a, _b;
6902
- return d.width - ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).rightMargin - ((_b = d.getConfig()) === null || _b === undefined ? undefined : _b.look).leftMargin;
6903
- }).attr('height', d => {
6904
- var _a;
6905
- return ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).topMargin;
6906
- }).attr('href', d => {
6907
- var _a, _b;
6908
- return d.selected ? ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).selectedBackgroundImageTop : ((_b = d.getConfig()) === null || _b === undefined ? undefined : _b.look).backgroundImageTop;
6909
- });
6910
- mergeSelection.filter('.stretchable-image-look').select('image.top-right-image').attr('x', d => {
6911
- var _a;
6912
- return d.width - ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).rightMargin;
6913
- }).attr('y', 0).attr('width', d => {
6914
- var _a;
6915
- return ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).rightMargin;
6916
- }).attr('height', d => {
6917
- var _a;
6918
- return ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).topMargin;
6919
- }).attr('href', d => {
6920
- var _a, _b;
6921
- return d.selected ? ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).selectedBackgroundImageTopRight : ((_b = d.getConfig()) === null || _b === undefined ? undefined : _b.look).backgroundImageTopRight;
6922
- });
6923
- mergeSelection.filter('.stretchable-image-look').select('image.left-image').attr('x', 0).attr('y', d => {
6924
- var _a;
6925
- return ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).topMargin;
6926
- }).attr('width', d => {
6927
- var _a;
6928
- return ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).leftMargin;
6929
- }).attr('height', d => {
6930
- var _a, _b;
6931
- return d.height - ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).bottomMargin - ((_b = d.getConfig()) === null || _b === undefined ? undefined : _b.look).topMargin;
6932
- }).attr('href', d => {
6933
- var _a, _b;
6934
- return d.selected ? ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).selectedBackgroundImageLeft : ((_b = d.getConfig()) === null || _b === undefined ? undefined : _b.look).backgroundImageLeft;
6935
- });
6936
- mergeSelection.filter('.stretchable-image-look').select('image.center-image').attr('x', d => {
6937
- var _a;
6938
- return ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).leftMargin;
6939
- }).attr('y', d => {
6940
- var _a;
6941
- return ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).topMargin;
6942
- }).attr('width', d => {
6943
- var _a, _b;
6944
- return d.width - ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).rightMargin - ((_b = d.getConfig()) === null || _b === undefined ? undefined : _b.look).leftMargin;
6945
- }).attr('height', d => {
6946
- var _a, _b;
6947
- return d.height - ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).bottomMargin - ((_b = d.getConfig()) === null || _b === undefined ? undefined : _b.look).topMargin;
6948
- }).attr('href', d => {
6949
- var _a, _b;
6950
- return d.selected ? ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).selectedBackgroundImageCenter : ((_b = d.getConfig()) === null || _b === undefined ? undefined : _b.look).backgroundImageCenter;
6951
- });
6952
- mergeSelection.filter('.stretchable-image-look').select('image.right-image').attr('x', d => {
6953
- var _a;
6954
- return d.width - ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).rightMargin;
6955
- }).attr('y', d => {
6956
- var _a;
6957
- return ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).topMargin;
6958
- }).attr('width', d => {
6959
- var _a;
6960
- return ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).rightMargin;
6961
- }).attr('height', d => {
6962
- var _a, _b;
6963
- return d.height - ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).bottomMargin - ((_b = d.getConfig()) === null || _b === undefined ? undefined : _b.look).topMargin;
6964
- }).attr('href', d => {
6965
- var _a, _b;
6966
- return d.selected ? ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).selectedBackgroundImageRight : ((_b = d.getConfig()) === null || _b === undefined ? undefined : _b.look).backgroundImageRight;
6967
- });
6968
- mergeSelection.filter('.stretchable-image-look').select('image.bottom-left-image').attr('x', 0).attr('y', d => {
6969
- var _a;
6970
- return d.height - ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).bottomMargin;
6971
- }).attr('width', d => {
6972
- var _a;
6973
- return ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).leftMargin;
6974
- }).attr('height', d => {
6975
- var _a;
6976
- return ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).bottomMargin;
6977
- }).attr('href', d => {
6978
- var _a, _b;
6979
- return d.selected ? ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).selectedBackgroundImageBottomLeft : ((_b = d.getConfig()) === null || _b === undefined ? undefined : _b.look).backgroundImageBottomLeft;
6980
- });
6981
- mergeSelection.filter('.stretchable-image-look').select('image.bottom-image').attr('x', d => {
6982
- var _a;
6983
- return ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).leftMargin;
6984
- }).attr('y', d => {
6985
- var _a;
6986
- return d.height - ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).bottomMargin;
6987
- }).attr('width', d => {
6988
- var _a, _b;
6989
- return d.width - ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).rightMargin - ((_b = d.getConfig()) === null || _b === undefined ? undefined : _b.look).leftMargin;
6990
- }).attr('height', d => {
6991
- var _a;
6992
- return ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).bottomMargin;
6993
- }).attr('href', d => {
6994
- var _a, _b;
6995
- return d.selected ? ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).selectedBackgroundImageBottom : ((_b = d.getConfig()) === null || _b === undefined ? undefined : _b.look).backgroundImageBottom;
6996
- });
6997
- mergeSelection.filter('.stretchable-image-look').select('image.bottom-right-image').attr('x', d => {
6998
- var _a;
6999
- return d.width - ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).rightMargin;
7000
- }).attr('y', d => {
7001
- var _a;
7002
- return d.height - ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).bottomMargin;
7003
- }).attr('width', d => {
7004
- var _a;
7005
- return ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).rightMargin;
7006
- }).attr('height', d => {
7007
- var _a;
7008
- return ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).bottomMargin;
7009
- }).attr('href', d => {
7010
- var _a, _b;
7011
- return d.selected ? ((_a = d.getConfig()) === null || _a === undefined ? undefined : _a.look).selectedBackgroundImageBottomRight : ((_b = d.getConfig()) === null || _b === undefined ? undefined : _b.look).backgroundImageBottomRight;
7012
- });
7398
+ updateLook(mergeSelection);
7013
7399
  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);
7014
7400
  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);
7015
7401
  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);
@@ -7018,10 +7404,7 @@ class DiagramCanvas {
7018
7404
  updatePortsInView(...ids) {
7019
7405
  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);
7020
7406
  const exitSelection = updateSelection.exit();
7021
- const enterSelection = updateSelection.enter().append('g').attr('id', d => d.id).attr('class', d => {
7022
- var _a, _b;
7023
- return `diagram-port ${((_b = (_a = d.type) === null || _a === undefined ? undefined : _a.look) === null || _b === undefined ? undefined : _b.lookType) || 'default'}`;
7024
- });
7407
+ const enterSelection = updateSelection.enter().append('g').attr('id', d => d.id).attr('class', d => `diagram-port ${d.look.lookType}`);
7025
7408
  if (ids && ids.length > 0) {
7026
7409
  updateSelection = updateSelection.filter(d => ids.includes(d.id));
7027
7410
  }
@@ -7108,7 +7491,7 @@ class DiagramCanvas {
7108
7491
  if (this.canUserPerformAction(DiagramActions.AddConnection) && !d.removed) {
7109
7492
  if (this.unfinishedConnection !== undefined) {
7110
7493
  const endCoords = [event.x, event.y];
7111
- (_a = this.unfinishedConnectionTracer) === null || _a === undefined ? undefined : _a.attr('d', getConnectionPath(this.unfinishedConnection.type.shape, this.unfinishedConnection.startCoords, endCoords, this.unfinishedConnection.startDirection, this.unfinishedConnection.endDirection, this.unfinishedConnection.type.width, (_b = this.unfinishedConnection.startMarkerLook) === null || _b === undefined ? undefined : _b.markerWidth, (_c = this.unfinishedConnection.endMarkerLook) === null || _c === undefined ? undefined : _c.markerWidth));
7494
+ (_a = this.unfinishedConnectionTracer) === null || _a === undefined ? undefined : _a.attr('d', getConnectionPath(this.unfinishedConnection.look.shape, this.unfinishedConnection.startCoords, endCoords, this.unfinishedConnection.startDirection, this.unfinishedConnection.endDirection, this.unfinishedConnection.look.thickness, (_b = this.unfinishedConnection.startMarkerLook) === null || _b === undefined ? undefined : _b.width, (_c = this.unfinishedConnection.endMarkerLook) === null || _c === undefined ? undefined : _c.width));
7112
7495
  const unfinishedConnectionGhostNode = (_d = this.unfinishedConnectionTracer) === null || _d === undefined ? undefined : _d.node();
7113
7496
  if (unfinishedConnectionGhostNode) {
7114
7497
  let margin = 2;
@@ -7180,14 +7563,10 @@ class DiagramCanvas {
7180
7563
  }
7181
7564
  this.secondaryButton = false;
7182
7565
  }));
7183
- enterSelection.filter('.default').append('circle');
7184
7566
  enterSelection.filter('.image-look').append('image');
7185
- mergeSelection.attr('transform', d => `translate(${d.coords[0]},${d.coords[1]})`).attr('opacity', d => d.removed ? 0.5 : 1);
7186
- mergeSelection.filter('.default').select('circle').attr('cx', 0).attr('cy', 0).attr('r', DIAGRAM_PORT_TYPE_DEFAULTS.width / 2).attr('fill', d => d.selected ? DIAGRAM_PORT_DEFAULTS.selectedColor : DIAGRAM_PORT_DEFAULTS.highlightedColor).attr('opacity', d => d.highlighted || d.selected ? 0.5 : 0);
7187
- mergeSelection.filter('.image-look').select('image').attr('x', d => -d.type.width / 2).attr('y', d => -d.type.width / 2).attr('width', d => d.type.width).attr('height', d => d.type.width).attr('href', d => {
7188
- var _a, _b;
7189
- return d.selected ? ((_a = d.type) === null || _a === undefined ? undefined : _a.look).selectedBackgroundImage : ((_b = d.type) === null || _b === undefined ? undefined : _b.look).backgroundImage;
7190
- });
7567
+ initializeLook(enterSelection);
7568
+ mergeSelection.attr('transform', d => `translate(${d.coords[0] - d.width / 2},${d.coords[1] - d.width / 2})`).attr('opacity', d => d.removed ? 0.5 : 1);
7569
+ updateLook(mergeSelection);
7191
7570
  }
7192
7571
  updateConnectionsInView(...ids) {
7193
7572
  const connectionList = this.model.connections.filter(e => this.priorityThreshold !== undefined ? e.getPriority() >= this.priorityThreshold : true);
@@ -7260,14 +7639,14 @@ class DiagramCanvas {
7260
7639
  enterSelection.select('g.diagram-connection-end-label').append('text').style('user-select', 'none');
7261
7640
  mergeSelection.attr('opacity', d => d.removed ? 0.5 : 1).select('path.diagram-connection-path').attr('d', d => {
7262
7641
  var _a, _b;
7263
- return getConnectionPath(d.type.shape, d.startCoords, d.endCoords, d.startDirection, d.endDirection, d.type.width, (_a = d.startMarkerLook) === null || _a === undefined ? undefined : _a.markerWidth, (_b = d.endMarkerLook) === null || _b === undefined ? undefined : _b.markerWidth);
7264
- }).attr('marker-start', d => `url(#${d.id}-start-marker)`).attr('marker-end', d => `url(#${d.id}-end-marker)`).attr('stroke', d => d.selected ? d.type.selectedColor : d.type.color).attr('stroke-width', d => `${d.highlighted ? d.type.width + 1 : d.type.width}px`).attr('stroke-dasharray', d => lineStyleDasharray(d.type.style, d.type.width)).attr('fill', 'none');
7642
+ return getConnectionPath(d.look.shape, d.startCoords, d.endCoords, d.startDirection, d.endDirection, d.look.thickness, (_a = d.startMarkerLook) === null || _a === undefined ? undefined : _a.width, (_b = d.endMarkerLook) === null || _b === undefined ? undefined : _b.width);
7643
+ }).attr('marker-start', d => `url(#${d.id}-start-marker)`).attr('marker-end', d => `url(#${d.id}-end-marker)`).attr('stroke', d => d.look.color).attr('stroke-width', d => `${d.look.thickness}px`).attr('stroke-dasharray', d => lineStyleDasharray(d.look.style, d.look.thickness)).attr('fill', 'none');
7265
7644
  mergeSelection.select('path.diagram-connection-path-box').attr('d', d => {
7266
7645
  var _a, _b;
7267
- return getConnectionPath(d.type.shape, d.startCoords, d.endCoords, d.startDirection, d.endDirection, d.type.width, (_a = d.startMarkerLook) === null || _a === undefined ? undefined : _a.markerWidth, (_b = d.endMarkerLook) === null || _b === undefined ? undefined : _b.markerWidth);
7646
+ return getConnectionPath(d.look.shape, d.startCoords, d.endCoords, d.startDirection, d.endDirection, d.look.thickness, (_a = d.startMarkerLook) === null || _a === undefined ? undefined : _a.width, (_b = d.endMarkerLook) === null || _b === undefined ? undefined : _b.width);
7268
7647
  }).attr('stroke', 'transparent')
7269
7648
  // allow generating pointer events even when it is transparent
7270
- .attr('pointer-events', 'stroke').attr('stroke-width', d => `${d.type.width + CONNECTION_PATH_BOX_THICKNESS}px`).attr('stroke-dasharray', d => lineStyleDasharray(d.type.style, d.type.width)).attr('fill', 'none');
7649
+ .attr('pointer-events', 'stroke').attr('stroke-width', d => `${d.look.thickness + CONNECTION_PATH_BOX_THICKNESS}px`).attr('stroke-dasharray', d => lineStyleDasharray(d.look.style, d.look.thickness)).attr('fill', 'none');
7271
7650
  mergeSelection.data().forEach(connection => {
7272
7651
  this.updateConnectionLabelsInView(connection);
7273
7652
  this.updateConnectionMarkersInView(connection);
@@ -7416,11 +7795,17 @@ class DiagramCanvas {
7416
7795
  this.secondaryButton = isSecondaryButton(event);
7417
7796
  return true;
7418
7797
  }).on(DragEvents.Start, event => {
7419
- this.startMultipleSelection(event);
7798
+ if (this.multipleSelectionOn || this.secondaryButton) {
7799
+ this.startMultipleSelection(event);
7800
+ }
7420
7801
  }).on(DragEvents.Drag, event => {
7421
- this.continueMultipleSelection(event);
7802
+ if (this.multipleSelectionOn || this.secondaryButton) {
7803
+ this.continueMultipleSelection(event);
7804
+ }
7422
7805
  }).on(DragEvents.End, event => {
7423
- this.finishMultipleSelection(event);
7806
+ if (this.multipleSelectionOn || this.secondaryButton) {
7807
+ this.finishMultipleSelection(event);
7808
+ }
7424
7809
  }));
7425
7810
  }
7426
7811
  updateDecoratorsInView(...ids) {
@@ -7452,12 +7837,55 @@ class DiagramCanvas {
7452
7837
  }).call(d3.drag().filter(event => {
7453
7838
  this.secondaryButton = isSecondaryButton(event);
7454
7839
  return true;
7455
- }).on(DragEvents.Start, event => {
7456
- this.startMultipleSelection(event);
7457
- }).on(DragEvents.Drag, event => {
7458
- this.continueMultipleSelection(event);
7459
- }).on(DragEvents.End, event => {
7460
- this.finishMultipleSelection(event);
7840
+ }).on(DragEvents.Start, (event, d) => {
7841
+ if (this.multipleSelectionOn || this.secondaryButton) {
7842
+ this.startMultipleSelection(event);
7843
+ } else {
7844
+ let node;
7845
+ if (d.rootElement instanceof DiagramNode) {
7846
+ node = d.rootElement;
7847
+ } else if (d.rootElement instanceof DiagramSection) {
7848
+ node = d.rootElement.node;
7849
+ }
7850
+ if (node) {
7851
+ this.startMovingNode(event, node);
7852
+ } else {
7853
+ setCursorStyle(CursorStyle.NotAllowed);
7854
+ }
7855
+ }
7856
+ }).on(DragEvents.Drag, (event, d) => {
7857
+ if (this.multipleSelectionOn || this.secondaryButton) {
7858
+ this.continueMultipleSelection(event);
7859
+ } else {
7860
+ let node;
7861
+ if (d.rootElement instanceof DiagramNode) {
7862
+ node = d.rootElement;
7863
+ } else if (d.rootElement instanceof DiagramSection) {
7864
+ node = d.rootElement.node;
7865
+ }
7866
+ if (node) {
7867
+ this.continueMovingNode(event, node);
7868
+ } else {
7869
+ setCursorStyle(CursorStyle.NotAllowed);
7870
+ }
7871
+ }
7872
+ }).on(DragEvents.End, (event, d) => {
7873
+ if (this.multipleSelectionOn || this.secondaryButton) {
7874
+ this.finishMultipleSelection(event);
7875
+ } else {
7876
+ let node;
7877
+ if (d.rootElement instanceof DiagramNode) {
7878
+ node = d.rootElement;
7879
+ } else if (d.rootElement instanceof DiagramSection) {
7880
+ node = d.rootElement.node;
7881
+ }
7882
+ if (node) {
7883
+ this.finishMovingNode(event, node);
7884
+ } else {
7885
+ setCursorStyle();
7886
+ }
7887
+ }
7888
+ this.secondaryButton = false;
7461
7889
  }));
7462
7890
  }
7463
7891
  updateConnectionLabelsInView(connection) {
@@ -7476,7 +7904,7 @@ class DiagramCanvas {
7476
7904
  const boundingWidth = !connection.startLabel ? 0 : startLabelBoundingRect.width / this.zoomTransform.k + getLeftPadding$1(labelConfiguration) + getRightPadding$1(labelConfiguration);
7477
7905
  const boundingHeight = !connection.startLabel ? 0 : startLabelBoundingRect.height / this.zoomTransform.k + getTopPadding$1(labelConfiguration) + getBottomPadding$1(labelConfiguration);
7478
7906
  const pathStartLabelPoint = pathNode.getPointAtLength(Math.max(getLeftMargin(labelConfiguration) + boundingWidth / 2, getRightMargin(labelConfiguration) + boundingWidth / 2, getTopMargin(labelConfiguration) + boundingHeight / 2, getBottomMargin(labelConfiguration) + boundingHeight / 2));
7479
- connectionSelection.select('g.diagram-connection-start-label path').attr('d', pillPath(-boundingWidth / 2, -boundingHeight / 2, boundingWidth, boundingHeight)).attr('fill', connection.selected ? connection.type.selectedColor : connection.type.color).attr('stroke', 'none');
7907
+ connectionSelection.select('g.diagram-connection-start-label path').attr('d', pillPath(-boundingWidth / 2, -boundingHeight / 2, boundingWidth, boundingHeight)).attr('fill', connection.look.color).attr('stroke', 'none');
7480
7908
  connectionSelection.select('g.diagram-connection-start-label').attr('transform', `translate(${pathStartLabelPoint.x},${pathStartLabelPoint.y})`);
7481
7909
  }
7482
7910
  // bind middle labels
@@ -7487,7 +7915,7 @@ class DiagramCanvas {
7487
7915
  const boundingWidth = !connection.middleLabel ? 0 : middleLabelBoundingRect.width / this.zoomTransform.k + getLeftPadding$1(labelConfiguration) + getRightPadding$1(labelConfiguration);
7488
7916
  const boundingHeight = !connection.middleLabel ? 0 : middleLabelBoundingRect.height / this.zoomTransform.k + getTopPadding$1(labelConfiguration) + getBottomPadding$1(labelConfiguration);
7489
7917
  const pathMiddleLabelPoint = pathNode.getPointAtLength(pathLength / 2);
7490
- connectionSelection.select('g.diagram-connection-middle-label path').attr('d', pillPath(-boundingWidth / 2, -boundingHeight / 2, boundingWidth, boundingHeight)).attr('fill', connection.selected ? connection.type.selectedColor : connection.type.color).attr('stroke', 'none');
7918
+ connectionSelection.select('g.diagram-connection-middle-label path').attr('d', pillPath(-boundingWidth / 2, -boundingHeight / 2, boundingWidth, boundingHeight)).attr('fill', connection.look.color).attr('stroke', 'none');
7491
7919
  connectionSelection.select('g.diagram-connection-middle-label').attr('transform', `translate(${pathMiddleLabelPoint.x},${pathMiddleLabelPoint.y})`);
7492
7920
  }
7493
7921
  // bind end labels
@@ -7498,7 +7926,7 @@ class DiagramCanvas {
7498
7926
  const boundingWidth = !connection.endLabel ? 0 : endLabelBoundingRect.width / this.zoomTransform.k + getLeftPadding$1(labelConfiguration) + getRightPadding$1(labelConfiguration);
7499
7927
  const boundingHeight = !connection.endLabel ? 0 : endLabelBoundingRect.height / this.zoomTransform.k + getTopPadding$1(labelConfiguration) + getBottomPadding$1(labelConfiguration);
7500
7928
  const pathEndLabelPoint = pathNode.getPointAtLength(pathLength - Math.max(getLeftMargin(labelConfiguration) + boundingWidth / 2, getRightMargin(labelConfiguration) + boundingWidth / 2, getTopMargin(labelConfiguration) + boundingHeight / 2, getBottomMargin(labelConfiguration) + boundingHeight / 2));
7501
- connectionSelection.select('g.diagram-connection-end-label path').attr('d', pillPath(-boundingWidth / 2, -boundingHeight / 2, boundingWidth, boundingHeight)).attr('fill', connection.selected ? connection.type.selectedColor : connection.type.color).attr('stroke', 'none');
7929
+ connectionSelection.select('g.diagram-connection-end-label path').attr('d', pillPath(-boundingWidth / 2, -boundingHeight / 2, boundingWidth, boundingHeight)).attr('fill', connection.look.color).attr('stroke', 'none');
7502
7930
  connectionSelection.select('g.diagram-connection-end-label').attr('transform', `translate(${pathEndLabelPoint.x},${pathEndLabelPoint.y})`);
7503
7931
  }
7504
7932
  }
@@ -7508,18 +7936,18 @@ class DiagramCanvas {
7508
7936
  const startMarkerSelection = connectionSelection.select('marker.diagram-connection-start-marker');
7509
7937
  const endMarkerSelection = connectionSelection.select('marker.diagram-connection-end-marker');
7510
7938
  if (connection.startMarkerLook !== null) {
7511
- startMarkerSelection.attr('orient', 'auto-start-reverse').attr('markerWidth', connection.startMarkerLook.markerWidth).attr('markerHeight', connection.startMarkerLook.markerHeight).attr('refX', connection.startMarkerLook.markerRefX).attr('refY', connection.startMarkerLook.markerRefY).select('image').attr('href', connection.selected ? connection.startMarkerLook.selectedImage : connection.startMarkerLook.image).attr('width', connection.startMarkerLook.markerWidth).attr('height', connection.startMarkerLook.markerHeight);
7939
+ startMarkerSelection.attr('orient', 'auto-start-reverse').attr('markerWidth', connection.startMarkerLook.width).attr('markerHeight', connection.startMarkerLook.height).attr('refX', connection.startMarkerLook.refX).attr('refY', connection.startMarkerLook.refY).select('image').attr('href', connection.startMarkerLook.image).attr('width', connection.startMarkerLook.width).attr('height', connection.startMarkerLook.height);
7512
7940
  } else {
7513
7941
  startMarkerSelection.attr('orient', 'auto-start-reverse').attr('markerWidth', 0).attr('markerHeight', 0);
7514
7942
  }
7515
7943
  if (connection.endMarkerLook !== null) {
7516
- endMarkerSelection.attr('orient', 'auto-start-reverse').attr('markerWidth', connection.endMarkerLook.markerWidth).attr('markerHeight', connection.endMarkerLook.markerHeight).attr('refX', connection.endMarkerLook.markerRefX).attr('refY', connection.endMarkerLook.markerRefY).select('image').attr('href', connection.selected ? connection.endMarkerLook.selectedImage : connection.endMarkerLook.image).attr('width', connection.endMarkerLook.markerWidth).attr('height', connection.endMarkerLook.markerHeight);
7944
+ endMarkerSelection.attr('orient', 'auto-start-reverse').attr('markerWidth', connection.endMarkerLook.width).attr('markerHeight', connection.endMarkerLook.height).attr('refX', connection.endMarkerLook.refX).attr('refY', connection.endMarkerLook.refY).select('image').attr('href', connection.endMarkerLook.image).attr('width', connection.endMarkerLook.width).attr('height', connection.endMarkerLook.height);
7517
7945
  } else {
7518
7946
  endMarkerSelection.attr('orient', 'auto-start-reverse').attr('markerWidth', 0).attr('markerHeight', 0);
7519
7947
  }
7520
7948
  }
7521
7949
  fitFieldRootInView(id) {
7522
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
7950
+ var _a, _b, _c;
7523
7951
  const field = this.model.fields.get(id);
7524
7952
  if (!field) {
7525
7953
  return;
@@ -7561,8 +7989,9 @@ class DiagramCanvas {
7561
7989
  if (fieldDimensions[1] < minimumFieldHeight) {
7562
7990
  fieldDimensions[1] = minimumFieldHeight;
7563
7991
  }
7564
- let stretchX = fieldDimensions[0] + getLeftMargin((_c = (_b = field.rootElement) === null || _b === undefined ? undefined : _b.getConfig()) === null || _c === undefined ? undefined : _c.label) + getRightMargin((_e = (_d = field.rootElement) === null || _d === undefined ? undefined : _d.getConfig()) === null || _e === undefined ? undefined : _e.label) - field.rootElement.width;
7565
- let stretchY = fieldDimensions[1] + getTopMargin((_g = (_f = field.rootElement) === null || _f === undefined ? undefined : _f.getConfig()) === null || _g === undefined ? undefined : _g.label) + getBottomMargin((_j = (_h = field.rootElement) === null || _h === undefined ? undefined : _h.getConfig()) === null || _j === undefined ? undefined : _j.label) - field.rootElement.height;
7992
+ const type = field.rootElement.type;
7993
+ let stretchX = fieldDimensions[0] + getLeftMargin(type === null || type === undefined ? undefined : type.label) + getRightMargin(type === null || type === undefined ? undefined : type.label) - field.rootElement.width;
7994
+ let stretchY = fieldDimensions[1] + getTopMargin(type === null || type === undefined ? undefined : type.label) + getBottomMargin(type === null || type === undefined ? undefined : type.label) - field.rootElement.height;
7566
7995
  if (this.snapToGrid) {
7567
7996
  stretchX = Math.ceil(stretchX / this.gridSize) * this.gridSize;
7568
7997
  stretchY = Math.ceil(stretchY / this.gridSize) * this.gridSize;
@@ -7574,8 +8003,8 @@ class DiagramCanvas {
7574
8003
  if (field.rootElement.height + stretchY < (field.rootElement.getMinHeight() || 0)) {
7575
8004
  stretchY = (field.rootElement.getMinHeight() || 0) - field.rootElement.height;
7576
8005
  }
7577
- (_k = field.rootElement.node) === null || _k === undefined ? undefined : _k.stretchSections(Side.Right, stretchX, field.rootElement.indexXInNode, field.rootElement.indexYInNode);
7578
- (_l = field.rootElement.node) === null || _l === undefined ? undefined : _l.stretchSections(Side.Bottom, stretchY, field.rootElement.indexXInNode, field.rootElement.indexYInNode);
8006
+ (_b = field.rootElement.node) === null || _b === undefined ? undefined : _b.stretchSections(Side.Right, stretchX, field.rootElement.indexXInNode, field.rootElement.indexYInNode);
8007
+ (_c = field.rootElement.node) === null || _c === undefined ? undefined : _c.stretchSections(Side.Bottom, stretchY, field.rootElement.indexXInNode, field.rootElement.indexYInNode);
7579
8008
  }
7580
8009
  }
7581
8010
  fitNodeInView(id) {
@@ -7906,41 +8335,6 @@ class DiagramCanvas {
7906
8335
  }
7907
8336
  }
7908
8337
  DiagramCanvas.canvasCount = 0;
7909
- /**
7910
- * Checks if the given mouse event was produced with a secondary button press.
7911
- * @private
7912
- * @param event A mouse event.
7913
- * @returns `true` if the given mouse event was produced with a secondary button press, `false` otherwise.
7914
- */
7915
- const isSecondaryButton = event => {
7916
- return !!event.button;
7917
- };
7918
- /**
7919
- * Get the SVG path of a diagram connection.
7920
- * @private
7921
- * @see linePath
7922
- */
7923
- const getConnectionPath = (shape, startCoords, endCoords, startDirection, endDirection, width, startMarkerWidth, endMarkerWidth) => {
7924
- return linePath(shape, [startCoords, endCoords], startDirection, endDirection, Math.max(
7925
- // reasonable value for the minimumDistanceBeforeTurn relative to the line width
7926
- 10, startMarkerWidth || 0, endMarkerWidth || 0) * width);
7927
- };
7928
- const setCursorStyle = style => {
7929
- if (!style) {
7930
- d3.select('body').style('cursor', CursorStyle.Auto);
7931
- } else {
7932
- d3.select('body').style('cursor', style);
7933
- }
7934
- };
7935
- const getRelatedNodeOrItself = element => {
7936
- if (element instanceof DiagramNode) {
7937
- return element;
7938
- }
7939
- if (element instanceof DiagramSection) {
7940
- return element.node || element;
7941
- }
7942
- return element.rootElement instanceof DiagramNode || element.rootElement instanceof DiagramSection || element.rootElement instanceof DiagramPort ? getRelatedNodeOrItself(element.rootElement) : element;
7943
- };
7944
8338
 
7945
8339
  const VERSION = '0.0.1';
7946
8340
  /**