@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.
@@ -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.0
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
- container.style.setProperty("--container-width", `${DEFAULT_WIDTH}px`);
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, throttledHandleResize, stopResize, blurResize);
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.0
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
- container.style.setProperty("--container-width", `${DEFAULT_WIDTH}px`);
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, throttledHandleResize, stopResize, blurResize);
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.0
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
- container.style.setProperty("--container-width", `${DEFAULT_WIDTH}px`);
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, throttledHandleResize, stopResize, blurResize);
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,6 +1,6 @@
1
1
  {
2
2
  "name": "@node-edit-utils/core",
3
- "version": "2.3.0",
3
+ "version": "2.3.1",
4
4
  "description": "Utilities for editing nodes in a dom tree.",
5
5
  "type": "module",
6
6
  "main": "dist/node-edit-utils.cjs.js",
@@ -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
- container.style.setProperty("--container-width", `${DEFAULT_WIDTH}px`);
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, throttledHandleResize, stopResize, blurResize);
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
  };