@kabel-project/kabel 1.0.7 → 1.0.8

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 (273) hide show
  1. package/dist/comment-renderer/renderer.d.ts +32 -0
  2. package/dist/comment-renderer/renderer.d.ts.map +1 -0
  3. package/dist/controllers/base.d.ts +39 -0
  4. package/dist/controllers/base.d.ts.map +1 -0
  5. package/dist/controllers/wasd.d.ts +33 -0
  6. package/dist/controllers/wasd.d.ts.map +1 -0
  7. package/dist/events/comment-drag-handle.d.ts +2 -0
  8. package/dist/events/comment-drag-handle.d.ts.map +1 -0
  9. package/dist/events/comment-input.d.ts +4 -0
  10. package/dist/events/comment-input.d.ts.map +1 -0
  11. package/dist/events/connection-line.d.ts +2 -0
  12. package/dist/events/connection-line.d.ts.map +1 -0
  13. package/dist/events/connector.d.ts +2 -0
  14. package/dist/events/connector.d.ts.map +1 -0
  15. package/dist/events/draggable.d.ts +2 -0
  16. package/dist/events/draggable.d.ts.map +1 -0
  17. package/{events/events.ts → dist/events/events.d.ts} +8 -7
  18. package/dist/events/events.d.ts.map +1 -0
  19. package/dist/events/input-box.d.ts +2 -0
  20. package/dist/events/input-box.d.ts.map +1 -0
  21. package/dist/events/node-x-btn.d.ts +2 -0
  22. package/dist/events/node-x-btn.d.ts.map +1 -0
  23. package/dist/kabel.js +2 -0
  24. package/dist/kabel.js.map +1 -0
  25. package/dist/renderers/apollo/apollo.d.ts +12 -0
  26. package/dist/renderers/apollo/apollo.d.ts.map +1 -0
  27. package/dist/renderers/apollo/constants.d.ts +21 -0
  28. package/dist/renderers/apollo/constants.d.ts.map +1 -0
  29. package/dist/renderers/apollo/renderer.d.ts +97 -0
  30. package/dist/renderers/apollo/renderer.d.ts.map +1 -0
  31. package/{renderers/atlas/atlas.ts → dist/renderers/atlas/atlas.d.ts} +6 -15
  32. package/dist/renderers/atlas/atlas.d.ts.map +1 -0
  33. package/dist/renderers/constants.d.ts +51 -0
  34. package/dist/renderers/constants.d.ts.map +1 -0
  35. package/dist/renderers/renderer.d.ts +470 -0
  36. package/dist/renderers/renderer.d.ts.map +1 -0
  37. package/dist/renderers/representer-node.d.ts +27 -0
  38. package/dist/renderers/representer-node.d.ts.map +1 -0
  39. package/dist/renderers/representer.d.ts +13 -0
  40. package/dist/renderers/representer.d.ts.map +1 -0
  41. package/dist/src/category.d.ts +48 -0
  42. package/dist/src/category.d.ts.map +1 -0
  43. package/{src/colors.ts → dist/src/colors.d.ts} +21 -20
  44. package/dist/src/colors.d.ts.map +1 -0
  45. package/dist/src/comment.d.ts +88 -0
  46. package/dist/src/comment.d.ts.map +1 -0
  47. package/dist/src/connection.d.ts +52 -0
  48. package/dist/src/connection.d.ts.map +1 -0
  49. package/dist/src/context-menu.d.ts +76 -0
  50. package/dist/src/context-menu.d.ts.map +1 -0
  51. package/dist/src/coordinates.d.ts +52 -0
  52. package/dist/src/coordinates.d.ts.map +1 -0
  53. package/dist/src/core.d.ts +153 -0
  54. package/dist/src/core.d.ts.map +1 -0
  55. package/dist/src/ctx-menu-registry.d.ts +22 -0
  56. package/dist/src/ctx-menu-registry.d.ts.map +1 -0
  57. package/dist/src/dropdown-menu.d.ts +87 -0
  58. package/dist/src/dropdown-menu.d.ts.map +1 -0
  59. package/dist/src/field.d.ts +305 -0
  60. package/dist/src/field.d.ts.map +1 -0
  61. package/dist/src/flyout.d.ts +41 -0
  62. package/dist/src/flyout.d.ts.map +1 -0
  63. package/dist/src/fonts-manager.d.ts +6 -0
  64. package/dist/src/fonts-manager.d.ts.map +1 -0
  65. package/dist/src/grid.d.ts +60 -0
  66. package/dist/src/grid.d.ts.map +1 -0
  67. package/dist/src/headless-node.d.ts +11 -0
  68. package/dist/src/headless-node.d.ts.map +1 -0
  69. package/dist/src/index.d.ts +38 -0
  70. package/dist/src/index.d.ts.map +1 -0
  71. package/dist/src/inject-headless.d.ts +4 -0
  72. package/dist/src/inject-headless.d.ts.map +1 -0
  73. package/{src/inject.ts → dist/src/inject.d.ts} +142 -213
  74. package/dist/src/inject.d.ts.map +1 -0
  75. package/{src/main-workspace.ts → dist/src/main-workspace.d.ts} +31 -51
  76. package/dist/src/main-workspace.d.ts.map +1 -0
  77. package/dist/src/mutator.d.ts +2 -0
  78. package/dist/src/mutator.d.ts.map +1 -0
  79. package/{src/node-types.ts → dist/src/node-types.d.ts} +26 -27
  80. package/dist/src/node-types.d.ts.map +1 -0
  81. package/dist/src/nodesvg.d.ts +266 -0
  82. package/dist/src/nodesvg.d.ts.map +1 -0
  83. package/{src/prototypes.ts → dist/src/prototypes.d.ts} +10 -9
  84. package/dist/src/prototypes.d.ts.map +1 -0
  85. package/{src/renderer-map.ts → dist/src/renderer-map.d.ts} +51 -86
  86. package/dist/src/renderer-map.d.ts.map +1 -0
  87. package/dist/src/toolbox.d.ts +51 -0
  88. package/dist/src/toolbox.d.ts.map +1 -0
  89. package/{src/types.ts → dist/src/types.d.ts} +159 -205
  90. package/dist/src/types.d.ts.map +1 -0
  91. package/dist/src/undo-redo.d.ts +15 -0
  92. package/dist/src/undo-redo.d.ts.map +1 -0
  93. package/{src/visual-types.ts → dist/src/visual-types.d.ts} +34 -29
  94. package/dist/src/visual-types.d.ts.map +1 -0
  95. package/dist/src/widget-prototypes.d.ts +10 -0
  96. package/dist/src/widget-prototypes.d.ts.map +1 -0
  97. package/dist/src/widget.d.ts +62 -0
  98. package/dist/src/widget.d.ts.map +1 -0
  99. package/{src/workspace-coords.ts → dist/src/workspace-coords.d.ts} +10 -14
  100. package/dist/src/workspace-coords.d.ts.map +1 -0
  101. package/dist/src/workspace-svg.d.ts +371 -0
  102. package/dist/src/workspace-svg.d.ts.map +1 -0
  103. package/dist/src/workspace.d.ts +50 -0
  104. package/dist/src/workspace.d.ts.map +1 -0
  105. package/dist/themes/dark.d.ts +4 -0
  106. package/dist/themes/dark.d.ts.map +1 -0
  107. package/dist/themes/default.d.ts +4 -0
  108. package/dist/themes/default.d.ts.map +1 -0
  109. package/dist/themes/themes.d.ts +6 -0
  110. package/dist/themes/themes.d.ts.map +1 -0
  111. package/dist/util/emitter.d.ts +10 -0
  112. package/dist/util/emitter.d.ts.map +1 -0
  113. package/dist/util/env.d.ts +7 -0
  114. package/dist/util/env.d.ts.map +1 -0
  115. package/{util/escape-html.ts → dist/util/escape-html.d.ts} +16 -22
  116. package/dist/util/escape-html.d.ts.map +1 -0
  117. package/dist/util/eventer.d.ts +29 -0
  118. package/dist/util/eventer.d.ts.map +1 -0
  119. package/dist/util/has-prop.d.ts +2 -0
  120. package/dist/util/has-prop.d.ts.map +1 -0
  121. package/dist/util/parse-color.d.ts +6 -0
  122. package/dist/util/parse-color.d.ts.map +1 -0
  123. package/dist/util/path.d.ts +25 -0
  124. package/dist/util/path.d.ts.map +1 -0
  125. package/dist/util/styler.d.ts +12 -0
  126. package/dist/util/styler.d.ts.map +1 -0
  127. package/dist/util/uid.d.ts +42 -0
  128. package/dist/util/uid.d.ts.map +1 -0
  129. package/{util/unescape-html.ts → dist/util/unescape-html.d.ts} +16 -22
  130. package/dist/util/unescape-html.d.ts.map +1 -0
  131. package/dist/util/user-state.d.ts +37 -0
  132. package/dist/util/user-state.d.ts.map +1 -0
  133. package/{util/wait-anim-frames.ts → dist/util/wait-anim-frames.d.ts} +11 -24
  134. package/dist/util/wait-anim-frames.d.ts.map +1 -0
  135. package/dist/util/window-listeners.d.ts +8 -0
  136. package/dist/util/window-listeners.d.ts.map +1 -0
  137. package/package.json +4 -1
  138. package/(1.0.7)kabel.md +0 -18
  139. package/_READ_ME_MEDIA_/documentation/docs.md +0 -293
  140. package/_READ_ME_MEDIA_/workspace.png +0 -0
  141. package/comment-renderer/renderer.ts +0 -228
  142. package/controllers/base.ts +0 -186
  143. package/controllers/wasd.ts +0 -132
  144. package/docs/README.md +0 -98
  145. package/docs/_media/docs.md +0 -289
  146. package/docs/_media/workspace.png +0 -0
  147. package/docs/classes/CommentModel.md +0 -271
  148. package/docs/classes/CommentRenderer.md +0 -457
  149. package/docs/classes/ConnectableField.md +0 -597
  150. package/docs/classes/Connection.md +0 -191
  151. package/docs/classes/ContextMenuHTML.md +0 -163
  152. package/docs/classes/Coordinates.md +0 -187
  153. package/docs/classes/DropdownContainer.md +0 -300
  154. package/docs/classes/DummyField.md +0 -393
  155. package/docs/classes/Eventer.md +0 -185
  156. package/docs/classes/Field.md +0 -461
  157. package/docs/classes/InjectMsg.md +0 -85
  158. package/docs/classes/NodeSvg.md +0 -1011
  159. package/docs/classes/NumberField.md +0 -559
  160. package/docs/classes/OptConnectField.md +0 -624
  161. package/docs/classes/Renderer.md +0 -1636
  162. package/docs/classes/RendererConstants.md +0 -343
  163. package/docs/classes/Representer.md +0 -95
  164. package/docs/classes/RepresenterNode.md +0 -175
  165. package/docs/classes/TextField.md +0 -559
  166. package/docs/classes/Toolbox.md +0 -172
  167. package/docs/classes/WASDController.md +0 -616
  168. package/docs/classes/Widget.md +0 -195
  169. package/docs/classes/WorkspaceController.md +0 -385
  170. package/docs/classes/WorkspaceCoords.md +0 -218
  171. package/docs/classes/WorkspaceSvg.md +0 -1380
  172. package/docs/functions/clearMainWorkspace.md +0 -20
  173. package/docs/functions/getMainWorkspace.md +0 -19
  174. package/docs/functions/inject.md +0 -35
  175. package/docs/functions/setMainWorkspace.md +0 -28
  176. package/docs/globals.md +0 -95
  177. package/docs/interfaces/ColorStyle.md +0 -43
  178. package/docs/interfaces/ConnectorToFrom.md +0 -57
  179. package/docs/interfaces/DrawState.md +0 -81
  180. package/docs/interfaces/FieldConnectionData.md +0 -25
  181. package/docs/interfaces/FieldOptions.md +0 -63
  182. package/docs/interfaces/FieldRawBoxData.md +0 -25
  183. package/docs/interfaces/FieldVisualInfo.md +0 -65
  184. package/docs/interfaces/GridOptions.md +0 -61
  185. package/docs/interfaces/InjectOptions.md +0 -133
  186. package/docs/interfaces/InputFieldJson.md +0 -50
  187. package/docs/interfaces/KabelCommentRendering.md +0 -31
  188. package/docs/interfaces/KabelInterface.md +0 -469
  189. package/docs/interfaces/KabelNodeRendering.md +0 -77
  190. package/docs/interfaces/KabelUIX.md +0 -105
  191. package/docs/interfaces/KabelUtils.md +0 -215
  192. package/docs/interfaces/NodeEvents.md +0 -42
  193. package/docs/interfaces/NodeJson.md +0 -104
  194. package/docs/interfaces/NodePrototype.md +0 -82
  195. package/docs/interfaces/RegisteredEl.md +0 -53
  196. package/docs/interfaces/SerializedNode.md +0 -128
  197. package/docs/interfaces/TblxCategoryStruct.md +0 -41
  198. package/docs/interfaces/TblxFieldStruct.md +0 -28
  199. package/docs/interfaces/TblxNodeStruct.md +0 -35
  200. package/docs/interfaces/WidgetOptions.md +0 -115
  201. package/docs/interfaces/WidgetPrototypeList.md +0 -15
  202. package/docs/type-aliases/AnyField.md +0 -13
  203. package/docs/type-aliases/AnyFieldCls.md +0 -13
  204. package/docs/type-aliases/Color.md +0 -13
  205. package/docs/type-aliases/Connectable.md +0 -13
  206. package/docs/type-aliases/EventArgs.md +0 -11
  207. package/docs/type-aliases/EventSetupFn.md +0 -25
  208. package/docs/type-aliases/Hex.md +0 -13
  209. package/docs/type-aliases/RGBObject.md +0 -37
  210. package/docs/type-aliases/RGBString.md +0 -13
  211. package/docs/type-aliases/RGBTuple.md +0 -13
  212. package/docs/type-aliases/TblxObjStruct.md +0 -52
  213. package/docs/variables/CategoryColors.md +0 -29
  214. package/docs/variables/FieldMap.md +0 -41
  215. package/docs/variables/NodePrototypes.md +0 -18
  216. package/docs/variables/default.md +0 -11
  217. package/events/comment-drag-handle.ts +0 -61
  218. package/events/comment-input.ts +0 -291
  219. package/events/connection-line.ts +0 -68
  220. package/events/connector.ts +0 -116
  221. package/events/draggable.ts +0 -119
  222. package/events/input-box.ts +0 -213
  223. package/events/node-x-btn.ts +0 -25
  224. package/index.d.ts +0 -4
  225. package/renderers/apollo/apollo.ts +0 -21
  226. package/renderers/apollo/constants.ts +0 -40
  227. package/renderers/apollo/renderer.ts +0 -331
  228. package/renderers/constants.ts +0 -87
  229. package/renderers/renderer.ts +0 -1288
  230. package/renderers/representer-node.ts +0 -52
  231. package/renderers/representer.ts +0 -25
  232. package/src/category.ts +0 -107
  233. package/src/comment.ts +0 -142
  234. package/src/connection.ts +0 -114
  235. package/src/context-menu.ts +0 -194
  236. package/src/coordinates.ts +0 -74
  237. package/src/core.ts +0 -202
  238. package/src/ctx-menu-registry.ts +0 -143
  239. package/src/dropdown-menu.ts +0 -215
  240. package/src/field.ts +0 -595
  241. package/src/flyout.ts +0 -165
  242. package/src/fonts-manager.ts +0 -38
  243. package/src/grid.ts +0 -162
  244. package/src/headless-node.ts +0 -27
  245. package/src/index.ts +0 -115
  246. package/src/inject-headless.ts +0 -18
  247. package/src/mutator.ts +0 -40
  248. package/src/nodesvg.ts +0 -756
  249. package/src/styles.css +0 -224
  250. package/src/toolbox.ts +0 -125
  251. package/src/undo-redo.ts +0 -87
  252. package/src/widget-prototypes.ts +0 -11
  253. package/src/widget.ts +0 -139
  254. package/src/workspace-svg.ts +0 -736
  255. package/src/workspace.ts +0 -155
  256. package/test-server.js +0 -61
  257. package/themes/dark.ts +0 -32
  258. package/themes/default.ts +0 -28
  259. package/themes/themes.ts +0 -9
  260. package/tsconfig.json +0 -25
  261. package/typedoc.json +0 -10
  262. package/util/emitter.ts +0 -33
  263. package/util/env.ts +0 -11
  264. package/util/eventer.ts +0 -108
  265. package/util/has-prop.ts +0 -4
  266. package/util/parse-color.ts +0 -42
  267. package/util/path.ts +0 -99
  268. package/util/styler.ts +0 -41
  269. package/util/uid.ts +0 -184
  270. package/util/user-state.ts +0 -68
  271. package/util/window-listeners.ts +0 -62
  272. package/webpack.config.js +0 -80
  273. /package/{docs/_media → dist}/index.html +0 -0
