@peter.prib/renderengine 0.0.0-stage → 0.2.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 (451) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +203 -2
  3. package/REFERENCE.md +2198 -0
  4. package/dist/renderengine-workspace.umd.js +46905 -0
  5. package/dist/renderengine.umd.js +42223 -0
  6. package/examples/archimate.html +66 -0
  7. package/examples/diagram-editor.html +51 -0
  8. package/package.json +65 -4
  9. package/src/BaseRenderer.js +57 -0
  10. package/src/CanvasRenderer.js +194 -0
  11. package/src/Mat4.js +111 -0
  12. package/src/OrbitCamera.js +57 -0
  13. package/src/RendererFactory.js +50 -0
  14. package/src/SVGRenderer.js +439 -0
  15. package/src/archimate.js +723 -0
  16. package/src/archimateArchiFormat.js +1693 -0
  17. package/src/archimateArchiTypes.js +72 -0
  18. package/src/archimateArchive.js +140 -0
  19. package/src/archimateCSV.js +127 -0
  20. package/src/archimateDrawio.js +182 -0
  21. package/src/archimateExchangeFormat.js +546 -0
  22. package/src/archimateRelationshipTable.js +93 -0
  23. package/src/archimateSpecializations.js +161 -0
  24. package/src/chartCatalog.js +589 -0
  25. package/src/charting/ArchimateDiagramEditor.js +1624 -0
  26. package/src/charting/ArchimateSpecializationSelector.js +134 -0
  27. package/src/charting/Axis.js +68 -0
  28. package/src/charting/CameraSeeder.js +30 -0
  29. package/src/charting/CatalogDialog.js +92 -0
  30. package/src/charting/Chart.js +37 -0
  31. package/src/charting/Chart3D.js +99 -0
  32. package/src/charting/ChartBox.js +80 -0
  33. package/src/charting/ChartData.js +27 -0
  34. package/src/charting/ChartRegistry.js +76 -0
  35. package/src/charting/CheckboxTreeSelector.js +304 -0
  36. package/src/charting/ColorField.js +107 -0
  37. package/src/charting/ColorPalette.js +88 -0
  38. package/src/charting/CommandHistory.js +176 -0
  39. package/src/charting/DataFilter.js +52 -0
  40. package/src/charting/Diagram.js +36 -0
  41. package/src/charting/Diagram3D.js +29 -0
  42. package/src/charting/DiagramClipboard.js +31 -0
  43. package/src/charting/DiagramEditor.js +3330 -0
  44. package/src/charting/DiagramEditorCommand.js +110 -0
  45. package/src/charting/DiagramEditorCommands.js +237 -0
  46. package/src/charting/DiagramEditorEdgeCommands.js +142 -0
  47. package/src/charting/DiagramEditorState.js +98 -0
  48. package/src/charting/DiagramRegistry.js +86 -0
  49. package/src/charting/DiagramTypeRegistry.js +326 -0
  50. package/src/charting/DiagramViewPropertiesDialog.js +46 -0
  51. package/src/charting/Edge.js +113 -0
  52. package/src/charting/ErrorBars.js +37 -0
  53. package/src/charting/FilterSystem.js +285 -0
  54. package/src/charting/FindReplaceDialog.js +139 -0
  55. package/src/charting/FormDialog.js +385 -0
  56. package/src/charting/Gauge.js +58 -0
  57. package/src/charting/Hierarchy.js +175 -0
  58. package/src/charting/HintPanel.js +86 -0
  59. package/src/charting/ImageSelector.js +148 -0
  60. package/src/charting/InteractionManager.js +725 -0
  61. package/src/charting/Legend.js +58 -0
  62. package/src/charting/MenuBar.js +62 -0
  63. package/src/charting/ModelFileFormat.js +115 -0
  64. package/src/charting/OrbitControls.js +77 -0
  65. package/src/charting/Palette.js +119 -0
  66. package/src/charting/PopupMenu.js +117 -0
  67. package/src/charting/PropertiesPanel.js +155 -0
  68. package/src/charting/PropertyListEditor.js +96 -0
  69. package/src/charting/PropertyLog.js +92 -0
  70. package/src/charting/SettingsCascade.js +93 -0
  71. package/src/charting/SettingsDialog.js +53 -0
  72. package/src/charting/SettingsManager.js +179 -0
  73. package/src/charting/SettingsViewPropertiesDialog.js +58 -0
  74. package/src/charting/ShapePaths.js +27 -0
  75. package/src/charting/Statistics.js +134 -0
  76. package/src/charting/TemplateCatalog.js +59 -0
  77. package/src/charting/TemplateLibrary.js +103 -0
  78. package/src/charting/TextStyle.js +168 -0
  79. package/src/charting/ViewFit.js +55 -0
  80. package/src/charting/ViewMenu.js +70 -0
  81. package/src/charting/ViewPropertiesDialog.js +77 -0
  82. package/src/charting/ViewTabStrip.js +81 -0
  83. package/src/charting/archimate/ArchiFileFormat.js +32 -0
  84. package/src/charting/archimate/ArchimateCanvasEditor.js +815 -0
  85. package/src/charting/archimate/ArchimateCsvFileFormat.js +35 -0
  86. package/src/charting/archimate/ArchimateEdge.js +137 -0
  87. package/src/charting/archimate/ArchimateElementTemplate.js +195 -0
  88. package/src/charting/archimate/ArchimatePalette.js +102 -0
  89. package/src/charting/archimate/CsvImportDialog.js +105 -0
  90. package/src/charting/archimate/CustomViewpoints.js +74 -0
  91. package/src/charting/archimate/DerivedEdge.js +29 -0
  92. package/src/charting/archimate/DrawioFileFormat.js +24 -0
  93. package/src/charting/archimate/ElementFilterRule.js +21 -0
  94. package/src/charting/archimate/ExchangeFileFormat.js +28 -0
  95. package/src/charting/archimate/ViewGroupTemplate.js +137 -0
  96. package/src/charting/archimate/ViewLineEdge.js +84 -0
  97. package/src/charting/archimate/ViewpointRule.js +45 -0
  98. package/src/charting/archimate/archimateFileFormats.js +12 -0
  99. package/src/charting/archimate/archimateNames.js +5 -0
  100. package/src/charting/archimate/csvMapping.js +122 -0
  101. package/src/charting/archimate/elementMenuItems.js +32 -0
  102. package/src/charting/archimate/elementProperties.js +146 -0
  103. package/src/charting/archimate/elementTypeChoices.js +7 -0
  104. package/src/charting/archimate/elementTypeGroups.js +19 -0
  105. package/src/charting/archimate/index.js +17 -0
  106. package/src/charting/archimate/specializationCatalogDialog.js +64 -0
  107. package/src/charting/archimate/typeGlyph.js +29 -0
  108. package/src/charting/arrangement/Arrangement.js +112 -0
  109. package/src/charting/arrangement/ArrangementCommand.js +29 -0
  110. package/src/charting/arrangement/BackgroundCommand.js +41 -0
  111. package/src/charting/arrangement/BackgroundGroup.js +18 -0
  112. package/src/charting/arrangement/GroupCommand.js +46 -0
  113. package/src/charting/arrangement/ItemGroup.js +62 -0
  114. package/src/charting/arrangement/LockCommand.js +32 -0
  115. package/src/charting/arrangement/UngroupCommand.js +27 -0
  116. package/src/charting/arrangement/alignment.js +88 -0
  117. package/src/charting/arrangement/arrangeMenuItems.js +25 -0
  118. package/src/charting/arrangement/index.js +11 -0
  119. package/src/charting/arrangement/layouts.js +233 -0
  120. package/src/charting/canvas/ArchiHint.js +78 -0
  121. package/src/charting/canvas/CanvasBoxKind.js +39 -0
  122. package/src/charting/canvas/CanvasPalette.js +49 -0
  123. package/src/charting/canvas/CanvasTemplateLibrary.js +61 -0
  124. package/src/charting/canvas/CanvasTemplateMenu.js +151 -0
  125. package/src/charting/canvas/EditHintCommand.js +28 -0
  126. package/src/charting/canvas/canvasBoxKinds.js +27 -0
  127. package/src/charting/canvas/canvasBoxMenuItems.js +40 -0
  128. package/src/charting/canvas/defaultCanvasTemplates.js +186 -0
  129. package/src/charting/canvas/diagramBoxKinds.js +12 -0
  130. package/src/charting/canvas/hintMenuItems.js +49 -0
  131. package/src/charting/charts/ArcGauge.js +55 -0
  132. package/src/charting/charts/AreaChart.js +71 -0
  133. package/src/charting/charts/BarChart.js +80 -0
  134. package/src/charting/charts/BarChart3D.js +56 -0
  135. package/src/charting/charts/BarChart3DOrbit.js +53 -0
  136. package/src/charting/charts/BarChartBase.js +70 -0
  137. package/src/charting/charts/BarGauge.js +42 -0
  138. package/src/charting/charts/BoxPlotChart.js +41 -0
  139. package/src/charting/charts/BubbleChart.js +99 -0
  140. package/src/charting/charts/BubbleChart3D.js +78 -0
  141. package/src/charting/charts/BulletGauge.js +87 -0
  142. package/src/charting/charts/CalendarHeatmapChart.js +204 -0
  143. package/src/charting/charts/CandlestickChart.js +54 -0
  144. package/src/charting/charts/ChordDiagram.js +130 -0
  145. package/src/charting/charts/DensityChart.js +73 -0
  146. package/src/charting/charts/DialGauge.js +65 -0
  147. package/src/charting/charts/DonutChart.js +15 -0
  148. package/src/charting/charts/FunnelChart.js +47 -0
  149. package/src/charting/charts/GanttChart.js +201 -0
  150. package/src/charting/charts/GaugeChart.js +175 -0
  151. package/src/charting/charts/GeoMapChart.js +146 -0
  152. package/src/charting/charts/GroupedBarChart.js +88 -0
  153. package/src/charting/charts/GroupedDistributionChart.js +70 -0
  154. package/src/charting/charts/HeatmapChart.js +80 -0
  155. package/src/charting/charts/HierarchyChart.js +39 -0
  156. package/src/charting/charts/HistogramChart.js +45 -0
  157. package/src/charting/charts/KpiTile.js +72 -0
  158. package/src/charting/charts/LagPlotChart.js +41 -0
  159. package/src/charting/charts/LineChart.js +124 -0
  160. package/src/charting/charts/MultiRingGauge.js +54 -0
  161. package/src/charting/charts/OutlineChart.js +95 -0
  162. package/src/charting/charts/ParallelCoordinatesChart.js +130 -0
  163. package/src/charting/charts/PieChart.js +56 -0
  164. package/src/charting/charts/PipeChart.js +88 -0
  165. package/src/charting/charts/PopulationPyramidChart.js +106 -0
  166. package/src/charting/charts/QQPlotChart.js +64 -0
  167. package/src/charting/charts/RadarChart.js +76 -0
  168. package/src/charting/charts/RadialBarChart.js +96 -0
  169. package/src/charting/charts/RingGauge.js +23 -0
  170. package/src/charting/charts/SankeyDiagram.js +174 -0
  171. package/src/charting/charts/ScatterChart.js +104 -0
  172. package/src/charting/charts/StackedAreaChart.js +15 -0
  173. package/src/charting/charts/StackedBarChart.js +33 -0
  174. package/src/charting/charts/StackedBarChart3DOrbit.js +58 -0
  175. package/src/charting/charts/StreamGraphChart.js +131 -0
  176. package/src/charting/charts/SunburstChart.js +57 -0
  177. package/src/charting/charts/ThermometerGauge.js +43 -0
  178. package/src/charting/charts/TreemapChart.js +54 -0
  179. package/src/charting/charts/ViolinChart.js +37 -0
  180. package/src/charting/charts/WaterfallChart.js +66 -0
  181. package/src/charting/charts/WordCloudChart.js +104 -0
  182. package/src/charting/diagramModel/AddViewCommand.js +33 -0
  183. package/src/charting/diagramModel/DiagramModel.js +39 -0
  184. package/src/charting/diagramModel/DiagramModelSearch.js +22 -0
  185. package/src/charting/diagramModel/DiagramView.js +50 -0
  186. package/src/charting/diagramModel/ModelHistory.js +43 -0
  187. package/src/charting/diagramModel/ModelReport.js +153 -0
  188. package/src/charting/diagramModel/ModelSearch.js +223 -0
  189. package/src/charting/diagramModel/RemoveViewCommand.js +25 -0
  190. package/src/charting/diagramModel/RenameViewCommand.js +21 -0
  191. package/src/charting/diagramModel/ReplaceTextCommand.js +25 -0
  192. package/src/charting/diagramModel/ViewSetChecker.js +34 -0
  193. package/src/charting/diagramModel/ViewSetModel.js +243 -0
  194. package/src/charting/diagramModel/index.js +6 -0
  195. package/src/charting/diagramModel/nameTransforms.js +29 -0
  196. package/src/charting/diagrams/ArchimateCommands.js +141 -0
  197. package/src/charting/diagrams/ArchimateDiagram.js +263 -0
  198. package/src/charting/diagrams/ArchimateModel.js +1155 -0
  199. package/src/charting/diagrams/ArchimateModelChecker.js +125 -0
  200. package/src/charting/diagrams/ArchimateModelReport.js +128 -0
  201. package/src/charting/diagrams/ArchimateModelSearch.js +41 -0
  202. package/src/charting/diagrams/ArchimateValidator.js +357 -0
  203. package/src/charting/diagrams/CanvasView.js +112 -0
  204. package/src/charting/diagrams/ContextMenu.js +37 -0
  205. package/src/charting/diagrams/DataModelDiagram.js +86 -0
  206. package/src/charting/diagrams/DataModelRelationshipStrategy.js +38 -0
  207. package/src/charting/diagrams/DerivedRelationships.js +102 -0
  208. package/src/charting/diagrams/EbnfDiagram.js +39 -0
  209. package/src/charting/diagrams/EdgeGeometry.js +553 -0
  210. package/src/charting/diagrams/EditViewItemCommand.js +128 -0
  211. package/src/charting/diagrams/ElementInstance.js +157 -0
  212. package/src/charting/diagrams/GraphDiagram.js +1340 -0
  213. package/src/charting/diagrams/GraphDiagram3D.js +152 -0
  214. package/src/charting/diagrams/GraphMetrics.js +81 -0
  215. package/src/charting/diagrams/GridOverlay.js +137 -0
  216. package/src/charting/diagrams/ImportRowsCommand.js +62 -0
  217. package/src/charting/diagrams/LabelHelper.js +108 -0
  218. package/src/charting/diagrams/MergeElementsCommand.js +101 -0
  219. package/src/charting/diagrams/NestInstanceCommand.js +34 -0
  220. package/src/charting/diagrams/NodeGeometry.js +158 -0
  221. package/src/charting/diagrams/PlaceItemsCommand.js +77 -0
  222. package/src/charting/diagrams/RadialLayout.js +101 -0
  223. package/src/charting/diagrams/RelationshipInstance.js +93 -0
  224. package/src/charting/diagrams/RemoveGroupFromViewCommand.js +28 -0
  225. package/src/charting/diagrams/RemoveLineCommand.js +27 -0
  226. package/src/charting/diagrams/ShowElementCommand.js +43 -0
  227. package/src/charting/diagrams/SvgCoordinate.js +17 -0
  228. package/src/charting/diagrams/SvgZoom.js +127 -0
  229. package/src/charting/diagrams/Tooltip.js +62 -0
  230. package/src/charting/diagrams/ViewConnectionInstance.js +102 -0
  231. package/src/charting/diagrams/ViewObjectInstance.js +56 -0
  232. package/src/charting/diagrams/commands/AddEdgeCommand.js +34 -0
  233. package/src/charting/diagrams/commands/AddNodeCommand.js +28 -0
  234. package/src/charting/diagrams/commands/AddWaypointCommand.js +27 -0
  235. package/src/charting/diagrams/commands/CreateFolderCommand.js +27 -0
  236. package/src/charting/diagrams/commands/DeleteEdgeCommand.js +30 -0
  237. package/src/charting/diagrams/commands/DeleteFolderCommand.js +47 -0
  238. package/src/charting/diagrams/commands/DeleteNodeCommand.js +35 -0
  239. package/src/charting/diagrams/commands/DeleteWaypointCommand.js +24 -0
  240. package/src/charting/diagrams/commands/GraphCommand.js +65 -0
  241. package/src/charting/diagrams/commands/InvertEdgeCommand.js +24 -0
  242. package/src/charting/diagrams/commands/MoveNodeCommand.js +44 -0
  243. package/src/charting/diagrams/commands/MoveWaypointCommand.js +27 -0
  244. package/src/charting/diagrams/commands/RenameEdgeCommand.js +23 -0
  245. package/src/charting/diagrams/commands/RenameFolderCommand.js +31 -0
  246. package/src/charting/diagrams/commands/RenameNodeCommand.js +27 -0
  247. package/src/charting/diagrams/commands/ResizeNodeCommand.js +46 -0
  248. package/src/charting/diagrams/commands/UpdateEdgeSideCommand.js +40 -0
  249. package/src/charting/diagrams/commands/index.js +17 -0
  250. package/src/charting/diagrams/duplicates.js +49 -0
  251. package/src/charting/diagrams/nesting.js +30 -0
  252. package/src/charting/diagrams/roadmap.js +77 -0
  253. package/src/charting/edgeMarkers/ArrowMarker.js +15 -0
  254. package/src/charting/edgeMarkers/CircleMarker.js +13 -0
  255. package/src/charting/edgeMarkers/CrowsFootMarker.js +16 -0
  256. package/src/charting/edgeMarkers/DiamondMarker.js +15 -0
  257. package/src/charting/edgeMarkers/EdgeMarker.js +34 -0
  258. package/src/charting/edgeMarkers/HalfArrowMarker.js +8 -0
  259. package/src/charting/edgeMarkers/HollowDiamondMarker.js +18 -0
  260. package/src/charting/edgeMarkers/HollowTriangleMarker.js +18 -0
  261. package/src/charting/edgeMarkers/OpenArrowMarker.js +17 -0
  262. package/src/charting/edgeMarkers/index.js +27 -0
  263. package/src/charting/edgeStyle/EdgeStyleCascade.js +22 -0
  264. package/src/charting/edgeStyle/EdgeStyleDialog.js +51 -0
  265. package/src/charting/edgeStyle/EdgeStyleSchema.js +43 -0
  266. package/src/charting/edgeStyle/SetStyleCommand.js +12 -0
  267. package/src/charting/edgeStyle/index.js +4 -0
  268. package/src/charting/emphasis/EmphasisRule.js +42 -0
  269. package/src/charting/emphasis/HighlightRule.js +24 -0
  270. package/src/charting/gauges/ArcTrack.js +51 -0
  271. package/src/charting/gauges/GaugeAnimation.js +51 -0
  272. package/src/charting/gauges/GaugeBands.js +48 -0
  273. package/src/charting/gauges/GaugeScale.js +87 -0
  274. package/src/charting/gauges/GaugeTrack.js +44 -0
  275. package/src/charting/gauges/GaugeValue.js +61 -0
  276. package/src/charting/gauges/HorizontalTrack.js +14 -0
  277. package/src/charting/gauges/LinearTrack.js +29 -0
  278. package/src/charting/gauges/Sparkline.js +42 -0
  279. package/src/charting/gauges/VerticalTrack.js +17 -0
  280. package/src/charting/glyphs/ArrowGlyph.js +21 -0
  281. package/src/charting/glyphs/BatteryGlyph.js +18 -0
  282. package/src/charting/glyphs/ChevronGlyph.js +18 -0
  283. package/src/charting/glyphs/CircleGlyph.js +15 -0
  284. package/src/charting/glyphs/CloudGlyph.js +19 -0
  285. package/src/charting/glyphs/ComponentGlyph.js +18 -0
  286. package/src/charting/glyphs/ConstraintGlyph.js +24 -0
  287. package/src/charting/glyphs/ContractBoxGlyph.js +10 -0
  288. package/src/charting/glyphs/CubeGlyph.js +19 -0
  289. package/src/charting/glyphs/CylinderGlyph.js +19 -0
  290. package/src/charting/glyphs/DashedDoubleArrowGlyph.js +11 -0
  291. package/src/charting/glyphs/DeviceGlyph.js +17 -0
  292. package/src/charting/glyphs/DiamondGlyph.js +17 -0
  293. package/src/charting/glyphs/DocumentGlyph.js +17 -0
  294. package/src/charting/glyphs/DoubleArrowGlyph.js +23 -0
  295. package/src/charting/glyphs/DoubleCircleGlyph.js +24 -0
  296. package/src/charting/glyphs/EllipseGlyph.js +18 -0
  297. package/src/charting/glyphs/FactoryGlyph.js +20 -0
  298. package/src/charting/glyphs/FlagGlyph.js +16 -0
  299. package/src/charting/glyphs/GapCircleGlyph.js +17 -0
  300. package/src/charting/glyphs/GearGlyph.js +37 -0
  301. package/src/charting/glyphs/Glyph.js +98 -0
  302. package/src/charting/glyphs/GroupingBoxGlyph.js +13 -0
  303. package/src/charting/glyphs/HalfCircleGlyph.js +22 -0
  304. package/src/charting/glyphs/HexagonGlyph.js +28 -0
  305. package/src/charting/glyphs/IconGlyph.js +22 -0
  306. package/src/charting/glyphs/ImageGlyph.js +16 -0
  307. package/src/charting/glyphs/JunctionGlyph.js +17 -0
  308. package/src/charting/glyphs/LollipopGlyph.js +22 -0
  309. package/src/charting/glyphs/MagnifierGlyph.js +17 -0
  310. package/src/charting/glyphs/NoteGlyph.js +33 -0
  311. package/src/charting/glyphs/ObjectBoxGlyph.js +21 -0
  312. package/src/charting/glyphs/OrJunctionGlyph.js +17 -0
  313. package/src/charting/glyphs/ParallelogramGlyph.js +20 -0
  314. package/src/charting/glyphs/PersonGlyph.js +23 -0
  315. package/src/charting/glyphs/PillGlyph.js +23 -0
  316. package/src/charting/glyphs/PinGlyph.js +18 -0
  317. package/src/charting/glyphs/PrincipleGlyph.js +23 -0
  318. package/src/charting/glyphs/ProductBoxGlyph.js +16 -0
  319. package/src/charting/glyphs/RectGlyph.js +15 -0
  320. package/src/charting/glyphs/RoundedBoxGlyph.js +13 -0
  321. package/src/charting/glyphs/StackGlyph.js +14 -0
  322. package/src/charting/glyphs/StepsGlyph.js +20 -0
  323. package/src/charting/glyphs/StickFigureGlyph.js +32 -0
  324. package/src/charting/glyphs/SystemSoftwareBoxGlyph.js +16 -0
  325. package/src/charting/glyphs/TabbedBoxGlyph.js +37 -0
  326. package/src/charting/glyphs/TargetGlyph.js +23 -0
  327. package/src/charting/glyphs/WavyBoxGlyph.js +17 -0
  328. package/src/charting/glyphs/WheelGlyph.js +28 -0
  329. package/src/charting/glyphs/drawGlyph.js +28 -0
  330. package/src/charting/glyphs/glyphSvg.js +55 -0
  331. package/src/charting/glyphs/index.js +109 -0
  332. package/src/charting/modelTree/AnalysisPanel.js +159 -0
  333. package/src/charting/modelTree/DiagramTabs.js +217 -0
  334. package/src/charting/modelTree/ModelTree.js +164 -0
  335. package/src/charting/modelTree/ModelTreePanel.js +914 -0
  336. package/src/charting/modelTree/TreeBuilder.js +238 -0
  337. package/src/charting/modelTree/TreeModeRegistry.js +51 -0
  338. package/src/charting/modelTree/TreeViewMode.js +110 -0
  339. package/src/charting/modelTree/buildFilterTrees.js +138 -0
  340. package/src/charting/modelTree/modes/FlatTreeMode.js +46 -0
  341. package/src/charting/modelTree/modes/LayerGroupedTreeMode.js +62 -0
  342. package/src/charting/modelTree/modes/TypeGroupedTreeMode.js +60 -0
  343. package/src/charting/modelTree/treeLayers.js +11 -0
  344. package/src/charting/report/reportHtml.js +82 -0
  345. package/src/charting/report/reportViewer.js +118 -0
  346. package/src/charting/shapes/CircleShape.js +19 -0
  347. package/src/charting/shapes/PathShape.js +17 -0
  348. package/src/charting/shapes/RectShape.js +20 -0
  349. package/src/charting/shapes/Shape.js +20 -0
  350. package/src/charting/shapes/ShapeFactory.js +23 -0
  351. package/src/charting/storage/LocalJsonStore.js +43 -0
  352. package/src/charting/templates/ActorTemplate.js +36 -0
  353. package/src/charting/templates/BoxTemplate.js +27 -0
  354. package/src/charting/templates/CircleTemplate.js +18 -0
  355. package/src/charting/templates/ClassTemplate.js +20 -0
  356. package/src/charting/templates/CloudTemplate.js +43 -0
  357. package/src/charting/templates/ComponentTemplate.js +19 -0
  358. package/src/charting/templates/CylinderTemplate.js +30 -0
  359. package/src/charting/templates/DataStoreTemplate.js +16 -0
  360. package/src/charting/templates/DiamondTemplate.js +10 -0
  361. package/src/charting/templates/DocumentTemplate.js +32 -0
  362. package/src/charting/templates/EllipseTemplate.js +15 -0
  363. package/src/charting/templates/FinalStateTemplate.js +12 -0
  364. package/src/charting/templates/GlyphTemplate.js +47 -0
  365. package/src/charting/templates/HexagonTemplate.js +17 -0
  366. package/src/charting/templates/LifelineTemplate.js +20 -0
  367. package/src/charting/templates/ManualInputTemplate.js +12 -0
  368. package/src/charting/templates/NoteTemplate.js +23 -0
  369. package/src/charting/templates/OctagonTemplate.js +7 -0
  370. package/src/charting/templates/PackageTemplate.js +25 -0
  371. package/src/charting/templates/ParallelogramTemplate.js +11 -0
  372. package/src/charting/templates/PentagonTemplate.js +5 -0
  373. package/src/charting/templates/PolygonTemplate.js +18 -0
  374. package/src/charting/templates/PredefinedProcessTemplate.js +13 -0
  375. package/src/charting/templates/RectangleTemplate.js +28 -0
  376. package/src/charting/templates/RegularPolygonTemplate.js +21 -0
  377. package/src/charting/templates/RoundedRectangleTemplate.js +5 -0
  378. package/src/charting/templates/StadiumTemplate.js +8 -0
  379. package/src/charting/templates/StarTemplate.js +17 -0
  380. package/src/charting/templates/SwimlaneTemplate.js +18 -0
  381. package/src/charting/templates/Template.js +208 -0
  382. package/src/charting/templates/TrapezoidTemplate.js +11 -0
  383. package/src/charting/templates/TriangleTemplate.js +12 -0
  384. package/src/charting/templates/index.js +31 -0
  385. package/src/charting/templates/outline.js +59 -0
  386. package/src/charting/templates/svg.js +19 -0
  387. package/src/charting/textToShapes.js +61 -0
  388. package/src/charting/toolbar/ToolbarButton.js +38 -0
  389. package/src/charting/toolbar/ToolbarCheckbox.js +31 -0
  390. package/src/charting/toolbar/ToolbarItem.js +19 -0
  391. package/src/charting/toolbar/ToolbarMenu.js +36 -0
  392. package/src/charting/toolbar/ToolbarSelect.js +38 -0
  393. package/src/charting/toolbar/ToolbarSeparator.js +7 -0
  394. package/src/charting/toolbar/ToolbarText.js +22 -0
  395. package/src/charting/toolbar/index.js +8 -0
  396. package/src/charting/toolbar/pickFile.js +14 -0
  397. package/src/charting/viewDecorations.js +85 -0
  398. package/src/charting/zOrder.js +57 -0
  399. package/src/csvTable.js +61 -0
  400. package/src/datamodel.js +122 -0
  401. package/src/datawindow/BoundedWindow.js +36 -0
  402. package/src/datawindow/FlatDataWindow.js +34 -0
  403. package/src/datawindow/GraphDataWindow.js +40 -0
  404. package/src/datawindow/GroupedSampleDataWindow.js +16 -0
  405. package/src/datawindow/SeriesDataWindow.js +42 -0
  406. package/src/datawindow/index.js +31 -0
  407. package/src/diagramCatalog.js +30 -0
  408. package/src/ebnfDiagram.js +57 -0
  409. package/src/ebnfParser.js +129 -0
  410. package/src/exportImage.js +233 -0
  411. package/src/index.js +2636 -0
  412. package/src/itIcons.js +84 -0
  413. package/src/kernelExpr.js +243 -0
  414. package/src/propertiesDialog.js +463 -0
  415. package/src/railroadDiagram.js +571 -0
  416. package/src/treeModeCatalog.js +16 -0
  417. package/src/workspace/ContextBus.js +79 -0
  418. package/src/workspace/EditorShell.js +67 -0
  419. package/src/workspace/Part.js +163 -0
  420. package/src/workspace/PartFactory.js +49 -0
  421. package/src/workspace/PartRegistry.js +86 -0
  422. package/src/workspace/Workspace.js +321 -0
  423. package/src/workspace/archimateServices.js +33 -0
  424. package/src/workspace/dom.js +120 -0
  425. package/src/workspace/index.js +75 -0
  426. package/src/workspace/layout/GridNode.js +280 -0
  427. package/src/workspace/layout/LayoutNode.js +89 -0
  428. package/src/workspace/layout/PartNode.js +77 -0
  429. package/src/workspace/layout/SplitNode.js +114 -0
  430. package/src/workspace/layout/TabsNode.js +191 -0
  431. package/src/workspace/layout/index.js +24 -0
  432. package/src/workspace/parts/AdapterPart.js +33 -0
  433. package/src/workspace/parts/ArchimateCanvasPart.js +345 -0
  434. package/src/workspace/parts/ArchimateEditorPart.js +79 -0
  435. package/src/workspace/parts/ChartPart.js +115 -0
  436. package/src/workspace/parts/ContentPart.js +34 -0
  437. package/src/workspace/parts/DetailPart.js +46 -0
  438. package/src/workspace/parts/DiagramEditorPart.js +135 -0
  439. package/src/workspace/parts/EditorPart.js +388 -0
  440. package/src/workspace/parts/HtmlPart.js +25 -0
  441. package/src/workspace/parts/ListPart.js +57 -0
  442. package/src/workspace/parts/ModelFile.js +187 -0
  443. package/src/workspace/parts/ModelsPart.js +135 -0
  444. package/src/workspace/styles.js +258 -0
  445. package/src/workspace/themes.js +96 -0
  446. package/src/workspace/workArea.js +413 -0
  447. package/src/workspace/workAreaModel.js +197 -0
  448. package/src/workspace.js +16 -0
  449. package/src/zip/ZipArchive.js +160 -0
  450. package/src/zip/crc32.js +25 -0
  451. package/src/zip/inflate.js +159 -0
