@node-edit-utils/core 2.3.1 → 2.3.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.
- package/dist/lib/node-tools/select/helpers/isInsideViewport.d.ts +1 -0
- package/dist/lib/viewport/constants.d.ts +2 -2
- package/dist/lib/viewport/label/getViewportLabelsOverlay.d.ts +1 -0
- package/dist/lib/viewport/label/helpers/getLabelPosition.d.ts +4 -0
- package/dist/lib/viewport/label/helpers/getTransformValues.d.ts +4 -0
- package/dist/lib/viewport/label/helpers/getZoomValue.d.ts +1 -0
- package/dist/lib/viewport/label/index.d.ts +4 -0
- package/dist/lib/viewport/label/isViewportLabelDragging.d.ts +2 -0
- package/dist/lib/viewport/label/refreshViewportLabels.d.ts +1 -0
- package/dist/lib/viewport/label/setupViewportLabelDrag.d.ts +1 -0
- package/dist/node-edit-utils.cjs.js +273 -32
- package/dist/node-edit-utils.esm.js +273 -32
- package/dist/node-edit-utils.umd.js +273 -32
- package/dist/node-edit-utils.umd.min.js +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/src/lib/canvas/createCanvasObserver.ts +14 -0
- package/src/lib/node-tools/createNodeTools.ts +12 -5
- package/src/lib/node-tools/select/helpers/isInsideViewport.ts +19 -0
- package/src/lib/node-tools/select/selectNode.ts +13 -1
- package/src/lib/node-tools/text/events/setupMutationObserver.ts +1 -0
- package/src/lib/styles/styles.css +48 -1
- package/src/lib/viewport/constants.ts +2 -2
- package/src/lib/viewport/createViewport.ts +18 -0
- package/src/lib/viewport/label/getViewportLabelsOverlay.ts +33 -0
- package/src/lib/viewport/label/helpers/getLabelPosition.ts +8 -0
- package/src/lib/viewport/label/helpers/getTransformValues.ts +8 -0
- package/src/lib/viewport/label/helpers/getZoomValue.ts +4 -0
- package/src/lib/viewport/label/index.ts +4 -0
- package/src/lib/viewport/label/isViewportLabelDragging.ts +9 -0
- package/src/lib/viewport/label/refreshViewportLabels.ts +69 -0
- package/src/lib/viewport/label/setupViewportLabelDrag.ts +98 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const isInsideViewport: (element: Element) => boolean;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export declare const DEFAULT_WIDTH = 400;
|
|
2
2
|
export declare const RESIZE_CONFIG: {
|
|
3
|
-
readonly minWidth:
|
|
4
|
-
readonly maxWidth:
|
|
3
|
+
readonly minWidth: 4;
|
|
4
|
+
readonly maxWidth: 2560;
|
|
5
5
|
};
|
|
6
6
|
export declare const RESIZE_PRESETS: readonly [{
|
|
7
7
|
readonly name: "Mobile";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const getViewportLabelsOverlay: () => SVGSVGElement;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const getZoomValue: () => number;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { getViewportLabelsOverlay } from "./getViewportLabelsOverlay";
|
|
2
|
+
export { isViewportLabelDragging } from "./isViewportLabelDragging";
|
|
3
|
+
export { refreshViewportLabels } from "./refreshViewportLabels";
|
|
4
|
+
export { setupViewportLabelDrag } from "./setupViewportLabelDrag";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const refreshViewportLabels: () => void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const setupViewportLabelDrag: (labelElement: SVGTextElement, viewportElement: HTMLElement, viewportName: string) => (() => void);
|
|
@@ -1,10 +1,218 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Markup Canvas
|
|
3
3
|
* High-performance markup canvas with zoom and pan capabilities
|
|
4
|
-
* @version 2.3.
|
|
4
|
+
* @version 2.3.2
|
|
5
5
|
*/
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
|
+
function getScreenBounds(element) {
|
|
9
|
+
const rect = element.getBoundingClientRect();
|
|
10
|
+
return {
|
|
11
|
+
top: rect.top,
|
|
12
|
+
left: rect.left,
|
|
13
|
+
width: rect.width,
|
|
14
|
+
height: rect.height,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const getCanvasContainer = () => {
|
|
19
|
+
return document.querySelector(".canvas-container");
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const getViewportLabelsOverlay = () => {
|
|
23
|
+
const canvasContainer = getCanvasContainer();
|
|
24
|
+
const container = canvasContainer || document.body;
|
|
25
|
+
// Check if overlay already exists
|
|
26
|
+
let overlay = container.querySelector(".viewport-labels-overlay");
|
|
27
|
+
if (!overlay) {
|
|
28
|
+
// Create new SVG overlay
|
|
29
|
+
overlay = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
30
|
+
overlay.classList.add("viewport-labels-overlay");
|
|
31
|
+
// Set fixed positioning
|
|
32
|
+
overlay.style.position = "absolute";
|
|
33
|
+
overlay.style.top = "0";
|
|
34
|
+
overlay.style.left = "0";
|
|
35
|
+
overlay.style.width = "100vw";
|
|
36
|
+
overlay.style.height = "100vh";
|
|
37
|
+
overlay.style.pointerEvents = "none";
|
|
38
|
+
overlay.style.zIndex = "500";
|
|
39
|
+
const viewportWidth = document.documentElement.clientWidth || window.innerWidth;
|
|
40
|
+
const viewportHeight = document.documentElement.clientHeight || window.innerHeight;
|
|
41
|
+
overlay.setAttribute("width", viewportWidth.toString());
|
|
42
|
+
overlay.setAttribute("height", viewportHeight.toString());
|
|
43
|
+
container.appendChild(overlay);
|
|
44
|
+
}
|
|
45
|
+
return overlay;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// Global flag to prevent refreshViewportLabels during drag
|
|
49
|
+
let globalIsDragging = false;
|
|
50
|
+
const isViewportLabelDragging = () => globalIsDragging;
|
|
51
|
+
const setViewportLabelDragging = (isDragging) => {
|
|
52
|
+
globalIsDragging = isDragging;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
function sendPostMessage(action, data) {
|
|
56
|
+
window.parent.postMessage({
|
|
57
|
+
source: "node-edit-utils",
|
|
58
|
+
action,
|
|
59
|
+
data,
|
|
60
|
+
timestamp: Date.now(),
|
|
61
|
+
}, "*");
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const getLabelPosition = (labelGroup) => {
|
|
65
|
+
const transform = labelGroup.getAttribute("transform");
|
|
66
|
+
const match = transform?.match(/translate\((-?\d+(?:\.\d+)?),\s*(-?\d+(?:\.\d+)?)\)/);
|
|
67
|
+
if (match) {
|
|
68
|
+
return { x: parseFloat(match[1]), y: parseFloat(match[2]) };
|
|
69
|
+
}
|
|
70
|
+
return { x: 0, y: 0 };
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const getTransformValues = (element) => {
|
|
74
|
+
const style = element.style.transform;
|
|
75
|
+
const match = style.match(/translate3d\((-?\d+(?:\.\d+)?)px,\s*(-?\d+(?:\.\d+)?)px,\s*(-?\d+(?:\.\d+)?)px\)/);
|
|
76
|
+
if (match) {
|
|
77
|
+
return { x: parseFloat(match[1]), y: parseFloat(match[2]) };
|
|
78
|
+
}
|
|
79
|
+
return { x: 0, y: 0 };
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const getZoomValue = () => {
|
|
83
|
+
const zoomValue = getComputedStyle(document.body).getPropertyValue("--zoom").trim();
|
|
84
|
+
return zoomValue ? parseFloat(zoomValue) : 1;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const setupViewportLabelDrag = (labelElement, viewportElement, viewportName) => {
|
|
88
|
+
let isDragging = false;
|
|
89
|
+
let startX = 0;
|
|
90
|
+
let startY = 0;
|
|
91
|
+
let initialTransform = { x: 0, y: 0 };
|
|
92
|
+
let initialLabelPosition = { x: 0, y: 0 };
|
|
93
|
+
// Get the parent group element that contains the label
|
|
94
|
+
const labelGroup = labelElement.parentElement;
|
|
95
|
+
const startDrag = (event) => {
|
|
96
|
+
event.preventDefault();
|
|
97
|
+
event.stopPropagation();
|
|
98
|
+
isDragging = true;
|
|
99
|
+
setViewportLabelDragging(true);
|
|
100
|
+
startX = event.clientX;
|
|
101
|
+
startY = event.clientY;
|
|
102
|
+
initialTransform = getTransformValues(viewportElement);
|
|
103
|
+
initialLabelPosition = getLabelPosition(labelGroup);
|
|
104
|
+
};
|
|
105
|
+
const handleDrag = (event) => {
|
|
106
|
+
if (!isDragging)
|
|
107
|
+
return;
|
|
108
|
+
const zoom = getZoomValue();
|
|
109
|
+
// Calculate mouse delta
|
|
110
|
+
const rawDeltaX = event.clientX - startX;
|
|
111
|
+
const rawDeltaY = event.clientY - startY;
|
|
112
|
+
// Adjust delta for zoom level
|
|
113
|
+
const deltaX = rawDeltaX / zoom;
|
|
114
|
+
const deltaY = rawDeltaY / zoom;
|
|
115
|
+
const newX = initialTransform.x + deltaX;
|
|
116
|
+
const newY = initialTransform.y + deltaY;
|
|
117
|
+
// Update label position with raw delta (labels are in screen space)
|
|
118
|
+
const newLabelX = initialLabelPosition.x + rawDeltaX;
|
|
119
|
+
const newLabelY = initialLabelPosition.y + rawDeltaY;
|
|
120
|
+
labelGroup.setAttribute("transform", `translate(${newLabelX}, ${newLabelY})`);
|
|
121
|
+
// Update viewport position with zoom-adjusted delta
|
|
122
|
+
viewportElement.style.transform = `translate3d(${newX}px, ${newY}px, 0)`;
|
|
123
|
+
};
|
|
124
|
+
const stopDrag = (event) => {
|
|
125
|
+
if (!isDragging)
|
|
126
|
+
return;
|
|
127
|
+
event.preventDefault();
|
|
128
|
+
event.stopPropagation();
|
|
129
|
+
isDragging = false;
|
|
130
|
+
setViewportLabelDragging(false);
|
|
131
|
+
const finalTransform = getTransformValues(viewportElement);
|
|
132
|
+
// Trigger refresh after drag completes to update highlight frame and labels
|
|
133
|
+
// biome-ignore lint/suspicious/noExplicitAny: global window extension
|
|
134
|
+
const nodeTools = window.nodeTools;
|
|
135
|
+
if (nodeTools?.refreshHighlightFrame) {
|
|
136
|
+
nodeTools.refreshHighlightFrame();
|
|
137
|
+
}
|
|
138
|
+
// Notify parent about the new position
|
|
139
|
+
sendPostMessage("viewport-position-changed", {
|
|
140
|
+
viewportName,
|
|
141
|
+
x: finalTransform.x,
|
|
142
|
+
y: finalTransform.y,
|
|
143
|
+
});
|
|
144
|
+
};
|
|
145
|
+
const cancelDrag = () => {
|
|
146
|
+
isDragging = false;
|
|
147
|
+
setViewportLabelDragging(false);
|
|
148
|
+
};
|
|
149
|
+
// Attach event listeners
|
|
150
|
+
labelElement.addEventListener("mousedown", startDrag);
|
|
151
|
+
document.addEventListener("mousemove", handleDrag);
|
|
152
|
+
document.addEventListener("mouseup", stopDrag);
|
|
153
|
+
window.addEventListener("blur", cancelDrag);
|
|
154
|
+
// Return cleanup function
|
|
155
|
+
return () => {
|
|
156
|
+
labelElement.removeEventListener("mousedown", startDrag);
|
|
157
|
+
document.removeEventListener("mousemove", handleDrag);
|
|
158
|
+
document.removeEventListener("mouseup", stopDrag);
|
|
159
|
+
window.removeEventListener("blur", cancelDrag);
|
|
160
|
+
};
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
// Store cleanup functions for drag listeners
|
|
164
|
+
const dragCleanupFunctions = new Map();
|
|
165
|
+
const refreshViewportLabels = () => {
|
|
166
|
+
// Skip refresh if a viewport label is being dragged
|
|
167
|
+
if (isViewportLabelDragging()) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
const overlay = getViewportLabelsOverlay();
|
|
171
|
+
// Update SVG dimensions to match current viewport
|
|
172
|
+
const viewportWidth = document.documentElement.clientWidth || window.innerWidth;
|
|
173
|
+
const viewportHeight = document.documentElement.clientHeight || window.innerHeight;
|
|
174
|
+
overlay.setAttribute("width", viewportWidth.toString());
|
|
175
|
+
overlay.setAttribute("height", viewportHeight.toString());
|
|
176
|
+
// Find all viewports with names
|
|
177
|
+
const viewports = document.querySelectorAll(".viewport[data-viewport-name]");
|
|
178
|
+
// Clean up existing drag listeners
|
|
179
|
+
dragCleanupFunctions.forEach((cleanup) => {
|
|
180
|
+
cleanup();
|
|
181
|
+
});
|
|
182
|
+
dragCleanupFunctions.clear();
|
|
183
|
+
// Remove existing label groups
|
|
184
|
+
const existingGroups = overlay.querySelectorAll(".viewport-label-group");
|
|
185
|
+
existingGroups.forEach((group) => {
|
|
186
|
+
group.remove();
|
|
187
|
+
});
|
|
188
|
+
// Create/update labels for each viewport
|
|
189
|
+
viewports.forEach((viewport) => {
|
|
190
|
+
const viewportElement = viewport;
|
|
191
|
+
const viewportName = viewportElement.getAttribute("data-viewport-name");
|
|
192
|
+
if (!viewportName)
|
|
193
|
+
return;
|
|
194
|
+
const bounds = getScreenBounds(viewportElement);
|
|
195
|
+
// Create group for this viewport label
|
|
196
|
+
const group = document.createElementNS("http://www.w3.org/2000/svg", "g");
|
|
197
|
+
group.classList.add("viewport-label-group");
|
|
198
|
+
group.setAttribute("data-viewport-name", viewportName);
|
|
199
|
+
group.setAttribute("transform", `translate(${bounds.left}, ${bounds.top})`);
|
|
200
|
+
// Create text element
|
|
201
|
+
const text = document.createElementNS("http://www.w3.org/2000/svg", "text");
|
|
202
|
+
text.classList.add("viewport-label-text");
|
|
203
|
+
text.setAttribute("x", "0");
|
|
204
|
+
text.setAttribute("y", "-8");
|
|
205
|
+
text.setAttribute("vector-effect", "non-scaling-stroke");
|
|
206
|
+
text.setAttribute("pointer-events", "auto");
|
|
207
|
+
text.textContent = viewportName;
|
|
208
|
+
group.appendChild(text);
|
|
209
|
+
overlay.appendChild(group);
|
|
210
|
+
// Setup drag functionality for this label
|
|
211
|
+
const cleanup = setupViewportLabelDrag(text, viewportElement, viewportName);
|
|
212
|
+
dragCleanupFunctions.set(viewportName, cleanup);
|
|
213
|
+
});
|
|
214
|
+
};
|
|
215
|
+
|
|
8
216
|
const getCanvasWindowValue = (path, canvasName = "canvas") => {
|
|
9
217
|
// biome-ignore lint/suspicious/noExplicitAny: global window extension
|
|
10
218
|
const canvas = window[canvasName];
|
|
@@ -34,6 +242,8 @@ function createCanvasObserver(canvasName = "canvas") {
|
|
|
34
242
|
if (nodeTools?.refreshHighlightFrame) {
|
|
35
243
|
nodeTools.refreshHighlightFrame();
|
|
36
244
|
}
|
|
245
|
+
// Refresh viewport labels
|
|
246
|
+
refreshViewportLabels();
|
|
37
247
|
});
|
|
38
248
|
observer.observe(transformLayer, {
|
|
39
249
|
attributes: true,
|
|
@@ -41,8 +251,16 @@ function createCanvasObserver(canvasName = "canvas") {
|
|
|
41
251
|
subtree: true,
|
|
42
252
|
childList: true,
|
|
43
253
|
});
|
|
254
|
+
// Handle window resize for viewport labels
|
|
255
|
+
const handleResize = () => {
|
|
256
|
+
refreshViewportLabels();
|
|
257
|
+
};
|
|
258
|
+
window.addEventListener("resize", handleResize);
|
|
259
|
+
// Initial refresh of viewport labels
|
|
260
|
+
refreshViewportLabels();
|
|
44
261
|
function disconnect() {
|
|
45
262
|
observer.disconnect();
|
|
263
|
+
window.removeEventListener("resize", handleResize);
|
|
46
264
|
}
|
|
47
265
|
return {
|
|
48
266
|
disconnect,
|
|
@@ -57,15 +275,6 @@ const connectResizeObserver = (element, handler) => {
|
|
|
57
275
|
return resizeObserver;
|
|
58
276
|
};
|
|
59
277
|
|
|
60
|
-
function sendPostMessage(action, data) {
|
|
61
|
-
window.parent.postMessage({
|
|
62
|
-
source: "node-edit-utils",
|
|
63
|
-
action,
|
|
64
|
-
data,
|
|
65
|
-
timestamp: Date.now(),
|
|
66
|
-
}, "*");
|
|
67
|
-
}
|
|
68
|
-
|
|
69
278
|
const bindToWindow = (key, value) => {
|
|
70
279
|
if (typeof window !== "undefined") {
|
|
71
280
|
// biome-ignore lint/suspicious/noExplicitAny: global window extension requires flexibility
|
|
@@ -93,10 +302,6 @@ const processPostMessage = (event, onNodeSelected) => {
|
|
|
93
302
|
}
|
|
94
303
|
};
|
|
95
304
|
|
|
96
|
-
const getCanvasContainer = () => {
|
|
97
|
-
return document.querySelector(".canvas-container");
|
|
98
|
-
};
|
|
99
|
-
|
|
100
305
|
const clearHighlightFrame = () => {
|
|
101
306
|
const canvasContainer = getCanvasContainer();
|
|
102
307
|
const container = canvasContainer || document.body;
|
|
@@ -148,6 +353,21 @@ const isInsideComponent = (element) => {
|
|
|
148
353
|
return false;
|
|
149
354
|
};
|
|
150
355
|
|
|
356
|
+
const isInsideViewport = (element) => {
|
|
357
|
+
let current = element;
|
|
358
|
+
while (current) {
|
|
359
|
+
if (current.classList.contains("viewport")) {
|
|
360
|
+
return true;
|
|
361
|
+
}
|
|
362
|
+
// Stop at node-provider to avoid checking beyond the editable area
|
|
363
|
+
if (current.getAttribute("data-role") === "node-provider") {
|
|
364
|
+
break;
|
|
365
|
+
}
|
|
366
|
+
current = current.parentElement;
|
|
367
|
+
}
|
|
368
|
+
return false;
|
|
369
|
+
};
|
|
370
|
+
|
|
151
371
|
const targetSameCandidates = (cache, current) => cache.length === current.length && cache.every((el, i) => el === current[i]);
|
|
152
372
|
|
|
153
373
|
let candidateCache = [];
|
|
@@ -160,7 +380,16 @@ const selectNode = (event, nodeProvider, text) => {
|
|
|
160
380
|
const clickThrough = event.metaKey || event.ctrlKey;
|
|
161
381
|
const candidates = getElementsFromPoint(clickX, clickY).filter((element) => !IGNORED_DOM_ELEMENTS.includes(element.tagName.toLowerCase()) &&
|
|
162
382
|
!element.classList.contains("select-none") &&
|
|
163
|
-
!
|
|
383
|
+
!element.classList.contains("content-layer") &&
|
|
384
|
+
!element.classList.contains("resize-handle") &&
|
|
385
|
+
!element.classList.contains("resize-presets") &&
|
|
386
|
+
!isInsideComponent(element) &&
|
|
387
|
+
isInsideViewport(element));
|
|
388
|
+
console.log("candidates", candidates);
|
|
389
|
+
if (candidates.length === 0) {
|
|
390
|
+
lastSelectedNode = null;
|
|
391
|
+
return null;
|
|
392
|
+
}
|
|
164
393
|
const editableNode = text.getEditableNode();
|
|
165
394
|
if (editableNode && candidates.includes(editableNode)) {
|
|
166
395
|
selectedNode = editableNode;
|
|
@@ -265,16 +494,6 @@ const createCornerHandles = (group, width, height, isInstance = false, isTextEdi
|
|
|
265
494
|
createCornerHandle(group, 0, height, "handle-bottom-left", isInstance, isTextEdit);
|
|
266
495
|
};
|
|
267
496
|
|
|
268
|
-
function getScreenBounds(element) {
|
|
269
|
-
const rect = element.getBoundingClientRect();
|
|
270
|
-
return {
|
|
271
|
-
top: rect.top,
|
|
272
|
-
left: rect.left,
|
|
273
|
-
width: rect.width,
|
|
274
|
-
height: rect.height,
|
|
275
|
-
};
|
|
276
|
-
}
|
|
277
|
-
|
|
278
497
|
const getComponentColor$1 = () => {
|
|
279
498
|
return getComputedStyle(document.documentElement).getPropertyValue("--component-color").trim() || "oklch(65.6% 0.241 354.308)";
|
|
280
499
|
};
|
|
@@ -707,6 +926,7 @@ const setupMutationObserver = (node, nodeProvider, canvasName = "canvas") => {
|
|
|
707
926
|
// Accumulate mutations instead of replacing
|
|
708
927
|
pendingMutations.push(...mutations);
|
|
709
928
|
scheduleProcess();
|
|
929
|
+
console.log("refreshHighlightFrame in mutationObserver");
|
|
710
930
|
refreshHighlightFrame(node, nodeProvider, canvasName);
|
|
711
931
|
});
|
|
712
932
|
return () => {
|
|
@@ -844,14 +1064,15 @@ const createNodeTools = (element, canvasName = "canvas") => {
|
|
|
844
1064
|
checkNodeExists();
|
|
845
1065
|
if (!document.contains(node))
|
|
846
1066
|
return;
|
|
1067
|
+
console.log("refreshHighlightFrame in mutationObserver 2");
|
|
847
1068
|
refreshHighlightFrame(node, nodeProvider, canvasName);
|
|
848
1069
|
updateHighlightFrameVisibility(node);
|
|
849
1070
|
});
|
|
850
1071
|
mutationObserver.observe(node, {
|
|
851
1072
|
attributes: true,
|
|
852
1073
|
characterData: true,
|
|
853
|
-
childList: true,
|
|
854
|
-
subtree: true,
|
|
1074
|
+
//childList: true,
|
|
1075
|
+
//subtree: true,
|
|
855
1076
|
});
|
|
856
1077
|
// Also observe parent node to catch when this node is removed
|
|
857
1078
|
const parentNode = node.parentElement;
|
|
@@ -880,15 +1101,22 @@ const createNodeTools = (element, canvasName = "canvas") => {
|
|
|
880
1101
|
if (!document.contains(node))
|
|
881
1102
|
return; // Exit early if node was removed
|
|
882
1103
|
refreshHighlightFrame(node, nodeProvider, canvasName);
|
|
1104
|
+
console.log("refreshHighlightFrame in resizeObserver");
|
|
883
1105
|
updateHighlightFrameVisibility(node);
|
|
884
1106
|
});
|
|
885
1107
|
}
|
|
886
1108
|
selectedNode = node;
|
|
887
1109
|
sendPostMessage("selectedNodeChanged", node?.getAttribute("data-node-id") ?? null);
|
|
888
1110
|
highlightNode(node) ?? null;
|
|
889
|
-
if (node
|
|
890
|
-
|
|
891
|
-
|
|
1111
|
+
if (node) {
|
|
1112
|
+
highlightNode(node);
|
|
1113
|
+
if (nodeProvider) {
|
|
1114
|
+
updateHighlightFrameVisibility(node);
|
|
1115
|
+
updateHighlightFrameVisibility(node);
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
else {
|
|
1119
|
+
clearHighlightFrame();
|
|
892
1120
|
}
|
|
893
1121
|
};
|
|
894
1122
|
// Setup event listener
|
|
@@ -929,8 +1157,8 @@ const createNodeTools = (element, canvasName = "canvas") => {
|
|
|
929
1157
|
|
|
930
1158
|
const DEFAULT_WIDTH = 400;
|
|
931
1159
|
const RESIZE_CONFIG = {
|
|
932
|
-
minWidth:
|
|
933
|
-
maxWidth:
|
|
1160
|
+
minWidth: 4,
|
|
1161
|
+
maxWidth: 2560,
|
|
934
1162
|
};
|
|
935
1163
|
const RESIZE_PRESETS = [
|
|
936
1164
|
{
|
|
@@ -1081,14 +1309,27 @@ const createViewport = (container, initialWidth) => {
|
|
|
1081
1309
|
isDragging = false;
|
|
1082
1310
|
};
|
|
1083
1311
|
const removeListeners = setupEventListener(resizeHandle, startResize, handleResize, stopResize, blurResize);
|
|
1312
|
+
// Refresh viewport labels when viewport is created
|
|
1313
|
+
refreshViewportLabels();
|
|
1084
1314
|
const cleanup = () => {
|
|
1085
1315
|
isDragging = false;
|
|
1086
1316
|
removeListeners();
|
|
1087
1317
|
resizeHandle.remove();
|
|
1318
|
+
// Refresh labels after cleanup to remove this viewport's label if needed
|
|
1319
|
+
refreshViewportLabels();
|
|
1088
1320
|
};
|
|
1089
1321
|
return {
|
|
1090
1322
|
setWidth: (width) => {
|
|
1091
1323
|
updateWidth(container, width);
|
|
1324
|
+
refreshViewportLabels();
|
|
1325
|
+
// Refresh highlight frame when viewport width changes to update node positions
|
|
1326
|
+
// biome-ignore lint/suspicious/noExplicitAny: global window extension
|
|
1327
|
+
const nodeTools = window.nodeTools;
|
|
1328
|
+
const selectedNode = nodeTools?.getSelectedNode?.();
|
|
1329
|
+
const nodeProvider = document.querySelector('[data-role="node-provider"]');
|
|
1330
|
+
if (selectedNode && nodeProvider) {
|
|
1331
|
+
refreshHighlightFrame(selectedNode, nodeProvider);
|
|
1332
|
+
}
|
|
1092
1333
|
},
|
|
1093
1334
|
cleanup,
|
|
1094
1335
|
};
|