@@ -1,736 +0,0 @@
1
- import Coordinates from "./coordinates";
2
- import NodeSvg from "./nodesvg";
3
- import { Svg, SVG, Pattern, Rect } from '@svgdotjs/svg.js';
4
- import Renderer from '../renderers/renderer';
5
- import { InjectOptions } from "./inject";
6
- import WorkspaceCoords from "./workspace-coords";
7
- import WorkspaceController from '../controllers/base';
8
- import WASDController from '../controllers/wasd';
9
- import { RMap } from "./renderer-map";
10
- import Toolbox from "./toolbox";
11
- import NodePrototypes from "./prototypes";
12
- import newHeadlessNode from "./headless-node";
13
- import Widget from "./widget";
14
- import WidgetPrototypes from "./widget-prototypes";
15
- import ContextMenuHTML from "./context-menu";
16
- import CommentModel from "./comment";
17
- import Field, { ConnectableField } from "./field";
18
- import waitFrames from "../util/wait-anim-frames";
19
- import { addWindowListener } from "../util/window-listeners";
20
- import Grid from "./grid";
21
- import UndoRedoHistory from "./undo-redo";
22
- import hasProp from "../util/has-prop";
23
- import Workspace from "./workspace";
24
- import Themes from '../themes/themes';
25
- import { Color } from "./visual-types";
26
- import { parseColor } from "../util/parse-color";
27
-
28
- export interface IDragState {
29
- isDragging: boolean;
30
- startX: number;
31
- startY: number;
32
- lastX: number;
33
- lastY: number;
34
- deltaX: number;
35
- deltaY: number;
36
- offsetX: number;
37
- offsetY: number;
38
- node: NodeSvg | null;
39
- }
40
-
41
- function resolveController(options: InjectOptions): typeof WorkspaceController {
42
- if (options?.controls) {
43
- if (options?.controls.wasd) {
44
- return WASDController;
45
- }
46
- }
47
- return WorkspaceController;
48
- }
49
-
50
- export interface WSTheme {
51
- UIStyles?: {
52
- workspaceBGColor?: Color;
53
- toolboxCategoriesBG?: Partial<CSSStyleDeclaration>;
54
- toolboxFlyoutBG?: Partial<CSSStyleDeclaration>;
55
- }
56
- }
57
- type ThemeKeys = keyof typeof Themes; // "Classic" | "Dark"
58
- /**
59
- * Represents the visual workspace containing nodes and connections.
60
- * Handles rendering, panning, and coordinate transformations.
61
- */
62
- class WorkspaceSvg extends Workspace {
63
- static get BACKGROUND_CLASS() {
64
- return 'WorkspaceBackgroundRect';
65
- }
66
- /**
67
- * Theme of the workspace
68
- */
69
- theme!: WSTheme;
70
- /**
71
- * Workspace background pattern items.
72
- */
73
- grid?: Grid;
74
- /** Top-left offset of the workspace viewport */
75
- _camera: WorkspaceCoords;
76
-
77
- /** Node storage by unique ID */
78
- _nodeDB: Map<string, NodeSvg>;
79
-
80
- /** Root HTML container for the workspace */
81
- _root: HTMLElement;
82
-
83
- /** Top-level wrapper for the SVG */
84
- _wsTop: HTMLElement;
85
-
86
- /** SVG.js instance for rendering */
87
- svg: Svg;
88
- /** The background element */
89
- _backgroundRect!: Rect;
90
- /** Renderer instance for drawing nodes and connections */
91
- renderer: Renderer;
92
-
93
- /** Options for workspace behavior and rendering overrides */
94
- options: InjectOptions;
95
-
96
- /** Flag to temporarily prevent redraws */
97
- noRedraw: boolean;
98
- /**
99
- * A class instance that moves the camera based on user interactions.
100
- */
101
- controller: WorkspaceController;
102
- /**
103
- * Toolbox for the workspace.
104
- */
105
- toolbox?: Toolbox;
106
- /**
107
- * A list of widgets active in this workspace
108
- */
109
- _widgetDB: Map<string, Widget>
110
-
111
- /**
112
- * A manager for the context menu widget
113
- */
114
- _ctxMenu: ContextMenuHTML
115
- /**
116
- * A list of comments for this workspace.
117
- */
118
- _commentDB: Set<CommentModel>;
119
- /**
120
- * Undo/redo history
121
- */
122
- history: UndoRedoHistory;
123
- /**
124
- * Whether to record undo/redo history or not
125
- */
126
- recordHistory: boolean = true;
127
- /**
128
- * Stack of old recordHistory values for toggleHistory
129
- */
130
- recordHistoryRecord: boolean[];
131
- /**
132
- * Internal flag to indicate if the camera has moved this frame.
133
- */
134
- _didMove: boolean = false;
135
- /**
136
- * Listeners to call when the workspace moves.
137
- */
138
- moveListeners: (() => void)[];
139
- /** Current drag state for node dragging */
140
- dragState: IDragState | null = null;
141
- /**
142
- * Creates a new WorkspaceSvg instance.
143
- * @param root - The root HTML element containing the workspace.
144
- * @param wsTop - The top-level wrapper element for the SVG.
145
- * @param options - Configuration and renderer override options.
146
- */
147
- constructor(root: HTMLElement, wsTop: HTMLElement, options: InjectOptions) {
148
- super();
149
- this.isHeadless = false;
150
- wsTop.style.width = '100%';
151
- wsTop.style.height = '100%';
152
-
153
- this._root = root;
154
- this._wsTop = wsTop;
155
- this.svg = SVG().addTo(this._wsTop).size('100%', '100%');
156
- this.options = options;
157
- let RClass: typeof Renderer = RMap.resolve(options.renderer);
158
- this.renderer = new RClass(this, this.options.rendererOverrides || {});
159
-
160
- const themeKey = (typeof options.theme === 'string' && options.theme in Themes)
161
- ? options.theme as ThemeKeys
162
- : 'Classic';
163
-
164
- const theme = (typeof options.theme === 'object' && options.theme)
165
- ? options.theme
166
- : Themes[themeKey];
167
-
168
- if (this.options.toolbox) {
169
- this.toolbox = new Toolbox(this);
170
- }
171
-
172
- this._camera = new WorkspaceCoords(0, 0);
173
- this._nodeDB = new Map();
174
- this.noRedraw = false;
175
- this.controller = new (options.Controller ?? resolveController(options))(this);
176
- this._widgetDB = new Map();
177
- this._ctxMenu = new ContextMenuHTML(this);
178
- this._commentDB = new Set();
179
- this.history = new UndoRedoHistory(this);
180
- this.recordHistoryRecord = [];
181
- this.moveListeners = [];
182
- if (options.initUndoRedo !== false) {
183
- this.history.emitChange();
184
- }
185
- this.theme = {}; //placeholder
186
- this._initBackground();
187
-
188
- this.setTheme(theme); // set theme to user-defined theme.
189
- }
190
- setTheme(theme: WSTheme) {
191
- try {
192
- this.theme = structuredClone(theme);
193
- } catch {
194
- this.theme = Object.assign({}, theme);
195
- }
196
- // Clone theme so you can mutate ws.theme seperate from Kabels.Themes[ThemeName]
197
- if (this.toolbox) this.toolbox.updateStyles(this.theme);
198
- if (this.theme.UIStyles) {
199
- this._backgroundRect.fill(parseColor(this.theme.UIStyles.workspaceBGColor || '#fffffff'))
200
- }
201
- }
202
- /**
203
- * Getter and setter for whether we moved or not this frame.
204
- */
205
- get didMove() { return this._didMove; }
206
- set didMove(value: boolean) {
207
- this._didMove = value;
208
- if (value) {
209
- waitFrames(1, () => { this._didMove = false; });
210
- }
211
- }
212
- /**
213
- * Sets the drag state of the workspace.
214
- * @param params - Drag state parameters.
215
- * @returns Void.
216
- */
217
- setDragState(params: {
218
- node: NodeSvg | null;
219
- startX: number;
220
- startY: number;
221
- currentX: number;
222
- currentY: number;
223
- offsetX?: number;
224
- offsetY?: number;
225
- }) {
226
- if (!params.node) {
227
- this.dragState = null;
228
- return;
229
- }
230
-
231
- const {
232
- node,
233
- startX,
234
- startY,
235
- currentX,
236
- currentY,
237
- offsetX = 0,
238
- offsetY = 0
239
- } = params;
240
-
241
- this.dragState = {
242
- isDragging: true,
243
- node,
244
- startX,
245
- startY,
246
- offsetX,
247
- offsetY,
248
- lastX: currentX,
249
- lastY: currentY,
250
- deltaX: currentX - startX,
251
- deltaY: currentY - startY
252
- };
253
- }
254
- beginDrag(node: NodeSvg, startX: number, startY: number, offsetX: number = 0, offsetY: number = 0) {
255
- this.dragState = {
256
- isDragging: true,
257
- node,
258
- startX,
259
- startY,
260
- offsetX,
261
- offsetY,
262
- lastX: startX,
263
- lastY: startY,
264
- deltaX: 0,
265
- deltaY: 0
266
- };
267
- }
268
- /**
269
- * Updates the current drag position.
270
- * @param currentX - Current X position.
271
- * @param currentY - Current Y position.
272
- * @returns Void.
273
- */
274
- updateDrag(currentX: number, currentY: number) {
275
- if (!this.dragState || !this.dragState.node) return;
276
-
277
- this.dragState.lastX = currentX;
278
- this.dragState.lastY = currentY;
279
- this.dragState.deltaX = currentX - this.dragState.startX;
280
- this.dragState.deltaY = currentY - this.dragState.startY;
281
- }
282
- endDrag() {
283
- // Set drag state.isDragging to false instead of clearing.
284
- if (this.dragState) this.dragState.isDragging = false;
285
- }
286
-
287
-
288
- /**
289
- * Fires all move listeners registered to this workspace.
290
- */
291
- fireMoveListeners() {
292
- this.moveListeners.forEach(e => e());
293
- }
294
- /**
295
- * Adds a move listener to the workspace.
296
- * @param listener - The listener function to add.
297
- * @returns A function to remove the added listener.
298
- */
299
- addMoveListener(listener: () => void): () => void {
300
- this.moveListeners.push(listener);
301
- return () => {
302
- this.removeMoveListener(listener);
303
- }
304
- }
305
- /**
306
- * Removes a move listener from the workspace.
307
- * @param listener - The listener function to remove.
308
- */
309
- removeMoveListener(listener: () => void) {
310
- this.moveListeners = this.moveListeners.filter(e => e != listener);
311
- }
312
- /**
313
- * Emits a change event for the workspace, triggering
314
- * undo/redo history tracking.
315
- */
316
- emitChange() {
317
- this.history.emitChange();
318
- }
319
-
320
- /**
321
- * Temporarily sets the workspace's history recording state.
322
- * Pushes the previous state onto a stack for later restoration.
323
- *
324
- * @param {boolean} value - Whether history recording should be enabled.
325
- */
326
- toggleHistory(value: boolean) {
327
- this.recordHistoryRecord.push(this.recordHistory);
328
- this.recordHistory = value;
329
- }
330
-
331
- /**
332
- * Restores the previous history recording state from the stack.
333
- * Use after a temporary toggle to revert to the previous state.
334
- */
335
- untoggleHistory() {
336
- if (this.recordHistoryRecord.length == 0 || this.recordHistoryRecord.length < 0) return;
337
- this.recordHistory = this.recordHistoryRecord.pop() as boolean;
338
- }
339
-
340
- /**
341
- * Sets the background grid up based on user selected options.
342
- */
343
- _initBackground() {
344
- try {
345
- this._backgroundRect = this.svg.rect(this.svg.width(), this.svg.height())
346
- .fill(parseColor(this.theme.UIStyles?.workspaceBGColor || '#ffffff'))
347
- .addClass(WorkspaceSvg.BACKGROUND_CLASS)
348
- .addTo(this.svg);
349
-
350
- // ensure it has a parent
351
- this.svg.add(this._backgroundRect);
352
-
353
- // now you can safely move it to the back
354
- this._backgroundRect.back();
355
- } catch (e) {
356
- console.error(e);
357
- }
358
- if (this.options.grid) {
359
- this.grid = new Grid(this, this.svg, this.options.grid);
360
- }
361
- }
362
- /**
363
- * Updates the transform of the background grid
364
- */
365
- _updateBackgroundTransform() {
366
- this.grid?.updateTransform?.();
367
- try {
368
- this._backgroundRect.back();
369
- } catch (e) {
370
- console.error(e);
371
- }
372
- }
373
-
374
- /**
375
- * Get the current zoom factor of the workspace.
376
- * @returns - The zoom factor
377
- */
378
- getZoom() {
379
- return this.controller.getZoom();
380
- }
381
- /**
382
- * Refresh comments.
383
- */
384
- refreshComments() {
385
- this.renderer.refreshComments();
386
- }
387
- /**
388
- * Get all comments
389
- * @returns {CommentModel[]}
390
- */
391
- getComments() {
392
- return Array.from(this._commentDB);
393
- }
394
- /**
395
- * Duplicate node data from one to another
396
- * @param nodeSvg - The node
397
- */
398
- cloneNode(nodeSvg: NodeSvg) {
399
- const n = new NodeSvg(nodeSvg.prototype, this);
400
- n.init();
401
- n.fromNode(nodeSvg);
402
- this.redraw();
403
- }
404
- /**
405
- * Internal: Add widget to DB
406
- * @param wdgt - The widget
407
- */
408
- _addWidgetToDB(wdgt: Widget) {
409
- this._widgetDB.set(wdgt.id, wdgt);
410
- }
411
- /**
412
- * Internal: Delete a widget from DB.
413
- * @param wdgt - Widget to delete
414
- */
415
- _delWidgetFromDB(wdgt: Widget) {
416
- this._widgetDB.delete(wdgt.id);
417
- }
418
- /**
419
- * Create a new widget of type.
420
- * @param type - The prototype
421
- * @returns {Widget|void}
422
- */
423
- newWidget(type: string): void | Widget {
424
- const opts = WidgetPrototypes[type];
425
- if (!opts) return;
426
- if (opts.cls) {
427
- const wdgt = new (opts.cls)(this, opts);
428
- this._addWidgetToDB(wdgt);
429
- return wdgt;
430
- }
431
- const wdgt = new Widget(this, opts);
432
- this._addWidgetToDB(wdgt);
433
- return wdgt;
434
- }
435
- /**
436
- * Get a widget
437
- * @param id - Identifier
438
- * @returns {Widget|undefined} - A widget
439
- */
440
- getWidget(id: string): Widget | undefined {
441
- if (this._widgetDB.has(id)) return this._widgetDB.get(id);
442
- return undefined;
443
- }
444
- /**
445
- * Returns the current width and height of the workspace's svg content size in pixels.
446
- * Useful for camera positioning.
447
- */
448
- getContentSize(): { width: number; height: number } {
449
- const bbox = this.svg.bbox();
450
- return { width: bbox.width, height: bbox.height };
451
- }
452
- /**
453
- * Returns the current width and height of the workspace in pixels.
454
- * Useful for camera centering, zoom calculations, and viewport sizing.
455
- */
456
- getSize(): { width: number; height: number } {
457
- const rect = this._wsTop.getBoundingClientRect();
458
- return { width: rect.width, height: rect.height };
459
- }
460
-
461
- /**
462
- * Updates all connection lines & node screen positions without a full redraw.
463
- * Used when nodes are dragged or the camera moves.
464
- */
465
- refresh() {
466
- this.renderer.refreshNodeTransforms();
467
- this._updateBackgroundTransform();
468
- }
469
-
470
- /** Draws all nodes in the workspace. Very heavy. */
471
- drawAllNodes() {
472
- for (let [nodeId, _] of this._nodeDB) {
473
- this.drawNode(nodeId);
474
- }
475
- }
476
-
477
- /** Redraws the entire workspace unless noRedraw is set. */
478
- redraw() {
479
- if (this.noRedraw) return;
480
- this.renderer.clearScreen();
481
- this.drawAllNodes();
482
- this.refresh();
483
- this.renderer.clearComments();
484
- this.renderer.drawComments();
485
- }
486
-
487
- /**
488
- * Converts workspace coordinates to screen (SVG) coordinates.
489
- * @param x - X position in workspace coordinates.
490
- * @param y - Y position in workspace coordinates.
491
- * @returns Screen coordinates as a Coordinates instance.
492
- */
493
- workspaceToScreen(workX: number, workY: number) {
494
- const zoom = this.getZoom();
495
- // _camera represents the top-left of the visible viewport in workspace coords
496
- const x = (workX - this._camera.x) * zoom;
497
- const y = (workY - this._camera.y) * zoom;
498
- return { x, y };
499
- }
500
-
501
- /**
502
- * Converts screen (SVG) coordinates to workspace coordinates.
503
- * @param x - X position in screen coordinates.
504
- * @param y - Y position in screen coordinates.
505
- * @returns Workspace coordinates as a Coordinates instance.
506
- */
507
- screenToWorkspace(screenX: number, screenY: number) {
508
- const zoom = this.getZoom();
509
- const workX = screenX / zoom + this._camera.x;
510
- const workY = screenY / zoom + this._camera.y;
511
- return { x: workX, y: workY };
512
- }
513
-
514
- /**
515
- * Draws a node by its ID.
516
- * @param id - The ID of the node to render.
517
- * @returns The rendered node.
518
- */
519
- drawNode(id: string) {
520
- return this.renderer.rerenderNode(this._nodeDB.get(id) as NodeSvg);
521
- }
522
-
523
- /**
524
- * Adds a node to the workspace.
525
- * @param node - The node instance to add.
526
- * @param nodeId - Optional custom ID to use instead of node.id.
527
- */
528
- addNode(node: NodeSvg, nodeId?: string) {
529
- let id = nodeId || node.id;
530
- if (this._nodeDB.has(id)) {
531
- console.warn(`Node with id ${id} already exists, overwriting.`);
532
- }
533
- if (node.workspace !== this) {
534
- node.workspace = this;
535
- }
536
- this._nodeDB.set(id, node);
537
- this.drawNode(id);
538
- this.history.emitChange();
539
-
540
- }
541
-
542
- /**
543
- * Create a new node of *type*.
544
- * @param type - The node's prototype name.
545
- */
546
- newNode(type: keyof typeof NodePrototypes, add: boolean = true): NodeSvg | undefined {
547
- if (!NodePrototypes[type]) return;
548
- const node = newHeadlessNode(type as string);
549
- if (!node) return;
550
- if (add) this.addNode(node);
551
- return node;
552
- }
553
- /**
554
- * Spawns a node at x, y of prototype type
555
- * @param type - The node prototype name
556
- * @param x - X position
557
- * @param y - Y position
558
- * @returns {Node} - The new node
559
- */
560
- spawnAt(type: keyof typeof NodePrototypes, x: number, y: number): NodeSvg | undefined {
561
- const node = this.newNode(type, false);
562
- if (!node) return;
563
- node.relativeCoords.set(x, y);
564
- this.addNode(node);
565
- this.drawNode(node.id);
566
- return node;
567
- }
568
- /**
569
- * Dereference a node from all of its connected neighbors
570
- */
571
- derefNode(node: NodeSvg) {
572
- // Disconnect from previous node or field
573
- const prev = node.previousConnection?.getFrom?.();
574
- if (prev instanceof NodeSvg) {
575
- prev.nextConnection?.disconnectTo();
576
- } else if (prev instanceof ConnectableField && prev.hasConnectable()) {
577
- prev.disconnect();
578
- }
579
-
580
- // Disconnect from next node
581
- const next = node.nextConnection?.getTo?.();
582
- if (next instanceof NodeSvg) {
583
- next.previousConnection?.disconnectFrom();
584
- }
585
-
586
- // Disconnect all fields
587
- for (let field of node.allFields()) {
588
- if ((field as ConnectableField).hasConnectable?.()) {
589
- (field as ConnectableField).disconnect();
590
- }
591
- }
592
- }
593
- /**
594
- * Removes a node by its ID.
595
- * @param id - The ID of the node to remove.
596
- */
597
- removeNodeById(id: string) {
598
- const node = this._nodeDB.get(id);
599
- if (!node) return;
600
-
601
- this.derefNode(node);
602
- this._nodeDB.delete(id);
603
- this.redraw();
604
- this.history.emitChange();
605
-
606
- }
607
-
608
-
609
- /**
610
- * Removes a node by its instance.
611
- * @param node - The node instance to remove.
612
- */
613
- removeNode(node: NodeSvg) {
614
- if (!node) return;
615
- this.removeNodeById(node.id);
616
- }
617
-
618
- /**
619
- * Retrieves a node by its ID.
620
- * @param id - The ID of the node.
621
- * @returns The NodeSvg instance or undefined if not found.
622
- */
623
- getNode(id: string | NodeSvg): NodeSvg | undefined {
624
- if (id instanceof NodeSvg) return id;
625
- return this._nodeDB.get(id);
626
- }
627
-
628
- /**
629
- * Pans the camera by the given delta values.
630
- * @param dx - Change in X direction.
631
- * @param dy - Change in Y direction.
632
- */
633
- pan(dx: number, dy: number) {
634
- this.controller.pan(dx, dy);
635
- }
636
- /**
637
- * Comment methods
638
- */
639
-
640
- /**
641
- * Adds a comment, returns the model.
642
- */
643
- addComment() {
644
- const model = new CommentModel(this);
645
- this._commentDB.add(model);
646
- this.redrawComments();
647
- return model;
648
- }
649
- /**
650
- * Gets a comment by id
651
- * @param id - The comment id.
652
- */
653
- getComment(id: string) {
654
- return Array.from(this._commentDB).find(e => e.id === id);
655
- }
656
- /**
657
- * Remove a comment by its instance or id.
658
- * @param commentOrId - The comment instance or its id.
659
- */
660
- removeComment(commentOrId: CommentModel | string) {
661
- let comment: CommentModel | undefined;
662
-
663
- if (typeof commentOrId === "string") {
664
- comment = this.getComment(commentOrId);
665
- } else {
666
- comment = commentOrId;
667
- }
668
-
669
- if (!comment) return false;
670
-
671
- this._commentDB.delete(comment);
672
- this.redrawComments();
673
- return true;
674
- }
675
- /**
676
- * Redraw all comments in this workspace.
677
- */
678
- redrawComments() {
679
- this.renderer.clearComments();
680
- this.renderer.drawComments();
681
- }
682
- /**
683
- * Deserialize this workspace from json data.
684
- * @param json - Serialized workspace
685
- */
686
- fromJson(json: { nodes: any[]; circular: boolean }, recordBigEvent: boolean = false) {
687
- this.toggleHistory(false); // disable recording
688
-
689
- for (let [_, node] of this._nodeDB.entries()) {
690
- this.removeNode(node);
691
- }
692
- if (json.circular) {
693
- for (let node of json.nodes) {
694
- NodeSvg.deserialize(node, this);
695
- }
696
- } else {
697
- for (let node of json.nodes) {
698
- NodeSvg.fromJson(node, this);
699
- }
700
- }
701
-
702
- this.untoggleHistory(); // restore previous history state
703
-
704
- // only emit a single snapshot if we were told to treat it as a user-level event
705
- if (recordBigEvent && this.recordHistory) {
706
- this.history.emitChange();
707
- }
708
- }
709
-
710
- /**
711
- * Serialize this workspace, optionally using circular references.
712
- */
713
- toJson(circular: boolean) {
714
- const nodes = [];
715
- if (circular) {
716
- for (let [id, node] of this._nodeDB) {
717
- if (node.topLevel) {
718
- nodes.push(node.serialize());
719
- }
720
- }
721
- } else {
722
- for (let [id, node] of this._nodeDB) {
723
- if (node.topLevel) {
724
- nodes.push(node.toJson());
725
- }
726
- }
727
- }
728
-
729
- return {
730
- circular,
731
- nodes
732
- }
733
- }
734
- }
735
-
736
- export default WorkspaceSvg;