@eclipse-glsp/client 2.7.0-next.3 → 2.7.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 (167) hide show
  1. package/lib/base/action-dispatcher.d.ts +2 -1
  2. package/lib/base/action-dispatcher.d.ts.map +1 -1
  3. package/lib/base/action-dispatcher.js +48 -24
  4. package/lib/base/action-dispatcher.js.map +1 -1
  5. package/lib/base/default.module.d.ts.map +1 -1
  6. package/lib/base/default.module.js +2 -0
  7. package/lib/base/default.module.js.map +1 -1
  8. package/lib/base/editor-context-service.d.ts +4 -3
  9. package/lib/base/editor-context-service.d.ts.map +1 -1
  10. package/lib/base/editor-context-service.js +11 -1
  11. package/lib/base/editor-context-service.js.map +1 -1
  12. package/lib/base/model/diagram-loader.d.ts +8 -6
  13. package/lib/base/model/diagram-loader.d.ts.map +1 -1
  14. package/lib/base/model/diagram-loader.js +1 -1
  15. package/lib/base/model/diagram-loader.js.map +1 -1
  16. package/lib/base/model/glsp-model-source.d.ts +5 -2
  17. package/lib/base/model/glsp-model-source.d.ts.map +1 -1
  18. package/lib/base/model/glsp-model-source.js +28 -1
  19. package/lib/base/model/glsp-model-source.js.map +1 -1
  20. package/lib/base/selection-service.d.ts +4 -3
  21. package/lib/base/selection-service.d.ts.map +1 -1
  22. package/lib/base/selection-service.js +6 -1
  23. package/lib/base/selection-service.js.map +1 -1
  24. package/lib/base/shortcuts/available-shortcuts-extension.d.ts +1 -1
  25. package/lib/base/shortcuts/available-shortcuts-extension.d.ts.map +1 -1
  26. package/lib/base/shortcuts/available-shortcuts-extension.js +3 -4
  27. package/lib/base/shortcuts/available-shortcuts-extension.js.map +1 -1
  28. package/lib/base/view/mouse-tool.d.ts +1 -1
  29. package/lib/base/view/mouse-tool.d.ts.map +1 -1
  30. package/lib/base/view/mouse-tool.js +3 -19
  31. package/lib/base/view/mouse-tool.js.map +1 -1
  32. package/lib/features/change-bounds/move-element-handler.d.ts +2 -3
  33. package/lib/features/change-bounds/move-element-handler.d.ts.map +1 -1
  34. package/lib/features/change-bounds/move-element-handler.js +2 -3
  35. package/lib/features/change-bounds/move-element-handler.js.map +1 -1
  36. package/lib/features/change-bounds/resize/resize-handler.d.ts +2 -3
  37. package/lib/features/change-bounds/resize/resize-handler.d.ts.map +1 -1
  38. package/lib/features/change-bounds/resize/resize-handler.js +2 -3
  39. package/lib/features/change-bounds/resize/resize-handler.js.map +1 -1
  40. package/lib/features/export/default-png-diagram-exporter.d.ts +52 -0
  41. package/lib/features/export/default-png-diagram-exporter.d.ts.map +1 -0
  42. package/lib/features/export/default-png-diagram-exporter.js +157 -0
  43. package/lib/features/export/default-png-diagram-exporter.js.map +1 -0
  44. package/lib/features/export/default-svg-diagram-exporter.d.ts +32 -0
  45. package/lib/features/export/default-svg-diagram-exporter.d.ts.map +1 -0
  46. package/lib/features/export/default-svg-diagram-exporter.js +54 -0
  47. package/lib/features/export/default-svg-diagram-exporter.js.map +1 -0
  48. package/lib/features/export/diagram-export-postprocessor.d.ts +33 -0
  49. package/lib/features/export/diagram-export-postprocessor.d.ts.map +1 -0
  50. package/lib/features/export/diagram-export-postprocessor.js +84 -0
  51. package/lib/features/export/diagram-export-postprocessor.js.map +1 -0
  52. package/lib/features/export/diagram-exporter.d.ts +44 -0
  53. package/lib/features/export/diagram-exporter.d.ts.map +1 -0
  54. package/lib/features/export/diagram-exporter.js +18 -0
  55. package/lib/features/export/diagram-exporter.js.map +1 -0
  56. package/lib/features/export/export-modules.d.ts +1 -1
  57. package/lib/features/export/export-modules.d.ts.map +1 -1
  58. package/lib/features/export/export-modules.js +20 -3
  59. package/lib/features/export/export-modules.js.map +1 -1
  60. package/lib/features/export/export-result-action-handler.d.ts +28 -0
  61. package/lib/features/export/export-result-action-handler.d.ts.map +1 -0
  62. package/lib/features/export/export-result-action-handler.js +72 -0
  63. package/lib/features/export/export-result-action-handler.js.map +1 -0
  64. package/lib/features/export/export-svg-action-handler.d.ts +19 -0
  65. package/lib/features/export/export-svg-action-handler.d.ts.map +1 -1
  66. package/lib/features/export/export-svg-action-handler.js +4 -15
  67. package/lib/features/export/export-svg-action-handler.js.map +1 -1
  68. package/lib/features/export/glsp-svg-exporter.d.ts +18 -1
  69. package/lib/features/export/glsp-svg-exporter.d.ts.map +1 -1
  70. package/lib/features/export/glsp-svg-exporter.js +44 -11
  71. package/lib/features/export/glsp-svg-exporter.js.map +1 -1
  72. package/lib/features/export/request-export-command.d.ts +29 -0
  73. package/lib/features/export/request-export-command.d.ts.map +1 -0
  74. package/lib/features/export/request-export-command.js +73 -0
  75. package/lib/features/export/request-export-command.js.map +1 -0
  76. package/lib/features/export/request-export-key-listener.d.ts +21 -0
  77. package/lib/features/export/request-export-key-listener.d.ts.map +1 -0
  78. package/lib/features/export/request-export-key-listener.js +40 -0
  79. package/lib/features/export/request-export-key-listener.js.map +1 -0
  80. package/lib/features/helper-lines/helper-line-feedback.d.ts +1 -1
  81. package/lib/features/helper-lines/helper-line-feedback.d.ts.map +1 -1
  82. package/lib/features/helper-lines/helper-line-feedback.js +2 -3
  83. package/lib/features/helper-lines/helper-line-feedback.js.map +1 -1
  84. package/lib/features/label-edit-ui/label-edit-ui.d.ts +1 -1
  85. package/lib/features/label-edit-ui/label-edit-ui.js +1 -1
  86. package/lib/features/routing/edge-router.d.ts +2 -1
  87. package/lib/features/routing/edge-router.d.ts.map +1 -1
  88. package/lib/features/routing/edge-router.js +2 -1
  89. package/lib/features/routing/edge-router.js.map +1 -1
  90. package/lib/features/routing/routing-module.d.ts +1 -1
  91. package/lib/features/routing/routing-module.d.ts.map +1 -1
  92. package/lib/features/routing/routing-module.js +7 -1
  93. package/lib/features/routing/routing-module.js.map +1 -1
  94. package/lib/features/routing/sticky-manhattan-anchors.d.ts +29 -0
  95. package/lib/features/routing/sticky-manhattan-anchors.d.ts.map +1 -0
  96. package/lib/features/routing/sticky-manhattan-anchors.js +62 -0
  97. package/lib/features/routing/sticky-manhattan-anchors.js.map +1 -0
  98. package/lib/features/routing/sticky-manhattan-edge-router.d.ts +107 -0
  99. package/lib/features/routing/sticky-manhattan-edge-router.d.ts.map +1 -0
  100. package/lib/features/routing/sticky-manhattan-edge-router.js +626 -0
  101. package/lib/features/routing/sticky-manhattan-edge-router.js.map +1 -0
  102. package/lib/features/search-palette/search-palette.d.ts +2 -2
  103. package/lib/features/search-palette/search-palette.d.ts.map +1 -1
  104. package/lib/features/search-palette/search-palette.js +3 -4
  105. package/lib/features/search-palette/search-palette.js.map +1 -1
  106. package/lib/features/select/select-module.d.ts +1 -1
  107. package/lib/features/select/select-module.js +1 -1
  108. package/lib/features/tool-palette/tool-palette.d.ts.map +1 -1
  109. package/lib/features/tool-palette/tool-palette.js +1 -2
  110. package/lib/features/tool-palette/tool-palette.js.map +1 -1
  111. package/lib/features/tools/change-bounds/change-bounds-tool-move-feedback.d.ts +2 -3
  112. package/lib/features/tools/change-bounds/change-bounds-tool-move-feedback.d.ts.map +1 -1
  113. package/lib/features/tools/change-bounds/change-bounds-tool-move-feedback.js +2 -3
  114. package/lib/features/tools/change-bounds/change-bounds-tool-move-feedback.js.map +1 -1
  115. package/lib/features/viewport/origin-viewport.d.ts +2 -13
  116. package/lib/features/viewport/origin-viewport.d.ts.map +1 -1
  117. package/lib/features/viewport/origin-viewport.js +3 -19
  118. package/lib/features/viewport/origin-viewport.js.map +1 -1
  119. package/lib/index.d.ts +11 -1
  120. package/lib/index.d.ts.map +1 -1
  121. package/lib/index.js +11 -1
  122. package/lib/index.js.map +1 -1
  123. package/lib/views/gedge-view-with-gaps-on-intersections.d.ts +39 -0
  124. package/lib/views/gedge-view-with-gaps-on-intersections.d.ts.map +1 -0
  125. package/lib/views/gedge-view-with-gaps-on-intersections.js +85 -0
  126. package/lib/views/gedge-view-with-gaps-on-intersections.js.map +1 -0
  127. package/lib/views/rounded-corner-manhattan-edge-view.d.ts +58 -0
  128. package/lib/views/rounded-corner-manhattan-edge-view.d.ts.map +1 -0
  129. package/lib/views/rounded-corner-manhattan-edge-view.js +170 -0
  130. package/lib/views/rounded-corner-manhattan-edge-view.js.map +1 -0
  131. package/package.json +4 -6
  132. package/src/base/action-dispatcher.spec.ts +103 -3
  133. package/src/base/action-dispatcher.ts +50 -25
  134. package/src/base/default.module.ts +4 -0
  135. package/src/base/editor-context-service.ts +17 -5
  136. package/src/base/model/diagram-loader.ts +8 -6
  137. package/src/base/model/glsp-model-source.ts +35 -1
  138. package/src/base/selection-service.ts +11 -2
  139. package/src/base/shortcuts/available-shortcuts-extension.ts +3 -4
  140. package/src/base/view/mouse-tool.ts +4 -19
  141. package/src/features/change-bounds/move-element-handler.ts +3 -2
  142. package/src/features/change-bounds/resize/resize-handler.ts +4 -3
  143. package/src/features/export/default-png-diagram-exporter.ts +145 -0
  144. package/src/features/export/default-svg-diagram-exporter.ts +39 -0
  145. package/src/features/export/diagram-export-postprocessor.ts +82 -0
  146. package/src/features/export/diagram-exporter.ts +45 -0
  147. package/src/features/export/export-modules.ts +24 -4
  148. package/src/features/export/export-result-action-handler.ts +66 -0
  149. package/src/features/export/export-svg-action-handler.ts +7 -2
  150. package/src/features/export/glsp-svg-exporter.ts +48 -12
  151. package/src/features/export/request-export-command.ts +65 -0
  152. package/src/features/export/request-export-key-listener.ts +29 -0
  153. package/src/features/helper-lines/helper-line-feedback.ts +6 -4
  154. package/src/features/label-edit-ui/label-edit-ui.ts +1 -1
  155. package/src/features/routing/edge-router.ts +2 -2
  156. package/src/features/routing/routing-module.ts +8 -1
  157. package/src/features/routing/sticky-manhattan-anchors.ts +53 -0
  158. package/src/features/routing/sticky-manhattan-edge-router.spec.ts +212 -0
  159. package/src/features/routing/sticky-manhattan-edge-router.ts +713 -0
  160. package/src/features/search-palette/search-palette.ts +3 -4
  161. package/src/features/select/select-module.ts +1 -1
  162. package/src/features/tool-palette/tool-palette.ts +1 -1
  163. package/src/features/tools/change-bounds/change-bounds-tool-move-feedback.ts +13 -3
  164. package/src/features/viewport/origin-viewport.ts +10 -23
  165. package/src/index.ts +11 -1
  166. package/src/views/gedge-view-with-gaps-on-intersections.tsx +99 -0
  167. package/src/views/rounded-corner-manhattan-edge-view.ts +171 -0
