pict-section-flow 1.3.0 → 2.0.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 (162) hide show
  1. package/package.json +7 -2
  2. package/source/Pict-Section-Flow.js +20 -14
  3. package/source/providers/PictProvider-Flow-Background.js +303 -0
  4. package/source/providers/PictProvider-Flow-CSS.js +99 -7
  5. package/source/providers/PictProvider-Flow-ConnectorShapes.js +8 -0
  6. package/source/providers/PictProvider-Flow-Geometry.js +11 -421
  7. package/source/providers/PictProvider-Flow-Icons.js +20 -0
  8. package/source/providers/PictProvider-Flow-Layouts.js +107 -0
  9. package/source/services/PictService-Flow-ConnectionRenderer.js +77 -5
  10. package/source/services/PictService-Flow-CursorManager.js +113 -0
  11. package/source/services/PictService-Flow-InteractionManager.js +443 -61
  12. package/source/services/PictService-Flow-Layout.js +21 -16
  13. package/source/services/PictService-Flow-PathGenerator.js +30 -417
  14. package/source/services/PictService-Flow-RenderManager.js +9 -1
  15. package/source/services/PictService-Flow-ViewportManager.js +102 -0
  16. package/source/views/PictView-Flow-FloatingToolbar.js +57 -0
  17. package/source/views/PictView-Flow-Node.js +36 -0
  18. package/source/views/PictView-Flow-PropertiesPanel.js +27 -5
  19. package/source/views/PictView-Flow-Toolbar.js +148 -13
  20. package/source/views/PictView-Flow.js +628 -3
  21. package/.claude/launch.json +0 -11
  22. package/docs/.nojekyll +0 -0
  23. package/docs/Architecture.md +0 -163
  24. package/docs/Custom-Styling.md +0 -275
  25. package/docs/Data_Model.md +0 -149
  26. package/docs/Event_System.md +0 -156
  27. package/docs/Getting_Started.md +0 -237
  28. package/docs/Implementation_Reference.md +0 -528
  29. package/docs/Layout_Persistence.md +0 -117
  30. package/docs/README.md +0 -103
  31. package/docs/Theme_Integration.md +0 -150
  32. package/docs/_brand.json +0 -18
  33. package/docs/_cover.md +0 -17
  34. package/docs/_playground.json +0 -24
  35. package/docs/_sidebar.md +0 -57
  36. package/docs/_topbar.md +0 -8
  37. package/docs/_version.json +0 -7
  38. package/docs/api/PictFlowCard.md +0 -216
  39. package/docs/api/PictFlowCardPropertiesPanel.md +0 -235
  40. package/docs/api/addConnection.md +0 -101
  41. package/docs/api/addNode.md +0 -137
  42. package/docs/api/autoLayout.md +0 -77
  43. package/docs/api/getFlowData.md +0 -112
  44. package/docs/api/marshalToView.md +0 -95
  45. package/docs/api/openPanel.md +0 -128
  46. package/docs/api/registerHandler.md +0 -174
  47. package/docs/api/registerNodeType.md +0 -142
  48. package/docs/api/removeConnection.md +0 -57
  49. package/docs/api/removeNode.md +0 -80
  50. package/docs/api/saveLayout.md +0 -152
  51. package/docs/api/screenToSVGCoords.md +0 -68
  52. package/docs/api/selectNode.md +0 -116
  53. package/docs/api/setTheme.md +0 -168
  54. package/docs/api/setZoom.md +0 -97
  55. package/docs/api/toggleFullscreen.md +0 -68
  56. package/docs/card-help/EACH.md +0 -19
  57. package/docs/card-help/FREAD.md +0 -24
  58. package/docs/card-help/FWRITE.md +0 -24
  59. package/docs/card-help/GET.md +0 -22
  60. package/docs/card-help/ITE.md +0 -23
  61. package/docs/card-help/LOG.md +0 -23
  62. package/docs/card-help/NOTE.md +0 -17
  63. package/docs/card-help/PREV.md +0 -18
  64. package/docs/card-help/SET.md +0 -27
  65. package/docs/card-help/SPKL.md +0 -22
  66. package/docs/card-help/STAT.md +0 -23
  67. package/docs/card-help/SW.md +0 -25
  68. package/docs/diagrams/architecture-at-a-glance.excalidraw +0 -4270
  69. package/docs/diagrams/architecture-at-a-glance.mmd +0 -30
  70. package/docs/diagrams/architecture-at-a-glance.svg +0 -2
  71. package/docs/diagrams/data-flow.excalidraw +0 -1451
  72. package/docs/diagrams/data-flow.mmd +0 -17
  73. package/docs/diagrams/data-flow.svg +0 -2
  74. package/docs/diagrams/high-level-design.excalidraw +0 -5767
  75. package/docs/diagrams/high-level-design.mmd +0 -86
  76. package/docs/diagrams/high-level-design.svg +0 -2
  77. package/docs/diagrams/relationships.excalidraw +0 -3852
  78. package/docs/diagrams/relationships.mmd +0 -9
  79. package/docs/diagrams/relationships.svg +0 -2
  80. package/docs/diagrams/service-initialization-sequence.excalidraw +0 -1466
  81. package/docs/diagrams/service-initialization-sequence.mmd +0 -19
  82. package/docs/diagrams/service-initialization-sequence.svg +0 -2
  83. package/docs/diagrams/svg-layer-structure.excalidraw +0 -1060
  84. package/docs/diagrams/svg-layer-structure.mmd +0 -18
  85. package/docs/diagrams/svg-layer-structure.svg +0 -2
  86. package/docs/examples/README.md +0 -9
  87. package/docs/examples/simple_cards/README.md +0 -677
  88. package/docs/examples/simple_cards/css/flowexample.css +0 -65
  89. package/docs/examples/simple_cards/index.html +0 -32
  90. package/docs/examples/simple_cards/js/pict.min.js +0 -12
  91. package/docs/examples/simple_cards/pict-section-flow-example-simple-cards.compatible.min.js +0 -1
  92. package/docs/index.html +0 -38
  93. package/docs/playground/app.json +0 -6
  94. package/docs/playground/appdata.json +0 -85
  95. package/docs/playground/application.js +0 -23
  96. package/docs/playground/pict.json +0 -17
  97. package/docs/playground/runtime/pict-application.min.js +0 -2
  98. package/docs/playground/runtime/pict-section-flow.min.js +0 -2
  99. package/docs/playground/runtime/pict-section-modal.min.js +0 -2
  100. package/docs/playground/runtime/pict.min.js +0 -12
  101. package/docs/retold-catalog.json +0 -244
  102. package/docs/retold-keyword-index.json +0 -26028
  103. package/example_applications/simple_cards/css/flowexample.css +0 -65
  104. package/example_applications/simple_cards/html/index.html +0 -32
  105. package/example_applications/simple_cards/package.json +0 -52
  106. package/example_applications/simple_cards/source/Pict-Application-FlowExample-Configuration.json +0 -15
  107. package/example_applications/simple_cards/source/Pict-Application-FlowExample.js +0 -539
  108. package/example_applications/simple_cards/source/card-help-content.js +0 -16
  109. package/example_applications/simple_cards/source/cards/FlowCard-Comment.js +0 -38
  110. package/example_applications/simple_cards/source/cards/FlowCard-DataPreview.js +0 -44
  111. package/example_applications/simple_cards/source/cards/FlowCard-Each.js +0 -38
  112. package/example_applications/simple_cards/source/cards/FlowCard-FileRead.js +0 -56
  113. package/example_applications/simple_cards/source/cards/FlowCard-FileWrite.js +0 -50
  114. package/example_applications/simple_cards/source/cards/FlowCard-GetValue.js +0 -37
  115. package/example_applications/simple_cards/source/cards/FlowCard-IfThenElse.js +0 -49
  116. package/example_applications/simple_cards/source/cards/FlowCard-LogValues.js +0 -55
  117. package/example_applications/simple_cards/source/cards/FlowCard-SetValue.js +0 -97
  118. package/example_applications/simple_cards/source/cards/FlowCard-Sparkline.js +0 -100
  119. package/example_applications/simple_cards/source/cards/FlowCard-StatusMonitor.js +0 -46
  120. package/example_applications/simple_cards/source/cards/FlowCard-Switch.js +0 -39
  121. package/example_applications/simple_cards/source/providers/PictRouter-FlowExample-Configuration.json +0 -22
  122. package/example_applications/simple_cards/source/sample-flows.js +0 -410
  123. package/example_applications/simple_cards/source/views/PictView-FlowExample-About.js +0 -184
  124. package/example_applications/simple_cards/source/views/PictView-FlowExample-BottomBar.js +0 -77
  125. package/example_applications/simple_cards/source/views/PictView-FlowExample-Documentation.js +0 -325
  126. package/example_applications/simple_cards/source/views/PictView-FlowExample-FileWriteInfo.js +0 -59
  127. package/example_applications/simple_cards/source/views/PictView-FlowExample-Layout.js +0 -90
  128. package/example_applications/simple_cards/source/views/PictView-FlowExample-MainWorkspace.js +0 -453
  129. package/example_applications/simple_cards/source/views/PictView-FlowExample-TopBar.js +0 -95
  130. package/scripts/generate-card-help.js +0 -214
  131. package/source/providers/edges/Edge-Bezier.js +0 -41
  132. package/source/providers/edges/Edge-Orthogonal.js +0 -37
  133. package/source/providers/edges/Edge-OrthogonalSnap.js +0 -72
  134. package/source/providers/edges/Edge-Perimeter-Linear.js +0 -31
  135. package/source/providers/edges/Edge-Perimeter-Orthogonal.js +0 -39
  136. package/source/providers/edges/Edge-Perimeter.js +0 -48
  137. package/source/providers/edges/Edge-PerimeterMath.js +0 -92
  138. package/source/providers/edges/Edge-Straight.js +0 -24
  139. package/source/providers/layouts/Layout-Circular.js +0 -203
  140. package/source/providers/layouts/Layout-Coerce.js +0 -40
  141. package/source/providers/layouts/Layout-Columnar.js +0 -134
  142. package/source/providers/layouts/Layout-Custom.js +0 -27
  143. package/source/providers/layouts/Layout-ForcedFromCenter.js +0 -256
  144. package/source/providers/layouts/Layout-Grid.js +0 -134
  145. package/source/providers/layouts/Layout-Layered.js +0 -155
  146. package/source/providers/layouts/Layout-Rank.js +0 -141
  147. package/source/providers/layouts/Layout-Staggered.js +0 -131
  148. package/source/providers/layouts/Layout-Tabular.js +0 -94
  149. package/test/ConnectionHandleManager_tests.js +0 -717
  150. package/test/ConnectionRenderer_tests.js +0 -591
  151. package/test/DataManager_tests.js +0 -859
  152. package/test/Geometry_tests.js +0 -767
  153. package/test/InteractionManager_tests.js +0 -279
  154. package/test/Layout_tests.js +0 -1604
  155. package/test/NodeView_tests.js +0 -66
  156. package/test/PanelManager_tests.js +0 -172
  157. package/test/PathGenerator_tests.js +0 -978
  158. package/test/PortRenderer_tests.js +0 -376
  159. package/test/RenderManager_tests.js +0 -756
  160. package/test/Renderer_tests.js +0 -133
  161. package/test/SelectionManager_tests.js +0 -185
  162. package/test/StylePresets_tests.js +0 -153
