@node-edit-utils/core 2.3.0 → 2.3.1
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/createViewport.d.ts +1 -1
- package/dist/node-edit-utils.cjs.js +16 -32
- package/dist/node-edit-utils.esm.js +16 -32
- package/dist/node-edit-utils.umd.js +16 -32
- package/dist/node-edit-utils.umd.min.js +1 -1
- package/package.json +1 -1
- package/src/lib/viewport/createViewport.ts +8 -7
- package/src/lib/viewport/events/setupEventListener.ts +9 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { Viewport } from "./types";
|
|
2
|
-
export declare const createViewport: (container: HTMLElement) => Viewport;
|
|
2
|
+
export declare const createViewport: (container: HTMLElement, initialWidth?: number) => Viewport;
|
|
@@ -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.1
|
|
5
5
|
*/
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
@@ -927,32 +927,6 @@ const createNodeTools = (element, canvasName = "canvas") => {
|
|
|
927
927
|
return nodeTools;
|
|
928
928
|
};
|
|
929
929
|
|
|
930
|
-
// biome-ignore lint/suspicious/noExplicitAny: generic constraint requires flexibility
|
|
931
|
-
function withRAFThrottle(func) {
|
|
932
|
-
let rafId = null;
|
|
933
|
-
let lastArgs = null;
|
|
934
|
-
const throttled = (...args) => {
|
|
935
|
-
lastArgs = args;
|
|
936
|
-
if (rafId === null) {
|
|
937
|
-
rafId = requestAnimationFrame(() => {
|
|
938
|
-
if (lastArgs) {
|
|
939
|
-
func(...lastArgs);
|
|
940
|
-
}
|
|
941
|
-
rafId = null;
|
|
942
|
-
lastArgs = null;
|
|
943
|
-
});
|
|
944
|
-
}
|
|
945
|
-
};
|
|
946
|
-
throttled.cleanup = () => {
|
|
947
|
-
if (rafId !== null) {
|
|
948
|
-
cancelAnimationFrame(rafId);
|
|
949
|
-
rafId = null;
|
|
950
|
-
lastArgs = null;
|
|
951
|
-
}
|
|
952
|
-
};
|
|
953
|
-
return throttled;
|
|
954
|
-
}
|
|
955
|
-
|
|
956
930
|
const DEFAULT_WIDTH = 400;
|
|
957
931
|
const RESIZE_CONFIG = {
|
|
958
932
|
minWidth: 320,
|
|
@@ -987,14 +961,22 @@ const RESIZE_PRESETS = [
|
|
|
987
961
|
];
|
|
988
962
|
|
|
989
963
|
const setupEventListener = (resizeHandle, startResize, handleResize, stopResize, blurResize) => {
|
|
964
|
+
const handleMouseLeave = (event) => {
|
|
965
|
+
// Check if mouse is leaving the window/document
|
|
966
|
+
if (!event.relatedTarget && (event.target === document || event.target === document.documentElement)) {
|
|
967
|
+
blurResize();
|
|
968
|
+
}
|
|
969
|
+
};
|
|
990
970
|
resizeHandle.addEventListener("mousedown", startResize);
|
|
991
971
|
document.addEventListener("mousemove", handleResize);
|
|
992
972
|
document.addEventListener("mouseup", stopResize);
|
|
973
|
+
document.addEventListener("mouseleave", handleMouseLeave);
|
|
993
974
|
window.addEventListener("blur", blurResize);
|
|
994
975
|
return () => {
|
|
995
976
|
resizeHandle.removeEventListener("mousedown", startResize);
|
|
996
977
|
document.removeEventListener("mousemove", handleResize);
|
|
997
978
|
document.removeEventListener("mouseup", stopResize);
|
|
979
|
+
document.removeEventListener("mouseleave", handleMouseLeave);
|
|
998
980
|
window.removeEventListener("blur", blurResize);
|
|
999
981
|
};
|
|
1000
982
|
};
|
|
@@ -1054,7 +1036,7 @@ const updateWidth = (container, width) => {
|
|
|
1054
1036
|
updateActivePreset(container, width);
|
|
1055
1037
|
};
|
|
1056
1038
|
|
|
1057
|
-
const createViewport = (container) => {
|
|
1039
|
+
const createViewport = (container, initialWidth) => {
|
|
1058
1040
|
const canvas = getCanvasContainer();
|
|
1059
1041
|
// Remove any existing resize handle to prevent duplicates
|
|
1060
1042
|
const existingHandle = container.querySelector(".resize-handle");
|
|
@@ -1062,7 +1044,8 @@ const createViewport = (container) => {
|
|
|
1062
1044
|
existingHandle.remove();
|
|
1063
1045
|
}
|
|
1064
1046
|
const resizeHandle = createResizeHandle(container);
|
|
1065
|
-
|
|
1047
|
+
const width = initialWidth ?? DEFAULT_WIDTH;
|
|
1048
|
+
container.style.setProperty("--container-width", `${width}px`);
|
|
1066
1049
|
createResizePresets(resizeHandle, container, updateWidth);
|
|
1067
1050
|
let isDragging = false;
|
|
1068
1051
|
let startX = 0;
|
|
@@ -1083,7 +1066,6 @@ const createViewport = (container) => {
|
|
|
1083
1066
|
const width = calcWidth(event, startX, startWidth);
|
|
1084
1067
|
updateWidth(container, width);
|
|
1085
1068
|
};
|
|
1086
|
-
const throttledHandleResize = withRAFThrottle(handleResize);
|
|
1087
1069
|
const stopResize = (event) => {
|
|
1088
1070
|
event.preventDefault();
|
|
1089
1071
|
event.stopPropagation();
|
|
@@ -1093,12 +1075,14 @@ const createViewport = (container) => {
|
|
|
1093
1075
|
isDragging = false;
|
|
1094
1076
|
};
|
|
1095
1077
|
const blurResize = () => {
|
|
1078
|
+
if (canvas) {
|
|
1079
|
+
canvas.style.cursor = "default";
|
|
1080
|
+
}
|
|
1096
1081
|
isDragging = false;
|
|
1097
1082
|
};
|
|
1098
|
-
const removeListeners = setupEventListener(resizeHandle, startResize,
|
|
1083
|
+
const removeListeners = setupEventListener(resizeHandle, startResize, handleResize, stopResize, blurResize);
|
|
1099
1084
|
const cleanup = () => {
|
|
1100
1085
|
isDragging = false;
|
|
1101
|
-
throttledHandleResize?.cleanup();
|
|
1102
1086
|
removeListeners();
|
|
1103
1087
|
resizeHandle.remove();
|
|
1104
1088
|
};
|
|
@@ -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.1
|
|
5
5
|
*/
|
|
6
6
|
const getCanvasWindowValue = (path, canvasName = "canvas") => {
|
|
7
7
|
// biome-ignore lint/suspicious/noExplicitAny: global window extension
|
|
@@ -925,32 +925,6 @@ const createNodeTools = (element, canvasName = "canvas") => {
|
|
|
925
925
|
return nodeTools;
|
|
926
926
|
};
|
|
927
927
|
|
|
928
|
-
// biome-ignore lint/suspicious/noExplicitAny: generic constraint requires flexibility
|
|
929
|
-
function withRAFThrottle(func) {
|
|
930
|
-
let rafId = null;
|
|
931
|
-
let lastArgs = null;
|
|
932
|
-
const throttled = (...args) => {
|
|
933
|
-
lastArgs = args;
|
|
934
|
-
if (rafId === null) {
|
|
935
|
-
rafId = requestAnimationFrame(() => {
|
|
936
|
-
if (lastArgs) {
|
|
937
|
-
func(...lastArgs);
|
|
938
|
-
}
|
|
939
|
-
rafId = null;
|
|
940
|
-
lastArgs = null;
|
|
941
|
-
});
|
|
942
|
-
}
|
|
943
|
-
};
|
|
944
|
-
throttled.cleanup = () => {
|
|
945
|
-
if (rafId !== null) {
|
|
946
|
-
cancelAnimationFrame(rafId);
|
|
947
|
-
rafId = null;
|
|
948
|
-
lastArgs = null;
|
|
949
|
-
}
|
|
950
|
-
};
|
|
951
|
-
return throttled;
|
|
952
|
-
}
|
|
953
|
-
|
|
954
928
|
const DEFAULT_WIDTH = 400;
|
|
955
929
|
const RESIZE_CONFIG = {
|
|
956
930
|
minWidth: 320,
|
|
@@ -985,14 +959,22 @@ const RESIZE_PRESETS = [
|
|
|
985
959
|
];
|
|
986
960
|
|
|
987
961
|
const setupEventListener = (resizeHandle, startResize, handleResize, stopResize, blurResize) => {
|
|
962
|
+
const handleMouseLeave = (event) => {
|
|
963
|
+
// Check if mouse is leaving the window/document
|
|
964
|
+
if (!event.relatedTarget && (event.target === document || event.target === document.documentElement)) {
|
|
965
|
+
blurResize();
|
|
966
|
+
}
|
|
967
|
+
};
|
|
988
968
|
resizeHandle.addEventListener("mousedown", startResize);
|
|
989
969
|
document.addEventListener("mousemove", handleResize);
|
|
990
970
|
document.addEventListener("mouseup", stopResize);
|
|
971
|
+
document.addEventListener("mouseleave", handleMouseLeave);
|
|
991
972
|
window.addEventListener("blur", blurResize);
|
|
992
973
|
return () => {
|
|
993
974
|
resizeHandle.removeEventListener("mousedown", startResize);
|
|
994
975
|
document.removeEventListener("mousemove", handleResize);
|
|
995
976
|
document.removeEventListener("mouseup", stopResize);
|
|
977
|
+
document.removeEventListener("mouseleave", handleMouseLeave);
|
|
996
978
|
window.removeEventListener("blur", blurResize);
|
|
997
979
|
};
|
|
998
980
|
};
|
|
@@ -1052,7 +1034,7 @@ const updateWidth = (container, width) => {
|
|
|
1052
1034
|
updateActivePreset(container, width);
|
|
1053
1035
|
};
|
|
1054
1036
|
|
|
1055
|
-
const createViewport = (container) => {
|
|
1037
|
+
const createViewport = (container, initialWidth) => {
|
|
1056
1038
|
const canvas = getCanvasContainer();
|
|
1057
1039
|
// Remove any existing resize handle to prevent duplicates
|
|
1058
1040
|
const existingHandle = container.querySelector(".resize-handle");
|
|
@@ -1060,7 +1042,8 @@ const createViewport = (container) => {
|
|
|
1060
1042
|
existingHandle.remove();
|
|
1061
1043
|
}
|
|
1062
1044
|
const resizeHandle = createResizeHandle(container);
|
|
1063
|
-
|
|
1045
|
+
const width = initialWidth ?? DEFAULT_WIDTH;
|
|
1046
|
+
container.style.setProperty("--container-width", `${width}px`);
|
|
1064
1047
|
createResizePresets(resizeHandle, container, updateWidth);
|
|
1065
1048
|
let isDragging = false;
|
|
1066
1049
|
let startX = 0;
|
|
@@ -1081,7 +1064,6 @@ const createViewport = (container) => {
|
|
|
1081
1064
|
const width = calcWidth(event, startX, startWidth);
|
|
1082
1065
|
updateWidth(container, width);
|
|
1083
1066
|
};
|
|
1084
|
-
const throttledHandleResize = withRAFThrottle(handleResize);
|
|
1085
1067
|
const stopResize = (event) => {
|
|
1086
1068
|
event.preventDefault();
|
|
1087
1069
|
event.stopPropagation();
|
|
@@ -1091,12 +1073,14 @@ const createViewport = (container) => {
|
|
|
1091
1073
|
isDragging = false;
|
|
1092
1074
|
};
|
|
1093
1075
|
const blurResize = () => {
|
|
1076
|
+
if (canvas) {
|
|
1077
|
+
canvas.style.cursor = "default";
|
|
1078
|
+
}
|
|
1094
1079
|
isDragging = false;
|
|
1095
1080
|
};
|
|
1096
|
-
const removeListeners = setupEventListener(resizeHandle, startResize,
|
|
1081
|
+
const removeListeners = setupEventListener(resizeHandle, startResize, handleResize, stopResize, blurResize);
|
|
1097
1082
|
const cleanup = () => {
|
|
1098
1083
|
isDragging = false;
|
|
1099
|
-
throttledHandleResize?.cleanup();
|
|
1100
1084
|
removeListeners();
|
|
1101
1085
|
resizeHandle.remove();
|
|
1102
1086
|
};
|
|
@@ -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.1
|
|
5
5
|
*/
|
|
6
6
|
(function (global, factory) {
|
|
7
7
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
@@ -931,32 +931,6 @@
|
|
|
931
931
|
return nodeTools;
|
|
932
932
|
};
|
|
933
933
|
|
|
934
|
-
// biome-ignore lint/suspicious/noExplicitAny: generic constraint requires flexibility
|
|
935
|
-
function withRAFThrottle(func) {
|
|
936
|
-
let rafId = null;
|
|
937
|
-
let lastArgs = null;
|
|
938
|
-
const throttled = (...args) => {
|
|
939
|
-
lastArgs = args;
|
|
940
|
-
if (rafId === null) {
|
|
941
|
-
rafId = requestAnimationFrame(() => {
|
|
942
|
-
if (lastArgs) {
|
|
943
|
-
func(...lastArgs);
|
|
944
|
-
}
|
|
945
|
-
rafId = null;
|
|
946
|
-
lastArgs = null;
|
|
947
|
-
});
|
|
948
|
-
}
|
|
949
|
-
};
|
|
950
|
-
throttled.cleanup = () => {
|
|
951
|
-
if (rafId !== null) {
|
|
952
|
-
cancelAnimationFrame(rafId);
|
|
953
|
-
rafId = null;
|
|
954
|
-
lastArgs = null;
|
|
955
|
-
}
|
|
956
|
-
};
|
|
957
|
-
return throttled;
|
|
958
|
-
}
|
|
959
|
-
|
|
960
934
|
const DEFAULT_WIDTH = 400;
|
|
961
935
|
const RESIZE_CONFIG = {
|
|
962
936
|
minWidth: 320,
|
|
@@ -991,14 +965,22 @@
|
|
|
991
965
|
];
|
|
992
966
|
|
|
993
967
|
const setupEventListener = (resizeHandle, startResize, handleResize, stopResize, blurResize) => {
|
|
968
|
+
const handleMouseLeave = (event) => {
|
|
969
|
+
// Check if mouse is leaving the window/document
|
|
970
|
+
if (!event.relatedTarget && (event.target === document || event.target === document.documentElement)) {
|
|
971
|
+
blurResize();
|
|
972
|
+
}
|
|
973
|
+
};
|
|
994
974
|
resizeHandle.addEventListener("mousedown", startResize);
|
|
995
975
|
document.addEventListener("mousemove", handleResize);
|
|
996
976
|
document.addEventListener("mouseup", stopResize);
|
|
977
|
+
document.addEventListener("mouseleave", handleMouseLeave);
|
|
997
978
|
window.addEventListener("blur", blurResize);
|
|
998
979
|
return () => {
|
|
999
980
|
resizeHandle.removeEventListener("mousedown", startResize);
|
|
1000
981
|
document.removeEventListener("mousemove", handleResize);
|
|
1001
982
|
document.removeEventListener("mouseup", stopResize);
|
|
983
|
+
document.removeEventListener("mouseleave", handleMouseLeave);
|
|
1002
984
|
window.removeEventListener("blur", blurResize);
|
|
1003
985
|
};
|
|
1004
986
|
};
|
|
@@ -1058,7 +1040,7 @@
|
|
|
1058
1040
|
updateActivePreset(container, width);
|
|
1059
1041
|
};
|
|
1060
1042
|
|
|
1061
|
-
const createViewport = (container) => {
|
|
1043
|
+
const createViewport = (container, initialWidth) => {
|
|
1062
1044
|
const canvas = getCanvasContainer();
|
|
1063
1045
|
// Remove any existing resize handle to prevent duplicates
|
|
1064
1046
|
const existingHandle = container.querySelector(".resize-handle");
|
|
@@ -1066,7 +1048,8 @@
|
|
|
1066
1048
|
existingHandle.remove();
|
|
1067
1049
|
}
|
|
1068
1050
|
const resizeHandle = createResizeHandle(container);
|
|
1069
|
-
|
|
1051
|
+
const width = initialWidth ?? DEFAULT_WIDTH;
|
|
1052
|
+
container.style.setProperty("--container-width", `${width}px`);
|
|
1070
1053
|
createResizePresets(resizeHandle, container, updateWidth);
|
|
1071
1054
|
let isDragging = false;
|
|
1072
1055
|
let startX = 0;
|
|
@@ -1087,7 +1070,6 @@
|
|
|
1087
1070
|
const width = calcWidth(event, startX, startWidth);
|
|
1088
1071
|
updateWidth(container, width);
|
|
1089
1072
|
};
|
|
1090
|
-
const throttledHandleResize = withRAFThrottle(handleResize);
|
|
1091
1073
|
const stopResize = (event) => {
|
|
1092
1074
|
event.preventDefault();
|
|
1093
1075
|
event.stopPropagation();
|
|
@@ -1097,12 +1079,14 @@
|
|
|
1097
1079
|
isDragging = false;
|
|
1098
1080
|
};
|
|
1099
1081
|
const blurResize = () => {
|
|
1082
|
+
if (canvas) {
|
|
1083
|
+
canvas.style.cursor = "default";
|
|
1084
|
+
}
|
|
1100
1085
|
isDragging = false;
|
|
1101
1086
|
};
|
|
1102
|
-
const removeListeners = setupEventListener(resizeHandle, startResize,
|
|
1087
|
+
const removeListeners = setupEventListener(resizeHandle, startResize, handleResize, stopResize, blurResize);
|
|
1103
1088
|
const cleanup = () => {
|
|
1104
1089
|
isDragging = false;
|
|
1105
|
-
throttledHandleResize?.cleanup();
|
|
1106
1090
|
removeListeners();
|
|
1107
1091
|
resizeHandle.remove();
|
|
1108
1092
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).MarkupCanvas={})}(this,function(e){"use strict";const t=(e,t="canvas")=>{const n=window[t];return e.reduce((e,t)=>e?.[t],n)};function n(e,t){window.parent.postMessage({source:"node-edit-utils",action:e,data:t,timestamp:Date.now()},"*")}const o=()=>document.querySelector(".canvas-container"),r=()=>{const e=o()||document.body,t=e.querySelector(".highlight-frame-overlay");t&&t.remove();const n=e.querySelector(".highlight-frame-tools-wrapper");n&&n.remove()},i=(e,t,n)=>{e&&t&&n.enableEditMode(e,t)},s=["path","rect","circle","ellipse","polygon","line","polyline","text","text-noci"];let a=[],l=0,d=null;const c=(e,t,n)=>{let o=null;const r=e.clientX,c=e.clientY,u=e.metaKey||e.ctrlKey,m=((e,t)=>{const n=document.elementsFromPoint(e,t);return Array.from(n).reduce((e,t)=>e.found?e:"node-provider"===t.getAttribute("data-role")?(e.found=!0,e):(e.elements.push(t),e),{elements:[],found:!1}).elements})(r,c).filter(e=>!s.includes(e.tagName.toLowerCase())&&!e.classList.contains("select-none")&&!(e=>{let t=e.parentElement;for(;t;){if("true"===t.getAttribute("data-instance"))return!0;if("node-provider"===t.getAttribute("data-role"))break;t=t.parentElement}return!1})(e)),h=n.getEditableNode();if(h&&m.includes(h))return o=h,d=o,o;if(u)return a=[],o=m[0],d&&d===o&&i(o,t,n),d=o,o;var g,p;p=m,(g=a).length===p.length&&g.every((e,t)=>e===p[t])?l<=m.length-2&&l++:l=0;return o=m[m.length-1-l],a=m,d&&d===o&&i(o,t,n),d=o,o},u=(e,t,n,o)=>{const i=e=>{((e,t)=>{if("application"===e.data.source&&"selectedNodeChanged"===e.data.action){const o=e.data.data,r=document.querySelector(`[data-node-id="${o}"]`);if(n=r,n?.classList.contains("select-none"))return void t?.(null);r&&t?.(r)}var n})(e,t)},s=n=>{((e,t,n,o)=>{if(e.preventDefault(),e.stopPropagation(),t&&!t.contains(e.target))return r(),void o(null);o(c(e,t,n))})(n,e,o,t)},a=e=>{"Escape"===e.key&&(e.preventDefault(),e.stopPropagation(),n?.())};return window.addEventListener("message",i),document.addEventListener("click",s),document.addEventListener("keydown",a),()=>{window.removeEventListener("message",i),document.removeEventListener("click",s),document.removeEventListener("keydown",a)}},m=e=>"true"===e.getAttribute("data-instance"),h=(e,t,n,o,r=!1,i=!1)=>{const s=document.createElementNS("http://www.w3.org/2000/svg","rect");return s.setAttribute("x",(t-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)"),e.appendChild(s),s};function g(e){const t=e.getBoundingClientRect();return{top:t.top,left:t.left,width:t.width,height:t.height}}const p=(e,t=!1,n=!1)=>{const{top:r,left:i,width:s,height:a}=g(e),l=Math.max(s,3),d=document.createElementNS("http://www.w3.org/2000/svg","svg");d.classList.add("highlight-frame-overlay"),t&&d.classList.add("is-instance"),n&&d.classList.add("is-text-edit"),d.setAttribute("data-node-id",e.getAttribute("data-node-id")||""),d.style.position="absolute",d.style.top="0",d.style.left="0",d.style.width="100vw",d.style.height="100vh",d.style.pointerEvents="none",d.style.zIndex="500";const c=document.documentElement.clientWidth||window.innerWidth,u=document.documentElement.clientHeight||window.innerHeight;d.setAttribute("width",c.toString()),d.setAttribute("height",u.toString());const m=document.createElementNS("http://www.w3.org/2000/svg","g");m.classList.add("highlight-frame-group"),m.setAttribute("transform",`translate(${i}, ${r})`);const p=document.createElementNS("http://www.w3.org/2000/svg","rect");p.setAttribute("x","0"),p.setAttribute("y","0"),p.setAttribute("width",l.toString()),p.setAttribute("height",a.toString()),p.setAttribute("vector-effect","non-scaling-stroke"),p.classList.add("highlight-frame-rect"),t?p.setAttribute("stroke",getComputedStyle(document.documentElement).getPropertyValue("--component-color").trim()||"oklch(65.6% 0.241 354.308)"):n&&p.setAttribute("stroke",getComputedStyle(document.documentElement).getPropertyValue("--text-edit-color").trim()||"oklch(62.3% 0.214 259.815)"),m.appendChild(p),((e,t,n,o=!1,r=!1)=>{h(e,0,0,"handle-top-left",o,r),h(e,t,0,"handle-top-right",o,r),h(e,t,n,"handle-bottom-right",o,r),h(e,0,n,"handle-bottom-left",o,r)})(m,l,a,t,n),d.appendChild(m);const b=o();return b?b.appendChild(d):document.body.appendChild(d),d},b={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"},v=(e,t,n=!1,o=!1)=>{const r=document.createElement("div");r.className="node-tools",n&&r.classList.add("is-instance"),o&&r.classList.add("is-text-edit"),t.appendChild(r),((e,t)=>{const n=document.createElement("div");n.className="tag-label";const o=e.getAttribute("data-instance-name"),r=e.tagName.toLowerCase(),i=o||b[r]||r;var s;n.textContent=(s=i)?s.charAt(0).toUpperCase()+s.slice(1):s,t.appendChild(n)})(e,r)};function y(){return(o()||document.body).querySelector(".highlight-frame-overlay")}const f=()=>getComputedStyle(document.documentElement).getPropertyValue("--component-color").trim()||"oklch(65.6% 0.241 354.308)",w=()=>getComputedStyle(document.documentElement).getPropertyValue("--text-edit-color").trim()||"oklch(62.3% 0.214 259.815)",E=(e,n,r="canvas")=>{const i=y();if(!i)return;const s=m(e),a="true"===e.contentEditable,l=document.documentElement.clientWidth||window.innerWidth,d=document.documentElement.clientHeight||window.innerHeight;i.setAttribute("width",l.toString()),i.setAttribute("height",d.toString()),s?i.classList.add("is-instance"):i.classList.remove("is-instance"),a?i.classList.add("is-text-edit"):i.classList.remove("is-text-edit");const c=i.querySelector(".highlight-frame-group");if(!c)return;const u=c.querySelector("rect");if(!u)return;s?u.setAttribute("stroke",f()):a?u.setAttribute("stroke",w()):u.removeAttribute("stroke");const h=(o()||document.body).querySelector(".highlight-frame-tools-wrapper"),p=h?.querySelector(".node-tools"),b=t(["zoom","current"],r)??1,v=g(e),{top:E,left:L,width:A,height:x}=v,S=Math.max(A,3),C=E+x;h&&(s?h.classList.add("is-instance"):h.classList.remove("is-instance"),a?h.classList.add("is-text-edit"):h.classList.remove("is-text-edit")),p&&(s?p.classList.add("is-instance"):p.classList.remove("is-instance"),a?p.classList.add("is-text-edit"):p.classList.remove("is-text-edit")),c.setAttribute("transform",`translate(${L}, ${E})`),u.setAttribute("width",S.toString()),u.setAttribute("height",x.toString());const k=c.querySelector(".handle-top-left"),N=c.querySelector(".handle-top-right"),q=c.querySelector(".handle-bottom-right"),M=c.querySelector(".handle-bottom-left");[k,N,q,M].forEach(e=>{e&&(s?e.setAttribute("stroke",f()):a?e.setAttribute("stroke",w()):e.removeAttribute("stroke"))}),k&&(k.setAttribute("x",(-3).toString()),k.setAttribute("y",(-3).toString())),N&&(N.setAttribute("x",(S-3).toString()),N.setAttribute("y",(-3).toString())),q&&(q.setAttribute("x",(S-3).toString()),q.setAttribute("y",(x-3).toString())),M&&(M.setAttribute("x",(-3).toString()),M.setAttribute("y",(x-3).toString())),h&&(h.style.transform=`translate(${L}px, ${C}px)`),b<=10?n.style.setProperty("--tool-opacity","1"):n.style.setProperty("--tool-opacity","0")},L=e=>{const t=y();if(!t)return;const n=e.classList.contains("hidden")||e.classList.contains("select-none")?"none":"";t.style.display=n;const r=(o()||document.body).querySelector(".highlight-frame-tools-wrapper");r&&(r.style.display=n)},A=e=>{const t=e=>{"Enter"===e.key&&(e.preventDefault(),e.stopPropagation(),(()=>{const e=window.getSelection();if(e&&e.rangeCount>0){const t=e.getRangeAt(0);t.deleteContents();const n=document.createElement("br");t.insertNode(n),t.setStartAfter(n),t.setEndAfter(n),e.removeAllRanges(),e.addRange(t)}})())};return e.addEventListener("keydown",t),()=>{e.removeEventListener("keydown",t)}},x=(e,t,o=!1)=>{if(!t.some(e=>"characterData"===e.type||"childList"===e.type&&(e.addedNodes.length>0||e.removedNodes.length>0))&&!o)return;const r=e.textContent??"",i=e.getAttribute("data-node-id");console.log("textContentChanged",r,o),n("textContentChanged",{nodeId:i,textContent:r,final:o})},S=(e,t,n="canvas")=>{let o=[],r=null,i=null;const s=()=>{null===r&&(r=requestAnimationFrame(()=>{i=requestAnimationFrame(()=>{(()=>{if(o.length>0){const t=[...o];o=[],x(e,t,!1)}})(),r=null,i=null})}))},a=((e,t)=>{const n=new MutationObserver(e=>{t(e)});return n.observe(e,{subtree:!0,childList:!0,characterData:!0}),n})(e,r=>{o.push(...r),s(),E(e,t,n)});return()=>{a.disconnect(),null!==r&&(cancelAnimationFrame(r),r=null),null!==i&&(cancelAnimationFrame(i),i=null),o=[]}},C=(e="canvas")=>{let n=null,o=!1,r=null;const i=()=>{if(o||!n)return;o=!0;const i=n;var s;x(i,[],!0),(s=i).contentEditable="false",s.classList.remove("is-editable"),s.style.outline="none",((e="canvas")=>{const n=t(["keyboard","disableTextEditMode"],e);n?.()})(e),r?.(),n=null,o=!1};return{enableEditMode:(o,s)=>{if(n===o)return;n&&n!==o&&i();const a=(e=>Array.from(e.childNodes).some(e=>e.nodeType===Node.TEXT_NODE&&e.textContent?.trim()))(o);a&&(n=o,(e=>{e.contentEditable="true",e.classList.add("is-editable"),e.style.outline="none"})(o),((e="canvas")=>{const n=t(["keyboard","enableTextEditMode"],e);n?.()})(e),r=((e,t,n,o="canvas")=>{if(!t)return()=>{};e.addEventListener("blur",n);const r=A(e),i=S(e,t,o);return()=>{e.removeEventListener("blur",n),r(),i?.()}})(o,s,i,e))},blurEditMode:i,getEditableNode:()=>n,isEditing:()=>null!==n}};const k=320,N=1680,q=[{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"}],M=(e,t,n)=>{const o=parseFloat(document.body.dataset.zoom||"1"),r=((e,t)=>{const n=e+Math.round(t);return Math.max(k,Math.min(N,n))})(n,(e.clientX-t)/o);return r},P=(e,t)=>{e.style.setProperty("--container-width",`${t}px`),((e,t)=>{e.querySelectorAll(".resize-preset-button").forEach((e,n)=>{n<q.length&&(q[n].rawValue===t?e.classList.add("is-active"):e.classList.remove("is-active"))})})(e,t)};e.createCanvasObserver=function(e="canvas"){const n=document.querySelector(".transform-layer");if(!n)return{disconnect:()=>{}};const o=new MutationObserver(()=>{((e="canvas")=>{const n=t(["zoom","current"],e)??1;document.body.style.setProperty("--zoom",n.toFixed(5)),document.body.style.setProperty("--stroke-width",(2/n).toFixed(3)),document.body.dataset.zoom=n.toFixed(5),document.body.dataset.strokeWidth=(2/n).toFixed(3)})(e);const n=window.nodeTools;n?.refreshHighlightFrame&&n.refreshHighlightFrame()});return o.observe(n,{attributes:!0,attributeOldValue:!0,subtree:!0,childList:!0}),{disconnect:function(){o.disconnect()}}},e.createNodeTools=(e,t="canvas")=>{const i=e;let s=null,a=null,l=null,d=null;const c=C(t),h=e=>{if(d!==e){if(c.isEditing()){const t=c.getEditableNode();t&&t!==e&&c.blurEditMode()}if(s?.disconnect(),a?.disconnect(),l?.disconnect(),e&&i){const o=()=>{if(!document.contains(e))return r(),d=null,s?.disconnect(),a?.disconnect(),l?.disconnect(),void n("selectedNodeChanged",null)};a=new MutationObserver(()=>{o(),document.contains(e)&&(E(e,i,t),L(e))}),a.observe(e,{attributes:!0,characterData:!0,childList:!0,subtree:!0});const c=e.parentElement;c&&(l=new MutationObserver(t=>{for(const n of t)if("childList"===n.type)for(const t of Array.from(n.removedNodes))if(t===e||t instanceof Node&&t.contains(e))return void o()}),l.observe(c,{childList:!0,subtree:!1})),s=((e,t)=>{const n=new ResizeObserver(e=>{t(e)});return n.observe(e),n})(e,()=>{o(),document.contains(e)&&(E(e,i,t),L(e))})}d=e,n("selectedNodeChanged",e?.getAttribute("data-node-id")??null),(e=>{if(!e)return;const t=y(),n=o(),r=n?.querySelector(".highlight-frame-tools-wrapper")||document.body.querySelector(".highlight-frame-tools-wrapper");t&&t.remove(),r&&r.remove();const i=m(e),s="true"===e.contentEditable,a=p(e,i,s);"true"===e.contentEditable&&a.classList.add("is-editable");const{left:l,top:d,height:c}=g(e),u=d+c,h=document.createElement("div");h.classList.add("highlight-frame-tools-wrapper"),i&&h.classList.add("is-instance"),s&&h.classList.add("is-text-edit"),h.style.position="absolute",h.style.transform=`translate(${l}px, ${u}px)`,h.style.transformOrigin="left center",h.style.pointerEvents="none",h.style.zIndex="500",v(e,h,i,s),n?n.appendChild(h):document.body.appendChild(h)})(e),e&&i&&(L(e),L(e))}},b=u(i,h,()=>{c.isEditing()&&c.blurEditMode(),d&&i&&(r(),d=null,s?.disconnect(),a?.disconnect(),l?.disconnect())},c),f={selectNode:h,getSelectedNode:()=>d,refreshHighlightFrame:()=>{d&&i&&(E(d,i,t),L(d))},clearSelectedNode:()=>{r(),d=null,s?.disconnect(),a?.disconnect(),l?.disconnect()},getEditableNode:()=>c.getEditableNode(),cleanup:()=>{b(),s?.disconnect(),a?.disconnect(),l?.disconnect(),c.blurEditMode(),r(),d=null,n("selectedNodeChanged",null)}};var w,A;return w="nodeTools",A=f,"undefined"!=typeof window&&(window[w]=A),f},e.createViewport=e=>{const t=o(),n=e.querySelector(".resize-handle");n&&n.remove();const r=(e=>{const t=document.createElement("div");return t.className="resize-handle",e.appendChild(t),t})(e);e.style.setProperty("--container-width","400px"),((e,t,n)=>{const o=document.createElement("div");o.className="resize-presets",q.forEach(e=>{const r=document.createElement("button");r.textContent=e.name,r.className="resize-preset-button",r.addEventListener("click",()=>{n(t,e.rawValue)}),o.appendChild(r)}),e.appendChild(o)})(r,e,P);let i=!1,s=0,a=0;const l=function(e){let t=null,n=null;const o=(...o)=>{n=o,null===t&&(t=requestAnimationFrame(()=>{n&&e(...n),t=null,n=null}))};return o.cleanup=()=>{null!==t&&(cancelAnimationFrame(t),t=null,n=null)},o}(n=>{if(!i)return;t&&(t.style.cursor="ew-resize");const o=M(n,s,a);P(e,o)}),d=((e,t,n,o,r)=>(e.addEventListener("mousedown",t),document.addEventListener("mousemove",n),document.addEventListener("mouseup",o),window.addEventListener("blur",r),()=>{e.removeEventListener("mousedown",t),document.removeEventListener("mousemove",n),document.removeEventListener("mouseup",o),window.removeEventListener("blur",r)}))(r,t=>{t.preventDefault(),t.stopPropagation(),i=!0,s=t.clientX,a=e.offsetWidth},l,e=>{e.preventDefault(),e.stopPropagation(),t&&(t.style.cursor="default"),i=!1},()=>{i=!1});return{setWidth:t=>{P(e,t)},cleanup:()=>{i=!1,l?.cleanup(),d(),r.remove()}}}});
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).MarkupCanvas={})}(this,function(e){"use strict";const t=(e,t="canvas")=>{const n=window[t];return e.reduce((e,t)=>e?.[t],n)};function n(e,t){window.parent.postMessage({source:"node-edit-utils",action:e,data:t,timestamp:Date.now()},"*")}const o=()=>document.querySelector(".canvas-container"),r=()=>{const e=o()||document.body,t=e.querySelector(".highlight-frame-overlay");t&&t.remove();const n=e.querySelector(".highlight-frame-tools-wrapper");n&&n.remove()},s=(e,t,n)=>{e&&t&&n.enableEditMode(e,t)},i=["path","rect","circle","ellipse","polygon","line","polyline","text","text-noci"];let a=[],d=0,l=null;const c=(e,t,n)=>{let o=null;const r=e.clientX,c=e.clientY,u=e.metaKey||e.ctrlKey,m=((e,t)=>{const n=document.elementsFromPoint(e,t);return Array.from(n).reduce((e,t)=>e.found?e:"node-provider"===t.getAttribute("data-role")?(e.found=!0,e):(e.elements.push(t),e),{elements:[],found:!1}).elements})(r,c).filter(e=>!i.includes(e.tagName.toLowerCase())&&!e.classList.contains("select-none")&&!(e=>{let t=e.parentElement;for(;t;){if("true"===t.getAttribute("data-instance"))return!0;if("node-provider"===t.getAttribute("data-role"))break;t=t.parentElement}return!1})(e)),h=n.getEditableNode();if(h&&m.includes(h))return o=h,l=o,o;if(u)return a=[],o=m[0],l&&l===o&&s(o,t,n),l=o,o;var g,p;p=m,(g=a).length===p.length&&g.every((e,t)=>e===p[t])?d<=m.length-2&&d++:d=0;return o=m[m.length-1-d],a=m,l&&l===o&&s(o,t,n),l=o,o},u=(e,t,n,o)=>{const s=e=>{((e,t)=>{if("application"===e.data.source&&"selectedNodeChanged"===e.data.action){const o=e.data.data,r=document.querySelector(`[data-node-id="${o}"]`);if(n=r,n?.classList.contains("select-none"))return void t?.(null);r&&t?.(r)}var n})(e,t)},i=n=>{((e,t,n,o)=>{if(e.preventDefault(),e.stopPropagation(),t&&!t.contains(e.target))return r(),void o(null);o(c(e,t,n))})(n,e,o,t)},a=e=>{"Escape"===e.key&&(e.preventDefault(),e.stopPropagation(),n?.())};return window.addEventListener("message",s),document.addEventListener("click",i),document.addEventListener("keydown",a),()=>{window.removeEventListener("message",s),document.removeEventListener("click",i),document.removeEventListener("keydown",a)}},m=e=>"true"===e.getAttribute("data-instance"),h=(e,t,n,o,r=!1,s=!1)=>{const i=document.createElementNS("http://www.w3.org/2000/svg","rect");return i.setAttribute("x",(t-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)"),e.appendChild(i),i};function g(e){const t=e.getBoundingClientRect();return{top:t.top,left:t.left,width:t.width,height:t.height}}const p=(e,t=!1,n=!1)=>{const{top:r,left:s,width:i,height:a}=g(e),d=Math.max(i,3),l=document.createElementNS("http://www.w3.org/2000/svg","svg");l.classList.add("highlight-frame-overlay"),t&&l.classList.add("is-instance"),n&&l.classList.add("is-text-edit"),l.setAttribute("data-node-id",e.getAttribute("data-node-id")||""),l.style.position="absolute",l.style.top="0",l.style.left="0",l.style.width="100vw",l.style.height="100vh",l.style.pointerEvents="none",l.style.zIndex="500";const c=document.documentElement.clientWidth||window.innerWidth,u=document.documentElement.clientHeight||window.innerHeight;l.setAttribute("width",c.toString()),l.setAttribute("height",u.toString());const m=document.createElementNS("http://www.w3.org/2000/svg","g");m.classList.add("highlight-frame-group"),m.setAttribute("transform",`translate(${s}, ${r})`);const p=document.createElementNS("http://www.w3.org/2000/svg","rect");p.setAttribute("x","0"),p.setAttribute("y","0"),p.setAttribute("width",d.toString()),p.setAttribute("height",a.toString()),p.setAttribute("vector-effect","non-scaling-stroke"),p.classList.add("highlight-frame-rect"),t?p.setAttribute("stroke",getComputedStyle(document.documentElement).getPropertyValue("--component-color").trim()||"oklch(65.6% 0.241 354.308)"):n&&p.setAttribute("stroke",getComputedStyle(document.documentElement).getPropertyValue("--text-edit-color").trim()||"oklch(62.3% 0.214 259.815)"),m.appendChild(p),((e,t,n,o=!1,r=!1)=>{h(e,0,0,"handle-top-left",o,r),h(e,t,0,"handle-top-right",o,r),h(e,t,n,"handle-bottom-right",o,r),h(e,0,n,"handle-bottom-left",o,r)})(m,d,a,t,n),l.appendChild(m);const v=o();return v?v.appendChild(l):document.body.appendChild(l),l},v={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"},b=(e,t,n=!1,o=!1)=>{const r=document.createElement("div");r.className="node-tools",n&&r.classList.add("is-instance"),o&&r.classList.add("is-text-edit"),t.appendChild(r),((e,t)=>{const n=document.createElement("div");n.className="tag-label";const o=e.getAttribute("data-instance-name"),r=e.tagName.toLowerCase(),s=o||v[r]||r;var i;n.textContent=(i=s)?i.charAt(0).toUpperCase()+i.slice(1):i,t.appendChild(n)})(e,r)};function y(){return(o()||document.body).querySelector(".highlight-frame-overlay")}const f=()=>getComputedStyle(document.documentElement).getPropertyValue("--component-color").trim()||"oklch(65.6% 0.241 354.308)",w=()=>getComputedStyle(document.documentElement).getPropertyValue("--text-edit-color").trim()||"oklch(62.3% 0.214 259.815)",E=(e,n,r="canvas")=>{const s=y();if(!s)return;const i=m(e),a="true"===e.contentEditable,d=document.documentElement.clientWidth||window.innerWidth,l=document.documentElement.clientHeight||window.innerHeight;s.setAttribute("width",d.toString()),s.setAttribute("height",l.toString()),i?s.classList.add("is-instance"):s.classList.remove("is-instance"),a?s.classList.add("is-text-edit"):s.classList.remove("is-text-edit");const c=s.querySelector(".highlight-frame-group");if(!c)return;const u=c.querySelector("rect");if(!u)return;i?u.setAttribute("stroke",f()):a?u.setAttribute("stroke",w()):u.removeAttribute("stroke");const h=(o()||document.body).querySelector(".highlight-frame-tools-wrapper"),p=h?.querySelector(".node-tools"),v=t(["zoom","current"],r)??1,b=g(e),{top:E,left:L,width:A,height:x}=b,S=Math.max(A,3),C=E+x;h&&(i?h.classList.add("is-instance"):h.classList.remove("is-instance"),a?h.classList.add("is-text-edit"):h.classList.remove("is-text-edit")),p&&(i?p.classList.add("is-instance"):p.classList.remove("is-instance"),a?p.classList.add("is-text-edit"):p.classList.remove("is-text-edit")),c.setAttribute("transform",`translate(${L}, ${E})`),u.setAttribute("width",S.toString()),u.setAttribute("height",x.toString());const k=c.querySelector(".handle-top-left"),N=c.querySelector(".handle-top-right"),q=c.querySelector(".handle-bottom-right"),M=c.querySelector(".handle-bottom-left");[k,N,q,M].forEach(e=>{e&&(i?e.setAttribute("stroke",f()):a?e.setAttribute("stroke",w()):e.removeAttribute("stroke"))}),k&&(k.setAttribute("x",(-3).toString()),k.setAttribute("y",(-3).toString())),N&&(N.setAttribute("x",(S-3).toString()),N.setAttribute("y",(-3).toString())),q&&(q.setAttribute("x",(S-3).toString()),q.setAttribute("y",(x-3).toString())),M&&(M.setAttribute("x",(-3).toString()),M.setAttribute("y",(x-3).toString())),h&&(h.style.transform=`translate(${L}px, ${C}px)`),v<=10?n.style.setProperty("--tool-opacity","1"):n.style.setProperty("--tool-opacity","0")},L=e=>{const t=y();if(!t)return;const n=e.classList.contains("hidden")||e.classList.contains("select-none")?"none":"";t.style.display=n;const r=(o()||document.body).querySelector(".highlight-frame-tools-wrapper");r&&(r.style.display=n)},A=e=>{const t=e=>{"Enter"===e.key&&(e.preventDefault(),e.stopPropagation(),(()=>{const e=window.getSelection();if(e&&e.rangeCount>0){const t=e.getRangeAt(0);t.deleteContents();const n=document.createElement("br");t.insertNode(n),t.setStartAfter(n),t.setEndAfter(n),e.removeAllRanges(),e.addRange(t)}})())};return e.addEventListener("keydown",t),()=>{e.removeEventListener("keydown",t)}},x=(e,t,o=!1)=>{if(!t.some(e=>"characterData"===e.type||"childList"===e.type&&(e.addedNodes.length>0||e.removedNodes.length>0))&&!o)return;const r=e.textContent??"",s=e.getAttribute("data-node-id");console.log("textContentChanged",r,o),n("textContentChanged",{nodeId:s,textContent:r,final:o})},S=(e,t,n="canvas")=>{let o=[],r=null,s=null;const i=()=>{null===r&&(r=requestAnimationFrame(()=>{s=requestAnimationFrame(()=>{(()=>{if(o.length>0){const t=[...o];o=[],x(e,t,!1)}})(),r=null,s=null})}))},a=((e,t)=>{const n=new MutationObserver(e=>{t(e)});return n.observe(e,{subtree:!0,childList:!0,characterData:!0}),n})(e,r=>{o.push(...r),i(),E(e,t,n)});return()=>{a.disconnect(),null!==r&&(cancelAnimationFrame(r),r=null),null!==s&&(cancelAnimationFrame(s),s=null),o=[]}},C=(e="canvas")=>{let n=null,o=!1,r=null;const s=()=>{if(o||!n)return;o=!0;const s=n;var i;x(s,[],!0),(i=s).contentEditable="false",i.classList.remove("is-editable"),i.style.outline="none",((e="canvas")=>{const n=t(["keyboard","disableTextEditMode"],e);n?.()})(e),r?.(),n=null,o=!1};return{enableEditMode:(o,i)=>{if(n===o)return;n&&n!==o&&s();const a=(e=>Array.from(e.childNodes).some(e=>e.nodeType===Node.TEXT_NODE&&e.textContent?.trim()))(o);a&&(n=o,(e=>{e.contentEditable="true",e.classList.add("is-editable"),e.style.outline="none"})(o),((e="canvas")=>{const n=t(["keyboard","enableTextEditMode"],e);n?.()})(e),r=((e,t,n,o="canvas")=>{if(!t)return()=>{};e.addEventListener("blur",n);const r=A(e),s=S(e,t,o);return()=>{e.removeEventListener("blur",n),r(),s?.()}})(o,i,s,e))},blurEditMode:s,getEditableNode:()=>n,isEditing:()=>null!==n}},k=320,N=1680,q=[{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"}],M=(e,t,n)=>{const o=parseFloat(document.body.dataset.zoom||"1"),r=((e,t)=>{const n=e+Math.round(t);return Math.max(k,Math.min(N,n))})(n,(e.clientX-t)/o);return r},P=(e,t)=>{e.style.setProperty("--container-width",`${t}px`),((e,t)=>{e.querySelectorAll(".resize-preset-button").forEach((e,n)=>{n<q.length&&(q[n].rawValue===t?e.classList.add("is-active"):e.classList.remove("is-active"))})})(e,t)};e.createCanvasObserver=function(e="canvas"){const n=document.querySelector(".transform-layer");if(!n)return{disconnect:()=>{}};const o=new MutationObserver(()=>{((e="canvas")=>{const n=t(["zoom","current"],e)??1;document.body.style.setProperty("--zoom",n.toFixed(5)),document.body.style.setProperty("--stroke-width",(2/n).toFixed(3)),document.body.dataset.zoom=n.toFixed(5),document.body.dataset.strokeWidth=(2/n).toFixed(3)})(e);const n=window.nodeTools;n?.refreshHighlightFrame&&n.refreshHighlightFrame()});return o.observe(n,{attributes:!0,attributeOldValue:!0,subtree:!0,childList:!0}),{disconnect:function(){o.disconnect()}}},e.createNodeTools=(e,t="canvas")=>{const s=e;let i=null,a=null,d=null,l=null;const c=C(t),h=e=>{if(l!==e){if(c.isEditing()){const t=c.getEditableNode();t&&t!==e&&c.blurEditMode()}if(i?.disconnect(),a?.disconnect(),d?.disconnect(),e&&s){const o=()=>{if(!document.contains(e))return r(),l=null,i?.disconnect(),a?.disconnect(),d?.disconnect(),void n("selectedNodeChanged",null)};a=new MutationObserver(()=>{o(),document.contains(e)&&(E(e,s,t),L(e))}),a.observe(e,{attributes:!0,characterData:!0,childList:!0,subtree:!0});const c=e.parentElement;c&&(d=new MutationObserver(t=>{for(const n of t)if("childList"===n.type)for(const t of Array.from(n.removedNodes))if(t===e||t instanceof Node&&t.contains(e))return void o()}),d.observe(c,{childList:!0,subtree:!1})),i=((e,t)=>{const n=new ResizeObserver(e=>{t(e)});return n.observe(e),n})(e,()=>{o(),document.contains(e)&&(E(e,s,t),L(e))})}l=e,n("selectedNodeChanged",e?.getAttribute("data-node-id")??null),(e=>{if(!e)return;const t=y(),n=o(),r=n?.querySelector(".highlight-frame-tools-wrapper")||document.body.querySelector(".highlight-frame-tools-wrapper");t&&t.remove(),r&&r.remove();const s=m(e),i="true"===e.contentEditable,a=p(e,s,i);"true"===e.contentEditable&&a.classList.add("is-editable");const{left:d,top:l,height:c}=g(e),u=l+c,h=document.createElement("div");h.classList.add("highlight-frame-tools-wrapper"),s&&h.classList.add("is-instance"),i&&h.classList.add("is-text-edit"),h.style.position="absolute",h.style.transform=`translate(${d}px, ${u}px)`,h.style.transformOrigin="left center",h.style.pointerEvents="none",h.style.zIndex="500",b(e,h,s,i),n?n.appendChild(h):document.body.appendChild(h)})(e),e&&s&&(L(e),L(e))}},v=u(s,h,()=>{c.isEditing()&&c.blurEditMode(),l&&s&&(r(),l=null,i?.disconnect(),a?.disconnect(),d?.disconnect())},c),f={selectNode:h,getSelectedNode:()=>l,refreshHighlightFrame:()=>{l&&s&&(E(l,s,t),L(l))},clearSelectedNode:()=>{r(),l=null,i?.disconnect(),a?.disconnect(),d?.disconnect()},getEditableNode:()=>c.getEditableNode(),cleanup:()=>{v(),i?.disconnect(),a?.disconnect(),d?.disconnect(),c.blurEditMode(),r(),l=null,n("selectedNodeChanged",null)}};var w,A;return w="nodeTools",A=f,"undefined"!=typeof window&&(window[w]=A),f},e.createViewport=(e,t)=>{const n=o(),r=e.querySelector(".resize-handle");r&&r.remove();const s=(e=>{const t=document.createElement("div");return t.className="resize-handle",e.appendChild(t),t})(e),i=t??400;e.style.setProperty("--container-width",`${i}px`),((e,t,n)=>{const o=document.createElement("div");o.className="resize-presets",q.forEach(e=>{const r=document.createElement("button");r.textContent=e.name,r.className="resize-preset-button",r.addEventListener("click",()=>{n(t,e.rawValue)}),o.appendChild(r)}),e.appendChild(o)})(s,e,P);let a=!1,d=0,l=0;const c=((e,t,n,o,r)=>{const s=e=>{e.relatedTarget||e.target!==document&&e.target!==document.documentElement||r()};return e.addEventListener("mousedown",t),document.addEventListener("mousemove",n),document.addEventListener("mouseup",o),document.addEventListener("mouseleave",s),window.addEventListener("blur",r),()=>{e.removeEventListener("mousedown",t),document.removeEventListener("mousemove",n),document.removeEventListener("mouseup",o),document.removeEventListener("mouseleave",s),window.removeEventListener("blur",r)}})(s,t=>{t.preventDefault(),t.stopPropagation(),a=!0,d=t.clientX,l=e.offsetWidth},t=>{if(!a)return;n&&(n.style.cursor="ew-resize");const o=M(t,d,l);P(e,o)},e=>{e.preventDefault(),e.stopPropagation(),n&&(n.style.cursor="default"),a=!1},()=>{n&&(n.style.cursor="default"),a=!1});return{setWidth:t=>{P(e,t)},cleanup:()=>{a=!1,c(),s.remove()}}}});
|
package/package.json
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { getCanvasContainer } from "../canvas/helpers/getCanvasContainer";
|
|
2
|
-
import { withRAFThrottle } from "../helpers";
|
|
3
2
|
import { DEFAULT_WIDTH } from "./constants";
|
|
4
3
|
import { setupEventListener } from "./events/setupEventListener";
|
|
5
4
|
import { createResizeHandle } from "./resize/createResizeHandle";
|
|
@@ -8,7 +7,7 @@ import type { Viewport } from "./types";
|
|
|
8
7
|
import { calcWidth } from "./width/calcWidth";
|
|
9
8
|
import { updateWidth } from "./width/updateWidth";
|
|
10
9
|
|
|
11
|
-
export const createViewport = (container: HTMLElement): Viewport => {
|
|
10
|
+
export const createViewport = (container: HTMLElement, initialWidth?: number): Viewport => {
|
|
12
11
|
const canvas: HTMLElement | null = getCanvasContainer();
|
|
13
12
|
|
|
14
13
|
// Remove any existing resize handle to prevent duplicates
|
|
@@ -18,7 +17,8 @@ export const createViewport = (container: HTMLElement): Viewport => {
|
|
|
18
17
|
}
|
|
19
18
|
|
|
20
19
|
const resizeHandle = createResizeHandle(container);
|
|
21
|
-
|
|
20
|
+
const width = initialWidth ?? DEFAULT_WIDTH;
|
|
21
|
+
container.style.setProperty("--container-width", `${width}px`);
|
|
22
22
|
|
|
23
23
|
createResizePresets(resizeHandle, container, updateWidth);
|
|
24
24
|
|
|
@@ -46,8 +46,6 @@ export const createViewport = (container: HTMLElement): Viewport => {
|
|
|
46
46
|
updateWidth(container, width);
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
-
const throttledHandleResize = withRAFThrottle(handleResize);
|
|
50
|
-
|
|
51
49
|
const stopResize = (event: MouseEvent): void => {
|
|
52
50
|
event.preventDefault();
|
|
53
51
|
event.stopPropagation();
|
|
@@ -60,14 +58,17 @@ export const createViewport = (container: HTMLElement): Viewport => {
|
|
|
60
58
|
};
|
|
61
59
|
|
|
62
60
|
const blurResize = (): void => {
|
|
61
|
+
if (canvas) {
|
|
62
|
+
canvas.style.cursor = "default";
|
|
63
|
+
}
|
|
64
|
+
|
|
63
65
|
isDragging = false;
|
|
64
66
|
};
|
|
65
67
|
|
|
66
|
-
const removeListeners = setupEventListener(resizeHandle, startResize,
|
|
68
|
+
const removeListeners = setupEventListener(resizeHandle, startResize, handleResize, stopResize, blurResize);
|
|
67
69
|
|
|
68
70
|
const cleanup = (): void => {
|
|
69
71
|
isDragging = false;
|
|
70
|
-
throttledHandleResize?.cleanup();
|
|
71
72
|
removeListeners();
|
|
72
73
|
resizeHandle.remove();
|
|
73
74
|
};
|
|
@@ -5,9 +5,17 @@ export const setupEventListener = (
|
|
|
5
5
|
stopResize: (event: MouseEvent) => void,
|
|
6
6
|
blurResize: () => void
|
|
7
7
|
): (() => void) => {
|
|
8
|
+
const handleMouseLeave = (event: MouseEvent): void => {
|
|
9
|
+
// Check if mouse is leaving the window/document
|
|
10
|
+
if (!event.relatedTarget && (event.target === document || event.target === document.documentElement)) {
|
|
11
|
+
blurResize();
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
|
|
8
15
|
resizeHandle.addEventListener("mousedown", startResize);
|
|
9
16
|
document.addEventListener("mousemove", handleResize);
|
|
10
17
|
document.addEventListener("mouseup", stopResize);
|
|
18
|
+
document.addEventListener("mouseleave", handleMouseLeave);
|
|
11
19
|
|
|
12
20
|
window.addEventListener("blur", blurResize);
|
|
13
21
|
|
|
@@ -15,6 +23,7 @@ export const setupEventListener = (
|
|
|
15
23
|
resizeHandle.removeEventListener("mousedown", startResize);
|
|
16
24
|
document.removeEventListener("mousemove", handleResize);
|
|
17
25
|
document.removeEventListener("mouseup", stopResize);
|
|
26
|
+
document.removeEventListener("mouseleave", handleMouseLeave);
|
|
18
27
|
window.removeEventListener("blur", blurResize);
|
|
19
28
|
};
|
|
20
29
|
};
|