resize-quill-image 1.0.15 → 1.0.16

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/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [1.0.16] - 12-10-2026
6
+ ### Fixed
7
+ - Images can no longer be resized in read-only mode (`readOnly: true` or `quill.disable()`). Before, the resize showed on screen, but Quill didn't record it until the next edit after re-enabling
8
+ - One resize is now one edit: a single undo step, and no full document rebuild on every frame of the drag
9
+ - Calling `destroy()` more than once no longer throws
10
+
11
+ ---
12
+
5
13
  ## [1.0.15] - 12-10-2026
6
14
  ### Fixed
7
15
  - Moving the cursor no longer makes Quill rebuild its copy of the document on every selection change, which made typing and navigation slow in large documents
package/dist/index.cjs.js CHANGED
@@ -1 +1 @@
1
- let e=require("quill");var t=`#AED2FF`,n=`#687EFF`,r=`#fff`,i={minWidth:16,minHeight:16,noSelectionClass:`no-selection`,handleStyles:{position:`absolute`,width:`15px`,height:`15px`,backgroundColor:t,border:`1px solid ${n}`},overlayStyles:{position:`absolute`,boxSizing:`border-box`,border:`1px dashed #777`,zIndex:8},positions:[{top:0,left:0,clipPath:`polygon(0% 0%, 100% 0%, 0% 100%)`},{top:0,right:0,clipPath:`polygon(100% 0%, 0% 0%, 100% 100%)`},{bottom:0,left:0,clipPath:`polygon(0% 100%, 100% 100%, 0% 0%)`},{bottom:0,right:0,clipPath:`polygon(100% 100%, 0% 100%, 100% 0%)`}],displaySizeStyles:{position:`absolute`,fontSize:`12px`,backgroundColor:t,color:r,padding:`2px 4px`,borderRadius:`4px`,userSelect:`none`,pointerEvents:`none`},displaySizePositionStyles:{right:`20px`,bottom:`5px`,left:`auto`},tooltip:{iconStyles:{position:`absolute`,top:`8px`,right:`8px`,width:`20px`,height:`20px`,background:t,color:r,borderRadius:`50%`,textAlign:`center`,lineHeight:`20px`,fontSize:`14px`,cursor:`pointer`,userSelect:`none`},textStyles:{position:`absolute`,background:t,color:r,padding:`6px 8px`,borderRadius:`4px`,display:`none`,pointerEvents:`none`,fontSize:`12px`,whiteSpace:`pre`}}},a=class{constructor(e,t){this.parent=e,this.styles=t,this.overlay=null}create(){this.overlay=document.createElement(`div`),Object.assign(this.overlay.style,this.styles),this.parent.appendChild(this.overlay)}remove(){this.overlay&&=(this.overlay.remove(),null)}reposition(e){if(!this.overlay)return;let t=e.getBoundingClientRect(),n=this.overlay.offsetParent||this.parent,r=n.getBoundingClientRect();Object.assign(this.overlay.style,{left:`${t.left-r.left-1+n.scrollLeft}px`,top:`${t.top-r.top+n.scrollTop}px`,width:`${t.width}px`,height:`${t.height}px`})}},o=class{constructor(e,t,n,r){this.overlay=e,this.positions=t,this.handleStyles=n,this.mousedownCallback=r,this.boxes=[]}createHandles(){this.positions.forEach(e=>{let t=document.createElement(`div`);Object.assign(t.style,this.handleStyles,e),t.style.clipPath=e.clipPath;let n=e.top!==void 0&&e.left!==void 0||e.bottom!==void 0&&e.right!==void 0;t.style.cursor=n?`nwse-resize`:`nesw-resize`,t.addEventListener(`mousedown`,this.mousedownCallback,!1),t.addEventListener(`touchstart`,this.mousedownCallback,{passive:!1}),this.overlay.appendChild(t),this.boxes.push(t)})}removeHandles(){this.boxes.forEach(e=>{e.removeEventListener(`mousedown`,this.mousedownCallback),e.removeEventListener(`touchstart`,this.mousedownCallback),e.onmousedown=null,e.ontouchstart=null,e.remove()}),this.boxes=[],this.overlay=null,this.positions=null,this.handleStyles=null,this.mousedownCallback=null}},s=class{constructor(e,t,n,r,i){this.minWidth=e,this.minHeight=t,this.overlayManager=n,this.displaySizeManager=r,this.tooltipInfoManager=i,this.img=null,this.dragBox=null,this.startX=0,this.startY=0,this.startWidth=0,this.startHeight=0,this.handleDrag=this.handleDrag.bind(this),this.handleMouseup=this.handleMouseup.bind(this)}setDisplaySizeManager(e){this.displaySizeManager=e}setTooltipInfoManager(e){this.tooltipInfoManager=e}addEventListeners(){document.addEventListener(`mousemove`,this.handleDrag),document.addEventListener(`touchmove`,this.handleDrag,{passive:!1}),document.addEventListener(`mouseup`,this.handleMouseup,!0),document.addEventListener(`touchend`,this.handleMouseup,!0),document.addEventListener(`touchcancel`,this.handleMouseup,!0)}removeEventListeners(){document.removeEventListener(`mousemove`,this.handleDrag),document.removeEventListener(`touchmove`,this.handleDrag),document.removeEventListener(`mouseup`,this.handleMouseup,!0),document.removeEventListener(`touchend`,this.handleMouseup,!0),document.removeEventListener(`touchcancel`,this.handleMouseup,!0)}startDragging(e,t,n){if(e.preventDefault(),this.img=t,this.dragBox=n,e.type===`touchstart`){if(!e.changedTouches.length)return;this.startX=e.changedTouches[0].clientX,this.startY=e.changedTouches[0].clientY}else this.startX=e.clientX,this.startY=e.clientY;this.startWidth=t.width||t.naturalWidth,this.startHeight=t.height||t.naturalHeight,this.addEventListeners()}handleDrag(e){if(!this.img)return;let t,n;if(e.type===`touchmove`){if(!e.changedTouches.length)return;t=e.changedTouches[0].clientX,n=e.changedTouches[0].clientY}else t=e.clientX,n=e.clientY;let r=t-this.startX,i=n-this.startY,a=this.startHeight===0?1:this.startWidth/this.startHeight,o=e.ctrlKey,s=e.shiftKey,c=e.altKey;if(o){let e=this.startWidth+r,t=this.startHeight+i;e=Math.max(e,this.minWidth),t=Math.max(t,this.minHeight),this.img.width=Math.round(e),this.img.height=Math.round(t)}else if(s){let e=this.startHeight+i;e=Math.max(e,this.minHeight),this.img.height=Math.round(e)}else if(c){let e=this.startWidth+r;e=Math.max(e,this.minWidth),this.img.width=Math.round(e)}else{let e=Math.abs(r)>Math.abs(i)?r:i,t=this.startWidth+e,n=t/a;t=Math.max(t,this.minWidth),n=Math.max(n,this.minHeight),this.img.width=Math.round(t),this.img.height=Math.round(n)}this.overlayManager&&this.overlayManager.reposition(this.img),this.displaySizeManager&&this.displaySizeManager.update(),this.tooltipInfoManager&&this.tooltipInfoManager.update(),this.startX=t,this.startY=n,this.startWidth=this.img.offsetWidth,this.startHeight=this.img.offsetHeight}handleMouseup(){this.removeEventListeners(),this.img=null,this.dragBox=null}destroy(){this.removeEventListeners(),this.img=null,this.dragBox=null,this.overlayManager=null,this.displaySizeManager=null,this.tooltipInfoManager=null}},c=class{constructor(e,t,n){this.overlay=e,this.img=t,this.displaySizeStyles=n,this.display=null}create(){this.display=document.createElement(`div`),Object.assign(this.display.style,this.displaySizeStyles),this.overlay.appendChild(this.display),this.update()}update(){if(!this.display||!this.img)return;let e=this.img.offsetWidth,t=this.img.offsetHeight;this.display.textContent=`${e} × ${t}`;let n=this.display.getBoundingClientRect();e>120&&t>30?Object.assign(this.display.style,i.displaySizePositionStyles):Object.assign(this.display.style,{right:`-${n.width+4}px`,bottom:`0`,left:`auto`})}remove(){this.display&&(this.display.remove(),this.display=null,this.overlay=null,this.img=null)}},l=class{constructor(e){this.overlay=e,this.icon=null,this.tooltip=null,this.handleMouseEnter=this.handleMouseEnter.bind(this),this.handleMouseLeave=this.handleMouseLeave.bind(this)}create(){this.icon=document.createElement(`div`),this.icon.textContent=`?`,Object.assign(this.icon.style,i.tooltip.iconStyles),this.tooltip=document.createElement(`div`);let e=this.tooltip;[`Shift for vertical`,`Ctrl for custom`,`Alt for horizontal`].forEach(t=>{let n=document.createElement(`span`);n.textContent=t,n.style.display=`block`,e.appendChild(n)}),Object.assign(this.tooltip.style,i.tooltip.textStyles),this.icon.addEventListener(`mouseenter`,this.handleMouseEnter),this.icon.addEventListener(`mouseleave`,this.handleMouseLeave),this.overlay.appendChild(this.icon),this.overlay.appendChild(this.tooltip),this.update()}handleMouseEnter(){this.tooltip&&(this.tooltip.style.display=`block`)}handleMouseLeave(){this.tooltip&&(this.tooltip.style.display=`none`)}update(){if(!this.icon||!this.tooltip)return;let e=this.icon.offsetTop+25,t=this.icon.offsetLeft-100;Object.assign(this.tooltip.style,{top:`${e}px`,left:`${t}px`})}remove(){(this.icon||this.tooltip)&&(this.icon&&=(this.icon.removeEventListener(`mouseenter`,this.handleMouseEnter),this.icon.removeEventListener(`mouseleave`,this.handleMouseLeave),this.icon.remove(),null),this.tooltip&&=(this.tooltip.remove(),null),this.overlay=null)}},u=class{constructor(e,t){this.options=t,this.img=null,this._showing=!1,this.overlayManager=new a(e,t.overlayStyles),this.dragController=new s(t.minWidth,t.minHeight,this.overlayManager,null,null),this.handleMousedown=this.handleMousedown.bind(this)}show(e){this.img!==e&&e&&e instanceof HTMLImageElement&&(this._showing||=(this._showing=!0,this.hide(),this.img=e,this.overlayManager?.overlay||this.overlayManager?.create(),this.handleManager=new o(this.overlayManager?.overlay,this.options.positions,this.options.handleStyles,this.handleMousedown),this.handleManager.createHandles(),this.overlayManager?.reposition(this.img),this.options.displaySize&&(this.displaySizeManager=new c(this.overlayManager?.overlay,this.img,this.options.displaySizeStyles),this.displaySizeManager.create(),this.dragController?.setDisplaySizeManager(this.displaySizeManager)),this.options.helpIcon&&(this.tooltipInfoManager=new l(this.overlayManager?.overlay),this.tooltipInfoManager.create(),this.dragController?.setTooltipInfoManager(this.tooltipInfoManager)),!1))}hide(){this.dragController?.setDisplaySizeManager(null),this.dragController?.setTooltipInfoManager(null),this.handleManager&&this.handleManager.removeHandles(),this.overlayManager?.remove(),this.displaySizeManager&&this.displaySizeManager.remove(),this.displaySizeManager=null,this.tooltipInfoManager&&=(this.tooltipInfoManager.remove(),null),this.img=null}update(){this.overlayManager?.reposition(this.img),this.displaySizeManager&&this.displaySizeManager.update(),this.tooltipInfoManager&&this.tooltipInfoManager.update()}handleMousedown(e){e.target instanceof HTMLElement&&this.dragController?.startDragging(e,this.img,e.target)}destroy(){this.hide(),this.dragController?.destroy(),this.dragController=null,this.overlayManager=null}};(()=>{if(typeof document>`u`)return;let e=document.createElement(`style`);e.textContent=`.no-selection::selection { background: transparent !important; }`,document.head.appendChild(e)})();var d=class extends e.Module{constructor(e,t={}){super(e,t),this.quill=e,this.options={helpIcon:!0,displaySize:!0,styleSelection:!0,...i,...t,overlayStyles:{...i.overlayStyles,...t.overlayStyles},handleStyles:{...i.handleStyles,...t.handleStyles},displaySizeStyles:{...i.displaySizeStyles,...t.displaySizeStyles}};let n=this.quill.root.parentNode;if(!n)throw Error(`ImageResize: quill.root has no parentNode`);this.uiController=new u(n,this.options),this.bindHandlers(),this.addEventListeners()}bindHandlers(){this.handleClick=this.handleClick.bind(this),this.handleSelectionChange=this.handleSelectionChange.bind(this),this.handleTextChange=this.handleTextChange.bind(this)}addEventListeners(){this.quill.root.addEventListener(`click`,this.handleClick),this.quill.on(`selection-change`,this.handleSelectionChange),this.quill.on(`text-change`,this.handleTextChange)}removeEventListeners(){this.quill.root.removeEventListener(`click`,this.handleClick),this.quill.off(`selection-change`,this.handleSelectionChange),this.quill.off(`text-change`,this.handleTextChange)}handleClick(e){if(e.target instanceof HTMLImageElement){let t=this.quill.constructor.find(e.target);t&&(this.quill.setSelection(t.offset(this.quill.scroll),t.length(),`silent`),this.show(e.target),this.disableTextSelection())}}handleSelectionChange(e){if(!e)return this.hide();let[t]=e.length===1?this.quill.scroll.descendant(this.quill.constructor.import(`formats/image`),e.index):[null];t&&t.domNode instanceof HTMLImageElement?(this.disableTextSelection(),this.show(t.domNode)):(this.enableTextSelection(),this.hide())}handleTextChange(){let e=this.uiController?.img;e&&(e&&!this.quill.root.contains(e)?(this.hide(),this.enableTextSelection()):this.uiController?.update())}disableTextSelection(){this.options.styleSelection&&this.quill.root.classList.toggle(this.options.noSelectionClass,!0)}enableTextSelection(){this.options.styleSelection&&this.quill.root.classList.toggle(this.options.noSelectionClass,!1)}show(e){this.uiController?.show(e)}hide(){this.uiController?.hide()}destroy(){this.removeEventListeners(),this.enableTextSelection(),this.uiController?.destroy(),this.uiController=null,this.quill=null}};module.exports=d;
1
+ let e=require("quill");var t=`#AED2FF`,n=`#687EFF`,r=`#fff`,i={minWidth:16,minHeight:16,noSelectionClass:`no-selection`,handleStyles:{position:`absolute`,width:`15px`,height:`15px`,backgroundColor:t,border:`1px solid ${n}`},overlayStyles:{position:`absolute`,boxSizing:`border-box`,border:`1px dashed #777`,zIndex:8},positions:[{top:0,left:0,clipPath:`polygon(0% 0%, 100% 0%, 0% 100%)`},{top:0,right:0,clipPath:`polygon(100% 0%, 0% 0%, 100% 100%)`},{bottom:0,left:0,clipPath:`polygon(0% 100%, 100% 100%, 0% 0%)`},{bottom:0,right:0,clipPath:`polygon(100% 100%, 0% 100%, 100% 0%)`}],displaySizeStyles:{position:`absolute`,fontSize:`12px`,backgroundColor:t,color:r,padding:`2px 4px`,borderRadius:`4px`,userSelect:`none`,pointerEvents:`none`},displaySizePositionStyles:{right:`20px`,bottom:`5px`,left:`auto`},tooltip:{iconStyles:{position:`absolute`,top:`8px`,right:`8px`,width:`20px`,height:`20px`,background:t,color:r,borderRadius:`50%`,textAlign:`center`,lineHeight:`20px`,fontSize:`14px`,cursor:`pointer`,userSelect:`none`},textStyles:{position:`absolute`,background:t,color:r,padding:`6px 8px`,borderRadius:`4px`,display:`none`,pointerEvents:`none`,fontSize:`12px`,whiteSpace:`pre`}}},a=class{constructor(e,t){this.parent=e,this.styles=t,this.overlay=null}create(){this.overlay=document.createElement(`div`),Object.assign(this.overlay.style,this.styles),this.parent.appendChild(this.overlay)}remove(){this.overlay&&=(this.overlay.remove(),null)}reposition(e){if(!this.overlay)return;let t=e.getBoundingClientRect(),n=this.overlay.offsetParent||this.parent,r=n.getBoundingClientRect();Object.assign(this.overlay.style,{left:`${t.left-r.left-1+n.scrollLeft}px`,top:`${t.top-r.top+n.scrollTop}px`,width:`${t.width}px`,height:`${t.height}px`})}},o=class{constructor(e,t,n,r){this.overlay=e,this.positions=t,this.handleStyles=n,this.mousedownCallback=r,this.boxes=[]}createHandles(){this.positions.forEach(e=>{let t=document.createElement(`div`);Object.assign(t.style,this.handleStyles,e),t.style.clipPath=e.clipPath;let n=e.top!==void 0&&e.left!==void 0||e.bottom!==void 0&&e.right!==void 0;t.style.cursor=n?`nwse-resize`:`nesw-resize`,t.addEventListener(`mousedown`,this.mousedownCallback,!1),t.addEventListener(`touchstart`,this.mousedownCallback,{passive:!1}),this.overlay.appendChild(t),this.boxes.push(t)})}removeHandles(){this.boxes.forEach(e=>{e.removeEventListener(`mousedown`,this.mousedownCallback),e.removeEventListener(`touchstart`,this.mousedownCallback),e.onmousedown=null,e.ontouchstart=null,e.remove()}),this.boxes=[],this.overlay=null,this.positions=null,this.handleStyles=null,this.mousedownCallback=null}},s=class{constructor(e,t,n,r,i,a){this.minWidth=e,this.minHeight=t,this.overlayManager=n,this.displaySizeManager=r,this.tooltipInfoManager=i,this.quill=a,this.batching=!1,this.img=null,this.dragBox=null,this.startX=0,this.startY=0,this.startWidth=0,this.startHeight=0,this.handleDrag=this.handleDrag.bind(this),this.handleMouseup=this.handleMouseup.bind(this)}setDisplaySizeManager(e){this.displaySizeManager=e}setTooltipInfoManager(e){this.tooltipInfoManager=e}addEventListeners(){document.addEventListener(`mousemove`,this.handleDrag),document.addEventListener(`touchmove`,this.handleDrag,{passive:!1}),document.addEventListener(`mouseup`,this.handleMouseup,!0),document.addEventListener(`touchend`,this.handleMouseup,!0),document.addEventListener(`touchcancel`,this.handleMouseup,!0),window.addEventListener(`blur`,this.handleMouseup)}removeEventListeners(){document.removeEventListener(`mousemove`,this.handleDrag),document.removeEventListener(`touchmove`,this.handleDrag),document.removeEventListener(`mouseup`,this.handleMouseup,!0),document.removeEventListener(`touchend`,this.handleMouseup,!0),document.removeEventListener(`touchcancel`,this.handleMouseup,!0),window.removeEventListener(`blur`,this.handleMouseup)}startBatch(){!this.batching&&this.quill&&(this.quill.scroll.batchStart(),this.batching=!0)}endBatch(){if(!this.batching)return;this.batching=!1;let e=this.quill?.scroll;e&&(e.update(e.observer.takeRecords()),e.batchEnd())}startDragging(e,t,n){if(!this.quill||this.quill.isEnabled()){if(e.preventDefault(),this.img=t,this.dragBox=n,e.type===`touchstart`){if(!e.changedTouches.length)return;this.startX=e.changedTouches[0].clientX,this.startY=e.changedTouches[0].clientY}else this.startX=e.clientX,this.startY=e.clientY;this.startWidth=t.width||t.naturalWidth,this.startHeight=t.height||t.naturalHeight,this.addEventListeners(),this.startBatch()}}handleDrag(e){if(!this.img)return;let t,n;if(e.type===`touchmove`){if(!e.changedTouches.length)return;t=e.changedTouches[0].clientX,n=e.changedTouches[0].clientY}else t=e.clientX,n=e.clientY;let r=t-this.startX,i=n-this.startY,a=this.startHeight===0?1:this.startWidth/this.startHeight,o=e.ctrlKey,s=e.shiftKey,c=e.altKey;if(o){let e=this.startWidth+r,t=this.startHeight+i;e=Math.max(e,this.minWidth),t=Math.max(t,this.minHeight),this.img.width=Math.round(e),this.img.height=Math.round(t)}else if(s){let e=this.startHeight+i;e=Math.max(e,this.minHeight),this.img.height=Math.round(e)}else if(c){let e=this.startWidth+r;e=Math.max(e,this.minWidth),this.img.width=Math.round(e)}else{let e=Math.abs(r)>Math.abs(i)?r:i,t=this.startWidth+e,n=t/a;t=Math.max(t,this.minWidth),n=Math.max(n,this.minHeight),this.img.width=Math.round(t),this.img.height=Math.round(n)}this.overlayManager&&this.overlayManager.reposition(this.img),this.displaySizeManager&&this.displaySizeManager.update(),this.tooltipInfoManager&&this.tooltipInfoManager.update(),this.startX=t,this.startY=n,this.startWidth=this.img.offsetWidth,this.startHeight=this.img.offsetHeight}handleMouseup(){this.removeEventListeners(),this.endBatch(),this.img=null,this.dragBox=null}destroy(){this.removeEventListeners(),this.endBatch(),this.img=null,this.dragBox=null,this.overlayManager=null,this.displaySizeManager=null,this.tooltipInfoManager=null,this.quill=null}},c=class{constructor(e,t,n){this.overlay=e,this.img=t,this.displaySizeStyles=n,this.display=null}create(){this.display=document.createElement(`div`),Object.assign(this.display.style,this.displaySizeStyles),this.overlay.appendChild(this.display),this.update()}update(){if(!this.display||!this.img)return;let e=this.img.offsetWidth,t=this.img.offsetHeight;this.display.textContent=`${e} × ${t}`;let n=this.display.getBoundingClientRect();e>120&&t>30?Object.assign(this.display.style,i.displaySizePositionStyles):Object.assign(this.display.style,{right:`-${n.width+4}px`,bottom:`0`,left:`auto`})}remove(){this.display&&(this.display.remove(),this.display=null,this.overlay=null,this.img=null)}},l=class{constructor(e){this.overlay=e,this.icon=null,this.tooltip=null,this.handleMouseEnter=this.handleMouseEnter.bind(this),this.handleMouseLeave=this.handleMouseLeave.bind(this)}create(){this.icon=document.createElement(`div`),this.icon.textContent=`?`,Object.assign(this.icon.style,i.tooltip.iconStyles),this.tooltip=document.createElement(`div`);let e=this.tooltip;[`Shift for vertical`,`Ctrl for custom`,`Alt for horizontal`].forEach(t=>{let n=document.createElement(`span`);n.textContent=t,n.style.display=`block`,e.appendChild(n)}),Object.assign(this.tooltip.style,i.tooltip.textStyles),this.icon.addEventListener(`mouseenter`,this.handleMouseEnter),this.icon.addEventListener(`mouseleave`,this.handleMouseLeave),this.overlay.appendChild(this.icon),this.overlay.appendChild(this.tooltip),this.update()}handleMouseEnter(){this.tooltip&&(this.tooltip.style.display=`block`)}handleMouseLeave(){this.tooltip&&(this.tooltip.style.display=`none`)}update(){if(!this.icon||!this.tooltip)return;let e=this.icon.offsetTop+25,t=this.icon.offsetLeft-100;Object.assign(this.tooltip.style,{top:`${e}px`,left:`${t}px`})}remove(){(this.icon||this.tooltip)&&(this.icon&&=(this.icon.removeEventListener(`mouseenter`,this.handleMouseEnter),this.icon.removeEventListener(`mouseleave`,this.handleMouseLeave),this.icon.remove(),null),this.tooltip&&=(this.tooltip.remove(),null),this.overlay=null)}},u=class{constructor(e,t,n){this.options=t,this.img=null,this._showing=!1,this.overlayManager=new a(e,t.overlayStyles),this.dragController=new s(t.minWidth,t.minHeight,this.overlayManager,null,null,n),this.handleMousedown=this.handleMousedown.bind(this)}show(e){this.img!==e&&e&&e instanceof HTMLImageElement&&(this._showing||=(this._showing=!0,this.hide(),this.img=e,this.overlayManager?.overlay||this.overlayManager?.create(),this.handleManager=new o(this.overlayManager?.overlay,this.options.positions,this.options.handleStyles,this.handleMousedown),this.handleManager.createHandles(),this.overlayManager?.reposition(this.img),this.options.displaySize&&(this.displaySizeManager=new c(this.overlayManager?.overlay,this.img,this.options.displaySizeStyles),this.displaySizeManager.create(),this.dragController?.setDisplaySizeManager(this.displaySizeManager)),this.options.helpIcon&&(this.tooltipInfoManager=new l(this.overlayManager?.overlay),this.tooltipInfoManager.create(),this.dragController?.setTooltipInfoManager(this.tooltipInfoManager)),!1))}hide(){this.dragController?.setDisplaySizeManager(null),this.dragController?.setTooltipInfoManager(null),this.handleManager&&this.handleManager.removeHandles(),this.overlayManager?.remove(),this.displaySizeManager&&this.displaySizeManager.remove(),this.displaySizeManager=null,this.tooltipInfoManager&&=(this.tooltipInfoManager.remove(),null),this.img=null}update(){this.overlayManager?.reposition(this.img),this.displaySizeManager&&this.displaySizeManager.update(),this.tooltipInfoManager&&this.tooltipInfoManager.update()}handleMousedown(e){e.target instanceof HTMLElement&&this.dragController?.startDragging(e,this.img,e.target)}destroy(){this.hide(),this.dragController?.destroy(),this.dragController=null,this.overlayManager=null}};(()=>{if(typeof document>`u`)return;let e=document.createElement(`style`);e.textContent=`.no-selection::selection { background: transparent !important; }`,document.head.appendChild(e)})();var d=class extends e.Module{constructor(e,t={}){super(e,t),this.quill=e,this.options={helpIcon:!0,displaySize:!0,styleSelection:!0,...i,...t,overlayStyles:{...i.overlayStyles,...t.overlayStyles},handleStyles:{...i.handleStyles,...t.handleStyles},displaySizeStyles:{...i.displaySizeStyles,...t.displaySizeStyles}};let n=this.quill.root.parentNode;if(!n)throw Error(`ImageResize: quill.root has no parentNode`);this.uiController=new u(n,this.options,this.quill),this.bindHandlers(),this.addEventListeners()}bindHandlers(){this.handleClick=this.handleClick.bind(this),this.handleSelectionChange=this.handleSelectionChange.bind(this),this.handleTextChange=this.handleTextChange.bind(this)}addEventListeners(){this.quill.root.addEventListener(`click`,this.handleClick),this.quill.on(`selection-change`,this.handleSelectionChange),this.quill.on(`text-change`,this.handleTextChange)}removeEventListeners(){this.quill.root.removeEventListener(`click`,this.handleClick),this.quill.off(`selection-change`,this.handleSelectionChange),this.quill.off(`text-change`,this.handleTextChange)}handleClick(e){if(!this.quill.isEnabled())return this.deselect();if(e.target instanceof HTMLImageElement){let t=this.quill.constructor.find(e.target);t&&(this.quill.setSelection(t.offset(this.quill.scroll),t.length(),`silent`),this.show(e.target),this.disableTextSelection())}}handleSelectionChange(e){if(!e)return this.hide();if(!this.quill.isEnabled())return this.deselect();let[t]=e.length===1?this.quill.scroll.descendant(this.quill.constructor.import(`formats/image`),e.index):[null];t&&t.domNode instanceof HTMLImageElement?(this.disableTextSelection(),this.show(t.domNode)):(this.enableTextSelection(),this.hide())}handleTextChange(){let e=this.uiController?.img;e&&(e&&!this.quill.root.contains(e)?(this.hide(),this.enableTextSelection()):this.uiController?.update())}disableTextSelection(){this.options.styleSelection&&this.quill.root.classList.toggle(this.options.noSelectionClass,!0)}enableTextSelection(){this.options.styleSelection&&this.quill.root.classList.toggle(this.options.noSelectionClass,!1)}show(e){this.uiController?.show(e)}hide(){this.uiController?.hide()}deselect(){this.enableTextSelection(),this.hide()}destroy(){this.quill&&=(this.removeEventListeners(),this.enableTextSelection(),this.uiController?.destroy(),this.uiController=null,null)}};module.exports=d;
package/dist/index.es.js CHANGED
@@ -120,8 +120,8 @@ var t = "#AED2FF", n = "#687EFF", r = "#fff", i = {
120
120
  }), this.boxes = [], this.overlay = null, this.positions = null, this.handleStyles = null, this.mousedownCallback = null;