@@ -1,756 +0,0 @@
1
- const libFable = require('fable');
2
- const libChai = require('chai');
3
- const libExpect = libChai.expect;
4
-
5
- const libRenderManager = require('../source/services/PictService-Flow-RenderManager.js');
6
-
7
- suite
8
- (
9
- 'PictService-Flow-RenderManager',
10
- function ()
11
- {
12
- let _Fable;
13
- let _RenderManager;
14
- let _MockFlowView;
15
-
16
- /**
17
- * Create a minimal mock DOM element that supports the operations
18
- * used by RenderManager (firstChild, removeChild, appendChild,
19
- * querySelectorAll, setAttribute, querySelector).
20
- */
21
- function createMockElement()
22
- {
23
- let tmpChildren = [];
24
- return {
25
- _children: tmpChildren,
26
- get firstChild() { return tmpChildren.length > 0 ? tmpChildren[0] : null; },
27
- removeChild: function (pChild)
28
- {
29
- let tmpIdx = tmpChildren.indexOf(pChild);
30
- if (tmpIdx >= 0) tmpChildren.splice(tmpIdx, 1);
31
- },
32
- appendChild: function (pChild)
33
- {
34
- tmpChildren.push(pChild);
35
- },
36
- querySelectorAll: function (pSelector)
37
- {
38
- // Simple mock: match data-connection-hash, data-panel-hash, data-node-hash
39
- let tmpMatch = pSelector.match(/\[data-(connection|panel|node)-hash="([^"]+)"\]/);
40
- if (!tmpMatch) return [];
41
- let tmpType = tmpMatch[1];
42
- let tmpHash = tmpMatch[2];
43
- return tmpChildren.filter((c) => c._dataHash === tmpHash && c._dataType === tmpType);
44
- },
45
- querySelector: function (pSelector)
46
- {
47
- let tmpResults = this.querySelectorAll(pSelector);
48
- return tmpResults.length > 0 ? tmpResults[0] : null;
49
- }
50
- };
51
- }
52
-
53
- function createMockSVGChild(pDataType, pDataHash, pParent)
54
- {
55
- let tmpSelf =
56
- {
57
- _dataType: pDataType,
58
- _dataHash: pDataHash,
59
- remove: function ()
60
- {
61
- if (pParent)
62
- {
63
- let tmpIdx = pParent._children.indexOf(tmpSelf);
64
- if (tmpIdx >= 0) pParent._children.splice(tmpIdx, 1);
65
- }
66
- },
67
- setAttribute: function () {}
68
- };
69
- return tmpSelf;
70
- }
71
-
72
- setup
73
- (
74
- function ()
75
- {
76
- _Fable = new libFable({});
77
-
78
- _MockFlowView =
79
- {
80
- fable: _Fable,
81
- log: _Fable.log,
82
- options:
83
- {
84
- ViewIdentifier: 'test-flow',
85
- EnableGridSnap: false,
86
- GridSnapSize: 20
87
- },
88
- _FlowData:
89
- {
90
- Nodes:
91
- [
92
- {
93
- Hash: 'n1',
94
- Type: 'generic',
95
- X: 100, Y: 100,
96
- Width: 160, Height: 80,
97
- Ports:
98
- [
99
- { Hash: 'p-out', Direction: 'output', Side: 'right', Label: 'Out' }
100
- ]
101
- },
102
- {
103
- Hash: 'n2',
104
- Type: 'generic',
105
- X: 400, Y: 100,
106
- Width: 160, Height: 80,
107
- Ports:
108
- [
109
- { Hash: 'p-in', Direction: 'input', Side: 'left', Label: 'In' }
110
- ]
111
- }
112
- ],
113
- Connections:
114
- [
115
- {
116
- Hash: 'c1',
117
- SourceNodeHash: 'n1',
118
- SourcePortHash: 'p-out',
119
- TargetNodeHash: 'n2',
120
- TargetPortHash: 'p-in',
121
- Data: {}
122
- }
123
- ],
124
- OpenPanels: [],
125
- ViewState:
126
- {
127
- SelectedNodeHash: null,
128
- SelectedConnectionHash: null,
129
- SelectedTetherHash: null
130
- }
131
- },
132
- _NodesLayer: createMockElement(),
133
- _ConnectionsLayer: createMockElement(),
134
- _PanelsLayer: createMockElement(),
135
- _TethersLayer: createMockElement(),
136
- _SVGElement: null,
137
- _ConnectionRenderer:
138
- {
139
- renderConnection: function (pConn, pLayer, pIsSelected)
140
- {
141
- let tmpEl = createMockSVGChild('connection', pConn.Hash, pLayer);
142
- pLayer.appendChild(tmpEl);
143
- }
144
- },
145
- _NodeView:
146
- {
147
- renderNode: function (pNode, pLayer, pIsSelected, pConfig)
148
- {
149
- let tmpEl = createMockSVGChild('node', pNode.Hash, pLayer);
150
- pLayer.appendChild(tmpEl);
151
- }
152
- },
153
- _NodeTypeProvider:
154
- {
155
- getNodeType: function () { return null; }
156
- },
157
- _PropertiesPanelView: null,
158
- _TetherService:
159
- {
160
- renderTether: function (pPanel, pNodeData, pLayer, pIsSelected, pViewId)
161
- {
162
- let tmpEl = createMockSVGChild('panel', pPanel.Hash, pLayer);
163
- pLayer.appendChild(tmpEl);
164
- }
165
- },
166
- _LayoutService:
167
- {
168
- snapToGrid: function (pVal, pSize) { return Math.round(pVal / pSize) * pSize; }
169
- },
170
- _ConnectorShapesProvider: null,
171
- getNode: function (pHash)
172
- {
173
- return _MockFlowView._FlowData.Nodes.find((n) => n.Hash === pHash) || null;
174
- },
175
- getConnection: function (pHash)
176
- {
177
- return _MockFlowView._FlowData.Connections.find((c) => c.Hash === pHash) || null;
178
- },
179
- updateViewportTransform: function () {},
180
- _resetHandlesForNode: function () {}
181
- };
182
-
183
- _RenderManager = new libRenderManager(_Fable, { FlowView: _MockFlowView }, 'RM-Test');
184
- }
185
- );
186
-
187
- // ---- Constructor ----
188
-
189
- suite
190
- (
191
- 'Constructor',
192
- function ()
193
- {
194
- test
195
- (
196
- 'should instantiate with correct serviceType',
197
- function (fDone)
198
- {
199
- libExpect(_RenderManager).to.be.an('object');
200
- libExpect(_RenderManager.serviceType).to.equal('PictServiceFlowRenderManager');
201
- fDone();
202
- }
203
- );
204
-
205
- test
206
- (
207
- 'should store FlowView reference from options',
208
- function (fDone)
209
- {
210
- libExpect(_RenderManager._FlowView).to.equal(_MockFlowView);
211
- fDone();
212
- }
213
- );
214
-
215
- test
216
- (
217
- 'should handle missing FlowView',
218
- function (fDone)
219
- {
220
- let tmpManager = new libRenderManager(_Fable, {}, 'NoView');
221
- libExpect(tmpManager._FlowView).to.be.null;
222
- fDone();
223
- }
224
- );
225
- }
226
- );
227
-
228
- // ---- renderFlow ----
229
-
230
- suite
231
- (
232
- 'renderFlow',
233
- function ()
234
- {
235
- test
236
- (
237
- 'should clear layers and re-render all nodes and connections',
238
- function (fDone)
239
- {
240
- // Pre-populate layers
241
- _MockFlowView._NodesLayer.appendChild({ mock: true });
242
- _MockFlowView._ConnectionsLayer.appendChild({ mock: true });
243
-
244
- _RenderManager.renderFlow();
245
-
246
- // Connections should be rendered (1 connection)
247
- libExpect(_MockFlowView._ConnectionsLayer._children).to.have.length(1);
248
- // Nodes should be rendered (2 nodes)
249
- libExpect(_MockFlowView._NodesLayer._children).to.have.length(2);
250
- fDone();
251
- }
252
- );
253
-
254
- test
255
- (
256
- 'should call updateViewportTransform',
257
- function (fDone)
258
- {
259
- let tmpViewportCalled = false;
260
- _MockFlowView.updateViewportTransform = function () { tmpViewportCalled = true; };
261
-
262
- _RenderManager.renderFlow();
263
-
264
- libExpect(tmpViewportCalled).to.be.true;
265
- fDone();
266
- }
267
- );
268
-
269
- test
270
- (
271
- 'should do nothing when no FlowView',
272
- function (fDone)
273
- {
274
- let tmpManager = new libRenderManager(_Fable, {}, 'NoView');
275
- tmpManager.renderFlow();
276
- fDone();
277
- }
278
- );
279
-
280
- test
281
- (
282
- 'should do nothing when layers are missing',
283
- function (fDone)
284
- {
285
- _MockFlowView._NodesLayer = null;
286
- _RenderManager.renderFlow();
287
- // Should not throw
288
- fDone();
289
- }
290
- );
291
-
292
- test
293
- (
294
- 'should enrich port data from node type config',
295
- function (fDone)
296
- {
297
- _MockFlowView._NodeTypeProvider.getNodeType = function (pType)
298
- {
299
- if (pType === 'action')
300
- {
301
- return {
302
- DefaultPorts:
303
- [
304
- { Direction: 'input', Label: 'In', PortType: 'data', Side: 'left' },
305
- { Direction: 'output', Label: 'Out', PortType: 'data', Side: 'right' }
306
- ]
307
- };
308
- }
309
- return null;
310
- };
311
-
312
- _MockFlowView._FlowData.Nodes = [
313
- {
314
- Hash: 'n-action',
315
- Type: 'action',
316
- X: 100, Y: 100,
317
- Width: 160, Height: 80,
318
- Ports:
319
- [
320
- { Hash: 'p1', Direction: 'input', Label: 'In' },
321
- { Hash: 'p2', Direction: 'output', Label: 'Out' }
322
- ]
323
- }
324
- ];
325
- _MockFlowView._FlowData.Connections = [];
326
-
327
- _RenderManager.renderFlow();
328
-
329
- // Ports should now have enriched PortType and Side
330
- let tmpNode = _MockFlowView._FlowData.Nodes[0];
331
- libExpect(tmpNode.Ports[0].PortType).to.equal('data');
332
- libExpect(tmpNode.Ports[0].Side).to.equal('left');
333
- libExpect(tmpNode.Ports[1].PortType).to.equal('data');
334
- libExpect(tmpNode.Ports[1].Side).to.equal('right');
335
- fDone();
336
- }
337
- );
338
-
339
- test
340
- (
341
- 'should render panels and tethers when PropertiesPanelView exists',
342
- function (fDone)
343
- {
344
- let tmpPanelsRendered = false;
345
- _MockFlowView._PropertiesPanelView =
346
- {
347
- renderPanels: function () { tmpPanelsRendered = true; }
348
- };
349
- _MockFlowView._FlowData.OpenPanels = [{ Hash: 'panel-1', NodeHash: 'n1' }];
350
-
351
- _RenderManager.renderFlow();
352
-
353
- libExpect(tmpPanelsRendered).to.be.true;
354
- fDone();
355
- }
356
- );
357
- }
358
- );
359
-
360
- // ---- renderSingleConnection ----
361
-
362
- suite
363
- (
364
- 'renderSingleConnection',
365
- function ()
366
- {
367
- test
368
- (
369
- 'should remove and re-render a single connection',
370
- function (fDone)
371
- {
372
- // Pre-render
373
- _RenderManager.renderFlow();
374
- libExpect(_MockFlowView._ConnectionsLayer._children).to.have.length(1);
375
-
376
- // Re-render single
377
- _RenderManager.renderSingleConnection('c1');
378
-
379
- // Should still have 1 connection element
380
- libExpect(_MockFlowView._ConnectionsLayer._children).to.have.length(1);
381
- fDone();
382
- }
383
- );
384
-
385
- test
386
- (
387
- 'should do nothing for non-existent connection',
388
- function (fDone)
389
- {
390
- _RenderManager.renderSingleConnection('non-existent');
391
- fDone();
392
- }
393
- );
394
-
395
- test
396
- (
397
- 'should do nothing when ConnectionsLayer is null',
398
- function (fDone)
399
- {
400
- _MockFlowView._ConnectionsLayer = null;
401
- _RenderManager.renderSingleConnection('c1');
402
- fDone();
403
- }
404
- );
405
- }
406
- );
407
-
408
- // ---- renderSingleTether ----
409
-
410
- suite
411
- (
412
- 'renderSingleTether',
413
- function ()
414
- {
415
- test
416
- (
417
- 'should render a tether for an open panel',
418
- function (fDone)
419
- {
420
- _MockFlowView._FlowData.OpenPanels = [{ Hash: 'panel-1', NodeHash: 'n1' }];
421
-
422
- _RenderManager.renderSingleTether('panel-1');
423
-
424
- libExpect(_MockFlowView._TethersLayer._children).to.have.length(1);
425
- fDone();
426
- }
427
- );
428
-
429
- test
430
- (
431
- 'should do nothing for non-existent panel',
432
- function (fDone)
433
- {
434
- _RenderManager.renderSingleTether('non-existent');
435
- fDone();
436
- }
437
- );
438
-
439
- test
440
- (
441
- 'should do nothing when TethersLayer is null',
442
- function (fDone)
443
- {
444
- _MockFlowView._TethersLayer = null;
445
- _RenderManager.renderSingleTether('panel-1');
446
- fDone();
447
- }
448
- );
449
-
450
- test
451
- (
452
- 'should do nothing when TetherService is null',
453
- function (fDone)
454
- {
455
- _MockFlowView._TetherService = null;
456
- _RenderManager.renderSingleTether('panel-1');
457
- fDone();
458
- }
459
- );
460
- }
461
- );
462
-
463
- // ---- updateNodePosition ----
464
-
465
- suite
466
- (
467
- 'updateNodePosition',
468
- function ()
469
- {
470
- test
471
- (
472
- 'should update node X and Y',
473
- function (fDone)
474
- {
475
- _RenderManager.renderFlow();
476
-
477
- _RenderManager.updateNodePosition('n1', 500, 300);
478
-
479
- let tmpNode = _MockFlowView._FlowData.Nodes.find((n) => n.Hash === 'n1');
480
- libExpect(tmpNode.X).to.equal(500);
481
- libExpect(tmpNode.Y).to.equal(300);
482
- fDone();
483
- }
484
- );
485
-
486
- test
487
- (
488
- 'should snap to grid when enabled',
489
- function (fDone)
490
- {
491
- _MockFlowView.options.EnableGridSnap = true;
492
- _MockFlowView.options.GridSnapSize = 20;
493
-
494
- _RenderManager.renderFlow();
495
-
496
- _RenderManager.updateNodePosition('n1', 513, 307);
497
-
498
- let tmpNode = _MockFlowView._FlowData.Nodes.find((n) => n.Hash === 'n1');
499
- libExpect(tmpNode.X).to.equal(520);
500
- libExpect(tmpNode.Y).to.equal(300);
501
- fDone();
502
- }
503
- );
504
-
505
- test
506
- (
507
- 'should call _resetHandlesForNode',
508
- function (fDone)
509
- {
510
- let tmpResetHash = null;
511
- _MockFlowView._resetHandlesForNode = function (pHash) { tmpResetHash = pHash; };
512
-
513
- _RenderManager.renderFlow();
514
- _RenderManager.updateNodePosition('n1', 200, 200);
515
-
516
- libExpect(tmpResetHash).to.equal('n1');
517
- fDone();
518
- }
519
- );
520
-
521
- test
522
- (
523
- 'should re-render connections for the moved node',
524
- function (fDone)
525
- {
526
- let tmpRenderedConnHashes = [];
527
- _MockFlowView._ConnectionRenderer.renderConnection = function (pConn, pLayer)
528
- {
529
- tmpRenderedConnHashes.push(pConn.Hash);
530
- let tmpEl = createMockSVGChild('connection', pConn.Hash);
531
- pLayer.appendChild(tmpEl);
532
- };
533
-
534
- _RenderManager.renderFlow();
535
- tmpRenderedConnHashes = [];
536
-
537
- _RenderManager.updateNodePosition('n1', 200, 200);
538
-
539
- // c1 connects n1 and n2, so it should be re-rendered
540
- libExpect(tmpRenderedConnHashes).to.include('c1');
541
- fDone();
542
- }
543
- );
544
-
545
- test
546
- (
547
- 'should do nothing for non-existent node',
548
- function (fDone)
549
- {
550
- _RenderManager.updateNodePosition('non-existent', 200, 200);
551
- fDone();
552
- }
553
- );
554
-
555
- test
556
- (
557
- 'should do nothing when no FlowView',
558
- function (fDone)
559
- {
560
- let tmpManager = new libRenderManager(_Fable, {}, 'NoView');
561
- tmpManager.updateNodePosition('n1', 200, 200);
562
- fDone();
563
- }
564
- );
565
- }
566
- );
567
-
568
- // ---- renderConnectionsForNode ----
569
-
570
- suite
571
- (
572
- 'renderConnectionsForNode',
573
- function ()
574
- {
575
- test
576
- (
577
- 'should re-render connections involving the specified node',
578
- function (fDone)
579
- {
580
- _RenderManager.renderFlow();
581
-
582
- let tmpRenderCount = 0;
583
- _MockFlowView._ConnectionRenderer.renderConnection = function (pConn, pLayer)
584
- {
585
- tmpRenderCount++;
586
- let tmpEl = createMockSVGChild('connection', pConn.Hash);
587
- pLayer.appendChild(tmpEl);
588
- };
589
-
590
- _RenderManager.renderConnectionsForNode('n1');
591
-
592
- libExpect(tmpRenderCount).to.equal(1);
593
- fDone();
594
- }
595
- );
596
-
597
- test
598
- (
599
- 'should not re-render connections for unrelated nodes',
600
- function (fDone)
601
- {
602
- _RenderManager.renderFlow();
603
-
604
- let tmpRenderCount = 0;
605
- _MockFlowView._ConnectionRenderer.renderConnection = function ()
606
- {
607
- tmpRenderCount++;
608
- };
609
-
610
- _RenderManager.renderConnectionsForNode('unrelated-node');
611
-
612
- libExpect(tmpRenderCount).to.equal(0);
613
- fDone();
614
- }
615
- );
616
-
617
- test
618
- (
619
- 'should do nothing when ConnectionsLayer is null',
620
- function (fDone)
621
- {
622
- _MockFlowView._ConnectionsLayer = null;
623
- _RenderManager.renderConnectionsForNode('n1');
624
- fDone();
625
- }
626
- );
627
- }
628
- );
629
-
630
- // ---- renderTethersForNode ----
631
-
632
- suite
633
- (
634
- 'renderTethersForNode',
635
- function ()
636
- {
637
- test
638
- (
639
- 'should re-render tethers for panels attached to the node',
640
- function (fDone)
641
- {
642
- _MockFlowView._FlowData.OpenPanels = [{ Hash: 'panel-1', NodeHash: 'n1' }];
643
-
644
- let tmpRenderCount = 0;
645
- _MockFlowView._TetherService.renderTether = function (pPanel, pNodeData, pLayer)
646
- {
647
- tmpRenderCount++;
648
- let tmpEl = createMockSVGChild('panel', pPanel.Hash);
649
- pLayer.appendChild(tmpEl);
650
- };
651
-
652
- _RenderManager.renderTethersForNode('n1');
653
-
654
- libExpect(tmpRenderCount).to.equal(1);
655
- fDone();
656
- }
657
- );
658
-
659
- test
660
- (
661
- 'should skip panels for other nodes',
662
- function (fDone)
663
- {
664
- _MockFlowView._FlowData.OpenPanels = [{ Hash: 'panel-1', NodeHash: 'n2' }];
665
-
666
- let tmpRenderCount = 0;
667
- _MockFlowView._TetherService.renderTether = function ()
668
- {
669
- tmpRenderCount++;
670
- };
671
-
672
- _RenderManager.renderTethersForNode('n1');
673
-
674
- libExpect(tmpRenderCount).to.equal(0);
675
- fDone();
676
- }
677
- );
678
-
679
- test
680
- (
681
- 'should do nothing when no panels for node',
682
- function (fDone)
683
- {
684
- _MockFlowView._FlowData.OpenPanels = [];
685
- _RenderManager.renderTethersForNode('n1');
686
- fDone();
687
- }
688
- );
689
-
690
- test
691
- (
692
- 'should do nothing when TethersLayer is null',
693
- function (fDone)
694
- {
695
- _MockFlowView._TethersLayer = null;
696
- _RenderManager.renderTethersForNode('n1');
697
- fDone();
698
- }
699
- );
700
-
701
- test
702
- (
703
- 'should do nothing when TetherService is null',
704
- function (fDone)
705
- {
706
- _MockFlowView._TetherService = null;
707
- _RenderManager.renderTethersForNode('n1');
708
- fDone();
709
- }
710
- );
711
- }
712
- );
713
-
714
- // ---- reinjectMarkerDefs ----
715
-
716
- suite
717
- (
718
- 'reinjectMarkerDefs',
719
- function ()
720
- {
721
- test
722
- (
723
- 'should do nothing when ConnectorShapesProvider is null',
724
- function (fDone)
725
- {
726
- _MockFlowView._ConnectorShapesProvider = null;
727
- _RenderManager.reinjectMarkerDefs();
728
- fDone();
729
- }
730
- );
731
-
732
- test
733
- (
734
- 'should do nothing when SVGElement is null',
735
- function (fDone)
736
- {
737
- _MockFlowView._SVGElement = null;
738
- _RenderManager.reinjectMarkerDefs();
739
- fDone();
740
- }
741
- );
742
-
743
- test
744
- (
745
- 'should do nothing when no FlowView',
746
- function (fDone)
747
- {
748
- let tmpManager = new libRenderManager(_Fable, {}, 'NoView');
749
- tmpManager.reinjectMarkerDefs();
750
- fDone();
751
- }
752
- );
753
- }
754
- );
755
- }
756
- );