@node-edit-utils/core 1.2.2

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 (102) hide show
  1. package/README.md +268 -0
  2. package/dist/index.d.ts +6 -0
  3. package/dist/lib/canvas/createCanvasObserver.d.ts +2 -0
  4. package/dist/lib/canvas/disableCanvasKeyboard.d.ts +1 -0
  5. package/dist/lib/canvas/enableCanvasKeyboard.d.ts +1 -0
  6. package/dist/lib/canvas/helpers/applyCanvasState.d.ts +1 -0
  7. package/dist/lib/canvas/helpers/getCanvasContainer.d.ts +1 -0
  8. package/dist/lib/canvas/helpers/getCanvasWindowValue.d.ts +1 -0
  9. package/dist/lib/helpers/index.d.ts +1 -0
  10. package/dist/lib/helpers/observer/connectMutationObserver.d.ts +1 -0
  11. package/dist/lib/helpers/observer/connectResizeObserver.d.ts +1 -0
  12. package/dist/lib/helpers/withRAF.d.ts +4 -0
  13. package/dist/lib/node-tools/createNodeTools.d.ts +2 -0
  14. package/dist/lib/node-tools/events/click/handleNodeClick.d.ts +1 -0
  15. package/dist/lib/node-tools/events/setupEventListener.d.ts +1 -0
  16. package/dist/lib/node-tools/highlight/clearHighlightFrame.d.ts +1 -0
  17. package/dist/lib/node-tools/highlight/createHighlightFrame.d.ts +1 -0
  18. package/dist/lib/node-tools/highlight/createTagLabel.d.ts +1 -0
  19. package/dist/lib/node-tools/highlight/createToolsContainer.d.ts +1 -0
  20. package/dist/lib/node-tools/highlight/helpers/getElementBounds.d.ts +6 -0
  21. package/dist/lib/node-tools/highlight/helpers/getHighlightFrameElement.d.ts +1 -0
  22. package/dist/lib/node-tools/highlight/highlightNode.d.ts +1 -0
  23. package/dist/lib/node-tools/highlight/refreshHighlightFrame.d.ts +1 -0
  24. package/dist/lib/node-tools/select/constants.d.ts +1 -0
  25. package/dist/lib/node-tools/select/helpers/getElementsFromPoint.d.ts +1 -0
  26. package/dist/lib/node-tools/select/helpers/targetSameCandidates.d.ts +1 -0
  27. package/dist/lib/node-tools/select/selectNode.d.ts +1 -0
  28. package/dist/lib/node-tools/text/events/setupKeydownHandler.d.ts +1 -0
  29. package/dist/lib/node-tools/text/events/setupMutationObserver.d.ts +1 -0
  30. package/dist/lib/node-tools/text/events/setupNodeListeners.d.ts +1 -0
  31. package/dist/lib/node-tools/text/helpers/hasTextContent.d.ts +1 -0
  32. package/dist/lib/node-tools/text/helpers/insertLineBreak.d.ts +1 -0
  33. package/dist/lib/node-tools/text/helpers/makeNodeEditable.d.ts +1 -0
  34. package/dist/lib/node-tools/text/helpers/makeNodeNonEditable.d.ts +1 -0
  35. package/dist/lib/node-tools/text/nodeText.d.ts +2 -0
  36. package/dist/lib/post-message/handlePostMessage.d.ts +1 -0
  37. package/dist/lib/post-message/sendPostMessage.d.ts +1 -0
  38. package/dist/lib/viewport/constants.d.ts +5 -0
  39. package/dist/lib/viewport/createViewport.d.ts +2 -0
  40. package/dist/lib/viewport/events/setupEventListener.d.ts +1 -0
  41. package/dist/lib/viewport/resize/createResizeHandle.d.ts +1 -0
  42. package/dist/lib/viewport/width/calcConstrainedWidth.d.ts +1 -0
  43. package/dist/lib/viewport/width/calcWidth.d.ts +1 -0
  44. package/dist/lib/viewport/width/updateWidth.d.ts +1 -0
  45. package/dist/lib/window/bindToWindow.d.ts +1 -0
  46. package/dist/node-edit-utils.cjs.js +588 -0
  47. package/dist/node-edit-utils.esm.js +584 -0
  48. package/dist/node-edit-utils.umd.js +594 -0
  49. package/dist/node-edit-utils.umd.min.js +1 -0
  50. package/dist/styles.css +1 -0
  51. package/dist/umd.d.ts +1 -0
  52. package/package.json +65 -0
  53. package/src/index.ts +9 -0
  54. package/src/lib/canvas/createCanvasObserver.ts +37 -0
  55. package/src/lib/canvas/disableCanvasKeyboard.ts +7 -0
  56. package/src/lib/canvas/enableCanvasKeyboard.ts +7 -0
  57. package/src/lib/canvas/helpers/applyCanvasState.ts +11 -0
  58. package/src/lib/canvas/helpers/getCanvasContainer.ts +3 -0
  59. package/src/lib/canvas/helpers/getCanvasWindowValue.ts +5 -0
  60. package/src/lib/canvas/types.d.ts +3 -0
  61. package/src/lib/helpers/index.ts +1 -0
  62. package/src/lib/helpers/observer/connectMutationObserver.ts +12 -0
  63. package/src/lib/helpers/observer/connectResizeObserver.ts +8 -0
  64. package/src/lib/helpers/withRAF.ts +39 -0
  65. package/src/lib/node-tools/createNodeTools.ts +88 -0
  66. package/src/lib/node-tools/events/click/handleNodeClick.ts +21 -0
  67. package/src/lib/node-tools/events/setupEventListener.ts +35 -0
  68. package/src/lib/node-tools/highlight/clearHighlightFrame.ts +12 -0
  69. package/src/lib/node-tools/highlight/createHighlightFrame.ts +37 -0
  70. package/src/lib/node-tools/highlight/createTagLabel.ts +7 -0
  71. package/src/lib/node-tools/highlight/createToolsContainer.ts +10 -0
  72. package/src/lib/node-tools/highlight/helpers/getElementBounds.ts +31 -0
  73. package/src/lib/node-tools/highlight/helpers/getHighlightFrameElement.ts +5 -0
  74. package/src/lib/node-tools/highlight/highlightNode.ts +23 -0
  75. package/src/lib/node-tools/highlight/refreshHighlightFrame.ts +23 -0
  76. package/src/lib/node-tools/select/constants.ts +1 -0
  77. package/src/lib/node-tools/select/helpers/getElementsFromPoint.ts +16 -0
  78. package/src/lib/node-tools/select/helpers/targetSameCandidates.ts +2 -0
  79. package/src/lib/node-tools/select/selectNode.ts +44 -0
  80. package/src/lib/node-tools/text/events/setupKeydownHandler.ts +18 -0
  81. package/src/lib/node-tools/text/events/setupMutationObserver.ts +10 -0
  82. package/src/lib/node-tools/text/events/setupNodeListeners.ts +20 -0
  83. package/src/lib/node-tools/text/helpers/hasTextContent.ts +3 -0
  84. package/src/lib/node-tools/text/helpers/insertLineBreak.ts +17 -0
  85. package/src/lib/node-tools/text/helpers/makeNodeEditable.ts +5 -0
  86. package/src/lib/node-tools/text/helpers/makeNodeNonEditable.ts +5 -0
  87. package/src/lib/node-tools/text/nodeText.ts +67 -0
  88. package/src/lib/node-tools/text/types.d.ts +6 -0
  89. package/src/lib/node-tools/types.d.ts +12 -0
  90. package/src/lib/post-message/handlePostMessage.ts +8 -0
  91. package/src/lib/post-message/sendPostMessage.ts +11 -0
  92. package/src/lib/styles/styles.css +133 -0
  93. package/src/lib/viewport/constants.ts +6 -0
  94. package/src/lib/viewport/createViewport.ts +70 -0
  95. package/src/lib/viewport/events/setupEventListener.ts +20 -0
  96. package/src/lib/viewport/resize/createResizeHandle.ts +9 -0
  97. package/src/lib/viewport/types.d.ts +8 -0
  98. package/src/lib/viewport/width/calcConstrainedWidth.ts +6 -0
  99. package/src/lib/viewport/width/calcWidth.ts +9 -0
  100. package/src/lib/viewport/width/updateWidth.ts +3 -0
  101. package/src/lib/window/bindToWindow.ts +6 -0
  102. package/src/umd.ts +1 -0
