@joint/core 4.1.2 → 4.2.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +1 -1
  2. package/dist/geometry.js +128 -123
  3. package/dist/geometry.min.js +2 -2
  4. package/dist/joint.d.ts +79 -16
  5. package/dist/joint.js +2249 -1730
  6. package/dist/joint.min.js +2 -2
  7. package/dist/joint.nowrap.js +2248 -1727
  8. package/dist/joint.nowrap.min.js +2 -2
  9. package/dist/vectorizer.js +469 -272
  10. package/dist/vectorizer.min.js +2 -2
  11. package/dist/version.mjs +1 -1
  12. package/package.json +28 -22
  13. package/src/V/create.mjs +51 -0
  14. package/src/V/index.mjs +69 -154
  15. package/src/V/namespace.mjs +9 -0
  16. package/src/V/transform.mjs +183 -0
  17. package/src/V/traverse.mjs +16 -0
  18. package/src/anchors/index.mjs +140 -33
  19. package/src/cellTools/Boundary.mjs +1 -1
  20. package/src/cellTools/Control.mjs +1 -1
  21. package/src/connectionPoints/index.mjs +24 -9
  22. package/src/connectionStrategies/index.mjs +1 -1
  23. package/src/connectors/jumpover.mjs +1 -1
  24. package/src/dia/Cell.mjs +6 -2
  25. package/src/dia/CellView.mjs +47 -39
  26. package/src/dia/Element.mjs +79 -35
  27. package/src/dia/ElementView.mjs +9 -3
  28. package/src/dia/HighlighterView.mjs +32 -11
  29. package/src/dia/Paper.mjs +134 -22
  30. package/src/dia/PaperLayer.mjs +9 -2
  31. package/src/dia/attributes/text.mjs +12 -3
  32. package/src/dia/layers/GridLayer.mjs +5 -0
  33. package/src/dia/ports.mjs +152 -39
  34. package/src/env/index.mjs +1 -1
  35. package/src/g/rect.mjs +7 -0
  36. package/src/highlighters/stroke.mjs +1 -1
  37. package/src/linkAnchors/index.mjs +2 -2
  38. package/src/linkTools/Anchor.mjs +2 -2
  39. package/src/linkTools/Vertices.mjs +4 -6
  40. package/src/mvc/Dom/methods.mjs +2 -2
  41. package/src/util/util.mjs +1 -1
  42. package/src/util/utilHelpers.mjs +2 -0
  43. package/types/geometry.d.ts +2 -0
  44. package/types/joint.d.ts +81 -20
  45. package/src/V/annotation.mjs +0 -0
package/src/dia/ports.mjs CHANGED
@@ -8,15 +8,28 @@ var PortData = function(data) {
8
8
 
9
9
  var clonedData = util.cloneDeep(data) || {};
10
10
  this.ports = [];
11
+ this.portsMap = {};
11
12
  this.groups = {};
12
13
  this.portLayoutNamespace = Port;
13
14
  this.portLabelLayoutNamespace = PortLabel;
15
+ this.metrics = {};
16
+ this.metricsKey = null;
14
17
 
15
18
  this._init(clonedData);
16
19
  };
17
20
 
18
21
  PortData.prototype = {
19
22
 
23
+ hasPort: function(id) {
24
+ return id in this.portsMap;
25
+ },
26
+
27
+ getPort: function(id) {
28
+ const port = this.portsMap[id];
29
+ if (port) return port;
30
+ throw new Error('Element: unable to find port with id ' + id);
31
+ },
32
+
20
33
  getPorts: function() {
21
34
  return this.ports;
22
35
  },
@@ -32,7 +45,26 @@ PortData.prototype = {
32
45
  });
33
46
  },
34
47
 
