@node-edit-utils/core 2.1.6 → 2.1.7

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,7 +1,7 @@
1
1
  /**
2
2
  * Markup Canvas
3
3
  * High-performance markup canvas with zoom and pan capabilities
4
- * @version 2.1.6
4
+ * @version 2.1.7
5
5
  */
6
6
  'use strict';
7
7
 
@@ -458,8 +458,8 @@ const nodeText = () => {
458
458
  const createNodeTools = (element) => {
459
459
  const nodeProvider = element;
460
460
  let resizeObserver = null;
461
+ let nodeResizeObserver = null;
461
462
  let mutationObserver = null;
462
- let parentMutationObserver = null;
463
463
  let selectedNode = null;
464
464
  const text = nodeText();
465
465
  const throttledFrameRefresh = withRAFThrottle(refreshHighlightFrame);
@@ -472,8 +472,8 @@ const createNodeTools = (element) => {
472
472
  clearHighlightFrame(nodeProvider);
473
473
  selectedNode = null;
474
474
  resizeObserver?.disconnect();
475
+ nodeResizeObserver?.disconnect();
475
476
  mutationObserver?.disconnect();
476
- parentMutationObserver?.disconnect();
477
477
  }
478
478
  }
479
479
  };
@@ -488,8 +488,8 @@ const createNodeTools = (element) => {
488
488
  }
489
489
  }
490
490
  resizeObserver?.disconnect();
491
+ nodeResizeObserver?.disconnect();
491
492
  mutationObserver?.disconnect();
