@node-edit-utils/core 2.3.3 → 2.3.4
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/viewport/label/getViewportLabelOverlay.d.ts +1 -0
- package/dist/lib/viewport/label/index.d.ts +5 -3
- package/dist/lib/viewport/label/isViewportDragging.d.ts +2 -0
- package/dist/lib/viewport/label/refreshViewportLabel.d.ts +8 -0
- package/dist/lib/viewport/label/removeViewportLabel.d.ts +5 -0
- package/dist/lib/viewport/label/setupViewportDrag.d.ts +1 -0
- package/dist/node-edit-utils.cjs.js +100 -62
- package/dist/node-edit-utils.esm.js +100 -62
- package/dist/node-edit-utils.umd.js +100 -62
- package/dist/node-edit-utils.umd.min.js +1 -1
- package/dist/styles.css +1 -1
- package/package.json +7 -2
- package/src/lib/canvas/createCanvasObserver.test.ts +242 -0
- package/src/lib/canvas/disableCanvasKeyboard.test.ts +53 -0
- package/src/lib/canvas/disableCanvasKeyboard.ts +1 -1
- package/src/lib/canvas/disableCanvasTextMode.test.ts +53 -0
- package/src/lib/canvas/disableCanvasTextMode.ts +1 -1
- package/src/lib/canvas/enableCanvasKeyboard.test.ts +53 -0
- package/src/lib/canvas/enableCanvasKeyboard.ts +1 -1
- package/src/lib/canvas/enableCanvasTextMode.test.ts +53 -0
- package/src/lib/canvas/enableCanvasTextMode.ts +1 -1
- package/src/lib/canvas/helpers/applyCanvasState.test.ts +119 -0
- package/src/lib/canvas/helpers/applyCanvasState.ts +1 -1
- package/src/lib/canvas/helpers/getCanvasContainer.test.ts +62 -0
- package/src/lib/canvas/helpers/getCanvasContainerOrBody.test.ts +51 -0
- package/src/lib/canvas/helpers/getCanvasWindowValue.test.ts +116 -0
- package/src/lib/helpers/adjustForZoom.test.ts +65 -0
- package/src/lib/helpers/createDragHandler.test.ts +325 -0
- package/src/lib/helpers/getNodeProvider.test.ts +71 -0
- package/src/lib/helpers/getNodeTools.test.ts +50 -0
- package/src/lib/helpers/getViewportDimensions.test.ts +93 -0
- package/src/lib/helpers/observer/connectMutationObserver.test.ts +127 -0
- package/src/lib/helpers/observer/connectResizeObserver.test.ts +147 -0
- package/src/lib/helpers/parseTransform.test.ts +117 -0
- package/src/lib/helpers/toggleClass.test.ts +71 -0
- package/src/lib/helpers/withRAF.test.ts +439 -0
- package/src/lib/node-tools/createNodeTools.test.ts +373 -0
- package/src/lib/node-tools/events/click/handleNodeClick.test.ts +109 -0
- package/src/lib/node-tools/events/setupEventListener.test.ts +136 -0
- package/src/lib/node-tools/highlight/clearHighlightFrame.test.ts +88 -0
- package/src/lib/node-tools/highlight/createCornerHandles.test.ts +150 -0
- package/src/lib/node-tools/highlight/createHighlightFrame.test.ts +237 -0
- package/src/lib/node-tools/highlight/createTagLabel.test.ts +135 -0
- package/src/lib/node-tools/highlight/createToolsContainer.test.ts +97 -0
- package/src/lib/node-tools/highlight/helpers/getElementBounds.test.ts +158 -0
- package/src/lib/node-tools/highlight/helpers/getHighlightFrameElement.test.ts +78 -0
- package/src/lib/node-tools/highlight/helpers/getScreenBounds.test.ts +133 -0
- package/src/lib/node-tools/highlight/highlightNode.test.ts +213 -0
- package/src/lib/node-tools/highlight/refreshHighlightFrame.test.ts +323 -0
- package/src/lib/node-tools/highlight/updateHighlightFrameVisibility.test.ts +110 -0
- package/src/lib/node-tools/select/helpers/getElementsFromPoint.test.ts +109 -0
- package/src/lib/node-tools/select/helpers/isInsideComponent.test.ts +81 -0
- package/src/lib/node-tools/select/helpers/isInsideViewport.test.ts +82 -0
- package/src/lib/node-tools/select/helpers/targetSameCandidates.test.ts +81 -0
- package/src/lib/node-tools/select/selectNode.test.ts +238 -0
- package/src/lib/node-tools/text/events/setupKeydownHandler.test.ts +91 -0
- package/src/lib/node-tools/text/events/setupMutationObserver.test.ts +213 -0
- package/src/lib/node-tools/text/events/setupNodeListeners.test.ts +133 -0
- package/src/lib/node-tools/text/helpers/enterTextEditMode.test.ts +50 -0
- package/src/lib/node-tools/text/helpers/handleTextChange.test.ts +201 -0
- package/src/lib/node-tools/text/helpers/hasTextContent.test.ts +101 -0
- package/src/lib/node-tools/text/helpers/insertLineBreak.test.ts +96 -0
- package/src/lib/node-tools/text/helpers/makeNodeEditable.test.ts +56 -0
- package/src/lib/node-tools/text/helpers/makeNodeNonEditable.test.ts +57 -0
- package/src/lib/node-tools/text/helpers/shouldEnterTextEditMode.test.ts +61 -0
- package/src/lib/node-tools/text/nodeText.test.ts +233 -0
- package/src/lib/post-message/processPostMessage.test.ts +218 -0
- package/src/lib/post-message/sendPostMessage.test.ts +120 -0
- package/src/lib/styles/styles.css +2 -2
- package/src/lib/viewport/createViewport.test.ts +267 -0
- package/src/lib/viewport/createViewport.ts +7 -4
- package/src/lib/viewport/events/setupEventListener.test.ts +103 -0
- package/src/lib/viewport/label/getViewportLabelOverlay.test.ts +77 -0
- package/src/lib/viewport/label/{getViewportLabelsOverlay.ts → getViewportLabelOverlay.ts} +2 -1
- package/src/lib/viewport/label/helpers/getLabelPosition.test.ts +51 -0
- package/src/lib/viewport/label/helpers/getTransformValues.test.ts +59 -0
- package/src/lib/viewport/label/helpers/getZoomValue.test.ts +53 -0
- package/src/lib/viewport/label/helpers/selectFirstViewportNode.test.ts +105 -0
- package/src/lib/viewport/label/helpers/selectFirstViewportNode.ts +8 -0
- package/src/lib/viewport/label/index.ts +5 -3
- package/src/lib/viewport/label/isViewportDragging.test.ts +35 -0
- package/src/lib/viewport/label/isViewportDragging.ts +9 -0
- package/src/lib/viewport/label/refreshViewportLabel.test.ts +105 -0
- package/src/lib/viewport/label/refreshViewportLabel.ts +50 -0
- package/src/lib/viewport/label/refreshViewportLabels.test.ts +107 -0
- package/src/lib/viewport/label/refreshViewportLabels.ts +17 -50
- package/src/lib/viewport/label/removeViewportLabel.test.ts +67 -0
- package/src/lib/viewport/label/removeViewportLabel.ts +20 -0
- package/src/lib/viewport/label/setupViewportDrag.test.ts +249 -0
- package/src/lib/viewport/label/{setupViewportLabelDrag.ts → setupViewportDrag.ts} +14 -14
- package/src/lib/viewport/resize/createResizeHandle.test.ts +37 -0
- package/src/lib/viewport/resize/createResizePresets.test.ts +75 -0
- package/src/lib/viewport/resize/updateActivePreset.test.ts +92 -0
- package/src/lib/viewport/width/calcConstrainedWidth.test.ts +47 -0
- package/src/lib/viewport/width/calcWidth.test.ts +68 -0
- package/src/lib/viewport/width/updateWidth.test.ts +78 -0
- package/src/lib/window/bindToWindow.test.ts +166 -0
- package/dist/lib/viewport/label/getViewportLabelsOverlay.d.ts +0 -1
- package/dist/lib/viewport/label/isViewportLabelDragging.d.ts +0 -2
- package/dist/lib/viewport/label/setupViewportLabelDrag.d.ts +0 -1
- package/src/lib/viewport/label/isViewportLabelDragging.ts +0 -9
|
@@ -1,7 +1,7 @@
|
|
|
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.4
|
|
5
5
|
*/
|
|
6
6
|
(function (global, factory) {
|
|
7
7
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
@@ -20,16 +20,6 @@
|
|
|
20
20
|
};
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
-
function getScreenBounds(element) {
|
|
24
|
-
const rect = element.getBoundingClientRect();
|
|
25
|
-
return {
|
|
26
|
-
top: rect.top,
|
|
27
|
-
left: rect.left,
|
|
28
|
-
width: rect.width,
|
|
29
|
-
height: rect.height,
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
|
|
33
23
|
const getCanvasContainer = () => {
|
|
34
24
|
return document.querySelector(".canvas-container");
|
|
35
25
|
};
|
|
@@ -38,7 +28,7 @@
|
|
|
38
28
|
return getCanvasContainer() || document.body;
|
|
39
29
|
};
|
|
40
30
|
|
|
41
|
-
const
|
|
31
|
+
const getViewportLabelOverlay = () => {
|
|
42
32
|
const container = getCanvasContainerOrBody();
|
|
43
33
|
// Check if overlay already exists
|
|
44
34
|
let overlay = container.querySelector(".viewport-labels-overlay");
|
|
@@ -64,11 +54,21 @@
|
|
|
64
54
|
|
|
65
55
|
// Global flag to prevent refreshViewportLabels during drag
|
|
66
56
|
let globalIsDragging = false;
|
|
67
|
-
const
|
|
68
|
-
const
|
|
57
|
+
const isViewportDragging = () => globalIsDragging;
|
|
58
|
+
const setViewportDragging = (isDragging) => {
|
|
69
59
|
globalIsDragging = isDragging;
|
|
70
60
|
};
|
|
71
61
|
|
|
62
|
+
function getScreenBounds(element) {
|
|
63
|
+
const rect = element.getBoundingClientRect();
|
|
64
|
+
return {
|
|
65
|
+
top: rect.top,
|
|
66
|
+
left: rect.left,
|
|
67
|
+
width: rect.width,
|
|
68
|
+
height: rect.height,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
72
|
/**
|
|
73
73
|
* Creates a reusable drag handler for mouse drag operations
|
|
74
74
|
* @param element - Element that triggers the drag (mousedown listener attached here)
|
|
@@ -202,12 +202,18 @@
|
|
|
202
202
|
if (firstChild) {
|
|
203
203
|
const nodeTools = getNodeTools();
|
|
204
204
|
if (nodeTools?.selectNode) {
|
|
205
|
+
const wasAlreadySelected = nodeTools.getSelectedNode() === firstChild;
|
|
205
206
|
nodeTools.selectNode(firstChild);
|
|
207
|
+
// Always emit postMessage when selecting via viewport label click,
|
|
208
|
+
// even if the node was already selected (to match behavior of direct node clicks)
|
|
209
|
+
if (wasAlreadySelected) {
|
|
210
|
+
sendPostMessage("selectedNodeChanged", firstChild.getAttribute("data-node-id") ?? null);
|
|
211
|
+
}
|
|
206
212
|
}
|
|
207
213
|
}
|
|
208
214
|
};
|
|
209
215
|
|
|
210
|
-
const
|
|
216
|
+
const setupViewportDrag = (labelElement, viewportElement, viewportName) => {
|
|
211
217
|
// Get the parent group element that contains the label
|
|
212
218
|
const labelGroup = labelElement.parentElement;
|
|
213
219
|
// Track initial positions for calculations
|
|
@@ -215,7 +221,7 @@
|
|
|
215
221
|
let initialLabelPosition = { x: 0, y: 0 };
|
|
216
222
|
return createDragHandler(labelElement, {
|
|
217
223
|
onStart: () => {
|
|
218
|
-
|
|
224
|
+
setViewportDragging(true);
|
|
219
225
|
initialTransform = getTransformValues(viewportElement);
|
|
220
226
|
initialLabelPosition = getLabelPosition(labelGroup);
|
|
221
227
|
selectFirstViewportNode(viewportElement);
|
|
@@ -236,66 +242,51 @@
|
|
|
236
242
|
viewportElement.style.transform = `translate3d(${newX}px, ${newY}px, 0)`;
|
|
237
243
|
},
|
|
238
244
|
onStop: (_event, { hasDragged }) => {
|
|
239
|
-
|
|
245
|
+
setViewportDragging(false);
|
|
246
|
+
const finalTransform = getTransformValues(viewportElement);
|
|
240
247
|
// If it was a drag, handle drag completion
|
|
241
248
|
if (hasDragged) {
|
|
242
|
-
const finalTransform = getTransformValues(viewportElement);
|
|
243
249
|
// Trigger refresh after drag completes to update highlight frame and labels
|
|
244
250
|
const nodeTools = getNodeTools();
|
|
245
251
|
if (nodeTools?.refreshHighlightFrame) {
|
|
246
252
|
nodeTools.refreshHighlightFrame();
|
|
247
253
|
}
|
|
248
|
-
// Notify parent about the new position
|
|
249
|
-
sendPostMessage("viewport-position-changed", {
|
|
250
|
-
viewportName,
|
|
251
|
-
x: finalTransform.x,
|
|
252
|
-
y: finalTransform.y,
|
|
253
|
-
});
|
|
254
254
|
}
|
|
255
|
+
// Always notify parent about the new position on drag stop
|
|
256
|
+
sendPostMessage("viewport-position-changed", {
|
|
257
|
+
viewportName,
|
|
258
|
+
x: finalTransform.x,
|
|
259
|
+
y: finalTransform.y,
|
|
260
|
+
});
|
|
255
261
|
},
|
|
256
262
|
onCancel: () => {
|
|
257
|
-
|
|
263
|
+
setViewportDragging(false);
|
|
258
264
|
},
|
|
259
265
|
onPreventClick: () => { },
|
|
260
266
|
});
|
|
261
267
|
};
|
|
262
268
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
269
|
+
/**
|
|
270
|
+
* Refreshes (updates) a viewport label for a single viewport element.
|
|
271
|
+
* Creates the label if it doesn't exist, or updates its position if it does.
|
|
272
|
+
* Similar to refreshHighlightFrame - updates existing elements rather than recreating.
|
|
273
|
+
*
|
|
274
|
+
* @param viewportElement - The viewport element to refresh the label for
|
|
275
|
+
*/
|
|
276
|
+
const refreshViewportLabel = (viewportElement) => {
|
|
277
|
+
const viewportName = viewportElement.getAttribute("data-viewport-name");
|
|
278
|
+
if (!viewportName) {
|
|
268
279
|
return;
|
|
269
280
|
}
|
|
270
|
-
const overlay =
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
overlay.
|
|
274
|
-
|
|
275
|
-
// Find all viewports with names
|
|
276
|
-
const viewports = document.querySelectorAll(".viewport[data-viewport-name]");
|
|
277
|
-
// Clean up existing drag listeners
|
|
278
|
-
dragCleanupFunctions.forEach((cleanup) => {
|
|
279
|
-
cleanup();
|
|
280
|
-
});
|
|
281
|
-
dragCleanupFunctions.clear();
|
|
282
|
-
// Remove existing label groups
|
|
283
|
-
const existingGroups = overlay.querySelectorAll(".viewport-label-group");
|
|
284
|
-
existingGroups.forEach((group) => {
|
|
285
|
-
group.remove();
|
|
286
|
-
});
|
|
287
|
-
// Create/update labels for each viewport
|
|
288
|
-
viewports.forEach((viewport) => {
|
|
289
|
-
const viewportElement = viewport;
|
|
290
|
-
const viewportName = viewportElement.getAttribute("data-viewport-name");
|
|
291
|
-
if (!viewportName)
|
|
292
|
-
return;
|
|
293
|
-
const bounds = getScreenBounds(viewportElement);
|
|
281
|
+
const overlay = getViewportLabelOverlay();
|
|
282
|
+
const bounds = getScreenBounds(viewportElement);
|
|
283
|
+
// Get existing label group or create if it doesn't exist
|
|
284
|
+
let group = overlay.querySelector(`[data-viewport-name="${viewportName}"]`);
|
|
285
|
+
if (!group) {
|
|
294
286
|
// Create group for this viewport label
|
|
295
|
-
|
|
287
|
+
group = document.createElementNS("http://www.w3.org/2000/svg", "g");
|
|
296
288
|
group.classList.add("viewport-label-group");
|
|
297
289
|
group.setAttribute("data-viewport-name", viewportName);
|
|
298
|
-
group.setAttribute("transform", `translate(${bounds.left}, ${bounds.top})`);
|
|
299
290
|
// Create text element
|
|
300
291
|
const text = document.createElementNS("http://www.w3.org/2000/svg", "text");
|
|
301
292
|
text.classList.add("viewport-label-text");
|
|
@@ -306,9 +297,38 @@
|
|
|
306
297
|
text.textContent = viewportName;
|
|
307
298
|
group.appendChild(text);
|
|
308
299
|
overlay.appendChild(group);
|
|
309
|
-
// Setup drag functionality
|
|
310
|
-
|
|
311
|
-
|
|
300
|
+
// Setup drag functionality only when creating new label
|
|
301
|
+
setupViewportDrag(text, viewportElement, viewportName);
|
|
302
|
+
}
|
|
303
|
+
// Update label position (this is the refresh part - updates existing label)
|
|
304
|
+
group.setAttribute("transform", `translate(${bounds.left}, ${bounds.top})`);
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
const refreshViewportLabels = () => {
|
|
308
|
+
// Skip refresh if a viewport label is being dragged
|
|
309
|
+
if (isViewportDragging()) {
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
const overlay = getViewportLabelOverlay();
|
|
313
|
+
// Update SVG dimensions to match current viewport (handles window resize and ensures coordinate system is correct)
|
|
314
|
+
const { width: viewportWidth, height: viewportHeight } = getViewportDimensions();
|
|
315
|
+
overlay.setAttribute("width", viewportWidth.toString());
|
|
316
|
+
overlay.setAttribute("height", viewportHeight.toString());
|
|
317
|
+
// Find all viewports with names and refresh each label
|
|
318
|
+
const viewports = document.querySelectorAll(".viewport[data-viewport-name]");
|
|
319
|
+
viewports.forEach((viewport) => {
|
|
320
|
+
refreshViewportLabel(viewport);
|
|
321
|
+
});
|
|
322
|
+
// Remove labels for viewports that no longer exist
|
|
323
|
+
const existingGroups = overlay.querySelectorAll(".viewport-label-group");
|
|
324
|
+
existingGroups.forEach((group) => {
|
|
325
|
+
const viewportName = group.getAttribute("data-viewport-name");
|
|
326
|
+
if (viewportName) {
|
|
327
|
+
const viewportExists = Array.from(viewports).some((viewport) => viewport.getAttribute("data-viewport-name") === viewportName);
|
|
328
|
+
if (!viewportExists) {
|
|
329
|
+
group.remove();
|
|
330
|
+
}
|
|
331
|
+
}
|
|
312
332
|
});
|
|
313
333
|
};
|
|
314
334
|
|
|
@@ -1238,6 +1258,22 @@
|
|
|
1238
1258
|
},
|
|
1239
1259
|
];
|
|
1240
1260
|
|
|
1261
|
+
/**
|
|
1262
|
+
* Removes a viewport label for a single viewport element.
|
|
1263
|
+
* @param viewportElement - The viewport element to remove the label for
|
|
1264
|
+
*/
|
|
1265
|
+
const removeViewportLabel = (viewportElement) => {
|
|
1266
|
+
const viewportName = viewportElement.getAttribute("data-viewport-name");
|
|
1267
|
+
if (!viewportName) {
|
|
1268
|
+
return;
|
|
1269
|
+
}
|
|
1270
|
+
const overlay = getViewportLabelOverlay();
|
|
1271
|
+
const labelGroup = overlay.querySelector(`[data-viewport-name="${viewportName}"]`);
|
|
1272
|
+
if (labelGroup) {
|
|
1273
|
+
labelGroup.remove();
|
|
1274
|
+
}
|
|
1275
|
+
};
|
|
1276
|
+
|
|
1241
1277
|
const createResizeHandle = (container) => {
|
|
1242
1278
|
const handle = document.createElement("div");
|
|
1243
1279
|
handle.className = "resize-handle";
|
|
@@ -1341,17 +1377,19 @@
|
|
|
1341
1377
|
onPreventClick: () => { },
|
|
1342
1378
|
});
|
|
1343
1379
|
document.addEventListener("mouseleave", handleMouseLeave);
|
|
1344
|
-
|
|
1380
|
+
// Create/refresh the label for this viewport
|
|
1381
|
+
refreshViewportLabel(container);
|
|
1345
1382
|
const cleanup = () => {
|
|
1346
1383
|
removeDragListeners();
|
|
1347
1384
|
document.removeEventListener("mouseleave", handleMouseLeave);
|
|
1348
1385
|
resizeHandle.remove();
|
|
1349
|
-
|
|
1386
|
+
// Remove the label for this viewport
|
|
1387
|
+
removeViewportLabel(container);
|
|
1350
1388
|
};
|
|
1351
1389
|
return {
|
|
1352
1390
|
setWidth: (width) => {
|
|
1353
1391
|
updateWidth(container, width);
|
|
1354
|
-
|
|
1392
|
+
refreshViewportLabel(container);
|
|
1355
1393
|
const nodeTools = getNodeTools();
|
|
1356
1394
|
const selectedNode = nodeTools?.getSelectedNode?.();
|
|
1357
1395
|
const nodeProvider = getNodeProvider();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).MarkupCanvas={})}(this,function(t){"use strict";const e=()=>window.nodeTools,n=()=>({width:document.documentElement.clientWidth||window.innerWidth,height:document.documentElement.clientHeight||window.innerHeight});function o(t){const e=t.getBoundingClientRect();return{top:e.top,left:e.left,width:e.width,height:e.height}}const r=()=>document.querySelector(".canvas-container"),s=()=>r()||document.body;let i=!1;const a=t=>{i=t};function l(t,e,n={}){const{preventDefault:o=!0,stopPropagation:r=!0}=n,s={isDragging:!1,hasDragged:!1,startX:0,startY:0},i=t=>{o&&t.preventDefault(),r&&t.stopPropagation(),s.isDragging=!0,s.hasDragged=!1,s.startX=t.clientX,s.startY=t.clientY,e.onStart?.(t,s)},a=t=>{if(!s.isDragging)return;const n=t.clientX-s.startX,o=t.clientY-s.startY;s.hasDragged=!0,e.onDrag(t,{...s,deltaX:n,deltaY:o})},l=t=>{s.isDragging&&(o&&t.preventDefault(),r&&t.stopPropagation(),s.isDragging=!1,e.onStop?.(t,s))},d=()=>{s.isDragging&&(s.isDragging=!1,e.onCancel?.(s))},c=t=>{o&&t.preventDefault(),r&&t.stopPropagation(),e.onPreventClick?.(t,s),s.hasDragged&&(s.hasDragged=!1)};return t.addEventListener("mousedown",i),e.onPreventClick&&t.addEventListener("click",c),document.addEventListener("mousemove",a),document.addEventListener("mouseup",l),window.addEventListener("blur",d),()=>{t.removeEventListener("mousedown",i),e.onPreventClick&&t.removeEventListener("click",c),document.removeEventListener("mousemove",a),document.removeEventListener("mouseup",l),window.removeEventListener("blur",d)}}function d(t,e){window.parent.postMessage({source:"node-edit-utils",action:t,data:e,timestamp:Date.now()},"*")}const c=t=>(t=>{const e=t?.match(/translate\((-?\d+(?:\.\d+)?),\s*(-?\d+(?:\.\d+)?)\)/);return e?{x:parseFloat(e[1]),y:parseFloat(e[2])}:{x:0,y:0}})(t.getAttribute("transform")),u=t=>(t=>{const e=t.match(/translate3d\((-?\d+(?:\.\d+)?)px,\s*(-?\d+(?:\.\d+)?)px,\s*(-?\d+(?:\.\d+)?)px\)/);return e?{x:parseFloat(e[1]),y:parseFloat(e[2])}:{x:0,y:0}})(t.style.transform),g=(t,n,o)=>{const r=t.parentElement;let s={x:0,y:0},i={x:0,y:0};return l(t,{onStart:()=>{a(!0),s=u(n),i=c(r),(t=>{const n=Array.from(t.children).find(t=>!t.classList.contains("resize-handle"));if(n){const t=e();t?.selectNode&&t.selectNode(n)}})(n)},onDrag:(t,{deltaX:e,deltaY:o})=>{const a=(()=>{const t=getComputedStyle(document.body).getPropertyValue("--zoom").trim();return t?parseFloat(t):1})(),l=e/a,d=o/a,c=s.x+l,u=s.y+d,g=i.x+e,m=i.y+o;r.setAttribute("transform",`translate(${g}, ${m})`),n.style.transform=`translate3d(${c}px, ${u}px, 0)`},onStop:(t,{hasDragged:r})=>{if(a(!1),r){const t=u(n),r=e();r?.refreshHighlightFrame&&r.refreshHighlightFrame(),d("viewport-position-changed",{viewportName:o,x:t.x,y:t.y})}},onCancel:()=>{a(!1)},onPreventClick:()=>{}})},m=new Map,h=()=>{if(i)return;const t=(()=>{const t=s();let e=t.querySelector(".viewport-labels-overlay");if(!e){e=document.createElementNS("http://www.w3.org/2000/svg","svg"),e.classList.add("viewport-labels-overlay"),e.style.position="absolute",e.style.top="0",e.style.left="0",e.style.width="100vw",e.style.height="100vh",e.style.pointerEvents="none",e.style.zIndex="500";const{width:o,height:r}=n();e.setAttribute("width",o.toString()),e.setAttribute("height",r.toString()),t.appendChild(e)}return e})(),{width:e,height:r}=n();t.setAttribute("width",e.toString()),t.setAttribute("height",r.toString());const a=document.querySelectorAll(".viewport[data-viewport-name]");m.forEach(t=>{t()}),m.clear();t.querySelectorAll(".viewport-label-group").forEach(t=>{t.remove()}),a.forEach(e=>{const n=e,r=n.getAttribute("data-viewport-name");if(!r)return;const s=o(n),i=document.createElementNS("http://www.w3.org/2000/svg","g");i.classList.add("viewport-label-group"),i.setAttribute("data-viewport-name",r),i.setAttribute("transform",`translate(${s.left}, ${s.top})`);const a=document.createElementNS("http://www.w3.org/2000/svg","text");a.classList.add("viewport-label-text"),a.setAttribute("x","0"),a.setAttribute("y","-8"),a.setAttribute("vector-effect","non-scaling-stroke"),a.setAttribute("pointer-events","auto"),a.textContent=r,i.appendChild(a),t.appendChild(i);const l=g(a,n,r);m.set(r,l)})},p=(t,e="canvas")=>{const n=window[e];return t.reduce((t,e)=>t?.[e],n)};const v=()=>{const t=s(),e=t.querySelector(".highlight-frame-overlay");e&&e.remove();const n=t.querySelector(".highlight-frame-tools-wrapper");n&&n.remove()},f=(t,e,n)=>{t&&e&&n.enableEditMode(t,e)},b=["path","rect","circle","ellipse","polygon","line","polyline","text","text-noci"];let y=[],w=0,E=null;const A=(t,e,n)=>{let o=null;const r=t.clientX,s=t.clientY,i=t.metaKey||t.ctrlKey,a=((t,e)=>{const n=document.elementsFromPoint(t,e);return Array.from(n).reduce((t,e)=>t.found?t:"node-provider"===e.getAttribute("data-role")?(t.found=!0,t):(t.elements.push(e),t),{elements:[],found:!1}).elements})(r,s).filter(t=>!b.includes(t.tagName.toLowerCase())&&!t.classList.contains("select-none")&&!t.classList.contains("content-layer")&&!t.classList.contains("resize-handle")&&!t.classList.contains("resize-presets")&&!(t=>{let e=t.parentElement;for(;e;){if("true"===e.getAttribute("data-instance"))return!0;if("node-provider"===e.getAttribute("data-role"))break;e=e.parentElement}return!1})(t)&&(t=>{let e=t;for(;e;){if(e.classList.contains("viewport"))return!0;if("node-provider"===e.getAttribute("data-role"))break;e=e.parentElement}return!1})(t));if(console.log("candidates",a),0===a.length)return E=null,null;const l=n.getEditableNode();if(l&&a.includes(l))return o=l,E=o,o;if(i)return y=[],o=a[0],E&&E===o&&f(o,e,n),E=o,o;var d,c;c=a,(d=y).length===c.length&&d.every((t,e)=>t===c[e])?w<=a.length-2&&w++:w=0;return o=a[a.length-1-w],y=a,E&&E===o&&f(o,e,n),E=o,o},S=(t,e,n,o)=>{const r=t=>{((t,e)=>{if("application"===t.data.source&&"selectedNodeChanged"===t.data.action){const o=t.data.data,r=document.querySelector(`[data-node-id="${o}"]`);if(n=r,n?.classList.contains("select-none"))return void e?.(null);r&&e?.(r)}var n})(t,e)},s=n=>{((t,e,n,o)=>{if(t.preventDefault(),t.stopPropagation(),e&&!e.contains(t.target))return v(),void o(null);o(A(t,e,n))})(n,t,o,e)},i=t=>{"Escape"===t.key&&(t.preventDefault(),t.stopPropagation(),n?.())};return window.addEventListener("message",r),document.addEventListener("click",s),document.addEventListener("keydown",i),()=>{window.removeEventListener("message",r),document.removeEventListener("click",s),document.removeEventListener("keydown",i)}},x=(t,e,n)=>{t&&(n?t.classList.add(e):t.classList.remove(e))},L=t=>"true"===t.getAttribute("data-instance"),C=(t,e,n,o,r=!1,s=!1)=>{const i=document.createElementNS("http://www.w3.org/2000/svg","rect");return i.setAttribute("x",(e-3).toString()),i.setAttribute("y",(n-3).toString()),i.setAttribute("width",6..toString()),i.setAttribute("height",6..toString()),i.setAttribute("vector-effect","non-scaling-stroke"),i.classList.add("highlight-frame-handle",o),r?i.setAttribute("stroke",getComputedStyle(document.documentElement).getPropertyValue("--component-color").trim()||"oklch(65.6% 0.241 354.308)"):s&&i.setAttribute("stroke",getComputedStyle(document.documentElement).getPropertyValue("--text-edit-color").trim()||"oklch(62.3% 0.214 259.815)"),t.appendChild(i),i},k=(t,e=!1,r=!1)=>{const{top:i,left:a,width:l,height:d}=o(t),c=Math.max(l,3),u=document.createElementNS("http://www.w3.org/2000/svg","svg");u.classList.add("highlight-frame-overlay"),e&&u.classList.add("is-instance"),r&&u.classList.add("is-text-edit"),u.setAttribute("data-node-id",t.getAttribute("data-node-id")||""),u.style.position="absolute",u.style.top="0",u.style.left="0",u.style.width="100vw",u.style.height="100vh",u.style.pointerEvents="none",u.style.zIndex="500";const{width:g,height:m}=n();u.setAttribute("width",g.toString()),u.setAttribute("height",m.toString());const h=document.createElementNS("http://www.w3.org/2000/svg","g");h.classList.add("highlight-frame-group"),h.setAttribute("transform",`translate(${a}, ${i})`);const p=document.createElementNS("http://www.w3.org/2000/svg","rect");p.setAttribute("x","0"),p.setAttribute("y","0"),p.setAttribute("width",c.toString()),p.setAttribute("height",d.toString()),p.setAttribute("vector-effect","non-scaling-stroke"),p.classList.add("highlight-frame-rect"),e?p.setAttribute("stroke",getComputedStyle(document.documentElement).getPropertyValue("--component-color").trim()||"oklch(65.6% 0.241 354.308)"):r&&p.setAttribute("stroke",getComputedStyle(document.documentElement).getPropertyValue("--text-edit-color").trim()||"oklch(62.3% 0.214 259.815)"),h.appendChild(p),((t,e,n,o=!1,r=!1)=>{C(t,0,0,"handle-top-left",o,r),C(t,e,0,"handle-top-right",o,r),C(t,e,n,"handle-bottom-right",o,r),C(t,0,n,"handle-bottom-left",o,r)})(h,c,d,e,r),u.appendChild(h);return s().appendChild(u),u},N={div:"Container",h1:"Heading 1",h2:"Heading 2",h3:"Heading 3",h4:"Heading 4",h5:"Heading 5",h6:"Heading 6",p:"Text",li:"List Item",ul:"Unordered List",ol:"Ordered List",img:"Image",a:"Link"},D=(t,e,n=!1,o=!1)=>{const r=document.createElement("div");r.className="node-tools",x(r,"is-instance",n),x(r,"is-text-edit",o),e.appendChild(r),((t,e)=>{const n=document.createElement("div");n.className="tag-label";const o=t.getAttribute("data-instance-name"),r=t.tagName.toLowerCase(),s=o||N[r]||r;var i;n.textContent=(i=s)?i.charAt(0).toUpperCase()+i.slice(1):i,e.appendChild(n)})(t,r)};function P(){return s().querySelector(".highlight-frame-overlay")}const q=t=>{if(!t)return;const e=P(),n=s(),r=n.querySelector(".highlight-frame-tools-wrapper");e&&e.remove(),r&&r.remove();const i=L(t),a="true"===t.contentEditable,l=k(t,i,a);"true"===t.contentEditable&&l.classList.add("is-editable");const{left:d,top:c,height:u}=o(t),g=c+u,m=document.createElement("div");m.classList.add("highlight-frame-tools-wrapper"),x(m,"is-instance",i),x(m,"is-text-edit",a),m.style.position="absolute",m.style.transform=`translate(${d}px, ${g}px)`,m.style.transformOrigin="left center",m.style.pointerEvents="none",m.style.zIndex="500",D(t,m,i,a),n.appendChild(m)},F=()=>getComputedStyle(document.documentElement).getPropertyValue("--component-color").trim()||"oklch(65.6% 0.241 354.308)",z=()=>getComputedStyle(document.documentElement).getPropertyValue("--text-edit-color").trim()||"oklch(62.3% 0.214 259.815)",M=(t,e,r="canvas")=>{const i=P();if(!i)return;const a=L(t),l="true"===t.contentEditable,{width:d,height:c}=n();i.setAttribute("width",d.toString()),i.setAttribute("height",c.toString()),x(i,"is-instance",a),x(i,"is-text-edit",l);const u=i.querySelector(".highlight-frame-group");if(!u)return;const g=u.querySelector("rect");if(!g)return;a?g.setAttribute("stroke",F()):l?g.setAttribute("stroke",z()):g.removeAttribute("stroke");const m=s().querySelector(".highlight-frame-tools-wrapper"),h=m?.querySelector(".node-tools"),v=p(["zoom","current"],r)??1,f=o(t),{top:b,left:y,width:w,height:E}=f,A=Math.max(w,3),S=b+E;x(m,"is-instance",a),x(m,"is-text-edit",l),x(h,"is-instance",a),x(h,"is-text-edit",l),u.setAttribute("transform",`translate(${y}, ${b})`),g.setAttribute("width",A.toString()),g.setAttribute("height",E.toString());const C=u.querySelector(".handle-top-left"),k=u.querySelector(".handle-top-right"),N=u.querySelector(".handle-bottom-right"),D=u.querySelector(".handle-bottom-left");[C,k,N,D].forEach(t=>{t&&(a?t.setAttribute("stroke",F()):l?t.setAttribute("stroke",z()):t.removeAttribute("stroke"))}),C&&(C.setAttribute("x",(-3).toString()),C.setAttribute("y",(-3).toString())),k&&(k.setAttribute("x",(A-3).toString()),k.setAttribute("y",(-3).toString())),N&&(N.setAttribute("x",(A-3).toString()),N.setAttribute("y",(E-3).toString())),D&&(D.setAttribute("x",(-3).toString()),D.setAttribute("y",(E-3).toString())),m&&(m.style.transform=`translate(${y}px, ${S}px)`),v<=10?e.style.setProperty("--tool-opacity","1"):e.style.setProperty("--tool-opacity","0")},$=t=>{const e=P();if(!e)return;const n=t.classList.contains("hidden")||t.classList.contains("select-none")?"none":"";e.style.display=n;const o=s().querySelector(".highlight-frame-tools-wrapper");o&&(o.style.display=n)},H=t=>{const e=t=>{"Enter"===t.key&&(t.preventDefault(),t.stopPropagation(),(()=>{const t=window.getSelection();if(t&&t.rangeCount>0){const e=t.getRangeAt(0);e.deleteContents();const n=document.createElement("br");e.insertNode(n),e.setStartAfter(n),e.setEndAfter(n),t.removeAllRanges(),t.addRange(e)}})())};return t.addEventListener("keydown",e),()=>{t.removeEventListener("keydown",e)}},V=(t,e,n=!1)=>{if(!e.some(t=>"characterData"===t.type||"childList"===t.type&&(t.addedNodes.length>0||t.removedNodes.length>0))&&!n)return;const o=t.textContent??"",r=t.getAttribute("data-node-id");console.log("textContentChanged",o,n),d("textContentChanged",{nodeId:r,textContent:o,final:n})},T=(t,e,n="canvas")=>{let o=[],r=null,s=null;const i=()=>{null===r&&(r=requestAnimationFrame(()=>{s=requestAnimationFrame(()=>{(()=>{if(o.length>0){const e=[...o];o=[],V(t,e,!1)}})(),r=null,s=null})}))},a=((t,e)=>{const n=new MutationObserver(t=>{e(t)});return n.observe(t,{subtree:!0,childList:!0,characterData:!0}),n})(t,r=>{o.push(...r),i(),console.log("refreshHighlightFrame in mutationObserver"),M(t,e,n)});return()=>{a.disconnect(),null!==r&&(cancelAnimationFrame(r),r=null),null!==s&&(cancelAnimationFrame(s),s=null),o=[]}},O=(t="canvas")=>{let e=null,n=!1,o=null;const r=()=>{if(n||!e)return;n=!0;const r=e;var s;V(r,[],!0),(s=r).contentEditable="false",s.classList.remove("is-editable"),s.style.outline="none",((t="canvas")=>{const e=p(["keyboard","disableTextEditMode"],t);e?.()})(t),o?.(),e=null,n=!1};return{enableEditMode:(n,s)=>{if(e===n)return;e&&e!==n&&r();const i=(t=>Array.from(t.childNodes).some(t=>t.nodeType===Node.TEXT_NODE&&t.textContent?.trim()))(n);i&&(e=n,(t=>{t.contentEditable="true",t.classList.add("is-editable"),t.style.outline="none"})(n),((t="canvas")=>{const e=p(["keyboard","enableTextEditMode"],t);e?.()})(t),o=((t,e,n,o="canvas")=>{if(!e)return()=>{};t.addEventListener("blur",n);const r=H(t),s=T(t,e,o);return()=>{t.removeEventListener("blur",n),r(),s?.()}})(n,s,r,t))},blurEditMode:r,getEditableNode:()=>e,isEditing:()=>null!==e}},X=4,Y=2560,I=[{name:"Mobile",rawValue:390,value:"320px"},{name:"Tablet Portrait",rawValue:768,value:"768px"},{name:"Tablet Landscape",rawValue:1024,value:"1024px"},{name:"Notebook",rawValue:1280,value:"1280px"},{name:"Desktop",rawValue:1680,value:"1680px"}],R=(t,e,n)=>{const o=parseFloat(document.body.dataset.zoom||"1"),r=((t,e)=>{const n=t+Math.round(e);return Math.max(X,Math.min(Y,n))})(n,(t.clientX-e)/o);return r},W=(t,e)=>{t.style.setProperty("--container-width",`${e}px`),((t,e)=>{t.querySelectorAll(".resize-preset-button").forEach((t,n)=>{n<I.length&&(I[n].rawValue===e?t.classList.add("is-active"):t.classList.remove("is-active"))})})(t,e)};t.createCanvasObserver=function(t="canvas"){const n=document.querySelector(".transform-layer");if(!n)return{disconnect:()=>{}};const o=new MutationObserver(()=>{((t="canvas")=>{const e=p(["zoom","current"],t)??1;document.body.style.setProperty("--zoom",e.toFixed(5)),document.body.style.setProperty("--stroke-width",(2/e).toFixed(3)),document.body.dataset.zoom=e.toFixed(5),document.body.dataset.strokeWidth=(2/e).toFixed(3)})(t);const n=e();n?.refreshHighlightFrame&&n.refreshHighlightFrame(),h()});o.observe(n,{attributes:!0,attributeOldValue:!0,subtree:!0,childList:!0});const r=()=>{h()};return window.addEventListener("resize",r),h(),{disconnect:function(){o.disconnect(),window.removeEventListener("resize",r)}}},t.createNodeTools=(t,e="canvas")=>{const n=t;let o=null,r=null,s=null,i=null;const a=O(e),l=t=>{if(i!==t){if(a.isEditing()){const e=a.getEditableNode();e&&e!==t&&a.blurEditMode()}if(o?.disconnect(),r?.disconnect(),s?.disconnect(),t&&n){const a=()=>{if(!document.contains(t))return v(),i=null,o?.disconnect(),r?.disconnect(),s?.disconnect(),void d("selectedNodeChanged",null)};r=new MutationObserver(()=>{a(),document.contains(t)&&(console.log("refreshHighlightFrame in mutationObserver 2"),M(t,n,e),$(t))}),r.observe(t,{attributes:!0,characterData:!0});const l=t.parentElement;l&&(s=new MutationObserver(e=>{for(const n of e)if("childList"===n.type)for(const e of Array.from(n.removedNodes))if(e===t||e instanceof Node&&e.contains(t))return void a()}),s.observe(l,{childList:!0,subtree:!1})),o=((t,e)=>{const n=new ResizeObserver(t=>{e(t)});return n.observe(t),n})(t,()=>{a(),document.contains(t)&&(M(t,n,e),console.log("refreshHighlightFrame in resizeObserver"),$(t))})}i=t,d("selectedNodeChanged",t?.getAttribute("data-node-id")??null),q(t),t?(q(t),n&&$(t)):v()}},c=S(n,l,()=>{a.isEditing()&&a.blurEditMode(),i&&n&&(v(),i=null,o?.disconnect(),r?.disconnect(),s?.disconnect())},a),u={selectNode:l,getSelectedNode:()=>i,refreshHighlightFrame:()=>{i&&n&&(M(i,n,e),$(i))},clearSelectedNode:()=>{v(),i=null,o?.disconnect(),r?.disconnect(),s?.disconnect()},getEditableNode:()=>a.getEditableNode(),cleanup:()=>{c(),o?.disconnect(),r?.disconnect(),s?.disconnect(),a.blurEditMode(),v(),i=null,d("selectedNodeChanged",null)}};var g,m;return g="nodeTools",m=u,"undefined"!=typeof window&&(window[g]=m),u},t.createViewport=(t,n)=>{const o=r(),s=t.querySelector(".resize-handle");s&&s.remove();const i=(t=>{const e=document.createElement("div");return e.className="resize-handle",t.appendChild(e),e})(t),a=n??400;t.style.setProperty("--container-width",`${a}px`),((t,e,n)=>{const o=document.createElement("div");o.className="resize-presets",I.forEach(t=>{const r=document.createElement("button");r.textContent=t.name,r.className="resize-preset-button",r.addEventListener("click",()=>{n(e,t.rawValue)}),o.appendChild(r)}),t.appendChild(o)})(i,t,W);let d=0,c=0;const u=t=>{t.relatedTarget||t.target!==document&&t.target!==document.documentElement||o&&(o.style.cursor="default")},g=l(i,{onStart:(e,{startX:n})=>{d=n,c=t.offsetWidth},onDrag:e=>{o&&(o.style.cursor="ew-resize");const n=R(e,d,c);W(t,n)},onStop:()=>{o&&(o.style.cursor="default")},onCancel:()=>{o&&(o.style.cursor="default")},onPreventClick:()=>{}});document.addEventListener("mouseleave",u),h();return{setWidth:n=>{W(t,n),h();const o=e(),r=o?.getSelectedNode?.(),s=document.querySelector('[data-role="node-provider"]');r&&s&&M(r,s)},cleanup:()=>{g(),document.removeEventListener("mouseleave",u),i.remove(),h()}}}});
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).MarkupCanvas={})}(this,function(t){"use strict";const e=()=>window.nodeTools,n=()=>({width:document.documentElement.clientWidth||window.innerWidth,height:document.documentElement.clientHeight||window.innerHeight}),o=()=>document.querySelector(".canvas-container"),r=()=>o()||document.body,i=()=>{const t=r();let e=t.querySelector(".viewport-labels-overlay");if(!e){e=document.createElementNS("http://www.w3.org/2000/svg","svg"),e.classList.add("viewport-labels-overlay"),e.style.position="absolute",e.style.top="0",e.style.left="0",e.style.width="100vw",e.style.height="100vh",e.style.pointerEvents="none",e.style.zIndex="500";const{width:o,height:r}=n();e.setAttribute("width",o.toString()),e.setAttribute("height",r.toString()),t.appendChild(e)}return e};let s=!1;const a=t=>{s=t};function l(t){const e=t.getBoundingClientRect();return{top:e.top,left:e.left,width:e.width,height:e.height}}function d(t,e,n={}){const{preventDefault:o=!0,stopPropagation:r=!0}=n,i={isDragging:!1,hasDragged:!1,startX:0,startY:0},s=t=>{o&&t.preventDefault(),r&&t.stopPropagation(),i.isDragging=!0,i.hasDragged=!1,i.startX=t.clientX,i.startY=t.clientY,e.onStart?.(t,i)},a=t=>{if(!i.isDragging)return;const n=t.clientX-i.startX,o=t.clientY-i.startY;i.hasDragged=!0,e.onDrag(t,{...i,deltaX:n,deltaY:o})},l=t=>{i.isDragging&&(o&&t.preventDefault(),r&&t.stopPropagation(),i.isDragging=!1,e.onStop?.(t,i))},d=()=>{i.isDragging&&(i.isDragging=!1,e.onCancel?.(i))},c=t=>{o&&t.preventDefault(),r&&t.stopPropagation(),e.onPreventClick?.(t,i),i.hasDragged&&(i.hasDragged=!1)};return t.addEventListener("mousedown",s),e.onPreventClick&&t.addEventListener("click",c),document.addEventListener("mousemove",a),document.addEventListener("mouseup",l),window.addEventListener("blur",d),()=>{t.removeEventListener("mousedown",s),e.onPreventClick&&t.removeEventListener("click",c),document.removeEventListener("mousemove",a),document.removeEventListener("mouseup",l),window.removeEventListener("blur",d)}}function c(t,e){window.parent.postMessage({source:"node-edit-utils",action:t,data:e,timestamp:Date.now()},"*")}const u=t=>(t=>{const e=t?.match(/translate\((-?\d+(?:\.\d+)?),\s*(-?\d+(?:\.\d+)?)\)/);return e?{x:parseFloat(e[1]),y:parseFloat(e[2])}:{x:0,y:0}})(t.getAttribute("transform")),g=t=>(t=>{const e=t.match(/translate3d\((-?\d+(?:\.\d+)?)px,\s*(-?\d+(?:\.\d+)?)px,\s*(-?\d+(?:\.\d+)?)px\)/);return e?{x:parseFloat(e[1]),y:parseFloat(e[2])}:{x:0,y:0}})(t.style.transform),m=(t,n,o)=>{const r=t.parentElement;let i={x:0,y:0},s={x:0,y:0};return d(t,{onStart:()=>{a(!0),i=g(n),s=u(r),(t=>{const n=Array.from(t.children).find(t=>!t.classList.contains("resize-handle"));if(n){const t=e();if(t?.selectNode){const e=t.getSelectedNode()===n;t.selectNode(n),e&&c("selectedNodeChanged",n.getAttribute("data-node-id")??null)}}})(n)},onDrag:(t,{deltaX:e,deltaY:o})=>{const a=(()=>{const t=getComputedStyle(document.body).getPropertyValue("--zoom").trim();return t?parseFloat(t):1})(),l=e/a,d=o/a,c=i.x+l,u=i.y+d,g=s.x+e,m=s.y+o;r.setAttribute("transform",`translate(${g}, ${m})`),n.style.transform=`translate3d(${c}px, ${u}px, 0)`},onStop:(t,{hasDragged:r})=>{a(!1);const i=g(n);if(r){const t=e();t?.refreshHighlightFrame&&t.refreshHighlightFrame()}c("viewport-position-changed",{viewportName:o,x:i.x,y:i.y})},onCancel:()=>{a(!1)},onPreventClick:()=>{}})},h=t=>{const e=t.getAttribute("data-viewport-name");if(!e)return;const n=i(),o=l(t);let r=n.querySelector(`[data-viewport-name="${e}"]`);if(!r){r=document.createElementNS("http://www.w3.org/2000/svg","g"),r.classList.add("viewport-label-group"),r.setAttribute("data-viewport-name",e);const o=document.createElementNS("http://www.w3.org/2000/svg","text");o.classList.add("viewport-label-text"),o.setAttribute("x","0"),o.setAttribute("y","-8"),o.setAttribute("vector-effect","non-scaling-stroke"),o.setAttribute("pointer-events","auto"),o.textContent=e,r.appendChild(o),n.appendChild(r),m(o,t,e)}r.setAttribute("transform",`translate(${o.left}, ${o.top})`)},p=()=>{if(s)return;const t=i(),{width:e,height:o}=n();t.setAttribute("width",e.toString()),t.setAttribute("height",o.toString());const r=document.querySelectorAll(".viewport[data-viewport-name]");r.forEach(t=>{h(t)});t.querySelectorAll(".viewport-label-group").forEach(t=>{const e=t.getAttribute("data-viewport-name");if(e){Array.from(r).some(t=>t.getAttribute("data-viewport-name")===e)||t.remove()}})},v=(t,e="canvas")=>{const n=window[e];return t.reduce((t,e)=>t?.[e],n)};const f=()=>{const t=r(),e=t.querySelector(".highlight-frame-overlay");e&&e.remove();const n=t.querySelector(".highlight-frame-tools-wrapper");n&&n.remove()},b=(t,e,n)=>{t&&e&&n.enableEditMode(t,e)},y=["path","rect","circle","ellipse","polygon","line","polyline","text","text-noci"];let w=[],E=0,A=null;const S=(t,e,n)=>{let o=null;const r=t.clientX,i=t.clientY,s=t.metaKey||t.ctrlKey,a=((t,e)=>{const n=document.elementsFromPoint(t,e);return Array.from(n).reduce((t,e)=>t.found?t:"node-provider"===e.getAttribute("data-role")?(t.found=!0,t):(t.elements.push(e),t),{elements:[],found:!1}).elements})(r,i).filter(t=>!y.includes(t.tagName.toLowerCase())&&!t.classList.contains("select-none")&&!t.classList.contains("content-layer")&&!t.classList.contains("resize-handle")&&!t.classList.contains("resize-presets")&&!(t=>{let e=t.parentElement;for(;e;){if("true"===e.getAttribute("data-instance"))return!0;if("node-provider"===e.getAttribute("data-role"))break;e=e.parentElement}return!1})(t)&&(t=>{let e=t;for(;e;){if(e.classList.contains("viewport"))return!0;if("node-provider"===e.getAttribute("data-role"))break;e=e.parentElement}return!1})(t));if(console.log("candidates",a),0===a.length)return A=null,null;const l=n.getEditableNode();if(l&&a.includes(l))return o=l,A=o,o;if(s)return w=[],o=a[0],A&&A===o&&b(o,e,n),A=o,o;var d,c;c=a,(d=w).length===c.length&&d.every((t,e)=>t===c[e])?E<=a.length-2&&E++:E=0;return o=a[a.length-1-E],w=a,A&&A===o&&b(o,e,n),A=o,o},x=(t,e,n,o)=>{const r=t=>{((t,e)=>{if("application"===t.data.source&&"selectedNodeChanged"===t.data.action){const o=t.data.data,r=document.querySelector(`[data-node-id="${o}"]`);if(n=r,n?.classList.contains("select-none"))return void e?.(null);r&&e?.(r)}var n})(t,e)},i=n=>{((t,e,n,o)=>{if(t.preventDefault(),t.stopPropagation(),e&&!e.contains(t.target))return f(),void o(null);o(S(t,e,n))})(n,t,o,e)},s=t=>{"Escape"===t.key&&(t.preventDefault(),t.stopPropagation(),n?.())};return window.addEventListener("message",r),document.addEventListener("click",i),document.addEventListener("keydown",s),()=>{window.removeEventListener("message",r),document.removeEventListener("click",i),document.removeEventListener("keydown",s)}},L=(t,e,n)=>{t&&(n?t.classList.add(e):t.classList.remove(e))},C=t=>"true"===t.getAttribute("data-instance"),k=(t,e,n,o,r=!1,i=!1)=>{const s=document.createElementNS("http://www.w3.org/2000/svg","rect");return s.setAttribute("x",(e-3).toString()),s.setAttribute("y",(n-3).toString()),s.setAttribute("width",6..toString()),s.setAttribute("height",6..toString()),s.setAttribute("vector-effect","non-scaling-stroke"),s.classList.add("highlight-frame-handle",o),r?s.setAttribute("stroke",getComputedStyle(document.documentElement).getPropertyValue("--component-color").trim()||"oklch(65.6% 0.241 354.308)"):i&&s.setAttribute("stroke",getComputedStyle(document.documentElement).getPropertyValue("--text-edit-color").trim()||"oklch(62.3% 0.214 259.815)"),t.appendChild(s),s},N=(t,e=!1,o=!1)=>{const{top:i,left:s,width:a,height:d}=l(t),c=Math.max(a,3),u=document.createElementNS("http://www.w3.org/2000/svg","svg");u.classList.add("highlight-frame-overlay"),e&&u.classList.add("is-instance"),o&&u.classList.add("is-text-edit"),u.setAttribute("data-node-id",t.getAttribute("data-node-id")||""),u.style.position="absolute",u.style.top="0",u.style.left="0",u.style.width="100vw",u.style.height="100vh",u.style.pointerEvents="none",u.style.zIndex="500";const{width:g,height:m}=n();u.setAttribute("width",g.toString()),u.setAttribute("height",m.toString());const h=document.createElementNS("http://www.w3.org/2000/svg","g");h.classList.add("highlight-frame-group"),h.setAttribute("transform",`translate(${s}, ${i})`);const p=document.createElementNS("http://www.w3.org/2000/svg","rect");p.setAttribute("x","0"),p.setAttribute("y","0"),p.setAttribute("width",c.toString()),p.setAttribute("height",d.toString()),p.setAttribute("vector-effect","non-scaling-stroke"),p.classList.add("highlight-frame-rect"),e?p.setAttribute("stroke",getComputedStyle(document.documentElement).getPropertyValue("--component-color").trim()||"oklch(65.6% 0.241 354.308)"):o&&p.setAttribute("stroke",getComputedStyle(document.documentElement).getPropertyValue("--text-edit-color").trim()||"oklch(62.3% 0.214 259.815)"),h.appendChild(p),((t,e,n,o=!1,r=!1)=>{k(t,0,0,"handle-top-left",o,r),k(t,e,0,"handle-top-right",o,r),k(t,e,n,"handle-bottom-right",o,r),k(t,0,n,"handle-bottom-left",o,r)})(h,c,d,e,o),u.appendChild(h);return r().appendChild(u),u},D={div:"Container",h1:"Heading 1",h2:"Heading 2",h3:"Heading 3",h4:"Heading 4",h5:"Heading 5",h6:"Heading 6",p:"Text",li:"List Item",ul:"Unordered List",ol:"Ordered List",img:"Image",a:"Link"},P=(t,e,n=!1,o=!1)=>{const r=document.createElement("div");r.className="node-tools",L(r,"is-instance",n),L(r,"is-text-edit",o),e.appendChild(r),((t,e)=>{const n=document.createElement("div");n.className="tag-label";const o=t.getAttribute("data-instance-name"),r=t.tagName.toLowerCase(),i=o||D[r]||r;var s;n.textContent=(s=i)?s.charAt(0).toUpperCase()+s.slice(1):s,e.appendChild(n)})(t,r)};function q(){return r().querySelector(".highlight-frame-overlay")}const F=t=>{if(!t)return;const e=q(),n=r(),o=n.querySelector(".highlight-frame-tools-wrapper");e&&e.remove(),o&&o.remove();const i=C(t),s="true"===t.contentEditable,a=N(t,i,s);"true"===t.contentEditable&&a.classList.add("is-editable");const{left:d,top:c,height:u}=l(t),g=c+u,m=document.createElement("div");m.classList.add("highlight-frame-tools-wrapper"),L(m,"is-instance",i),L(m,"is-text-edit",s),m.style.position="absolute",m.style.transform=`translate(${d}px, ${g}px)`,m.style.transformOrigin="left center",m.style.pointerEvents="none",m.style.zIndex="500",P(t,m,i,s),n.appendChild(m)},z=()=>getComputedStyle(document.documentElement).getPropertyValue("--component-color").trim()||"oklch(65.6% 0.241 354.308)",M=()=>getComputedStyle(document.documentElement).getPropertyValue("--text-edit-color").trim()||"oklch(62.3% 0.214 259.815)",$=(t,e,o="canvas")=>{const i=q();if(!i)return;const s=C(t),a="true"===t.contentEditable,{width:d,height:c}=n();i.setAttribute("width",d.toString()),i.setAttribute("height",c.toString()),L(i,"is-instance",s),L(i,"is-text-edit",a);const u=i.querySelector(".highlight-frame-group");if(!u)return;const g=u.querySelector("rect");if(!g)return;s?g.setAttribute("stroke",z()):a?g.setAttribute("stroke",M()):g.removeAttribute("stroke");const m=r().querySelector(".highlight-frame-tools-wrapper"),h=m?.querySelector(".node-tools"),p=v(["zoom","current"],o)??1,f=l(t),{top:b,left:y,width:w,height:E}=f,A=Math.max(w,3),S=b+E;L(m,"is-instance",s),L(m,"is-text-edit",a),L(h,"is-instance",s),L(h,"is-text-edit",a),u.setAttribute("transform",`translate(${y}, ${b})`),g.setAttribute("width",A.toString()),g.setAttribute("height",E.toString());const x=u.querySelector(".handle-top-left"),k=u.querySelector(".handle-top-right"),N=u.querySelector(".handle-bottom-right"),D=u.querySelector(".handle-bottom-left");[x,k,N,D].forEach(t=>{t&&(s?t.setAttribute("stroke",z()):a?t.setAttribute("stroke",M()):t.removeAttribute("stroke"))}),x&&(x.setAttribute("x",(-3).toString()),x.setAttribute("y",(-3).toString())),k&&(k.setAttribute("x",(A-3).toString()),k.setAttribute("y",(-3).toString())),N&&(N.setAttribute("x",(A-3).toString()),N.setAttribute("y",(E-3).toString())),D&&(D.setAttribute("x",(-3).toString()),D.setAttribute("y",(E-3).toString())),m&&(m.style.transform=`translate(${y}px, ${S}px)`),p<=10?e.style.setProperty("--tool-opacity","1"):e.style.setProperty("--tool-opacity","0")},H=t=>{const e=q();if(!e)return;const n=t.classList.contains("hidden")||t.classList.contains("select-none")?"none":"";e.style.display=n;const o=r().querySelector(".highlight-frame-tools-wrapper");o&&(o.style.display=n)},V=t=>{const e=t=>{"Enter"===t.key&&(t.preventDefault(),t.stopPropagation(),(()=>{const t=window.getSelection();if(t&&t.rangeCount>0){const e=t.getRangeAt(0);e.deleteContents();const n=document.createElement("br");e.insertNode(n),e.setStartAfter(n),e.setEndAfter(n),t.removeAllRanges(),t.addRange(e)}})())};return t.addEventListener("keydown",e),()=>{t.removeEventListener("keydown",e)}},T=(t,e,n=!1)=>{if(!e.some(t=>"characterData"===t.type||"childList"===t.type&&(t.addedNodes.length>0||t.removedNodes.length>0))&&!n)return;const o=t.textContent??"",r=t.getAttribute("data-node-id");console.log("textContentChanged",o,n),c("textContentChanged",{nodeId:r,textContent:o,final:n})},O=(t,e,n="canvas")=>{let o=[],r=null,i=null;const s=()=>{null===r&&(r=requestAnimationFrame(()=>{i=requestAnimationFrame(()=>{(()=>{if(o.length>0){const e=[...o];o=[],T(t,e,!1)}})(),r=null,i=null})}))},a=((t,e)=>{const n=new MutationObserver(t=>{e(t)});return n.observe(t,{subtree:!0,childList:!0,characterData:!0}),n})(t,r=>{o.push(...r),s(),console.log("refreshHighlightFrame in mutationObserver"),$(t,e,n)});return()=>{a.disconnect(),null!==r&&(cancelAnimationFrame(r),r=null),null!==i&&(cancelAnimationFrame(i),i=null),o=[]}},X=(t="canvas")=>{let e=null,n=!1,o=null;const r=()=>{if(n||!e)return;n=!0;const r=e;var i;T(r,[],!0),(i=r).contentEditable="false",i.classList.remove("is-editable"),i.style.outline="none",((t="canvas")=>{const e=v(["keyboard","disableTextEditMode"],t);e?.()})(t),o?.(),e=null,n=!1};return{enableEditMode:(n,i)=>{if(e===n)return;e&&e!==n&&r();const s=(t=>Array.from(t.childNodes).some(t=>t.nodeType===Node.TEXT_NODE&&t.textContent?.trim()))(n);s&&(e=n,(t=>{t.contentEditable="true",t.classList.add("is-editable"),t.style.outline="none"})(n),((t="canvas")=>{const e=v(["keyboard","enableTextEditMode"],t);e?.()})(t),o=((t,e,n,o="canvas")=>{if(!e)return()=>{};t.addEventListener("blur",n);const r=V(t),i=O(t,e,o);return()=>{t.removeEventListener("blur",n),r(),i?.()}})(n,i,r,t))},blurEditMode:r,getEditableNode:()=>e,isEditing:()=>null!==e}},Y=4,I=2560,R=[{name:"Mobile",rawValue:390,value:"320px"},{name:"Tablet Portrait",rawValue:768,value:"768px"},{name:"Tablet Landscape",rawValue:1024,value:"1024px"},{name:"Notebook",rawValue:1280,value:"1280px"},{name:"Desktop",rawValue:1680,value:"1680px"}],W=(t,e,n)=>{const o=parseFloat(document.body.dataset.zoom||"1"),r=((t,e)=>{const n=t+Math.round(e);return Math.max(Y,Math.min(I,n))})(n,(t.clientX-e)/o);return r},K=(t,e)=>{t.style.setProperty("--container-width",`${e}px`),((t,e)=>{t.querySelectorAll(".resize-preset-button").forEach((t,n)=>{n<R.length&&(R[n].rawValue===e?t.classList.add("is-active"):t.classList.remove("is-active"))})})(t,e)};t.createCanvasObserver=function(t="canvas"){const n=document.querySelector(".transform-layer");if(!n)return{disconnect:()=>{}};const o=new MutationObserver(()=>{((t="canvas")=>{const e=v(["zoom","current"],t)??1;document.body.style.setProperty("--zoom",e.toFixed(5)),document.body.style.setProperty("--stroke-width",(2/e).toFixed(3)),document.body.dataset.zoom=e.toFixed(5),document.body.dataset.strokeWidth=(2/e).toFixed(3)})(t);const n=e();n?.refreshHighlightFrame&&n.refreshHighlightFrame(),p()});o.observe(n,{attributes:!0,attributeOldValue:!0,subtree:!0,childList:!0});const r=()=>{p()};return window.addEventListener("resize",r),p(),{disconnect:function(){o.disconnect(),window.removeEventListener("resize",r)}}},t.createNodeTools=(t,e="canvas")=>{const n=t;let o=null,r=null,i=null,s=null;const a=X(e),l=t=>{if(s!==t){if(a.isEditing()){const e=a.getEditableNode();e&&e!==t&&a.blurEditMode()}if(o?.disconnect(),r?.disconnect(),i?.disconnect(),t&&n){const a=()=>{if(!document.contains(t))return f(),s=null,o?.disconnect(),r?.disconnect(),i?.disconnect(),void c("selectedNodeChanged",null)};r=new MutationObserver(()=>{a(),document.contains(t)&&(console.log("refreshHighlightFrame in mutationObserver 2"),$(t,n,e),H(t))}),r.observe(t,{attributes:!0,characterData:!0});const l=t.parentElement;l&&(i=new MutationObserver(e=>{for(const n of e)if("childList"===n.type)for(const e of Array.from(n.removedNodes))if(e===t||e instanceof Node&&e.contains(t))return void a()}),i.observe(l,{childList:!0,subtree:!1})),o=((t,e)=>{const n=new ResizeObserver(t=>{e(t)});return n.observe(t),n})(t,()=>{a(),document.contains(t)&&($(t,n,e),console.log("refreshHighlightFrame in resizeObserver"),H(t))})}s=t,c("selectedNodeChanged",t?.getAttribute("data-node-id")??null),F(t),t?(F(t),n&&H(t)):f()}},d=x(n,l,()=>{a.isEditing()&&a.blurEditMode(),s&&n&&(f(),s=null,o?.disconnect(),r?.disconnect(),i?.disconnect())},a),u={selectNode:l,getSelectedNode:()=>s,refreshHighlightFrame:()=>{s&&n&&($(s,n,e),H(s))},clearSelectedNode:()=>{f(),s=null,o?.disconnect(),r?.disconnect(),i?.disconnect()},getEditableNode:()=>a.getEditableNode(),cleanup:()=>{d(),o?.disconnect(),r?.disconnect(),i?.disconnect(),a.blurEditMode(),f(),s=null,c("selectedNodeChanged",null)}};var g,m;return g="nodeTools",m=u,"undefined"!=typeof window&&(window[g]=m),u},t.createViewport=(t,n)=>{const r=o(),s=t.querySelector(".resize-handle");s&&s.remove();const a=(t=>{const e=document.createElement("div");return e.className="resize-handle",t.appendChild(e),e})(t),l=n??400;t.style.setProperty("--container-width",`${l}px`),((t,e,n)=>{const o=document.createElement("div");o.className="resize-presets",R.forEach(t=>{const r=document.createElement("button");r.textContent=t.name,r.className="resize-preset-button",r.addEventListener("click",()=>{n(e,t.rawValue)}),o.appendChild(r)}),t.appendChild(o)})(a,t,K);let c=0,u=0;const g=t=>{t.relatedTarget||t.target!==document&&t.target!==document.documentElement||r&&(r.style.cursor="default")},m=d(a,{onStart:(e,{startX:n})=>{c=n,u=t.offsetWidth},onDrag:e=>{r&&(r.style.cursor="ew-resize");const n=W(e,c,u);K(t,n)},onStop:()=>{r&&(r.style.cursor="default")},onCancel:()=>{r&&(r.style.cursor="default")},onPreventClick:()=>{}});document.addEventListener("mouseleave",g),h(t);return{setWidth:n=>{K(t,n),h(t);const o=e(),r=o?.getSelectedNode?.(),i=document.querySelector('[data-role="node-provider"]');r&&i&&$(r,i)},cleanup:()=>{m(),document.removeEventListener("mouseleave",g),a.remove(),(t=>{const e=t.getAttribute("data-viewport-name");if(!e)return;const n=i().querySelector(`[data-viewport-name="${e}"]`);n&&n.remove()})(t)}}}});
|
package/dist/styles.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
:root{--primary-color:oklch(0.6235 0.22 294);--uncode-color:oklch(45.7% 0.24 277.023);--component-color:oklch(65.6% 0.241 354.308);--text-edit-color:oklch(62.3% 0.214 259.815);--text-edit-selection-color:oklch(62.3% 0.214 259.815/0.2);--handle-color:oklch(55.2% 0.016 285.938);--handle-color-transparent:oklch(55.2% 0.016 285.938/0.7);--primary-color-selection:oklch(0.59 0.18 294/0.3);--text-color-white:#fff;--spacing-2xs:0.1875rem;--spacing-xs:0.25rem;--spacing-sm:0.375rem;--spacing-md:0.5rem;--spacing-lg:1.25rem;--transition-fast:0.1s ease-in-out;--transition-medium:0.2s ease-in-out;--z-index-high:10000;--z-index-highlight:500;--z-index-medium:1000;--letter-spacing:0.02em;--font-family-primary:"Manrope",sans-serif}.node-provider{::selection{background:transparent}::-moz-selection{background:transparent}::-webkit-selection{background:transparent}}.node-tools{bottom:0;contain:layout style;display:flex;gap:var(--spacing-xs);justify-content:center;left:0;opacity:var(--tool-opacity);padding-top:var(--spacing-2xs);position:absolute;top:0;transform:translate3d(0,100%,0);transform-origin:bottom center;transition:opacity var(--transition-fast);z-index:var(--z-index-high)}.highlight-frame-overlay,.viewport-labels-overlay{contain:layout style paint;height:100vh;inset:0;overflow:visible;pointer-events:none;position:absolute;width:100vw;will-change:transform;z-index:var(--z-index-highlight)}.viewport-label-text{fill:oklch(.5 0 0);font-family:var(--font-family-primary);font-size:.6875rem;font-weight:500;letter-spacing:var(--letter-spacing);pointer-events:auto;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}@media (prefers-color-scheme:dark){.viewport-label-text{fill:oklch(.5 0 0)}.viewport-label-text:hover{fill:oklch(
|
|
1
|
+
:root{--primary-color:oklch(0.6235 0.22 294);--uncode-color:oklch(45.7% 0.24 277.023);--component-color:oklch(65.6% 0.241 354.308);--text-edit-color:oklch(62.3% 0.214 259.815);--text-edit-selection-color:oklch(62.3% 0.214 259.815/0.2);--handle-color:oklch(55.2% 0.016 285.938);--handle-color-transparent:oklch(55.2% 0.016 285.938/0.7);--primary-color-selection:oklch(0.59 0.18 294/0.3);--text-color-white:#fff;--spacing-2xs:0.1875rem;--spacing-xs:0.25rem;--spacing-sm:0.375rem;--spacing-md:0.5rem;--spacing-lg:1.25rem;--transition-fast:0.1s ease-in-out;--transition-medium:0.2s ease-in-out;--z-index-high:10000;--z-index-highlight:500;--z-index-medium:1000;--letter-spacing:0.02em;--font-family-primary:"Manrope",sans-serif}.node-provider{::selection{background:transparent}::-moz-selection{background:transparent}::-webkit-selection{background:transparent}}.node-tools{bottom:0;contain:layout style;display:flex;gap:var(--spacing-xs);justify-content:center;left:0;opacity:var(--tool-opacity);padding-top:var(--spacing-2xs);position:absolute;top:0;transform:translate3d(0,100%,0);transform-origin:bottom center;transition:opacity var(--transition-fast);z-index:var(--z-index-high)}.highlight-frame-overlay,.viewport-labels-overlay{contain:layout style paint;height:100vh;inset:0;overflow:visible;pointer-events:none;position:absolute;width:100vw;will-change:transform;z-index:var(--z-index-highlight)}.viewport-label-text{fill:oklch(.5 0 0);font-family:var(--font-family-primary);font-size:.6875rem;font-weight:500;letter-spacing:var(--letter-spacing);pointer-events:auto;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}@media (prefers-color-scheme:dark){.viewport-label-text{fill:oklch(.5 0 0)}.viewport-label-text:hover{fill:oklch(.7 0 0)}}@media (prefers-color-scheme:light){.viewport-label-text{fill:oklch(.7 0 0)}.viewport-label-text:hover{fill:oklch(.5 0 0)}}.highlight-frame-rect{fill:none;stroke:var(--primary-color);stroke-width:2px}.highlight-frame-overlay.is-instance .highlight-frame-rect{stroke:var(--component-color)}.highlight-frame-overlay.is-text-edit .highlight-frame-rect{stroke:var(--text-edit-color)}.highlight-frame-handle{fill:#fff;stroke:var(--primary-color);stroke-width:1px;cursor:nwse-resize;pointer-events:auto}.highlight-frame-overlay.is-instance .highlight-frame-handle{stroke:var(--component-color)}.highlight-frame-overlay.is-text-edit .highlight-frame-handle{stroke:var(--text-edit-color)}.highlight-frame-handle.handle-top-left{cursor:nwse-resize}.highlight-frame-handle.handle-top-right{cursor:nesw-resize}.highlight-frame-handle.handle-bottom-right{cursor:nwse-resize}.highlight-frame-handle.handle-bottom-left{cursor:nesw-resize}.highlight-frame-tools-wrapper{contain:layout style;left:0;pointer-events:none;position:absolute;top:0;z-index:var(--z-index-highlight)}.tag-label{align-items:center;background-color:var(--primary-color);border-radius:var(--spacing-sm);color:var(--text-color-white);display:flex;font-size:.575rem;font-weight:500;height:1rem;justify-content:center;line-height:1.4;padding:.5625rem var(--spacing-sm);white-space:nowrap}.highlight-frame-tools-wrapper.is-instance .tag-label,.node-tools.is-instance .tag-label{background-color:var(--component-color)}.highlight-frame-tools-wrapper.is-text-edit .tag-label,.node-tools.is-text-edit .tag-label{background-color:var(--text-edit-color)}.viewport{left:0;position:absolute;top:0;width:var(--container-width)}.resize-handle{align-items:center;cursor:ew-resize;display:flex;height:40px;justify-content:center;opacity:0;pointer-events:auto;position:absolute;right:-12px;top:var(--spacing-lg);transform:scale(calc(1/var(--zoom)));transform-origin:top left;transition:opacity var(--transition-fast),visibility var(--transition-fast);visibility:hidden;width:12px;z-index:var(--z-index-high)}.viewport:hover .resize-handle{opacity:1;visibility:visible}.resize-handle:before{background:var(--handle-color);border-radius:4px;content:"";height:32px;position:relative;right:0;top:0;transition:transform var(--transition-medium);width:3px}.resize-handle:hover:before{transform:scaleY(1.3)}.resize-presets{display:flex;flex-direction:column;font-family:var(--font-family-primary);gap:var(--spacing-xs);left:0;letter-spacing:var(--letter-spacing);opacity:0;padding-left:var(--spacing-lg);position:absolute;top:0;transition:visibility var(--transition-fast),opacity var(--transition-fast);visibility:hidden}.resize-handle:hover .resize-presets{opacity:1;visibility:visible}.resize-preset-button{text-wrap:nowrap;backdrop-filter:blur(8px);background:var(--handle-color-transparent);border:none;border-radius:var(--spacing-md);color:var(--text-color-white);cursor:pointer;font-size:.625rem;padding:var(--spacing-xs) var(--spacing-md);text-align:left;transition:background var(--transition-fast);width:fit-content;&:hover{background:var(--handle-color)}&.is-active{background:var(--uncode-color)}}.is-editable{outline:none;user-select:text;&::selection{background:var(--text-edit-selection-color)}&::-moz-selection{background:var(--text-edit-selection-color)}&::-webkit-selection{background:var(--text-edit-selection-color)}}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@node-edit-utils/core",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.4",
|
|
4
4
|
"description": "Utilities for editing nodes in a dom tree.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/node-edit-utils.cjs.js",
|
|
@@ -28,6 +28,8 @@
|
|
|
28
28
|
"clean": "rm -rf dist",
|
|
29
29
|
"lint": "biome check .",
|
|
30
30
|
"format": "biome format --write .",
|
|
31
|
+
"test": "vitest",
|
|
32
|
+
"test:run": "vitest run",
|
|
31
33
|
"prepublishOnly": "npm run clean && npm run build"
|
|
32
34
|
},
|
|
33
35
|
"keywords": [
|
|
@@ -54,7 +56,10 @@
|
|
|
54
56
|
"tslib": "^2.8.1",
|
|
55
57
|
"ttypescript": "^1.5.15",
|
|
56
58
|
"typescript": "^5.9.3",
|
|
57
|
-
"typescript-transform-paths": "^3.5.5"
|
|
59
|
+
"typescript-transform-paths": "^3.5.5",
|
|
60
|
+
"vitest": "^2.1.8",
|
|
61
|
+
"@vitest/ui": "^2.1.8",
|
|
62
|
+
"jsdom": "^25.0.1"
|
|
58
63
|
},
|
|
59
64
|
"repository": {
|
|
60
65
|
"type": "git",
|