35
- getGroupPortsMetrics: function(groupName, elBBox) {
48
+ getGroupPortsMetrics: function(groupName, rect) {
49
+ const { x = 0, y = 0, width = 0, height = 0 } = rect;
50
+ const metricsKey = `${x}:${y}:${width}:${height}`;
51
+ if (this.metricsKey !== metricsKey) {
52
+ // Clear the cache (the element size has changed)
53
+ this.metrics = {};
54
+ this.metricsKey = metricsKey;
55
+ }
56
+ let groupPortsMetrics = this.metrics[groupName];
57
+ if (groupPortsMetrics) {
58
+ // Return cached metrics
59
+ return groupPortsMetrics;
60
+ }
61
+ // Calculate the metrics
62
+ groupPortsMetrics = this.resolveGroupPortsMetrics(groupName, new Rect(x, y, width, height));
63
+ this.metrics[groupName] = groupPortsMetrics;
64
+ return groupPortsMetrics;
65
+ },
66
+
67
+ resolveGroupPortsMetrics: function(groupName, elBBox) {
36
68
 
37
69
  var group = this.getGroup(groupName);
38
70
  var ports = this.getPortsByGroup(groupName);
@@ -52,21 +84,23 @@ PortData.prototype = {
52
84
 
53
85
  var accumulator = {
54
86
  ports: ports,
55
- result: []
87
+ result: {}
56
88
  };
57
89
 
58
- util.toArray(groupPortTransformations).reduce(function(res, portTransformation, index) {
59
- var port = res.ports[index];
60
- res.result.push({
61
- portId: port.id,
90
+ util.toArray(groupPortTransformations).reduce((res, portTransformation, index) => {
91
+ const port = res.ports[index];
92
+ const portId = port.id;
93
+ res.result[portId] = {
94
+ index,
95
+ portId,
62
96
  portTransformation: portTransformation,
63
97
  labelTransformation: this._getPortLabelLayout(port, Point(portTransformation), elBBox),
64
98
  portAttrs: port.attrs,
65
99
  portSize: port.size,
66
100
  labelSize: port.label.size
67
- });
101
+ };
68
102
  return res;
69
- }.bind(this), accumulator);
103
+ }, accumulator);
70
104
 
71
105
  return accumulator.result;
72
106
  },
@@ -97,7 +131,9 @@ PortData.prototype = {
97
131
  // prepare ports
98
132
  var ports = util.toArray(data.items);
99
133
  for (var j = 0, m = ports.length; j < m; j++) {
100
- this.ports.push(this._evaluatePort(ports[j]));
134
+ const resolvedPort = this._evaluatePort(ports[j]);
135
+ this.ports.push(resolvedPort);
136
+ this.portsMap[resolvedPort.id] = resolvedPort;
101
137
  }
102
138
  },
103
139
 
@@ -138,10 +174,18 @@ PortData.prototype = {
138
174
 
139
175
  _createPositionNode: function(group, port) {
140
176
 
141
- return util.merge({
142
- name: 'left',
143
- args: {}
144
- }, group.position, { args: port.args });
177
+ return util.merge(
178
+ {
179
+ name: 'left',
180
+ args: {}
181
+ },
182
+ group.position,
183
+ {
184
+ // TODO: remove `port.args` backwards compatibility
185
+ // NOTE: `x != null` is equivalent to `x !== null && x !== undefined`
186
+ args: (((port.position != null) && (port.position.args != null)) ? port.position.args : port.args)
187
+ }
188
+ );
145
189
  },
146
190
 
147
191
  _getPosition: function(position, setDefault) {
@@ -240,8 +284,7 @@ export const elementPortPrototype = {
240
284
  */
241
285
  hasPorts: function() {
242
286
 
243
- var ports = this.prop('ports/items');
244
- return Array.isArray(ports) && ports.length > 0;
287
+ return this._portSettingsData.getPorts().length > 0;
245
288
  },
246
289
 
247
290
  /**
@@ -250,7 +293,7 @@ export const elementPortPrototype = {
250
293
  */
251
294
  hasPort: function(id) {
252
295
 
253
- return this.getPortIndex(id) !== -1;
296
+ return this._portSettingsData.hasPort(id);
254
297
  },
255
298
 
256
299
  /**
@@ -274,10 +317,8 @@ export const elementPortPrototype = {
274
317
  * @returns {object}
275
318
  */
276
319
  getPort: function(id) {
277
-
278
- return util.cloneDeep(util.toArray(this.prop('ports/items')).find(function(port) {
279
- return port.id && port.id === id;
280
- }));
320
+ const port = util.toArray(this.prop('ports/items')).find(port => port.id && port.id === id);
321
+ return util.cloneDeep(port);
281
322
  },
282
323
 
283
324
  getPortGroupNames: function() {
@@ -290,17 +331,90 @@ export const elementPortPrototype = {
290
331
  */
291
332
  getPortsPositions: function(groupName) {
292
333
 
293
- var portsMetrics = this._portSettingsData.getGroupPortsMetrics(groupName, Rect(this.size()));
294
-
295
- return portsMetrics.reduce(function(positions, metrics) {
296
- var transformation = metrics.portTransformation;
297
- positions[metrics.portId] = {
298
- x: transformation.x,
299
- y: transformation.y,
300
- angle: transformation.angle
334
+ const portsMetrics = this.getGroupPortsMetrics(groupName);
335
+ const portsPosition = {};
336
+ for (const portId in portsMetrics) {
337
+ const {
338
+ portTransformation: { x, y, angle },
339
+ } = portsMetrics[portId];
340
+ portsPosition[portId] = {
341
+ x: x,
342
+ y: y,
343
+ angle
301
344
  };
302
- return positions;
303
- }, {});
345
+ }
346
+ return portsPosition;
347
+ },
348
+
349
+ getPortMetrics: function(portId) {
350
+ const port = this._portSettingsData.getPort(portId);
351
+ return this.getGroupPortsMetrics(port.group)[portId];
352
+ },
353
+
354
+ getGroupPortsMetrics: function(groupName) {
355
+ return this._portSettingsData.getGroupPortsMetrics(groupName, this.size());
356
+ },
357
+
358
+ getPortRelativePosition: function(portId) {
359
+ const { portTransformation: { x, y, angle }} = this.getPortMetrics(portId);
360
+ return { x, y, angle };
361
+ },
362
+
363
+ getPortRelativeRect(portId) {
364
+ const {
365
+ portTransformation: { x, y, angle },
366
+ portSize: { width, height }
367
+ } = this.getPortMetrics(portId);
368
+ const portRect = {
369
+ x: x - width / 2,
370
+ y: y - height / 2,
371
+ width,
372
+ height,
373
+ angle
374
+ };
375
+ return portRect;
376
+ },
377
+
378
+ /**
379
+ * @param {string} portId
380
+ * @returns {Point}
381
+ * @description Returns the port center in the graph coordinate system.
382
+ * The port center is in the graph coordinate system, and the position
383
+ * already takes into account the element rotation.
384
+ **/
385
+ getPortCenter(portId) {
386
+ const elementBBox = this.getBBox();
387
+ const portPosition = this.getPortRelativePosition(portId);
388
+ const portCenter = new Point(portPosition).offset(elementBBox.x, elementBBox.y);
389
+ const angle = this.angle();
390
+ if (angle) portCenter.rotate(elementBBox.center(), -angle);
391
+ return portCenter;
392
+ },
393
+
394
+ /**
395
+ * @param {string} portId
396
+ * @param {object} [opt]
397
+ * @param {boolean} [opt.rotate] - If true, the port bounding box is rotated
398
+ * around the port center.
399
+ * @returns {Rect}
400
+ * @description Returns the bounding box of the port in the graph coordinate system.
401
+ * The port center is rotated around the element center, but the port bounding box
402
+ * is not rotated (unless `opt.rotate` is set to true).
403
+ */
404
+ getPortBBox: function(portId, opt) {
405
+ const portRect = this.getPortRelativeRect(portId);
406
+ const elementBBox = this.getBBox();
407
+ // Note: the `angle` property of the `port` is ignore here for now
408
+ const portBBox = new Rect(portRect);
409
+ portBBox.offset(elementBBox.x, elementBBox.y);
410
+ const angle = this.angle();
411
+ if (angle) {
412
+ portBBox.moveAroundPoint(elementBBox.center(), -angle);
413
+ }
414
+ if (opt && opt.rotate) {
415
+ portBBox.rotateAroundCenter(angle);
416
+ }
417
+ return portBBox;
304
418
  },
305
419
 
306
420
  /**
@@ -822,15 +936,15 @@ export const elementViewPortPrototype = {
822
936
  */
823
937
  _updatePortGroup: function(groupName) {
824
938
 
825
- var elementBBox = Rect(this.model.size());
826
- var portsMetrics = this.model._portSettingsData.getGroupPortsMetrics(groupName, elementBBox);
939
+ const portsMetrics = this.model.getGroupPortsMetrics(groupName);
940
+ const portsIds = Object.keys(portsMetrics);
827
941
 
828
- for (var i = 0, n = portsMetrics.length; i < n; i++) {
829
- var metrics = portsMetrics[i];
830
- var portId = metrics.portId;
831
- var cached = this._portElementsCache[portId] || {};
832
- var portTransformation = metrics.portTransformation;
833
- var labelTransformation = metrics.labelTransformation;
942
+ for (let i = 0, n = portsIds.length; i < n; i++) {
943
+ const portId = portsIds[i];
944
+ const metrics = portsMetrics[portId];
945
+ const cached = this._portElementsCache[portId] || {};
946
+ const portTransformation = metrics.portTransformation;
947
+ const labelTransformation = metrics.labelTransformation;
834
948
  if (labelTransformation && cached.portLabelElement) {
835
949
  this.updateDOMSubtreeAttributes(cached.portLabelElement.node, labelTransformation.attrs, {
836
950
  rootBBox: new Rect(metrics.labelSize),
@@ -882,4 +996,3 @@ export const elementViewPortPrototype = {
882
996
  return label.markup || this.model.get('portLabelMarkup') || this.model.portLabelMarkup || this.portLabelMarkup;
883
997
  }
884
998
  };
885
-
package/src/env/index.mjs CHANGED
@@ -36,7 +36,7 @@ export const env = {
36
36
 
37
37
  try {
38
38
  result = fn();
39
- } catch (error) {
39
+ } catch {
40
40
  result = false;
41
41
  }
42
42
 
package/src/g/rect.mjs CHANGED
@@ -369,6 +369,13 @@ Rect.prototype = {
369
369
  return this;
370
370
  },
371
371
 
372
+ moveAroundPoint: function(origin, angle) {
373
+ const newCenter = this.center().rotate(origin, angle);
374
+ this.x = newCenter.x - this.width / 2;
375
+ this.y = newCenter.y - this.height / 2;
376
+ return this;
377
+ },
378
+
372
379
  // Normalize the rectangle; i.e., make it so that it has a non-negative width and height.
373
380
  // If width < 0 the function swaps the left and right corners,
374
381
  // and it swaps the top and bottom corners if height < 0
@@ -35,7 +35,7 @@ export const stroke = HighlighterView.extend({
35
35
  d = d.substr(0, secondSubpathIndex);
36
36
  }
37
37
  }
38
- } catch (error) {
38
+ } catch {
39
39
  // Failed to get path data from magnet element.
40
40
  // Draw a rectangle around the node instead.
41
41
  const nodeBBox = cellView.getNodeBoundingRect(node);
@@ -40,7 +40,7 @@ function _connectionClosest(view, _magnet, refPoint, _opt) {
40
40
  }
41
41
 
42
42
  export function resolveRef(fn) {
43
- return function(view, magnet, ref, opt) {
43
+ return function(view, magnet, ref, opt, endType, linkView) {
44
44
  if (ref instanceof Element) {
45
45
  var refView = this.paper.findView(ref);
46
46
  var refPoint;
@@ -55,7 +55,7 @@ export function resolveRef(fn) {
55
55
  // Something went wrong
56
56
  refPoint = new Point();
57
57
  }
58
- return fn.call(this, view, magnet, refPoint, opt);
58
+ return fn.call(this, view, magnet, refPoint, opt, endType, linkView);
59
59
  }
60
60
  return fn.apply(this, arguments);
61
61
  };
@@ -118,7 +118,7 @@ const Anchor = ToolView.extend({
118
118
  bbox = view.getNodeUnrotatedBBox(magnet);
119
119
  angle = model.angle();
120
120
  center = bbox.center();
121
- if (angle) center.rotate(model.getBBox().center(), -angle);
121
+ if (angle) center.rotate(model.getCenter(), -angle);
122
122
  // TODO: get the link's magnet rotation into account
123
123
  }
124
124
  bbox.inflate(padding);
@@ -185,7 +185,7 @@ const Anchor = ToolView.extend({
185
185
  // snap coords within node bbox
186
186
  var bbox = view.getNodeUnrotatedBBox(magnet);
187
187
  var angle = model.angle();
188
- var origin = model.getBBox().center();
188
+ var origin = model.getCenter();
189
189
  var rotatedCoords = coords.clone().rotate(origin, angle);
190
190
  if (!bbox.containsPoint(rotatedCoords)) {
191
191
  coords = bbox.pointNearestToPoint(rotatedCoords).rotate(origin, -angle);
@@ -221,18 +221,16 @@ export const Vertices = ToolView.extend({
221
221
  onHandleChanged: function(_handle, evt) {
222
222
  const { options, relatedView: linkView } = this;
223
223
  if (options.vertexAdding) this.updatePath();
224
- if (!options.redundancyRemoval) {
225
- linkView.checkMouseleave(util.normalizeEvent(evt));
226
- return;
224
+ if (options.redundancyRemoval) {
225
+ const verticesRemoved = linkView.removeRedundantLinearVertices({ ui: true, tool: this.cid });
226
+ if (verticesRemoved) this.render();
227
227
  }
228
- var verticesRemoved = linkView.removeRedundantLinearVertices({ ui: true, tool: this.cid });
229
- if (verticesRemoved) this.render();
230
228
  this.blur();
231
229
  linkView.model.stopBatch('vertex-move', { ui: true, tool: this.cid });
232
230
  if (this.eventData(evt).vertexAdded) {
233
231
  linkView.model.stopBatch('vertex-add', { ui: true, tool: this.cid });
234
232
  }
235
- var [normalizedEvt, x, y] = linkView.paper.getPointerArgs(evt);
233
+ const [normalizedEvt, x, y] = linkView.paper.getPointerArgs(evt);
236
234
  if (!options.stopPropagation) linkView.notifyPointerup(normalizedEvt, x, y);
237
235
  linkView.checkMouseleave(normalizedEvt);
238
236
  },
@@ -337,8 +337,8 @@ export function position() {
337
337
  doc = el.ownerDocument;
338
338
  offsetParent = el.offsetParent || doc.documentElement;
339
339
  const isStaticallyPositioned = (el) => {
340
- const { position } = el.style;
341
- return !position || position === 'static';
340
+ const { position } = getComputedStyle(el);
341
+ return position === 'static';
342
342
  };
343
343
  while (offsetParent && offsetParent !== doc.documentElement && isStaticallyPositioned(offsetParent)) {
344
344
  offsetParent = offsetParent.offsetParent || doc.documentElement;
package/src/util/util.mjs CHANGED
@@ -821,7 +821,7 @@ export const sanitizeHTML = function(html) {
821
821
  const value = node.getAttribute(name);
822
822
  // Remove attribute names that start with "on" (e.g. onload, onerror...).
823
823
  // Remove attribute values that start with "javascript:" pseudo protocol (e.g. `href="javascript:alert(1)"`).
824
- if (name.startsWith('on') || value.startsWith('javascript:' || value.startsWith('data:') || value.startsWith('vbscript:'))) {
824
+ if (name.startsWith('on') || value.startsWith('javascript:') || value.startsWith('data:') || value.startsWith('vbscript:')) {
825
825
  node.removeAttribute(name);
826
826
  }
827
827
  });
@@ -105,6 +105,7 @@ const rsOrdUpper = '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])';
105
105
  const rsSeq = rsOptVar + reOptMod + rsOptJoin;
106
106
  const rsEmoji = `(?:${[rsDingbat, rsRegional, rsSurrPair].join('|')})${rsSeq}`;
107
107
 
108
+ // eslint-disable-next-line no-misleading-character-class
108
109
  const reUnicodeWords = RegExp([
109
110
  `${rsUpper}?${rsLower}+${rsOptContrLower}(?=${[rsBreak, rsUpper, '$'].join('|')})`,
110
111
  `${rsMiscUpper}+${rsOptContrUpper}(?=${[rsBreak, rsUpper + rsMiscLower, '$'].join('|')})`,
@@ -130,6 +131,7 @@ const rsNonAstralCombo = `${rsNonAstral}${rsCombo}?`;
130
131
  const rsSymbol = `(?:${[rsNonAstralCombo, rsCombo, rsRegional, rsSurrPair, rsAstral].join('|')})`;
131
132
 
132
133
  // Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode)
134
+ // eslint-disable-next-line no-misleading-character-class
133
135
  const reUnicode = RegExp(`${rsFitz}(?=${rsFitz})|${rsSymbol + rsSeq}`, 'g');
134
136
 
135
137
  const reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/;
@@ -675,6 +675,8 @@ export namespace g {
675
675
 
676
676
  moveAndExpand(r: PlainRect): this;
677
677
 
678
+ moveAroundPoint(origin: PlainPoint | string, angle: number): this;
679
+
678
680
  normalize(): this;
679
681
 
680
682
  offset(dx?: number, dy?: number): this;
package/types/joint.d.ts CHANGED
@@ -333,6 +333,7 @@ export namespace dia {
333
333
  interface GenericAttributes<T> {
334
334
  attrs?: T;
335
335
  z?: number;
336
+ layer?: string;
336
337
  [key: string]: any;
337
338
  }
338
339
 
@@ -521,6 +522,8 @@ export namespace dia {
521
522
 
522
523
  getBBox(): g.Rect;
523
524
 
525
+ getCenter(): g.Point;
526
+
524
527
  getPointFromConnectedLink(link: dia.Link, endType: dia.LinkEnd): g.Point;
525
528
 
526
529
  getPointRotatedAroundCenter(angle: number, x: number, y: number): g.Point;
@@ -573,6 +576,7 @@ export namespace dia {
573
576
  position?: PositionType;
574
577
  markup?: string | MarkupJSON;
575
578
  attrs?: Cell.Selectors;
579
+ size?: Size;
576
580
  label?: {
577
581
  markup?: string | MarkupJSON;
578
582
  position?: PositionType;
@@ -584,7 +588,11 @@ export namespace dia {
584
588
  markup?: string | MarkupJSON;
585
589
  group?: string;
586
590
  attrs?: Cell.Selectors;
591
+ position?: {
592
+ args?: { [key: string]: any };
593
+ };
587
594
  args?: { [key: string]: any };
595
+ size?: Size;
588
596
  label?: {
589
597
  markup?: string | MarkupJSON;
590
598
  position?: PositionType;
@@ -596,6 +604,10 @@ export namespace dia {
596
604
  angle: number;
597
605
  }
598
606
 
607
+ interface PortRect extends BBox {
608
+ angle: number;
609
+ }
610
+
599
611
  interface TranslateOptions extends Cell.Options {
600
612
  restrictedArea?: BBox | Paper.PointConstraintCallback;
601
613
  transition?: Cell.TransitionOptions;
@@ -610,9 +622,26 @@ export namespace dia {
610
622
  direction?: Direction;
611
623
  }
612
624
 
613
- interface BBoxOptions extends Cell.EmbeddableOptions {
625
+ interface FitToChildrenOptions {
626
+ filter?: (cell: Cell) => boolean;
627
+ deep?: boolean;
628
+ padding?: Padding;
629
+ minRect?: g.Rect;
630
+ expandOnly?: boolean;
631
+ shrinkOnly?: boolean;
632
+ }
633
+
634
+ interface FitParentOptions extends FitToChildrenOptions {
635
+ terminator?: Cell | Cell.ID;
636
+ }
637
+
638
+ interface RotateOptions {
614
639
  rotate?: boolean;
615
640
  }
641
+
642
+ interface BBoxOptions extends Cell.EmbeddableOptions, RotateOptions {
643
+
644
+ }
616
645
  }
617
646
 
618
647
  class Element<A extends ObjectHash = Element.Attributes, S extends mvc.ModelSetOptions = dia.ModelSetOptions> extends Cell<A, S> {
@@ -634,10 +663,10 @@ export namespace dia {
634
663
 
635
664
  scale(scaleX: number, scaleY: number, origin?: Point, opt?: { [key: string]: any }): this;
636
665
 
637
- fitEmbeds(opt?: { deep?: boolean, padding?: Padding, expandOnly?: boolean, shrinkOnly?: boolean }): this;
638
- fitToChildren(opt?: { deep?: boolean, padding?: Padding, expandOnly?: boolean, shrinkOnly?: boolean }): this;
666
+ fitEmbeds(opt?: Element.FitToChildrenOptions): this;
667
+ fitToChildren(opt?: Element.FitToChildrenOptions): this;
639
668
 
640
- fitParent(opt?: { deep?: boolean, padding?: Padding, expandOnly?: boolean, shrinkOnly?: boolean, terminator?: Cell | Cell.ID }): this;
669
+ fitParent(opt?: Element.FitParentOptions): this;
641
670
 
642
671
  getBBox(opt?: Element.BBoxOptions): g.Rect;
643
672
 
@@ -664,6 +693,14 @@ export namespace dia {
664
693
 
665
694
  getPortsPositions(groupName: string): { [id: string]: Element.PortPosition };
666
695
 
696
+ getPortRelativePosition(portId: string): Element.PortPosition;
697
+
698
+ getPortRelativeRect(portId: string): Element.PortRect;
699
+
700
+ getPortCenter(portId: string): g.Point;
701
+
702
+ getPortBBox(portId: string, opt?: Element.RotateOptions): g.Rect;
703
+
667
704
  getPortIndex(port: string | Element.Port): number;
668
705
 
669
706
  getPortGroupNames(): string[];
@@ -946,6 +983,10 @@ export namespace dia {
946
983
 
947
984
  isIntersecting(geometryShape: g.Shape, geometryData?: g.SegmentSubdivisionsOpt | null): boolean;
948
985
 
986
+ cleanNodesCache(): void;
987
+
988
+ cleanNodeCache(node: SVGElement): void
989
+
949
990
  protected isEnclosedIn(area: g.Rect): boolean;
950
991
 
951
992
  protected isInArea(area: g.Rect, options: g.StrictOpt): boolean;
@@ -1002,8 +1043,6 @@ export namespace dia {
1002
1043
 
1003
1044
  protected addLinkFromMagnet(magnet: SVGElement, x: number, y: number): LinkView;
1004
1045
 
1005
- protected cleanNodesCache(): void;
1006
-
1007
1046
  protected nodeCache(magnet: SVGElement): CellView.NodeMetrics;
1008
1047
 
1009
1048
  protected getNodeData(magnet: SVGElement): CellView.NodeData;
@@ -1090,6 +1129,8 @@ export namespace dia {
1090
1129
 
1091
1130
  protected dragMagnetEnd(evt: dia.Event, x: number, y: number): void;
1092
1131
 
1132
+ protected snapToGrid(evt: dia.Event, x: number, y: number): dia.Point;
1133
+
1093
1134
  protected prepareEmbedding(data: any): void;
1094
1135
 
1095
1136
  protected processEmbedding(data: any, evt: dia.Event, x: number, y: number): void;
@@ -1363,6 +1404,7 @@ export namespace dia {
1363
1404
  type RestrictTranslateCallback = (elementView: ElementView, x0: number, y0: number) => BBox | boolean | PointConstraintCallback;
1364
1405
  type FindParentByType = 'bbox' | 'pointer' | PositionName;
1365
1406
  type FindParentByCallback = ((this: dia.Graph, elementView: ElementView, evt: dia.Event, x: number, y: number) => Cell[]);
1407
+ type MeasureNodeCallback = (node: SVGGraphicsElement, cellView: dia.CellView) => g.Rect;
1366
1408
 
1367
1409
  interface Options extends mvc.ViewOptions<Graph> {
1368
1410
  // appearance
@@ -1398,6 +1440,7 @@ export namespace dia {
1398
1440
  // views
1399
1441
  elementView?: typeof ElementView | ((element: Element) => typeof ElementView);
1400
1442
  linkView?: typeof LinkView | ((link: Link) => typeof LinkView);
1443
+ measureNode?: MeasureNodeCallback;
1401
1444
  // embedding
1402
1445
  embeddingMode?: boolean;
1403
1446
  frontParentOnly?: boolean;
@@ -1749,7 +1792,7 @@ export namespace dia {
1749
1792
 
1750
1793
  getLayerNode(layerName: Paper.Layers | string): SVGGElement;
1751
1794
 
1752
- getLayerView(layerName: Paper.Layers | string): any;
1795
+ getLayerView(layerName: Paper.Layers | string): PaperLayer;
1753
1796
 
1754
1797
  hasLayerView(layerName: Paper.Layers | string): boolean;
1755
1798
 
@@ -1759,6 +1802,18 @@ export namespace dia {
1759
1802
 
1760
1803
  protected resetLayers(): void;
1761
1804
 
1805
+ addLayer(layerName: string, layerView: PaperLayer, options?: { insertBefore?: string }): void;
1806
+
1807
+ removeLayer(layer: string | PaperLayer): void;
1808
+
1809
+ moveLayer(layer: string | PaperLayer, insertBefore: string | PaperLayer | null): void;
1810
+
1811
+ hasLayer(layer: string | PaperLayer): boolean;
1812
+
1813
+ getLayerNames(): string[];
1814
+
1815
+ getLayers(): Array<PaperLayer>;
1816
+
1762
1817
  // rendering
1763
1818
 
1764
1819
  freeze(opt?: Paper.FreezeOptions): void;
@@ -2622,20 +2677,22 @@ export namespace util {
2622
2677
  export function isPercentage(val: any): boolean;
2623
2678
 
2624
2679
  export function parseCssNumeric(val: any, restrictUnits: string | string[]): { value: number, unit?: string } | null;
2625
-
2680
+
2681
+ type BreakTextOptions = {
2682
+ svgDocument?: SVGElement;
2683
+ separator?: string | any;
2684
+ eol?: string;
2685
+ ellipsis?: boolean | string;
2686
+ hyphen?: string | RegExp;
2687
+ maxLineCount?: number;
2688
+ preserveSpaces?: boolean;
2689
+ }
2690
+
2626
2691
  type BreakTextFunction = (
2627
2692
  text: string,
2628
2693
  size: { width: number, height?: number },
2629
2694
  attrs?: attributes.NativeSVGAttributes,
2630
- opt?: {
2631
- svgDocument?: SVGElement;
2632
- separator?: string | any;
2633
- eol?: string;
2634
- ellipsis?: boolean | string;
2635
- hyphen?: string | RegExp;
2636
- maxLineCount?: number;
2637
- preserveSpaces?: boolean;
2638
- }
2695
+ opt?: BreakTextOptions
2639
2696
  ) => string;
2640
2697
 
2641
2698
  export var breakText: BreakTextFunction;
@@ -3429,7 +3486,7 @@ export namespace mvc {
3429
3486
 
3430
3487
  /**
3431
3488
  * Events hash or a method returning the events hash that maps events/selectors to methods on your View.
3432
- * For assigning events as object hash, do it like this: this.events = <any>{ "event:selector": callback, ... };
3489
+ * For assigning events as object hash, do it like this: `this.events = <any>{ "event:selector": callback, ... };`
3433
3490
  * That works only if you set it in the constructor or the initialize method.
3434
3491
  */
3435
3492
  events(): EventsHash;
@@ -3782,7 +3839,11 @@ export namespace connectors {
3782
3839
 
3783
3840
  export namespace anchors {
3784
3841
 
3785
- interface RotateAnchorArguments {
3842
+ interface ElementAnchorArguments {
3843
+ useModelGeometry?: boolean;
3844
+ }
3845
+
3846
+ interface RotateAnchorArguments extends ElementAnchorArguments {
3786
3847
  rotate?: boolean;
3787
3848
  }
3788
3849
 
@@ -3791,7 +3852,7 @@ export namespace anchors {
3791
3852
  dy?: number | string;
3792
3853
  }
3793
3854
 
3794
- interface PaddingAnchorArguments {
3855
+ interface PaddingAnchorArguments extends ElementAnchorArguments {
3795
3856
  padding?: number;
3796
3857
  }
3797
3858
 
File without changes