492
- parentMutationObserver?.disconnect();
493
493
  if (node && nodeProvider) {
494
494
  text.enableEditMode(node, nodeProvider);
495
495
  resizeObserver = connectResizeObserver(nodeProvider, () => {
@@ -505,17 +505,10 @@ const createNodeTools = (element) => {
505
505
  childList: true,
506
506
  characterData: true,
507
507
  });
508
- const parent = node.parentElement;
509
- if (parent) {
510
- parentMutationObserver = new MutationObserver(() => {
511
- throttledFrameRefresh(node, nodeProvider);
512
- updateHighlightFrameVisibility(node, nodeProvider);
513
- });
514
- parentMutationObserver.observe(parent, {
515
- childList: true,
516
- subtree: true,
517
- });
518
- }
508
+ nodeResizeObserver = connectResizeObserver(node, () => {
509
+ throttledFrameRefresh(node, nodeProvider);
510
+ updateHighlightFrameVisibility(node, nodeProvider);
511
+ });
519
512
  }
520
513
  selectedNode = node;
521
514
  sendPostMessage("selectedNodeChanged", node?.getAttribute("data-node-id") ?? null);
@@ -529,8 +522,8 @@ const createNodeTools = (element) => {
529
522
  const cleanup = () => {
530
523
  removeListeners();
531
524
  resizeObserver?.disconnect();
525
+ nodeResizeObserver?.disconnect();
532
526
  mutationObserver?.disconnect();
533
- parentMutationObserver?.disconnect();
534
527
  text.blurEditMode();
535
528
  throttledFrameRefresh.cleanup();
536
529
  };
@@ -544,8 +537,8 @@ const createNodeTools = (element) => {
544
537
  clearHighlightFrame(nodeProvider);
545
538
  selectedNode = null;
546
539
  resizeObserver?.disconnect();
540
+ nodeResizeObserver?.disconnect();
547
541
  mutationObserver?.disconnect();
548
- parentMutationObserver?.disconnect();
549
542
  },
550
543
  getEditableNode: () => text.getEditableNode(),
551
544
  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.1.6
4
+ * @version 2.1.7
5
5
  */
6
6
  // biome-ignore lint/suspicious/noExplicitAny: generic constraint requires flexibility
7
7
  function withRAFThrottle(func) {
@@ -456,8 +456,8 @@ const nodeText = () => {
456
456
  const createNodeTools = (element) => {
457
457
  const nodeProvider = element;
458
458
  let resizeObserver = null;
459
+ let nodeResizeObserver = null;
459
460
  let mutationObserver = null;
460
- let parentMutationObserver = null;
461
461
  let selectedNode = null;
462
462
  const text = nodeText();
463
463
  const throttledFrameRefresh = withRAFThrottle(refreshHighlightFrame);
@@ -470,8 +470,8 @@ const createNodeTools = (element) => {
470
470
  clearHighlightFrame(nodeProvider);
471
471
  selectedNode = null;
472
472
  resizeObserver?.disconnect();
473
+ nodeResizeObserver?.disconnect();
473
474
  mutationObserver?.disconnect();
474
- parentMutationObserver?.disconnect();
475
475
  }
476
476
  }
477
477
  };
@@ -486,8 +486,8 @@ const createNodeTools = (element) => {
486
486
  }
487
487
  }
488
488
  resizeObserver?.disconnect();
489
+ nodeResizeObserver?.disconnect();
489
490
  mutationObserver?.disconnect();
490
- parentMutationObserver?.disconnect();
491
491
  if (node && nodeProvider) {
492
492
  text.enableEditMode(node, nodeProvider);
493
493
  resizeObserver = connectResizeObserver(nodeProvider, () => {
@@ -503,17 +503,10 @@ const createNodeTools = (element) => {
503
503
  childList: true,
504
504
  characterData: true,
505
505
  });
506
- const parent = node.parentElement;
507
- if (parent) {
508
- parentMutationObserver = new MutationObserver(() => {
509
- throttledFrameRefresh(node, nodeProvider);
510
- updateHighlightFrameVisibility(node, nodeProvider);
511
- });
512
- parentMutationObserver.observe(parent, {
513
- childList: true,
514
- subtree: true,
515
- });
516
- }
506
+ nodeResizeObserver = connectResizeObserver(node, () => {
507
+ throttledFrameRefresh(node, nodeProvider);
508
+ updateHighlightFrameVisibility(node, nodeProvider);
509
+ });
517
510
  }
518
511
  selectedNode = node;
519
512
  sendPostMessage("selectedNodeChanged", node?.getAttribute("data-node-id") ?? null);
@@ -527,8 +520,8 @@ const createNodeTools = (element) => {
527
520
  const cleanup = () => {
528
521
  removeListeners();
529
522
  resizeObserver?.disconnect();
523
+ nodeResizeObserver?.disconnect();
530
524
  mutationObserver?.disconnect();
531
- parentMutationObserver?.disconnect();
532
525
  text.blurEditMode();
533
526
  throttledFrameRefresh.cleanup();
534
527
  };
@@ -542,8 +535,8 @@ const createNodeTools = (element) => {
542
535
  clearHighlightFrame(nodeProvider);
543
536
  selectedNode = null;
544
537
  resizeObserver?.disconnect();
538
+ nodeResizeObserver?.disconnect();
545
539
  mutationObserver?.disconnect();
546
- parentMutationObserver?.disconnect();
547
540
  },
548
541
  getEditableNode: () => text.getEditableNode(),
549
542
  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.1.6
4
+ * @version 2.1.7
5
5
  */
6
6
  (function (global, factory) {
7
7
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
@@ -462,8 +462,8 @@
462
462
  const createNodeTools = (element) => {
463
463
  const nodeProvider = element;
464
464
  let resizeObserver = null;
465
+ let nodeResizeObserver = null;
465
466
  let mutationObserver = null;
466
- let parentMutationObserver = null;
467
467
  let selectedNode = null;
468
468
  const text = nodeText();
469
469
  const throttledFrameRefresh = withRAFThrottle(refreshHighlightFrame);
@@ -476,8 +476,8 @@
476
476
  clearHighlightFrame(nodeProvider);
477
477
  selectedNode = null;
478
478
  resizeObserver?.disconnect();
479
+ nodeResizeObserver?.disconnect();
479
480
  mutationObserver?.disconnect();
480
- parentMutationObserver?.disconnect();
481
481
  }
482
482
  }
483
483
  };
@@ -492,8 +492,8 @@
492
492
  }
493
493
  }
494
494
  resizeObserver?.disconnect();
495
+ nodeResizeObserver?.disconnect();
495
496
  mutationObserver?.disconnect();
496
- parentMutationObserver?.disconnect();
497
497
  if (node && nodeProvider) {
498
498
  text.enableEditMode(node, nodeProvider);
499
499
  resizeObserver = connectResizeObserver(nodeProvider, () => {
@@ -509,17 +509,10 @@
509
509
  childList: true,
510
510
  characterData: true,
511
511
  });
512
- const parent = node.parentElement;
513
- if (parent) {
514
- parentMutationObserver = new MutationObserver(() => {
515
- throttledFrameRefresh(node, nodeProvider);
516
- updateHighlightFrameVisibility(node, nodeProvider);
517
- });
518
- parentMutationObserver.observe(parent, {
519
- childList: true,
520
- subtree: true,
521
- });
522
- }
512
+ nodeResizeObserver = connectResizeObserver(node, () => {
513
+ throttledFrameRefresh(node, nodeProvider);
514
+ updateHighlightFrameVisibility(node, nodeProvider);
515
+ });
523
516
  }
524
517
  selectedNode = node;
525
518
  sendPostMessage("selectedNodeChanged", node?.getAttribute("data-node-id") ?? null);
@@ -533,8 +526,8 @@
533
526
  const cleanup = () => {
534
527
  removeListeners();
535
528
  resizeObserver?.disconnect();
529
+ nodeResizeObserver?.disconnect();
536
530
  mutationObserver?.disconnect();
537
- parentMutationObserver?.disconnect();
538
531
  text.blurEditMode();
539
532
  throttledFrameRefresh.cleanup();
540
533
  };
@@ -548,8 +541,8 @@
548
541
  clearHighlightFrame(nodeProvider);
549
542
  selectedNode = null;
550
543
  resizeObserver?.disconnect();
544
+ nodeResizeObserver?.disconnect();
551
545
  mutationObserver?.disconnect();
552
- parentMutationObserver?.disconnect();
553
546
  },
554
547
  getEditableNode: () => text.getEditableNode(),
555
548
  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";function t(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}const n=e=>{const t=window.canvas;return e.reduce((e,t)=>e?.[t],t)};function o(e){return e.querySelector(".highlight-frame")}const r=e=>{if(!e)return;const t=o(e);t&&t.remove()},s=["path","rect","circle","ellipse","polygon","line","polyline","text","text-noci"];let i=[],a=0;const l=(e,t)=>{let n=null;const o=e.clientX,r=e.clientY,l=e.metaKey||e.ctrlKey,d=((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})(o,r).filter(e=>!s.includes(e.tagName.toLowerCase())&&!e.classList.contains("select-none"));if(t&&d.includes(t))return t;if(l)return i=[],n=d[0],n;var c,u;u=d,(c=i).length===u.length&&c.every((e,t)=>e===u[t])?a<=d.length&&a++:a=0;return n=d[d.length-1-a],i=d,n},d=(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(t),void o(null);o(l(e,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)}};function c(e,t){const o=e.getBoundingClientRect(),r=t.getBoundingClientRect(),s=o.top-r.top,i=o.left-r.left,a=n(["zoom","current"])??1;return{top:parseFloat((s/a).toFixed(5)),left:parseFloat((i/a).toFixed(5)),width:Math.max(4,parseFloat((o.width/a).toFixed(5))),height:parseFloat((o.height/a).toFixed(5))}}const u=(e,t)=>{const n=document.createElement("div");n.className="node-tools",t.appendChild(n),((e,t)=>{const n=document.createElement("div");n.className="tag-label",n.textContent=e.tagName.toLowerCase(),t.appendChild(n)})(e,n)},m=(e,t)=>{if(!e)return;const r=o(t);r&&r.remove();const s=((e,t)=>{const{top:o,left:r,width:s,height:i}=c(e,t),a=n(["zoom","current"])??1;document.body.style.setProperty("--zoom",a.toString()),document.body.style.setProperty("--stroke-width",(2/a).toFixed(3));const l=document.createElement("div");l.classList.add("highlight-frame"),l.style.setProperty("--frame-top",`${o}px`),l.style.setProperty("--frame-left",`${r}px`),l.style.setProperty("--frame-width",`${s}px`),l.style.setProperty("--frame-height",`${i}px`);const d=document.createElementNS("http://www.w3.org/2000/svg","svg");d.classList.add("highlight-frame-svg");const u=document.createElementNS("http://www.w3.org/2000/svg","rect");return u.setAttribute("x","0"),u.setAttribute("y","0"),u.setAttribute("width","100%"),u.setAttribute("height","100%"),u.classList.add("highlight-frame-rect"),d.appendChild(u),l.appendChild(d),l})(e,t);"true"===e.contentEditable&&s.classList.add("is-editable"),u(e,s),t.appendChild(s)},p=(e,t)=>{const r=o(t),s=n(["zoom","current"])??1;if(!r)return;s>=.3?t.style.setProperty("--tool-opacity","1"):t.style.setProperty("--tool-opacity","0");const{top:i,left:a,width:l,height:d}=c(e,t);r.style.setProperty("--frame-top",`${i}px`),r.style.setProperty("--frame-left",`${a}px`),r.style.setProperty("--frame-width",`${l}px`),r.style.setProperty("--frame-height",`${d}px`)},v=(e,t)=>{const n=o(t);if(!n)return;const r=e.classList.contains("hidden")||e.classList.contains("select-none")?"none":"";n.style.display=r;const s=n.querySelector(".tag-label");s&&(s.style.display=r)},h=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)}},y=(e,t)=>{const n=((e,t)=>{const n=new MutationObserver(e=>{t(e)});return n.observe(e,{subtree:!0,childList:!0,characterData:!0}),n})(e,()=>{p(e,t)});return()=>n.disconnect()},f=()=>{let e=null,t=!1,o=null;const r=()=>{if(t||!e)return;t=!0;var r;(r=e).contentEditable="false",r.classList.remove("is-editable"),r.style.outline="none",(()=>{const e=n(["keyboard","disableTextEditMode"]);e?.()})(),o?.(),e=null,t=!1};return{enableEditMode:(t,s)=>{if(e===t)return;e&&e!==t&&r();const i=(e=>Array.from(e.childNodes).some(e=>e.nodeType===Node.TEXT_NODE&&e.textContent?.trim()))(t);i&&(e=t,(e=>{e.contentEditable="true",e.classList.add("is-editable"),e.style.outline="none"})(t),(()=>{const e=n(["keyboard","enableTextEditMode"]);e?.()})(),o=((e,t,n)=>{if(!t)return()=>{};e.addEventListener("blur",n);const o=h(e),r=y(e,t);return()=>{e.removeEventListener("blur",n),o(),r?.()}})(t,s,r))},blurEditMode:r,getEditableNode:()=>e,isEditing:()=>null!==e}},b=320,g=1680,w=[{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"}],E=(e,t,n)=>{const o=parseFloat(document.body.dataset.zoom||"1"),r=((e,t)=>{const n=e+Math.round(t);return Math.max(b,Math.min(g,n))})(n,(e.clientX-t)/o);return r},L=(e,t)=>{e.style.setProperty("--container-width",`${t}px`),((e,t)=>{e.querySelectorAll(".resize-preset-button").forEach((e,n)=>{n<w.length&&(w[n].rawValue===t?e.classList.add("is-active"):e.classList.remove("is-active"))})})(e,t)};e.createCanvasObserver=function(){const e=document.querySelector(".transform-layer");if(!e)return{disconnect:()=>{}};const o=t(()=>{(()=>{const e=n(["zoom","current"]);document.body.style.setProperty("--zoom",e.toFixed(5)),document.body.style.setProperty("--stroke-width",(2/e).toFixed(3)),document.body.dataset.zoom=e.toFixed(5),document.body.dataset.strokeWidth=(2/e).toFixed(3)})()}),r=new MutationObserver(()=>{o()});return r.observe(e,{attributes:!0,attributeOldValue:!0,subtree:!0,childList:!0}),{disconnect:function(){o.cleanup(),r.disconnect()}}},e.createNodeTools=e=>{const n=e;let o=null,s=null,i=null,a=null;const l=f(),c=t(p),u=e=>{if(a!==e){if(l.isEditing()){const t=l.getEditableNode();t&&t!==e&&l.blurEditMode()}if(o?.disconnect(),s?.disconnect(),i?.disconnect(),e&&n){l.enableEditMode(e,n),o=((e,t)=>{const n=new ResizeObserver(e=>{t(e)});return n.observe(e),n})(n,()=>{c(e,n)}),s=new MutationObserver(()=>{c(e,n),v(e,n)}),s.observe(e,{attributes:!0,subtree:!0,childList:!0,characterData:!0});const t=e.parentElement;t&&(i=new MutationObserver(()=>{c(e,n),v(e,n)}),i.observe(t,{childList:!0,subtree:!0}))}var t,r;a=e,t="selectedNodeChanged",r=e?.getAttribute("data-node-id")??null,window.parent.postMessage({source:"node-edit-utils",action:t,data:r,timestamp:Date.now()},"*"),m(e,n),e&&n&&v(e,n)}},h=d(n,u,()=>{l.isEditing()&&l.blurEditMode(),a&&n&&(r(n),a=null,o?.disconnect(),s?.disconnect(),i?.disconnect())},l.getEditableNode),y={selectNode:u,getSelectedNode:()=>a,refreshHighlightFrame:()=>{c(a,n)},clearSelectedNode:()=>{r(n),a=null,o?.disconnect(),s?.disconnect(),i?.disconnect()},getEditableNode:()=>l.getEditableNode(),cleanup:()=>{h(),o?.disconnect(),s?.disconnect(),i?.disconnect(),l.blurEditMode(),c.cleanup()}};var b,g;return b="nodeTools",g=y,"undefined"!=typeof window&&(window[b]=g),y},e.createViewport=e=>{const n=document.querySelector(".canvas-container"),o=e.querySelector(".resize-handle");o&&o.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",w.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,L);let s=!1,i=0,a=0;const l=t(t=>{if(!s)return;n&&(n.style.cursor="ew-resize");const o=E(t,i,a);L(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(),s=!0,i=t.clientX,a=e.offsetWidth},l,e=>{e.preventDefault(),e.stopPropagation(),n&&(n.style.cursor="default"),s=!1},()=>{s=!1});return{setWidth:t=>{L(e,t)},cleanup:()=>{s=!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";function t(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}const n=e=>{const t=window.canvas;return e.reduce((e,t)=>e?.[t],t)};const o=(e,t)=>{const n=new ResizeObserver(e=>{t(e)});return n.observe(e),n};function r(e){return e.querySelector(".highlight-frame")}const s=e=>{if(!e)return;const t=r(e);t&&t.remove()},a=["path","rect","circle","ellipse","polygon","line","polyline","text","text-noci"];let i=[],d=0;const l=(e,t)=>{let n=null;const o=e.clientX,r=e.clientY,s=e.metaKey||e.ctrlKey,l=((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})(o,r).filter(e=>!a.includes(e.tagName.toLowerCase())&&!e.classList.contains("select-none"));if(t&&l.includes(t))return t;if(s)return i=[],n=l[0],n;var c,u;u=l,(c=i).length===u.length&&c.every((e,t)=>e===u[t])?d<=l.length&&d++:d=0;return n=l[l.length-1-d],i=l,n},c=(e,t,n,o)=>{const r=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)},a=n=>{((e,t,n,o)=>{if(e.preventDefault(),e.stopPropagation(),t&&!t.contains(e.target))return s(t),void o(null);o(l(e,n))})(n,e,o(),t)},i=e=>{"Escape"===e.key&&(e.preventDefault(),e.stopPropagation(),n?.())};return window.addEventListener("message",r),document.addEventListener("click",a),document.addEventListener("keydown",i),()=>{window.removeEventListener("message",r),document.removeEventListener("click",a),document.removeEventListener("keydown",i)}};function u(e,t){const o=e.getBoundingClientRect(),r=t.getBoundingClientRect(),s=o.top-r.top,a=o.left-r.left,i=n(["zoom","current"])??1;return{top:parseFloat((s/i).toFixed(5)),left:parseFloat((a/i).toFixed(5)),width:Math.max(4,parseFloat((o.width/i).toFixed(5))),height:parseFloat((o.height/i).toFixed(5))}}const m=(e,t)=>{const n=document.createElement("div");n.className="node-tools",t.appendChild(n),((e,t)=>{const n=document.createElement("div");n.className="tag-label",n.textContent=e.tagName.toLowerCase(),t.appendChild(n)})(e,n)},p=(e,t)=>{if(!e)return;const o=r(t);o&&o.remove();const s=((e,t)=>{const{top:o,left:r,width:s,height:a}=u(e,t),i=n(["zoom","current"])??1;document.body.style.setProperty("--zoom",i.toString()),document.body.style.setProperty("--stroke-width",(2/i).toFixed(3));const d=document.createElement("div");d.classList.add("highlight-frame"),d.style.setProperty("--frame-top",`${o}px`),d.style.setProperty("--frame-left",`${r}px`),d.style.setProperty("--frame-width",`${s}px`),d.style.setProperty("--frame-height",`${a}px`);const l=document.createElementNS("http://www.w3.org/2000/svg","svg");l.classList.add("highlight-frame-svg");const c=document.createElementNS("http://www.w3.org/2000/svg","rect");return c.setAttribute("x","0"),c.setAttribute("y","0"),c.setAttribute("width","100%"),c.setAttribute("height","100%"),c.classList.add("highlight-frame-rect"),l.appendChild(c),d.appendChild(l),d})(e,t);"true"===e.contentEditable&&s.classList.add("is-editable"),m(e,s),t.appendChild(s)},h=(e,t)=>{const o=r(t),s=n(["zoom","current"])??1;if(!o)return;s>=.3?t.style.setProperty("--tool-opacity","1"):t.style.setProperty("--tool-opacity","0");const{top:a,left:i,width:d,height:l}=u(e,t);o.style.setProperty("--frame-top",`${a}px`),o.style.setProperty("--frame-left",`${i}px`),o.style.setProperty("--frame-width",`${d}px`),o.style.setProperty("--frame-height",`${l}px`)},v=(e,t)=>{const n=r(t);if(!n)return;const o=e.classList.contains("hidden")||e.classList.contains("select-none")?"none":"";n.style.display=o;const s=n.querySelector(".tag-label");s&&(s.style.display=o)},y=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)}},f=(e,t)=>{const n=((e,t)=>{const n=new MutationObserver(e=>{t(e)});return n.observe(e,{subtree:!0,childList:!0,characterData:!0}),n})(e,()=>{h(e,t)});return()=>n.disconnect()},g=()=>{let e=null,t=!1,o=null;const r=()=>{if(t||!e)return;t=!0;var r;(r=e).contentEditable="false",r.classList.remove("is-editable"),r.style.outline="none",(()=>{const e=n(["keyboard","disableTextEditMode"]);e?.()})(),o?.(),e=null,t=!1};return{enableEditMode:(t,s)=>{if(e===t)return;e&&e!==t&&r();const a=(e=>Array.from(e.childNodes).some(e=>e.nodeType===Node.TEXT_NODE&&e.textContent?.trim()))(t);a&&(e=t,(e=>{e.contentEditable="true",e.classList.add("is-editable"),e.style.outline="none"})(t),(()=>{const e=n(["keyboard","enableTextEditMode"]);e?.()})(),o=((e,t,n)=>{if(!t)return()=>{};e.addEventListener("blur",n);const o=y(e),r=f(e,t);return()=>{e.removeEventListener("blur",n),o(),r?.()}})(t,s,r))},blurEditMode:r,getEditableNode:()=>e,isEditing:()=>null!==e}},b=320,w=1680,E=[{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"}],x=(e,t,n)=>{const o=parseFloat(document.body.dataset.zoom||"1"),r=((e,t)=>{const n=e+Math.round(t);return Math.max(b,Math.min(w,n))})(n,(e.clientX-t)/o);return r},L=(e,t)=>{e.style.setProperty("--container-width",`${t}px`),((e,t)=>{e.querySelectorAll(".resize-preset-button").forEach((e,n)=>{n<E.length&&(E[n].rawValue===t?e.classList.add("is-active"):e.classList.remove("is-active"))})})(e,t)};e.createCanvasObserver=function(){const e=document.querySelector(".transform-layer");if(!e)return{disconnect:()=>{}};const o=t(()=>{(()=>{const e=n(["zoom","current"]);document.body.style.setProperty("--zoom",e.toFixed(5)),document.body.style.setProperty("--stroke-width",(2/e).toFixed(3)),document.body.dataset.zoom=e.toFixed(5),document.body.dataset.strokeWidth=(2/e).toFixed(3)})()}),r=new MutationObserver(()=>{o()});return r.observe(e,{attributes:!0,attributeOldValue:!0,subtree:!0,childList:!0}),{disconnect:function(){o.cleanup(),r.disconnect()}}},e.createNodeTools=e=>{const n=e;let r=null,a=null,i=null,d=null;const l=g(),u=t(h),m=e=>{if(d!==e){if(l.isEditing()){const t=l.getEditableNode();t&&t!==e&&l.blurEditMode()}var t,s;r?.disconnect(),a?.disconnect(),i?.disconnect(),e&&n&&(l.enableEditMode(e,n),r=o(n,()=>{u(e,n)}),i=new MutationObserver(()=>{u(e,n),v(e,n)}),i.observe(e,{attributes:!0,subtree:!0,childList:!0,characterData:!0}),a=o(e,()=>{u(e,n),v(e,n)})),d=e,t="selectedNodeChanged",s=e?.getAttribute("data-node-id")??null,window.parent.postMessage({source:"node-edit-utils",action:t,data:s,timestamp:Date.now()},"*"),p(e,n),e&&n&&v(e,n)}},y=c(n,m,()=>{l.isEditing()&&l.blurEditMode(),d&&n&&(s(n),d=null,r?.disconnect(),a?.disconnect(),i?.disconnect())},l.getEditableNode),f={selectNode:m,getSelectedNode:()=>d,refreshHighlightFrame:()=>{u(d,n)},clearSelectedNode:()=>{s(n),d=null,r?.disconnect(),a?.disconnect(),i?.disconnect()},getEditableNode:()=>l.getEditableNode(),cleanup:()=>{y(),r?.disconnect(),a?.disconnect(),i?.disconnect(),l.blurEditMode(),u.cleanup()}};var b,w;return b="nodeTools",w=f,"undefined"!=typeof window&&(window[b]=w),f},e.createViewport=e=>{const n=document.querySelector(".canvas-container"),o=e.querySelector(".resize-handle");o&&o.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",E.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,L);let s=!1,a=0,i=0;const d=t(t=>{if(!s)return;n&&(n.style.cursor="ew-resize");const o=x(t,a,i);L(e,o)}),l=((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(),s=!0,a=t.clientX,i=e.offsetWidth},d,e=>{e.preventDefault(),e.stopPropagation(),n&&(n.style.cursor="default"),s=!1},()=>{s=!1});return{setWidth:t=>{L(e,t)},cleanup:()=>{s=!1,d?.cleanup(),l(),r.remove()}}}});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@node-edit-utils/core",
3
- "version": "2.1.6",
3
+ "version": "2.1.7",
4
4
  "description": "Utilities for editing nodes in a dom tree.",
5
5
  "type": "module",
6
6
  "main": "dist/node-edit-utils.cjs.js",
@@ -14,8 +14,8 @@ export const createNodeTools = (element: HTMLElement | null): NodeTools => {
14
14
  const nodeProvider = element;
15
15
 
16
16
  let resizeObserver: ResizeObserver | null = null;
17
+ let nodeResizeObserver: ResizeObserver | null = null;
17
18
  let mutationObserver: MutationObserver | null = null;
18
- let parentMutationObserver: MutationObserver | null = null;
19
19
  let selectedNode: HTMLElement | null = null;
20
20
 
21
21
  const text = nodeText();
@@ -32,8 +32,8 @@ export const createNodeTools = (element: HTMLElement | null): NodeTools => {
32
32
  selectedNode = null;
33
33
 
34
34
  resizeObserver?.disconnect();
35
+ nodeResizeObserver?.disconnect();
35
36
  mutationObserver?.disconnect();
36
- parentMutationObserver?.disconnect();
37
37
  }
38
38
  }
39
39
  };