package/README.md ADDED
@@ -0,0 +1,268 @@
1
+ # @node-edit-utils/core
2
+
3
+ Core utilities for selecting, highlighting, and editing DOM nodes. This package provides framework-agnostic tools for building interactive node editing experiences.
4
+
5
+ ## ✨ Features
6
+
7
+ - **Node Selection** - Select DOM nodes and highlight them with visual frames
8
+ - **Highlight Management** - Create and update visual highlight frames around selected nodes
9
+ - **Text Editing** - Enable inline text editing for node content
10
+ - **Canvas Observer** - Monitor canvas state and interactions
11
+ - **Viewport Management** - Create resizable viewports for content viewing
12
+ - **Event Handling** - Comprehensive keyboard and mouse event support
13
+ - **Post Message API** - Cross-frame communication support
14
+
15
+ ## 📦 Installation
16
+
17
+ ```bash
18
+ npm install @node-edit-utils/core
19
+ # or
20
+ pnpm add @node-edit-utils/core
21
+ # or
22
+ yarn add @node-edit-utils/core
23
+ ```
24
+
25
+ ## 🚀 Quick Start
26
+
27
+ ### Basic Node Selection and Highlighting
28
+
29
+ ```javascript
30
+ import { createNodeTools } from '@node-edit-utils/core';
31
+ import '@node-edit-utils/core/styles.css';
32
+
33
+ // Get the container element
34
+ const container = document.getElementById('content');
35
+
36
+ // Create node tools
37
+ const nodeTools = createNodeTools(container);
38
+
39
+ // Select a node to highlight it
40
+ const targetNode = document.querySelector('.editable-element');
41
+ nodeTools.selectNode(targetNode);
42
+
43
+ // Get the currently selected node
44
+ const selected = nodeTools.getSelectedNode();
45
+
46
+ // Clear the selection
47
+ nodeTools.clearSelectedNode();
48
+
49
+ // Clean up when done
50
+ nodeTools.cleanup();
51
+ ```
52
+
53
+ ### Working with Text Editing
54
+
55
+ The text editing functionality is built into the node selection system. When you select a node, it automatically becomes editable:
56
+
57
+ ```javascript
58
+ const nodeTools = createNodeTools(container);
59
+
60
+ // Select a node - it becomes editable
61
+ const node = document.querySelector('h1');
62
+ nodeTools.selectNode(node);
63
+
64
+ // The node is now in edit mode - users can edit the text
65
+ // Press Escape to exit edit mode
66
+ // Get the currently edited node
67
+ const editableNode = nodeTools.getEditableNode();
68
+ ```
69
+
70
+ ### Canvas Observer
71
+
72
+ Monitor canvas state changes and interactions:
73
+
74
+ ```javascript
75
+ import { createCanvasObserver } from '@node-edit-utils/core';
76
+
77
+ // Create observer to monitor canvas events
78
+ const observer = createCanvasObserver();
79
+
80
+ // The observer tracks canvas interactions automatically
81
+ // You can integrate it with your canvas library
82
+ ```
83
+
84
+ ### Viewport Management
85
+
86
+ Create a resizable viewport for content viewing:
87
+
88
+ ```javascript
89
+ import { createViewport } from '@node-edit-utils/core';
90
+
91
+ // Get your viewport container
92
+ const viewportContainer = document.getElementById('viewport');
93
+
94
+ // Create the viewport
95
+ const viewport = createViewport(viewportContainer);
96
+
97
+ // Programmatically set viewport width
98
+ viewport.setWidth(800);
99
+
100
+ // Clean up
101
+ viewport.cleanup();
102
+ ```
103
+
104
+ ## 📖 API Reference
105
+
106
+ ### `createNodeTools(element: HTMLElement | null): NodeTools`
107
+
108
+ Creates a node tools manager for a given container element.
109
+
110
+ **Parameters:**
111
+ - `element` - The container element that holds the nodes to edit
112
+
113
+ **Returns:** `NodeTools` object with the following methods:
114
+
115
+ #### NodeTools Methods
116
+
117
+ - **`selectNode(node: HTMLElement | null): void`** - Select and highlight a node
118
+ - **`getSelectedNode(): HTMLElement | null`** - Get the currently selected node
119
+ - **`getEditableNode(): HTMLElement | null`** - Get the node currently in edit mode
120
+ - **`clearSelectedNode(): void`** - Clear the selection and remove highlight
121
+ - **`refreshHighlightFrame(): void`** - Refresh the highlight frame (useful after DOM changes)
122
+ - **`cleanup(): void`** - Clean up and remove all listeners
123
+
124
+ ### `createCanvasObserver(): CanvasObserver`
125
+
126
+ Creates a canvas observer for monitoring canvas interactions.
127
+
128
+ **Returns:** `CanvasObserver` object
129
+
130
+ ### `createViewport(container: HTMLElement): Viewport`
131
+
132
+ Creates a viewport with resize handles.
133
+
134
+ **Parameters:**
135
+ - `container` - The viewport container element
136
+
137
+ **Returns:** `Viewport` object with methods:
138
+ - **`setWidth(width: number): void`** - Set the viewport width
139
+ - **`cleanup(): void`** - Clean up the viewport
140
+
141
+ ## 🎨 Styling
142
+
143
+ The package includes default styles that can be imported:
144
+
145
+ ```javascript
146
+ import '@node-edit-utils/core/styles.css';
147
+ ```
148
+
149
+ You can customize the appearance by overriding CSS variables:
150
+
151
+ ```css
152
+ /* Override highlight colors */
153
+ :root {
154
+ --highlight-color: #3b82f6;
155
+ --highlight-border-width: 2px;
156
+ }
157
+ ```
158
+
159
+ ## 💡 Examples
160
+
161
+ ### Example 1: Full Node Editor Setup
162
+
163
+ ```javascript
164
+ import { createNodeTools, createViewport, createCanvasObserver } from '@node-edit-utils/core';
165
+ import '@node-edit-utils/core/styles.css';
166
+
167
+ // Setup
168
+ const container = document.getElementById('editor-container');
169
+ const viewportEl = document.getElementById('viewport');
170
+
171
+ // Create tools
172
+ const nodeTools = createNodeTools(container);
173
+ const viewport = createViewport(viewportEl);
174
+ const canvasObserver = createCanvasObserver();
175
+
176
+ // Handle node selection from UI
177
+ document.addEventListener('click', (e) => {
178
+ if (e.target.classList.contains('editable')) {
179
+ nodeTools.selectNode(e.target);
180
+ }
181
+ });
182
+
183
+ // Handle exit
184
+ document.addEventListener('keydown', (e) => {
185
+ if (e.key === 'Escape') {
186
+ nodeTools.clearSelectedNode();
187
+ }
188
+ });
189
+
190
+ // Cleanup on page unload
191
+ window.addEventListener('beforeunload', () => {
192
+ nodeTools.cleanup();
193
+ viewport.cleanup();
194
+ });
195
+ ```
196
+
197
+ ### Example 2: Programmatic Node Selection
198
+
199
+ ```javascript
200
+ const nodeTools = createNodeTools(container);
201
+
202
+ // Select different nodes
203
+ const nodes = container.querySelectorAll('[data-selectable]');
204
+ nodes.forEach((node, index) => {
205
+ setTimeout(() => {
206
+ nodeTools.selectNode(node);
207
+ }, index * 1000);
208
+ });
209
+ ```
210
+
211
+ ### Example 3: Edit Mode with Custom Handling
212
+
213
+ ```javascript
214
+ const nodeTools = createNodeTools(container);
215
+
216
+ // Listen for when a node is selected
217
+ container.addEventListener('click', (e) => {
218
+ const target = e.target;
219
+ nodeTools.selectNode(target);
220
+
221
+ // Check if it's in edit mode
222
+ if (nodeTools.getEditableNode()) {
223
+ console.log('Node is now editable:', nodeTools.getEditableNode());
224
+ }
225
+ });
226
+ ```
227
+
228
+ ## 🔄 Event Handling
229
+
230
+ The node tools automatically handle:
231
+
232
+ - **Click events** - Select nodes on click
233
+ - **Keyboard events** - Exit edit mode with Escape key
234
+ - **Resize events** - Update highlight on viewport resize
235
+ - **Mutation events** - Refresh highlight on DOM changes
236
+
237
+ ## 🧹 Cleanup
238
+
239
+ Always clean up when you're done to prevent memory leaks:
240
+
241
+ ```javascript
242
+ // When component unmounts or feature is disabled
243
+ nodeTools.cleanup();
244
+ viewport.cleanup();
245
+ ```
246
+
247
+ ## 🤝 Integration with Other Libraries
248
+
249
+ This package works well with:
250
+
251
+ - **@markup-canvas/core** and **@markup-canvas/react** - Canvas manipulation
252
+ - **React** - Via the `@node-edit-utils/react` package
253
+ - Any custom canvas or DOM manipulation library
254
+
255
+ ## ⚠️ Notes
256
+
257
+ - The package modifies the DOM by adding highlight frames and edit mode elements
258
+ - Always import the CSS file for proper styling
259
+ - The package uses ResizeObserver and MutationObserver for monitoring
260
+ - Browser support requires a modern browser with ES2020+ support
261
+
262
+ ## 📝 License
263
+
264
+ CC-BY-NC-4.0
265
+
266
+ ## 👤 Author
267
+
268
+ Fritz Benning <mail@fritzbenning.de>
@@ -0,0 +1,6 @@
1
+ import "@/lib/styles/styles.css";
2
+ export { createCanvasObserver } from "@/lib/canvas/createCanvasObserver";
3
+ export { createNodeTools } from "@/lib/node-tools/createNodeTools";
4
+ export type { NodeTools, NodeToolsRef } from "@/lib/node-tools/types";
5
+ export { createViewport } from "@/lib/viewport/createViewport";
6
+ export type { Viewport, ViewportRef } from "@/lib/viewport/types";
@@ -0,0 +1,2 @@
1
+ import type { CanvasObserver } from "./types";
2
+ export declare function createCanvasObserver(): CanvasObserver;
@@ -0,0 +1 @@
1
+ export declare const disableCanvasKeyboard: () => void;
@@ -0,0 +1 @@
1
+ export declare const enableCanvasKeyboard: () => void;
@@ -0,0 +1 @@
1
+ export declare const applyCanvasState: () => void;
@@ -0,0 +1 @@
1
+ export declare const getCanvasContainer: () => HTMLElement | null;
@@ -0,0 +1 @@
1
+ export declare const getCanvasWindowValue: (path: string[]) => any;
@@ -0,0 +1 @@
1
+ export { withRAF, withRAFThrottle } from "./withRAF";
@@ -0,0 +1 @@
1
+ export declare const connectMutationObserver: (element: HTMLElement, handler: (mutations: MutationRecord[]) => void) => MutationObserver;
@@ -0,0 +1 @@
1
+ export declare const connectResizeObserver: (element: HTMLElement, handler: (entries: ResizeObserverEntry[]) => void) => ResizeObserver;
@@ -0,0 +1,4 @@
1
+ export declare function withRAF(operation: () => void): () => void;
2
+ export declare function withRAFThrottle<T extends (...args: any[]) => void>(func: T): T & {
3
+ cleanup: () => void;
4
+ };
@@ -0,0 +1,2 @@
1
+ import type { NodeTools } from "./types";
2
+ export declare const createNodeTools: (element: HTMLElement | null) => NodeTools;
@@ -0,0 +1 @@
1
+ export declare const handleNodeClick: (event: MouseEvent, nodeProvider: HTMLElement | null, editableNode: HTMLElement | null, onNodeSelected: (node: HTMLElement | null) => void) => void;
@@ -0,0 +1 @@
1
+ export declare const setupEventListener: (nodeProvider: HTMLElement | null, onNodeSelected: (node: HTMLElement | null) => void, onEscapePressed: () => void, getEditableNode: () => HTMLElement | null) => (() => void);
@@ -0,0 +1 @@
1
+ export declare const clearHighlightFrame: (nodeProvider: HTMLElement | null) => void;
@@ -0,0 +1 @@
1
+ export declare const createHighlightFrame: (node: HTMLElement, nodeProvider: HTMLElement) => HTMLElement;
@@ -0,0 +1 @@
1
+ export declare const createTagLabel: (node: HTMLElement, nodeTools: HTMLElement) => void;
@@ -0,0 +1 @@
1
+ export declare const createToolsContainer: (node: HTMLElement, highlightFrame: HTMLElement) => void;
@@ -0,0 +1,6 @@
1
+ export declare function getElementBounds(element: Element, nodeProvider: HTMLElement): {
2
+ top: number;
3
+ left: number;
4
+ width: number;
5
+ height: number;
6
+ };
@@ -0,0 +1 @@
1
+ export declare function getHighlightFrameElement(nodeProvider: HTMLElement): HTMLElement | null;
@@ -0,0 +1 @@
1
+ export declare const highlightNode: (node: HTMLElement | null, nodeProvider: HTMLElement) => void;
@@ -0,0 +1 @@
1
+ export declare const refreshHighlightFrame: (node: HTMLElement, nodeProvider: HTMLElement) => void;
@@ -0,0 +1 @@
1
+ export declare const IGNORED_DOM_ELEMENTS: string[];
@@ -0,0 +1 @@
1
+ export declare const getElementsFromPoint: (clickX: number, clickY: number) => Element[];
@@ -0,0 +1 @@
1
+ export declare const targetSameCandidates: (cache: Element[], current: Element[]) => boolean;
@@ -0,0 +1 @@
1
+ export declare const selectNode: (event: MouseEvent, editableNode: HTMLElement | null) => HTMLElement | null;
@@ -0,0 +1 @@
1
+ export declare const setupKeydownHandler: (node: HTMLElement) => (() => void);
@@ -0,0 +1 @@
1
+ export declare const setupMutationObserver: (node: HTMLElement, nodeProvider: HTMLElement) => (() => void) | undefined;
@@ -0,0 +1 @@
1
+ export declare const setupNodeListeners: (node: HTMLElement, nodeProvider: HTMLElement | null, blur: () => void) => (() => void);
@@ -0,0 +1 @@
1
+ export declare const hasTextContent: (node: HTMLElement) => boolean;
@@ -0,0 +1 @@
1
+ export declare const insertLineBreak: () => void;
@@ -0,0 +1 @@
1
+ export declare const makeNodeEditable: (node: HTMLElement) => void;
@@ -0,0 +1 @@
1
+ export declare const makeNodeNonEditable: (node: HTMLElement) => void;
@@ -0,0 +1,2 @@
1
+ import type { NodeText } from "./types";
2
+ export declare const nodeText: () => NodeText;
@@ -0,0 +1 @@
1
+ export declare const handlePostMessage: (event: MessageEvent) => void;
@@ -0,0 +1 @@
1
+ export declare function sendPostMessage(action: string, data: unknown): void;
@@ -0,0 +1,5 @@
1
+ export declare const DEFAULT_WIDTH = 400;
2
+ export declare const RESIZE_CONFIG: {
3
+ readonly minWidth: 320;
4
+ readonly maxWidth: 1680;
5
+ };
@@ -0,0 +1,2 @@
1
+ import type { Viewport } from "./types";
2
+ export declare const createViewport: (container: HTMLElement) => Viewport;
@@ -0,0 +1 @@
1
+ export declare const setupEventListener: (resizeHandle: HTMLElement, startResize: (event: MouseEvent) => void, handleResize: (event: MouseEvent) => void, stopResize: (event: MouseEvent) => void, blurResize: () => void) => (() => void);
@@ -0,0 +1 @@
1
+ export declare const createResizeHandle: (container: HTMLElement) => HTMLElement;
@@ -0,0 +1 @@
1
+ export declare const calcConstrainedWidth: (startWidth: number, deltaX: number) => number;
@@ -0,0 +1 @@
1
+ export declare const calcWidth: (event: MouseEvent, startX: number, startWidth: number) => number;
@@ -0,0 +1 @@
1
+ export declare const updateWidth: (container: HTMLElement, width: number) => void;
@@ -0,0 +1 @@
1
+ export declare const bindToWindow: <T>(key: string, value: T) => void;