@@ -0,0 +1,626 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var GLSPStickyManhattanEdgeRouter_1;
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.GLSPStickyManhattanEdgeRouter = void 0;
11
+ /********************************************************************************
12
+ * Copyright (c) 2022-2026 Imixs Software Solutions GmbH.
13
+ * Copyright (c) 2026 EclipseSource and others.
14
+ *
15
+ * This program and the accompanying materials are made available under the
16
+ * terms of the Eclipse Public License v. 2.0 which is available at
17
+ * http://www.eclipse.org/legal/epl-2.0.
18
+ *
19
+ * This Source Code may also be made available under the following Secondary
20
+ * Licenses when the conditions for such availability set forth in the Eclipse
21
+ * Public License v. 2.0 are satisfied: GNU General Public License, version 2
22
+ * with the GNU Classpath Exception which is available at
23
+ * https://www.gnu.org/software/classpath/license.html.
24
+ *
25
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
26
+ ********************************************************************************/
27
+ const sprotty_1 = require("@eclipse-glsp/sprotty");
28
+ const inversify_1 = require("inversify");
29
+ const edge_router_1 = require("./edge-router");
30
+ /**
31
+ * An alternative Manhattan-style edge router that preserves existing bend points.
32
+ *
33
+ * In contrast to the standard {@link GLSPManhattanEdgeRouter} which recomputes the
34
+ * full route whenever a connected node moves, this router only adjusts the corner
35
+ * adjacent to the moved endpoint. Intermediate bend points are kept in place, which
36
+ * results in more predictable routing when users reposition nodes in complex
37
+ * diagrams.
38
+ *
39
+ * Opt-in per edge by setting `edge.routerKind = 'sticky-manhattan'`.
40
+ *
41
+ * @experimental The API surface and implementation details of this router may
42
+ * change in future releases, potentially in breaking ways, as we iterate on the
43
+ * initial implementation.
44
+ *
45
+ * Based on the original `BPMNManhattanRouter` by Ralph Soika (Imixs Software
46
+ * Solutions GmbH), contributed via https://github.com/eclipse-glsp/glsp/discussions/1642.
47
+ */
48
+ let GLSPStickyManhattanEdgeRouter = GLSPStickyManhattanEdgeRouter_1 = class GLSPStickyManhattanEdgeRouter extends edge_router_1.GLSPAbstractEdgeRouter {
49
+ constructor() {
50
+ super(...arguments);
51
+ /** Move-detection baseline: source/target bounds at the last persistence. */
52
+ this.elementPositions = new WeakMap();
53
+ }
54
+ get kind() {
55
+ return GLSPStickyManhattanEdgeRouter_1.KIND;
56
+ }
57
+ getOptions(edge) {
58
+ return {
59
+ standardDistance: 20,
60
+ minimalPointDistance: 3,
61
+ selfEdgeOffset: 0.25,
62
+ axisTolerance: 1
63
+ };
64
+ }
65
+ route(edge) {
66
+ var _a, _b;
67
+ if (!edge.source || !edge.target || !edge.source.bounds || !edge.target.bounds) {
68
+ return [];
69
+ }
70
+ const routedCorners = this.createRoutedCorners(edge);
71
+ const sourceRefPoint = (_a = routedCorners[0]) !== null && _a !== void 0 ? _a : sprotty_1.Bounds.center(edge.target.bounds);
72
+ const targetRefPoint = (_b = routedCorners[routedCorners.length - 1]) !== null && _b !== void 0 ? _b : sprotty_1.Bounds.center(edge.source.bounds);
73
+ const sourceAnchor = this.getTranslatedAnchor(edge.source, sourceRefPoint, edge.parent, edge, edge.sourceAnchorCorrection);
74
+ const targetAnchor = this.getTranslatedAnchor(edge.target, targetRefPoint, edge.parent, edge, edge.targetAnchorCorrection);
75
+ if (!sourceAnchor || !targetAnchor) {
76
+ return [];
77
+ }
78
+ const result = [];
79
+ result.push({ kind: 'source', ...sourceAnchor });
80
+ routedCorners.forEach(corner => result.push(corner));
81
+ result.push({ kind: 'target', ...targetAnchor });
82
+ // Guard against NaN coordinates which would break path rendering downstream.
83
+ const sanitized = result.filter(p => !isNaN(p.x) && !isNaN(p.y));
84
+ if (sanitized.length < 2) {
85
+ return [];
86
+ }
87
+ return sanitized;
88
+ }
89
+ commitRoute(edge, routedPoints) {
90
+ super.commitRoute(edge, routedPoints);
91
+ this.captureBaseline(edge);
92
+ }
93
+ /** Snapshots current source/target bounds as the move-detection baseline. */
94
+ captureBaseline(edge) {
95
+ var _a, _b;
96
+ if (((_a = edge.source) === null || _a === void 0 ? void 0 : _a.bounds) && ((_b = edge.target) === null || _b === void 0 ? void 0 : _b.bounds)) {
97
+ this.elementPositions.set(edge, {
98
+ sourceX: edge.source.bounds.x,
99
+ sourceY: edge.source.bounds.y,
100
+ targetX: edge.target.bounds.x,
101
+ targetY: edge.target.bounds.y
102
+ });
103
+ }
104
+ }
105
+ /**
106
+ * Computes the intermediate corner points between source and target anchors.
107
+ *
108
+ * If the edge already has routing points and the connected nodes have moved
109
+ * since the previous route, the existing corners are preserved and only the
110
+ * endpoints closest to the moved node(s) slide along their constrained axis.
111
+ * Otherwise the corners are recomputed from scratch based on the current node
112
+ * geometry.
113
+ */
114
+ createRoutedCorners(edge) {
115
+ var _a, _b;
116
+ if (!((_a = edge.source) === null || _a === void 0 ? void 0 : _a.bounds) || !((_b = edge.target) === null || _b === void 0 ? void 0 : _b.bounds)) {
117
+ return [];
118
+ }
119
+ if (edge.routingPoints && edge.routingPoints.length > 0) {
120
+ const srcBounds = edge.source.bounds;
121
+ const tgtBounds = edge.target.bounds;
122
+ const lastPos = this.elementPositions.get(edge);
123
+ const elementMoved = lastPos !== undefined &&
124
+ (lastPos.sourceX !== srcBounds.x ||
125
+ lastPos.sourceY !== srcBounds.y ||
126
+ lastPos.targetX !== tgtBounds.x ||
127
+ lastPos.targetY !== tgtBounds.y);
128
+ // Seed the baseline on first sight; later refreshes happen in
129
+ // commitRoute / cleanupRoutingPoints to keep route() pure.
130
+ if (lastPos === undefined) {
131
+ this.elementPositions.set(edge, {
132
+ sourceX: srcBounds.x,
133
+ sourceY: srcBounds.y,
134
+ targetX: tgtBounds.x,
135
+ targetY: tgtBounds.y
136
+ });
137
+ }
138
+ const points = edge.routingPoints.slice();
139
+ const sourceAnchors = new sprotty_1.DefaultAnchors(edge.source, edge.parent, 'source');
140
+ const targetAnchors = new sprotty_1.DefaultAnchors(edge.target, edge.parent, 'target');
141
+ if (elementMoved) {
142
+ // Follow-adjust endpoints; rendering-only, edge.routingPoints
143
+ // is persisted via commitRoute.
144
+ this.applyFollowLogic(points, edge, sourceAnchors);
145
+ this.cleanupRoutingPoints(edge, points, false, false, sourceAnchors, targetAnchors);
146
+ }
147
+ else {
148
+ this.cleanupRoutingPoints(edge, points, false, true, sourceAnchors, targetAnchors);
149
+ }
150
+ if (points.length > 0) {
151
+ return points.map((rp, index) => ({
152
+ kind: 'linear',
153
+ pointIndex: index,
154
+ x: rp.x,
155
+ y: rp.y
156
+ }));
157
+ }
158
+ }
159
+ // Fresh-default fallback: drop the baseline so the next real route re-seeds.
160
+ this.elementPositions.delete(edge);
161
+ const sourceAnchors = new sprotty_1.DefaultAnchors(edge.source, edge.parent, 'source');
162
+ const targetAnchors = new sprotty_1.DefaultAnchors(edge.target, edge.parent, 'target');
163
+ const options = this.getOptions(edge);
164
+ const bestAnchors = this.getBestConnectionAnchors(sourceAnchors, targetAnchors, options);
165
+ const corners = this.calculateCorners(sourceAnchors, targetAnchors, bestAnchors, options);
166
+ return corners.map((corner, index) => ({
167
+ kind: 'linear',
168
+ pointIndex: index,
169
+ x: corner.x,
170
+ y: corner.y
171
+ }));
172
+ }
173
+ /**
174
+ * Adjusts the endpoints of the existing route so they follow the moved node(s).
175
+ * The corner adjacent to a moved endpoint slides along its constrained axis so
176
+ * that the route stays orthogonal without discarding intermediate bend points.
177
+ */
178
+ applyFollowLogic(points, edge, sourceAnchors) {
179
+ const sourceAnchor = this.getTranslatedAnchor(edge.source, points[0], edge.parent, edge, edge.sourceAnchorCorrection);
180
+ const targetAnchor = this.getTranslatedAnchor(edge.target, points[points.length - 1], edge.parent, edge, edge.targetAnchorCorrection);
181
+ if (!sourceAnchor || !targetAnchor) {
182
+ return;
183
+ }
184
+ const { axisTolerance } = this.getOptions(edge);
185
+ if (points.length === 1) {
186
+ // Classify the first segment via the source side closest to the bend — this
187
+ // matches how the Manhattan anchor computer picks the source anchor.
188
+ sourceAnchors !== null && sourceAnchors !== void 0 ? sourceAnchors : (sourceAnchors = new sprotty_1.DefaultAnchors(edge.source, edge.parent, 'source'));
189
+ const side = sourceAnchors.getNearestSide(points[0]);
190
+ const isVertical = side === sprotty_1.Side.TOP || side === sprotty_1.Side.BOTTOM;
191
+ if (isVertical) {
192
+ points[0] = { x: sourceAnchor.x, y: sprotty_1.Bounds.center(edge.target.bounds).y };
193
+ }
194
+ else {
195
+ points[0] = { x: sprotty_1.Bounds.center(edge.target.bounds).x, y: sourceAnchor.y };
196
+ }
197
+ return;
198
+ }
199
+ // First corner follows the source element.
200
+ if (sprotty_1.Point.isVerticalAligned(points[0], points[1], axisTolerance)) {
201
+ points[0] = { x: points[0].x, y: sprotty_1.Bounds.center(edge.source.bounds).y };
202
+ }
203
+ else {
204
+ points[0] = { x: sprotty_1.Bounds.center(edge.source.bounds).x, y: points[0].y };
205
+ }
206
+ // Last corner follows the target element.
207
+ const last = points.length - 1;
208
+ if (sprotty_1.Point.isVerticalAligned(points[last], points[last - 1], axisTolerance)) {
209
+ points[last] = { x: points[last].x, y: sprotty_1.Bounds.center(edge.target.bounds).y };
210
+ }
211
+ else {
212
+ points[last] = { x: sprotty_1.Bounds.center(edge.target.bounds).x, y: points[last].y };
213
+ }
214
+ }
215
+ createRoutingHandles(edge) {
216
+ const routedPoints = this.route(edge);
217
+ this.commitRoute(edge, routedPoints);
218
+ if (routedPoints.length > 0) {
219
+ this.addHandle(edge, 'source', 'routing-point', -2);
220
+ for (let i = 0; i < routedPoints.length - 1; i++) {
221
+ this.addHandle(edge, 'manhattan-50%', 'volatile-routing-point', i - 1);
222
+ }
223
+ this.addHandle(edge, 'target', 'routing-point', routedPoints.length - 2);
224
+ }
225
+ }
226
+ getInnerHandlePosition(edge, route, handle) {
227
+ if (handle.kind === 'manhattan-50%') {
228
+ const { start, end } = this.findRouteSegment(edge, route, handle.pointIndex);
229
+ if (start !== undefined && end !== undefined) {
230
+ return sprotty_1.Point.linear(start, end, 0.5);
231
+ }
232
+ }
233
+ return undefined;
234
+ }
235
+ applyInnerHandleMoves(edge, moves) {
236
+ const route = this.route(edge);
237
+ const routingPoints = edge.routingPoints;
238
+ const { minimalPointDistance, axisTolerance } = this.getOptions(edge);
239
+ moves.forEach(move => {
240
+ const handle = move.handle;
241
+ const index = handle.pointIndex;
242
+ if (handle.kind !== 'manhattan-50%') {
243
+ return;
244
+ }
245
+ const correctedX = this.correctX(routingPoints, index, move.toPosition.x, minimalPointDistance);
246
+ const correctedY = this.correctY(routingPoints, index, move.toPosition.y, minimalPointDistance);
247
+ if (index < 0) {
248
+ // First segment: source anchor → first corner.
249
+ if (routingPoints.length === 0) {
250
+ routingPoints.push({ x: correctedX, y: correctedY });
251
+ handle.pointIndex = 0;
252
+ }
253
+ else if (sprotty_1.Point.isVerticalAligned(route[0], route[1], axisTolerance)) {
254
+ this.alignX(routingPoints, 0, correctedX);
255
+ }
256
+ else {
257
+ this.alignY(routingPoints, 0, correctedY);
258
+ }
259
+ }
260
+ else if (index < routingPoints.length - 1) {
261
+ // Inner segment: move both endpoints of the segment in lockstep.
262
+ if (sprotty_1.Point.isVerticalAligned(routingPoints[index], routingPoints[index + 1], axisTolerance)) {
263
+ this.alignX(routingPoints, index, correctedX);
264
+ this.alignX(routingPoints, index + 1, correctedX);
265
+ }
266
+ else {
267
+ this.alignY(routingPoints, index, correctedY);
268
+ this.alignY(routingPoints, index + 1, correctedY);
269
+ }
270
+ }
271
+ else {
272
+ // Last segment: last corner → target anchor.
273
+ if (routingPoints.length === 0) {
274
+ routingPoints.push({ x: correctedX, y: correctedY });
275
+ handle.pointIndex = 0;
276
+ }
277
+ else if (sprotty_1.Point.isVerticalAligned(route[route.length - 2], route[route.length - 1], axisTolerance)) {
278
+ this.alignX(routingPoints, routingPoints.length - 1, correctedX);
279
+ }
280
+ else {
281
+ this.alignY(routingPoints, routingPoints.length - 1, correctedY);
282
+ }
283
+ }
284
+ });
285
+ }
286
+ cleanupRoutingPoints(edge, routingPoints, updateHandles, addRoutingPoints, sourceAnchors, targetAnchors) {
287
+ if (!(0, edge_router_1.ensureBounds)(edge.source) || !(0, edge_router_1.ensureBounds)(edge.target)) {
288
+ return;
289
+ }
290
+ sourceAnchors !== null && sourceAnchors !== void 0 ? sourceAnchors : (sourceAnchors = new sprotty_1.DefaultAnchors(edge.source, edge.parent, 'source'));
291
+ targetAnchors !== null && targetAnchors !== void 0 ? targetAnchors : (targetAnchors = new sprotty_1.DefaultAnchors(edge.target, edge.parent, 'target'));
292
+ const options = this.getOptions(edge);
293
+ // Persistence-style cleanup (applyHandleMoves / applyReconnect): refresh
294
+ // baseline so route() doesn't re-follow the committed coordinates.
295
+ if (updateHandles) {
296
+ this.captureBaseline(edge);
297
+ }
298
+ if (this.resetRoutingPointsOnReconnect(edge, routingPoints, updateHandles, sourceAnchors, targetAnchors)) {
299
+ return;
300
+ }
301
+ // Remove leading routing points that fall inside the source bounds.
302
+ for (let i = 0; i < routingPoints.length; i++) {
303
+ if (sprotty_1.Bounds.includes(sourceAnchors.bounds, routingPoints[i])) {
304
+ routingPoints.splice(0, 1);
305
+ if (updateHandles) {
306
+ this.removeHandle(edge, -1);
307
+ }
308
+ i--;
309
+ }
310
+ else {
311
+ break;
312
+ }
313
+ }
314
+ // Remove trailing routing points that fall inside the target bounds.
315
+ for (let i = routingPoints.length - 1; i >= 0; i--) {
316
+ if (sprotty_1.Bounds.includes(targetAnchors.bounds, routingPoints[i])) {
317
+ routingPoints.splice(i, 1);
318
+ if (updateHandles) {
319
+ this.removeHandle(edge, i);
320
+ }
321
+ }
322
+ else {
323
+ break;
324
+ }
325
+ }
326
+ // Collapse degenerate segments shorter than minimalPointDistance.
327
+ if (routingPoints.length >= 2) {
328
+ for (let i = routingPoints.length - 2; i >= 0; i--) {
329
+ if (sprotty_1.Point.manhattanDistance(routingPoints[i], routingPoints[i + 1]) < options.minimalPointDistance) {
330
+ routingPoints.splice(i, 2);
331
+ i--;
332
+ if (updateHandles) {
333
+ this.removeHandle(edge, i - 1);
334
+ this.removeHandle(edge, i);
335
+ }
336
+ }
337
+ }
338
+ }
339
+ if (addRoutingPoints) {
340
+ this.addAdditionalCorner(edge, routingPoints, sourceAnchors, targetAnchors, updateHandles);
341
+ this.addAdditionalCorner(edge, routingPoints, targetAnchors, sourceAnchors, updateHandles);
342
+ this.manhattanify(routingPoints, edge);
343
+ }
344
+ }
345
+ removeHandle(edge, pointIndex) {
346
+ const toBeRemoved = [];
347
+ edge.children.forEach(child => {
348
+ if (child instanceof sprotty_1.GRoutingHandle) {
349
+ if (child.pointIndex > pointIndex) {
350
+ child.pointIndex--;
351
+ }
352
+ else if (child.pointIndex === pointIndex) {
353
+ toBeRemoved.push(child);
354
+ }
355
+ }
356
+ });
357
+ toBeRemoved.forEach(child => edge.remove(child));
358
+ }
359
+ /**
360
+ * Inserts an additional corner when the first/last routing point is outside
361
+ * the node bounds in the direction of the adjacent segment. This keeps the
362
+ * route orthogonal after routing points have been dragged outside the node.
363
+ */
364
+ addAdditionalCorner(edge, points, currentAnchors, otherAnchors, updateHandles) {
365
+ if (points.length === 0) {
366
+ return;
367
+ }
368
+ const isSource = currentAnchors.kind === 'source';
369
+ const refPoint = isSource ? points[0] : points[points.length - 1];
370
+ const insertIndex = isSource ? 0 : points.length;
371
+ const shiftIndex = insertIndex - (isSource ? 1 : 0);
372
+ const { axisTolerance } = this.getOptions(edge);
373
+ let isHorizontal;
374
+ if (points.length > 1) {
375
+ isHorizontal = isSource
376
+ ? sprotty_1.Point.isVerticalAligned(points[0], points[1], axisTolerance)
377
+ : sprotty_1.Point.isVerticalAligned(points[points.length - 1], points[points.length - 2], axisTolerance);
378
+ }
379
+ else {
380
+ const nearestSide = otherAnchors.getNearestSide(refPoint);
381
+ isHorizontal = nearestSide === sprotty_1.Side.TOP || nearestSide === sprotty_1.Side.BOTTOM;
382
+ }
383
+ if (isHorizontal) {
384
+ const topY = currentAnchors.get(sprotty_1.Side.TOP).y;
385
+ const bottomY = currentAnchors.get(sprotty_1.Side.BOTTOM).y;
386
+ if (refPoint.y < topY || refPoint.y > bottomY) {
387
+ const newPoint = { x: currentAnchors.get(sprotty_1.Side.TOP).x, y: refPoint.y };
388
+ points.splice(insertIndex, 0, newPoint);
389
+ if (updateHandles) {
390
+ edge.children.forEach(child => {
391
+ if (child instanceof sprotty_1.GRoutingHandle && child.pointIndex >= shiftIndex) {
392
+ child.pointIndex++;
393
+ }
394
+ });
395
+ this.addHandle(edge, 'manhattan-50%', 'volatile-routing-point', shiftIndex);
396
+ }
397
+ }
398
+ }
399
+ else {
400
+ const leftX = currentAnchors.get(sprotty_1.Side.LEFT).x;
401
+ const rightX = currentAnchors.get(sprotty_1.Side.RIGHT).x;
402
+ if (refPoint.x < leftX || refPoint.x > rightX) {
403
+ const newPoint = { x: refPoint.x, y: currentAnchors.get(sprotty_1.Side.LEFT).y };
404
+ points.splice(insertIndex, 0, newPoint);
405
+ if (updateHandles) {
406
+ edge.children.forEach(child => {
407
+ if (child instanceof sprotty_1.GRoutingHandle && child.pointIndex >= shiftIndex) {
408
+ child.pointIndex++;
409
+ }
410
+ });
411
+ this.addHandle(edge, 'manhattan-50%', 'volatile-routing-point', shiftIndex);
412
+ }
413
+ }
414
+ }
415
+ }
416
+ /** Inserts intermediate corner points so every segment is strictly orthogonal. */
417
+ manhattanify(points, edge) {
418
+ const { axisTolerance } = this.getOptions(edge);
419
+ for (let i = 1; i < points.length; i++) {
420
+ if (!sprotty_1.Point.isAxisAligned(points[i - 1], points[i], axisTolerance)) {
421
+ points.splice(i, 0, { x: points[i - 1].x, y: points[i].y });
422
+ i++;
423
+ }
424
+ }
425
+ }
426
+ /**
427
+ * Picks the sides on source and target for a fresh default route, preferring
428
+ * (in order) direct, one-corner, and finally two-corner connections.
429
+ */
430
+ getBestConnectionAnchors(sourceAnchors, targetAnchors, options) {
431
+ const sd = options.standardDistance;
432
+ // Direct connections (no corners).
433
+ if (targetAnchors.get(sprotty_1.Side.LEFT).x - sourceAnchors.get(sprotty_1.Side.RIGHT).x > sd) {
434
+ return { source: sprotty_1.Side.RIGHT, target: sprotty_1.Side.LEFT };
435
+ }
436
+ if (sourceAnchors.get(sprotty_1.Side.LEFT).x - targetAnchors.get(sprotty_1.Side.RIGHT).x > sd) {
437
+ return { source: sprotty_1.Side.LEFT, target: sprotty_1.Side.RIGHT };
438
+ }
439
+ if (sourceAnchors.get(sprotty_1.Side.TOP).y - targetAnchors.get(sprotty_1.Side.BOTTOM).y > sd) {
440
+ return { source: sprotty_1.Side.TOP, target: sprotty_1.Side.BOTTOM };
441
+ }
442
+ if (targetAnchors.get(sprotty_1.Side.TOP).y - sourceAnchors.get(sprotty_1.Side.BOTTOM).y > sd) {
443
+ return { source: sprotty_1.Side.BOTTOM, target: sprotty_1.Side.TOP };
444
+ }
445
+ // One-corner connections.
446
+ if (targetAnchors.get(sprotty_1.Side.TOP).x - sourceAnchors.get(sprotty_1.Side.RIGHT).x > 0.5 * sd &&
447
+ targetAnchors.get(sprotty_1.Side.TOP).y - sourceAnchors.get(sprotty_1.Side.RIGHT).y > sd) {
448
+ return { source: sprotty_1.Side.RIGHT, target: sprotty_1.Side.TOP };
449
+ }
450
+ if (targetAnchors.get(sprotty_1.Side.BOTTOM).x - sourceAnchors.get(sprotty_1.Side.RIGHT).x > 0.5 * sd &&
451
+ sourceAnchors.get(sprotty_1.Side.RIGHT).y - targetAnchors.get(sprotty_1.Side.BOTTOM).y > sd) {
452
+ return { source: sprotty_1.Side.RIGHT, target: sprotty_1.Side.BOTTOM };
453
+ }
454
+ if (sourceAnchors.get(sprotty_1.Side.LEFT).x - targetAnchors.get(sprotty_1.Side.BOTTOM).x > 0.5 * sd &&
455
+ sourceAnchors.get(sprotty_1.Side.LEFT).y - targetAnchors.get(sprotty_1.Side.BOTTOM).y > sd) {
456
+ return { source: sprotty_1.Side.LEFT, target: sprotty_1.Side.BOTTOM };
457
+ }
458
+ if (sourceAnchors.get(sprotty_1.Side.LEFT).x - targetAnchors.get(sprotty_1.Side.TOP).x > 0.5 * sd &&
459
+ targetAnchors.get(sprotty_1.Side.TOP).y - sourceAnchors.get(sprotty_1.Side.LEFT).y > sd) {
460
+ return { source: sprotty_1.Side.LEFT, target: sprotty_1.Side.TOP };
461
+ }
462
+ if (targetAnchors.get(sprotty_1.Side.RIGHT).y - sourceAnchors.get(sprotty_1.Side.BOTTOM).y > 0.5 * sd &&
463
+ sourceAnchors.get(sprotty_1.Side.BOTTOM).x - targetAnchors.get(sprotty_1.Side.RIGHT).x > sd) {
464
+ return { source: sprotty_1.Side.BOTTOM, target: sprotty_1.Side.RIGHT };
465
+ }
466
+ if (targetAnchors.get(sprotty_1.Side.LEFT).y - sourceAnchors.get(sprotty_1.Side.BOTTOM).y > 0.5 * sd &&
467
+ targetAnchors.get(sprotty_1.Side.LEFT).x - sourceAnchors.get(sprotty_1.Side.BOTTOM).x > sd) {
468
+ return { source: sprotty_1.Side.BOTTOM, target: sprotty_1.Side.LEFT };
469
+ }
470
+ // Two-corner fallback. Simpler than sprotty's equivalent: no distance
471
+ // gate on same-side candidates, no diagonal fallbacks.
472
+ const srcTop = sourceAnchors.get(sprotty_1.Side.TOP);
473
+ const tgtTop = targetAnchors.get(sprotty_1.Side.TOP);
474
+ if (!sprotty_1.Bounds.includes(targetAnchors.bounds, srcTop) && !sprotty_1.Bounds.includes(sourceAnchors.bounds, tgtTop)) {
475
+ return { source: sprotty_1.Side.TOP, target: sprotty_1.Side.TOP };
476
+ }
477
+ const srcRight = sourceAnchors.get(sprotty_1.Side.RIGHT);
478
+ const tgtRight = targetAnchors.get(sprotty_1.Side.RIGHT);
479
+ if (!sprotty_1.Bounds.includes(targetAnchors.bounds, srcRight) && !sprotty_1.Bounds.includes(sourceAnchors.bounds, tgtRight)) {
480
+ return { source: sprotty_1.Side.RIGHT, target: sprotty_1.Side.RIGHT };
481
+ }
482
+ return { source: sprotty_1.Side.RIGHT, target: sprotty_1.Side.LEFT };
483
+ }
484
+ /** Computes 0, 1, or 2 corner points for a fresh default route between the given sides. */
485
+ calculateCorners(sourceAnchors, targetAnchors, sides, options) {
486
+ const src = sourceAnchors.get(sides.source);
487
+ const tgt = targetAnchors.get(sides.target);
488
+ const sd = options.standardDistance;
489
+ switch (sides.source) {
490
+ case sprotty_1.Side.RIGHT:
491
+ switch (sides.target) {
492
+ case sprotty_1.Side.LEFT: {
493
+ if (src.y !== tgt.y) {
494
+ const midX = (src.x + tgt.x) / 2;
495
+ return [
496
+ { x: midX, y: src.y },
497
+ { x: midX, y: tgt.y }
498
+ ];
499
+ }
500
+ return [];
501
+ }
502
+ case sprotty_1.Side.TOP:
503
+ case sprotty_1.Side.BOTTOM:
504
+ return [{ x: tgt.x, y: src.y }];
505
+ case sprotty_1.Side.RIGHT: {
506
+ const maxX = Math.max(src.x, tgt.x) + 1.5 * sd;
507
+ return [
508
+ { x: maxX, y: src.y },
509
+ { x: maxX, y: tgt.y }
510
+ ];
511
+ }
512
+ }
513
+ break;
514
+ case sprotty_1.Side.LEFT:
515
+ switch (sides.target) {
516
+ case sprotty_1.Side.RIGHT: {
517
+ if (src.y !== tgt.y) {
518
+ const midX = (src.x + tgt.x) / 2;
519
+ return [
520
+ { x: midX, y: src.y },
521
+ { x: midX, y: tgt.y }
522
+ ];
523
+ }
524
+ return [];
525
+ }
526
+ case sprotty_1.Side.TOP:
527
+ case sprotty_1.Side.BOTTOM:
528
+ return [{ x: tgt.x, y: src.y }];
529
+ default: {
530
+ const minX = Math.min(src.x, tgt.x) - 1.5 * sd;
531
+ return [
532
+ { x: minX, y: src.y },
533
+ { x: minX, y: tgt.y }
534
+ ];
535
+ }
536
+ }
537
+ case sprotty_1.Side.TOP:
538
+ switch (sides.target) {
539
+ case sprotty_1.Side.BOTTOM: {
540
+ if (src.x !== tgt.x) {
541
+ const midY = (src.y + tgt.y) / 2;
542
+ return [
543
+ { x: src.x, y: midY },
544
+ { x: tgt.x, y: midY }
545
+ ];
546
+ }
547
+ return [];
548
+ }
549
+ case sprotty_1.Side.TOP: {
550
+ const minY = Math.min(src.y, tgt.y) - 1.5 * sd;
551
+ return [
552
+ { x: src.x, y: minY },
553
+ { x: tgt.x, y: minY }
554
+ ];
555
+ }
556
+ case sprotty_1.Side.RIGHT:
557
+ case sprotty_1.Side.LEFT:
558
+ return [{ x: src.x, y: tgt.y }];
559
+ }
560
+ break;
561
+ case sprotty_1.Side.BOTTOM:
562
+ switch (sides.target) {
563
+ case sprotty_1.Side.TOP: {
564
+ if (src.x !== tgt.x) {
565
+ const midY = (src.y + tgt.y) / 2;
566
+ return [
567
+ { x: src.x, y: midY },
568
+ { x: tgt.x, y: midY }
569
+ ];
570
+ }
571
+ return [];
572
+ }
573
+ case sprotty_1.Side.BOTTOM: {
574
+ const maxY = Math.max(src.y, tgt.y) + 1.5 * sd;
575
+ return [
576
+ { x: src.x, y: maxY },
577
+ { x: tgt.x, y: maxY }
578
+ ];
579
+ }
580
+ case sprotty_1.Side.RIGHT:
581
+ case sprotty_1.Side.LEFT:
582
+ return [{ x: src.x, y: tgt.y }];
583
+ }
584
+ break;
585
+ }
586
+ const midX = (src.x + tgt.x) / 2;
587
+ return [
588
+ { x: midX, y: src.y },
589
+ { x: midX, y: tgt.y }
590
+ ];
591
+ }
592
+ correctX(routingPoints, index, x, minimalPointDistance) {
593
+ if (index > 0 && Math.abs(x - routingPoints[index - 1].x) < minimalPointDistance) {
594
+ return routingPoints[index - 1].x;
595
+ }
596
+ if (index < routingPoints.length - 2 && Math.abs(x - routingPoints[index + 2].x) < minimalPointDistance) {
597
+ return routingPoints[index + 2].x;
598
+ }
599
+ return x;
600
+ }
601
+ correctY(routingPoints, index, y, minimalPointDistance) {
602
+ if (index > 0 && Math.abs(y - routingPoints[index - 1].y) < minimalPointDistance) {
603
+ return routingPoints[index - 1].y;
604
+ }
605
+ if (index < routingPoints.length - 2 && Math.abs(y - routingPoints[index + 2].y) < minimalPointDistance) {
606
+ return routingPoints[index + 2].y;
607
+ }
608
+ return y;
609
+ }
610
+ alignX(points, index, x) {
611
+ if (index >= 0 && index < points.length) {
612
+ points[index] = { x, y: points[index].y };
613
+ }
614
+ }
615
+ alignY(points, index, y) {
616
+ if (index >= 0 && index < points.length) {
617
+ points[index] = { x: points[index].x, y };
618
+ }
619
+ }
620
+ };
621
+ exports.GLSPStickyManhattanEdgeRouter = GLSPStickyManhattanEdgeRouter;
622
+ GLSPStickyManhattanEdgeRouter.KIND = 'sticky-manhattan';
623
+ exports.GLSPStickyManhattanEdgeRouter = GLSPStickyManhattanEdgeRouter = GLSPStickyManhattanEdgeRouter_1 = __decorate([
624
+ (0, inversify_1.injectable)()
625
+ ], GLSPStickyManhattanEdgeRouter);
626
+ //# sourceMappingURL=sticky-manhattan-edge-router.js.map