@@ -51,8 +51,8 @@ export const createNodeTools = (element: HTMLElement | null): NodeTools => {
51
51
  }
52
52
 
53
53
  resizeObserver?.disconnect();
54
+ nodeResizeObserver?.disconnect();
54
55
  mutationObserver?.disconnect();
55
- parentMutationObserver?.disconnect();
56
56
 
57
57
  if (node && nodeProvider) {
58
58
  text.enableEditMode(node, nodeProvider);
@@ -73,19 +73,10 @@ export const createNodeTools = (element: HTMLElement | null): NodeTools => {
73
73
  characterData: true,
74
74
  });
75
75
 
76
- const parent = node.parentElement;
77
-
78
- if (parent) {
79
- parentMutationObserver = new MutationObserver(() => {
80
- throttledFrameRefresh(node, nodeProvider);
81
- updateHighlightFrameVisibility(node, nodeProvider);
82
- });
83
-
84
- parentMutationObserver.observe(parent, {
85
- childList: true,
86
- subtree: true,
87
- });
88
- }
76
+ nodeResizeObserver = connectResizeObserver(node, () => {
77
+ throttledFrameRefresh(node, nodeProvider);
78
+ updateHighlightFrameVisibility(node, nodeProvider);
79
+ });
89
80
  }
90
81
 
91
82
  selectedNode = node;
@@ -103,8 +94,8 @@ export const createNodeTools = (element: HTMLElement | null): NodeTools => {
103
94
  const cleanup = (): void => {
104
95
  removeListeners();
105
96
  resizeObserver?.disconnect();
97
+ nodeResizeObserver?.disconnect();
106
98
  mutationObserver?.disconnect();
107
- parentMutationObserver?.disconnect();
108
99
 
109
100
  text.blurEditMode();
110
101
  throttledFrameRefresh.cleanup();
@@ -120,8 +111,8 @@ export const createNodeTools = (element: HTMLElement | null): NodeTools => {
120
111
  clearHighlightFrame(nodeProvider);
121
112
  selectedNode = null;
122
113
  resizeObserver?.disconnect();
114
+ nodeResizeObserver?.disconnect();
123
115
  mutationObserver?.disconnect();
124
- parentMutationObserver?.disconnect();
125
116
  },
126
117
  getEditableNode: () => text.getEditableNode(),
127
118
  cleanup,