@node-edit-utils/core 2.2.9 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/node-tools/text/helpers/handleTextChange.d.ts +1 -1
- package/dist/node-edit-utils.cjs.js +8 -5
- package/dist/node-edit-utils.esm.js +8 -5
- package/dist/node-edit-utils.umd.js +8 -5
- package/dist/node-edit-utils.umd.min.js +1 -1
- package/package.json +1 -1
- package/src/lib/node-tools/text/events/setupMutationObserver.ts +1 -1
- package/src/lib/node-tools/text/helpers/handleTextChange.ts +4 -3
- package/src/lib/node-tools/text/nodeText.ts +4 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const handleTextChange: (node: HTMLElement, mutations: MutationRecord[]) => void;
|
|
1
|
+
export declare const handleTextChange: (node: HTMLElement, mutations: MutationRecord[], final?: boolean) => void;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Markup Canvas
|
|
3
3
|
* High-performance markup canvas with zoom and pan capabilities
|
|
4
|
-
* @version 2.
|
|
4
|
+
* @version 2.3.0
|
|
5
5
|
*/
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
@@ -645,24 +645,25 @@ const connectMutationObserver = (element, handler) => {
|
|
|
645
645
|
return mutationObserver;
|
|
646
646
|
};
|
|
647
647
|
|
|
648
|
-
const handleTextChange = (node, mutations) => {
|
|
648
|
+
const handleTextChange = (node, mutations, final = false) => {
|
|
649
649
|
// Check if any mutation is a text content change
|
|
650
650
|
const hasTextChange = mutations.some((mutation) => {
|
|
651
651
|
return (mutation.type === "characterData" ||
|
|
652
652
|
(mutation.type === "childList" && (mutation.addedNodes.length > 0 || mutation.removedNodes.length > 0)));
|
|
653
653
|
});
|
|
654
|
-
if (!hasTextChange) {
|
|
654
|
+
if (!hasTextChange && !final) {
|
|
655
655
|
return;
|
|
656
656
|
}
|
|
657
657
|
// Get the text content of the node
|
|
658
658
|
const textContent = node.textContent ?? "";
|
|
659
659
|
// Get the node ID
|
|
660
660
|
const nodeId = node.getAttribute("data-node-id");
|
|
661
|
-
console.log("textContentChanged",
|
|
661
|
+
console.log("textContentChanged", textContent, final);
|
|
662
662
|
// Send postMessage with the text change
|
|
663
663
|
sendPostMessage("textContentChanged", {
|
|
664
664
|
nodeId,
|
|
665
665
|
textContent,
|
|
666
|
+
final,
|
|
666
667
|
});
|
|
667
668
|
};
|
|
668
669
|
|
|
@@ -675,7 +676,7 @@ const setupMutationObserver = (node, nodeProvider, canvasName = "canvas") => {
|
|
|
675
676
|
if (pendingMutations.length > 0) {
|
|
676
677
|
const mutationsToProcess = [...pendingMutations];
|
|
677
678
|
pendingMutations = [];
|
|
678
|
-
handleTextChange(node, mutationsToProcess);
|
|
679
|
+
handleTextChange(node, mutationsToProcess, false);
|
|
679
680
|
}
|
|
680
681
|
};
|
|
681
682
|
const scheduleProcess = () => {
|
|
@@ -775,6 +776,8 @@ const nodeText = (canvasName = "canvas") => {
|
|
|
775
776
|
}
|
|
776
777
|
blurInProgress = true;
|
|
777
778
|
const nodeToCleanup = editableNode;
|
|
779
|
+
// Send final textContentChanged message before cleanup
|
|
780
|
+
handleTextChange(nodeToCleanup, [], true);
|
|
778
781
|
makeNodeNonEditable(nodeToCleanup);
|
|
779
782
|
disableCanvasTextMode(canvasName);
|
|
780
783
|
cleanup?.();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Markup Canvas
|
|
3
3
|
* High-performance markup canvas with zoom and pan capabilities
|
|
4
|
-
* @version 2.
|
|
4
|
+
* @version 2.3.0
|
|
5
5
|
*/
|
|
6
6
|
const getCanvasWindowValue = (path, canvasName = "canvas") => {
|
|
7
7
|
// biome-ignore lint/suspicious/noExplicitAny: global window extension
|
|
@@ -643,24 +643,25 @@ const connectMutationObserver = (element, handler) => {
|
|
|
643
643
|
return mutationObserver;
|
|
644
644
|
};
|
|
645
645
|
|
|
646
|
-
const handleTextChange = (node, mutations) => {
|
|
646
|
+
const handleTextChange = (node, mutations, final = false) => {
|
|
647
647
|
// Check if any mutation is a text content change
|
|
648
648
|
const hasTextChange = mutations.some((mutation) => {
|
|
649
649
|
return (mutation.type === "characterData" ||
|
|
650
650
|
(mutation.type === "childList" && (mutation.addedNodes.length > 0 || mutation.removedNodes.length > 0)));
|
|
651
651
|
});
|
|
652
|
-
if (!hasTextChange) {
|
|
652
|
+
if (!hasTextChange && !final) {
|
|
653
653
|
return;
|
|
654
654
|
}
|
|
655
655
|
// Get the text content of the node
|
|
656
656
|
const textContent = node.textContent ?? "";
|
|
657
657
|
// Get the node ID
|
|
658
658
|
const nodeId = node.getAttribute("data-node-id");
|
|
659
|
-
console.log("textContentChanged",
|
|
659
|
+
console.log("textContentChanged", textContent, final);
|
|
660
660
|
// Send postMessage with the text change
|
|
661
661
|
sendPostMessage("textContentChanged", {
|
|
662
662
|
nodeId,
|
|
663
663
|
textContent,
|
|
664
|
+
final,
|
|
664
665
|
});
|
|
665
666
|
};
|
|
666
667
|
|
|
@@ -673,7 +674,7 @@ const setupMutationObserver = (node, nodeProvider, canvasName = "canvas") => {
|
|
|
673
674
|
if (pendingMutations.length > 0) {
|
|
674
675
|
const mutationsToProcess = [...pendingMutations];
|
|
675
676
|
pendingMutations = [];
|
|
676
|
-
handleTextChange(node, mutationsToProcess);
|
|
677
|
+
handleTextChange(node, mutationsToProcess, false);
|
|
677
678
|
}
|
|
678
679
|
};
|
|
679
680
|
const scheduleProcess = () => {
|
|
@@ -773,6 +774,8 @@ const nodeText = (canvasName = "canvas") => {
|
|
|
773
774
|
}
|
|
774
775
|
blurInProgress = true;
|
|
775
776
|
const nodeToCleanup = editableNode;
|
|
777
|
+
// Send final textContentChanged message before cleanup
|
|
778
|
+
handleTextChange(nodeToCleanup, [], true);
|
|
776
779
|
makeNodeNonEditable(nodeToCleanup);
|
|
777
780
|
disableCanvasTextMode(canvasName);
|
|
778
781
|
cleanup?.();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Markup Canvas
|
|
3
3
|
* High-performance markup canvas with zoom and pan capabilities
|
|
4
|
-
* @version 2.
|
|
4
|
+
* @version 2.3.0
|
|
5
5
|
*/
|
|
6
6
|
(function (global, factory) {
|
|
7
7
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
@@ -649,24 +649,25 @@
|
|
|
649
649
|
return mutationObserver;
|
|
650
650
|
};
|
|
651
651
|
|
|
652
|
-
const handleTextChange = (node, mutations) => {
|
|
652
|
+
const handleTextChange = (node, mutations, final = false) => {
|
|
653
653
|
// Check if any mutation is a text content change
|
|
654
654
|
const hasTextChange = mutations.some((mutation) => {
|
|
655
655
|
return (mutation.type === "characterData" ||
|
|
656
656
|
(mutation.type === "childList" && (mutation.addedNodes.length > 0 || mutation.removedNodes.length > 0)));
|
|
657
657
|
});
|
|
658
|
-
if (!hasTextChange) {
|
|
658
|
+
if (!hasTextChange && !final) {
|
|
659
659
|
return;
|
|
660
660
|
}
|
|
661
661
|
// Get the text content of the node
|
|
662
662
|
const textContent = node.textContent ?? "";
|
|
663
663
|
// Get the node ID
|
|
664
664
|
const nodeId = node.getAttribute("data-node-id");
|
|
665
|
-
console.log("textContentChanged",
|
|
665
|
+
console.log("textContentChanged", textContent, final);
|
|
666
666
|
// Send postMessage with the text change
|
|
667
667
|
sendPostMessage("textContentChanged", {
|
|
668
668
|
nodeId,
|
|
669
669
|
textContent,
|
|
670
|
+
final,
|
|
670
671
|
});
|
|
671
672
|
};
|
|
672
673
|
|
|
@@ -679,7 +680,7 @@
|
|
|
679
680
|
if (pendingMutations.length > 0) {
|
|
680
681
|
const mutationsToProcess = [...pendingMutations];
|
|
681
682
|
pendingMutations = [];
|
|
682
|
-
handleTextChange(node, mutationsToProcess);
|
|
683
|
+
handleTextChange(node, mutationsToProcess, false);
|
|
683
684
|
}
|
|
684
685
|
};
|
|
685
686
|
const scheduleProcess = () => {
|
|
@@ -779,6 +780,8 @@
|
|
|
779
780
|
}
|
|
780
781
|
blurInProgress = true;
|
|
781
782
|
const nodeToCleanup = editableNode;
|
|
783
|
+
// Send final textContentChanged message before cleanup
|
|
784
|
+
handleTextChange(nodeToCleanup, [], true);
|
|
782
785
|
makeNodeNonEditable(nodeToCleanup);
|
|
783
786
|
disableCanvasTextMode(canvasName);
|
|
784
787
|
cleanup?.();
|
|
@@ -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="canvas")=>{let r=[],i=null,s=null;const a=()=>{if(r.length>0){const t=[...r];r=[],((e,t)=>{if(!t.some(e=>"characterData"===e.type||"childList"===e.type&&(e.addedNodes.length>0||e.removedNodes.length>0)))return;const o=e.textContent??"",r=e.getAttribute("data-node-id");console.log("textContentChanged",r,o),n("textContentChanged",{nodeId:r,textContent:o})})(e,t)}},l=((e,t)=>{const n=new MutationObserver(e=>{t(e)});return n.observe(e,{subtree:!0,childList:!0,characterData:!0}),n})(e,n=>{r.push(...n),null===i&&(i=requestAnimationFrame(()=>{s=requestAnimationFrame(()=>{a(),i=null,s=null})})),E(e,t,o)});return()=>{l.disconnect(),null!==i&&(cancelAnimationFrame(i),i=null),null!==s&&(cancelAnimationFrame(s),s=null),r=[]}},S=(e="canvas")=>{let n=null,o=!1,r=null;const i=()=>{if(o||!n)return;o=!0;var i;(i=n).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,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=x(e,t,o);return()=>{e.removeEventListener("blur",n),r(),i?.()}})(o,s,i,e))},blurEditMode:i,getEditableNode:()=>n,isEditing:()=>null!==n}};const C=320,k=1680,N=[{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"}],q=(e,t,n)=>{const o=parseFloat(document.body.dataset.zoom||"1"),r=((e,t)=>{const n=e+Math.round(t);return Math.max(C,Math.min(k,n))})(n,(e.clientX-t)/o);return r},M=(e,t)=>{e.style.setProperty("--container-width",`${t}px`),((e,t)=>{e.querySelectorAll(".resize-preset-button").forEach((e,n)=>{n<N.length&&(N[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=S(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",N.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,M);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=q(n,s,a);M(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=>{M(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()},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()}}}});
|
package/package.json
CHANGED
|
@@ -16,7 +16,7 @@ export const setupMutationObserver = (
|
|
|
16
16
|
if (pendingMutations.length > 0) {
|
|
17
17
|
const mutationsToProcess = [...pendingMutations];
|
|
18
18
|
pendingMutations = [];
|
|
19
|
-
handleTextChange(node, mutationsToProcess);
|
|
19
|
+
handleTextChange(node, mutationsToProcess, false);
|
|
20
20
|
}
|
|
21
21
|
};
|
|
22
22
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { sendPostMessage } from "@/lib/post-message/sendPostMessage";
|
|
2
2
|
|
|
3
|
-
export const handleTextChange = (node: HTMLElement, mutations: MutationRecord[]): void => {
|
|
3
|
+
export const handleTextChange = (node: HTMLElement, mutations: MutationRecord[], final: boolean = false): void => {
|
|
4
4
|
// Check if any mutation is a text content change
|
|
5
5
|
const hasTextChange = mutations.some((mutation) => {
|
|
6
6
|
return (
|
|
@@ -9,7 +9,7 @@ export const handleTextChange = (node: HTMLElement, mutations: MutationRecord[])
|
|
|
9
9
|
);
|
|
10
10
|
});
|
|
11
11
|
|
|
12
|
-
if (!hasTextChange) {
|
|
12
|
+
if (!hasTextChange && !final) {
|
|
13
13
|
return;
|
|
14
14
|
}
|
|
15
15
|
|
|
@@ -19,11 +19,12 @@ export const handleTextChange = (node: HTMLElement, mutations: MutationRecord[])
|
|
|
19
19
|
// Get the node ID
|
|
20
20
|
const nodeId = node.getAttribute("data-node-id");
|
|
21
21
|
|
|
22
|
-
console.log("textContentChanged",
|
|
22
|
+
console.log("textContentChanged", textContent, final);
|
|
23
23
|
|
|
24
24
|
// Send postMessage with the text change
|
|
25
25
|
sendPostMessage("textContentChanged", {
|
|
26
26
|
nodeId,
|
|
27
27
|
textContent,
|
|
28
|
+
final,
|
|
28
29
|
});
|
|
29
30
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { disableCanvasTextMode } from "@/lib/canvas/disableCanvasTextMode";
|
|
2
2
|
import { enableCanvasTextMode } from "@/lib/canvas/enableCanvasTextMode";
|
|
3
3
|
import { setupNodeListeners } from "./events/setupNodeListeners";
|
|
4
|
+
import { handleTextChange } from "./helpers/handleTextChange";
|
|
4
5
|
import { hasTextContent } from "./helpers/hasTextContent";
|
|
5
6
|
import { makeNodeEditable } from "./helpers/makeNodeEditable";
|
|
6
7
|
import { makeNodeNonEditable } from "./helpers/makeNodeNonEditable";
|
|
@@ -49,6 +50,9 @@ export const nodeText = (canvasName: string = "canvas"): NodeText => {
|
|
|
49
50
|
|
|
50
51
|
const nodeToCleanup = editableNode;
|
|
51
52
|
|
|
53
|
+
// Send final textContentChanged message before cleanup
|
|
54
|
+
handleTextChange(nodeToCleanup, [], true);
|
|
55
|
+
|
|
52
56
|
makeNodeNonEditable(nodeToCleanup);
|
|
53
57
|
disableCanvasTextMode(canvasName);
|
|
54
58
|
cleanup?.();
|