@@ -0,0 +1,135 @@
1
+ import { render } from '../dom.js';
2
+ import { EditorShell } from '../EditorShell.js';
3
+ import { EditorPart } from './EditorPart.js';
4
+ import { DiagramEditor } from '../../charting/DiagramEditor.js';
5
+ import { MenuBar } from '../../charting/MenuBar.js';
6
+ import { DiagramModel } from '../../charting/diagramModel/index.js';
7
+ import { ViewTabStrip } from '../../charting/ViewTabStrip.js';
8
+ import { LocalJsonStore } from '../../charting/storage/LocalJsonStore.js';
9
+ import { EdgeStyleCascade } from '../../charting/edgeStyle/index.js';
10
+ import { DiagramViewPropertiesDialog } from '../../charting/DiagramViewPropertiesDialog.js';
11
+
12
+ const SVG_NS = 'http://www.w3.org/2000/svg';
13
+
14
+ /**
15
+ * DiagramEditorPart — a complete diagram editor as a workspace part: menu bar,
16
+ * palette, one tab per diagram and the canvas, over a DiagramModel.
17
+ *
18
+ * Spec (JSON): `templateType` (palette category), `tabOrientation`
19
+ * ('horizontal'|'vertical'), `diagramTitle` (first diagram), `toolStyleKey`
20
+ * (localStorage key for the tool-level line style; `null` keeps it in memory).
21
+ *
22
+ * Line styles cascade line → diagram (`view.edgeStyle`) → model
23
+ * (`model.edgeStyle`) → tool. Each diagram keeps its own undo history, so undo
24
+ * survives switching tabs. The diagrams' menu (new, duplicate, rename, delete)
25
+ * comes from EditorPart. Like ChartPart it needs the engine, so it is not in
26
+ * BUILTIN_PARTS: register it explicitly.
27
+ */
28
+ export class DiagramEditorPart extends EditorPart {
29
+ static type = 'diagram-editor';
30
+ static viewNoun = 'diagram';
31
+
32
+ constructor(spec = {}) {
33
+ super(spec);
34
+ this.tabOrientation = spec.tabOrientation ?? 'horizontal';
35
+ // The editor is rebuilt with the canvas on every render, which follows every model change.
36
+ this._unsubscribe = this.model.onChange(() => { if (this.mounted) this.render(); });
37
+ }
38
+
39
+ createModel(spec) {
40
+ const store = spec.toolStyleKey === null ? null
41
+ : new LocalJsonStore(spec.toolStyleKey ?? 'renderengine.diagramEditor.toolEdgeStyle');
42
+ this.toolEdgeStyle = store?.load({}) ?? {};
43
+ const model = new DiagramModel({
44
+ name: spec.name ?? '',
45
+ templateType: spec.templateType ?? 'generic',
46
+ // Tool-level style edits go through the diagram's undo history; persist whenever it moves.
47
+ historyOptions: { onChange: () => store?.save(this.toolEdgeStyle) },
48
+ });
49
+ model.createView(spec.diagramTitle ?? 'Diagram 1');
50
+ return model;
51
+ }
52
+
53
+ render() {
54
+ const model = this.model;
55
+ const view = model.currentView;
56
+ const doc = this.document;
57
+ const canvasId = `diagram-canvas-${this.id}`;
58
+
59
+ const canvas = doc.createElementNS(SVG_NS, 'svg');
60
+ canvas.id = canvasId;
61
+ canvas.setAttribute('viewBox', '0 0 800 600');
62
+ canvas.style.cssText = 'flex: 1; width: 100%; height: 100%; display: block; background: #fff; border: 2px solid #333; box-sizing: border-box;';
63
+ const elements = doc.createElementNS(SVG_NS, 'g');
64
+ elements.id = 'elements';
65
+ canvas.appendChild(elements);
66
+
67
+ const tabs = new ViewTabStrip({
68
+ orientation: this.tabOrientation,
69
+ document: doc,
70
+ onSelect: (id) => model.switchTo(id),
71
+ menuItems: (id) => this.viewMenu.items(id),
72
+ }).render(model.views(), model.currentViewId);
73
+
74
+ // The shared workbench layout: toolbar, palette at the side, tabs + canvas in the main area.
75
+ const { toolbar: menuBarEl, side: palette, main } = new EditorShell({ document: doc, sideWidth: '200px' }).mount(this.container);
76
+ palette.classList.add('ws-diagram-palette');
77
+ Object.assign(palette.style, { padding: '8px', fontSize: '12px', display: 'flex', flexDirection: 'column', overflowY: 'hidden' });
78
+ main.style.flexDirection = this.tabOrientation === 'vertical' ? 'row' : 'column';
79
+ render(main, [tabs, { style: { flex: '1', display: 'flex', flexDirection: 'column', minHeight: '0' }, children: [canvas] }], doc);
80
+
81
+ // The editor is bound to the view's own maps and history: nothing to save back on switch.
82
+ const previous = this.editor;
83
+ previous?.dispose();
84
+ this.editor = new DiagramEditor({
85
+ diagramContainerId: canvasId,
86
+ model,
87
+ templateType: model.templateType,
88
+ onTemplateTypeChange: (type) => model.setTemplateType(type),
89
+ templates: view.templates,
90
+ edges: view.edges,
91
+ history: view.history,
92
+ arrangement: view.arrangement,
93
+ edgeStyleLevels: this.edgeStyleLevels(view),
94
+ });
95
+ if (previous) {
96
+ this.editor.showGrid = previous.showGrid;
97
+ this.editor.gridSize = previous.gridSize;
98
+ }
99
+ this.editor.initPaletteForDiagramType(palette, model.templateType);
100
+ this.menuBar?.dispose();
101
+ this.menuBar = new MenuBar({
102
+ container: menuBarEl,
103
+ editor: this.editor,
104
+ items: [this.fileMenu(), this.editMenu(), ...this.editor.menuBarItems()],
105
+ }).render();
106
+ this.editor.render();
107
+ }
108
+
109
+ /** A diagram's line-style levels, most specific first: the diagram, the model, the tool. */
110
+ edgeStyleLevels(view) {
111
+ return [
112
+ { key: 'view', label: 'Diagram', style: view.edgeStyle },
113
+ { key: 'model', label: 'Model', style: this.model.edgeStyle },
114
+ { key: 'tool', label: 'Tool', style: this.toolEdgeStyle },
115
+ ];
116
+ }
117
+
118
+ /** A diagram's properties: name, documentation and its line-style defaults. */
119
+ showViewProperties(view) {
120
+ return new DiagramViewPropertiesDialog({
121
+ model: this.model,
122
+ view,
123
+ document: this.document,
124
+ cascade: new EdgeStyleCascade(this.edgeStyleLevels(view)),
125
+ // The editor shows the current diagram; a style change there needs a redraw.
126
+ onStyleChange: () => { if (view === this.model.currentView) this.editor?.render(); },
127
+ }).open();
128
+ }
129
+
130
+ dispose() {
131
+ this.menuBar?.dispose();
132
+ this._unsubscribe();
133
+ super.dispose();
134
+ }
135
+ }
@@ -0,0 +1,388 @@
1
+ import { Part } from '../Part.js';
2
+ import { ViewMenu } from '../../charting/ViewMenu.js';
3
+ import { ToolbarMenu } from '../../charting/toolbar/index.js';
4
+ import { modelFileMenuItems } from '../../charting/ModelFileFormat.js';
5
+ import { ModelFile } from './ModelFile.js';
6
+ import { reportHtml, reportFileName } from '../../charting/report/reportHtml.js';
7
+ import { downloadBlob } from '../../exportImage.js';
8
+ import { FindReplaceDialog } from '../../charting/FindReplaceDialog.js';
9
+ import { FormDialog } from '../../charting/FormDialog.js';
10
+ import { NAME_TRANSFORMS } from '../../charting/diagramModel/nameTransforms.js';
11
+
12
+ /**
13
+ * EditorPart — base for workbench parts that edit a model of several views
14
+ * (a ViewSetModel): the template editor's DiagramEditorPart and
15
+ * ArchimateEditorPart.
16
+ *
17
+ * Owns what they share: the model (made by the subclass from the part's JSON
18
+ * spec), the view menu (new, duplicate, rename, delete) over it, a File menu
19
+ * that starts with those items and offers the part's file formats (export,
20
+ * and import, which replaces the model), and disposing the editor with the
21
+ * part. Subclasses build their editor in render() and supply
22
+ * `createModel(spec)`, and `fileFormats()` when they read and write files.
23
+ *
24
+ * With file formats the part also opens and saves a file (ModelFile): Open…,
25
+ * Save and Save As… (Ctrl+O, Ctrl+S, Ctrl+Shift+S), writing back to the file
26
+ * it opened or last saved where the browser allows; it knows when the model
27
+ * has changed since (`model.isDirty()`), shows it (`fileLabel`, the page
28
+ * title) and asks before the page is left with changes unsaved.
29
+ *
30
+ * Hosted by a ModelsPart (`ctx.models`: several models open at once, a tab
31
+ * each), its File menu also offers New model, Open… in a new tab and Close
32
+ * model, and its tab follows its file's name and saved state.
33
+ */
34
+ export class EditorPart extends Part {
35
+ /** What a view is called in this part's menus ('view', 'diagram'). */
36
+ static viewNoun = 'view';
37
+
38
+ constructor(spec = {}) {
39
+ super(spec);
40
+ if (new.target === EditorPart) throw new TypeError('EditorPart is abstract — subclass it');
41
+ this._model = this.createModel(spec);
42
+ /** The editor this part hosts; set by render(). */
43
+ this.editor = null;
44
+ /** The file the model is open from, and saved to (ModelFile). */
45
+ this.file = new ModelFile(this);
46
+ this._followEdits(this._model);
47
+ }
48
+
49
+ /** Install the file keys and the leave-page guard once mounted. */
50
+ mount(host, ctx) {
51
+ const first = !this.mounted;
52
+ super.mount(host, ctx);
53
+ if (!first || !this.fileFormats().length) return;
54
+ const win = this.document.defaultView;
55
+ this.listen(this.document, 'keydown', (e) => this.file.onKey(e));
56
+ this.listen(win, 'beforeunload', (e) => {
57
+ if (!this.model.isDirty?.()) return;
58
+ e.preventDefault();
59
+ e.returnValue = '';
60
+ });
61
+ this.file.showState();
62
+ }
63
+
64
+ /** What the part's title shows: the file's name, and • when there are unsaved changes. */
65
+ get fileLabel() {
66
+ return this.file.label;
67
+ }
68
+
69
+ /**
70
+ * Show the saved state on every edit of `model`, from now on as saved and
71
+ * with nothing to undo (making it, or opening it, is no edit). @private
72
+ */
73
+ _followEdits(model) {
74
+ this._unsubscribeEdits?.();
75
+ model.history?.clear?.();
76
+ model.markSaved?.();
77
+ this._unsubscribeEdits = model.onEdit?.(() => this.file.showState()) ?? null;
78
+ }
79
+
80
+ /** The model this part edits, built from its spec. @abstract */
81
+ createModel(spec) {
82
+ throw new Error(`${this.constructor.name} must implement createModel()`);
83
+ }
84
+
85
+ /** The model being edited (a subclass whose editor can replace it reads it from there). */
86
+ get model() {
87
+ return this._model;
88
+ }
89
+
90
+ /** The page this part is mounted in. */
91
+ get document() {
92
+ return this.container?.ownerDocument ?? globalThis.document;
93
+ }
94
+
95
+ /**
96
+ * View menu items over the current model. A subclass that can show a
97
+ * view's properties (`showViewProperties(view)`, the name included) gets
98
+ * "Properties…" in place of "Rename…".
99
+ */
100
+ get viewMenu() {
101
+ if (this._viewMenu?.model !== this.model) {
102
+ this._viewMenu = new ViewMenu(this.model, {
103
+ document: () => this.document,
104
+ noun: this.constructor.viewNoun,
105
+ editProperties: typeof this.showViewProperties === 'function' ? (view) => this.showViewProperties(view) : null,
106
+ });
107
+ }
108
+ return this._viewMenu;
109
+ }
110
+
111
+ /** File menu (fileMenuItems). */
112
+ fileMenu() {
113
+ return new ToolbarMenu('File', () => this.fileMenuItems());
114
+ }
115
+
116
+ /** Edit menu: undo and redo (the editor's), then Find and replace… over the whole model. */
117
+ editMenu() {
118
+ return new ToolbarMenu('Edit', () => this.editMenuItems());
119
+ }
120
+
121
+ editMenuItems() {
122
+ const history = this.editor?.history;
123
+ return [
124
+ { label: 'Undo', disabled: !history?.canUndo || undefined, action: () => this.editor.undo() },
125
+ { label: 'Redo', disabled: !history?.canRedo || undefined, action: () => this.editor.redo() },
126
+ ...(typeof this.model.search === 'function' ? [
127
+ { separator: true },
128
+ { label: 'Find and replace…', action: () => this.findAndReplace() },
129
+ { label: 'Transform names…', action: () => this.askTransformNames() },
130
+ ...(this.model.search().propertyNames().length ? [{ label: 'Rename property…', action: () => this.askRenameProperty() }] : []),
131
+ ] : []),
132
+ ];
133
+ }
134
+
135
+ /** Run a model-wide edit (null: nothing to do) as one undo step, then redraw. @protected */
136
+ _runModelEdit(command) {
137
+ if (!command) return null;
138
+ (this.editor?.history ?? this.model.history).execute(command);
139
+ if (this.mounted) this.render();
140
+ return command;
141
+ }
142
+
143
+ /**
144
+ * Transform names…: Title Case, Sentence case, split camelCase and the
145
+ * rest (nameTransforms.js) on every name, or on those containing some
146
+ * text. One undo step.
147
+ */
148
+ askTransformNames() {
149
+ return new FormDialog({
150
+ title: 'Transform names',
151
+ fields: [
152
+ { key: 'transform', label: 'Make them', type: 'select', value: 'title', choices: NAME_TRANSFORMS.map(([k, label]) => [k, label]) },
153
+ { key: 'text', label: 'Only names containing', type: 'text', value: '', placeholder: 'every name' },
154
+ ],
155
+ submitLabel: 'Transform',
156
+ idPrefix: 'transform-names-',
157
+ document: this.document,
158
+ validate: ({ transform, text }) => (this.model.search().transformCommand(transform, text) ? null : 'No name would change'),
159
+ onApply: ({ transform, text }) => this.transformNames(transform, text),
160
+ }).open();
161
+ }
162
+
163
+ /** Transform names (ModelSearch#transformCommand), one undo step. */
164
+ transformNames(transform, text = '') {
165
+ return this._runModelEdit(this.model.search().transformCommand(transform, text));
166
+ }
167
+
168
+ /** Rename property…: a property's name, everywhere in the model. One undo step. */
169
+ askRenameProperty() {
170
+ const names = this.model.search().propertyNames();
171
+ return new FormDialog({
172
+ title: 'Rename property',
173
+ fields: [
174
+ { key: 'from', label: 'Property', type: 'select', value: names[0], choices: names.map(n => [n, n]) },
175
+ { key: 'to', label: 'New name', type: 'text', value: '' },
176
+ ],
177
+ submitLabel: 'Rename',
178
+ idPrefix: 'rename-property-',
179
+ document: this.document,
180
+ validate: ({ from, to }) => (to?.trim() ? (to.trim() === from ? 'That is its name' : null) : 'Give its new name'),
181
+ onApply: ({ from, to }) => this.renameProperty(from, to.trim()),
182
+ }).open();
183
+ }
184
+
185
+ /** Rename a property everywhere (ModelSearch#renamePropertyCommand), one undo step. */
186
+ renameProperty(from, to) {
187
+ return this._runModelEdit(this.model.search().renamePropertyCommand(from, to));
188
+ }
189
+
190
+ /**
191
+ * Find and replace over the model (FindReplaceDialog on `model.search()`):
192
+ * a replace is one undo step on the model's history, and choosing a
193
+ * match shows it (revealMatch). The last search is kept between opens.
194
+ */
195
+ findAndReplace() {
196
+ this._findReplace ??= new FindReplaceDialog({
197
+ model: () => this.model,
198
+ history: () => this.editor?.history ?? this.model.currentView.history,
199
+ onReveal: (match) => this.revealMatch(match),
200
+ onReplaced: () => { if (this.mounted) this.render(); },
201
+ document: () => this.document,
202
+ });
203
+ return this._findReplace.open();
204
+ }
205
+
206
+ /** Show a match: its view, and on it the item (the editor's revealFinding). */
207
+ revealMatch(match) {
208
+ if (match.viewId && match.viewId !== this.model.currentViewId) this.model.switchTo(match.viewId); // the part redraws for it
209
+ if (match.kind === 'model' || match.kind === 'view') return;
210
+ this.editor?.revealFinding?.({ kind: match.kind, ids: [match.id] });
211
+ }
212
+
213
+ /** What File offers to make: a new view here; a subclass adds its own kinds (a canvas, ...). */
214
+ newItems() {
215
+ return [this.viewMenu.newViewItem()];
216
+ }
217
+
218
+ /** The ModelsPart this part is a tab of (several models open at once), or null. */
219
+ get modelsHost() {
220
+ return this.ctx?.models ?? null;
221
+ }
222
+
223
+ /** With a ModelsPart: New model, Open… in a new tab (when it opens files) and Close model. */
224
+ modelItems() {
225
+ const host = this.modelsHost;
226
+ if (!host) return [];
227
+ return [
228
+ { label: 'New model', action: () => host.newModel() },
229
+ ...(this.fileFormats().length ? [{ label: 'Open… in a new tab', action: () => host.openInNewTab(this) }] : []),
230
+ { label: 'Close model', action: () => host.closeModel(this.id) },
231
+ ];
232
+ }
233
+
234
+ /** The file or its saved state changed: a ModelsPart's tab follows it. */
235
+ onFileState() {
236
+ this.modelsHost?.fileStateChanged?.(this);
237
+ }
238
+
239
+ /**
240
+ * The File menu, grouped: **New** ▸ (a view, a subclass's kinds, a model),
241
+ * Open…, Save, Save As… (and, with a ModelsPart, Open… in a new tab, Close
242
+ * model), **Import** ▸ and **Export** ▸ (each file format, a subclass's own,
243
+ * the HTML report and the pictures), a subclass's own groups, and **This
244
+ * view** ▸ (its properties, duplicate, delete). A group of one is that item.
245
+ */
246
+ fileMenuItems() {
247
+ const models = Object.fromEntries(this.modelItems().map(i => [i.label, i]));
248
+ const [open, ...saving] = this.fileFormats().length ? this.file.menuItems() : [];
249
+ const some = (...items) => items.filter(Boolean);
250
+ return EditorPart.tidyMenu([
251
+ ...EditorPart.menuGroup('New', some(...this.newItems(), models['New model'])),
252
+ { separator: true },
253
+ ...some(open, models['Open… in a new tab'], ...saving, models['Close model']),
254
+ { separator: true },
255
+ ...EditorPart.menuGroup('Import', this.importItems(), { prefix: true }),
256
+ ...EditorPart.menuGroup('Export', this.exportItems(), { prefix: true }),
257
+ ...this.ownFileItems(),
258
+ { separator: true },
259
+ ...EditorPart.menuGroup(`This ${this.constructor.viewNoun}`, this.viewMenu.items(this.model.currentViewId)),
260
+ ]);
261
+ }
262
+
263
+ /** File > Import's items: each format that imports (it replaces the model), then the subclass's own (ownImportItems). */
264
+ importItems() {
265
+ return EditorPart.tidyMenu([
266
+ ...modelFileMenuItems(this.fileFormats(), {
267
+ model: () => this.model, only: 'import',
268
+ onImport: (model) => { this.replaceModel(model); this.file.forget(); },
269
+ document: () => this.document,
270
+ }),
271
+ ...this.ownImportItems(),
272
+ ]);
273
+ }
274
+
275
+ /** File > Export's items: each format, the subclass's own (ownExportItems), then the HTML report and the pictures. */
276
+ exportItems() {
277
+ return EditorPart.tidyMenu([
278
+ ...modelFileMenuItems(this.fileFormats(), { model: () => this.model, only: 'export', document: () => this.document }),
279
+ ...this.ownExportItems(),
280
+ { separator: true },
281
+ // In Export, "Export HTML report" is "HTML report", "Export image (PNG)" "Image (PNG)".
282
+ ...[...this.reportItems(), ...(this.editor?.imageMenuItems?.() ?? [])]
283
+ .map(i => ({ ...i, label: i.label.replace(/^Export (.)/, (_, c) => c.toUpperCase()) })),
284
+ ]);
285
+ }
286
+
287
+ /** A subclass's own File > Import items. None here. */
288
+ ownImportItems() {
289
+ return [];
290
+ }
291
+
292
+ /** A subclass's own File > Export items. None here. */
293
+ ownExportItems() {
294
+ return [];
295
+ }
296
+
297
+ /**
298
+ * Items as a submenu named `label`; none is nothing, and one is that item
299
+ * itself (with `prefix`, named as the group says it: "Export HTML report").
300
+ */
301
+ static menuGroup(label, items, { prefix = false } = {}) {
302
+ const real = EditorPart.tidyMenu(items);
303
+ if (!real.length) return [];
304
+ if (real.length > 1) return [{ label, items: real }];
305
+ const [only] = real;
306
+ if (!prefix) return [only];
307
+ // "Image (PNG)" reads "Export image (PNG)"; an acronym (HTML, CSV) or ".archimate" stays as it is.
308
+ const word = /^[A-Z][a-z]/.test(only.label) ? only.label.charAt(0).toLowerCase() + only.label.slice(1) : only.label;
309
+ return [{ ...only, label: `${label} ${word}` }];
310
+ }
311
+
312
+ /** Separators only between items: none first, last or twice in a row. */
313
+ static tidyMenu(items) {
314
+ const out = [];
315
+ for (const item of items) {
316
+ if (item.separator && (!out.length || out.at(-1).separator)) continue;
317
+ out.push(item);
318
+ }
319
+ while (out.at(-1)?.separator) out.pop();
320
+ return out;
321
+ }
322
+
323
+ /** Export HTML report, when the model has a report (ViewSetModel#report). */
324
+ reportItems() {
325
+ return typeof this.model.report === 'function' ? [{ label: 'Export HTML report', action: () => this.exportReport() }] : [];
326
+ }
327
+
328
+ /**
329
+ * The model's report as one HTML file (reportHtml), each view's picture
330
+ * in it: downloaded as `<model>-report.html`. Returns the HTML.
331
+ */
332
+ exportReport() {
333
+ const report = this.model.report({ pictures: this.viewPictures() });
334
+ const html = reportHtml(report.data());
335
+ downloadBlob(new (this.document.defaultView ?? globalThis).Blob([html], { type: 'text/html' }), reportFileName(report.title));
336
+ return html;
337
+ }
338
+
339
+ /**
340
+ * Every view's picture (DiagramEditor#viewPicture), by view id: each view
341
+ * is shown in turn, then the one that was. None when the editor draws no pictures.
342
+ */
343
+ viewPictures() {
344
+ const model = this.model;
345
+ if (typeof this.editor?.viewPicture !== 'function') return {};
346
+ const start = model.currentViewId;
347
+ const pictures = {};
348
+ try {
349
+ for (const view of model.views()) {
350
+ if (model.currentViewId !== view.id) model.switchTo(view.id); // the part redraws for it
351
+ const picture = this.editor?.viewPicture?.();
352
+ if (picture) pictures[view.id] = picture;
353
+ }
354
+ } finally {
355
+ if (model.currentViewId !== start) model.switchTo(start);
356
+ }
357
+ return pictures;
358
+ }
359
+
360
+ /** A subclass's own File items or groups, after Import and Export (templates, ...). None here. */
361
+ ownFileItems() {
362
+ return [];
363
+ }
364
+
365
+ /** The file formats (ModelFileFormat) this part's model is exported to and imported from: none here. */
366
+ fileFormats() {
367
+ return [];
368
+ }
369
+
370
+ /** Edit another model (an imported one) in place of this one, and show it. */
371
+ replaceModel(model) {
372
+ this._model = model;
373
+ this._followEdits(model);
374
+ this.modelReplaced(model);
375
+ if (this.mounted) this.render();
376
+ }
377
+
378
+ /** After `replaceModel`: a subclass moves what follows the model (change listeners, ...) onto the new one. */
379
+ modelReplaced(model) {}
380
+
381
+ dispose() {
382
+ this._unsubscribeEdits?.();
383
+ this.file.restoreTitle();
384
+ this.editor?.dispose?.();
385
+ this.editor = null;
386
+ super.dispose();
387
+ }
388
+ }
@@ -0,0 +1,25 @@
1
+ import { Part } from '../Part.js';
2
+
3
+ /**
4
+ * HtmlPart — raw markup injection. **The escape hatch, not the default.**
5
+ *
6
+ * Reach for this only when the HTML genuinely comes from outside — a server
7
+ * response, a stored document, a third-party embed. For content you are
8
+ * authoring, use `ContentPart`, which declares the same structure as a JSON
9
+ * element tree: storable, serializable, composable, and incapable of injecting
10
+ * markup through its text.
11
+ *
12
+ * `spec.html` is injected verbatim and is therefore a trust boundary — never
13
+ * pass user-supplied strings through it. `spec.text` is escaped and safe.
14
+ */
15
+ export class HtmlPart extends Part {
16
+ static type = 'html';
17
+
18
+ render() {
19
+ if (this.spec.html != null) {
20
+ this.container.innerHTML = this.spec.html;
21
+ } else {
22
+ this.container.textContent = this.spec.text ?? '';
23
+ }
24
+ }
25
+ }
@@ -0,0 +1,57 @@
1
+ import { Part } from '../Part.js';
2
+ import { el } from '../dom.js';
3
+
4
+ /**
5
+ * ListPart — a selectable list that publishes the selected item.
6
+ *
7
+ * The canonical *producer* in a mashup: it knows nothing about who consumes its
8
+ * selection. `spec.channel` names the channel (default `selection:item`);
9
+ * `spec.items` is an array of strings or `{id, label, ...}` objects, and the
10
+ * whole item object is what gets published so consumers can read extra fields.
11
+ */
12
+ export class ListPart extends Part {
13
+ static type = 'list';
14
+ static publishes = ['selection:item'];
15
+
16
+ constructor(spec = {}) {
17
+ super(spec);
18
+ this.channel = spec.channel ?? 'selection:item';
19
+ this.items = (spec.items ?? []).map(it => (typeof it === 'string' ? { id: it, label: it } : it));
20
+ this.selectedId = spec.selectedId ?? null;
21
+ }
22
+
23
+ render() {
24
+ this._buttons = new Map();
25
+ this.container.appendChild(el({
26
+ tag: 'ul',
27
+ cls: 'ws-list',
28
+ children: this.items.map(item => ({
29
+ tag: 'li',
30
+ children: [{
31
+ tag: 'button',
32
+ cls: 'ws-list-item',
33
+ text: item.label ?? item.id,
34
+ attrs: { type: 'button' },
35
+ on: { click: () => this.select(item.id) },
36
+ ref: n => this._buttons.set(item.id, n),
37
+ }],
38
+ })),
39
+ }));
40
+
41
+ if (this.selectedId != null) this.select(this.selectedId);
42
+ }
43
+
44
+ select(id) {
45
+ const item = this.items.find(i => i.id === id);
46
+ if (!item) return;
47
+ this.selectedId = id;
48
+ for (const [key, btn] of this._buttons) {
49
+ btn.classList.toggle('ws-list-item-active', key === id);
50
+ }
51
+ this.publish(this.channel, item);
52
+ }
53
+
54
+ serialize() {
55
+ return { ...super.serialize(), selectedId: this.selectedId };
56
+ }
57
+ }