121
121
  }
122
122
  }, s = class {
123
- constructor(e, t, n, r, i) {
124
- this.minWidth = e, this.minHeight = t, this.overlayManager = n, this.displaySizeManager = r, this.tooltipInfoManager = i, this.img = null, this.dragBox = null, this.startX = 0, this.startY = 0, this.startWidth = 0, this.startHeight = 0, this.handleDrag = this.handleDrag.bind(this), this.handleMouseup = this.handleMouseup.bind(this);
123
+ constructor(e, t, n, r, i, a) {
124
+ this.minWidth = e, this.minHeight = t, this.overlayManager = n, this.displaySizeManager = r, this.tooltipInfoManager = i, this.quill = a, this.batching = !1, this.img = null, this.dragBox = null, this.startX = 0, this.startY = 0, this.startWidth = 0, this.startHeight = 0, this.handleDrag = this.handleDrag.bind(this), this.handleMouseup = this.handleMouseup.bind(this);
125
125
  }
126
126
  setDisplaySizeManager(e) {
127
127
  this.displaySizeManager = e;
@@ -130,17 +130,28 @@ var t = "#AED2FF", n = "#687EFF", r = "#fff", i = {
130
130
  this.tooltipInfoManager = e;
131
131
  }
132
132
  addEventListeners() {
133
- document.addEventListener("mousemove", this.handleDrag), document.addEventListener("touchmove", this.handleDrag, { passive: !1 }), document.addEventListener("mouseup", this.handleMouseup, !0), document.addEventListener("touchend", this.handleMouseup, !0), document.addEventListener("touchcancel", this.handleMouseup, !0);
133
+ document.addEventListener("mousemove", this.handleDrag), document.addEventListener("touchmove", this.handleDrag, { passive: !1 }), document.addEventListener("mouseup", this.handleMouseup, !0), document.addEventListener("touchend", this.handleMouseup, !0), document.addEventListener("touchcancel", this.handleMouseup, !0), window.addEventListener("blur", this.handleMouseup);
134
134
  }
135
135
  removeEventListeners() {
136
- document.removeEventListener("mousemove", this.handleDrag), document.removeEventListener("touchmove", this.handleDrag), document.removeEventListener("mouseup", this.handleMouseup, !0), document.removeEventListener("touchend", this.handleMouseup, !0), document.removeEventListener("touchcancel", this.handleMouseup, !0);
136
+ document.removeEventListener("mousemove", this.handleDrag), document.removeEventListener("touchmove", this.handleDrag), document.removeEventListener("mouseup", this.handleMouseup, !0), document.removeEventListener("touchend", this.handleMouseup, !0), document.removeEventListener("touchcancel", this.handleMouseup, !0), window.removeEventListener("blur", this.handleMouseup);
137
+ }
138
+ startBatch() {
139
+ !this.batching && this.quill && (this.quill.scroll.batchStart(), this.batching = !0);
140
+ }
141
+ endBatch() {
142
+ if (!this.batching) return;
143
+ this.batching = !1;
144
+ let e = this.quill?.scroll;
145
+ e && (e.update(e.observer.takeRecords()), e.batchEnd());
137
146
  }
138
147
  startDragging(e, t, n) {
139
- if (e.preventDefault(), this.img = t, this.dragBox = n, e.type === "touchstart") {
140
- if (!e.changedTouches.length) return;
141
- this.startX = e.changedTouches[0].clientX, this.startY = e.changedTouches[0].clientY;
142
- } else this.startX = e.clientX, this.startY = e.clientY;
143
- this.startWidth = t.width || t.naturalWidth, this.startHeight = t.height || t.naturalHeight, this.addEventListeners();
148
+ if (!this.quill || this.quill.isEnabled()) {
149
+ if (e.preventDefault(), this.img = t, this.dragBox = n, e.type === "touchstart") {
150
+ if (!e.changedTouches.length) return;
151
+ this.startX = e.changedTouches[0].clientX, this.startY = e.changedTouches[0].clientY;
152
+ } else this.startX = e.clientX, this.startY = e.clientY;
153
+ this.startWidth = t.width || t.naturalWidth, this.startHeight = t.height || t.naturalHeight, this.addEventListeners(), this.startBatch();
154
+ }
144
155
  }
145
156
  handleDrag(e) {
146
157
  if (!this.img) return;
@@ -166,10 +177,10 @@ var t = "#AED2FF", n = "#687EFF", r = "#fff", i = {
166
177
  this.overlayManager && this.overlayManager.reposition(this.img), this.displaySizeManager && this.displaySizeManager.update(), this.tooltipInfoManager && this.tooltipInfoManager.update(), this.startX = t, this.startY = n, this.startWidth = this.img.offsetWidth, this.startHeight = this.img.offsetHeight;
167
178
  }
168
179
  handleMouseup() {
169
- this.removeEventListeners(), this.img = null, this.dragBox = null;
180
+ this.removeEventListeners(), this.endBatch(), this.img = null, this.dragBox = null;
170
181
  }
171
182
  destroy() {
172
- this.removeEventListeners(), this.img = null, this.dragBox = null, this.overlayManager = null, this.displaySizeManager = null, this.tooltipInfoManager = null;
183
+ this.removeEventListeners(), this.endBatch(), this.img = null, this.dragBox = null, this.overlayManager = null, this.displaySizeManager = null, this.tooltipInfoManager = null, this.quill = null;
173
184
  }
174
185
  }, c = class {
175
186
  constructor(e, t, n) {
@@ -226,8 +237,8 @@ var t = "#AED2FF", n = "#687EFF", r = "#fff", i = {
226
237
  (this.icon || this.tooltip) && (this.icon &&= (this.icon.removeEventListener("mouseenter", this.handleMouseEnter), this.icon.removeEventListener("mouseleave", this.handleMouseLeave), this.icon.remove(), null), this.tooltip &&= (this.tooltip.remove(), null), this.overlay = null);
227
238
  }
228
239
  }, u = class {
229
- constructor(e, t) {
230
- this.options = t, this.img = null, this._showing = !1, this.overlayManager = new a(e, t.overlayStyles), this.dragController = new s(t.minWidth, t.minHeight, this.overlayManager, null, null), this.handleMousedown = this.handleMousedown.bind(this);
240
+ constructor(e, t, n) {
241
+ this.options = t, this.img = null, this._showing = !1, this.overlayManager = new a(e, t.overlayStyles), this.dragController = new s(t.minWidth, t.minHeight, this.overlayManager, null, null, n), this.handleMousedown = this.handleMousedown.bind(this);
231
242
  }
232
243
  show(e) {
233
244
  this.img !== e && e && e instanceof HTMLImageElement && (this._showing ||= (this._showing = !0, this.hide(), this.img = e, this.overlayManager?.overlay || this.overlayManager?.create(), this.handleManager = new o(this.overlayManager?.overlay, this.options.positions, this.options.handleStyles, this.handleMousedown), this.handleManager.createHandles(), this.overlayManager?.reposition(this.img), this.options.displaySize && (this.displaySizeManager = new c(this.overlayManager?.overlay, this.img, this.options.displaySizeStyles), this.displaySizeManager.create(), this.dragController?.setDisplaySizeManager(this.displaySizeManager)), this.options.helpIcon && (this.tooltipInfoManager = new l(this.overlayManager?.overlay), this.tooltipInfoManager.create(), this.dragController?.setTooltipInfoManager(this.tooltipInfoManager)), !1));
@@ -273,7 +284,7 @@ var d = class extends e {
273
284
  };
274
285
  let n = this.quill.root.parentNode;
275
286
  if (!n) throw Error("ImageResize: quill.root has no parentNode");
276
- this.uiController = new u(n, this.options), this.bindHandlers(), this.addEventListeners();
287
+ this.uiController = new u(n, this.options, this.quill), this.bindHandlers(), this.addEventListeners();
277
288
  }
278
289
  bindHandlers() {
279
290
  this.handleClick = this.handleClick.bind(this), this.handleSelectionChange = this.handleSelectionChange.bind(this), this.handleTextChange = this.handleTextChange.bind(this);
@@ -285,6 +296,7 @@ var d = class extends e {
285
296
  this.quill.root.removeEventListener("click", this.handleClick), this.quill.off("selection-change", this.handleSelectionChange), this.quill.off("text-change", this.handleTextChange);
286
297
  }
287
298
  handleClick(e) {
299
+ if (!this.quill.isEnabled()) return this.deselect();
288
300
  if (e.target instanceof HTMLImageElement) {
289
301
  let t = this.quill.constructor.find(e.target);
290
302
  t && (this.quill.setSelection(t.offset(this.quill.scroll), t.length(), "silent"), this.show(e.target), this.disableTextSelection());
@@ -292,6 +304,7 @@ var d = class extends e {
292
304
  }
293
305
  handleSelectionChange(e) {
294
306
  if (!e) return this.hide();
307
+ if (!this.quill.isEnabled()) return this.deselect();
295
308
  let [t] = e.length === 1 ? this.quill.scroll.descendant(this.quill.constructor.import("formats/image"), e.index) : [null];
296
309
  t && t.domNode instanceof HTMLImageElement ? (this.disableTextSelection(), this.show(t.domNode)) : (this.enableTextSelection(), this.hide());
297
310
  }
@@ -311,8 +324,11 @@ var d = class extends e {
311
324
  hide() {
312
325
  this.uiController?.hide();
313
326
  }
327
+ deselect() {
328
+ this.enableTextSelection(), this.hide();
329
+ }
314
330
  destroy() {
315
- this.removeEventListeners(), this.enableTextSelection(), this.uiController?.destroy(), this.uiController = null, this.quill = null;
331
+ this.quill &&= (this.removeEventListeners(), this.enableTextSelection(), this.uiController?.destroy(), this.uiController = null, null);
316
332
  }
317
333
  };
318
334
  //#endregion
@@ -1 +1 @@
1
- (function(){if(typeof Quill<`u`&&!Quill.Module)try{Quill.Module=Quill.import(`core/module`)}catch{}})();var ImageResize=(function(e){var t=`#AED2FF`,n=`#687EFF`,r=`#fff`,i={minWidth:16,minHeight:16,noSelectionClass:`no-selection`,handleStyles:{position:`absolute`,width:`15px`,height:`15px`,backgroundColor:t,border:`1px solid ${n}`},overlayStyles:{position:`absolute`,boxSizing:`border-box`,border:`1px dashed #777`,zIndex:8},positions:[{top:0,left:0,clipPath:`polygon(0% 0%, 100% 0%, 0% 100%)`},{top:0,right:0,clipPath:`polygon(100% 0%, 0% 0%, 100% 100%)`},{bottom:0,left:0,clipPath:`polygon(0% 100%, 100% 100%, 0% 0%)`},{bottom:0,right:0,clipPath:`polygon(100% 100%, 0% 100%, 100% 0%)`}],displaySizeStyles:{position:`absolute`,fontSize:`12px`,backgroundColor:t,color:r,padding:`2px 4px`,borderRadius:`4px`,userSelect:`none`,pointerEvents:`none`},displaySizePositionStyles:{right:`20px`,bottom:`5px`,left:`auto`},tooltip:{iconStyles:{position:`absolute`,top:`8px`,right:`8px`,width:`20px`,height:`20px`,background:t,color:r,borderRadius:`50%`,textAlign:`center`,lineHeight:`20px`,fontSize:`14px`,cursor:`pointer`,userSelect:`none`},textStyles:{position:`absolute`,background:t,color:r,padding:`6px 8px`,borderRadius:`4px`,display:`none`,pointerEvents:`none`,fontSize:`12px`,whiteSpace:`pre`}}},a=class{constructor(e,t){this.parent=e,this.styles=t,this.overlay=null}create(){this.overlay=document.createElement(`div`),Object.assign(this.overlay.style,this.styles),this.parent.appendChild(this.overlay)}remove(){this.overlay&&=(this.overlay.remove(),null)}reposition(e){if(!this.overlay)return;let t=e.getBoundingClientRect(),n=this.overlay.offsetParent||this.parent,r=n.getBoundingClientRect();Object.assign(this.overlay.style,{left:`${t.left-r.left-1+n.scrollLeft}px`,top:`${t.top-r.top+n.scrollTop}px`,width:`${t.width}px`,height:`${t.height}px`})}},o=class{constructor(e,t,n,r){this.overlay=e,this.positions=t,this.handleStyles=n,this.mousedownCallback=r,this.boxes=[]}createHandles(){this.positions.forEach(e=>{let t=document.createElement(`div`);Object.assign(t.style,this.handleStyles,e),t.style.clipPath=e.clipPath;let n=e.top!==void 0&&e.left!==void 0||e.bottom!==void 0&&e.right!==void 0;t.style.cursor=n?`nwse-resize`:`nesw-resize`,t.addEventListener(`mousedown`,this.mousedownCallback,!1),t.addEventListener(`touchstart`,this.mousedownCallback,{passive:!1}),this.overlay.appendChild(t),this.boxes.push(t)})}removeHandles(){this.boxes.forEach(e=>{e.removeEventListener(`mousedown`,this.mousedownCallback),e.removeEventListener(`touchstart`,this.mousedownCallback),e.onmousedown=null,e.ontouchstart=null,e.remove()}),this.boxes=[],this.overlay=null,this.positions=null,this.handleStyles=null,this.mousedownCallback=null}},s=class{constructor(e,t,n,r,i){this.minWidth=e,this.minHeight=t,this.overlayManager=n,this.displaySizeManager=r,this.tooltipInfoManager=i,this.img=null,this.dragBox=null,this.startX=0,this.startY=0,this.startWidth=0,this.startHeight=0,this.handleDrag=this.handleDrag.bind(this),this.handleMouseup=this.handleMouseup.bind(this)}setDisplaySizeManager(e){this.displaySizeManager=e}setTooltipInfoManager(e){this.tooltipInfoManager=e}addEventListeners(){document.addEventListener(`mousemove`,this.handleDrag),document.addEventListener(`touchmove`,this.handleDrag,{passive:!1}),document.addEventListener(`mouseup`,this.handleMouseup,!0),document.addEventListener(`touchend`,this.handleMouseup,!0),document.addEventListener(`touchcancel`,this.handleMouseup,!0)}removeEventListeners(){document.removeEventListener(`mousemove`,this.handleDrag),document.removeEventListener(`touchmove`,this.handleDrag),document.removeEventListener(`mouseup`,this.handleMouseup,!0),document.removeEventListener(`touchend`,this.handleMouseup,!0),document.removeEventListener(`touchcancel`,this.handleMouseup,!0)}startDragging(e,t,n){if(e.preventDefault(),this.img=t,this.dragBox=n,e.type===`touchstart`){if(!e.changedTouches.length)return;this.startX=e.changedTouches[0].clientX,this.startY=e.changedTouches[0].clientY}else this.startX=e.clientX,this.startY=e.clientY;this.startWidth=t.width||t.naturalWidth,this.startHeight=t.height||t.naturalHeight,this.addEventListeners()}handleDrag(e){if(!this.img)return;let t,n;if(e.type===`touchmove`){if(!e.changedTouches.length)return;t=e.changedTouches[0].clientX,n=e.changedTouches[0].clientY}else t=e.clientX,n=e.clientY;let r=t-this.startX,i=n-this.startY,a=this.startHeight===0?1:this.startWidth/this.startHeight,o=e.ctrlKey,s=e.shiftKey,c=e.altKey;if(o){let e=this.startWidth+r,t=this.startHeight+i;e=Math.max(e,this.minWidth),t=Math.max(t,this.minHeight),this.img.width=Math.round(e),this.img.height=Math.round(t)}else if(s){let e=this.startHeight+i;e=Math.max(e,this.minHeight),this.img.height=Math.round(e)}else if(c){let e=this.startWidth+r;e=Math.max(e,this.minWidth),this.img.width=Math.round(e)}else{let e=Math.abs(r)>Math.abs(i)?r:i,t=this.startWidth+e,n=t/a;t=Math.max(t,this.minWidth),n=Math.max(n,this.minHeight),this.img.width=Math.round(t),this.img.height=Math.round(n)}this.overlayManager&&this.overlayManager.reposition(this.img),this.displaySizeManager&&this.displaySizeManager.update(),this.tooltipInfoManager&&this.tooltipInfoManager.update(),this.startX=t,this.startY=n,this.startWidth=this.img.offsetWidth,this.startHeight=this.img.offsetHeight}handleMouseup(){this.removeEventListeners(),this.img=null,this.dragBox=null}destroy(){this.removeEventListeners(),this.img=null,this.dragBox=null,this.overlayManager=null,this.displaySizeManager=null,this.tooltipInfoManager=null}},c=class{constructor(e,t,n){this.overlay=e,this.img=t,this.displaySizeStyles=n,this.display=null}create(){this.display=document.createElement(`div`),Object.assign(this.display.style,this.displaySizeStyles),this.overlay.appendChild(this.display),this.update()}update(){if(!this.display||!this.img)return;let e=this.img.offsetWidth,t=this.img.offsetHeight;this.display.textContent=`${e} × ${t}`;let n=this.display.getBoundingClientRect();e>120&&t>30?Object.assign(this.display.style,i.displaySizePositionStyles):Object.assign(this.display.style,{right:`-${n.width+4}px`,bottom:`0`,left:`auto`})}remove(){this.display&&(this.display.remove(),this.display=null,this.overlay=null,this.img=null)}},l=class{constructor(e){this.overlay=e,this.icon=null,this.tooltip=null,this.handleMouseEnter=this.handleMouseEnter.bind(this),this.handleMouseLeave=this.handleMouseLeave.bind(this)}create(){this.icon=document.createElement(`div`),this.icon.textContent=`?`,Object.assign(this.icon.style,i.tooltip.iconStyles),this.tooltip=document.createElement(`div`);let e=this.tooltip;[`Shift for vertical`,`Ctrl for custom`,`Alt for horizontal`].forEach(t=>{let n=document.createElement(`span`);n.textContent=t,n.style.display=`block`,e.appendChild(n)}),Object.assign(this.tooltip.style,i.tooltip.textStyles),this.icon.addEventListener(`mouseenter`,this.handleMouseEnter),this.icon.addEventListener(`mouseleave`,this.handleMouseLeave),this.overlay.appendChild(this.icon),this.overlay.appendChild(this.tooltip),this.update()}handleMouseEnter(){this.tooltip&&(this.tooltip.style.display=`block`)}handleMouseLeave(){this.tooltip&&(this.tooltip.style.display=`none`)}update(){if(!this.icon||!this.tooltip)return;let e=this.icon.offsetTop+25,t=this.icon.offsetLeft-100;Object.assign(this.tooltip.style,{top:`${e}px`,left:`${t}px`})}remove(){(this.icon||this.tooltip)&&(this.icon&&=(this.icon.removeEventListener(`mouseenter`,this.handleMouseEnter),this.icon.removeEventListener(`mouseleave`,this.handleMouseLeave),this.icon.remove(),null),this.tooltip&&=(this.tooltip.remove(),null),this.overlay=null)}},u=class{constructor(e,t){this.options=t,this.img=null,this._showing=!1,this.overlayManager=new a(e,t.overlayStyles),this.dragController=new s(t.minWidth,t.minHeight,this.overlayManager,null,null),this.handleMousedown=this.handleMousedown.bind(this)}show(e){this.img!==e&&e&&e instanceof HTMLImageElement&&(this._showing||=(this._showing=!0,this.hide(),this.img=e,this.overlayManager?.overlay||this.overlayManager?.create(),this.handleManager=new o(this.overlayManager?.overlay,this.options.positions,this.options.handleStyles,this.handleMousedown),this.handleManager.createHandles(),this.overlayManager?.reposition(this.img),this.options.displaySize&&(this.displaySizeManager=new c(this.overlayManager?.overlay,this.img,this.options.displaySizeStyles),this.displaySizeManager.create(),this.dragController?.setDisplaySizeManager(this.displaySizeManager)),this.options.helpIcon&&(this.tooltipInfoManager=new l(this.overlayManager?.overlay),this.tooltipInfoManager.create(),this.dragController?.setTooltipInfoManager(this.tooltipInfoManager)),!1))}hide(){this.dragController?.setDisplaySizeManager(null),this.dragController?.setTooltipInfoManager(null),this.handleManager&&this.handleManager.removeHandles(),this.overlayManager?.remove(),this.displaySizeManager&&this.displaySizeManager.remove(),this.displaySizeManager=null,this.tooltipInfoManager&&=(this.tooltipInfoManager.remove(),null),this.img=null}update(){this.overlayManager?.reposition(this.img),this.displaySizeManager&&this.displaySizeManager.update(),this.tooltipInfoManager&&this.tooltipInfoManager.update()}handleMousedown(e){e.target instanceof HTMLElement&&this.dragController?.startDragging(e,this.img,e.target)}destroy(){this.hide(),this.dragController?.destroy(),this.dragController=null,this.overlayManager=null}};return(()=>{if(typeof document>`u`)return;let e=document.createElement(`style`);e.textContent=`.no-selection::selection { background: transparent !important; }`,document.head.appendChild(e)})(),class extends e.Module{constructor(e,t={}){super(e,t),this.quill=e,this.options={helpIcon:!0,displaySize:!0,styleSelection:!0,...i,...t,overlayStyles:{...i.overlayStyles,...t.overlayStyles},handleStyles:{...i.handleStyles,...t.handleStyles},displaySizeStyles:{...i.displaySizeStyles,...t.displaySizeStyles}};let n=this.quill.root.parentNode;if(!n)throw Error(`ImageResize: quill.root has no parentNode`);this.uiController=new u(n,this.options),this.bindHandlers(),this.addEventListeners()}bindHandlers(){this.handleClick=this.handleClick.bind(this),this.handleSelectionChange=this.handleSelectionChange.bind(this),this.handleTextChange=this.handleTextChange.bind(this)}addEventListeners(){this.quill.root.addEventListener(`click`,this.handleClick),this.quill.on(`selection-change`,this.handleSelectionChange),this.quill.on(`text-change`,this.handleTextChange)}removeEventListeners(){this.quill.root.removeEventListener(`click`,this.handleClick),this.quill.off(`selection-change`,this.handleSelectionChange),this.quill.off(`text-change`,this.handleTextChange)}handleClick(e){if(e.target instanceof HTMLImageElement){let t=this.quill.constructor.find(e.target);t&&(this.quill.setSelection(t.offset(this.quill.scroll),t.length(),`silent`),this.show(e.target),this.disableTextSelection())}}handleSelectionChange(e){if(!e)return this.hide();let[t]=e.length===1?this.quill.scroll.descendant(this.quill.constructor.import(`formats/image`),e.index):[null];t&&t.domNode instanceof HTMLImageElement?(this.disableTextSelection(),this.show(t.domNode)):(this.enableTextSelection(),this.hide())}handleTextChange(){let e=this.uiController?.img;e&&(e&&!this.quill.root.contains(e)?(this.hide(),this.enableTextSelection()):this.uiController?.update())}disableTextSelection(){this.options.styleSelection&&this.quill.root.classList.toggle(this.options.noSelectionClass,!0)}enableTextSelection(){this.options.styleSelection&&this.quill.root.classList.toggle(this.options.noSelectionClass,!1)}show(e){this.uiController?.show(e)}hide(){this.uiController?.hide()}destroy(){this.removeEventListeners(),this.enableTextSelection(),this.uiController?.destroy(),this.uiController=null,this.quill=null}}})(Quill);
1
+ (function(){if(typeof Quill<`u`&&!Quill.Module)try{Quill.Module=Quill.import(`core/module`)}catch{}})();var ImageResize=(function(e){var t=`#AED2FF`,n=`#687EFF`,r=`#fff`,i={minWidth:16,minHeight:16,noSelectionClass:`no-selection`,handleStyles:{position:`absolute`,width:`15px`,height:`15px`,backgroundColor:t,border:`1px solid ${n}`},overlayStyles:{position:`absolute`,boxSizing:`border-box`,border:`1px dashed #777`,zIndex:8},positions:[{top:0,left:0,clipPath:`polygon(0% 0%, 100% 0%, 0% 100%)`},{top:0,right:0,clipPath:`polygon(100% 0%, 0% 0%, 100% 100%)`},{bottom:0,left:0,clipPath:`polygon(0% 100%, 100% 100%, 0% 0%)`},{bottom:0,right:0,clipPath:`polygon(100% 100%, 0% 100%, 100% 0%)`}],displaySizeStyles:{position:`absolute`,fontSize:`12px`,backgroundColor:t,color:r,padding:`2px 4px`,borderRadius:`4px`,userSelect:`none`,pointerEvents:`none`},displaySizePositionStyles:{right:`20px`,bottom:`5px`,left:`auto`},tooltip:{iconStyles:{position:`absolute`,top:`8px`,right:`8px`,width:`20px`,height:`20px`,background:t,color:r,borderRadius:`50%`,textAlign:`center`,lineHeight:`20px`,fontSize:`14px`,cursor:`pointer`,userSelect:`none`},textStyles:{position:`absolute`,background:t,color:r,padding:`6px 8px`,borderRadius:`4px`,display:`none`,pointerEvents:`none`,fontSize:`12px`,whiteSpace:`pre`}}},a=class{constructor(e,t){this.parent=e,this.styles=t,this.overlay=null}create(){this.overlay=document.createElement(`div`),Object.assign(this.overlay.style,this.styles),this.parent.appendChild(this.overlay)}remove(){this.overlay&&=(this.overlay.remove(),null)}reposition(e){if(!this.overlay)return;let t=e.getBoundingClientRect(),n=this.overlay.offsetParent||this.parent,r=n.getBoundingClientRect();Object.assign(this.overlay.style,{left:`${t.left-r.left-1+n.scrollLeft}px`,top:`${t.top-r.top+n.scrollTop}px`,width:`${t.width}px`,height:`${t.height}px`})}},o=class{constructor(e,t,n,r){this.overlay=e,this.positions=t,this.handleStyles=n,this.mousedownCallback=r,this.boxes=[]}createHandles(){this.positions.forEach(e=>{let t=document.createElement(`div`);Object.assign(t.style,this.handleStyles,e),t.style.clipPath=e.clipPath;let n=e.top!==void 0&&e.left!==void 0||e.bottom!==void 0&&e.right!==void 0;t.style.cursor=n?`nwse-resize`:`nesw-resize`,t.addEventListener(`mousedown`,this.mousedownCallback,!1),t.addEventListener(`touchstart`,this.mousedownCallback,{passive:!1}),this.overlay.appendChild(t),this.boxes.push(t)})}removeHandles(){this.boxes.forEach(e=>{e.removeEventListener(`mousedown`,this.mousedownCallback),e.removeEventListener(`touchstart`,this.mousedownCallback),e.onmousedown=null,e.ontouchstart=null,e.remove()}),this.boxes=[],this.overlay=null,this.positions=null,this.handleStyles=null,this.mousedownCallback=null}},s=class{constructor(e,t,n,r,i,a){this.minWidth=e,this.minHeight=t,this.overlayManager=n,this.displaySizeManager=r,this.tooltipInfoManager=i,this.quill=a,this.batching=!1,this.img=null,this.dragBox=null,this.startX=0,this.startY=0,this.startWidth=0,this.startHeight=0,this.handleDrag=this.handleDrag.bind(this),this.handleMouseup=this.handleMouseup.bind(this)}setDisplaySizeManager(e){this.displaySizeManager=e}setTooltipInfoManager(e){this.tooltipInfoManager=e}addEventListeners(){document.addEventListener(`mousemove`,this.handleDrag),document.addEventListener(`touchmove`,this.handleDrag,{passive:!1}),document.addEventListener(`mouseup`,this.handleMouseup,!0),document.addEventListener(`touchend`,this.handleMouseup,!0),document.addEventListener(`touchcancel`,this.handleMouseup,!0),window.addEventListener(`blur`,this.handleMouseup)}removeEventListeners(){document.removeEventListener(`mousemove`,this.handleDrag),document.removeEventListener(`touchmove`,this.handleDrag),document.removeEventListener(`mouseup`,this.handleMouseup,!0),document.removeEventListener(`touchend`,this.handleMouseup,!0),document.removeEventListener(`touchcancel`,this.handleMouseup,!0),window.removeEventListener(`blur`,this.handleMouseup)}startBatch(){!this.batching&&this.quill&&(this.quill.scroll.batchStart(),this.batching=!0)}endBatch(){if(!this.batching)return;this.batching=!1;let e=this.quill?.scroll;e&&(e.update(e.observer.takeRecords()),e.batchEnd())}startDragging(e,t,n){if(!this.quill||this.quill.isEnabled()){if(e.preventDefault(),this.img=t,this.dragBox=n,e.type===`touchstart`){if(!e.changedTouches.length)return;this.startX=e.changedTouches[0].clientX,this.startY=e.changedTouches[0].clientY}else this.startX=e.clientX,this.startY=e.clientY;this.startWidth=t.width||t.naturalWidth,this.startHeight=t.height||t.naturalHeight,this.addEventListeners(),this.startBatch()}}handleDrag(e){if(!this.img)return;let t,n;if(e.type===`touchmove`){if(!e.changedTouches.length)return;t=e.changedTouches[0].clientX,n=e.changedTouches[0].clientY}else t=e.clientX,n=e.clientY;let r=t-this.startX,i=n-this.startY,a=this.startHeight===0?1:this.startWidth/this.startHeight,o=e.ctrlKey,s=e.shiftKey,c=e.altKey;if(o){let e=this.startWidth+r,t=this.startHeight+i;e=Math.max(e,this.minWidth),t=Math.max(t,this.minHeight),this.img.width=Math.round(e),this.img.height=Math.round(t)}else if(s){let e=this.startHeight+i;e=Math.max(e,this.minHeight),this.img.height=Math.round(e)}else if(c){let e=this.startWidth+r;e=Math.max(e,this.minWidth),this.img.width=Math.round(e)}else{let e=Math.abs(r)>Math.abs(i)?r:i,t=this.startWidth+e,n=t/a;t=Math.max(t,this.minWidth),n=Math.max(n,this.minHeight),this.img.width=Math.round(t),this.img.height=Math.round(n)}this.overlayManager&&this.overlayManager.reposition(this.img),this.displaySizeManager&&this.displaySizeManager.update(),this.tooltipInfoManager&&this.tooltipInfoManager.update(),this.startX=t,this.startY=n,this.startWidth=this.img.offsetWidth,this.startHeight=this.img.offsetHeight}handleMouseup(){this.removeEventListeners(),this.endBatch(),this.img=null,this.dragBox=null}destroy(){this.removeEventListeners(),this.endBatch(),this.img=null,this.dragBox=null,this.overlayManager=null,this.displaySizeManager=null,this.tooltipInfoManager=null,this.quill=null}},c=class{constructor(e,t,n){this.overlay=e,this.img=t,this.displaySizeStyles=n,this.display=null}create(){this.display=document.createElement(`div`),Object.assign(this.display.style,this.displaySizeStyles),this.overlay.appendChild(this.display),this.update()}update(){if(!this.display||!this.img)return;let e=this.img.offsetWidth,t=this.img.offsetHeight;this.display.textContent=`${e} × ${t}`;let n=this.display.getBoundingClientRect();e>120&&t>30?Object.assign(this.display.style,i.displaySizePositionStyles):Object.assign(this.display.style,{right:`-${n.width+4}px`,bottom:`0`,left:`auto`})}remove(){this.display&&(this.display.remove(),this.display=null,this.overlay=null,this.img=null)}},l=class{constructor(e){this.overlay=e,this.icon=null,this.tooltip=null,this.handleMouseEnter=this.handleMouseEnter.bind(this),this.handleMouseLeave=this.handleMouseLeave.bind(this)}create(){this.icon=document.createElement(`div`),this.icon.textContent=`?`,Object.assign(this.icon.style,i.tooltip.iconStyles),this.tooltip=document.createElement(`div`);let e=this.tooltip;[`Shift for vertical`,`Ctrl for custom`,`Alt for horizontal`].forEach(t=>{let n=document.createElement(`span`);n.textContent=t,n.style.display=`block`,e.appendChild(n)}),Object.assign(this.tooltip.style,i.tooltip.textStyles),this.icon.addEventListener(`mouseenter`,this.handleMouseEnter),this.icon.addEventListener(`mouseleave`,this.handleMouseLeave),this.overlay.appendChild(this.icon),this.overlay.appendChild(this.tooltip),this.update()}handleMouseEnter(){this.tooltip&&(this.tooltip.style.display=`block`)}handleMouseLeave(){this.tooltip&&(this.tooltip.style.display=`none`)}update(){if(!this.icon||!this.tooltip)return;let e=this.icon.offsetTop+25,t=this.icon.offsetLeft-100;Object.assign(this.tooltip.style,{top:`${e}px`,left:`${t}px`})}remove(){(this.icon||this.tooltip)&&(this.icon&&=(this.icon.removeEventListener(`mouseenter`,this.handleMouseEnter),this.icon.removeEventListener(`mouseleave`,this.handleMouseLeave),this.icon.remove(),null),this.tooltip&&=(this.tooltip.remove(),null),this.overlay=null)}},u=class{constructor(e,t,n){this.options=t,this.img=null,this._showing=!1,this.overlayManager=new a(e,t.overlayStyles),this.dragController=new s(t.minWidth,t.minHeight,this.overlayManager,null,null,n),this.handleMousedown=this.handleMousedown.bind(this)}show(e){this.img!==e&&e&&e instanceof HTMLImageElement&&(this._showing||=(this._showing=!0,this.hide(),this.img=e,this.overlayManager?.overlay||this.overlayManager?.create(),this.handleManager=new o(this.overlayManager?.overlay,this.options.positions,this.options.handleStyles,this.handleMousedown),this.handleManager.createHandles(),this.overlayManager?.reposition(this.img),this.options.displaySize&&(this.displaySizeManager=new c(this.overlayManager?.overlay,this.img,this.options.displaySizeStyles),this.displaySizeManager.create(),this.dragController?.setDisplaySizeManager(this.displaySizeManager)),this.options.helpIcon&&(this.tooltipInfoManager=new l(this.overlayManager?.overlay),this.tooltipInfoManager.create(),this.dragController?.setTooltipInfoManager(this.tooltipInfoManager)),!1))}hide(){this.dragController?.setDisplaySizeManager(null),this.dragController?.setTooltipInfoManager(null),this.handleManager&&this.handleManager.removeHandles(),this.overlayManager?.remove(),this.displaySizeManager&&this.displaySizeManager.remove(),this.displaySizeManager=null,this.tooltipInfoManager&&=(this.tooltipInfoManager.remove(),null),this.img=null}update(){this.overlayManager?.reposition(this.img),this.displaySizeManager&&this.displaySizeManager.update(),this.tooltipInfoManager&&this.tooltipInfoManager.update()}handleMousedown(e){e.target instanceof HTMLElement&&this.dragController?.startDragging(e,this.img,e.target)}destroy(){this.hide(),this.dragController?.destroy(),this.dragController=null,this.overlayManager=null}};return(()=>{if(typeof document>`u`)return;let e=document.createElement(`style`);e.textContent=`.no-selection::selection { background: transparent !important; }`,document.head.appendChild(e)})(),class extends e.Module{constructor(e,t={}){super(e,t),this.quill=e,this.options={helpIcon:!0,displaySize:!0,styleSelection:!0,...i,...t,overlayStyles:{...i.overlayStyles,...t.overlayStyles},handleStyles:{...i.handleStyles,...t.handleStyles},displaySizeStyles:{...i.displaySizeStyles,...t.displaySizeStyles}};let n=this.quill.root.parentNode;if(!n)throw Error(`ImageResize: quill.root has no parentNode`);this.uiController=new u(n,this.options,this.quill),this.bindHandlers(),this.addEventListeners()}bindHandlers(){this.handleClick=this.handleClick.bind(this),this.handleSelectionChange=this.handleSelectionChange.bind(this),this.handleTextChange=this.handleTextChange.bind(this)}addEventListeners(){this.quill.root.addEventListener(`click`,this.handleClick),this.quill.on(`selection-change`,this.handleSelectionChange),this.quill.on(`text-change`,this.handleTextChange)}removeEventListeners(){this.quill.root.removeEventListener(`click`,this.handleClick),this.quill.off(`selection-change`,this.handleSelectionChange),this.quill.off(`text-change`,this.handleTextChange)}handleClick(e){if(!this.quill.isEnabled())return this.deselect();if(e.target instanceof HTMLImageElement){let t=this.quill.constructor.find(e.target);t&&(this.quill.setSelection(t.offset(this.quill.scroll),t.length(),`silent`),this.show(e.target),this.disableTextSelection())}}handleSelectionChange(e){if(!e)return this.hide();if(!this.quill.isEnabled())return this.deselect();let[t]=e.length===1?this.quill.scroll.descendant(this.quill.constructor.import(`formats/image`),e.index):[null];t&&t.domNode instanceof HTMLImageElement?(this.disableTextSelection(),this.show(t.domNode)):(this.enableTextSelection(),this.hide())}handleTextChange(){let e=this.uiController?.img;e&&(e&&!this.quill.root.contains(e)?(this.hide(),this.enableTextSelection()):this.uiController?.update())}disableTextSelection(){this.options.styleSelection&&this.quill.root.classList.toggle(this.options.noSelectionClass,!0)}enableTextSelection(){this.options.styleSelection&&this.quill.root.classList.toggle(this.options.noSelectionClass,!1)}show(e){this.uiController?.show(e)}hide(){this.uiController?.hide()}deselect(){this.enableTextSelection(),this.hide()}destroy(){this.quill&&=(this.removeEventListeners(),this.enableTextSelection(),this.uiController?.destroy(),this.uiController=null,null)}}})(Quill);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "resize-quill-image",
3
- "version": "1.0.15",
3
+ "version": "1.0.16",
4
4
  "description": "A lightweight Quill module to resize images with handles and overlays",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.es.js",
@@ -27,6 +27,7 @@
27
27
  "editor",
28
28
  "quill-resize-image",
29
29
  "image",
30
+ "wysiwyg",
30
31
  "resize",
31
32
  "quill image resize",
32
33
  "resize quill image",
@@ -47,13 +48,16 @@
47
48
  "license": "MIT",
48
49
  "scripts": {
49
50
  "typecheck": "tsc",
50
- "build": "vite build && node -e \"require('fs').cpSync('src/index.d.ts', 'dist/index.d.ts')\""
51
+ "build": "vite build && node -e \"require('fs').cpSync('src/index.d.ts', 'dist/index.d.ts')\"",
52
+ "test": "vitest run"
51
53
  },
52
54
  "peerDependencies": {
53
55
  "quill": "^2.0.3"
54
56
  },
55
57
  "devDependencies": {
58
+ "jsdom": "^30.1.2",
56
59
  "typescript": "^7.0.2",
57
- "vite": "^8.3.4"
60
+ "vite": "^8.3.4",
61
+ "vitest": "^5.0.4"
58
62
  }
59
63
  }